diff --git a/src/SpeedTreeLib/SpeedTreeConfig.h b/src/SpeedTreeLib/SpeedTreeConfig.h index 9a0f86f..b1f736c 100644 --- a/src/SpeedTreeLib/SpeedTreeConfig.h +++ b/src/SpeedTreeLib/SpeedTreeConfig.h @@ -72,8 +72,8 @@ const float c_afLightGlobalAmbient[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; #endif // leaf placement algorithm (enable ONE of the two below) -//#define WRAPPER_USE_GPU_LEAF_PLACEMENT -#define WRAPPER_USE_CPU_LEAF_PLACEMENT +#define WRAPPER_USE_GPU_LEAF_PLACEMENT +//#define WRAPPER_USE_CPU_LEAF_PLACEMENT #if defined WRAPPER_USE_GPU_LEAF_PLACEMENT && defined WRAPPER_USE_CPU_LEAF_PLACEMENT #error Please define exactly one leaf placement algorithm diff --git a/src/SpeedTreeLib/SpeedTreeForestDirectX8.cpp b/src/SpeedTreeLib/SpeedTreeForestDirectX8.cpp index 1beea30..cd9de0d 100644 --- a/src/SpeedTreeLib/SpeedTreeForestDirectX8.cpp +++ b/src/SpeedTreeLib/SpeedTreeForestDirectX8.cpp @@ -45,7 +45,7 @@ /////////////////////////////////////////////////////////////////////// // CSpeedTreeForestDirectX8::CSpeedTreeForestDirectX8 -CSpeedTreeForestDirectX8::CSpeedTreeForestDirectX8() : m_dwBranchVertexShader(0), m_dwLeafVertexShader(0) +CSpeedTreeForestDirectX8::CSpeedTreeForestDirectX8() : m_dwBranchVertexShader(nullptr), m_pLeafVertexShaderDecl(nullptr), m_pLeafVertexShader(nullptr) { } @@ -66,12 +66,12 @@ bool CSpeedTreeForestDirectX8::InitVertexShaders(void) if (!m_dwBranchVertexShader) m_dwBranchVertexShader = LoadBranchShader(m_pDx); - if (!m_dwLeafVertexShader) - m_dwLeafVertexShader = LoadLeafShader(m_pDx); + if (!m_pLeafVertexShaderDecl || !m_pLeafVertexShader) + LoadLeafShader(m_pDx, m_pLeafVertexShaderDecl, m_pLeafVertexShader); - if (m_dwBranchVertexShader && m_dwLeafVertexShader) + if (m_dwBranchVertexShader && m_pLeafVertexShaderDecl && m_pLeafVertexShader) { - CSpeedTreeWrapper::SetVertexShaders(m_dwBranchVertexShader, m_dwLeafVertexShader); + CSpeedTreeWrapper::SetVertexShaders(m_dwBranchVertexShader, m_pLeafVertexShaderDecl, m_pLeafVertexShader); return true; } @@ -261,7 +261,8 @@ void CSpeedTreeForestDirectX8::Render(unsigned long ulRenderBitVector) // render leaves if (ulRenderBitVector & Forest_RenderLeaves) { - STATEMANAGER.SetVertexDeclaration(m_dwLeafVertexShader); + STATEMANAGER.SetVertexDeclaration(m_pLeafVertexShaderDecl); + STATEMANAGER.SaveVertexShader(m_pLeafVertexShader); if (STATEMANAGER.GetRenderState(D3DRS_FOGENABLE)) { @@ -298,6 +299,7 @@ void CSpeedTreeForestDirectX8::Render(unsigned long ulRenderBitVector) STATEMANAGER.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF); } + STATEMANAGER.RestoreVertexShader(); } // render billboards diff --git a/src/SpeedTreeLib/SpeedTreeForestDirectX8.h b/src/SpeedTreeLib/SpeedTreeForestDirectX8.h index 9b6259e..5cfa5f0 100644 --- a/src/SpeedTreeLib/SpeedTreeForestDirectX8.h +++ b/src/SpeedTreeLib/SpeedTreeForestDirectX8.h @@ -59,6 +59,8 @@ class CSpeedTreeForestDirectX8 : public CSpeedTreeForest, public CGraphicBase, p private: LPDIRECT3DDEVICE9 m_pDx; // the rendering context - LPDIRECT3DVERTEXDECLARATION9 m_dwBranchVertexShader; // branch/frond vertex shaders - LPDIRECT3DVERTEXDECLARATION9 m_dwLeafVertexShader; // leaf vertex shader + LPDIRECT3DVERTEXDECLARATION9 m_dwBranchVertexShader; // branch/frond vertex shaders + + LPDIRECT3DVERTEXDECLARATION9 m_pLeafVertexShaderDecl; // leaf vertex shader declaration + LPDIRECT3DVERTEXSHADER9 m_pLeafVertexShader; // leaf vertex shader }; diff --git a/src/SpeedTreeLib/SpeedTreeWrapper.cpp b/src/SpeedTreeLib/SpeedTreeWrapper.cpp index 5be0aa6..a66c581 100644 --- a/src/SpeedTreeLib/SpeedTreeWrapper.cpp +++ b/src/SpeedTreeLib/SpeedTreeWrapper.cpp @@ -50,8 +50,9 @@ using namespace std; -LPDIRECT3DVERTEXDECLARATION9 CSpeedTreeWrapper::ms_dwBranchVertexShader = 0; -LPDIRECT3DVERTEXDECLARATION9 CSpeedTreeWrapper::ms_dwLeafVertexShader = 0; +LPDIRECT3DVERTEXDECLARATION9 CSpeedTreeWrapper::ms_dwBranchVertexShader = nullptr; +LPDIRECT3DVERTEXDECLARATION9 CSpeedTreeWrapper::ms_pLeafVertexShaderDecl = nullptr; +LPDIRECT3DVERTEXSHADER9 CSpeedTreeWrapper::ms_pLeafVertexShader = nullptr; bool CSpeedTreeWrapper::ms_bSelfShadowOn = true; /////////////////////////////////////////////////////////////////////// @@ -81,10 +82,11 @@ m_pTextureInfo(NULL) m_pSpeedTree->SetLocalMatrices(0, 4); } -void CSpeedTreeWrapper::SetVertexShaders(LPDIRECT3DVERTEXDECLARATION9 dwBranchVertexShader, LPDIRECT3DVERTEXDECLARATION9 dwLeafVertexShader) +void CSpeedTreeWrapper::SetVertexShaders(LPDIRECT3DVERTEXDECLARATION9 pBranchVertexShader, LPDIRECT3DVERTEXDECLARATION9 pLeafVertexShader, LPDIRECT3DVERTEXSHADER9 pVertexShader) { - ms_dwBranchVertexShader = dwBranchVertexShader; - ms_dwLeafVertexShader = dwLeafVertexShader; + ms_dwBranchVertexShader = pBranchVertexShader; + ms_pLeafVertexShaderDecl = pLeafVertexShader; + ms_pLeafVertexShader = pVertexShader; } void CSpeedTreeWrapper::OnRenderPCBlocker() @@ -95,12 +97,6 @@ void CSpeedTreeWrapper::OnRenderPCBlocker() //LogBox("Vertex Shader not assigned. You must call CSpeedTreeWrapper::SetVertexShader for this"); } - if (ms_dwLeafVertexShader == 0) - { - ms_dwLeafVertexShader = LoadLeafShader(ms_lpd3dDevice); - //LogBox("Vertex Shader not assigned. You must call CSpeedTreeWrapper::SetVertexShader for this"); - } - CSpeedTreeForestDirectX8::Instance().UpdateSystem(ELTimer_GetMSec() / 1000.0f); // Çϳª¸¸ ·»´õ¸µ ÇÒ ¶§´Â LOD »ç¿ëÇÏÁö ¾ÊÀ½ @@ -204,7 +200,8 @@ void CSpeedTreeWrapper::OnRenderPCBlocker() } RenderFronds(); - STATEMANAGER.SetVertexDeclaration(ms_dwLeafVertexShader); + STATEMANAGER.SetVertexDeclaration(ms_pLeafVertexShaderDecl); + STATEMANAGER.SaveVertexShader(ms_pLeafVertexShader); // SetupLeafForTreeType(); { @@ -218,6 +215,7 @@ void CSpeedTreeWrapper::OnRenderPCBlocker() } RenderLeaves(); EndLeafForTreeType(); + STATEMANAGER.RestoreVertexShader(); STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE); @@ -242,12 +240,6 @@ void CSpeedTreeWrapper::OnRender() //LogBox("Vertex Shader not assigned. You must call CSpeedTreeWrapper::SetVertexShader for this"); } - if (ms_dwLeafVertexShader == 0) - { - ms_dwLeafVertexShader = LoadLeafShader(ms_lpd3dDevice); - //LogBox("Vertex Shader not assigned. You must call CSpeedTreeWrapper::SetVertexShader for this"); - } - CSpeedTreeForestDirectX8::Instance().UpdateSystem(ELTimer_GetMSec() / 1000.0f); // Çϳª¸¸ ·»´õ¸µ ÇÒ ¶§´Â LOD »ç¿ëÇÏÁö ¾ÊÀ½ @@ -288,11 +280,13 @@ void CSpeedTreeWrapper::OnRender() SetupFrondForTreeType(); RenderFronds(); - STATEMANAGER.SetVertexDeclaration(ms_dwLeafVertexShader); + STATEMANAGER.SetVertexDeclaration(ms_pLeafVertexShaderDecl); + STATEMANAGER.SaveVertexShader(ms_pLeafVertexShader); SetupLeafForTreeType(); RenderLeaves(); EndLeafForTreeType(); + STATEMANAGER.RestoreVertexShader(); STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE); @@ -683,9 +677,9 @@ void CSpeedTreeWrapper::SetupLeafBuffers(void) SFVFLeafVertex* pVertexBuffer = NULL; // create the vertex buffer for storing leaf vertices #ifndef WRAPPER_USE_CPU_LEAF_PLACEMENT - ms_lpd3dDevice->CreateVertexBuffer(usLeafCount * 6 * sizeof(SFVFLeafVertex), D3DUSAGE_WRITEONLY, D3DFVF_SPEEDTREE_LEAF_VERTEX, D3DPOOL_MANAGED, &m_pLeafVertexBuffer[unLod]); + ms_lpd3dDevice->CreateVertexBuffer(usLeafCount * 6 * sizeof(SFVFLeafVertex), D3DUSAGE_WRITEONLY, D3DFVF_SPEEDTREE_LEAF_VERTEX, D3DPOOL_MANAGED, &m_pLeafVertexBuffer[unLod], nullptr); // fill the vertex buffer by interleaving SpeedTree data - m_pLeafVertexBuffer[unLod]->Lock(0, 0, reinterpret_cast(&pVertexBuffer), 0); + m_pLeafVertexBuffer[unLod]->Lock(0, 0, reinterpret_cast(&pVertexBuffer), 0); #else ms_lpd3dDevice->CreateVertexBuffer(usLeafCount * 6 * sizeof(SFVFLeafVertex), D3DUSAGE_DYNAMIC, D3DFVF_SPEEDTREE_LEAF_VERTEX, D3DPOOL_SYSTEMMEM, &m_pLeafVertexBuffer[unLod], NULL); // fill the vertex buffer by interleaving SpeedTree data diff --git a/src/SpeedTreeLib/SpeedTreeWrapper.h b/src/SpeedTreeLib/SpeedTreeWrapper.h index b338c11..ce9e2b3 100644 --- a/src/SpeedTreeLib/SpeedTreeWrapper.h +++ b/src/SpeedTreeLib/SpeedTreeWrapper.h @@ -34,6 +34,7 @@ /////////////////////////////////////////////////////////////////////// // Include files +#include "SpeedTreeConfig.h" #include "SpeedTreeMaterial.h" #include @@ -99,7 +100,7 @@ public: virtual ~CSpeedTreeWrapper(); const float * GetPosition(); - static void SetVertexShaders(LPDIRECT3DVERTEXDECLARATION9 dwBranchVertexShader, LPDIRECT3DVERTEXDECLARATION9 dwLeafVertexShader); + static void SetVertexShaders(LPDIRECT3DVERTEXDECLARATION9 pBranchVertexShader, LPDIRECT3DVERTEXDECLARATION9 pLeafVertexShader, LPDIRECT3DVERTEXSHADER9 pVertexShader); // geometry bool LoadTree(const char * pszSptFile, const BYTE * c_pbBlock = NULL, unsigned int uiBlockSize = 0, unsigned int nSeed = 1, float fSize = -1.0f, float fSizeVariance = -1.0f); @@ -197,7 +198,8 @@ private: CGraphicImageInstance m_CompositeImageInstance; static LPDIRECT3DVERTEXDECLARATION9 ms_dwBranchVertexShader; - static LPDIRECT3DVERTEXDECLARATION9 ms_dwLeafVertexShader; + static LPDIRECT3DVERTEXDECLARATION9 ms_pLeafVertexShaderDecl; + static LPDIRECT3DVERTEXSHADER9 ms_pLeafVertexShader; }; #pragma warning(pop) diff --git a/src/SpeedTreeLib/VertexShaders.h b/src/SpeedTreeLib/VertexShaders.h index b49c602..515cb38 100644 --- a/src/SpeedTreeLib/VertexShaders.h +++ b/src/SpeedTreeLib/VertexShaders.h @@ -196,6 +196,18 @@ static const char g_achLeafVertexProgram[] = { "vs.1.1\n" // identity shader version + "dcl_position v0\n" + +#ifdef WRAPPER_USE_STATIC_LIGHTING + "dcl_color v5\n" +#else + "dcl_normal v3\n" +#endif + "dcl_texcoord0 v7\n" +#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT + "dcl_texcoord2 v9\n" +#endif + "mov oT0.xy, v7\n" // always pass texcoord0 through #ifdef WRAPPER_USE_GPU_WIND @@ -245,27 +257,43 @@ static const char g_achLeafVertexProgram[] = /////////////////////////////////////////////////////////////////////// // LoadLeafShader -static LPDIRECT3DVERTEXDECLARATION9 LoadLeafShader(LPDIRECT3DDEVICE9 pDx) +static void LoadLeafShader(LPDIRECT3DDEVICE9 pDx, LPDIRECT3DVERTEXDECLARATION9& pVertexDecl, LPDIRECT3DVERTEXSHADER9& pVertexShader) { - // leaf shader declaration - D3DVERTEXELEMENT9 pLeafShaderDecl[] = { - { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, - { 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, - { 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, - { 0, 24, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 }, - D3DDECL_END() + SAFE_RELEASE(pVertexDecl); + SAFE_RELEASE(pVertexShader); + + const D3DVERTEXELEMENT9 leafVertexDecl[] = { + { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, +#ifdef WRAPPER_USE_DYNAMIC_LIGHTING + { 0, 12, D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, + { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, + #if defined WRAPPER_USE_GPU_WIND || defined WRAPPER_USE_GPU_LEAF_PLACEMENT + { 0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 }, + #endif +#else + { 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, + { 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, + #if defined WRAPPER_USE_GPU_WIND || defined WRAPPER_USE_GPU_LEAF_PLACEMENT + { 0, 24, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 }, + #endif +#endif + D3DDECL_END() }; - // assemble shader - LPDIRECT3DVERTEXDECLARATION9 dwShader = NULL; - - if (pDx->CreateVertexDeclaration(pLeafShaderDecl, &dwShader) != D3D_OK) - { - char szError[1024]; - sprintf_s(szError, "Failed to create leaf vertex shader."); - MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP); - + LPD3DXBUFFER pCode = nullptr, pError = nullptr; + if (D3DXAssembleShader(g_achLeafVertexProgram, sizeof(g_achLeafVertexProgram) - 1, nullptr, nullptr, 0, &pCode, &pError) == D3D_OK) { + if (pDx->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), &pVertexShader) != D3D_OK) { + TraceError("Failed to create leaf vertex shader."); + } + } + else { + TraceError("Failed to assemble leaf vertex shader. The error reported is [ %s ].", pError->GetBufferPointer()); } - return dwShader; + if (FAILED(pDx->CreateVertexDeclaration(leafVertexDecl, &pVertexDecl))) { + TraceError("Failed to create leaf vertex declaration"); + } + + SAFE_RELEASE(pCode); + SAFE_RELEASE(pError); }