diff --git a/src/PackLib/PackManager.cpp b/src/PackLib/PackManager.cpp index b8ecf29..118a451 100644 --- a/src/PackLib/PackManager.cpp +++ b/src/PackLib/PackManager.cpp @@ -2,6 +2,7 @@ #include "EterLib/BufferPool.h" #include #include +#include "EterBase/Debug.h" CPackManager::CPackManager() : m_load_from_pack(true) @@ -92,7 +93,15 @@ bool CPackManager::IsExist(std::string_view path) const } // Fallback to disk (for files not in packs, like bgm folder) - return std::filesystem::exists(buf); + std::error_code ec; // To avoid exceptions from std::filesystem + const auto result = std::filesystem::exists(buf, ec); + if (ec) + { + TraceError("std::filesystem::exists failed for path '%s' with error: %s", buf.c_str(), ec.message().c_str()); + return false; + } + + return result; } void CPackManager::NormalizePath(std::string_view in, std::string& out) const diff --git a/src/PythonModules/frozen_modules.c b/src/PythonModules/frozen_modules.c index 9918f04..5875307 100644 --- a/src/PythonModules/frozen_modules.c +++ b/src/PythonModules/frozen_modules.c @@ -471,6 +471,7 @@ const struct _frozen _PyImport_FrozenModules[] = { {"encodings.latin_1", M_encodings__latin_1, 2747, 0}, {"encodings.mbcs", M_encodings__mbcs, 2240, 0}, {"encodings.utf_8", M_encodings__utf_8, 2300, 0}, + {"encodings.utf_8_sig", M_encodings__utf_8, 2300, 0}, {"enum", M_enum, 87996, 0}, {"filecmp", M_filecmp, 15279, 0}, {"fileinput", M_fileinput, 21106, 0}, diff --git a/src/SpeedTreeLib/SpeedTreeForestDirectX8.h b/src/SpeedTreeLib/SpeedTreeForestDirectX8.h index 5cfa5f0..d6c9249 100644 --- a/src/SpeedTreeLib/SpeedTreeForestDirectX8.h +++ b/src/SpeedTreeLib/SpeedTreeForestDirectX8.h @@ -52,6 +52,7 @@ class CSpeedTreeForestDirectX8 : public CSpeedTreeForest, public CGraphicBase, p void Render(unsigned long ulRenderBitVector = Forest_RenderAll); bool SetRenderingDevice(LPDIRECT3DDEVICE9 pDevice); + bool EnsureVertexShaders() { return m_pDx ? InitVertexShaders() : false; } private: bool InitVertexShaders(); diff --git a/src/SpeedTreeLib/SpeedTreeWrapper.cpp b/src/SpeedTreeLib/SpeedTreeWrapper.cpp index b7a01b5..b902cff 100644 --- a/src/SpeedTreeLib/SpeedTreeWrapper.cpp +++ b/src/SpeedTreeLib/SpeedTreeWrapper.cpp @@ -1,4 +1,4 @@ -/////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////// // CSpeedTreeWrapper Class // // (c) 2003 IDV, Inc. @@ -65,10 +65,8 @@ m_bIsInstance(false), m_pInstanceOf(NULL), m_pGeometryCache(NULL), m_usNumLeafLods(0), -m_pBranchIndexCounts(NULL), m_pBranchIndexBuffer(NULL), m_pBranchVertexBuffer(NULL), -m_pFrondIndexCounts(NULL), m_pFrondIndexBuffer(NULL), m_pFrondVertexBuffer(NULL), m_pLeafVertexBuffer(NULL), @@ -93,6 +91,9 @@ void CSpeedTreeWrapper::SetVertexShaders(LPDIRECT3DVERTEXDECLARATION9 pBranchVer void CSpeedTreeWrapper::OnRenderPCBlocker() { + if (!ms_dwBranchVertexShader || !ms_pLeafVertexShaderDecl || !ms_pLeafVertexShader) + CSpeedTreeForestDirectX8::Instance().EnsureVertexShaders(); + if (ms_dwBranchVertexShader == 0) { ms_dwBranchVertexShader = LoadBranchShader(ms_lpd3dDevice); @@ -101,7 +102,7 @@ void CSpeedTreeWrapper::OnRenderPCBlocker() CSpeedTreeForestDirectX8::Instance().UpdateSystem(ELTimer_GetMSec() / 1000.0f); - // �ϳ��� ������ �� ���� LOD ������� ���� + // �ϳ��� ������ �� ���� LOD ������� ���� m_pSpeedTree->SetLodLevel(1.0f); //Advance(); @@ -202,22 +203,25 @@ void CSpeedTreeWrapper::OnRenderPCBlocker() } RenderFronds(); - STATEMANAGER.SetVertexDeclaration(ms_pLeafVertexShaderDecl); - STATEMANAGER.SaveVertexShader(ms_pLeafVertexShader); - -// SetupLeafForTreeType(); + if (ms_pLeafVertexShaderDecl && ms_pLeafVertexShader) { - // pass leaf tables to shader -#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT - UploadLeafTables(c_nVertexShader_LeafTables); -#endif + STATEMANAGER.SetVertexDeclaration(ms_pLeafVertexShaderDecl); + STATEMANAGER.SaveVertexShader(ms_pLeafVertexShader); - if (!m_CompositeImageInstance.IsEmpty()) - STATEMANAGER.SetTexture(0, m_CompositeImageInstance.GetTextureReference().GetD3DTexture()); +// SetupLeafForTreeType(); + { + // pass leaf tables to shader +#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT + UploadLeafTables(c_nVertexShader_LeafTables); +#endif + + if (!m_CompositeImageInstance.IsEmpty()) + STATEMANAGER.SetTexture(0, m_CompositeImageInstance.GetTextureReference().GetD3DTexture()); + } + RenderLeaves(); + STATEMANAGER.RestoreVertexShader(); } - RenderLeaves(); EndLeafForTreeType(); - STATEMANAGER.RestoreVertexShader(); STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE); @@ -236,6 +240,9 @@ void CSpeedTreeWrapper::OnRenderPCBlocker() void CSpeedTreeWrapper::OnRender() { + if (!ms_dwBranchVertexShader || !ms_pLeafVertexShaderDecl || !ms_pLeafVertexShader) + CSpeedTreeForestDirectX8::Instance().EnsureVertexShaders(); + if (ms_dwBranchVertexShader == 0) { ms_dwBranchVertexShader = LoadBranchShader(ms_lpd3dDevice); @@ -244,7 +251,7 @@ void CSpeedTreeWrapper::OnRender() CSpeedTreeForestDirectX8::Instance().UpdateSystem(ELTimer_GetMSec() / 1000.0f); - // �ϳ��� ������ �� ���� LOD ������� ���� + // �ϳ��� ������ �� ���� LOD ������� ���� m_pSpeedTree->SetLodLevel(1.0f); //Advance(); @@ -282,13 +289,16 @@ void CSpeedTreeWrapper::OnRender() SetupFrondForTreeType(); RenderFronds(); - STATEMANAGER.SetVertexDeclaration(ms_pLeafVertexShaderDecl); - STATEMANAGER.SaveVertexShader(ms_pLeafVertexShader); - - SetupLeafForTreeType(); - RenderLeaves(); + if (ms_pLeafVertexShaderDecl && ms_pLeafVertexShader) + { + STATEMANAGER.SetVertexDeclaration(ms_pLeafVertexShaderDecl); + STATEMANAGER.SaveVertexShader(ms_pLeafVertexShader); + + SetupLeafForTreeType(); + RenderLeaves(); + STATEMANAGER.RestoreVertexShader(); + } EndLeafForTreeType(); - STATEMANAGER.RestoreVertexShader(); STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE); @@ -314,14 +324,12 @@ CSpeedTreeWrapper::~CSpeedTreeWrapper() { SAFE_RELEASE(m_pBranchVertexBuffer); SAFE_RELEASE(m_pBranchIndexBuffer); - SAFE_DELETE_ARRAY(m_pBranchIndexCounts); } if (m_unFrondVertexCount > 0) { SAFE_RELEASE(m_pFrondVertexBuffer); SAFE_RELEASE(m_pFrondIndexBuffer); - SAFE_DELETE_ARRAY(m_pFrondIndexCounts); } for (short i = 0; i < m_usNumLeafLods; ++i) @@ -544,32 +552,58 @@ void CSpeedTreeWrapper::SetupBranchBuffers(void) m_pBranchVertexBuffer->Unlock(); } - // create and fill the index counts for each LOD - UINT unNumLodLevels = m_pSpeedTree->GetNumBranchLodLevels(); - m_pBranchIndexCounts = new unsigned short[unNumLodLevels]; - for (UINT i = 0; i < unNumLodLevels; ++i) - { - // force update for particular LOD - m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry, i); - - // check if this LOD has branches - if (pBranches->m_usNumStrips > 0) - m_pBranchIndexCounts[i] = pBranches->m_pStripLengths[0]; - else - m_pBranchIndexCounts[i] = 0; - } - // set back to highest LOD + const uint32_t unNumLodLevels = m_pSpeedTree->GetNumBranchLodLevels(); + m_branchStripOffsets.clear(); + m_branchStripLengths.clear(); + if (unNumLodLevels > 0) + m_branchStripLengths.resize(unNumLodLevels); + + // set LOD0 for strip offsets/index buffer sizing m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry, 0); - - // the first LOD level contains the most indices of all the levels, so - // we use its size to allocate the index buffer - ms_lpd3dDevice->CreateIndexBuffer(m_pBranchIndexCounts[0] * sizeof(unsigned short), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pBranchIndexBuffer, NULL); - - // fill the index buffer - unsigned short* pIndexBuffer = NULL; - m_pBranchIndexBuffer->Lock(0, 0, reinterpret_cast(&pIndexBuffer), 0); - memcpy(pIndexBuffer, pBranches->m_pStrips[0], pBranches->m_pStripLengths[0] * sizeof(unsigned short)); - m_pBranchIndexBuffer->Unlock(); + const uint32_t stripCount = pBranches->m_usNumStrips; + uint32_t totalIndexCount = 0; + if (stripCount > 0) + { + m_branchStripOffsets.resize(stripCount); + for (uint32_t s = 0; s < stripCount; ++s) + { + m_branchStripOffsets[s] = totalIndexCount; + totalIndexCount += pBranches->m_pStripLengths[s]; + } + } + + for (uint32_t i = 0; i < unNumLodLevels; ++i) + { + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry, i); + auto& lengths = m_branchStripLengths[i]; + lengths.assign(stripCount, 0); + const uint32_t lodStripCount = pBranches->m_usNumStrips; + for (uint32_t s = 0; s < stripCount && s < lodStripCount; ++s) + { + lengths[s] = pBranches->m_pStripLengths[s]; + } + } + // set back to highest LOD for buffer fill + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry, 0); + + if (totalIndexCount > 0) + { + // the first LOD level contains the most indices of all the levels, so + // we use its size to allocate the index buffer + ms_lpd3dDevice->CreateIndexBuffer(totalIndexCount * sizeof(uint16_t), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pBranchIndexBuffer, NULL); + + // fill the index buffer + uint16_t* pIndexBuffer = NULL; + m_pBranchIndexBuffer->Lock(0, 0, reinterpret_cast(&pIndexBuffer), 0); + uint32_t cursor = 0; + for (uint32_t s = 0; s < stripCount; ++s) + { + const uint32_t length = pBranches->m_pStripLengths[s]; + memcpy(pIndexBuffer + cursor, pBranches->m_pStrips[s], length * sizeof(uint16_t)); + cursor += length; + } + m_pBranchIndexBuffer->Unlock(); + } } } @@ -629,32 +663,58 @@ void CSpeedTreeWrapper::SetupFrondBuffers(void) } m_pFrondVertexBuffer->Unlock(); - // create and fill the index counts for each LOD - UINT unNumLodLevels = m_pSpeedTree->GetNumFrondLodLevels(); - m_pFrondIndexCounts = new unsigned short[unNumLodLevels]; - for (WORD j = 0; j < unNumLodLevels; ++j) + const uint32_t unNumLodLevels = m_pSpeedTree->GetNumFrondLodLevels(); + m_frondStripOffsets.clear(); + m_frondStripLengths.clear(); + if (unNumLodLevels > 0) + m_frondStripLengths.resize(unNumLodLevels); + + // set LOD0 for strip offsets/index buffer sizing + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry, -1, 0); + const uint32_t stripCount = pFronds->m_usNumStrips; + uint32_t totalIndexCount = 0; + if (stripCount > 0) { - // force update for this LOD - m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry, -1, j); - - // check if this LOD has fronds - if (pFronds->m_usNumStrips > 0) - m_pFrondIndexCounts[j] = pFronds->m_pStripLengths[0]; - else - m_pFrondIndexCounts[j] = 0; + m_frondStripOffsets.resize(stripCount); + for (uint32_t s = 0; s < stripCount; ++s) + { + m_frondStripOffsets[s] = totalIndexCount; + totalIndexCount += pFronds->m_pStripLengths[s]; + } } - // go back to highest LOD + + for (uint32_t j = 0; j < unNumLodLevels; ++j) + { + m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry, -1, j); + auto& lengths = m_frondStripLengths[j]; + lengths.assign(stripCount, 0); + const uint32_t lodStripCount = pFronds->m_usNumStrips; + for (uint32_t s = 0; s < stripCount && s < lodStripCount; ++s) + { + lengths[s] = pFronds->m_pStripLengths[s]; + } + } + // go back to highest LOD for buffer fill m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry, -1, 0); - // the first LOD level contains the most indices of all the levels, so - // we use its size to allocate the index buffer - ms_lpd3dDevice->CreateIndexBuffer(m_pFrondIndexCounts[0] * sizeof(unsigned short), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pFrondIndexBuffer, NULL); - - // fill the index buffer - unsigned short * pIndexBuffer = NULL; - m_pFrondIndexBuffer->Lock(0, 0, reinterpret_cast(&pIndexBuffer), 0); - memcpy(pIndexBuffer, pFronds->m_pStrips[0], pFronds->m_pStripLengths[0] * sizeof(unsigned short)); - m_pFrondIndexBuffer->Unlock(); + if (totalIndexCount > 0) + { + // the first LOD level contains the most indices of all the levels, so + // we use its size to allocate the index buffer + ms_lpd3dDevice->CreateIndexBuffer(totalIndexCount * sizeof(uint16_t), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pFrondIndexBuffer, NULL); + + // fill the index buffer + uint16_t * pIndexBuffer = NULL; + m_pFrondIndexBuffer->Lock(0, 0, reinterpret_cast(&pIndexBuffer), 0); + uint32_t cursor = 0; + for (uint32_t s = 0; s < stripCount; ++s) + { + const uint32_t length = pFronds->m_pStripLengths[s]; + memcpy(pIndexBuffer + cursor, pFronds->m_pStrips[s], length * sizeof(uint16_t)); + cursor += length; + } + m_pFrondIndexBuffer->Unlock(); + } } } @@ -787,12 +847,14 @@ CSpeedTreeWrapper::SpeedTreeWrapperPtr CSpeedTreeWrapper::MakeInstance() // use the same buffers spInstance->m_pBranchIndexBuffer = m_pBranchIndexBuffer; - spInstance->m_pBranchIndexCounts = m_pBranchIndexCounts; + spInstance->m_branchStripOffsets = m_branchStripOffsets; + spInstance->m_branchStripLengths = m_branchStripLengths; spInstance->m_pBranchVertexBuffer = m_pBranchVertexBuffer; spInstance->m_unBranchVertexCount = m_unBranchVertexCount; spInstance->m_pFrondIndexBuffer = m_pFrondIndexBuffer; - spInstance->m_pFrondIndexCounts = m_pFrondIndexCounts; + spInstance->m_frondStripOffsets = m_frondStripOffsets; + spInstance->m_frondStripLengths = m_frondStripLengths; spInstance->m_pFrondVertexBuffer = m_pFrondVertexBuffer; spInstance->m_unFrondVertexCount = m_unFrondVertexCount; @@ -908,19 +970,27 @@ void CSpeedTreeWrapper::RenderBranches(void) const { m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry); - if (m_pGeometryCache->m_fBranchAlphaTestValue) + if (m_pGeometryCache->m_sBranches.m_usVertexCount > 0 && m_pBranchIndexBuffer && !m_branchStripLengths.empty() && !m_branchStripOffsets.empty()) { + const int lod = m_pGeometryCache->m_sBranches.m_nDiscreteLodLevel; + if (lod < 0 || static_cast(lod) >= m_branchStripLengths.size()) + return; + PositionTree(); // set alpha test value STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(m_pGeometryCache->m_fBranchAlphaTestValue)); - // render if this LOD has branches - if (m_pBranchIndexCounts && - m_pBranchIndexCounts[m_pGeometryCache->m_sBranches.m_nDiscreteLodLevel] > 0) + const auto& lengths = m_branchStripLengths[lod]; + const size_t stripCount = lengths.size() < m_branchStripOffsets.size() ? lengths.size() : m_branchStripOffsets.size(); + for (size_t s = 0; s < stripCount; ++s) { - ms_faceCount += m_pBranchIndexCounts[m_pGeometryCache->m_sBranches.m_nDiscreteLodLevel] - 2; - STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_pGeometryCache->m_sBranches.m_usVertexCount, 0, m_pBranchIndexCounts[m_pGeometryCache->m_sBranches.m_nDiscreteLodLevel] - 2); + const uint16_t stripLength = lengths[s]; + if (stripLength > 2) + { + ms_faceCount += stripLength - 2; + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_pGeometryCache->m_sBranches.m_usVertexCount, m_branchStripOffsets[s], stripLength - 2); + } } } } @@ -981,19 +1051,27 @@ void CSpeedTreeWrapper::RenderFronds(void) const { m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry); - if (m_pGeometryCache->m_fFrondAlphaTestValue > 0.0f) + if (m_pGeometryCache->m_sFronds.m_usVertexCount > 0 && m_pFrondIndexBuffer && !m_frondStripLengths.empty() && !m_frondStripOffsets.empty()) { + const int lod = m_pGeometryCache->m_sFronds.m_nDiscreteLodLevel; + if (lod < 0 || static_cast(lod) >= m_frondStripLengths.size()) + return; + PositionTree(); // set alpha test value STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(m_pGeometryCache->m_fFrondAlphaTestValue)); - // render if this LOD has fronds - if (m_pFrondIndexCounts && - m_pFrondIndexCounts[m_pGeometryCache->m_sFronds.m_nDiscreteLodLevel] > 0) + const auto& lengths = m_frondStripLengths[lod]; + const size_t stripCount = lengths.size() < m_frondStripOffsets.size() ? lengths.size() : m_frondStripOffsets.size(); + for (size_t s = 0; s < stripCount; ++s) { - ms_faceCount += m_pFrondIndexCounts[m_pGeometryCache->m_sFronds.m_nDiscreteLodLevel] - 2; - STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_pGeometryCache->m_sFronds.m_usVertexCount, 0, m_pFrondIndexCounts[m_pGeometryCache->m_sFronds.m_nDiscreteLodLevel] - 2); + const uint16_t stripLength = lengths[s]; + if (stripLength > 2) + { + ms_faceCount += stripLength - 2; + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_pGeometryCache->m_sFronds.m_usVertexCount, m_frondStripOffsets[s], stripLength - 2); + } } } } @@ -1048,6 +1126,11 @@ void CSpeedTreeWrapper::RenderLeaves(void) const { // update leaf geometry m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_LeafGeometry); + + if (!m_pLeafVertexBuffer || m_usNumLeafLods == 0) + return; + + const int maxLeafLod = static_cast(m_usNumLeafLods); // update the LOD level vertex arrays we need #if defined(WRAPPER_USE_GPU_LEAF_PLACEMENT) && defined(WRAPPER_USE_GPU_WIND) @@ -1060,9 +1143,18 @@ void CSpeedTreeWrapper::RenderLeaves(void) const // reference to leaf structure const CSpeedTreeRT::SGeometry::SLeaf* pLeaf = (i == 0) ? &m_pGeometryCache->m_sLeaves0 : &m_pGeometryCache->m_sLeaves1; int unLod = pLeaf->m_nDiscreteLodLevel; + + if (!pLeaf->m_bIsActive || pLeaf->m_usLeafCount == 0) + continue; + + if (unLod < 0 || unLod >= maxLeafLod) + continue; + + if (!m_pLeafVertexBuffer[unLod]) + continue; #if defined WRAPPER_USE_GPU_LEAF_PLACEMENT - if (pLeaf->m_bIsActive && !m_pLeavesUpdatedByCpu[unLod]) + if (m_pLeavesUpdatedByCpu && !m_pLeavesUpdatedByCpu[unLod]) { // update the centers SFVFLeafVertex* pVertex = NULL; @@ -1081,7 +1173,6 @@ void CSpeedTreeWrapper::RenderLeaves(void) const m_pLeavesUpdatedByCpu[unLod] = true; } #else - if (pLeaf->m_bIsActive && m_pLeafVertexBuffer[unLod]) { // update the vertex positions SFVFLeafVertex * pVertex = NULL; @@ -1139,14 +1230,17 @@ void CSpeedTreeWrapper::RenderLeaves(void) const int unLod = pLeaf->m_nDiscreteLodLevel; - if (unLod > -1 && pLeaf->m_bIsActive && pLeaf->m_usLeafCount > 0) - { - STATEMANAGER.SetStreamSource(0, m_pLeafVertexBuffer[unLod], sizeof(SFVFLeafVertex)); - STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(pLeaf->m_fAlphaTestValue)); - - ms_faceCount += pLeaf->m_usLeafCount * 2; - STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLELIST, 0, pLeaf->m_usLeafCount * 2); - } + if (unLod < 0 || unLod >= maxLeafLod || !pLeaf->m_bIsActive || pLeaf->m_usLeafCount == 0) + continue; + + if (!m_pLeafVertexBuffer[unLod]) + continue; + + STATEMANAGER.SetStreamSource(0, m_pLeafVertexBuffer[unLod], sizeof(SFVFLeafVertex)); + STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(pLeaf->m_fAlphaTestValue)); + + ms_faceCount += pLeaf->m_usLeafCount * 2; + STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLELIST, 0, pLeaf->m_usLeafCount * 2); } } @@ -1156,6 +1250,9 @@ void CSpeedTreeWrapper::RenderLeaves(void) const void CSpeedTreeWrapper::EndLeafForTreeType(void) { + if (!m_pLeavesUpdatedByCpu) + return; + // reset copy flags for CPU wind for (UINT i = 0; i < m_usNumLeafLods; ++i) m_pLeavesUpdatedByCpu[i] = false; @@ -1455,3 +1552,4 @@ void CSpeedTreeWrapper::OnUpdateCollisionData(const CStaticCollisionDataVector * AddCollision(&CollisionData, &mat); } } + diff --git a/src/SpeedTreeLib/SpeedTreeWrapper.h b/src/SpeedTreeLib/SpeedTreeWrapper.h index 19315d9..5412836 100644 --- a/src/SpeedTreeLib/SpeedTreeWrapper.h +++ b/src/SpeedTreeLib/SpeedTreeWrapper.h @@ -1,4 +1,4 @@ -/////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////// // SpeedTreeRTExample Class // // (c) 2003 IDV, Inc. @@ -43,6 +43,7 @@ #include #include #include +#include #include "EterLib/GrpObjectInstance.h" #include "EterLib/GrpImageInstance.h" @@ -91,8 +92,8 @@ public: virtual void SetPosition(float x, float y, float z); virtual void CalculateBBox(); - virtual void OnRender(); // Render ÿ ޼ҵ, ׷ 䳪 Ư 쿡 Render θ - // ̿ܿ RenderBranches, RenderFronds ޼ҵ带 CSpeedTreeForest ȣѴ. + virtual void OnRender(); // Render ½Ã¿¡ ¸Þ¼Òµå, ±×·¯³ª ÇÁ¸®ºä³ª Ư¼öÇÑ °æ¿ì¿¡¸¸ Á÷Á¢ Render ÄÝÀ» ºÎ¸£¸ç + // ±× À̿ܿ¡´Â RenderBranches, RenderFronds µîÀÇ ¸Þ¼Òµå¸¦ CSpeedTreeForest¿¡¼­ È£ÃâÇÑ´Ù. virtual void OnBlendRender() {} virtual void OnRenderToShadowMap() {} virtual void OnRenderShadow() {} @@ -172,13 +173,15 @@ private: LPDIRECT3DVERTEXBUFFER9 m_pBranchVertexBuffer; // branch vertex buffer unsigned int m_unBranchVertexCount; // number of vertices in branches LPDIRECT3DINDEXBUFFER9 m_pBranchIndexBuffer; // branch index buffer - unsigned short* m_pBranchIndexCounts; // number of indexes per branch LOD level + std::vector m_branchStripOffsets; // strip start indices (LOD0 ordering) + std::vector> m_branchStripLengths; // [lod][strip] index counts // frond buffers LPDIRECT3DVERTEXBUFFER9 m_pFrondVertexBuffer; // frond vertex buffer unsigned int m_unFrondVertexCount; // number of vertices in frond LPDIRECT3DINDEXBUFFER9 m_pFrondIndexBuffer; // frond index buffer - unsigned short* m_pFrondIndexCounts; // number of indexes per frond LOD level + std::vector m_frondStripOffsets; // strip start indices (LOD0 ordering) + std::vector> m_frondStripLengths; // [lod][strip] index counts // leaf buffers unsigned short m_usNumLeafLods; // the number of leaf LODs @@ -205,3 +208,4 @@ private: }; #pragma warning(pop) + diff --git a/src/SpeedTreeLib/VertexShaders.h b/src/SpeedTreeLib/VertexShaders.h index 0f47ef5..84531a4 100644 --- a/src/SpeedTreeLib/VertexShaders.h +++ b/src/SpeedTreeLib/VertexShaders.h @@ -204,7 +204,7 @@ static const char g_achLeafVertexProgram[] = "dcl_normal v3\n" #endif "dcl_texcoord0 v7\n" -#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT +#if defined WRAPPER_USE_GPU_WIND || defined WRAPPER_USE_GPU_LEAF_PLACEMENT "dcl_texcoord2 v9\n" #endif @@ -259,9 +259,6 @@ static const char g_achLeafVertexProgram[] = static void LoadLeafShader(LPDIRECT3DDEVICE9 pDx, LPDIRECT3DVERTEXDECLARATION9& pVertexDecl, LPDIRECT3DVERTEXSHADER9& pVertexShader) { - SAFE_RELEASE(pVertexDecl); - SAFE_RELEASE(pVertexShader); - const D3DVERTEXELEMENT9 leafVertexDecl[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, #ifdef WRAPPER_USE_DYNAMIC_LIGHTING @@ -280,18 +277,42 @@ static void LoadLeafShader(LPDIRECT3DDEVICE9 pDx, LPDIRECT3DVERTEXDECLARATION9& D3DDECL_END() }; - 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()); + if (!pDx) + { + TraceError("Failed to load leaf shader: null D3D device."); + return; } - if (FAILED(pDx->CreateVertexDeclaration(leafVertexDecl, &pVertexDecl))) { - TraceError("Failed to create leaf vertex declaration"); + LPDIRECT3DVERTEXDECLARATION9 pNewVertexDecl = nullptr; + LPDIRECT3DVERTEXSHADER9 pNewVertexShader = nullptr; + LPD3DXBUFFER pCode = nullptr, pError = nullptr; + const HRESULT hrAssemble = D3DXAssembleShader(g_achLeafVertexProgram, sizeof(g_achLeafVertexProgram) - 1, nullptr, nullptr, 0, &pCode, &pError); + if (SUCCEEDED(hrAssemble) && pCode) + { + const HRESULT hrCreateShader = pDx->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), &pNewVertexShader); + if (FAILED(hrCreateShader)) + TraceError("Failed to create leaf vertex shader (hr=0x%08X).", hrCreateShader); + } + else + { + TraceError("Failed to assemble leaf vertex shader (hr=0x%08X). The error reported is [ %s ].", hrAssemble, pError ? pError->GetBufferPointer() : "unknown"); + } + + const HRESULT hrCreateDecl = pDx->CreateVertexDeclaration(leafVertexDecl, &pNewVertexDecl); + if (FAILED(hrCreateDecl)) + TraceError("Failed to create leaf vertex declaration (hr=0x%08X).", hrCreateDecl); + + if (pNewVertexDecl && pNewVertexShader) + { + SAFE_RELEASE(pVertexDecl); + SAFE_RELEASE(pVertexShader); + pVertexDecl = pNewVertexDecl; + pVertexShader = pNewVertexShader; + } + else + { + SAFE_RELEASE(pNewVertexDecl); + SAFE_RELEASE(pNewVertexShader); } SAFE_RELEASE(pCode);