HLSL顶点着色器

来源:互联网 发布:淘宝中秋节活动logo 编辑:程序博客网 时间:2024/04/27 19:50

顶点着色器替代了固定渲染管线中的 变幻 光照 阶段.

实现步骤:

1.在文本文件里编写顶点着色器代码(HLSL语言)

2.编译着色器代码(D3DXCompileShaderFromFile)

3.创建顶点着色器(CreateVertexShader)

4.获取HLSL语言中变量句柄(GetConstantByName)

5.根据句柄给HLSL语言中的变量传值(ID3DXConstTable->Setxxx)??

在文本文件里写顶点着色器代码:

//----------------------------------begin VertexShader.txt--------------------------------------------//世界-观察 矩阵matrix g_world_view;//世界-观察-投影 矩阵matrix g_world_view_proj;//颜色vector g_color;//光线方向vector g_dir_to_light;//输入struct VTIN{ vector pos :POSITION; //输入:位置 vector normal : NORMAL; //输入:法线};//输出struct VTOUT{ vector pos : POSITION; //输出:位置 float2 uv : TEXCOORD; //输出:纹理坐标 vector diffuse : COLOR; //输出:颜色};//函数入口VTOUT main(VTIN input){ //初始化输出结构 VTOUT output = (VTOUT)0;  //pos由建模空间-世界空间-观察空间-投影空间 变幻 output.pos = mul(input.pos, g_world_view_proj);  //转换光线和法线到观察空间,设置w分量为0 //确保没有缩放变幻,因为缩放会弄乱法线的方向 g_dir_to_light.w = 0.0f; input.normal.w = 0.0f; g_dir_to_light = mul(g_dir_to_light, g_world_view); input.normal   = mul(input.normal,   g_world_view);  //计算出uv //其实只要用到纹理的x(即u)就行了 float u = dot(g_dir_to_light, input.normal); //如果u<0.0f,说明角度大于90°,接受不到光线,so if(u < 0.0f) {  u = 0.0f; } float v = 0.5f; //纹理图片y轴像素(0.0f~1.0f)  output.uv.x = u; output.uv.y = v;  output.diffuse = g_color;   return output;}//----------------------------------end VertexShader.txt--------------------------------------------
<pre class="cpp" name="code">//vs中程序代码:#define MESH_TEAPOT0#define MESH_SPHERE1#define MESH_TORUS2#define MESH_CYLINDER3//-----------顶点着色器相关的变量------------------IDirect3DVertexShader9* m_VertexShader;ID3DXConstantTable*m_ConstantTable;IDirect3DTexture9*m_ShadeTexture;ID3DXMesh*m_Meshes[4];D3DXMATRIXm_WorldMatrices[4];D3DXVECTOR4m_MeshColors[4];D3DXMATRIXm_ProjMatrix;D3DXHANDLEm_WorldViewHandle;D3DXHANDLEm_WorldViewProjHandle;D3DXHANDLEm_ColorHandle;D3DXHANDLEm_DirLightHandle;//setup: main函数中调用一次void Setup(){//创建模型们: 茶壶 圆球 圆环 圆桶D3DXCreateTeapot(D3DDevice, &m_Meshes[MESH_TEAPOT], NULL);D3DXCreateSphere(D3DDevice, 1.0f, 20, 20, &m_Meshes[MESH_SPHERE], NULL);D3DXCreateTorus(D3DDevice, 0.5f, 1.0f, 20, 20, &m_Meshes[MESH_TORUS], NULL);D3DXCreateCylinder(D3DDevice, 0.5f, 0.5f, 2.0f, 20, 20, &m_Meshes[MESH_CYLINDER], NULL);//模型们的在世界中的矩阵:D3DXMatrixTranslation(&m_WorldMatrices[MESH_TEAPOT], 0.0f, 2.0f, 0.0f);D3DXMatrixTranslation(&m_WorldMatrices[MESH_SPHERE], 0.0f, -2.0f, 0.0f);D3DXMatrixTranslation(&m_WorldMatrices[MESH_TORUS], -3.0f, 0.0f, 0.0f);D3DXMatrixTranslation(&m_WorldMatrices[MESH_CYLINDER], 3.0f, 0.0f, 0.0f);//模型们的颜色:m_MeshColors[MESH_TEAPOT] = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);m_MeshColors[MESH_SPHERE] = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);m_MeshColors[MESH_TORUS] = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);m_MeshColors[MESH_CYLINDER] = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);//编译着色器:ID3DXBuffer*shader_buffer;ID3DXBuffer*error_buffer;HRESULT hr = D3DXCompileShaderFromFile(L"D:\\VertexShader.txt", NULL, NULL, "main", "vs_1_1",D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY,&shader_buffer, &error_buffer, &m_ConstantTable);// 输出错误信息:if (error_buffer){string str = (char*)error_buffer->GetBufferPointer();MessageBox(NULL, Common::StringToWString(str).c_str(), L"ERROR", MB_OK);//safe_release<ID3DXBuffer*>(error_buffer);}if (FAILED(hr)){MessageBox(NULL, L"D3DXCreateEffectFromFile() - FAILED", L"ERROR", MB_OK);}//创建顶点着色器hr = D3DDevice()CreateVertexShader((DWORD*)shader_buffer->GetBufferPointer(), &m_VertexShader);if (FAILED(hr)){MessageBox(NULL, L"CreateVertexShader - FAILED", L"ERROR", MB_OK);}//释放//safe_release<ID3DXBuffer*>(shader_buffer);//加载纹理:D3DXCreateTextureFromFile(D3DDevice, L"D:\\pic1.png", &m_ShadeTexture);//设置状态属性:D3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);D3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);D3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);//禁用过滤//获取常量句柄m_WorldViewHandle = m_ConstantTable->GetConstantByName(NULL, "g_world_view");m_WorldViewProjHandle = m_ConstantTable->GetConstantByName(NULL, "g_world_view_proj");m_ColorHandle = m_ConstantTable->GetConstantByName(NULL, "g_color");m_DirLightHandle = m_ConstantTable->GetConstantByName(NULL, "g_dir_to_light");// set shader constantsD3DXVECTOR4 dir_to_light(-0.57f, 0.57f, -0.57f, 0.0f);m_ConstantTable->SetVector(D3DDevice, m_DirLightHandle, &dir_to_light);m_ConstantTable->SetDefaults(D3DDevice);//设置投影矩阵RECT rt;GetClientRect(hwnd, &rt);D3DXMatrixPerspectiveFovLH(&m_ProjMatrix, D3DX_PI / 4.0f, (float)rt.right / rt.bottom, 1.0f, 1000.0f);}//display: 在消息循环中调用,时时更新void Display(float timeDelta){static float angle = (3.0f * D3DX_PI) / 2.0f;static float height = 5.0f;if (GetAsyncKeyState(VK_LEFT) & 0x8000f)angle -= 0.5f * timeDelta;if (GetAsyncKeyState(VK_RIGHT) & 0x8000f)angle += 0.5f * timeDelta;if (GetAsyncKeyState(VK_UP) & 0x8000f)height += 5.0f * timeDelta;if (GetAsyncKeyState(VK_DOWN) & 0x8000f)height -= 5.0f * timeDelta;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 nowD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);D3DDevice->BeginScene();D3DDevice->SetVertexShader(m_VertexShader);D3DDevice->SetTexture(0, m_ShadeTexture);D3DXMATRIX world_view, world_view_proj;for (int i = 0; i < 4; i++){world_view = m_WorldMatrices[i] * view_matrix;world_view_proj = m_WorldMatrices[i] * view_matrix * m_ProjMatrix;m_ConstantTable->SetMatrix(D3DDevice, m_WorldViewHandle, &world_view);m_ConstantTable->SetMatrix(D3DDevice, m_WorldViewProjHandle, &world_view_proj);m_ConstantTable->SetVector(D3DDevice, m_ColorHandle, &m_MeshColors[i]);m_Meshes[i]->DrawSubset(0);}D3DDevice()->EndScene();D3DDevice()->Present(NULL, NULL, NULL, NULL);}

代码来自博客:天行健君子当自强不息.

效果图:当纹理图为效果图为

当纹理图为效果图为:

0 0
原创粉丝点击