techniqueapplication.cpp
来自「real-time(实时渲染技术DirectX)25-30(1)」· C++ 代码 · 共 634 行 · 第 1/2 页
CPP
634 行
/***************************************************************
* TechniqueApplication.cpp *
* *
* This file contains the implementation of the *
* TechniqueApplication class. *
* To compile correctly, this file must be linked with: *
* kernel32.lib *
* user32.lib *
* d3dx8dt.lib *
* d3d8.lib *
* *
***************************************************************/
#include "TechniqueApplication.h"
#define TEX_DIMENSION 1024
#define D3DFVF_MESHVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE)
#define D3DFVF_TESTVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1)
struct MESH_VERTEX
{
float x, y, z;
float nx, ny, nz;
DWORD color;
};
struct TEST_VERTEX
{
float x, y, z, rhw;
float u, v;
};
CTechniqueApplication::CTechniqueApplication()
{
m_pPlaneVertexBuffer = NULL;
m_pMeshVertexBuffer = NULL;
m_pTestVertexBuffer = NULL;
m_pMeshIndexBuffer = NULL;
m_pMesh = NULL;
m_pMeshMaterials = NULL;
m_pShadowTexture = NULL;
m_pShadowTextureSurface = NULL;
m_pShadowZSurface = NULL;
m_pBackBuffer = NULL;
m_pZBuffer = NULL;
m_NumMaterials = 0;
m_CompareShader = 0;
m_DistanceShader = 0;
}
CTechniqueApplication::~CTechniqueApplication()
{
}
BOOL CTechniqueApplication::PostInitialize()
{
D3DCAPS8 Caps;
m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &Caps);
if (Caps.VertexShaderVersion == D3DVS_VERSION(1,1) &&
Caps.PixelShaderVersion == D3DPS_VERSION(1,1))
{
if (FAILED(EasyCreateWindowed(m_hWnd, D3DDEVTYPE_HAL,
D3DCREATE_HARDWARE_VERTEXPROCESSING)))
return FALSE;
}
else
{
if (FAILED(EasyCreateWindowed(m_hWnd, D3DDEVTYPE_REF,
D3DCREATE_SOFTWARE_VERTEXPROCESSING)))
return FALSE;
}
//Do the basic camera positioning, etc.
SetupDevice();
//Load the mesh object
LoadMesh();
//Create the buffers we're actually going to use
ExtractBuffers();
if (FAILED(CreatePlaneBuffers()))
return FALSE;
//Create the shader
if (FAILED(CreateShaders()))
return FALSE;
return TRUE;
}
void CTechniqueApplication::Render()
{
//The light is moving side to side over the model.
float Time = (float)GetTickCount() / 2000.0f;
//These are reusable matrices
D3DXMATRIX LightViewMatrix;
D3DXMATRIX TextureMatrix;
//Create the Texture Matrix
float Offset = 0.5f + (0.5f / (float)TEX_DIMENSION);
ZeroMemory(&TextureMatrix, sizeof(D3DXMATRIX));
TextureMatrix._11 = 0.5f;
TextureMatrix._22 = -0.5f;
TextureMatrix._33 = 1.0f;
TextureMatrix._41 = Offset;
TextureMatrix._42 = Offset;
TextureMatrix._44 = 1.0f;
//Set the view parameters
D3DXVECTOR4 EyePos(75.0, 75.0f, -75.0f, 0.0f);
D3DXVECTOR4 LightPos(-25.0f * sin(Time) - 50.0f, 90.0f, 0.0f, 1.0f);
//Set things up for the light
D3DXMatrixLookAtLH(&LightViewMatrix, &(D3DXVECTOR3)LightPos,
&D3DXVECTOR3(0.0f, 0.0f, 0.0f),
&D3DXVECTOR3(0.0f, 1.0f, 0.0f));
//Assume the light is pointed toward the origin.
D3DXVECTOR4 LightDir = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f) - LightPos;
D3DXVec4Normalize(&LightDir, &LightDir);
//Set the ambient light value.
D3DXVECTOR4 Ambient (0.1f, 0.1f, 0.1f, 0.0f);
m_pD3DDevice->SetVertexShaderConstant(6, &Ambient, 1);
//For this sample only - there is now world matrix transformation,
//so there is no need to transform to object space.
m_pD3DDevice->SetVertexShaderConstant(5, &LightDir, 1);
//Set things up for the viewer
D3DXMatrixLookAtLH(&m_ViewMatrix, &(D3DXVECTOR3)EyePos,
&D3DXVECTOR3(0.0f, 0.0f, 0.0f),
&D3DXVECTOR3(0.0f, 1.0f, 0.0f));
D3DXMATRIX LightShaderMatrix = m_WorldMatrix *
LightViewMatrix *
m_ProjectionMatrix;
D3DXMATRIX EyeShaderMatrix = m_WorldMatrix *
m_ViewMatrix *
m_ProjectionMatrix;
D3DXMATRIX TextureShaderMatrix = m_WorldMatrix * LightViewMatrix *
m_ProjectionMatrix * TextureMatrix;
D3DXMatrixTranspose(&LightShaderMatrix, &LightShaderMatrix);
D3DXMatrixTranspose(&EyeShaderMatrix, &EyeShaderMatrix);
D3DXMatrixTranspose(&TextureShaderMatrix, &TextureShaderMatrix);
//Set the global distance scaling constants
D3DXVECTOR4 DistanceScalers(100.0f, 0.025f, 0.0f, 1.0f);
m_pD3DDevice->SetVertexShaderConstant(4, &DistanceScalers, 1);
//The texture should be null for all distance operations
m_pD3DDevice->SetTexture(0, NULL);
//First, render the light's point of view into the render target.
m_pD3DDevice->SetVertexShader(m_DistanceShader);
D3DVIEWPORT8 NormalViewport;
m_pD3DDevice->GetViewport(&NormalViewport);
//Set up the renderTarget
m_pD3DDevice->SetRenderTarget(m_pShadowTextureSurface, m_pShadowZSurface);
D3DVIEWPORT8 ShadowViewport;
ShadowViewport.X = 0;
ShadowViewport.Y = 0;
ShadowViewport.Width = TEX_DIMENSION;
ShadowViewport.Height = TEX_DIMENSION;
ShadowViewport.MinZ = 0.0f;
ShadowViewport.MaxZ = 1.0f;
m_pD3DDevice->SetViewport(&ShadowViewport);
m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);
//Draw the plane and the mesh using the light view matrix
m_pD3DDevice->SetVertexShaderConstant(0, &LightShaderMatrix, 4);
RenderPlane();
//Draw the mesh
m_pD3DDevice->SetStreamSource(0, m_pMeshVertexBuffer, sizeof(MESH_VERTEX));
m_pD3DDevice->SetIndices(m_pMeshIndexBuffer, 0);
m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,
m_pMesh->GetNumVertices(), 0,
m_pMesh->GetNumFaces());
//Set the renderTarget back to the normal back buffer
m_pD3DDevice->SetRenderTarget(m_pBackBuffer, m_pZBuffer);
m_pD3DDevice->SetViewport(&NormalViewport);
//Use the compare shader
m_pD3DDevice->SetVertexShader(m_CompareShader);
//Set the pixel shader
m_pD3DDevice->SetPixelShader(m_PixelShader);
//Set the texture states to clamp the coordinates
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
//Render everything from the eye's point of view - use the first
//rendering as a texture.
m_pD3DDevice->SetTexture(0, m_pShadowTexture);
m_pD3DDevice->SetVertexShaderConstant(0, &EyeShaderMatrix, 4);
m_pD3DDevice->SetVertexShaderConstant(10, &LightShaderMatrix, 4);
m_pD3DDevice->SetVertexShaderConstant(20, &TextureShaderMatrix, 4);
RenderPlane();
m_pD3DDevice->SetStreamSource(0, m_pMeshVertexBuffer, sizeof(MESH_VERTEX));
m_pD3DDevice->SetIndices(m_pMeshIndexBuffer, 0);
m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,
m_pMesh->GetNumVertices(), 0,
m_pMesh->GetNumFaces());
//Turn off the pixel shader
m_pD3DDevice->SetPixelShader(NULL);
//Draw a small rectangle showing the light's view (for debugging)..
m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
m_pD3DDevice->SetVertexShader(D3DFVF_TESTVERTEX);
m_pD3DDevice->SetStreamSource(0, m_pTestVertexBuffer, sizeof(TEST_VERTEX));
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
}
HRESULT CTechniqueApplication::LoadMesh()
{
LPD3DXBUFFER pD3DXMtrlBuffer;
LPD3DXMESH pOriginalMesh;
//Load and initialize the mesh. This is a repeat of the code
//from Chapter 10.
if(FAILED(D3DXLoadMeshFromX("..\\media\\fattorus.x",
D3DXMESH_MANAGED,
m_pD3DDevice, NULL, &pD3DXMtrlBuffer,
&m_NumMaterials, &pOriginalMesh)))
return FALSE;
D3DXMATERIAL* d3dxMaterials =
(D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
m_pMeshMaterials = new D3DMATERIAL8[m_NumMaterials];
for(long MatCount = 0; MatCount < m_NumMaterials; MatCount++)
m_pMeshMaterials[MatCount] = d3dxMaterials[MatCount].MatD3D;
pD3DXMtrlBuffer->Release();
//This is new. If the FVF doesn't match, clone the mesh and
//create one that does. Then, release the loaded mesh. If the
//FVF does match, set the member mesh and move on.
if (pOriginalMesh->GetFVF() != D3DFVF_MESHVERTEX)
{
pOriginalMesh->CloneMeshFVF(D3DXMESH_MANAGED,
D3DFVF_MESHVERTEX,
m_pD3DDevice, &m_pMesh);
pOriginalMesh->Release();
pOriginalMesh = NULL;
}
else
m_pMesh = pOriginalMesh;
return S_OK;
}
BOOL CTechniqueApplication::PreReset()
{
//Delete the shaders
m_pD3DDevice->DeleteVertexShader(m_CompareShader);
m_pD3DDevice->DeleteVertexShader(m_DistanceShader);
m_pD3DDevice->DeletePixelShader(m_PixelShader);
//Get rid of all the render target objects
CleanUpTarget();
return TRUE;
}
BOOL CTechniqueApplication::PostReset()
{
SetupDevice();
//Recreate the shader
if (FAILED(CreateShaders()))
return FALSE;
return TRUE;
}
BOOL CTechniqueApplication::PreTerminate()
{
//Delete the shaders
m_pD3DDevice->DeleteVertexShader(m_CompareShader);
m_pD3DDevice->DeleteVertexShader(m_DistanceShader);
m_pD3DDevice->DeletePixelShader(m_PixelShader);
//Get rid of all the render target objects
CleanUpTarget();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?