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

更多

数码相机
MP4
LCD
机箱
音箱

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

顶点着色器入门(2)

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

     我们以检阅着色器代码作为开始:

 

以下是引用片段:
 /**********************************************************************************
  Vertex shader that does diffuse lighting.
  **********************************************************************************/
  matrix g_view_matrix;
  matrix g_view_proj_matrix;
  vector g_ambient_material;
  vector g_diffuse_material;
  vector g_dir_to_light; // the direction to the light source
  // Global variables used to hold the ambient light intensity (ambient light the light
  // source emits) and the diffuse light intensity (diffuse light the light source emits).
  // These variables are initialized here in the shader.
  const vector DIFFUSE_LIGHT_INTENSITY = {0.5f, 0.5f, 0.5f, 1.0f};
  const vector AMBIENT_LIGHT_INTENSITY = {2.0f, 2.0f, 1.0f, 1.0f};
  struct sVertexInput
  {
  vector position : POSITION;
  vector normal : NORMAL;
  };
  struct sVertexOutput
  {
  vector position : POSITION;
  vector diffuse : COLOR;
  };
  ///////////////////////////////////////////////////////////////////////////////////////////////
  sVertexOutput main(sVertexInput vertex_input)
  {
  sVertexOutput vertex_output = (sVertexOutput) 0;
  // transform position to homogeneous clip space
  vertex_output.position = mul(vertex_input.position, g_view_proj_matrix);
  // Transform lights and normals to view space.
  // Set w components to zero since we're transforming vectors here and not points.
  g_dir_to_light.w = 0.0f;
  vertex_input.normal.w = 0.0f;
  g_dir_to_light = mul(g_dir_to_light, g_view_matrix);
  vertex_input.normal = mul(vertex_input.normal, g_view_matrix);
  // compute cosine of the angle between light and normal
  float scalar = dot(g_dir_to_light, vertex_input.normal);
  // Recall that if the angle between the surface and light is greater than 90 degrees
  // the surface recieves no light. Thus, if the angle is greater than 90 degrees we set
  // scalar to zero so that the surface will not be lit.
  if(scalar < 0.0f)
  scalar = 0.0f;
  // Ambient light reflected is computed by performing a component wise multiplication with
  // the ambient material vector and the ambient light intensity vector.
  //
  // Diffuse light reflected is computed by performing a component wise multiplication with
  // the diffuse material vector and the diffuse light intensity vector.
  // Further we scale each component by the shading scalar s, which shades the color based on
  // how much light the vertex received from the light source.
  //
  // The sum of both the ambient and diffuse components gives us our final vertex color.
  vertex_output.diffuse = (g_ambient_material * AMBIENT_LIGHT_INTENSITY) +
  (scalar * (g_diffuse_material * DIFFUSE_LIGHT_INTENSITY));
  return vertex_output;
  }
  执行程序:
  /**************************************************************************************************
  Demonstrates diffuse lighting using a vertex shader. You will have to switch to
  the REF device to run this sample if your hardware does not support shaders.
  Or you can use software vertex processing: D3DCREATE_SOFTWARE_VERTEXPROCESSING.
  **************************************************************************************************/
  #include "d3dUtility.h"
  #pragma warning(disable : 4100)
  const int WIDTH = 640;
  const int HEIGHT = 480;
  IDirect3DDevice9* g_device;
  ID3DXMesh* g_teapot_mesh;
  IDirect3DVertexShader9* g_vertex_shader;
  ID3DXConstantTable* g_constant_table;
  D3DXHANDLE g_view_matrix_handle;
  D3DXHANDLE g_view_proj_matrix_handle;
  D3DXHANDLE g_ambient_material_handle;
  D3DXHANDLE g_diffuse_material_handle;
  D3DXHANDLE g_dir_to_light_handle;
  D3DXMATRIX g_proj_matrix;
  ////////////////////////////////////////////////////////////////////////////////////////////////////
  bool setup()
  {
  D3DXCreateTeapot(g_device, &g_teapot_mesh, NULL);
  // compile shader
  ID3DXBuffer* shader_buffer;
  ID3DXBuffer* error_buffer;
  HRESULT hr = D3DXCompileShaderFromFile("DiffuseShader.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);
  // get handles
  g_view_matrix_handle = g_constant_table->GetConstantByName(NULL, "g_view_matrix");
  g_view_proj_matrix_handle = g_constant_table->GetConstantByName(NULL, "g_view_proj_matrix");
  g_ambient_material_handle = g_constant_table->GetConstantByName(NULL, "g_ambient_material");
  g_diffuse_material_handle = g_constant_table->GetConstantByName(NULL, "g_diffuse_material");
  g_dir_to_light_handle = g_constant_table->GetConstantByName(NULL, "g_light_direction");
  //
  // set shader constants
  //
  // light direction
  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);
  // materials
  D3DXVECTOR4 ambient_material(1.0f, 1.0f, 0.5f, 1.0f);
  D3DXVECTOR4 diffuse_material(1.0f, 1.0f, 0.5f, 1.0f);
  g_constant_table->SetVector(g_device, g_ambient_material_handle, &ambient_material);
  g_constant_table->SetVector(g_device, g_diffuse_material_handle, &diffuse_material);
  g_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()
  {
  safe_release(g_teapot_mesh);
  safe_release(g_vertex_shader);
  safe_release(g_constant_table);
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  bool display(float time_delta)
  {
  static float angle = (3.0f * D3DX_PI) / 2.0f;
  static float height = 3.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);
  D3DXMATRIX view_proj_matrix = view_matrix * g_proj_matrix;
  g_constant_table->SetMatrix(g_device, g_view_proj_matrix_handle, &view_proj_matrix);
  // render now
  g_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
  g_device->BeginScene();
  g_device->SetVertexShader(g_vertex_shader);
  g_teapot_mesh->DrawSubset(0);
  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;
  }
  运行截图:

  

  setup函数执行下列任务:

  创建茶壶网格

  编译顶点着色器

  根据已编译代码创建顶点着色器

  通过常量表获取着色器程序中的几个变量的句柄

  通过常量表初始化着色器的这几个变量

  注意:对于本应用程序,我们的顶点结构不需要任何自由顶点格式没有的额外的分量。

  display函数非常简单。它检测用户输入(这里指的是用户输入的传入着色器程序的变量),并相应的更新视图矩阵。但是,因为我们在着色器中执行这个视图矩阵变换,所以我们还必须更新着色器中的视图矩阵变量。我们用常量表完成这件事情。

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

软件频道最新更新

热点推荐

IT嘉年华

编辑推荐

软件下载

热门
推荐

网友关注

软件
资料
游戏

装机推荐

文章排行

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