Directx11基础教程三之VertexShader,PixelShader,buffer

来源:互联网 发布:阿里云邮箱的pc客户端 编辑:程序博客网 时间:2024/06/07 02:50

一,看本节教程前应该掌握:

     (1)D3D11基础教程二之D3D11初始化

     (2)了解3D渲染流水线的知识,如世界变换,相机变换,透视投影变换,视口变换,光栅化,线性插值,gouraud着色等,最好具备一定的图形学基础,我推荐一本书<3D游戏编程大师技巧>,这本书完整的讲解了3D渲染流水线的方方面面。


二,本节教程的程序结构:






三,VertexShader(顶点着色器)和PixelShader(像素着色器)的作用:

在讲解VertexShader(顶点着色器)和PixelShader(像素着色器)的作用之前,我先放出一张D3D11简略版的3D渲染流水线图:



(1)VertexShader(顶点着色器):顶点着色器顾名思义,也就是对顶点进行操作,对顶点进行变换的着色器,看上面图红色圈住的部分就是顶点变换的过程了,而我们的VertexShader(顶点着色器),一般是对顶点进行上面红色圈的 世界变换(WorldTransform),   相机变换(也称视角变换,ViewTransform),    透视投影变换(PerspectiveProjection),(得注意的是"视口变换"不属于VertexShader,而是与"背面剔除'和"顶点属性线性插值"共属于光栅化阶段")剩下的几种变换经常是显卡帮我们自动进行的。


(2) PixelShader(像素着色器):像素着色器顾名思义,也就是对像素进行的操作的着色器,也就是上面图里的蓝色圈住的部分。像素着色器主要是对像素(像素的位置,颜色,向量等)操作,最终输出像素的颜色。


(3)VertexShader(顶点着色器)和PixelShader(像素着色器)之间的关系:这里用一个三角形作为例子,一个三角形由三个顶点ABC组成,三角形ABC位于局部空间,三个顶点ABC分别在VertexShader进行世界变换,相机变换等等各种变换,最终变换到屏幕空间,然后对屏幕空间的三角形ABC进行光栅化,得到三角形里面的像素,然后用PixelShader对像素进行操作,最终输出颜色到屏幕上。如下面图所示:


看图中的三角形ABC以及三角形ABC里面的像素,图中我用红色点表示像素,一个红色点就是一个像素。


(其实上面也不对,这里为了初学者教学的简便,我们就不引入其它种类的Shader了,以及深度缓存一大堆乱七八糟的)



三,程序的代码:


首先能GraphicsClass包含四个类,分别为D3DClass,ModelClass,CameraClass,ColorShaderClass


(1) GrapgicsClass

GraphicsClass.h

[cpp] view plain copy
  1. #pragma once  
  2. #ifndef _GRAPHICS_CLASS_H  
  3. #define _GRAPHICS_CLASS_H  
  4.   
  5. #include"D3DClass.h"  
  6. #include"CameraClass.h"  
  7. #include"ColorShaderClass.h"  
  8. #include"ModelClass.h"  
  9.   
  10.   
  11. //全局变量  
  12. const bool FULL_SCREEN = false;  
  13. const bool VSYNC_ENABLE = true;  //是尽可能快渲染还是限制帧渲染  
  14. const float SCREEN_FAR = 1000.0f;  //视截体远裁面  
  15. const float SCREEN_NEAR = 0.1f;  //视截体近裁面  
  16.   
  17.   
  18.   
  19. class GraphicsClass  
  20. {  
  21.   
  22. private:  
  23.     //D3D类  
  24.     D3DClass* mD3D;  
  25.   
  26.     //相机类,用于控制场景的相机  
  27.     CameraClass* mCamera;   
  28.   
  29.     //用于控制VertexShader PixelShader,InputLayout  
  30.     ColorShaderClass* mColorShader;  
  31.   
  32.     //用于控制VertexBuffer和IndexBuffer  
  33.     ModelClass* mModel;  
  34.   
  35. private:  
  36.     bool Render();  
  37.   
  38. public:  
  39.     GraphicsClass();  
  40.     GraphicsClass(const GraphicsClass&);  
  41.     ~GraphicsClass();  
  42.   
  43. public:  
  44.     bool Initialize(int ScreenWidth, int ScreenHeight, HWND hwnd);  
  45.     void Shutdown();  
  46.     bool Frame();   
  47. };  
  48. #endif // !_GRAPHICS_CLASS_H  



