client/src/SpeedTreeLib/CSpeedTreeDirectX.cpp
2024-03-28 22:27:09 +02:00

247 lines
8.0 KiB
C++

#include "StdAfx.h"
#include "CSpeedTreeDirectX.h"
#include <d3d9.h>
#include <d3d9types.h>
#include <directxsdk/d3dx9.h>
#include "VertexShaders.h"
#include "../eterBase/Timer.h"
#include "../eterLib/StateManager.h"
#include "../eterLib/Camera.h"
CSpeedTreeDirectX::CSpeedTreeDirectX() : m_dwBranchVertexShader(NULL), m_dwLeafVertexShader(NULL) {}
CSpeedTreeDirectX::~CSpeedTreeDirectX()
{
SAFE_RELEASE(m_dwBranchVertexShader);
SAFE_RELEASE(m_dwLeafVertexShader);
}
void CSpeedTreeDirectX::UploadWindMatrix(unsigned int uiLocation, const float* pMatrix) const
{
STATEMANAGER.SetVertexShaderConstant(uiLocation, pMatrix, 4);
}
void CSpeedTreeDirectX::UpdateCompundMatrix(const D3DXVECTOR3& c_rEyeVec, const D3DXMATRIX& c_rmatView, const D3DXMATRIX& c_rmatProj)
{
D3DXMATRIX matBlend;
D3DXMatrixIdentity(&matBlend);
D3DXMATRIX matBlendShader;
D3DXMatrixMultiply(&matBlendShader, &c_rmatView, &c_rmatProj);
float afDirection[3];
afDirection[0] = matBlendShader.m[0][2];
afDirection[1] = matBlendShader.m[1][2];
afDirection[2] = matBlendShader.m[2][2];
CSpeedTreeRT::SetCamera(c_rEyeVec, afDirection);
D3DXMatrixTranspose(&matBlendShader, &matBlendShader);
STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_CompoundMatrix, (const float*)&matBlendShader, 4);
}
bool CSpeedTreeDirectX::SetRenderingDevice()
{
if (!InitVertexShaders())
return false;
const float c_afLightPosition[4] = { -0.707f, -0.300f, 0.707f, 0.0f };
const float c_afLightAmbient[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
const float c_afLightDiffuse[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
const float c_afLightSpecular[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
float afLight1[] =
{
c_afLightPosition[0], c_afLightPosition[1], c_afLightPosition[2],
c_afLightDiffuse[0], c_afLightDiffuse[1], c_afLightDiffuse[2],
c_afLightAmbient[0], c_afLightAmbient[1], c_afLightAmbient[2],
c_afLightSpecular[0], c_afLightSpecular[1], c_afLightSpecular[2],
c_afLightPosition[3],
1.0f, 0.0f, 0.0f
};
CSpeedTreeRT::SetLightAttributes(0, afLight1);
CSpeedTreeRT::SetLightState(0, true);
return true;
}
void CSpeedTreeDirectX::Render(unsigned long ulRenderBitVector)
{
if (m_pMainTreeMap.empty())
return;
if (!(ulRenderBitVector & Forest_RenderToShadow) && !(ulRenderBitVector & Forest_RenderToMiniMap))
UpdateCompundMatrix(CCameraManager::Instance().GetCurrentCamera()->GetEye(), ms_matView, ms_matProj);
DWORD dwLightState = STATEMANAGER.GetRenderState(D3DRS_LIGHTING);
DWORD dwColorVertexState = STATEMANAGER.GetRenderState(D3DRS_COLORVERTEX);
DWORD dwFogVertexMode = STATEMANAGER.GetRenderState(D3DRS_FOGVERTEXMODE);
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, TRUE);
UINT uiCount;
TTreeMap::const_iterator itor = m_pMainTreeMap.begin();
while (itor != m_pMainTreeMap.end())
{
CSpeedTreeWrapper* pMainTree = (itor++)->second;
CSpeedTreeWrapper** ppInstances = pMainTree->GetInstances(uiCount);
for (UINT i = 0; i < uiCount; ++i)
{
ppInstances[i]->Advance();
}
}
STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_Light, m_afLighting, 3);
STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_Fog, m_afFog, 1);
if (ulRenderBitVector & Forest_RenderToShadow)
{
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
}
else
{
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
STATEMANAGER.SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
STATEMANAGER.SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
STATEMANAGER.SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_ANISOTROPIC);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
STATEMANAGER.SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
}
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_CW);
if (STATEMANAGER.GetRenderState(D3DRS_FOGENABLE)){}
STATEMANAGER.SetFVF(D3DFVF_SPEEDTREE_BRANCH_VERTEX);
STATEMANAGER.SetVertexShader(m_dwBranchVertexShader);
if (ulRenderBitVector & Forest_RenderBranches)
{
itor = m_pMainTreeMap.begin();
while (itor != m_pMainTreeMap.end())
{
CSpeedTreeWrapper* pMainTree = (itor++)->second;
CSpeedTreeWrapper** ppInstances = pMainTree->GetInstances(uiCount);
pMainTree->SetupBranchForTreeType();
for (UINT i = 0; i < uiCount; ++i)
if (ppInstances[i]->isShow())
ppInstances[i]->RenderBranches();
}
}
STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
if (ulRenderBitVector & Forest_RenderFronds)
{
itor = m_pMainTreeMap.begin();
while (itor != m_pMainTreeMap.end())
{
CSpeedTreeWrapper* pMainTree = (itor++)->second;
CSpeedTreeWrapper** ppInstances = pMainTree->GetInstances(uiCount);
pMainTree->SetupFrondForTreeType();
for (UINT i = 0; i < uiCount; ++i)
if (ppInstances[i]->isShow())
ppInstances[i]->RenderFronds();
}
}
if (ulRenderBitVector & Forest_RenderLeaves)
{
STATEMANAGER.SetFVF(D3DFVF_SPEEDTREE_LEAF_VERTEX);
STATEMANAGER.SetVertexShader(m_dwLeafVertexShader);
if (STATEMANAGER.GetRenderState(D3DRS_FOGENABLE)){}
if (ulRenderBitVector & Forest_RenderToShadow || ulRenderBitVector & Forest_RenderToMiniMap)
{
STATEMANAGER.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_NOTEQUAL);
STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000000);
}
itor = m_pMainTreeMap.begin();
while (itor != m_pMainTreeMap.end())
{
CSpeedTreeWrapper* pMainTree = (itor++)->second;
CSpeedTreeWrapper** ppInstances = pMainTree->GetInstances(uiCount);
pMainTree->SetupLeafForTreeType();
for (UINT i = 0; i < uiCount; ++i)
if (ppInstances[i]->isShow())
ppInstances[i]->RenderLeaves();
}
if (ulRenderBitVector & Forest_RenderToShadow || ulRenderBitVector & Forest_RenderToMiniMap)
{
STATEMANAGER.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF);
}
}
if (ulRenderBitVector & Forest_RenderBillboards)
{
STATEMANAGER.SetVertexShader(NULL);
STATEMANAGER.SetFVF(D3DFVF_SPEEDTREE_BILLBOARD_VERTEX);
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE);
itor = m_pMainTreeMap.begin();
while (itor != m_pMainTreeMap.end())
{
CSpeedTreeWrapper* pMainTree = (itor++)->second;
CSpeedTreeWrapper** ppInstances = pMainTree->GetInstances(uiCount);
pMainTree->SetupBranchForTreeType();
for (UINT i = 0; i < uiCount; ++i)
if (ppInstances[i]->isShow())
ppInstances[i]->RenderBillboards();
}
}
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, dwLightState);
STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, dwColorVertexState);
STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, dwFogVertexMode);
if (!(ulRenderBitVector & Forest_RenderToShadow))
{
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
}
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC);
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
}
bool CSpeedTreeDirectX::InitVertexShaders(void)
{
m_dwBranchVertexShader = LoadBranchShader(ms_lpd3dDevice);
m_dwLeafVertexShader = LoadLeafShader(ms_lpd3dDevice);
return true;
}