这篇是作为学习笔记之用,详细代码在Introduction to 3D Game Programming with Directx10里面的扉页,有个网址 www.d3dcoder.net 里面可以下载
这个程序的效果是:
这个demo展示了基本的directx基本的渲染流程.
首先是渲染管线: 它的作用是根据虚拟摄像机视角生成2D图像的基本步骤.
主要是类为ColoredCubeApp
class ColoredCubeApp : public D3DApp { public: ColoredCubeApp(HINSTANCE hInstance); ~ColoredCubeApp(); void initApp(); //初始化 void onResize(); //窗口大小变化时候调用 void updateScene(float dt); //每一帧调用,负责更新参数 void drawScene(); //每一帧调用,负责绘制 private: void buildFX(); //着色器 void buildVertexLayouts(); //输入汇编器,构建图元 private: Box mBox; ID3D10Effect* mFX; ID3D10EffectTechnique* mTech; ID3D10InputLayout* mVertexLayout; ID3D10EffectMatrixVariable* mfxWVPVar; D3DXMATRIX mView; D3DXMATRIX mProj; D3DXMATRIX mWVP; float mTheta; float mPhi; };
这个类中的initAPP()为初始化渲染做准备
void ColoredCubeApp::initApp() { D3DApp::initApp(); mBox.init(md3dDevice, 0.3f); //这个是所要创建立方体的初始化。 提供了顶点缓冲区,和索引缓冲区 buildFX(); //这个是顶点着色器、几何着色器、像素着色器的配置 buildVertexLayouts();//根据以上信息构建图元 }
下面看具体mBox.init是怎么初始化立方体的 void Box::init(ID3D10Device* device, float scale) { md3dDevice = device; mNumVertices = 8; mNumFaces = 12; // 2 per quad // Create vertex buffer Vertex vertices[] = { {D3DXVECTOR3(-1.0f, -1.0f, -1.0f), WHITE}, {D3DXVECTOR3(-1.0f, +1.0f, -1.0f), BLACK}, {D3DXVECTOR3(+1.0f, +1.0f, -1.0f), RED}, {D3DXVECTOR3(+1.0f, -1.0f, -1.0f), GREEN}, {D3DXVECTOR3(-1.0f, -1.0f, +1.0f), BLUE}, {D3DXVECTOR3(-1.0f, +1.0f, +1.0f), YELLOW}, {D3DXVECTOR3(+1.0f, +1.0f, +1.0f), CYAN}, {D3DXVECTOR3(+1.0f, -1.0f, +1.0f), MAGENTA}, }; // Scale the box. for(DWORD i = 0; i < mNumVertices; ++i) vertices[i].pos *= scale; //顶点缓冲区 D3D10_BUFFER_DESC vbd; vbd.Usage = D3D10_USAGE_IMMUTABLE; vbd.ByteWidth = sizeof(Vertex) * mNumVertices; vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER; vbd.CPUAccessFlags = 0; vbd.MiscFlags = 0; D3D10_SUBRESOURCE_DATA vinitData; vinitData.pSysMem = vertices; HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mVB)); // Create the index buffer //索引缓冲区 DWORD indices[] = { // front face 0, 1, 2, 0, 2, 3, // back face 4, 6, 5, 4, 7, 6, // left face 4, 5, 1, 4, 1, 0, // right face 3, 2, 6, 3, 6, 7, // top face 1, 5, 6, 1, 6, 2, // bottom face 4, 0, 3, 4, 3, 7 }; D3D10_BUFFER_DESC ibd; ibd.Usage = D3D10_USAGE_IMMUTABLE; ibd.ByteWidth = sizeof(DWORD) * mNumFaces*3; ibd.BindFlags = D3D10_BIND_INDEX_BUFFER; ibd.CPUAccessFlags = 0; ibd.MiscFlags = 0; D3D10_SUBRESOURCE_DATA iinitData; iinitData.pSysMem = indices; HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mIB)); }
从以上可知,主要作用就是先构建所需要的不重复的点,然后构建一个立方体索引点(索引是为了节约资源,不必再重复构建点)。
下面看buildFX() 里面的内容
hr = D3DX10CreateEffectFromFile(L"color.fx", 0, 0,
"fx_4_0",shaderFlags, 0, md3dDevice,0, 0, &mFX, &compilationErrors,0);
主要为这一句。
其中color.fx 是一个文本文件
//============================================================================= // color.fx by Frank Luna (C) 2008 All Rights Reserved. // // Transforms and colors geometry. //============================================================================= cbuffer cbPerObject { float4x4 gWVP; }; void VS(float3 iPosL : POSITION, float4 iColor : COLOR, out float4 oPosH : SV_POSITION, out float4 oColor : COLOR) { // Transform to homogeneous clip space. oPosH = mul(float4(iPosL, 1.0f), gWVP); // Just pass vertex color into the pixel shader. oColor = iColor; } float4 PS(float4 posH : SV_POSITION, float4 color : COLOR) : SV_Target { return color; } technique10 ColorTech { pass P0 { SetVertexShader( CompileShader( vs_4_0, VS() ) ); SetGeometryShader( NULL ); SetPixelShader( CompileShader( ps_4_0, PS() ) ); } }
以上可以看成类c++的文件,就是定义一组操作。 然后通过 void ColoredCubeApp::buildVertexLayouts() { // Create the vertex input layout. D3D10_INPUT_ELEMENT_DESC vertexDesc[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0} }; // Create the input layout D3D10_PASS_DESC PassDesc; mTech->GetPassByIndex(0)->GetDesc(&PassDesc); HR(md3dDevice->CreateInputLayout(vertexDesc, 2, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &mVertexLayout)); }
上面这个函数调用color.fx里面相应的操作函数实现图元的构建。
准备工作完成了。现在就是绘制过程了
void ColoredCubeApp::drawScene() { D3DApp::drawScene(); // Restore default states, input layout and primitive topology // because mFont->DrawText changes them. Note that we can // restore the default states by passing null. //md3dDevice->OMSetDepthStencilState(0, 0); float blendFactors[] = {0.0f, 0.0f, 0.0f, 0.0f}; //md3dDevice->OMSetBlendState(0, blendFactors, 0xffffffff); md3dDevice->IASetInputLayout(mVertexLayout); //图ª?元a列¢D表À¨ª-三¨y角?形? md3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP); // set constants mWVP = mView*mProj; mfxWVPVar->SetMatrix((float*)&mWVP); D3D10_TECHNIQUE_DESC techDesc; mTech->GetDesc( &techDesc ); for(UINT p = 0; p < techDesc.Passes; ++p) { mTech->GetPassByIndex( p )->Apply(0);//更¨¹新?GPU 常¡ê量¢?缓o冲?区?,ê?将?着Á?色¦?器¡Â绑㨮定¡§到Ì?管¨¹线?,ê?启?动¡¥pass mBox.draw(); } mSwapChain->Present(0, 0); } void ColoredCubeApp::updateScene(float dt) { D3DApp::updateScene(dt); // Update angles based on input to orbit camera around box. if(GetAsyncKeyState('A') & 0x8000) mTheta -= 2.0f*dt; if(GetAsyncKeyState('D') & 0x8000) mTheta += 2.0f*dt; if(GetAsyncKeyState('W') & 0x8000) mPhi -= 2.0f*dt; if(GetAsyncKeyState('S') & 0x8000) mPhi += 2.0f*dt; // Restrict the angle mPhi. if( mPhi < 0.1f ) mPhi = 0.1f; if( mPhi > PI-0.1f) mPhi = PI-0.1f; // Convert Spherical to Cartesian coordinates: mPhi measured from +y // and mTheta measured counterclockwise from -z. float x = 5.0f*sinf(mPhi)*sinf(mTheta); float z = -5.0f*sinf(mPhi)*cosf(mTheta); float y = 5.0f*cosf(mPhi); // Build the view matrix. 观?察¨¬者?到Ì?世º¨¤界?的Ì?矩?阵¨® D3DXVECTOR3 pos(x, y, z); D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&mView, &pos, &target, &up); }
目前还只是第一个比较完整的demo 细节代码很多还没有理解透彻。我们能了解个大概流程就可以啦。后面会越学越懂的
原文地址:http://blog.csdn.net/cq361106306/article/details/39268593