(2) ColorShaderClass


ColorShaderClass.h  (用于加载VertexShader和PixelShader)

[cpp] view plain copy
  1. #pragma once  
  2. #ifndef _COLOR_SHADER_CLASS_H  
  3. #define _COLOR_SHADER_CLASS_H  
  4. #define HR2(X) {if(FAILED(X)) { MessageBox(0,L"Create Failed",0,0); return false;}}  
  5.   
  6. #include<d3d11.h>  
  7. #include<xnamath.h>  
  8. #include<D3DX11.h> //含编译Shader程序的函数  
  9. #include<d3dcompiler.h>  
  10. #include<fstream>  
  11. using namespace std;  
  12.   
  13. class ColorShaderClass  
  14. {  
  15.   
  16. private:  
  17.     //常量缓存结构体  
  18.     struct CBMatrix  
  19.     {  
  20.         XMMATRIX mWorldMatrix;  
  21.         XMMATRIX mViewMatrix;  
  22.         XMMATRIX mProjMatrix;  
  23.     };  
  24.   
  25. private:  
  26.     ID3D11VertexShader* md3dVertexShader;  
  27.     ID3D11PixelShader* md3dPixelShader;  
  28.     ID3D11InputLayout* md3dInputLayout; //这与VertexShader相关联,因此要放在ColorShaderClass里,而不是D3DClass  
  29.     ID3D11Buffer* mCBMatrixBuffer; //(常量)缓存,顶点索引也是用这个类型  
  30.   
  31. private:  
  32.     bool InitializeShader(ID3D11Device*, HWNDWCHAR*, WCHAR*); //用于创建InputLayout,VertexShader,PixelShader,常量缓存  
  33.     bool ShutdownShader();  
  34.     void OutputShaderErrorMessage(ID3D10Blob*, HWNDWCHAR*);  
  35.   
  36.     bool SetShaderParameter(ID3D11DeviceContext*, CXMMATRIX, CXMMATRIX, CXMMATRIX);  
  37.     void RenderShader(ID3D11DeviceContext*, int);  
  38.   
  39. public:  
  40.     ColorShaderClass();  
  41.     ColorShaderClass(const ColorShaderClass&);  
  42.     ~ColorShaderClass();  
  43.   
  44. public:  
  45.     bool Initialize(ID3D11Device*, HWND);  
  46.     void Shutdown();  
  47.     bool Render(ID3D11DeviceContext*, int, CXMMATRIX, CXMMATRIX, CXMMATRIX);  
  48.   
  49. };  
  50. #endif   


ColorShaderClass.CPP

