第十一章 CrateDemo核心代码

来源:互联网 发布:淘宝禁止好评返现规则 编辑:程序博客网 时间:2024/06/08 08:05

 

 

CrateDemo.cpp

//=============================================================================// CrateDemo.cpp by Frank Luna (C) 2005 All Rights Reserved.//// Demonstrates texturing a box.//// Controls: Use mouse to orbit and zoom; use the 'W' and 'S' keys to //           alter the height of the camera.//=============================================================================#include "d3dApp.h"#include "DirectInput.h"#include <crtdbg.h>#include "GfxStats.h"#include <list>#include "Vertex.h"class CrateDemo : public D3DApp{public:CrateDemo(HINSTANCE hInstance, std::string winCaption, D3DDEVTYPE devType, DWORD requestedVP);~CrateDemo();bool checkDeviceCaps();void onLostDevice();void onResetDevice();void updateScene(float dt);void drawScene();// Helper methodsvoid buildBoxGeometry();void buildFX();void buildViewMtx();void buildProjMtx();private:GfxStats* mGfxStats;IDirect3DVertexBuffer9* mBoxVB;IDirect3DIndexBuffer9* mBoxIB;IDirect3DTexture9*     mCrateTex;ID3DXEffect* mFX;D3DXHANDLE   mhTech;D3DXHANDLE   mhWVP;D3DXHANDLE   mhWorldInvTrans;D3DXHANDLE   mhLightVecW;D3DXHANDLE   mhDiffuseMtrl;D3DXHANDLE   mhDiffuseLight;D3DXHANDLE   mhAmbientMtrl;D3DXHANDLE   mhAmbientLight;D3DXHANDLE   mhSpecularMtrl;D3DXHANDLE   mhSpecularLight;D3DXHANDLE   mhSpecularPower;D3DXHANDLE   mhEyePos;D3DXHANDLE   mhWorld;D3DXHANDLE   mhTex;D3DXVECTOR3 mLightVecW;D3DXCOLOR   mAmbientMtrl;D3DXCOLOR   mAmbientLight;D3DXCOLOR   mDiffuseMtrl;D3DXCOLOR   mDiffuseLight;D3DXCOLOR   mSpecularMtrl;D3DXCOLOR   mSpecularLight;float       mSpecularPower;float mCameraRotationY;float mCameraRadius;float mCameraHeight;D3DXMATRIX mWorld;D3DXMATRIX mView;D3DXMATRIX mProj;};int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,   PSTR cmdLine, int showCmd){// Enable run-time memory check for debug builds.#if defined(DEBUG) | defined(_DEBUG)_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );#endifCrateDemo app(hInstance, "Crate Demo", D3DDEVTYPE_HAL, D3DCREATE_HARDWARE_VERTEXPROCESSING);gd3dApp = &app;DirectInput di(DISCL_NONEXCLUSIVE|DISCL_FOREGROUND, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND);gDInput = &di;    return gd3dApp->run();}CrateDemo::CrateDemo(HINSTANCE hInstance, std::string winCaption, D3DDEVTYPE devType, DWORD requestedVP): D3DApp(hInstance, winCaption, devType, requestedVP){if(!checkDeviceCaps()){MessageBox(0, "checkDeviceCaps() Failed", 0, 0);PostQuitMessage(0);}mGfxStats = new GfxStats();mGfxStats->addVertices(24);mGfxStats->addTriangles(12);mCameraRadius    = 6.0f;mCameraRotationY = 1.2 * D3DX_PI;mCameraHeight    = 3.0f;mLightVecW     = D3DXVECTOR3(0.0, 0.0f, -1.0f);mDiffuseMtrl   = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);mDiffuseLight  = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);mAmbientMtrl   = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);mAmbientLight  = D3DXCOLOR(0.6f, 0.6f, 0.6f, 1.0f);mSpecularMtrl  = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f);mSpecularLight = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);mSpecularPower = 8.0f;D3DXMatrixIdentity(&mWorld);HR(D3DXCreateTextureFromFile(gd3dDevice, "crate.jpg", &mCrateTex));buildBoxGeometry();buildFX();onResetDevice();InitAllVertexDeclarations();}CrateDemo::~CrateDemo(){delete mGfxStats;ReleaseCOM(mBoxVB);ReleaseCOM(mBoxIB);ReleaseCOM(mCrateTex);ReleaseCOM(mFX);DestroyAllVertexDeclarations();}bool CrateDemo::checkDeviceCaps(){D3DCAPS9 caps;HR(gd3dDevice->GetDeviceCaps(&caps));// Check for vertex shader version 2.0 support.if( caps.VertexShaderVersion < D3DVS_VERSION(2, 0) )return false;// Check for pixel shader version 2.0 support.if( caps.PixelShaderVersion < D3DPS_VERSION(2, 0) )return false;return true;}void CrateDemo::onLostDevice(){mGfxStats->onLostDevice();HR(mFX->OnLostDevice());}void CrateDemo::onResetDevice(){mGfxStats->onResetDevice();HR(mFX->OnResetDevice());// The aspect ratio depends on the backbuffer dimensions, which can // possibly change after a reset.  So rebuild the projection matrix.buildProjMtx();}void CrateDemo::updateScene(float dt){mGfxStats->update(dt);// Get snapshot of input devices.gDInput->poll();// Check input.if( gDInput->keyDown(DIK_W) ) mCameraHeight   += 25.0f * dt;if( gDInput->keyDown(DIK_S) ) mCameraHeight   -= 25.0f * dt;// Divide by 50 to make mouse less sensitive. mCameraRotationY += gDInput->mouseDX() / 100.0f;mCameraRadius    += gDInput->mouseDY() / 25.0f;// If we rotate over 360 degrees, just roll back to 0if( fabsf(mCameraRotationY) >= 2.0f * D3DX_PI ) mCameraRotationY = 0.0f;// Don't let radius get too small.if( mCameraRadius < 5.0f )mCameraRadius = 5.0f;// The camera position/orientation relative to world space can // change every frame based on input, so we need to rebuild the// view matrix every frame with the latest changes.buildViewMtx();}void CrateDemo::drawScene(){// Clear the backbuffer and depth buffer.HR(gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffeeeeee, 1.0f, 0));HR(gd3dDevice->BeginScene());// Setup the rendering FXHR(mFX->SetTechnique(mhTech));HR(mFX->SetMatrix(mhWVP, &(mWorld*mView*mProj)));D3DXMATRIX worldInvTrans;D3DXMatrixInverse(&worldInvTrans, 0, &mWorld);D3DXMatrixTranspose(&worldInvTrans, &worldInvTrans);HR(mFX->SetMatrix(mhWorldInvTrans, &worldInvTrans));HR(mFX->SetValue(mhLightVecW, &mLightVecW, sizeof(D3DXVECTOR3)));HR(mFX->SetValue(mhDiffuseMtrl, &mDiffuseMtrl, sizeof(D3DXCOLOR)));HR(mFX->SetValue(mhDiffuseLight, &mDiffuseLight, sizeof(D3DXCOLOR)));HR(mFX->SetValue(mhAmbientMtrl, &mAmbientMtrl, sizeof(D3DXCOLOR)));HR(mFX->SetValue(mhAmbientLight, &mAmbientLight, sizeof(D3DXCOLOR)));HR(mFX->SetValue(mhSpecularLight, &mSpecularLight, sizeof(D3DXCOLOR)));HR(mFX->SetValue(mhSpecularMtrl, &mSpecularMtrl, sizeof(D3DXCOLOR)));HR(mFX->SetFloat(mhSpecularPower, mSpecularPower));HR(mFX->SetMatrix(mhWorld, &mWorld));HR(mFX->SetTexture(mhTex, mCrateTex));HR(gd3dDevice->SetVertexDeclaration(VertexPNT::Decl));HR(gd3dDevice->SetStreamSource(0, mBoxVB, 0, sizeof(VertexPNT)));HR(gd3dDevice->SetIndices(mBoxIB));// Begin passes.UINT numPasses = 0;HR(mFX->Begin(&numPasses, 0));for(UINT i = 0; i < numPasses; ++i){HR(mFX->BeginPass(i));HR(gd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12));HR(mFX->EndPass());}HR(mFX->End());mGfxStats->display();HR(gd3dDevice->EndScene());// Present the backbuffer.HR(gd3dDevice->Present(0, 0, 0, 0));}void CrateDemo::buildBoxGeometry(){// Create the vertex buffer.HR(gd3dDevice->CreateVertexBuffer(24 * sizeof(VertexPNT), D3DUSAGE_WRITEONLY,0, D3DPOOL_MANAGED,&mBoxVB, 0));// Write box vertices to the vertex buffer.VertexPNT* v = 0;HR(mBoxVB->Lock(0, 0, (void**)&v, 0));// Fill in the front face vertex data.v[0] = VertexPNT(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);v[1] = VertexPNT(-1.0f,  1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);v[2] = VertexPNT( 1.0f,  1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);v[3] = VertexPNT( 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);// Fill in the back face vertex data.v[4] = VertexPNT(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);v[5] = VertexPNT( 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f);v[6] = VertexPNT( 1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);v[7] = VertexPNT(-1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f);// Fill in the top face vertex data.v[8]  = VertexPNT(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f);v[9]  = VertexPNT(-1.0f, 1.0f,  1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);v[10] = VertexPNT( 1.0f, 1.0f,  1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);v[11] = VertexPNT( 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f);// Fill in the bottom face vertex data.v[12] = VertexPNT(-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f);v[13] = VertexPNT( 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f);v[14] = VertexPNT( 1.0f, -1.0f,  1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f);v[15] = VertexPNT(-1.0f, -1.0f,  1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);// Fill in the left face vertex data.v[16] = VertexPNT(-1.0f, -1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f);v[17] = VertexPNT(-1.0f,  1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f);v[18] = VertexPNT(-1.0f,  1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f);v[19] = VertexPNT(-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f);// Fill in the right face vertex data.v[20] = VertexPNT( 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);v[21] = VertexPNT( 1.0f,  1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f);v[22] = VertexPNT( 1.0f,  1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f);v[23] = VertexPNT( 1.0f, -1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f);HR(mBoxVB->Unlock());// Create the vertex buffer.HR(gd3dDevice->CreateIndexBuffer(36 * sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED, &mBoxIB, 0));// Write box indices to the index buffer.WORD* i = 0;HR(mBoxIB->Lock(0, 0, (void**)&i, 0));// Fill in the front face index datai[0] = 0; i[1] = 1; i[2] = 2;i[3] = 0; i[4] = 2; i[5] = 3;// Fill in the back face index datai[6] = 4; i[7]  = 5; i[8]  = 6;i[9] = 4; i[10] = 6; i[11] = 7;// Fill in the top face index datai[12] = 8; i[13] =  9; i[14] = 10;i[15] = 8; i[16] = 10; i[17] = 11;// Fill in the bottom face index datai[18] = 12; i[19] = 13; i[20] = 14;i[21] = 12; i[22] = 14; i[23] = 15;// Fill in the left face index datai[24] = 16; i[25] = 17; i[26] = 18;i[27] = 16; i[28] = 18; i[29] = 19;// Fill in the right face index datai[30] = 20; i[31] = 21; i[32] = 22;i[33] = 20; i[34] = 22; i[35] = 23;HR(mBoxIB->Unlock());}void CrateDemo::buildFX(){// Create the FX from a .fx file.ID3DXBuffer* errors = 0;HR(D3DXCreateEffectFromFile(gd3dDevice, "DirLightTex.fx", 0, 0, D3DXSHADER_DEBUG, 0, &mFX, &errors));if( errors )MessageBox(0, (char*)errors->GetBufferPointer(), 0, 0);// Obtain handles.mhTech          = mFX->GetTechniqueByName("DirLightTexTech");mhWVP           = mFX->GetParameterByName(0, "gWVP");mhWorldInvTrans = mFX->GetParameterByName(0, "gWorldInvTrans");mhLightVecW     = mFX->GetParameterByName(0, "gLightVecW");mhDiffuseMtrl   = mFX->GetParameterByName(0, "gDiffuseMtrl");mhDiffuseLight  = mFX->GetParameterByName(0, "gDiffuseLight");mhAmbientMtrl   = mFX->GetParameterByName(0, "gAmbientMtrl");mhAmbientLight  = mFX->GetParameterByName(0, "gAmbientLight");mhSpecularMtrl  = mFX->GetParameterByName(0, "gSpecularMtrl");mhSpecularLight = mFX->GetParameterByName(0, "gSpecularLight");mhSpecularPower = mFX->GetParameterByName(0, "gSpecularPower");mhEyePos        = mFX->GetParameterByName(0, "gEyePosW");mhWorld         = mFX->GetParameterByName(0, "gWorld");mhTex           = mFX->GetParameterByName(0, "gTex");}void CrateDemo::buildViewMtx(){float x = mCameraRadius * cosf(mCameraRotationY);float z = mCameraRadius * sinf(mCameraRotationY);D3DXVECTOR3 pos(x, mCameraHeight, z);D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);D3DXMatrixLookAtLH(&mView, &pos, &target, &up);HR(mFX->SetValue(mhEyePos, &pos, sizeof(D3DXVECTOR3)));}void CrateDemo::buildProjMtx(){float w = (float)md3dPP.BackBufferWidth;float h = (float)md3dPP.BackBufferHeight;D3DXMatrixPerspectiveFovLH(&mProj, D3DX_PI * 0.25f, w/h, 1.0f, 5000.0f);}

 

 

