【Visual C 】游戏开发笔记二十九 一步一步教你用优雅的DirectD代码画一个三角形_第1页
【Visual C 】游戏开发笔记二十九 一步一步教你用优雅的DirectD代码画一个三角形_第2页
【Visual C 】游戏开发笔记二十九 一步一步教你用优雅的DirectD代码画一个三角形_第3页
【Visual C 】游戏开发笔记二十九 一步一步教你用优雅的DirectD代码画一个三角形_第4页
【Visual C 】游戏开发笔记二十九 一步一步教你用优雅的DirectD代码画一个三角形_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 HYPERLINK /zhmxy555/article/details/7774929 【Visual C+】游戏开发笔记二十九 一步一步教你用优雅的Direct3D11代码画一个三角形本系列文章由zhmxy555(毛星云)编写,转载请注明出处。 HYPERLINK /zhmxy555/article/details/7774929 /zhmxy555/article/details/7774929作者:毛星云 邮箱: happylifemxy 这个demo演示的效果是用Direct3D11在屏幕上渲染一个三角形,当然是通过这个demo进一步巩固和学习Direct3D11,而不是单单为了画一

2、个三角形这么简单。正如之前所说,这个demo是建立在笔记二十八中讲解的D3D BlankWindows Demo之上的。那么,我们就开门见山,直入正题吧。一、 载入几何体我们知道,为了渲染几何图形,我们需要一个顶点缓存,一个描述顶点布局的输入层,以及一系列的着色器,自DirectX10以来,着色器开始作为图形渲染的基础组成部分,在这个demo之中我们会指定顶点着色器与像素着色器,渲染一种简单的纯色表面。后面我们将延伸的讲解如何拓展使用这种效果来在表面映射图形纹理。下面就开始进行这个demo的书写:这个demo的核心内容当然是一个叫做TriangleDemo的类,我们为这个类定义几个成员变量,他

3、们分别是ID3D11VertexShader类型的取名为solidColorVS_的变量,一个ID3D11PixelShader类型的唤作solidColorPS的变量。一个ID3D11InputLayout类型的唤作inputLayout_的变量,以及一个ID3D11Buffer类型的叫做vertexBuffer_的变量。下面就是TriangleDemo.h头文件的源代码,简单的勾勒出了本文主角TriangleDemo类的轮廓:代码段一 TriangleDemo.h头文件cpp HYPERLINK /zhmxy555/article/details/7774929 o view plain

4、view plain HYPERLINK /zhmxy555/article/details/7774929 o copy copy HYPERLINK /zhmxy555/article/details/7774929 o print print HYPERLINK /zhmxy555/article/details/7774929 o ? ?#includeDx11DemoBase.hclassTriangleDemo:publicDx11DemoBasepublic:TriangleDemo();virtualTriangleDemo();boolLoadContent();voidUn

5、loadContent();voidUpdate(floatdt);voidRender();private:ID3D11VertexShader*solidColorVS_;ID3D11PixelShader*solidColorPS_;ID3D11InputLayout*inputLayout_;ID3D11Buffer*vertexBuffer_;顶点我们采用一个简单的三分量式的浮点型结构体,在XNA Math library中一个叫做XMFLOAT3的结构体可以胜任这项殊荣。接下来,开始丰富我们的TriangleDemo类,我们在代码段二中书写顶点结构体VertexPos和Triang

6、leDemo的类的构造函数以及析构函数代码段二 TriangleDemo 顶点结构体, 构造函数和析构函数.cpp HYPERLINK /zhmxy555/article/details/7774929 o view plain view plain HYPERLINK /zhmxy555/article/details/7774929 o copy copy HYPERLINK /zhmxy555/article/details/7774929 o print print HYPERLINK /zhmxy555/article/details/7774929 o ? ?#includeTri

7、angleDemo.h#includestructVertexPosXMFLOAT3pos;TriangleDemo:TriangleDemo():solidColorVS_(0),solidColorPS_(0),inputLayout_(0),vertexBuffer_(0)TriangleDemo:TriangleDemo()下面继续丰富我们的TriangleDemo类,在代码段三中我们进行UnloadContent函数的书写,顾名思义,UnloadContent是进行unload content工作的,与后面将书写的LoadContent函数相对应。代码段三 TriangleDemo类