[cpp] view plain copy
  1. #include"ColorShaderClass.h"  
  2.   
  3. ColorShaderClass::ColorShaderClass()  
  4. {  
  5.      md3dVertexShader=NULL;  
  6.      md3dPixelShader=NULL;  
  7.      md3dInputLayout=NULL;  
  8.      mCBMatrixBuffer=NULL;  
  9. }  
  10.   
  11.   
  12. ColorShaderClass::ColorShaderClass(const ColorShaderClass&)  
  13. {  
  14.   
  15. }  
  16.   
  17. ColorShaderClass::~ColorShaderClass()  
  18. {  
  19.   
  20. }  
  21.   
  22.   
  23. bool ColorShaderClass::Initialize(ID3D11Device* d3dDevice, HWND hwnd)  
  24. {  
  25.     bool result;  
  26.     result = InitializeShader(d3dDevice, hwnd, L"MyShader.fx", L"MyShader.fx");  
  27.     if (!result)  
  28.         return false;  
  29.   
  30.     return true;  
  31. }  
  32.   
  33. void ColorShaderClass::Shutdown()  
  34. {  
  35.     ShutdownShader();  
  36. }  
  37.   
  38. bool ColorShaderClass::Render(ID3D11DeviceContext* d3dDeviceContext, int indexCount, CXMMATRIX worldMatrix, CXMMATRIX viewMatrix, CXMMATRIX ProjMatrix)  
  39. {  
  40.     bool result;  
  41.   
  42.     //设置用来渲染的Shader属性  
  43.     result = SetShaderParameter(d3dDeviceContext, worldMatrix, viewMatrix, ProjMatrix);  
  44.     if (!result)  
  45.         return false;  
  46.   
  47.     //渲染Shader  
  48.     RenderShader(d3dDeviceContext, indexCount);  
  49.       
  50.     return true;  
  51. }  
  52.   
  53. bool ColorShaderClass::InitializeShader(ID3D11Device* d3dDevice, HWND hwnd, WCHAR* VSFileName, WCHAR* PSFileName)  
  54. {  
  55.     HRESULT result;  
  56.     ID3D10Blob* errorMessage;  
  57.     ID3D10Blob* VertexShaderBuffer;    
  58.     ID3D10Blob* PixelShaderBuffer;  
  59.       
  60.     //第一,初始化参数  
  61.     errorMessage = NULL;  
  62.     VertexShaderBuffer=NULL;  
  63.     PixelShaderBuffer=NULL;  
  64.   
  65.     //第二,编译VertexShader代码,并创建VertexShader  
  66.     result = D3DX11CompileFromFile(VSFileName, NULL, NULL, "VS""vs_5_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, NULL, &VertexShaderBuffer, &errorMessage, NULL);  
  67.     if (FAILED(result))  
  68.     {  
  69.         //存在错误信息  
  70.         if (errorMessage)  
  71.         {  
  72.             OutputShaderErrorMessage(errorMessage, hwnd, VSFileName);  
  73.         }  
  74.         //不存在错误信息,也就是没有找到Shader文件  
  75.         else  
  76.         {  
  77.             MessageBox(hwnd, L"can not find VS file", L"error", MB_OK);  
  78.         }  
  79.     }  
  80.   
  81.     HR2(d3dDevice->CreateVertexShader(VertexShaderBuffer->GetBufferPointer(),VertexShaderBuffer->GetBufferSize(),NULL,&md3dVertexShader));  
  82.   
  83.   
  84.     //第三,编译PixelShader,并创建PixelShader  
  85.     result = D3DX11CompileFromFile(PSFileName, NULL, NULL, "PS""ps_5_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, NULL, &PixelShaderBuffer, &errorMessage, NULL);  
  86.     if (FAILED(result))  
  87.     {  
  88.         //存在错误信息  
  89.         if (errorMessage)  
  90.         {  
  91.             OutputShaderErrorMessage(errorMessage, hwnd, PSFileName);  
  92.         }  
  93.         //不存在错误信息,也就是没有找到Shader文件  
  94.         else  
  95.         {  
  96.             MessageBox(hwnd, L"can not find PS file", L"error", MB_OK);  
  97.         }  
  98.     }  
  99.   
  100.     HR2(d3dDevice->CreatePixelShader(PixelShaderBuffer->GetBufferPointer(), PixelShaderBuffer->GetBufferSize(), NULL, &md3dPixelShader));  
  101.   
  102.     //第四,填充输入布局形容结构体,创建输入布局  
  103.     D3D11_INPUT_ELEMENT_DESC VertexInputLayout[] =  
  104.     {  
  105.         { "POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0 }, // 96位即12个字节  
  106.         { "COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0 },  
  107.     };  
  108.   
  109.     unsigned int numElements = sizeof(VertexInputLayout) / sizeof(VertexInputLayout[0]);         //布局数量  
  110.       
  111.     HR2(d3dDevice->CreateInputLayout(VertexInputLayout, numElements, VertexShaderBuffer->GetBufferPointer(), VertexShaderBuffer->GetBufferSize(), &md3dInputLayout));  
  112.   
  113.     //第五,释放VertexShaderBuffer和PixelShaderBuffer  
  114.     VertexShaderBuffer->Release();  
  115.     VertexShaderBuffer = NULL;  
  116.     PixelShaderBuffer->Release();  
  117.     PixelShaderBuffer = NULL;  
  118.   
  119.     //第六,设置(常量)缓存形容结构体,并创建常量缓存  
  120.     D3D11_BUFFER_DESC matrixBufferDesc;  
  121.     ZeroMemory(&matrixBufferDesc, sizeof(matrixBufferDesc));  
  122.     matrixBufferDesc.Usage = D3D11_USAGE_DEFAULT;  
  123.     matrixBufferDesc.ByteWidth = sizeof(CBMatrix);   //结构体大小,必须为16字节倍数  
  124.     matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;  
  125.     matrixBufferDesc.CPUAccessFlags = 0;   
  126.   
  127.     HR2(d3dDevice->CreateBuffer(&matrixBufferDesc, NULL, &mCBMatrixBuffer));  
  128.   
  129.     return true;  
  130. }  
  131.   
  132. bool ColorShaderClass::ShutdownShader()  
  133. {  
  134.     HR2(mCBMatrixBuffer);  
  135.     HR2(md3dInputLayout);  
  136.     HR2(md3dPixelShader);  
  137.     HR2(md3dVertexShader);  
  138.     return true;  
  139. }  
  140.   
  141. void ColorShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND hwnd, WCHAR* shaderFilename)  
  142. {  
  143.     char* compileErrors;  
  144.     unsigned long bufferSize, i;  
  145.     ofstream fout;  
  146.   
  147.   
  148.     // 获取指向错误信息文本的指针  
  149.     compileErrors = (char*)(errorMessage->GetBufferPointer());  
  150.   
  151.     // 获取错误信息文本的长度  
  152.     bufferSize = errorMessage->GetBufferSize();  
  153.   
  154.     // 创建一个txt,用于写入错误信息  
  155.     fout.open("shader-error.txt");  
  156.   
  157.     //想txt文件写入错误信息  
  158.     for (i = 0; i<bufferSize; i++)  
  159.     {  
  160.         fout << compileErrors[i];  
  161.     }  
  162.   
  163.     // 关闭文件  
  164.     fout.close();  
  165.   
  166.     // Release the error message.  
  167.     errorMessage->Release();  
  168.     errorMessage = 0;  
  169.   
  170.     //弹出提醒的小窗口  
  171.     MessageBox(hwnd, L"Error compiling shader.  Check shader-error.txt for message.", shaderFilename, MB_OK);  
  172.   
  173. }  
  174.   
  175.   
  176. bool ColorShaderClass::SetShaderParameter(ID3D11DeviceContext* d3dDeviceContext, CXMMATRIX worldMatrix, CXMMATRIX viewMatrix, CXMMATRIX ProjMatrix)  
  177. {  
  178.     //D3D11_MAPPED_SUBRESOURCE mappedResource;  
  179.       
  180.   
  181.     //CBMatrix* cbPtr;  
  182.     unsigned int bufferNum;  
  183.   
  184.     //将矩阵转置,在传入常量缓存前进行转置,因为GPU对矩阵数据会自动进行一次转置  
  185.     CBMatrix cb;  
  186.     XMMATRIX worldMa = XMMatrixTranspose(worldMatrix);  
  187.     XMMATRIX viewMa = XMMatrixTranspose(viewMatrix);  
  188.     XMMATRIX ProjMa = XMMatrixTranspose(ProjMatrix);  
  189.     cb.mWorldMatrix = worldMa;  
  190.     cb.mViewMatrix = viewMa;  
  191.     cb.mProjMatrix = ProjMa;  
  192.     d3dDeviceContext->UpdateSubresource(mCBMatrixBuffer, 0, NULL, &cb, 0, 0);  
  193.     /**/  
  194.     //锁定常量缓存,这时候常量缓存和子资源关联在一起  
  195.     //HR2(d3dDeviceContext->Map(mCBMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));  
  196.   
  197.     //获取指向常量缓存数据的指针  
  198.     //cbPtr = (CBMatrix*)mappedResource.pData;  
  199.   
  200.     //赋予常量缓存数据  
  201.     //cbPtr->mProjMatrix = worldMa;  
  202.     //cbPtr->mViewMatrix = viewMa;  
  203.     //cbPtr->mProjMatrix = ProjMa;  
  204.   
  205.     //解锁常量缓存  
  206.     //d3dDeviceContext->Unmap(mCBMatrixBuffer, 0);  
  207.       
  208.     //设置在顶点缓存中常量缓存的位置,注册号  
  209.     bufferNum = 0;  
  210.   
  211.     //设置在VertexShader的常量缓存的值(带着更新的值)  
  212.     d3dDeviceContext->VSSetConstantBuffers(bufferNum, 1, &mCBMatrixBuffer);   
  213.   
  214.     return true;  
  215. }  
  216.   
  217. void ColorShaderClass::RenderShader(ID3D11DeviceContext* deviceContext, int indexCount)  
  218. {  
  219.     //设置顶点输入布局  
  220.     deviceContext->IASetInputLayout(md3dInputLayout);  
  221.   
  222.     //设置VertexShader和PixelShader  
  223.     deviceContext->VSSetShader(md3dVertexShader, NULL, 0);  
  224.     deviceContext->PSSetShader(md3dPixelShader, NULL, 0);  
  225.   
  226.     //渲染三角形  
  227.     deviceContext->DrawIndexed(indexCount, 0, 0);  
  228. }  



(3) ModelClass


ModelClass.h(用于加载顶点缓存和索引缓存)

[cpp] view plain copy
  1. #pragma once  
  2. #ifndef _MODEL_CLASS_H  
  3. #define _MODEL_CLASS_H  
  4.   
  5. #include<d3d11.h>  
  6. #include<xnamath.h>  
  7. #define HR1(X) {if(FAILED(X)) { MessageBox(0,L"Create Failed",0,0); return false;}}  
  8. #define ReleaseCOM1(x) { if (x) { x->Release(); x = 0; } }  
  9.   
  10. class ModelClass  
  11. {  
  12. private:  
  13.     struct Vertex  
  14.     {  
  15.         XMFLOAT3 pos;  
  16.         XMFLOAT4 color;  
  17.     };  
  18. private:  
  19.     ID3D11Buffer* md3dVertexBuffer; //顶点缓存  
  20.     ID3D11Buffer* md3dIndexBuffer;  //索引缓存  
  21.     int mVertexCount;  
  22.     int mIndexCount;  
  23.   
  24. private:  
  25.     bool InitializeBuffer(ID3D11Device* d3dDevice);  
  26.     void ShutdownBuffer();  
  27.     void RenderBuffers(ID3D11DeviceContext* d3dDeviceContext);  
  28.   
  29. public:  
  30.     ModelClass();  
  31.     ModelClass(const ModelClass&);  
  32.     ~ModelClass();  
  33.   
  34. public:  
  35.     //Initialize是创建元素,Render是设置元素,Shutdown是Release  
  36.     bool Initialize(ID3D11Device* d3dDevice);  
  37.     void Shutdown();  
  38.     void Render(ID3D11DeviceContext* d3dDeviceContext);  
  39.   
  40.     int GetIndexCount() { return mIndexCount; }  
  41.   
  42. };  
  43. #endif   


ModelClass.CPP

[cpp] view plain copy
  1. #include"ModelClass.h"  
  2.   
  3. ModelClass::ModelClass()  
  4. {  
  5.     md3dVertexBuffer=NULL; //顶点缓存  
  6.     md3dIndexBuffer=NULL;  //索引缓存  
  7.     mVertexCount = 0;  
  8.     mIndexCount = 0;  
  9.   
  10. }  
  11.   
  12.   
  13. ModelClass::ModelClass(const ModelClass& other)  
  14. {  
  15.   
  16. }  
  17.   
  18. ModelClass::~ModelClass()  
  19. {  
  20.   
  21. }  
  22.   
  23. bool ModelClass::Initialize(ID3D11Device* d3dDevice)  
  24. {  
  25.     bool result;  
  26.     result = InitializeBuffer(d3dDevice);  
  27.   
  28.     if (!result)  
  29.         return false;  
  30.   
  31.         return true;  
  32. }  
  33.   
  34. void ModelClass::Shutdown()  
  35. {  
  36.     ShutdownBuffer();  
  37. }  
  38.   
  39.   
  40. void ModelClass::Render(ID3D11DeviceContext* d3dDeviceContext)  
  41. {  
  42.     //设置渲染管线的顶点缓存和索引缓存(IA阶段)  
  43.     RenderBuffers(d3dDeviceContext);  
  44. }  
  45.   
  46. bool ModelClass::InitializeBuffer(ID3D11Device* d3dDevice)  
  47. {  
  48.     Vertex* vertexs=NULL;  
  49.     WORD*indices=NULL;  //一个字为两个字节   
  50.   
  51.     mVertexCount = 4;  
  52.     mIndexCount = 6;  
  53.   
  54.     //创建顶点数组  
  55.     vertexs = new Vertex[mVertexCount];  
  56.     if (!vertexs)  
  57.         return false;  
  58.   
  59.     //创建索引数组  
  60.     indices = new WORD[mIndexCount];  
  61.     if (!indices)  
  62.         return false;  
  63.       
  64.     //赋予顶点数组数据和索引数组数据  
  65.     vertexs[0].pos = XMFLOAT3(-1.0f, -1.0f, 0.0f);  
  66.     vertexs[0].color = XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f);  
  67.     vertexs[1].pos = XMFLOAT3(1.0f, 1.0f, 0.0f);  
  68.     vertexs[1].color = XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f);  
  69.     vertexs[2].pos = XMFLOAT3(1.0f, -1.0f, 0.0f);  
  70.     vertexs[2].color = XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f);  
  71.     vertexs[3].pos = XMFLOAT3(-1.0f, 1.0f, 0.0f);  
  72.     vertexs[3].color = XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f);  
  73.     //赋予索引数组数据  
  74.   
  75.     //注意用左手定则判定是不是背面  
  76.     indices[0] = 0;  
  77.     indices[1] = 3;  
  78.     indices[2] = 2;  
  79.     indices[3] = 1;  
  80.     indices[4] = 2;  
  81.     indices[5] = 3;  
  82.   
  83.   
  84.     //第一,填充(顶点)缓存形容结构体和子资源数据结构体,并创建顶点缓存  
  85.     D3D11_BUFFER_DESC vertexBufferDesc;  
  86.     vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;  
  87.     vertexBufferDesc.ByteWidth = sizeof(Vertex) * mVertexCount;  
  88.     vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;  
  89.     vertexBufferDesc.CPUAccessFlags = 0;  
  90.     vertexBufferDesc.MiscFlags = 0;  
  91.     vertexBufferDesc.StructureByteStride = 0;  
  92.   
  93.     D3D11_SUBRESOURCE_DATA vertexData;  
  94.     vertexData.pSysMem = vertexs;  
  95.     vertexData.SysMemPitch = 0;  
  96.     vertexData.SysMemSlicePitch = 0;  
  97.     HR1(d3dDevice->CreateBuffer(&vertexBufferDesc, &vertexData, &md3dVertexBuffer));  
  98.   
  99.     //第二,填充(索引)缓存形容结构体和子资源数据结构体,并创建索引缓存  
  100.     D3D11_BUFFER_DESC  indexBufferDesc;  
  101.     indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;  
  102.     indexBufferDesc.ByteWidth = sizeof(WORD) * mIndexCount;  
  103.     indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;  
  104.     indexBufferDesc.CPUAccessFlags = 0;  
  105.     indexBufferDesc.MiscFlags = 0;  
  106.     indexBufferDesc.StructureByteStride = 0;  
  107.   
  108.     D3D11_SUBRESOURCE_DATA indexData;  
  109.     indexData.pSysMem = indices;  
  110.     indexData.SysMemPitch = 0;  
  111.     indexData.SysMemSlicePitch = 0;  
  112.     HR1(d3dDevice->CreateBuffer(&indexBufferDesc, &indexData, &md3dIndexBuffer));  
  113.   
  114.     //释放顶点数组和索引数组(这时数据已经载入缓存,不需要这些数组了)  
  115.     delete[]vertexs;  
  116.     vertexs = NULL;  
  117.     delete[]indices;  
  118.     indices = NULL;  
  119.       
  120.     return true;  
  121. }  
  122.   
  123. void ModelClass::ShutdownBuffer()  
  124. {  
  125.     //释放顶点缓存和索引缓存  
  126.     ReleaseCOM1(md3dIndexBuffer);  
  127.     ReleaseCOM1(md3dVertexBuffer);  
  128. }  
  129.   
  130. void ModelClass::RenderBuffers(ID3D11DeviceContext* d3dDeviceContext)  
  131. {  
  132.     //设置顶点缓存  
  133.     UINT stride = sizeof(Vertex); //每个顶点元素的跨度大小,或者说每个顶点元素的大小  
  134.     UINT offset = 0;  
  135.     d3dDeviceContext->IASetVertexBuffers(0, 1, &md3dVertexBuffer, &stride, &offset);  
  136.   
  137.     //设置索引缓存  
  138.     d3dDeviceContext->IASetIndexBuffer(md3dIndexBuffer, DXGI_FORMAT_R16_UINT, 0); //Word为两个字节  
  139.   
  140.     //设置拓扑方式  
  141.     d3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);  
  142. }  


