diff --git a/audit/history.jsonl b/audit/history.jsonl index 2fad8a51..fabea2b7 100644 --- a/audit/history.jsonl +++ b/audit/history.jsonl @@ -565,3 +565,4 @@ {"date": "2026-09-28T04:34:02+00:00", "unit": "EterLib/GrpMarkInstance.cpp", "action": "unit F: platform_stub skeleton deleted (every member was MT_PLATFORM_STUB), 40250 source copied verbatim; guild marks (PythonTextTail, PythonWindow CMarkBox) now load and draw", "evidence": "ctest 35/35 (login_live excluded); mark rendering NEEDS_LIVE"} {"date": "2026-09-28T04:53:55+00:00", "unit": "GameLib/MapOutdoorRenderSTP.cpp + UserInterface/PythonApplication.cpp Create (tiling) + RecordingDevice caps", "action": "unit G: STP file replaced by the full 40250 source (native-terrain gate only); Create gains the 40250 SOFTWARE_TILING/auto-tiling block and MinLOD for !IsFastTNL; RecordingDevice GetDeviceCaps reports VertexShaderVersion 1.1 + D3DPMISCCAPS_CLIPTLVERTS (40250 on a fast T&L card = HTP); native_render XYZRHW fixes: screen→NDC Y was inverted (drawn upside down and back-face culled), negative rhw forced w=1 (spikes), texture transform no longer applied to TL vertices, specular-alpha vertex fog plumbed (Render3DDraw.vertex_fog, capture v9)", "evidence": "ctest 35/35 (login_live excluded); default HTP frame 900 vs previous baseline mean abs diff ~0.6/255; STP forced (temporary edit, reverted) renders the spawn plaza/grass matching HTP layout, STP pixels NEEDS_LIVE"} {"date": "2026-09-28T04:56:02+00:00", "unit": "GameLib/MapOutdoorRenderHTP.cpp", "action": "unit H1: platform rewrite replaced by the full 40250 source (native-terrain gate only); drops the invented texture-0 fallback splat, restores first-splat stage-1 ALPHAOP DISABLE, GetNumTextures() loop bound, shadow-pass FOGCOLOR white/restore, stage-0 ALPHAOP DISABLE + CLAMP, TEXTURE1 = m_matDynamicShadow, stage-1 SELECTARG1 restore, TEXTURE0 1/640 tiling", "evidence": "ctest (see commit); fake-server frame 900: white far band gone, terrain matches STP-path layout (mean abs diff vs STP ~20/255 from per-texture m_matTransform vs STP's fixed 1/640, as in 40250); HTP pixels NEEDS_LIVE"} +{"date": "2026-09-28T04:59:25+00:00", "unit": "GameLib/MapOutdoorWater.cpp", "action": "unit H2: platform rewrite replaced by the full 40250 source (native-terrain gate only): far-fog second water pass restored, invented LIGHTING=FALSE save/restore and empty-texture guard removed", "evidence": "build ok; fake-server spawn frame 900 unchanged (mean abs diff ~0.4/255, no water in view); water visuals NEEDS_LIVE"} diff --git a/audit/port-map/GameLib/MapOutdoorWater.cpp.json b/audit/port-map/GameLib/MapOutdoorWater.cpp.json index 01d2a93b..5c5169c4 100644 --- a/audit/port-map/GameLib/MapOutdoorWater.cpp.json +++ b/audit/port-map/GameLib/MapOutdoorWater.cpp.json @@ -17,16 +17,18 @@ ] }, "CMapOutdoor::RenderWater": { - "status": "DIVERGENT", + "status": "NEEDS_LIVE", "impl": [ "extension/src/platform/GameLib/MapOutdoorWater.cpp:CMapOutdoor::RenderWater" ], - "note": "No-op: water surfaces are not drawn through the recording device yet (the Godot terrain adapter owns terrain rendering, PORT-PLAN §3)." + "note": "Verbatim 40250 plus an early return when IsNativeTerrainRenderEnabled() is false (Godot water adapter, PORT-PLAN §3). Restores the far-fog second pass (untextured, blend off, patches >= __GetFogDistance()) and drops the invented LIGHTING=FALSE save/restore and empty-texture guard. No water in the fake-server spawn view; visuals not verified." }, "CMapOutdoor::DrawWater": { - "status": "DIVERGENT", - "impl": [], - "note": "Not built: only called from RenderWater, which is a no-op." + "status": "NEEDS_LIVE", + "impl": [ + "extension/src/platform/GameLib/MapOutdoorWater.cpp:CMapOutdoor::DrawWater" + ], + "note": "Verbatim 40250, reached from RenderWater on the native path; visuals not verified." } } } diff --git a/extension/src/platform/GameLib/MapOutdoorWater.cpp b/extension/src/platform/GameLib/MapOutdoorWater.cpp index 41f6f71b..c471a569 100644 --- a/extension/src/platform/GameLib/MapOutdoorWater.cpp +++ b/extension/src/platform/GameLib/MapOutdoorWater.cpp @@ -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(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 >::iterator i; + + for(i = m_PatchVector.begin();i != m_PatchVector.end(); ++i) { - DrawWater(i->second); + if (i->firstsecond); } + 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);