网的重要作用可以导入3DMAX等创建的模型,到游戏中;着色器可以实现特定绚丽的效果。它们的实现如下
1. 网 Mesh的实现:
#pragma once
//========================================================================
// File: Mesh.h - classes to render meshes in D3D9 and D3D11
// 主要是导入3DMAX等软件生成的模型文件 基于Windows Direct3D9 和 Direct3D11
//========================================================================
#include <SDKMesh.h>
#include "Geometry.h"
#include "ResCache.h"
#define GCC_NEW new
#if !defined(SAFE_RELEASE)
#define SAFE_RELEASE(x) if(x) x->Release(); x=NULL;
#endif
//BaseRenderComponent defined in Actors folder
typedef BaseRenderComponent* WeakBaseRenderComponentPtr;
typedef unsigned int ActorId;
typedef unsigned int GameViewId;
typedef D3DXCOLOR Color;
typedef unsigned int DWORD;
typedef unsigned char BYTE;
typedef float FLOAT;
typedef unsigned int UINT;
#ifdef UNICODE
typedef wchar_t TCHAR;
#else
typedef unsigned char TCHAR;
#endif
typedef unsigned char CHAR;
typedef unsigned wchar_t WCHAR;
enum HRESULT
{
E_INVALIDARG,
E_FAIL,
S_OK,
};
enum RenderPass
{
RenderPass_0,
RenderPass_Static = RenderPass_0,
RenderPass_Actor,
RenderPass_Sky,
RenderPass_NotRendered,
RenderPass_Last
};
//
// class D3DSdkMeshResourceExtraData11
//
class IResourceExtraData
{
public:
virtual std::string VToString()=0;
};
class D3DSdkMeshResourceExtraData11 : public IResourceExtraData
{
friend class SdkMeshResourceLoader;
public:
D3DSdkMeshResourceExtraData11() { };
virtual ~D3DSdkMeshResourceExtraData11() { }
virtual std::string VToString() { return "D3DSdkMeshResourceExtraData11"; }
CDXUTSDKMesh m_Mesh11; //This class includes functions to import, render, and destroy a mesh
};
//
// class SdkMeshResourceLoader
//
class IResourceLoader
{
public:
virtual std::string VGetPattern()=0;
virtual bool VUseRawFile()=0;
virtual bool VDiscardRawBufferAfterLoad()=0;
virtual bool VAddNullZero() { return false; }
virtual unsigned int VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize)=0;
virtual bool VLoadResource(char *rawBuffer, unsigned int rawSize, shared_ptr<ResHandle> handle)=0;
};
class SdkMeshResourceLoader : public IResourceLoader
{
public:
virtual bool VUseRawFile() { return false; }
virtual bool VDiscardRawBufferAfterLoad() { return false; }
virtual unsigned int VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize);
virtual bool VLoadResource(char *rawBuffer, unsigned int rawSize, shared_ptr<ResHandle> handle);
virtual std::string VGetPattern() { return "*.sdkmesh"; }
};
//
// D3DMeshNode9 Description
//
// Attaches a ID3DXMesh Mesh object to the GameCode4 scene graph
// This is a creature of D3D9, and not described in the 4th edition.
// In the 3rd edition this was called D3DMeshNode
//
class D3DMeshNode9 : public D3DSceneNode9 // defined in SceneNode.h
{
protected:
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb174069(v=vs.85).aspx
ID3DXMesh *m_pMesh;
std::wstring m_XFileName;
public:
D3DMeshNode9(const ActorId actorId,
WeakBaseRenderComponentPtr renderComponent,
ID3DXMesh *Mesh,
RenderPass renderPass,
const Mat4x4 *t);
D3DMeshNode9(const ActorId actorId,
WeakBaseRenderComponentPtr renderComponent,
std::wstring xFileName,
RenderPass renderPass,
const Mat4x4 *t);
virtual ~D3DMeshNode9() { SAFE_RELEASE(m_pMesh); }
HRESULT VRender(Scene *pScene);
virtual HRESULT VOnRestore(Scene *pScene);
virtual HRESULT VPick(Scene *pScene, RayCast *pRayCast);
float CalcBoundingSphere();
};
//
// D3DShaderMeshNode9 Description
//
// Attaches a ID3DXMesh Mesh object to the GameCode4 scene graph and renders it with a shader.
// This is a creature of D3D9, and not described in the 4th edition.
// In the 3rd edition this was called D3DShaderMeshNode
//
class D3DShaderMeshNode9 : public D3DMeshNode9
{
protected:
ID3DXEffect *m_pEffect;
std::string m_fxFileName;
public:
D3DShaderMeshNode9(const ActorId actorId,
WeakBaseRenderComponentPtr renderComponent,
ID3DXMesh *Mesh,
std::string fxFileName,
RenderPass renderPass,
const Mat4x4 *t);
D3DShaderMeshNode9(const ActorId actorId,
WeakBaseRenderComponentPtr renderComponent,
std::wstring xFileName,
std::string fxFileName,
RenderPass renderPass,
const Mat4x4 *t);
virtual ~D3DShaderMeshNode9() { SAFE_RELEASE(m_pEffect); }
virtual HRESULT VOnRestore(Scene *pScene);
virtual HRESULT VOnLostDevice(Scene *pScene);
HRESULT VRender(Scene *pScene);
};
//
// class TeapotMeshNode9 teapot模型
//
class D3DTeapotMeshNode9 : public D3DShaderMeshNode9
{
public:
D3DTeapotMeshNode9(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, std::string fxFileName, RenderPass renderPass, const Mat4x4 *t);
virtual HRESULT VOnRestore(Scene *pScene);
};
class D3DShaderMeshNode11 : public SceneNode
{
public:
D3DShaderMeshNode11(const ActorId actorId,
WeakBaseRenderComponentPtr renderComponent,
std::string sdkMeshFileName,
RenderPass renderPass,
const Mat4x4 *t);
virtual HRESULT VOnRestore(Scene *pScene);
virtual HRESULT VOnLostDevice(Scene *pScene) { return S_OK; }
virtual HRESULT VRender(Scene *pScene);
virtual HRESULT VPick(Scene *pScene, RayCast *pRayCast);
protected:
std::string m_sdkMeshFileName;
GameCode4_Hlsl_VertexShader m_VertexShader;
GameCode4_Hlsl_PixelShader m_PixelShader;
float CalcBoundingSphere(CDXUTSDKMesh *mesh11); // this was added post press.
};
class D3DTeapotMeshNode11 : public D3DShaderMeshNode11
{
public:
D3DTeapotMeshNode11(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, RenderPass renderPass,const Mat4x4 *t)
: D3DShaderMeshNode11(actorId, renderComponent, "art\\teapot.sdkmesh", renderPass, t) { }
bool VIsVisible() { return true; }
};
//========================================================================
// Mesh.cpp - classes to render meshes in D3D9 and D3D11
//========================================================================
#include "GameCodeStd.h"
#include <SDKmisc.h>
#include "GameCode.h"
#include "ResCache.h"
#include "D3DRenderer.h" // defined in Direct X渲染系统
#include "Lights.h"
#include "Mesh.h"
#include "Raycast.h"
#include "SceneNodes.h"
shared_ptr<IResourceLoader> CreateSdkMeshResourceLoader()
{
return shared_ptr<IResourceLoader>(GCC_NEW SdkMeshResourceLoader());
}
unsigned int SdkMeshResourceLoader::VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize)
{
// The raw data of the SDK Mesh file is needed by the CDXUTMesh class, so we're going to keep it around.
return rawSize;
}
//
// SdkMeshResourceLoader::VLoadResource
//
bool SdkMeshResourceLoader::VLoadResource(char *rawBuffer, unsigned int rawSize, shared_ptr<ResHandle> handle)
{
GameCodeApp::Renderer renderer = GameCodeApp::GetRendererImpl();
if (renderer == GameCodeApp::Renderer_D3D9)
{
GCC_ASSERT(0 && "This is not supported in D3D9");
}
else if (renderer == GameCodeApp::Renderer_D3D11)
{
shared_ptr<D3DSdkMeshResourceExtraData11> extra = shared_ptr<D3DSdkMeshResourceExtraData11>(GCC_NEW D3DSdkMeshResourceExtraData11());
// Load the Mesh 倒入模型文件
if (SUCCEEDED ( extra->m_Mesh11.Create( DXUTGetD3D11Device(), (BYTE *)rawBuffer, (UINT)rawSize, true ) ) )
{
handle->SetExtra(shared_ptr<D3DSdkMeshResourceExtraData11>(extra));
}
return true;
}
GCC_ASSERT(0 && "Unsupported Renderer in SdkMeshResourceLoader::VLoadResource");
return false;
}
// MeshNode Implementation
//
// D3DMeshNode9::D3DMeshNode9
//
D3DMeshNode9::D3DMeshNode9(const ActorId actorId,
WeakBaseRenderComponentPtr renderComponent,
ID3DXMesh *Mesh,
RenderPass renderPass,
const Mat4x4 *t )
: D3DSceneNode9(actorId, renderComponent, renderPass, t)
{
m_pMesh = Mesh;
if (m_pMesh)
{
// Added post press - not all Mesh modes have Meshes. Some are just effects!
m_pMesh->AddRef();
}
}
//
// MeshNode::MeshNode
//
D3DMeshNode9::D3DMeshNode9(const ActorId actorId,
WeakBaseRenderComponentPtr renderComponent,
std::wstring xFileName,
RenderPass renderPass,
const Mat4x4 *t)
: D3DSceneNode9(actorId, renderComponent, renderPass, t)
{
m_pMesh = NULL;
m_XFileName = xFileName;
}
//
// MeshNode::CalcBoundingSphere
//
typedef struct D3DXVECTOR3 {
float x;
float y;
float z;
} D3DXVECTOR3, *LPD3DXVECTOR3;
float D3DMeshNode9::CalcBoundingSphere()
{
D3DXVECTOR3* pData;
D3DXVECTOR3 vCenter;
FLOAT fObjectRadius;
HRESULT hr;
V( m_pMesh->LockVertexBuffer( 0, ( LPVOID* )&pData ) );
V( D3DXComputeBoundingSphere( pData, m_pMesh->GetNumVertices(),
D3DXGetFVFVertexSize( m_pMesh->GetFVF() ), &vCenter, &fObjectRadius ) );
V( m_pMesh->UnlockVertexBuffer() );
return fObjectRadius;
}
//
// MeshNode::VRender
//
HRESULT D3DMeshNode9::VRender(Scene *pScene)
{
if (S_OK != D3DSceneNode9::VRender(pScene) )
return E_FAIL;
return m_pMesh->DrawSubset(0);
}
//
// MeshNode::VOnRestore
//
// This function loads the Mesh and ensures the Mesh has normals; it also optimizes the
// Mesh for the graphics card's vertex cache, which improves performance by organizing
// the internal triangle list for less cache misses.
//
HRESULT D3DMeshNode9::VOnRestore(Scene *pScene)
{
if (m_XFileName.empty())
{
SetRadius(CalcBoundingSphere());
return D3DSceneNode9::VOnRestore(pScene);
}
// Change post press - release the Mesh only if we have a valid Mesh file name to load.
// Otherwise we likely created it on our own, and needs to be kept.
SAFE_RELEASE(m_pMesh);
WCHAR str[MAX_PATH];
HRESULT hr;
// Load the Mesh with D3DX and get back a ID3DXMesh*. For this
// sample we'll ignore the X file's embedded materials since we know
// exactly the model we're loading. See the Mesh samples such as
// "OptimizedMesh" for a more generic Mesh loading example.
V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, m_XFileName.c_str() ) );
V_RETURN( D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, DXUTGetD3D9Device(), NULL, NULL, NULL, NULL, &m_pMesh) );
DWORD *rgdwAdjacency = NULL;
// Make sure there are normals which are required for lighting
if( !(m_pMesh->GetFVF() & D3DFVF_NORMAL) )
{
ID3DXMesh* pTempMesh;
V( m_pMesh->CloneMeshFVF( m_pMesh->GetOptions(),
m_pMesh->GetFVF() | D3DFVF_NORMAL,
DXUTGetD3D9Device(), &pTempMesh ) );
V( D3DXComputeNormals( pTempMesh, NULL ) );
SAFE_RELEASE( m_pMesh );
m_pMesh = pTempMesh;
}
// Optimize the Mesh for this graphics card's vertex cache
// so when rendering the Mesh's triangle list the vertices will
// cache hit more often so it won't have to re-execute the vertex shader
// on those vertices so it will improve perf.
rgdwAdjacency = GCC_NEW DWORD[m_pMesh->GetNumFaces() * 3];
if( rgdwAdjacency == NULL )
return E_OUTOFMEMORY;
V( m_pMesh->ConvertPointRepsToAdjacency(NULL, rgdwAdjacency) );
V( m_pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL) );
SAFE_DELETE_ARRAY(rgdwAdjacency);
SetRadius(CalcBoundingSphere());
return D3DSceneNode9::VOnRestore(pScene);
}
HRESULT D3DMeshNode9::VPick(Scene *pScene, RayCast *pRayCast)
{
if (SceneNode::VPick(pScene, pRayCast)==E_FAIL)
return E_FAIL;
pScene->PushAndSetMatrix(m_Props.ToWorld());
HRESULT hr = pRayCast->Pick(pScene, m_Props.ActorId(), m_pMesh);
pScene->PopMatrix();
return hr;
}
// D3DShaderMeshNode9 Implementation
//
// ShaderMeshNode::ShaderMeshNode
//
D3DShaderMeshNode9::D3DShaderMeshNode9(const ActorId actorId,
WeakBaseRenderComponentPtr renderComponent,
ID3DXMesh *Mesh,
std::string fxFileName, // used to be effect pointer - changed to fix a VOnRestore crash.
RenderPass renderPass,
const Mat4x4 *t)
: D3DMeshNode9(actorId, renderComponent, Mesh, renderPass, t)
{
m_pEffect = NULL;
m_fxFileName = fxFileName;
}
//
// ShaderMeshNode::ShaderMeshNode
//
D3DShaderMeshNode9::D3DShaderMeshNode9(const ActorId actorId,
WeakBaseRenderComponentPtr renderComponent,
std::wstring xFileName,
std::string fxFileName,
RenderPass renderPass,
const Mat4x4 *t)
: D3DMeshNode9(actorId, renderComponent, xFileName, renderPass, t)
{
m_pEffect = NULL;
m_fxFileName = fxFileName;
}
//
// ShaderMeshNode::VOnRestore - very similar to MeshNode::VOnRestore
//
HRESULT D3DShaderMeshNode9::VOnRestore(Scene *pScene)
{
SAFE_RELEASE(m_pEffect);
DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE | D3DXSHADER_DEBUG | D3DXSHADER_NO_PRESHADER;
HRESULT hr;
Resource resource(m_fxFileName);
shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource); // this actually loads the XML file from the zip file
V ( D3DXCreateEffect( DXUTGetD3D9Device(), pResourceHandle->Buffer(), pResourceHandle->Size(), NULL, NULL, dwShaderFlags, NULL, &m_pEffect, NULL ) );
return D3DMeshNode9::VOnRestore(pScene);
}
//
// ShaderMeshNode::VRender
//
HRESULT D3DShaderMeshNode9::VRender(Scene *pScene)
{
if (S_OK != D3DSceneNode9::VRender(pScene) )
return E_FAIL;
HRESULT hr;
// Update the effect's variables. Instead of using strings, it would
// be more efficient to cache a handle to the parameter by calling
// ID3DXEffect::GetParameterByName
Mat4x4 worldViewProj = pScene->GetCamera()->GetWorldViewProjection(pScene);
Mat4x4 world = pScene->GetTopMatrix();
D3DXCOLOR ambient = m_Props.GetMaterial().GetAmbient();
V_RETURN( m_pEffect->SetValue( "g_MaterialAmbientColor", &ambient, sizeof( D3DXCOLOR ) ) );
D3DXCOLOR diffuse = m_Props.GetMaterial().GetDiffuse();
V_RETURN( m_pEffect->SetValue( "g_MaterialDiffuseColor", &diffuse, sizeof( D3DXCOLOR ) ) );
V( m_pEffect->SetMatrix( "g_mWorldViewProjection", &worldViewProj ) );
V( m_pEffect->SetMatrix( "g_mWorld", &world ) );
V( m_pEffect->SetFloat( "g_fTime", ( float )1.0f ) );
int count = pScene->GetLightManager()->GetLightCount(this);
if (count)
{
// Light 0 is the only one we use for ambient lighting. The rest are ignored in this simple shader.
V( m_pEffect->SetValue( "g_LightAmbient", pScene->GetLightManager()->GetLightAmbient(this), sizeof( D3DXVECTOR4 ) * 1 ) );
V( m_pEffect->SetValue( "g_LightDir", pScene->GetLightManager()->GetLightDirection(this), sizeof( D3DXVECTOR4 ) * MAXIMUM_LIGHTS_SUPPORTED ) );
V( m_pEffect->SetValue( "g_LightDiffuse", pScene->GetLightManager()->GetLightDiffuse(this), sizeof( D3DXVECTOR4 ) * MAXIMUM_LIGHTS_SUPPORTED ) );
V( m_pEffect->SetInt( "g_nNumLights", count ) );
}
float alpha = m_Props.GetMaterial().GetAlpha();
V( m_pEffect->SetFloat( "g_fAlpha", alpha ) );
V( m_pEffect->SetTechnique( (alpha < 1.0f ) ? "RenderSceneWithAlpha" : "RenderScene" ) );
// Apply the technique contained in the effect
UINT iPass, cPasses;
V( m_pEffect->Begin( &cPasses, 0 ) );
for( iPass = 0; iPass < cPasses; iPass++ )
{
V( m_pEffect->BeginPass( iPass ) );
// The effect interface queues up the changes and performs them
// with the CommitChanges call. You do not need to call CommitChanges if
// you are not setting any parameters between the BeginPass and EndPass.
// V( g_pEffect->CommitChanges() );
// Render the Mesh with the applied technique
V( m_pMesh->DrawSubset( 0 ) );
V( m_pEffect->EndPass() );
}
V( m_pEffect->End() );
return S_OK;
}
HRESULT D3DShaderMeshNode9::VOnLostDevice(Scene *pScene)
{
SAFE_RELEASE(m_pEffect);
HRESULT hr;
V_RETURN(D3DMeshNode9::VOnLostDevice(pScene));
return S_OK;
}
//
// TeapotMeshNode::TeapotMeshNode
//
D3DTeapotMeshNode9::D3DTeapotMeshNode9(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, std::string fxFileName, RenderPass renderPass, const Mat4x4 *t)
: D3DShaderMeshNode9(actorId, renderComponent, NULL, fxFileName, renderPass, t)
{
// there's nothing else needed here...
}
//
// TeapotMeshNode::VOnRestore
//
HRESULT D3DTeapotMeshNode9::VOnRestore(Scene *pScene)
{
HRESULT hr;
IDirect3DDevice9 * pDevice = DXUTGetD3D9Device();
SAFE_RELEASE(m_pMesh);
V( D3DXCreateTeapot( pDevice, &m_pMesh, NULL ) );
//Rotate the teapot 90 degrees from default so that the spout faces forward
Mat4x4 rotateY90;
rotateY90.BuildRotationY(-GCC_PI / 2.0f);
IDirect3DVertexBuffer9* pVB = NULL;
m_pMesh->GetVertexBuffer(&pVB);
Vec3* pVertices = NULL;
pVB->Lock( 0, 0, (void**)&pVertices, 0 );
for (unsigned int i=0; i<m_pMesh->GetNumVertices(); ++i)
{
*pVertices = rotateY90.Xform(*pVertices);
++pVertices;
//The structs depicted in this vertex buffer actually store
//information for normals in addition to xyz, thereby
//making the vertices in pVB twice the size of the one described
//by *pVertices. So we address that here.
*pVertices = rotateY90.Xform(*pVertices); //rotate the normals, too
++pVertices;
}
pVB->Unlock();
SAFE_RELEASE( pVB );
//...end rotation
// Note - the Mesh is needed BEFORE calling the base class VOnRestore.
V ( D3DShaderMeshNode9::VOnRestore ( pScene ) );
return S_OK;
}
//
// D3DShaderMeshNode11::D3DShaderMeshNode11
//
D3DShaderMeshNode11::D3DShaderMeshNode11(const ActorId actorId,
WeakBaseRenderComponentPtr renderComponent,
std::string sdkMeshFileName,
RenderPass renderPass,
const Mat4x4 *t)
: SceneNode(actorId, renderComponent, renderPass, t)
{
m_sdkMeshFileName = sdkMeshFileName;
}
//
// D3DShaderMeshNode11::VOnRestore
//
HRESULT D3DShaderMeshNode11::VOnRestore(Scene *pScene)
{
HRESULT hr;
V_RETURN(SceneNode::VOnRestore(pScene) );
V_RETURN (m_VertexShader.OnRestore(pScene) );
V_RETURN (m_PixelShader.OnRestore(pScene) );
// Force the Mesh to reload
Resource resource(m_sdkMeshFileName);
shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource);
shared_ptr<D3DSdkMeshResourceExtraData11> extra = static_pointer_cast<D3DSdkMeshResourceExtraData11>(pResourceHandle->GetExtra());
SetRadius(CalcBoundingSphere(&extra->m_Mesh11));
return S_OK;
}
//
// D3DShaderMeshNode11::VRender
//
HRESULT D3DShaderMeshNode11::VRender(Scene *pScene)
{
HRESULT hr;
V_RETURN (m_VertexShader.SetupRender(pScene, this) );
V_RETURN (m_PixelShader.SetupRender(pScene, this) );
//Get the Mesh
Resource resource(m_sdkMeshFileName);
shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource);
shared_ptr<D3DSdkMeshResourceExtraData11> extra = static_pointer_cast<D3DSdkMeshResourceExtraData11>(pResourceHandle->GetExtra());
// FUTURE WORK - this code WON'T be able to find texture resources referred to by the sdkmesh file
// in the Resource cache.
//IA setup
UINT Strides[1];
UINT Offsets[1];
ID3D11Buffer* pVB[1];
pVB[0] = extra->m_Mesh11.GetVB11( 0, 0 );
Strides[0] = ( UINT )extra->m_Mesh11.GetVertexStride( 0, 0 );
Offsets[0] = 0;
DXUTGetD3D11DeviceContext()->IASetVertexBuffers( 0, 1, pVB, Strides, Offsets );
DXUTGetD3D11DeviceContext()->IASetIndexBuffer( extra->m_Mesh11.GetIB11( 0 ), extra->m_Mesh11.GetIBFormat11( 0 ), 0 );
//Render
D3D11_PRIMITIVE_TOPOLOGY PrimType;
for( UINT subset = 0; subset < extra->m_Mesh11.GetNumSubsets( 0 ); ++subset )
{
// Get the subset
SDKMESH_SUBSET *pSubset = extra->m_Mesh11.GetSubset( 0, subset );
PrimType = CDXUTSDKMesh::GetPrimitiveType11( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType );
DXUTGetD3D11DeviceContext()->IASetPrimitiveTopology( PrimType );
ID3D11ShaderResourceView* pDiffuseRV = extra->m_Mesh11.GetMaterial( pSubset->MaterialID )->pDiffuseRV11;
DXUTGetD3D11DeviceContext()->PSSetShaderResources( 0, 1, &pDiffuseRV );
DXUTGetD3D11DeviceContext()->DrawIndexed( ( UINT )pSubset->IndexCount, 0, ( UINT )pSubset->VertexStart );
}
return S_OK;
}
HRESULT D3DShaderMeshNode11::VPick(Scene *pScene, RayCast *pRayCast)
{
if (SceneNode::VPick(pScene, pRayCast)==E_FAIL)
return E_FAIL;
pScene->PushAndSetMatrix(m_Props.ToWorld());
//Get the Mesh
Resource resource(m_sdkMeshFileName);
shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource);
shared_ptr<D3DSdkMeshResourceExtraData11> extra = static_pointer_cast<D3DSdkMeshResourceExtraData11>(pResourceHandle->GetExtra());
HRESULT hr = pRayCast->Pick(pScene, m_Props.ActorId(), &extra->m_Mesh11);
pScene->PopMatrix();
return hr;
}
float D3DShaderMeshNode11::CalcBoundingSphere(CDXUTSDKMesh *mesh11)
{
float radius = 0.0f;
for( UINT subset = 0; subset < mesh11->GetNumSubsets( 0 ); ++subset )
{
Vec3 extents = mesh11->GetMeshBBoxExtents(subset);
extents.x = abs(extents.x);
extents.y = abs(extents.y);
extents.z = abs(extents.z);
radius = (radius > extents.x) ? radius : extents.x;
radius = (radius > extents.y) ? radius : extents.y;
radius = (radius > extents.z) ? radius : extents.z;
}
return radius;
}
2. 着色器 Shader实现
#pragma once
//========================================================================
// Shaders.h - helper classes to call GameCode4_VS.hlsl and GameCode4_PS.hlsl
//========================================================================
#include <xnamath.h>
#include "Geometry.h"
#include "Material.h"
#define GCC_NEW new
#if !defined(SAFE_RELEASE)
#define SAFE_RELEASE(x) if(x) x->Release(); x=NULL;
#endif
//BaseRenderComponent defined in Actors folder
typedef BaseRenderComponent* WeakBaseRenderComponentPtr;
typedef unsigned int ActorId;
typedef unsigned int GameViewId;
typedef D3DXCOLOR Color;
typedef unsigned int DWORD;
typedef unsigned char BYTE;
typedef float FLOAT;
typedef unsigned int UINT;
#ifdef UNICODE
typedef wchar_t TCHAR;
#else
typedef unsigned char TCHAR;
#endif
typedef unsigned char CHAR;
typedef unsigned wchar_t WCHAR;
enum HRESULT
{
E_INVALIDARG,
E_FAIL,
S_OK,
};
// Forward declarations
class SceneNode;
class Scene;
class GameCode4_Hlsl_VertexShader
{
public:
GameCode4_Hlsl_VertexShader();
~GameCode4_Hlsl_VertexShader();
HRESULT OnRestore(Scene *pScene);
HRESULT SetupRender(Scene *pScene, SceneNode *pNode);
void EnableLights(bool enableLights) { m_enableLights = enableLights; }
protected:
ID3D11InputLayout* m_pVertexLayout11;
ID3D11VertexShader* m_pVertexShader;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ff476351(v=vs.85).aspx
ID3D11Buffer* m_pcbVSMatrices;
ID3D11Buffer* m_pcbVSLighting;
ID3D11Buffer* m_pcbVSMaterial;
bool m_enableLights;
};
class GameCode4_Hlsl_PixelShader
{
public:
GameCode4_Hlsl_PixelShader();
~GameCode4_Hlsl_PixelShader();
HRESULT OnRestore(Scene *pScene);
HRESULT SetupRender(Scene *pScene, SceneNode *pNode);
HRESULT SetTexture(const std::string& textureName);
HRESULT SetTexture(ID3D11ShaderResourceView* const *pDiffuseRV, ID3D11SamplerState * const *ppSamplers);
protected:
ID3D11PixelShader* m_pPixelShader;
ID3D11Buffer* m_pcbPSMaterial;
std::string m_textureResource;
};
// http://msdn.microsoft.com/en-us/library/windows/desktop/ff476652(v=vs.85).aspx
struct ID3DX11Effect;
struct ID3DX11EffectTechnique;
struct ID3DX11EffectPass;
class LineDraw_Hlsl_Shader
{
public:
LineDraw_Hlsl_Shader();
~LineDraw_Hlsl_Shader();
HRESULT OnRestore(Scene *pScene);
HRESULT SetupRender(Scene *pScene);
HRESULT SetDiffuse(const std::string& textureName, const Color &color);
HRESULT SetTexture(ID3D11ShaderResourceView* const *pDiffuseRV, ID3D11SamplerState * const *ppSamplers);
protected:
ID3D11InputLayout* m_pVertexLayout11;
ID3D11Buffer* m_pcbRenderTargetSize;
ID3DX11Effect* m_pEffect;
ID3DX11EffectTechnique* m_EffectTechnique; // No need to be Release()-d.
ID3DX11EffectPass* m_EffectPass; // No need to be Release()-d.
ID3D11Buffer* m_pcbChangePerFrame;
ID3D11Buffer* m_pcbDiffuseColor;
std::string m_textureResource;
};
//=============================================================================
// Shaders.cpp - helper classes to call GameCode4_VS.hlsl and GameCode4_PS.hlsl
//=============================================================================
#include "GameCodeStd.h"
#include "GameCode.h"
#include "D3DRenderer.h"
#include "Geometry.h"
#include "Lights.h"
#include "Mesh.h"
#include "SceneNodes.h"
#include "ResCache.h"
#include <xnamath.h>
#pragma comment(lib, "effects11.lib") // [mrmike] Note you can remove this if you don't want the D3DX11CreateEffectFromMemory API.
#include "d3dx11effect.h"
//
// GameCode4_Hlsl_VertexShader::GameCode4_Hlsl_VertexShader
//
GameCode4_Hlsl_VertexShader::GameCode4_Hlsl_VertexShader()
{
m_pVertexLayout11 = NULL;
m_pVertexShader = NULL;
m_pcbVSMatrices = NULL;
m_pcbVSLighting = NULL;
m_pcbVSMaterial = NULL;
m_enableLights = true;
}
//
// GameCode4_Hlsl_VertexShader::~GameCode4_Hlsl_VertexShader
//
GameCode4_Hlsl_VertexShader::~GameCode4_Hlsl_VertexShader()
{
SAFE_RELEASE(m_pVertexLayout11);
SAFE_RELEASE(m_pVertexShader);
SAFE_RELEASE(m_pcbVSMatrices);
SAFE_RELEASE(m_pcbVSLighting );
SAFE_RELEASE(m_pcbVSMaterial);
}
//
// GameCode4_Hlsl_VertexShader::OnRestore
//
HRESULT GameCode4_Hlsl_VertexShader::OnRestore(Scene *pScene)
{
HRESULT hr = S_OK;
SAFE_RELEASE(m_pVertexLayout11);
SAFE_RELEASE(m_pVertexShader);
SAFE_RELEASE(m_pcbVSMatrices);
SAFE_RELEASE(m_pcbVSLighting );
SAFE_RELEASE(m_pcbVSMaterial);
shared_ptr<D3DRenderer11> d3dRenderer11 = static_pointer_cast<D3DRenderer11>(pScene->GetRenderer());
//========================================================
// Set up the vertex shader and related constant buffers
// Compile the vertex shader using the lowest possible profile for broadest feature level support
ID3DBlob* pVertexShaderBuffer = NULL;
std::string hlslFileName = "Effects\\GameCode4_VS.hlsl";
Resource resource(hlslFileName.c_str());
shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource); // this actually loads the HLSL file from the zip file
if (FAILED (d3dRenderer11->CompileShader(pResourceHandle->Buffer(), pResourceHandle->Size(), hlslFileName.c_str(), "GameCode4_VSMain", "vs_4_0_level_9_1", &pVertexShaderBuffer ) ) )
{
SAFE_RELEASE (pVertexShaderBuffer);
return hr;
}
if (FAILED ( DXUTGetD3D11Device()->CreateVertexShader( pVertexShaderBuffer->GetBufferPointer(),
pVertexShaderBuffer->GetBufferSize(), NULL, &m_pVertexShader ) ) )
{
SAFE_RELEASE (pVertexShaderBuffer);
return hr;
}
DXUT_SetDebugName( m_pVertexShader, "GameCode4_VSMain" );
if (SUCCEEDED ( DXUTGetD3D11Device()->CreateInputLayout( D3D11VertexLayout_UnlitTextured, ARRAYSIZE( D3D11VertexLayout_UnlitTextured ), pVertexShaderBuffer->GetBufferPointer(),
pVertexShaderBuffer->GetBufferSize(), &m_pVertexLayout11 ) ) )
{
DXUT_SetDebugName( m_pVertexLayout11, "Primary" );
// Setup constant buffers
D3D11_BUFFER_DESC Desc;
Desc.Usage = D3D11_USAGE_DYNAMIC;
Desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
Desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
Desc.MiscFlags = 0;
Desc.ByteWidth = sizeof( ConstantBuffer_Matrices );
V_RETURN( DXUTGetD3D11Device()->CreateBuffer( &Desc, NULL, &m_pcbVSMatrices ) );
DXUT_SetDebugName( m_pcbVSMatrices, "ConstantBuffer_Matrices" );
Desc.ByteWidth = sizeof( ConstantBuffer_Lighting );
V_RETURN( DXUTGetD3D11Device()->CreateBuffer( &Desc, NULL, &m_pcbVSLighting ) );
DXUT_SetDebugName( m_pcbPSLighting, "ConstantBuffer_Lighting" );
Desc.ByteWidth = sizeof( ConstantBuffer_Material );
V_RETURN( DXUTGetD3D11Device()->CreateBuffer( &Desc, NULL, &m_pcbVSMaterial ) );
DXUT_SetDebugName( m_pcbVSMaterial, "ConstantBuffer_Material" );
}
SAFE_RELEASE( pVertexShaderBuffer );
return S_OK;
}
//
// GameCode4_Hlsl_VertexShader::SetupRender
//
HRESULT GameCode4_Hlsl_VertexShader::SetupRender(Scene *pScene, SceneNode *pNode)
{
HRESULT hr = S_OK;
// Set the vertex shader and the vertex layout
DXUTGetD3D11DeviceContext()->VSSetShader( m_pVertexShader, NULL, 0 );
DXUTGetD3D11DeviceContext()->IASetInputLayout( m_pVertexLayout11 );
// Get the projection & view matrix from the camera class
Mat4x4 mWorldViewProjection = pScene->GetCamera()->GetWorldViewProjection(pScene);
Mat4x4 mWorld = pScene->GetTopMatrix();
D3D11_MAPPED_SUBRESOURCE MappedResource;
// ----- Transform Matricies ------
V( DXUTGetD3D11DeviceContext()->Map( m_pcbVSMatrices, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
ConstantBuffer_Matrices* pVSMatricies = ( ConstantBuffer_Matrices* )MappedResource.pData;
D3DXMatrixTranspose( &pVSMatricies->m_WorldViewProj, &mWorldViewProjection );
D3DXMatrixTranspose( &pVSMatricies->m_World, &mWorld );
DXUTGetD3D11DeviceContext()->Unmap( m_pcbVSMatrices, 0 );
// ----- Lighting ------
V( DXUTGetD3D11DeviceContext()->Map( m_pcbVSLighting, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
ConstantBuffer_Lighting* pLighting = ( ConstantBuffer_Lighting* )MappedResource.pData;
if (m_enableLights)
{
pScene->GetLightManager()->CalcLighting(pLighting, pNode);
}
else
{
pLighting->m_nNumLights = 0;
pLighting->m_vLightAmbient = Vec4(1.0f, 1.0f, 1.0f, 1.0f);
}
DXUTGetD3D11DeviceContext()->Unmap( m_pcbVSLighting, 0 );
// ----- Material ------
V( DXUTGetD3D11DeviceContext()->Map( m_pcbVSMaterial, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
ConstantBuffer_Material* pPSMaterial = ( ConstantBuffer_Material* )MappedResource.pData;
Color color = pNode->VGet()->GetMaterial().GetDiffuse();
pPSMaterial->m_vDiffuseObjectColor = Vec4(color.r, color.g, color.b, color.a);
color = (m_enableLights) ? pNode->VGet()->GetMaterial().GetAmbient() : Color(1.0f, 1.0f, 1.0f, 1.0f);
pPSMaterial->m_vAmbientObjectColor = Vec4(color.r, color.g, color.b, color.a);
// Note - the vertex shader doesn't care about the texture one way or another so we'll just set it to false
pPSMaterial->m_bHasTexture = false;
DXUTGetD3D11DeviceContext()->Unmap( m_pcbVSMaterial, 0 );
DXUTGetD3D11DeviceContext()->VSSetConstantBuffers( 0, 1, &m_pcbVSMatrices );
DXUTGetD3D11DeviceContext()->VSSetConstantBuffers( 1, 1, &m_pcbVSLighting );
DXUTGetD3D11DeviceContext()->VSSetConstantBuffers( 2, 1, &m_pcbVSMaterial );
return S_OK;
}
//
// GameCode4_Hlsl_PixelShader::GameCode4_Hlsl_PixelShader
//
GameCode4_Hlsl_PixelShader::GameCode4_Hlsl_PixelShader()
{
m_pPixelShader = NULL;
m_pcbPSMaterial = NULL;
}
//
// GameCode4_Hlsl_PixelShader::~GameCode4_Hlsl_PixelShader
//
GameCode4_Hlsl_PixelShader::~GameCode4_Hlsl_PixelShader()
{
SAFE_RELEASE(m_pPixelShader);
SAFE_RELEASE(m_pcbPSMaterial);
}
//
// GameCode4_Hlsl_PixelShader::OnRestore
//
HRESULT GameCode4_Hlsl_PixelShader::OnRestore(Scene *pScene)
{
HRESULT hr = S_OK;
SAFE_RELEASE(m_pPixelShader);
SAFE_RELEASE(m_pcbPSMaterial);
shared_ptr<D3DRenderer11> d3dRenderer11 = static_pointer_cast<D3DRenderer11>(pScene->GetRenderer());
//========================================================
// Set up the pixel shader and related constant buffers
// Compile the pixel shader using the lowest possible profile for broadest feature level support
ID3DBlob* pPixelShaderBuffer = NULL;
std::string hlslFileName = "Effects\\GameCode4_PS.hlsl";
Resource resource(hlslFileName.c_str());
shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource); // this actually loads the HLSL file from the zip file
if (FAILED (d3dRenderer11->CompileShader(pResourceHandle->Buffer(), pResourceHandle->Size(), hlslFileName.c_str(), "GameCode4_PSMain", "ps_4_0_level_9_1", &pPixelShaderBuffer ) ) )
{
SAFE_RELEASE (pPixelShaderBuffer);
return hr;
}
if (SUCCEEDED ( DXUTGetD3D11Device()->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer(),
pPixelShaderBuffer->GetBufferSize(), NULL, &m_pPixelShader ) ) )
{
DXUT_SetDebugName( m_pPixelShader, "GameCode4_PSMain" );
// Setup constant buffers
D3D11_BUFFER_DESC Desc;
Desc.Usage = D3D11_USAGE_DYNAMIC;
Desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
Desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
Desc.MiscFlags = 0;
Desc.ByteWidth = sizeof( ConstantBuffer_Material );
hr = DXUTGetD3D11Device()->CreateBuffer( &Desc, NULL, &m_pcbPSMaterial );
DXUT_SetDebugName( m_pcbPSMaterial, "ConstantBuffer_Material" );
}
SAFE_RELEASE( pPixelShaderBuffer );
return hr;
}
//
// GameCode4_Hlsl_PixelShader::SetupRender
//
HRESULT GameCode4_Hlsl_PixelShader::SetupRender(Scene *pScene, SceneNode *pNode)
{
HRESULT hr = S_OK;
DXUTGetD3D11DeviceContext()->PSSetShader( m_pPixelShader, NULL, 0 );
D3D11_MAPPED_SUBRESOURCE MappedResource;
V( DXUTGetD3D11DeviceContext()->Map( m_pcbPSMaterial, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
ConstantBuffer_Material* pPSMaterial = ( ConstantBuffer_Material* )MappedResource.pData;
Color color = pNode->VGet()->GetMaterial().GetDiffuse();
pPSMaterial->m_vDiffuseObjectColor = Vec4(color.r, color.g, color.b, color.a);
if (m_textureResource.length() > 0)
{
pPSMaterial->m_bHasTexture = true;
}
else
{
pPSMaterial->m_bHasTexture = false;
}
DXUTGetD3D11DeviceContext()->Unmap( m_pcbPSMaterial, 0 );
DXUTGetD3D11DeviceContext()->PSSetConstantBuffers( 0, 1, &m_pcbPSMaterial );
// Set up the texture
SetTexture(m_textureResource);
return S_OK;
}
//
// GameCode4_Hlsl_PixelShader::SetTexture
//
HRESULT GameCode4_Hlsl_PixelShader::SetTexture(const std::string& textureName)
{
m_textureResource = textureName;
if (m_textureResource.length() > 0)
{
Resource resource(m_textureResource);
shared_ptr<ResHandle> texture = g_pApp->m_ResCache->GetHandle(&resource);
if (texture)
{
shared_ptr<D3DTextureResourceExtraData11> extra = static_pointer_cast<D3DTextureResourceExtraData11>(texture->GetExtra());
SetTexture(extra->GetTexture(), extra->GetSampler());
}
}
return S_OK;
}
HRESULT GameCode4_Hlsl_PixelShader::SetTexture(ID3D11ShaderResourceView* const *pDiffuseRV, ID3D11SamplerState * const *ppSamplers)
{
DXUTGetD3D11DeviceContext()->PSSetShaderResources( 0, 1, pDiffuseRV );
DXUTGetD3D11DeviceContext()->PSSetSamplers( 0, 1, ppSamplers );
return S_OK;
}
struct LineDrawerChangePerFrameBuffer
{
Mat4x4 m_WorldViewProjection;
Vec4 m_DiffuseColor;
};
LineDraw_Hlsl_Shader::LineDraw_Hlsl_Shader()
{
m_pEffect = NULL;
m_pVertexLayout11 = NULL;
m_pcbChangePerFrame = NULL;
m_pcbRenderTargetSize = NULL;
m_pcbDiffuseColor = NULL;
}
LineDraw_Hlsl_Shader::~LineDraw_Hlsl_Shader()
{
SAFE_RELEASE(m_pVertexLayout11);
SAFE_RELEASE(m_pcbChangePerFrame);
SAFE_RELEASE(m_pcbRenderTargetSize);
SAFE_RELEASE(m_pcbDiffuseColor);
SAFE_RELEASE(m_pEffect);
}
HRESULT LineDraw_Hlsl_Shader::OnRestore(Scene *pScene)
{
HRESULT hr = S_OK;
SAFE_RELEASE(m_pEffect);
SAFE_RELEASE(m_pcbDiffuseColor);
SAFE_RELEASE(m_pVertexLayout11);
SAFE_RELEASE(m_pcbChangePerFrame);
SAFE_RELEASE(m_pcbRenderTargetSize);
shared_ptr<D3DRenderer11> d3dRenderer11 = static_pointer_cast<D3DRenderer11>(pScene->GetRenderer());
//========================================================
// Set up the vertex shader and related constant buffers
// Compile the vertex shader using the lowest possible profile for broadest feature level support
ID3DBlob* pVertexShaderBuffer = NULL;
std::string hlslFileName = "Effects\\LineDraw.hlsl";
Resource resource(hlslFileName.c_str());
shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource); // this actually loads the HLSL file from the zip file
// Compile effect from HLSL file into binary Blob in memory
// The code in this function was found here - http://asawicki.info/news_1371_effects_in_directx_11.html
ID3D10Blob *effectBlob = 0, *errorsBlob = 0;
hr = D3DX11CompileFromMemory(
pResourceHandle->Buffer(), // srcData
pResourceHandle->Size(), // srcLen
0, 0, 0, 0, // fileName, pDefines, pInclude, functionName
"fx_5_0", 0, 0, 0, // profile, flags1, flags2, pump
&effectBlob, &errorsBlob, 0); // shader, errorMsg, pResult
assert(SUCCEEDED(hr) && effectBlob);
if (errorsBlob) errorsBlob->Release();
// Create D3DX11 effect from compiled binary memory block
if (FAILED ( D3DX11CreateEffectFromMemory(
effectBlob->GetBufferPointer(), effectBlob->GetBufferSize(), 0, DXUTGetD3D11Device(), &m_pEffect) ) )
{
return hr;
}
effectBlob->Release();
m_EffectTechnique = m_pEffect->GetTechniqueByIndex(0);
GCC_ASSERT(m_EffectTechnique && m_EffectTechnique->IsValid());
m_EffectPass = m_EffectTechnique->GetPassByIndex(0);
GCC_ASSERT(m_EffectPass && m_EffectPass->IsValid());
D3DX11_PASS_SHADER_DESC effectVsDesc;
m_EffectPass->GetVertexShaderDesc(&effectVsDesc);
D3DX11_EFFECT_SHADER_DESC effectVsDesc2;
effectVsDesc.pShaderVariable->GetShaderDesc(effectVsDesc.ShaderIndex, &effectVsDesc2);
const void *vsCodePtr = effectVsDesc2.pBytecode;
unsigned vsCodeLen = effectVsDesc2.BytecodeLength;
if (SUCCEEDED ( DXUTGetD3D11Device()->CreateInputLayout( D3D11VertexLayout_Position, ARRAYSIZE( D3D11VertexLayout_Position ), vsCodePtr, vsCodeLen, &m_pVertexLayout11 ) ) )
{
DXUT_SetDebugName( m_pVertexLayout11, "Primary" );
// Setup constant buffers
D3D11_BUFFER_DESC Desc;
Desc.Usage = D3D11_USAGE_DYNAMIC;
Desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
Desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
Desc.MiscFlags = 0;
Desc.ByteWidth = sizeof( Vec4 );
V_RETURN( DXUTGetD3D11Device()->CreateBuffer( &Desc, NULL, &m_pcbRenderTargetSize) );
DXUT_SetDebugName( m_pcbRenderTargetSize, "Vec4_RenderTargetSize" );
Desc.ByteWidth = sizeof( Mat4x4 );
V_RETURN( DXUTGetD3D11Device()->CreateBuffer( &Desc, NULL, &m_pcbChangePerFrame ) );
DXUT_SetDebugName( m_pcbChangePerFrame, "LineDrawerChangePerFrameBuffer" );
Desc.ByteWidth = sizeof( Vec4 );
V_RETURN( DXUTGetD3D11Device()->CreateBuffer( &Desc, NULL, &m_pcbDiffuseColor ) );
DXUT_SetDebugName( m_pcbDiffuseColor, "DiffuseColor" );
}
SAFE_RELEASE( pVertexShaderBuffer );
return S_OK;
}
//
// GameCode4_Hlsl_VertexShader::SetupRender
//
HRESULT LineDraw_Hlsl_Shader::SetupRender(Scene *pScene)
{
HRESULT hr = S_OK;
m_EffectPass->Apply(0, DXUTGetD3D11DeviceContext());
DXUTGetD3D11DeviceContext()->IASetInputLayout( m_pVertexLayout11 );
D3D11_MAPPED_SUBRESOURCE MappedResource;
// ----- Render Target Size ------
V( DXUTGetD3D11DeviceContext()->Map( m_pcbRenderTargetSize, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
Vec4 * pRenderTargetSize = ( Vec4 * )MappedResource.pData;
pRenderTargetSize->x = (FLOAT)DXUTGetWindowWidth();
pRenderTargetSize->y = (FLOAT)DXUTGetWindowHeight();
pRenderTargetSize->z = 0.0f;
pRenderTargetSize->w = 0.0f;
DXUTGetD3D11DeviceContext()->Unmap( m_pcbRenderTargetSize, 0 );
// ----- Transform Matricies ------
V( DXUTGetD3D11DeviceContext()->Map( m_pcbChangePerFrame, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
LineDrawerChangePerFrameBuffer * pChangePerFrame = ( LineDrawerChangePerFrameBuffer* )MappedResource.pData;
Mat4x4 mWorldViewProjection = pScene->GetCamera()->GetWorldViewProjection(pScene);
D3DXMatrixTranspose( &pChangePerFrame->m_WorldViewProjection, &mWorldViewProjection );
DXUTGetD3D11DeviceContext()->Unmap( m_pcbChangePerFrame, 0 );
// ----- Constant Buffers -----
ID3DX11EffectConstantBuffer* fxRenderTargetCB = m_pEffect->GetConstantBufferByName("cbRenderTarget")->AsConstantBuffer();
ID3DX11EffectConstantBuffer* fxChangePerFrameCB = m_pEffect->GetConstantBufferByName("cbChangePerFrame")->AsConstantBuffer();
ID3DX11EffectConstantBuffer* fxDiffuseCB = m_pEffect->GetConstantBufferByName("cbDiffuseColor")->AsConstantBuffer();
fxRenderTargetCB->SetConstantBuffer(m_pcbRenderTargetSize);
fxChangePerFrameCB->SetConstantBuffer(m_pcbChangePerFrame);
fxDiffuseCB->SetConstantBuffer(m_pcbDiffuseColor);
return S_OK;
}
// FUTURE WORK - Creating a component like architecture for C++ shader integration would be a good idea!
// For example - a texture component like the one below is almost exactly line the one
// int the GameCode4_Hlsl_PixelShader - this could be factored into a single component.
HRESULT LineDraw_Hlsl_Shader::SetDiffuse(const std::string& textureName, const Color &color)
{
m_textureResource = textureName;
if (m_textureResource.length() > 0)
{
Resource resource(m_textureResource);
shared_ptr<ResHandle> texture = g_pApp->m_ResCache->GetHandle(&resource);
if (texture)
{
shared_ptr<D3DTextureResourceExtraData11> extra = static_pointer_cast<D3DTextureResourceExtraData11>(texture->GetExtra());
SetTexture(extra->GetTexture(), extra->GetSampler());
}
}
HRESULT hr;
D3D11_MAPPED_SUBRESOURCE MappedResource;
// ----- Diffuse Color ------
V( DXUTGetD3D11DeviceContext()->Map( m_pcbDiffuseColor, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) );
Vec4 * pDiffuseColor = ( Vec4* )MappedResource.pData;
*pDiffuseColor = Vec4(color.r, color.g, color.b, color.a);
DXUTGetD3D11DeviceContext()->Unmap( m_pcbDiffuseColor, 0 );
return S_OK;
}
HRESULT LineDraw_Hlsl_Shader::SetTexture(ID3D11ShaderResourceView* const *pDiffuseRV, ID3D11SamplerState * const *ppSamplers)
{
DXUTGetD3D11DeviceContext()->PSSetShaderResources( 0, 1, pDiffuseRV );
DXUTGetD3D11DeviceContext()->PSSetSamplers( 0, 1, ppSamplers );
return S_OK;
}
以上就是网和着色器的实现,它们大大增强了游戏的画面效果,令游戏呈现出绚丽多彩的画面。下一篇关于
光线投射和天空盒子 Raycast and Sky~~