8、的UnloadContent函数的书写cpp HYPERLINK /zhmxy555/article/details/7774929 o view plain view plain HYPERLINK /zhmxy555/article/details/7774929 o copy copy HYPERLINK /zhmxy555/article/details/7774929 o print print HYPERLINK /zhmxy555/article/details/7774929 o ? ?voidTriangleDemo:UnloadContent()if(solidColorV

9、S_)solidColorVS_-Release();if(solidColorPS_)solidColorPS_-Release();if(inputLayout_)inputLayout_-Release();if(vertexBuffer_)vertexBuffer_-Release();solidColorVS_=0;solidColorPS_=0;inputLayout_=0;vertexBuffer_=0;顺理成章的,下一步便是LoadContent函数的书写。这个函数由顶点着色器载入,在文件SolidGreenColor.fx中可以查看。一旦顶点着色器的源代码编译完成,着色器便创

10、建一个CreateVertexShader函数的调用,我们接着创建顶点格式。由于顶点着色器与顶点格式相关联,所以我们还需要将顶点着色器加载到内存中。创建完顶点着色器和输入格式后,下一步我们创建像素着色器。下面这段代码实现了LoadContent方法的一半的功能:代码段四 LoadContent函数着色器载入代码cpp HYPERLINK /zhmxy555/article/details/7774929 o view plain view plain HYPERLINK /zhmxy555/article/details/7774929 o copy copy HYPERLINK /zhmxy

11、555/article/details/7774929 o print print HYPERLINK /zhmxy555/article/details/7774929 o ? ?boolTriangleDemo:LoadContent()ID3DBlob*vsBuffer=0;boolcompileResult=CompileD3DShader(SolidGreenColor.fx,VS_Main,vs_4_0,&vsBuffer);if(compileResult=false)MessageBox(0,载入顶点着色器错误!,编译错误,MB_OK);returnfalse;HRESULTd

