首页产品库评测行情新闻|手机数码笔记本台式机DIY硬件数字家庭数码相机办公外设|软件下载游戏开发|社区

更多

数码相机
MP4
LCD
机箱
音箱

软件资讯设计 工具 系统 开发 安全 办公 陶吧 IT教育 Vista频道 | 下载中心酷我音乐盒 腾讯QQ
天极网 > 开发频道>顶点着色器入门(4)

顶点着色器入门(4)

2008-04-10 13:39作者:lovedday出处:天极网责任编辑:孙蓬阳

  17.5.4 轮廓边顶点着色器代码

  我们现在呈现渲染轮廓边的顶点着色器代码。这个着色器的主要任务就是确定传入的顶点是否在轮廓边上。如果是,顶点着色器就以一定的值,沿顶点法线的方向偏移顶点。

 

以下是引用片段:
 /*************************************************************************************
  Vertex shader that draws the outline edges of a mesh.
  *************************************************************************************/
  matrix g_world_view;
  matrix g_proj;
  static vector BLACK = {0.0f, 0.0f, 0.0f, 0.0f};
  struct sVertexInput
  {
  vector position : POSITION;
  vector normal : NORMAL0;
  vector face_normal_1 : NORMAL1;
  vector face_normal_2 : NORMAL2;
  };
  struct sVertexOutput
  {
  vector position : POSITION;
  vector diffuse : COLOR;
  };
  ////////////////////////////////////////////////////////////////////////////////////////////////////
  sVertexOutput main(sVertexInput input)
  {
  sVertexOutput output = (sVertexOutput) 0;
  // transform position to view space
  input.position = mul(input.position, g_world_view);
  // Compute a vector in the direction of the vertex from the eye.
  // Recall the eye is at the origin in view space - eye is just camera position.
  vector eye_to_vertex = input.position;
  // Transform normals to view space.
  // !! Important, set w components to zero since we're transforming vectors.
  // Assume there are no scalings in the world matrix as well.
  input.normal.w = 0.0f;
  input.face_normal_1.w = 0.0f;
  input.face_normal_2.w = 0.0f;
  input.normal = mul(input.normal, g_world_view);
  input.face_normal_1 = mul(input.face_normal_1, g_world_view);
  input.face_normal_2 = mul(input.face_normal_2, g_world_view);
  // compute the cosine of the angles between the eye_to_vertex vector and the face normals
  float dot0 = dot(eye_to_vertex, input.face_normal_1);
  float dot1 = dot(eye_to_vertex, input.face_normal_2);
  // If cosines are different signs (positive/negative) than we are on a outline edge.
  // Do the signs differ?
  if((dot0 * dot1) < 0.0f)
  {
  // Yes, then this vertex is on a outline edge, offset the vertex position by some scalar
  // in the direction of the vertex normal, which scalar value designate outline's tickness.
  input.position += 0.1f * input.normal;
  }
  // transform to homogeneous clip space
  output.position = mul(input.position, g_proj);
  output.diffuse = BLACK; // set outline color
  return output;
  }
  执行程序: /**************************************************************************************************
  Demonstrates cartoon rendering with outline edges using a vertex shader.
  Note that you will have to switch to the REF device to view this sample if your
  graphics card does not support vertex shaders.
  Or you can use software vertex processing: D3DCREATE_SOFTWARE_VERTEXPROCESSING.
  **************************************************************************************************/
  #include "d3dUtility.h"
  #include "OutlineEdges.h"
  #pragma warning(disable : 4100)
  #define MESH_TEAPOT 0
  #define MESH_SPHERE 1
  #define MESH_TORUS 2
  #define MESH_CYLINDER 3
  #define NUM_MESH 4
  const int WIDTH = 640;
  const int HEIGHT = 480;
  IDirect3DDevice9* g_device;
  IDirect3DVertexShader9* g_vertex_shader;
  ID3DXConstantTable* g_constant_table;
  IDirect3DTexture9* g_shade_texture;
  ID3DXMesh* g_meshes[NUM_MESH];
  D3DXMATRIX g_world_matrices[NUM_MESH];
  D3DXVECTOR4 g_mesh_colors[NUM_MESH];
  D3DXMATRIX g_proj_matrix;
  D3DXHANDLE g_world_view_handle;
  D3DXHANDLE g_world_view_proj_handle;
  D3DXHANDLE g_color_handle;
  D3DXHANDLE g_dir_to_light_handle;
  cOutlineEdges* g_mesh_outlines[NUM_MESH];
  IDirect3DVertexShader9* g_outline_shader;
  ID3DXConstantTable* g_outline_constant_table;
  D3DXHANDLE g_outline_world_view_handle;
  D3DXHANDLE g_outline_proj_handle;
  ////////////////////////////////////////////////////////////////////////////////////////////////////
  bool setup()
  {
  // create geometry and compute corresponding world matrix and color for each mesh
  ID3DXBuffer* adj_buffer[NUM_MESH];
  D3DXCreateTeapot(g_device, &g_meshes[MESH_TEAPOT], &adj_buffer[MESH_TEAPOT]);
  D3DXCreateSphere(g_device, 1.0f, 20, 20, &g_meshes[MESH_SPHERE], &adj_buffer[MESH_SPHERE]);
  D3DXCreateTorus(g_device, 0.5f, 1.0f, 20, 20, &g_meshes[MESH_TORUS], &adj_buffer[MESH_TORUS]);
  D3DXCreateCylinder(g_device, 0.5f, 0.5f, 2.0f, 20, 20, &g_meshes[MESH_CYLINDER], &adj_buffer[MESH_CYLINDER]);
  D3DXMatrixTranslation(&g_world_matrices[MESH_TEAPOT], 0.0f, 2.0f, 0.0f);
  D3DXMatrixTranslation(&g_world_matrices[MESH_SPHERE], 0.0f, -2.0f, 0.0f);
  D3DXMatrixTranslation(&g_world_matrices[MESH_TORUS], -3.0f, 0.0f, 0.0f);
  D3DXMatrixTranslation(&g_world_matrices[MESH_CYLINDER], 3.0f, 0.0f, 0.0f);
  g_mesh_colors[MESH_TEAPOT] = D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f);
  g_mesh_colors[MESH_SPHERE] = D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f);
  g_mesh_colors[MESH_TORUS] = D3DXVECTOR4(0.0f, 0.0f, 1.0f, 1.0f);
  g_mesh_colors[MESH_CYLINDER] = D3DXVECTOR4(1.0f, 1.0f, 0.0f, 1.0f);
  // allocate mesh outlines
  g_mesh_outlines[MESH_TEAPOT] = new cOutlineEdges(g_device, g_meshes[MESH_TEAPOT], adj_buffer[MESH_TEAPOT]);
  g_mesh_outlines[MESH_SPHERE] = new cOutlineEdges(g_device, g_meshes[MESH_SPHERE], adj_buffer[MESH_SPHERE]);
  g_mesh_outlines[MESH_TORUS] = new cOutlineEdges(g_device, g_meshes[MESH_TORUS], adj_buffer[MESH_TORUS]);
  g_mesh_outlines[MESH_CYLINDER] = new cOutlineEdges(g_device, g_meshes[MESH_CYLINDER], adj_buffer[MESH_CYLINDER]);
  safe_release(adj_buffer[MESH_TEAPOT]);
  safe_release(adj_buffer[MESH_SPHERE]);
  safe_release(adj_buffer[MESH_TORUS]);
  safe_release(adj_buffer[MESH_CYLINDER]);
  // compile cartoon shader
  ID3DXBuffer* shader_buffer;
  ID3DXBuffer* error_buffer;
  HRESULT hr = D3DXCompileShaderFromFile("ToonShader.cxx", NULL, NULL, "main", "vs_1_1",
  D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY,
  &shader_buffer, &error_buffer, &g_constant_table);
  // output any error messages
  if(error_buffer)
  {
  MessageBox(NULL, (char*)error_buffer->GetBufferPointer(), "ERROR", MB_OK);
  safe_release(error_buffer);
  }
  if(FAILED(hr))
  {
  MessageBox(NULL, "D3DXCreateEffectFromFile() - FAILED", "ERROR", MB_OK);
  return false;
  }
  hr = g_device->CreateVertexShader((DWORD*) shader_buffer->GetBufferPointer(), &g_vertex_shader);
  if(FAILED(hr))
  {
  MessageBox(NULL, "CreateVertexShader - FAILED", "ERROR", MB_OK);
  return false;
  }
  safe_release(shader_buffer);
  // compile outline shader
  ID3DXBuffer* outline_shader_buffer;
  ID3DXBuffer* outline_error_buffer;
  hr = D3DXCompileShaderFromFile("OutlineShader.cxx", NULL, NULL, "main", "vs_1_1",
  D3DXSHADER_DEBUG, &outline_shader_buffer, &outline_error_buffer, &g_outline_constant_table);
  // output any error messages
  if(outline_error_buffer)
  {
  MessageBox(NULL, (char*) outline_error_buffer->GetBufferPointer(), "ERROR", MB_OK);
  safe_release(outline_error_buffer);
  }
  if(FAILED(hr))
  {
  MessageBox(NULL, "D3DXCompileShaderFromFile() - FAILED", "ERROR", MB_OK);
  return false;
  }
  hr = g_device->CreateVertexShader((DWORD*) outline_shader_buffer->GetBufferPointer(), &g_outline_shader);
  if(FAILED(hr))
  {
  MessageBox(NULL, "CreateVertexShader - FAILED", "ERROR", MB_OK);
  return false;
  }
  safe_release(outline_shader_buffer);
  // load textures
  D3DXCreateTextureFromFile(g_device, "toonshade.bmp", &g_shade_texture);
  g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
  g_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
  g_device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); // disable mipmap
  // get handles
  g_world_view_handle = g_constant_table->GetConstantByName(NULL, "g_world_view");
  g_world_view_proj_handle = g_constant_table->GetConstantByName(NULL, "g_world_view_proj");
  g_color_handle = g_constant_table->GetConstantByName(NULL, "g_color");
  g_dir_to_light_handle = g_constant_table->GetConstantByName(NULL, "g_dir_to_light");
  g_outline_world_view_handle = g_outline_constant_table->GetConstantByName(NULL, "g_world_view");
  g_outline_proj_handle = g_outline_constant_table->GetConstantByName(NULL, "g_proj");
  // set shader constants
  D3DXVECTOR4 dir_to_light(-0.57f, 0.57f, -0.57f, 0.0f);
  g_constant_table->SetVector(g_device, g_dir_to_light_handle, &dir_to_light);
  g_constant_table->SetDefaults(g_device);
  g_outline_constant_table->SetDefaults(g_device);
  // set the projection matrix
  D3DXMatrixPerspectiveFovLH(&g_proj_matrix, D3DX_PI/4.0f, (float)WIDTH/HEIGHT, 1.0f, 1000.0f);
  //g_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
  return true;
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  void cleanup()
  {
  for(int i = 0; i < NUM_MESH; i++)
  {
  safe_release(g_meshes[i]);
  safe_delete(g_mesh_outlines[i]);
  }
  safe_release(g_shade_texture);
  safe_release(g_vertex_shader);
  safe_release(g_constant_table);
  safe_release(g_outline_shader);
  safe_release(g_outline_constant_table);
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  bool display(float time_delta)
  {
  static float angle = (3.0f * D3DX_PI) / 2.0f;
  static float height = 5.0f;
  if(GetAsyncKeyState(VK_LEFT) & 0x8000f)
  angle -= 0.5f * time_delta;
  if(GetAsyncKeyState(VK_RIGHT) & 0x8000f)
  angle += 0.5f * time_delta;
  if(GetAsyncKeyState(VK_UP) & 0x8000f)
  height += 5.0f * time_delta;
  if(GetAsyncKeyState(VK_DOWN) & 0x8000f)
  height -= 5.0f * time_delta;
  D3DXVECTOR3 position(cosf(angle) * 7.0f, height, sinf(angle) * 7.0f);
  D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
  D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
  D3DXMATRIX view_matrix;
  D3DXMatrixLookAtLH(&view_matrix, &position, &target, &up);
  // render now
  g_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 1.0f, 0);
  g_device->BeginScene();
  // draw cartoon
  g_device->SetVertexShader(g_vertex_shader);
  g_device->SetTexture(0, g_shade_texture);
  D3DXMATRIX world_view, world_view_proj;
  for(int i = 0; i < NUM_MESH; i++)
  {
  world_view = g_world_matrices[i] * view_matrix;
  world_view_proj = g_world_matrices[i] * view_matrix * g_proj_matrix;
  g_constant_table->SetMatrix(g_device, g_world_view_handle, &world_view);
  g_constant_table->SetMatrix(g_device, g_world_view_proj_handle, &world_view_proj);
  g_constant_table->SetVector(g_device, g_color_handle, &g_mesh_colors[i]);
  g_meshes[i]->DrawSubset(0);
  }
  // draw outlines
  g_device->SetVertexShader(g_outline_shader);
  g_device->SetTexture(0, NULL);
  // !! Important, do not cull back faces.
  g_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  for(int i = 0; i < NUM_MESH; i++)
  {
  world_view = g_world_matrices[i] * view_matrix;
  g_outline_constant_table->SetMatrix(g_device, g_outline_world_view_handle, &world_view);
  g_outline_constant_table->SetMatrix(g_device, g_outline_proj_handle, &g_proj_matrix);
  g_mesh_outlines[i]->render();
  }
  // restore to cull back faces with counterclockwise vertices
  g_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
  g_device->EndScene();
  g_device->Present(NULL, NULL, NULL, NULL);
  return true;
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
  {
  switch(msg)
  {
  case WM_DESTROY:
  PostQuitMessage(0);
  break;
  case WM_KEYDOWN:
  if(word_param == VK_ESCAPE)
  DestroyWindow(hwnd);
  break;
  }
  return DefWindowProc(hwnd, msg, word_param, long_param);
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  int WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line, int cmd_show)
  {
  if(! init_d3d(inst, WIDTH, HEIGHT, true, D3DDEVTYPE_HAL, &g_device))
  {
  MessageBox(NULL, "init_d3d() - failed.", 0, MB_OK);
  return 0;
  }
  if(! setup())
  {
  MessageBox(NULL, "Steup() - failed.", 0, MB_OK);
  return 0;
  }
  enter_msg_loop(display);
  cleanup();
  g_device->Release();
  return 0;
  }
  运行截图

  

关注此文的读者还看过:

返回开发频道首页

共3页。 上一页123
进入 最权威的Windows 7论坛 查看网友讨论

软件频道最新更新

热点推荐

IT嘉年华

编辑推荐

软件下载

热门
推荐

网友关注

软件
资料
游戏

装机推荐

文章排行

本周
本月
最新更新
天极服务|关于我们|About us|网站律师|RSS订阅|友情合作|加入我们|天极动态|网站地图|意见反馈|MSN/QQ上看天极
Copyright (C) 1999-2012 Yesky.com, All Rights Reserved 版权所有 天极网络