render parity unit H2: verbatim 40250 water

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-28 14:03:12 +09:00
co-authored by Claude Opus 5.5
parent 6dffd1572a
commit 3e270dccc1
3 changed files with 57 additions and 33 deletions
@@ -1,5 +1,6 @@
// Platform implementation of 40250 GameLib/MapOutdoorWater.cpp. The water texture set is loaded as in
// 40250; the water surface itself is drawn by the Godot water adapter (PORT-PLAN §3).
// Platform copy of 40250 GameLib/MapOutdoorWater.cpp, as is apart from the includes and the
// native-terrain gate: the Godot water adapter draws the surface (PORT-PLAN §3) unless
// IsNativeTerrainRenderEnabled().
#include "GameLib/StdAfx.h"
#include "EterLib/StateManager.h"
#include "EterLib/ResourceManager.h"
@@ -28,35 +29,33 @@ void CMapOutdoor::UnloadWaterTexture()
void CMapOutdoor::RenderWater()
{
if (!IsNativeTerrainRenderEnabled())
return;
if (m_PatchVector.empty())
return;
if (!IsVisiblePart(PART_WATER))
return;
D3DXMATRIX matTexTransformWater;
// PORT: see the file comment.
if (!IsNativeTerrainRenderEnabled())
return;
//////////////////////////////////////////////////////////////////////////
// RenderState
D3DXMATRIX matTexTransformWater;
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
STATEMANAGER.SaveRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
STATEMANAGER.SaveRenderState(D3DRS_COLORVERTEX, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE);
CGraphicImageInstance& rkWaterInst = m_WaterInstances[((ELTimer_GetMSec() / 70) % 30)];
if (!rkWaterInst.IsEmpty() && rkWaterInst.GetTexturePointer())
STATEMANAGER.SetTexture(0, rkWaterInst.GetTexturePointer()->GetD3DTexture());
else
STATEMANAGER.SetTexture(0, NULL);
STATEMANAGER.SetTexture(0, m_WaterInstances[((ELTimer_GetMSec() / 70) % 30)].GetTexturePointer()->GetD3DTexture());
D3DXMatrixScaling(&matTexTransformWater, m_fWaterTexCoordBase, -m_fWaterTexCoordBase, 0.0f);
D3DXMatrixMultiply(&matTexTransformWater, &m_matViewInverse, &matTexTransformWater);
STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &matTexTransformWater);
STATEMANAGER.SaveVertexShader(D3DFVF_XYZ | D3DFVF_DIFFUSE);
STATEMANAGER.SaveVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
@@ -65,28 +64,34 @@ void CMapOutdoor::RenderWater()
STATEMANAGER.SaveTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTexture(1, NULL);
STATEMANAGER.SetTexture(1,NULL);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
// RenderState
//////////////////////////////////////////////////////////////////////////
// 물 위 아래 애니시키기...
static float s_fWaterHeightCurrent = 0;
static float s_fWaterHeightBegin = 0;
static float s_fWaterHeightEnd = 0;
static DWORD s_dwLastHeightChangeTime = CTimer::Instance().GetCurrentMillisecond();
static DWORD s_dwBlendtime = 300;
// 1.5초 마다 변경
if ((CTimer::Instance().GetCurrentMillisecond() - s_dwLastHeightChangeTime) > s_dwBlendtime)
{
s_dwBlendtime = random_range(1000, 3000);
if (s_fWaterHeightEnd == 0)
s_fWaterHeightEnd = -static_cast<float>(random_range(0, 15));
s_fWaterHeightEnd = -random_range(0, 15);
else
s_fWaterHeightEnd = 0;
@@ -94,20 +99,37 @@ void CMapOutdoor::RenderWater()
s_dwLastHeightChangeTime = CTimer::Instance().GetCurrentMillisecond();
}
s_fWaterHeightCurrent = s_fWaterHeightBegin + (s_fWaterHeightEnd - s_fWaterHeightBegin) * (float)((CTimer::Instance().GetCurrentMillisecond() - s_dwLastHeightChangeTime) / (float)s_dwBlendtime);
s_fWaterHeightCurrent = s_fWaterHeightBegin + (s_fWaterHeightEnd - s_fWaterHeightBegin) * (float) ((CTimer::Instance().GetCurrentMillisecond() - s_dwLastHeightChangeTime) / (float) s_dwBlendtime);
m_matWorldForCommonUse._43 = s_fWaterHeightCurrent;
m_matWorldForCommonUse._41 = 0.0f;
m_matWorldForCommonUse._42 = 0.0f;
STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldForCommonUse);
float fFogDistance = __GetFogDistance();
for (auto i = m_PatchVector.begin(); i != m_PatchVector.end(); ++i)
std::vector<std::pair<float, long> >::iterator i;
for(i = m_PatchVector.begin();i != m_PatchVector.end(); ++i)
{
DrawWater(i->second);
if (i->first<fFogDistance)
DrawWater(i->second);
}
STATEMANAGER.SetTexture(0, NULL);
STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
for(i = m_PatchVector.begin();i != m_PatchVector.end(); ++i)
{
if (i->first>=fFogDistance)
DrawWater(i->second);
}
// 렌더링 한 후에는 물 z 위치를 복구
m_matWorldForCommonUse._43 = 0.0f;
//////////////////////////////////////////////////////////////////////////
// RenderState
STATEMANAGER.RestoreVertexShader();
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER);
@@ -117,18 +139,17 @@ void CMapOutdoor::RenderWater()
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS);
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
STATEMANAGER.RestoreRenderState(D3DRS_DIFFUSEMATERIALSOURCE);
STATEMANAGER.RestoreRenderState(D3DRS_COLORVERTEX);
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
}
void CMapOutdoor::DrawWater(long patchnum)
{
assert(NULL != m_pTerrainPatchProxyList);
assert(NULL!=m_pTerrainPatchProxyList);
if (!m_pTerrainPatchProxyList)
return;
@@ -140,17 +161,17 @@ void CMapOutdoor::DrawWater(long patchnum)
if (!rkTerrainPatchProxy.isWaterExists())
return;
CGraphicVertexBuffer* pkVB = rkTerrainPatchProxy.GetWaterVertexBufferPointer();
CGraphicVertexBuffer* pkVB=rkTerrainPatchProxy.GetWaterVertexBufferPointer();
if (!pkVB)
return;
if (!pkVB->GetD3DVertexBuffer())
return;
UINT uPriCount = rkTerrainPatchProxy.GetWaterFaceCount();
UINT uPriCount=rkTerrainPatchProxy.GetWaterFaceCount();
if (!uPriCount)
return;
STATEMANAGER.SetStreamSource(0, pkVB->GetD3DVertexBuffer(), sizeof(SWaterVertex));
STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLELIST, 0, uPriCount);