dirLightTex.fx

//=============================================================================// dirLightTex.fx by Frank Luna (C) 2004 All Rights Reserved.//// Uses a directional light plus texturing.//=============================================================================uniform extern float4x4 gWorld;uniform extern float4x4 gWorldInvTrans;uniform extern float4x4 gWVP;uniform extern float4 gAmbientMtrl;uniform extern float4 gAmbientLight;uniform extern float4 gDiffuseMtrl;uniform extern float4 gDiffuseLight;uniform extern float4 gSpecularMtrl;uniform extern float4 gSpecularLight;uniform extern float  gSpecularPower;uniform extern float3 gLightVecW;uniform extern float3 gEyePosW;uniform extern texture gTex;sampler TexS = sampler_state{Texture = <gTex>;MinFilter = Anisotropic;MagFilter = LINEAR;MipFilter = LINEAR;MaxAnisotropy = 8;AddressU  = WRAP;    AddressV  = WRAP;}; struct OutputVS{    float4 posH    : POSITION0;    float4 diffuse : COLOR0;    float4 spec    : COLOR1;    float2 tex0    : TEXCOORD0;};OutputVS DirLightTexVS(float3 posL : POSITION0, float3 normalL : NORMAL0, float2 tex0: TEXCOORD0){    // Zero out our output.OutputVS outVS = (OutputVS)0;// Transform normal to world space.float3 normalW = mul(float4(normalL, 0.0f), gWorldInvTrans).xyz;normalW = normalize(normalW);// Transform vertex position to world space.float3 posW  = mul(float4(posL, 1.0f), gWorld).xyz;//=======================================================// Compute the color: Equation 10.3.// Compute the vector from the vertex to the eye position.float3 toEye = normalize(gEyePosW - posW);// Compute the reflection vector.float3 r = reflect(-gLightVecW, normalW);// Determine how much (if any) specular light makes it into the eye.float t  = pow(max(dot(r, toEye), 0.0f), gSpecularPower);// Determine the diffuse light intensity that strikes the vertex.float s = max(dot(gLightVecW, normalW), 0.0f);// Compute the ambient, diffuse and specular terms separatly. float3 spec = t*(gSpecularMtrl*gSpecularLight).rgb;float3 diffuse = s*(gDiffuseMtrl*gDiffuseLight).rgb;float3 ambient = gAmbientMtrl*gAmbientLight;// Sum all the terms together and copy over the diffuse alpha.outVS.diffuse.rgb = ambient + diffuse;outVS.diffuse.a   = gDiffuseMtrl.a;outVS.spec = float4(spec, 0.0f);//=======================================================// Transform to homogeneous clip space.outVS.posH = mul(float4(posL, 1.0f), gWVP);// Pass on texture coordinates to be interpolated in rasterization.outVS.tex0 = tex0;// Done--return the output.    return outVS;}float4 DirLightTexPS(float4 c : COLOR0, float4 spec : COLOR1, float2 tex0 : TEXCOORD0) : COLOR{float3 texColor = tex2D(TexS, tex0).rgb;float3 diffuse = c.rgb * texColor;    return float4(diffuse + spec.rgb, c.a); }technique DirLightTexTech{    pass P0    {        // Specify the vertex and pixel shader associated with this pass.        vertexShader = compile vs_2_0 DirLightTexVS();        pixelShader  = compile ps_2_0 DirLightTexPS();    }}


 


 

原创粉丝点击