12、3dResult;d3dResult=d3dDevice_-CreateVertexShader(vsBuffer-GetBufferPointer(),vsBuffer-GetBufferSize(),0,&solidColorVS_);if(FAILED(d3dResult)if(vsBuffer)vsBuffer-Release();returnfalse;D3D11_INPUT_ELEMENT_DESCsolidColorLayout=POSITION,0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0;uns

13、ignedinttotalLayoutElements=ARRAYSIZE(solidColorLayout);d3dResult=d3dDevice_-CreateInputLayout(solidColorLayout,totalLayoutElements,vsBuffer-GetBufferPointer(),vsBuffer-GetBufferSize(),&inputLayout_);vsBuffer-Release();if(FAILED(d3dResult)returnfalse;ID3DBlob*psBuffer=0;compileResult=CompileD3DShade

14、r(SolidGreenColor.fx,PS_Main,ps_4_0,&psBuffer);if(compileResult=false)MessageBox(0,载入像素着色器错误!,编译错误,MB_OK);returnfalse;d3dResult=d3dDevice_-CreatePixelShader(psBuffer-GetBufferPointer(),psBuffer-GetBufferSize(),0,&solidColorPS_);psBuffer-Release();if(FAILED(d3dResult)returnfalse;./后接函数的下半段CompileD3DS

15、hader相关的代码在代码段五中进行了演绎,这段代码巧妙地被分离于LoadContent之外,这样在加载多个不同的着色效果的时候便可以避免大段大段的冗余代码:代码段五 CompileShader 函数的实现方法cpp HYPERLINK /zhmxy555/article/details/7774929 o view plain view plain HYPERLINK /zhmxy555/article/details/7774929 o copy copy HYPERLINK /zhmxy555/article/details/7774929 o print print HYPERLINK

16、 /zhmxy555/article/details/7774929 o ? ?boolDx11DemoBase:CompileD3DShader(char*filePath,char*entry,char*shaderModel,ID3DBlob*buffer)DWORDshaderFlags=D3DCOMPILE_ENABLE_STRICTNESS;#ifdefined(DEBUG)|defined(_DEBUG)shaderFlags|=D3DCOMPILE_DEBUG;#endifID3DBlob*errorBuffer=0;HRESULTresult;result=D3DX11Com

17、pileFromFile(filePath,0,0,entry,shaderModel,shaderFlags,0,0,buffer,&errorBuffer,0);if(FAILED(result)if(errorBuffer!=0)OutputDebugStringA(char*)errorBuffer-GetBufferPointer();errorBuffer-Release();returnfalse;if(errorBuffer!=0)errorBuffer-Release();returntrue;上面我们介绍了上半段LoadContent函数的构成,而下半段LoadConten

18、t函数主要实现了顶点缓存的创建。这段代码行文思路很明朗,首先定义一个简单的三角形,沿X轴与Y轴都是0.5f(半个单位的长度)。Z轴依然设为为0.5f,来使此三角形可见。因为若镜头隔表面太近或者太远,表面都不会成功的渲染。顶点列表存储于一个叫做vertices的数组中,它提供了一个子资源数据,在CreateBuffer函数开始调用进行实际顶点缓存的创建的时候,这些数据可以派上用场。下面就是上面这段叙述的代码实现,LoadContent函数的下半部分书写风格如下:代码段六 LoadContent函数的几何图形载入代码cpp HYPERLINK /zhmxy555/article/details/7

19、774929 o view plain view plain HYPERLINK /zhmxy555/article/details/7774929 o copy copy HYPERLINK /zhmxy555/article/details/7774929 o print print HYPERLINK /zhmxy555/article/details/7774929 o ? ?boolTriangleDemo:LoadContent()/前接函数的上半段.VertexPosvertices=XMFLOAT3(0.5f,0.5f,0.5f),XMFLOAT3(0.5f,-0.5f,0.5

20、f),XMFLOAT3(-0.5f,-0.5f,0.5f);D3D11_BUFFER_DESCvertexDesc;ZeroMemory(&vertexDesc,sizeof(vertexDesc);vertexDesc.Usage=D3D11_USAGE_DEFAULT;vertexDesc.BindFlags=D3D11_BIND_VERTEX_BUFFER;vertexDesc.ByteWidth=sizeof(VertexPos)*3;D3D11_SUBRESOURCE_DATAresourceData;ZeroMemory(&resourceData,sizeof(resourceD

21、ata);resourceData.pSysMem=vertices;d3dResult=d3dDevice_-CreateBuffer(&vertexDesc,&resourceData,&vertexBuffer_);if(FAILED(d3dResult)returnfalse;returntrue;二、渲染几何体Direct11三角形Demo代码的最后两部分由实现几何渲染功能的代码和着色器本身构成。渲染几何图形的构成代码在TriangleDemo类中的Render函数中进行。函数中有有一个条件语句,这样可以确保在Direct3D的上下文是有效的。接下来,我们清除渲染目标,并设定输出程序

22、集(input assembler)。而实际上,因为在这个demo之中的三角形是静态的,我们并不一定非要清除渲染目标,这里只是为了规范我们的代码书写,以免养成不良的开发习惯。在输出程序集阶段的设置由我们已经创建的输出结构(input layout)进行绑定,并提供顶点缓存,设置拓扑三角形的列表。下面贴出Render函数的书写思路:代码段七 TriangleDemo类的render函数书写cpp HYPERLINK /zhmxy555/article/details/7774929 o view plain view plain HYPERLINK /zhmxy555/article/detai

23、ls/7774929 o copy copy HYPERLINK /zhmxy555/article/details/7774929 o print print HYPERLINK /zhmxy555/article/details/7774929 o ? ?voidTriangleDemo:Render()if(d3dContext_=0)return;floatclearColor4=0.5,0.5f,0.5f,1.0f;/设定背景颜色d3dContext_-ClearRenderTargetView(backBufferTarget_,clearColor);unsignedintstr

24、ide=sizeof(VertexPos);unsignedintoffset=0;d3dContext_-IASetInputLayout(inputLayout_);d3dContext_-IASetVertexBuffers(0,1,&vertexBuffer_,&stride,&offset);d3dContext_-IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);d3dContext_-VSSetShader(solidColorVS_,0,0);d3dContext_-PSSetShader(solidCo

25、lorPS_,0,0);d3dContext_-Draw(3,0);swapChain_-Present(0,0);最后一部分要介绍的代码是着色器。笼统的来说,顶点着色器基于它得到的内容。详细的来说,顶点着色器的作用是将内部得到的顶点位置传递到输出处,之后,我们须处理这些数据,正确绘制出我们的图形。但对于这个非常基础的demo,仅仅进行顶点位置内容的传递就够了。如果没有几何图形着色器绑定到输出程序集之上,顶点着色器的输出的数据就是像素着色器的输入的数据。其中,像素着色器的输出就是写到输出缓存之中的颜色值。当交换链中的Present函数调用的时候,这个缓存就会最终显示给用户。TriangleDe

26、mo的顶点着色器和像素着色器的书写方法如下代码段八:代码段八 Triangledemo着色器的实现代码cpp HYPERLINK /zhmxy555/article/details/7774929 o view plain view plain HYPERLINK /zhmxy555/article/details/7774929 o copy copy HYPERLINK /zhmxy555/article/details/7774929 o print print HYPERLINK /zhmxy555/article/details/7774929 o ? ?float4VS_Main(

27、float4pos:POSITION):SV_POSITIONreturnpos;float4PS_Main(float4pos:SV_POSITION):SV_TARGETreturnfloat4(0.0f,1.0f,0.0f,1.0f);这样,Triangledemo类就随着一步一步的勾勒,被我们书写完成了。三、Dx11DemoBase类的书写接下来,我们将之前讲解的BlankD3DWindows Demo模板中的Dx11DemoBase类进行丰富和修改,即可得到适用于本节demo的Dx11DemoBase类。代码段九 Dx11DemoBase.hcpp HYPERLINK /zhmxy5

28、55/article/details/7774929 o view plain view plain HYPERLINK /zhmxy555/article/details/7774929 o copy copy HYPERLINK /zhmxy555/article/details/7774929 o print print HYPERLINK /zhmxy555/article/details/7774929 o ? ?#ifndef_DEMO_BASE_H_#define_DEMO_BASE_H_#include#include#includeclassDx11DemoBasepubli

29、c:Dx11DemoBase();virtualDx11DemoBase();boolInitialize(HINSTANCEhInstance,HWNDhwnd);voidShutdown();boolCompileD3DShader(char*filePath,char*entry,char*shaderModel,ID3DBlob*buffer);virtualboolLoadContent();virtualvoidUnloadContent();virtualvoidUpdate(floatdt)=0;virtualvoidRender()=0;protected:HINSTANCE

30、hInstance_;HWNDhwnd_;D3D_DRIVER_TYPEdriverType_;D3D_FEATURE_LEVELfeatureLevel_;ID3D11Device*d3dDevice_;ID3D11DeviceContext*d3dContext_;IDXGISwapChain*swapChain_;ID3D11RenderTargetView*backBufferTarget_;#endif代码段十 Dx11DemoBase.cppcpp HYPERLINK /zhmxy555/article/details/7774929 o view plain view plain

31、 HYPERLINK /zhmxy555/article/details/7774929 o copy copy HYPERLINK /zhmxy555/article/details/7774929 o print print HYPERLINK /zhmxy555/article/details/7774929 o ? ?#includeDx11DemoBase.h#includeDx11DemoBase:Dx11DemoBase():driverType_(D3D_DRIVER_TYPE_NULL),featureLevel_(D3D_FEATURE_LEVEL_11_0),d3dDev

32、ice_(0),d3dContext_(0),swapChain_(0),backBufferTarget_(0)Dx11DemoBase:Dx11DemoBase()Shutdown();boolDx11DemoBase:Initialize(HINSTANCEhInstance,HWNDhwnd)hInstance_=hInstance;hwnd_=hwnd;RECTdimensions;GetClientRect(hwnd,&dimensions);unsignedintwidth=dimensions.right-dimensions.left;unsignedintheight=di

33、mensions.bottom-dimensions.top;D3D_DRIVER_TYPEdriverTypes=D3D_DRIVER_TYPE_HARDWARE,D3D_DRIVER_TYPE_WARP,D3D_DRIVER_TYPE_REFERENCE,D3D_DRIVER_TYPE_SOFTWARE;unsignedinttotalDriverTypes=ARRAYSIZE(driverTypes);D3D_FEATURE_LEVELfeatureLevels=D3D_FEATURE_LEVEL_11_0,D3D_FEATURE_LEVEL_10_1,D3D_FEATURE_LEVEL

34、_10_0;unsignedinttotalFeatureLevels=ARRAYSIZE(featureLevels);DXGI_SWAP_CHAIN_DESCswapChainDesc;ZeroMemory(&swapChainDesc,sizeof(swapChainDesc);swapChainDesc.BufferCount=1;swapChainDesc.BufferDesc.Width=width;swapChainDesc.BufferDesc.Height=height;swapChainDesc.BufferDesc.Format=DXGI_FORMAT_R8G8B8A8_

35、UNORM;swapChainDesc.BufferDesc.RefreshRate.Numerator=60;swapChainDesc.BufferDesc.RefreshRate.Denominator=1;swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;swapChainDesc.OutputWindow=hwnd;swapChainDesc.Windowed=true;swapChainDesc.SampleDesc.Count=1;swapChainDesc.SampleDesc.Quality=0;unsigne

36、dintcreationFlags=0;#ifdef_DEBUGcreationFlags|=D3D11_CREATE_DEVICE_DEBUG;#endifHRESULTresult;unsignedintdriver=0;for(driver=0;driverGetBuffer(0,_uuidof(ID3D11Texture2D),(LPVOID*)&backBufferTexture);if(FAILED(result)DXTRACE_MSG(获取交换链后台缓存失败!);returnfalse;result=d3dDevice_-CreateRenderTargetView(backBu

37、fferTexture,0,&backBufferTarget_);if(backBufferTexture)backBufferTexture-Release();if(FAILED(result)DXTRACE_MSG(创建渲染目标视图失败!);returnfalse;d3dContext_-OMSetRenderTargets(1,&backBufferTarget_,0);D3D11_VIEWPORTviewport;viewport.Width=static_cast(width);viewport.Height=static_cast(height);viewport.MinDep

38、th=0.0f;viewport.MaxDepth=1.0f;viewport.TopLeftX=0.0f;viewport.TopLeftY=0.0f;d3dContext_-RSSetViewports(1,&viewport);returnLoadContent();boolDx11DemoBase:CompileD3DShader(char*filePath,char*entry,char*shaderModel,ID3DBlob*buffer)DWORDshaderFlags=D3DCOMPILE_ENABLE_STRICTNESS;#ifdefined(DEBUG)|defined

39、(_DEBUG)shaderFlags|=D3DCOMPILE_DEBUG;#endifID3DBlob*errorBuffer=0;HRESULTresult;result=D3DX11CompileFromFile(filePath,0,0,entry,shaderModel,shaderFlags,0,0,buffer,&errorBuffer,0);if(FAILED(result)if(errorBuffer!=0)OutputDebugStringA(char*)errorBuffer-GetBufferPointer();errorBuffer-Release();returnf

40、alse;if(errorBuffer!=0)errorBuffer-Release();returntrue;boolDx11DemoBase:LoadContent()/进行相关重载returntrue;voidDx11DemoBase:UnloadContent()/进行相关重载voidDx11DemoBase:Shutdown()UnloadContent();if(backBufferTarget_)backBufferTarget_-Release();if(swapChain_)swapChain_-Release();if(d3dContext_)d3dContext_-Rel

41、ease();if(d3dDevice_)d3dDevice_-Release();backBufferTarget_=0;swapChain_=0;d3dContext_=0;d3dDevice_=0;四、 赋予程序生命wWinMain函数的书写最后一步,依旧是主函数的书写,这个函数大家应该是最熟悉的,任何想顺利运行的C/C+程序中必不可少,而且这里的书写方式和前面demo中的也大同小异,浅墨在这里就不多赘言了,代码如下:代码段十一 wWinMain函数的书写cpp HYPERLINK /zhmxy555/article/details/7774929 o view plain view p

42、lain HYPERLINK /zhmxy555/article/details/7774929 o copy copy HYPERLINK /zhmxy555/article/details/7774929 o print print HYPERLINK /zhmxy555/article/details/7774929 o ? ?#include#include#includeTriangleDemo.hLRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam);intWINAPIwWinMain(HINST

43、ANCEhInstance,HINSTANCEprevInstance,LPWSTRcmdLine,intcmdShow)UNREFERENCED_PARAMETER(prevInstance);UNREFERENCED_PARAMETER(cmdLine);WNDCLASSEXwndClass=0;wndClass.cbSize=sizeof(WNDCLASSEX);wndClass.style=CS_HREDRAW|CS_VREDRAW;wndClass.lpfnWndProc=WndProc;wndClass.hInstance=hInstance;wndClass.hCursor=LoadCursor(NULL,IDC_ARROW);wndClass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);wndClass.lpszMenuName=NULL;wndClass.lpszClassName=DX11BookWindowClass;if(!RegisterClassEx(&wndClass)return-1;RECTrc=0,0,640,480;AdjustWindowRect(&rc,WS_OVERLAPPEDWINDO

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论