首页 > 代码库 > 游戏框架其九:网和着色器( Mesh and Shader )
游戏框架其九:网和着色器( Mesh and Shader )
网的重要作用可以导入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~~
游戏框架其九:网和着色器( Mesh and Shader )
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。