四,本节教程的程序得注意的地方:

(1)在一个.h文件里包含XNAMATH.h一定得先包含一个windows.h。

(2)XMMATRIX作为函数参数时应该用CXMMATRIX。

(3)指定顶点的索引值时得注意绕线方向,用左手定则,得到三角形法线方向跟相机LookAt方向为钝角的被正面,反之为背面.

(4)我的VertexShader和PixelShader都在从MyShader.fx文件中编译的,其实.HLSL文件.VS文件.PS文件.FX文件都能编译成Shader

(5)在.FX文件中常量缓存CBMatrix注意用register()注册,注册为b0,则在ColorShaderClass::SetShaderParameter()的d3dDeviceContext->VSSetConstantBuffers(bufferNum, 1, &mCBMatrixBuffer)的bufferNum为0,若注册为b1,则bufferNum为1,以此类推.

(6)在VertexShader阶段和PixelShade阶段,常量缓存的值一直未曾改变,不会进行光栅化,因此世界空间的平行光,聚光灯,点光源都是采用常量缓存。

(7)在对应与常量缓存的结构体一定是16个字节的倍数,XMMATRIX为64个字节,float为4个字节,实在要是怕忘记16字节对齐规则,可在结构体前加个前缀,__declspec(align(16))  ,比如

[html] view plain copy
  1. __declspec(align(16))    
  2. struct CbNeverChange   //常量缓存结构严格16字节的倍数  
  3. {  
  4.     DirectionLight DireLight;  
  5.     PointLight PoLight;  
  6.     SpotLight SpLight;  
  7.     Material SkullMaterial;  
  8.     XMFLOAT3 EyePostion;  
  9. };  


五,本节教程的程序运行的结果:




六,程序源代码链接如下

点击打开链接

原创粉丝点击