forked from metin-server/m2dev-client-src
@@ -2,6 +2,7 @@
|
|||||||
#include "EterLib/BufferPool.h"
|
#include "EterLib/BufferPool.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include "EterBase/Debug.h"
|
||||||
|
|
||||||
CPackManager::CPackManager()
|
CPackManager::CPackManager()
|
||||||
: m_load_from_pack(true)
|
: 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)
|
// 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
|
void CPackManager::NormalizePath(std::string_view in, std::string& out) const
|
||||||
|
|||||||
@@ -471,6 +471,7 @@ const struct _frozen _PyImport_FrozenModules[] = {
|
|||||||
{"encodings.latin_1", M_encodings__latin_1, 2747, 0},
|
{"encodings.latin_1", M_encodings__latin_1, 2747, 0},
|
||||||
{"encodings.mbcs", M_encodings__mbcs, 2240, 0},
|
{"encodings.mbcs", M_encodings__mbcs, 2240, 0},
|
||||||
{"encodings.utf_8", M_encodings__utf_8, 2300, 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},
|
{"enum", M_enum, 87996, 0},
|
||||||
{"filecmp", M_filecmp, 15279, 0},
|
{"filecmp", M_filecmp, 15279, 0},
|
||||||
{"fileinput", M_fileinput, 21106, 0},
|
{"fileinput", M_fileinput, 21106, 0},
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ class CSpeedTreeForestDirectX8 : public CSpeedTreeForest, public CGraphicBase, p
|
|||||||
|
|
||||||
void Render(unsigned long ulRenderBitVector = Forest_RenderAll);
|
void Render(unsigned long ulRenderBitVector = Forest_RenderAll);
|
||||||
bool SetRenderingDevice(LPDIRECT3DDEVICE9 pDevice);
|
bool SetRenderingDevice(LPDIRECT3DDEVICE9 pDevice);
|
||||||
|
bool EnsureVertexShaders() { return m_pDx ? InitVertexShaders() : false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool InitVertexShaders();
|
bool InitVertexShaders();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
// CSpeedTreeWrapper Class
|
// CSpeedTreeWrapper Class
|
||||||
//
|
//
|
||||||
// (c) 2003 IDV, Inc.
|
// (c) 2003 IDV, Inc.
|
||||||
@@ -65,10 +65,8 @@ m_bIsInstance(false),
|
|||||||
m_pInstanceOf(NULL),
|
m_pInstanceOf(NULL),
|
||||||
m_pGeometryCache(NULL),
|
m_pGeometryCache(NULL),
|
||||||
m_usNumLeafLods(0),
|
m_usNumLeafLods(0),
|
||||||
m_pBranchIndexCounts(NULL),
|
|
||||||
m_pBranchIndexBuffer(NULL),
|
m_pBranchIndexBuffer(NULL),
|
||||||
m_pBranchVertexBuffer(NULL),
|
m_pBranchVertexBuffer(NULL),
|
||||||
m_pFrondIndexCounts(NULL),
|
|
||||||
m_pFrondIndexBuffer(NULL),
|
m_pFrondIndexBuffer(NULL),
|
||||||
m_pFrondVertexBuffer(NULL),
|
m_pFrondVertexBuffer(NULL),
|
||||||
m_pLeafVertexBuffer(NULL),
|
m_pLeafVertexBuffer(NULL),
|
||||||
@@ -93,6 +91,9 @@ void CSpeedTreeWrapper::SetVertexShaders(LPDIRECT3DVERTEXDECLARATION9 pBranchVer
|
|||||||
|
|
||||||
void CSpeedTreeWrapper::OnRenderPCBlocker()
|
void CSpeedTreeWrapper::OnRenderPCBlocker()
|
||||||
{
|
{
|
||||||
|
if (!ms_dwBranchVertexShader || !ms_pLeafVertexShaderDecl || !ms_pLeafVertexShader)
|
||||||
|
CSpeedTreeForestDirectX8::Instance().EnsureVertexShaders();
|
||||||
|
|
||||||
if (ms_dwBranchVertexShader == 0)
|
if (ms_dwBranchVertexShader == 0)
|
||||||
{
|
{
|
||||||
ms_dwBranchVertexShader = LoadBranchShader(ms_lpd3dDevice);
|
ms_dwBranchVertexShader = LoadBranchShader(ms_lpd3dDevice);
|
||||||
@@ -101,7 +102,7 @@ void CSpeedTreeWrapper::OnRenderPCBlocker()
|
|||||||
|
|
||||||
CSpeedTreeForestDirectX8::Instance().UpdateSystem(ELTimer_GetMSec() / 1000.0f);
|
CSpeedTreeForestDirectX8::Instance().UpdateSystem(ELTimer_GetMSec() / 1000.0f);
|
||||||
|
|
||||||
// <EFBFBD>ϳ<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> LOD <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
// �ϳ��� ������ �� ���� LOD ������� ����
|
||||||
m_pSpeedTree->SetLodLevel(1.0f);
|
m_pSpeedTree->SetLodLevel(1.0f);
|
||||||
//Advance();
|
//Advance();
|
||||||
|
|
||||||
@@ -202,6 +203,8 @@ void CSpeedTreeWrapper::OnRenderPCBlocker()
|
|||||||
}
|
}
|
||||||
RenderFronds();
|
RenderFronds();
|
||||||
|
|
||||||
|
if (ms_pLeafVertexShaderDecl && ms_pLeafVertexShader)
|
||||||
|
{
|
||||||
STATEMANAGER.SetVertexDeclaration(ms_pLeafVertexShaderDecl);
|
STATEMANAGER.SetVertexDeclaration(ms_pLeafVertexShaderDecl);
|
||||||
STATEMANAGER.SaveVertexShader(ms_pLeafVertexShader);
|
STATEMANAGER.SaveVertexShader(ms_pLeafVertexShader);
|
||||||
|
|
||||||
@@ -216,8 +219,9 @@ void CSpeedTreeWrapper::OnRenderPCBlocker()
|
|||||||
STATEMANAGER.SetTexture(0, m_CompositeImageInstance.GetTextureReference().GetD3DTexture());
|
STATEMANAGER.SetTexture(0, m_CompositeImageInstance.GetTextureReference().GetD3DTexture());
|
||||||
}
|
}
|
||||||
RenderLeaves();
|
RenderLeaves();
|
||||||
EndLeafForTreeType();
|
|
||||||
STATEMANAGER.RestoreVertexShader();
|
STATEMANAGER.RestoreVertexShader();
|
||||||
|
}
|
||||||
|
EndLeafForTreeType();
|
||||||
|
|
||||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||||
STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE);
|
STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE);
|
||||||
@@ -236,6 +240,9 @@ void CSpeedTreeWrapper::OnRenderPCBlocker()
|
|||||||
|
|
||||||
void CSpeedTreeWrapper::OnRender()
|
void CSpeedTreeWrapper::OnRender()
|
||||||
{
|
{
|
||||||
|
if (!ms_dwBranchVertexShader || !ms_pLeafVertexShaderDecl || !ms_pLeafVertexShader)
|
||||||
|
CSpeedTreeForestDirectX8::Instance().EnsureVertexShaders();
|
||||||
|
|
||||||
if (ms_dwBranchVertexShader == 0)
|
if (ms_dwBranchVertexShader == 0)
|
||||||
{
|
{
|
||||||
ms_dwBranchVertexShader = LoadBranchShader(ms_lpd3dDevice);
|
ms_dwBranchVertexShader = LoadBranchShader(ms_lpd3dDevice);
|
||||||
@@ -244,7 +251,7 @@ void CSpeedTreeWrapper::OnRender()
|
|||||||
|
|
||||||
CSpeedTreeForestDirectX8::Instance().UpdateSystem(ELTimer_GetMSec() / 1000.0f);
|
CSpeedTreeForestDirectX8::Instance().UpdateSystem(ELTimer_GetMSec() / 1000.0f);
|
||||||
|
|
||||||
// <EFBFBD>ϳ<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> LOD <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
// �ϳ��� ������ �� ���� LOD ������� ����
|
||||||
m_pSpeedTree->SetLodLevel(1.0f);
|
m_pSpeedTree->SetLodLevel(1.0f);
|
||||||
//Advance();
|
//Advance();
|
||||||
|
|
||||||
@@ -282,13 +289,16 @@ void CSpeedTreeWrapper::OnRender()
|
|||||||
SetupFrondForTreeType();
|
SetupFrondForTreeType();
|
||||||
RenderFronds();
|
RenderFronds();
|
||||||
|
|
||||||
|
if (ms_pLeafVertexShaderDecl && ms_pLeafVertexShader)
|
||||||
|
{
|
||||||
STATEMANAGER.SetVertexDeclaration(ms_pLeafVertexShaderDecl);
|
STATEMANAGER.SetVertexDeclaration(ms_pLeafVertexShaderDecl);
|
||||||
STATEMANAGER.SaveVertexShader(ms_pLeafVertexShader);
|
STATEMANAGER.SaveVertexShader(ms_pLeafVertexShader);
|
||||||
|
|
||||||
SetupLeafForTreeType();
|
SetupLeafForTreeType();
|
||||||
RenderLeaves();
|
RenderLeaves();
|
||||||
EndLeafForTreeType();
|
|
||||||
STATEMANAGER.RestoreVertexShader();
|
STATEMANAGER.RestoreVertexShader();
|
||||||
|
}
|
||||||
|
EndLeafForTreeType();
|
||||||
|
|
||||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||||
STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE);
|
STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE);
|
||||||
@@ -314,14 +324,12 @@ CSpeedTreeWrapper::~CSpeedTreeWrapper()
|
|||||||
{
|
{
|
||||||
SAFE_RELEASE(m_pBranchVertexBuffer);
|
SAFE_RELEASE(m_pBranchVertexBuffer);
|
||||||
SAFE_RELEASE(m_pBranchIndexBuffer);
|
SAFE_RELEASE(m_pBranchIndexBuffer);
|
||||||
SAFE_DELETE_ARRAY(m_pBranchIndexCounts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_unFrondVertexCount > 0)
|
if (m_unFrondVertexCount > 0)
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(m_pFrondVertexBuffer);
|
SAFE_RELEASE(m_pFrondVertexBuffer);
|
||||||
SAFE_RELEASE(m_pFrondIndexBuffer);
|
SAFE_RELEASE(m_pFrondIndexBuffer);
|
||||||
SAFE_DELETE_ARRAY(m_pFrondIndexCounts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (short i = 0; i < m_usNumLeafLods; ++i)
|
for (short i = 0; i < m_usNumLeafLods; ++i)
|
||||||
@@ -544,34 +552,60 @@ void CSpeedTreeWrapper::SetupBranchBuffers(void)
|
|||||||
m_pBranchVertexBuffer->Unlock();
|
m_pBranchVertexBuffer->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// create and fill the index counts for each LOD
|
const uint32_t unNumLodLevels = m_pSpeedTree->GetNumBranchLodLevels();
|
||||||
UINT unNumLodLevels = m_pSpeedTree->GetNumBranchLodLevels();
|
m_branchStripOffsets.clear();
|
||||||
m_pBranchIndexCounts = new unsigned short[unNumLodLevels];
|
m_branchStripLengths.clear();
|
||||||
for (UINT i = 0; i < unNumLodLevels; ++i)
|
if (unNumLodLevels > 0)
|
||||||
{
|
m_branchStripLengths.resize(unNumLodLevels);
|
||||||
// force update for particular LOD
|
|
||||||
m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry, i);
|
|
||||||
|
|
||||||
// check if this LOD has branches
|
// set LOD0 for strip offsets/index buffer sizing
|
||||||
if (pBranches->m_usNumStrips > 0)
|
m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry, 0);
|
||||||
m_pBranchIndexCounts[i] = pBranches->m_pStripLengths[0];
|
const uint32_t stripCount = pBranches->m_usNumStrips;
|
||||||
else
|
uint32_t totalIndexCount = 0;
|
||||||
m_pBranchIndexCounts[i] = 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];
|
||||||
}
|
}
|
||||||
// set back to highest LOD
|
}
|
||||||
|
|
||||||
|
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);
|
m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry, 0);
|
||||||
|
|
||||||
|
if (totalIndexCount > 0)
|
||||||
|
{
|
||||||
// the first LOD level contains the most indices of all the levels, so
|
// the first LOD level contains the most indices of all the levels, so
|
||||||
// we use its size to allocate the index buffer
|
// 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);
|
ms_lpd3dDevice->CreateIndexBuffer(totalIndexCount * sizeof(uint16_t), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pBranchIndexBuffer, NULL);
|
||||||
|
|
||||||
// fill the index buffer
|
// fill the index buffer
|
||||||
unsigned short* pIndexBuffer = NULL;
|
uint16_t* pIndexBuffer = NULL;
|
||||||
m_pBranchIndexBuffer->Lock(0, 0, reinterpret_cast<void**>(&pIndexBuffer), 0);
|
m_pBranchIndexBuffer->Lock(0, 0, reinterpret_cast<void**>(&pIndexBuffer), 0);
|
||||||
memcpy(pIndexBuffer, pBranches->m_pStrips[0], pBranches->m_pStripLengths[0] * sizeof(unsigned short));
|
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();
|
m_pBranchIndexBuffer->Unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
@@ -629,34 +663,60 @@ void CSpeedTreeWrapper::SetupFrondBuffers(void)
|
|||||||
}
|
}
|
||||||
m_pFrondVertexBuffer->Unlock();
|
m_pFrondVertexBuffer->Unlock();
|
||||||
|
|
||||||
// create and fill the index counts for each LOD
|
const uint32_t unNumLodLevels = m_pSpeedTree->GetNumFrondLodLevels();
|
||||||
UINT unNumLodLevels = m_pSpeedTree->GetNumFrondLodLevels();
|
m_frondStripOffsets.clear();
|
||||||
m_pFrondIndexCounts = new unsigned short[unNumLodLevels];
|
m_frondStripLengths.clear();
|
||||||
for (WORD j = 0; j < unNumLodLevels; ++j)
|
if (unNumLodLevels > 0)
|
||||||
{
|
m_frondStripLengths.resize(unNumLodLevels);
|
||||||
// force update for this LOD
|
|
||||||
m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry, -1, j);
|
|
||||||
|
|
||||||
// check if this LOD has fronds
|
// set LOD0 for strip offsets/index buffer sizing
|
||||||
if (pFronds->m_usNumStrips > 0)
|
m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry, -1, 0);
|
||||||
m_pFrondIndexCounts[j] = pFronds->m_pStripLengths[0];
|
const uint32_t stripCount = pFronds->m_usNumStrips;
|
||||||
else
|
uint32_t totalIndexCount = 0;
|
||||||
m_pFrondIndexCounts[j] = 0;
|
if (stripCount > 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);
|
m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_FrondGeometry, -1, 0);
|
||||||
|
|
||||||
|
if (totalIndexCount > 0)
|
||||||
|
{
|
||||||
// the first LOD level contains the most indices of all the levels, so
|
// the first LOD level contains the most indices of all the levels, so
|
||||||
// we use its size to allocate the index buffer
|
// 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);
|
ms_lpd3dDevice->CreateIndexBuffer(totalIndexCount * sizeof(uint16_t), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pFrondIndexBuffer, NULL);
|
||||||
|
|
||||||
// fill the index buffer
|
// fill the index buffer
|
||||||
unsigned short * pIndexBuffer = NULL;
|
uint16_t * pIndexBuffer = NULL;
|
||||||
m_pFrondIndexBuffer->Lock(0, 0, reinterpret_cast<void**>(&pIndexBuffer), 0);
|
m_pFrondIndexBuffer->Lock(0, 0, reinterpret_cast<void**>(&pIndexBuffer), 0);
|
||||||
memcpy(pIndexBuffer, pFronds->m_pStrips[0], pFronds->m_pStripLengths[0] * sizeof(unsigned short));
|
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();
|
m_pFrondIndexBuffer->Unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
@@ -787,12 +847,14 @@ CSpeedTreeWrapper::SpeedTreeWrapperPtr CSpeedTreeWrapper::MakeInstance()
|
|||||||
|
|
||||||
// use the same buffers
|
// use the same buffers
|
||||||
spInstance->m_pBranchIndexBuffer = m_pBranchIndexBuffer;
|
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_pBranchVertexBuffer = m_pBranchVertexBuffer;
|
||||||
spInstance->m_unBranchVertexCount = m_unBranchVertexCount;
|
spInstance->m_unBranchVertexCount = m_unBranchVertexCount;
|
||||||
|
|
||||||
spInstance->m_pFrondIndexBuffer = m_pFrondIndexBuffer;
|
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_pFrondVertexBuffer = m_pFrondVertexBuffer;
|
||||||
spInstance->m_unFrondVertexCount = m_unFrondVertexCount;
|
spInstance->m_unFrondVertexCount = m_unFrondVertexCount;
|
||||||
|
|
||||||
@@ -908,19 +970,27 @@ void CSpeedTreeWrapper::RenderBranches(void) const
|
|||||||
{
|
{
|
||||||
m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_BranchGeometry);
|
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<size_t>(lod) >= m_branchStripLengths.size())
|
||||||
|
return;
|
||||||
|
|
||||||
PositionTree();
|
PositionTree();
|
||||||
|
|
||||||
// set alpha test value
|
// set alpha test value
|
||||||
STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(m_pGeometryCache->m_fBranchAlphaTestValue));
|
STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(m_pGeometryCache->m_fBranchAlphaTestValue));
|
||||||
|
|
||||||
// render if this LOD has branches
|
const auto& lengths = m_branchStripLengths[lod];
|
||||||
if (m_pBranchIndexCounts &&
|
const size_t stripCount = lengths.size() < m_branchStripOffsets.size() ? lengths.size() : m_branchStripOffsets.size();
|
||||||
m_pBranchIndexCounts[m_pGeometryCache->m_sBranches.m_nDiscreteLodLevel] > 0)
|
for (size_t s = 0; s < stripCount; ++s)
|
||||||
{
|
{
|
||||||
ms_faceCount += m_pBranchIndexCounts[m_pGeometryCache->m_sBranches.m_nDiscreteLodLevel] - 2;
|
const uint16_t stripLength = lengths[s];
|
||||||
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_pGeometryCache->m_sBranches.m_usVertexCount, 0, m_pBranchIndexCounts[m_pGeometryCache->m_sBranches.m_nDiscreteLodLevel] - 2);
|
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);
|
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<size_t>(lod) >= m_frondStripLengths.size())
|
||||||
|
return;
|
||||||
|
|
||||||
PositionTree();
|
PositionTree();
|
||||||
|
|
||||||
// set alpha test value
|
// set alpha test value
|
||||||
STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(m_pGeometryCache->m_fFrondAlphaTestValue));
|
STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(m_pGeometryCache->m_fFrondAlphaTestValue));
|
||||||
|
|
||||||
// render if this LOD has fronds
|
const auto& lengths = m_frondStripLengths[lod];
|
||||||
if (m_pFrondIndexCounts &&
|
const size_t stripCount = lengths.size() < m_frondStripOffsets.size() ? lengths.size() : m_frondStripOffsets.size();
|
||||||
m_pFrondIndexCounts[m_pGeometryCache->m_sFronds.m_nDiscreteLodLevel] > 0)
|
for (size_t s = 0; s < stripCount; ++s)
|
||||||
{
|
{
|
||||||
ms_faceCount += m_pFrondIndexCounts[m_pGeometryCache->m_sFronds.m_nDiscreteLodLevel] - 2;
|
const uint16_t stripLength = lengths[s];
|
||||||
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_pGeometryCache->m_sFronds.m_usVertexCount, 0, m_pFrondIndexCounts[m_pGeometryCache->m_sFronds.m_nDiscreteLodLevel] - 2);
|
if (stripLength > 2)
|
||||||
|
{
|
||||||
|
ms_faceCount += stripLength - 2;
|
||||||
|
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_pGeometryCache->m_sFronds.m_usVertexCount, m_frondStripOffsets[s], stripLength - 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1049,6 +1127,11 @@ void CSpeedTreeWrapper::RenderLeaves(void) const
|
|||||||
// update leaf geometry
|
// update leaf geometry
|
||||||
m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_LeafGeometry);
|
m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_LeafGeometry);
|
||||||
|
|
||||||
|
if (!m_pLeafVertexBuffer || m_usNumLeafLods == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int maxLeafLod = static_cast<int>(m_usNumLeafLods);
|
||||||
|
|
||||||
// update the LOD level vertex arrays we need
|
// update the LOD level vertex arrays we need
|
||||||
#if defined(WRAPPER_USE_GPU_LEAF_PLACEMENT) && defined(WRAPPER_USE_GPU_WIND)
|
#if defined(WRAPPER_USE_GPU_LEAF_PLACEMENT) && defined(WRAPPER_USE_GPU_WIND)
|
||||||
// do nothing, needs no updates
|
// do nothing, needs no updates
|
||||||
@@ -1061,8 +1144,17 @@ void CSpeedTreeWrapper::RenderLeaves(void) const
|
|||||||
const CSpeedTreeRT::SGeometry::SLeaf* pLeaf = (i == 0) ? &m_pGeometryCache->m_sLeaves0 : &m_pGeometryCache->m_sLeaves1;
|
const CSpeedTreeRT::SGeometry::SLeaf* pLeaf = (i == 0) ? &m_pGeometryCache->m_sLeaves0 : &m_pGeometryCache->m_sLeaves1;
|
||||||
int unLod = pLeaf->m_nDiscreteLodLevel;
|
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 defined WRAPPER_USE_GPU_LEAF_PLACEMENT
|
||||||
if (pLeaf->m_bIsActive && !m_pLeavesUpdatedByCpu[unLod])
|
if (m_pLeavesUpdatedByCpu && !m_pLeavesUpdatedByCpu[unLod])
|
||||||
{
|
{
|
||||||
// update the centers
|
// update the centers
|
||||||
SFVFLeafVertex* pVertex = NULL;
|
SFVFLeafVertex* pVertex = NULL;
|
||||||
@@ -1081,7 +1173,6 @@ void CSpeedTreeWrapper::RenderLeaves(void) const
|
|||||||
m_pLeavesUpdatedByCpu[unLod] = true;
|
m_pLeavesUpdatedByCpu[unLod] = true;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (pLeaf->m_bIsActive && m_pLeafVertexBuffer[unLod])
|
|
||||||
{
|
{
|
||||||
// update the vertex positions
|
// update the vertex positions
|
||||||
SFVFLeafVertex * pVertex = NULL;
|
SFVFLeafVertex * pVertex = NULL;
|
||||||
@@ -1139,8 +1230,12 @@ void CSpeedTreeWrapper::RenderLeaves(void) const
|
|||||||
|
|
||||||
int unLod = pLeaf->m_nDiscreteLodLevel;
|
int unLod = pLeaf->m_nDiscreteLodLevel;
|
||||||
|
|
||||||
if (unLod > -1 && pLeaf->m_bIsActive && pLeaf->m_usLeafCount > 0)
|
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.SetStreamSource(0, m_pLeafVertexBuffer[unLod], sizeof(SFVFLeafVertex));
|
||||||
STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(pLeaf->m_fAlphaTestValue));
|
STATEMANAGER.SetRenderState(D3DRS_ALPHAREF, DWORD(pLeaf->m_fAlphaTestValue));
|
||||||
|
|
||||||
@@ -1148,7 +1243,6 @@ void CSpeedTreeWrapper::RenderLeaves(void) const
|
|||||||
STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLELIST, 0, 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)
|
void CSpeedTreeWrapper::EndLeafForTreeType(void)
|
||||||
{
|
{
|
||||||
|
if (!m_pLeavesUpdatedByCpu)
|
||||||
|
return;
|
||||||
|
|
||||||
// reset copy flags for CPU wind
|
// reset copy flags for CPU wind
|
||||||
for (UINT i = 0; i < m_usNumLeafLods; ++i)
|
for (UINT i = 0; i < m_usNumLeafLods; ++i)
|
||||||
m_pLeavesUpdatedByCpu[i] = false;
|
m_pLeavesUpdatedByCpu[i] = false;
|
||||||
@@ -1455,3 +1552,4 @@ void CSpeedTreeWrapper::OnUpdateCollisionData(const CStaticCollisionDataVector *
|
|||||||
AddCollision(&CollisionData, &mat);
|
AddCollision(&CollisionData, &mat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
// SpeedTreeRTExample Class
|
// SpeedTreeRTExample Class
|
||||||
//
|
//
|
||||||
// (c) 2003 IDV, Inc.
|
// (c) 2003 IDV, Inc.
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
#include <d3dx9.h>
|
#include <d3dx9.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
#include "EterLib/GrpObjectInstance.h"
|
#include "EterLib/GrpObjectInstance.h"
|
||||||
#include "EterLib/GrpImageInstance.h"
|
#include "EterLib/GrpImageInstance.h"
|
||||||
@@ -91,8 +92,8 @@ public:
|
|||||||
virtual void SetPosition(float x, float y, float z);
|
virtual void SetPosition(float x, float y, float z);
|
||||||
virtual void CalculateBBox();
|
virtual void CalculateBBox();
|
||||||
|
|
||||||
virtual void OnRender(); // Render 시에 메소드, 그러나 프리뷰나 특수한 경우에만 직접 Render 콜을 부르며
|
virtual void OnRender(); // Render ½Ã¿¡ ¸Þ¼Òµå, ±×·¯³ª ÇÁ¸®ºä³ª Ư¼öÇÑ °æ¿ì¿¡¸¸ Á÷Á¢ Render ÄÝÀ» ºÎ¸£¸ç
|
||||||
// 그 이외에는 RenderBranches, RenderFronds 등의 메소드를 CSpeedTreeForest에서 호출한다.
|
// ±× À̿ܿ¡´Â RenderBranches, RenderFronds µîÀÇ ¸Þ¼Òµå¸¦ CSpeedTreeForest¿¡¼ È£ÃâÇÑ´Ù.
|
||||||
virtual void OnBlendRender() {}
|
virtual void OnBlendRender() {}
|
||||||
virtual void OnRenderToShadowMap() {}
|
virtual void OnRenderToShadowMap() {}
|
||||||
virtual void OnRenderShadow() {}
|
virtual void OnRenderShadow() {}
|
||||||
@@ -172,13 +173,15 @@ private:
|
|||||||
LPDIRECT3DVERTEXBUFFER9 m_pBranchVertexBuffer; // branch vertex buffer
|
LPDIRECT3DVERTEXBUFFER9 m_pBranchVertexBuffer; // branch vertex buffer
|
||||||
unsigned int m_unBranchVertexCount; // number of vertices in branches
|
unsigned int m_unBranchVertexCount; // number of vertices in branches
|
||||||
LPDIRECT3DINDEXBUFFER9 m_pBranchIndexBuffer; // branch index buffer
|
LPDIRECT3DINDEXBUFFER9 m_pBranchIndexBuffer; // branch index buffer
|
||||||
unsigned short* m_pBranchIndexCounts; // number of indexes per branch LOD level
|
std::vector<uint32_t> m_branchStripOffsets; // strip start indices (LOD0 ordering)
|
||||||
|
std::vector<std::vector<uint16_t>> m_branchStripLengths; // [lod][strip] index counts
|
||||||
|
|
||||||
// frond buffers
|
// frond buffers
|
||||||
LPDIRECT3DVERTEXBUFFER9 m_pFrondVertexBuffer; // frond vertex buffer
|
LPDIRECT3DVERTEXBUFFER9 m_pFrondVertexBuffer; // frond vertex buffer
|
||||||
unsigned int m_unFrondVertexCount; // number of vertices in frond
|
unsigned int m_unFrondVertexCount; // number of vertices in frond
|
||||||
LPDIRECT3DINDEXBUFFER9 m_pFrondIndexBuffer; // frond index buffer
|
LPDIRECT3DINDEXBUFFER9 m_pFrondIndexBuffer; // frond index buffer
|
||||||
unsigned short* m_pFrondIndexCounts; // number of indexes per frond LOD level
|
std::vector<uint32_t> m_frondStripOffsets; // strip start indices (LOD0 ordering)
|
||||||
|
std::vector<std::vector<uint16_t>> m_frondStripLengths; // [lod][strip] index counts
|
||||||
|
|
||||||
// leaf buffers
|
// leaf buffers
|
||||||
unsigned short m_usNumLeafLods; // the number of leaf LODs
|
unsigned short m_usNumLeafLods; // the number of leaf LODs
|
||||||
@@ -205,3 +208,4 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ static const char g_achLeafVertexProgram[] =
|
|||||||
"dcl_normal v3\n"
|
"dcl_normal v3\n"
|
||||||
#endif
|
#endif
|
||||||
"dcl_texcoord0 v7\n"
|
"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"
|
"dcl_texcoord2 v9\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -259,9 +259,6 @@ static const char g_achLeafVertexProgram[] =
|
|||||||
|
|
||||||
static void LoadLeafShader(LPDIRECT3DDEVICE9 pDx, LPDIRECT3DVERTEXDECLARATION9& pVertexDecl, LPDIRECT3DVERTEXSHADER9& pVertexShader)
|
static void LoadLeafShader(LPDIRECT3DDEVICE9 pDx, LPDIRECT3DVERTEXDECLARATION9& pVertexDecl, LPDIRECT3DVERTEXSHADER9& pVertexShader)
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(pVertexDecl);
|
|
||||||
SAFE_RELEASE(pVertexShader);
|
|
||||||
|
|
||||||
const D3DVERTEXELEMENT9 leafVertexDecl[] = {
|
const D3DVERTEXELEMENT9 leafVertexDecl[] = {
|
||||||
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
|
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
|
||||||
#ifdef WRAPPER_USE_DYNAMIC_LIGHTING
|
#ifdef WRAPPER_USE_DYNAMIC_LIGHTING
|
||||||
@@ -280,18 +277,42 @@ static void LoadLeafShader(LPDIRECT3DDEVICE9 pDx, LPDIRECT3DVERTEXDECLARATION9&
|
|||||||
D3DDECL_END()
|
D3DDECL_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
LPD3DXBUFFER pCode = nullptr, pError = nullptr;
|
if (!pDx)
|
||||||
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 load leaf shader: null D3D device.");
|
||||||
TraceError("Failed to create leaf vertex shader.");
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
TraceError("Failed to assemble leaf vertex shader. The error reported is [ %s ].", pError->GetBufferPointer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(pDx->CreateVertexDeclaration(leafVertexDecl, &pVertexDecl))) {
|
LPDIRECT3DVERTEXDECLARATION9 pNewVertexDecl = nullptr;
|
||||||
TraceError("Failed to create leaf vertex declaration");
|
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);
|
SAFE_RELEASE(pCode);
|
||||||
|
|||||||
Reference in New Issue
Block a user