From 6dffd1572ad7d4745b8d2c9e17b194ff44efa0a5 Mon Sep 17 00:00:00 2001 From: shenlei Date: Mon, 28 Sep 2026 13:57:55 +0900 Subject: [PATCH] render parity unit H1: verbatim 40250 HTP terrain MapOutdoorRenderHTP.cpp is the full 40250 source behind the native-terrain gate: no invented texture-0 fallback, first-splat stage-1 ALPHAOP DISABLE, GetNumTextures() bound, 40250 shadow-pass states (FOGCOLOR white, CLAMP, TEXTURE1 m_matDynamicShadow). Fixes the white far-terrain band. Co-Authored-By: Claude Opus 5.5 --- audit/history.jsonl | 1 + .../GameLib/MapOutdoorRenderHTP.cpp.json | 10 +- .../platform/GameLib/MapOutdoorRenderHTP.cpp | 812 +++++++++++++----- 3 files changed, 607 insertions(+), 216 deletions(-) diff --git a/audit/history.jsonl b/audit/history.jsonl index 0fe1b257..2fad8a51 100644 --- a/audit/history.jsonl +++ b/audit/history.jsonl @@ -564,3 +564,4 @@ {"date": "2026-09-28T04:31:20+00:00", "unit": "SpeedTreeLib/SpeedTreeWrapper.cpp + SpeedTreeForest.cpp + SpeedTreeForestDirectX8.cpp (+ CSpeedTreeRT stand-in)", "action": "unit E: platform proxy tree renderer deleted; 40250 wrapper/forest/DirectX8 copied verbatim (with SpeedTreeConfig.h, VertexShaders.h); SDK SpeedTreeRT.h public API as shim, closed CSpeedTreeRT reimplemented in platform/SpeedTreeLib/SpeedTreeRT.cpp (procedural geometry kept, DIVERGENT); D3D8 vertex-shader decl tokens, D3D_OK, CreateVertexShader/DeleteVertexShader, ID3DXBuffer/D3DXAssembleShader, MessageBox, __min/__max added to shims", "evidence": "ctest 35/35 (login_live excluded); fake-server frame 900 at spawn vs unit D mean abs diff ~3.2/255 (area-name fade + anim phase, no trees in view); spawn moved next to a tree (temporary) shows trunk/branches/leaf cards drawn by the wrapper; tree visuals NEEDS_LIVE"} {"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"} diff --git a/audit/port-map/GameLib/MapOutdoorRenderHTP.cpp.json b/audit/port-map/GameLib/MapOutdoorRenderHTP.cpp.json index 9e0e5758..faee665f 100644 --- a/audit/port-map/GameLib/MapOutdoorRenderHTP.cpp.json +++ b/audit/port-map/GameLib/MapOutdoorRenderHTP.cpp.json @@ -5,25 +5,25 @@ "contracts": [], "functions": { "CMapOutdoor::__RenderTerrain_RenderHardwareTransformPatch": { - "status": "DIVERGENT", + "status": "NEEDS_LIVE", "impl": [ "extension/src/platform/GameLib/MapOutdoorRenderHTP.cpp:CMapOutdoor::__RenderTerrain_RenderHardwareTransformPatch" ], - "note": "Native path now follows 40250 near/mid/far patch distance bands, LOD 0/1/2, splat limit and fog-color far fill; Godot path stays adapted. Same-scene Windows color and image comparison remains open." + "note": "Verbatim 40250 body plus an early return when IsNativeTerrainRenderEnabled() is false (Godot terrain adapter path, PORT-PLAN §3). Fake-server frame: far band no longer white, layout matches the STP path; pixel parity vs a 40250 frame not verified." }, "CMapOutdoor::__HardwareTransformPatch_RenderPatchSplat": { - "status": "DIVERGENT", + "status": "NEEDS_LIVE", "impl": [ "extension/src/platform/GameLib/MapOutdoorRenderHTP.cpp:CMapOutdoor::__HardwareTransformPatch_RenderPatchSplat" ], - "note": "Native path draws 40250 terrain splat layers and static/character shadows; texture-0 fallback and state sequencing still differ from the reference and need matched image verification." + "note": "Verbatim 40250 (non-WORLD_EDITOR branch): no texture-0 fallback, first splat with stage-1 ALPHAOP DISABLE, GetNumTextures() bound, shadow pass FOGCOLOR white + TEXTURE1 m_matDynamicShadow; pixel parity vs a 40250 frame not verified." }, "CMapOutdoor::__HardwareTransformPatch_RenderPatchNone": { "status": "NEEDS_LIVE", "impl": [ "extension/src/platform/GameLib/MapOutdoorRenderHTP.cpp:CMapOutdoor::__HardwareTransformPatch_RenderPatchNone" ], - "note": "Native path now draws the far patch with the 40250 fog texture factor; matched Windows image comparison remains open." + "note": "Verbatim 40250; drawn with the caller's TFACTOR fog fill. Pixel parity vs a 40250 frame not verified." } } } diff --git a/extension/src/platform/GameLib/MapOutdoorRenderHTP.cpp b/extension/src/platform/GameLib/MapOutdoorRenderHTP.cpp index 52cf19ac..fdbe823b 100644 --- a/extension/src/platform/GameLib/MapOutdoorRenderHTP.cpp +++ b/extension/src/platform/GameLib/MapOutdoorRenderHTP.cpp @@ -1,55 +1,101 @@ -// Platform implementation of 40250 GameLib/MapOutdoorRenderHTP.cpp (hardware-transform terrain patches). -// PORT: the Godot Metin2World adapter draws the terrain from the same .raw/.tga/tile data (PORT-PLAN §3). -// When IsNativeTerrainRenderEnabled() is true (MT_NATIVE_TERRAIN=1 or standalone native renderer), -// terrain patches are emitted through CStateManager with D3DTSS_TCI_CAMERASPACEPOSITION texture transforms. +// Platform copy of 40250 GameLib/MapOutdoorRenderHTP.cpp (hardware-transform terrain patches), as is +// apart from the includes and the native-terrain gate: the Godot Metin2World adapter draws the terrain +// (PORT-PLAN §3) unless IsNativeTerrainRenderEnabled() (MT_NATIVE_TERRAIN=1 or the standalone native +// renderer). 40250 takes this path on a fast-T&L device with auto tiling, or SOFTWARE_TILING 0. #include "GameLib/StdAfx.h" #include "GameLib/MapOutdoor.h" -#include "GameLib/TerrainPatch.h" -#include "GameLib/AreaTerrain.h" + #include "EterLib/StateManager.h" #include "../EterLib/RenderCommands3D.h" -#include void CMapOutdoor::__RenderTerrain_RenderHardwareTransformPatch() { + // PORT: see the file comment. if (!IsNativeTerrainRenderEnabled()) return; - const DWORD fogColor = mc_pEnvironmentData ? DWORD(mc_pEnvironmentData->FogColor) : 0xffffffff; - const float fogNear = mc_pEnvironmentData ? mc_pEnvironmentData->GetFogNearDistance() : 5000.0f; - const float fogFar = mc_pEnvironmentData ? mc_pEnvironmentData->GetFogFarDistance() : 10000.0f; + + DWORD dwFogColor; + float fFogFarDistance; + float fFogNearDistance; + if (mc_pEnvironmentData) + { + dwFogColor=mc_pEnvironmentData->FogColor; + fFogNearDistance=mc_pEnvironmentData->GetFogNearDistance(); + fFogFarDistance=mc_pEnvironmentData->GetFogFarDistance(); + } + else + { + dwFogColor=0xffffffff; + fFogNearDistance=5000.0f; + fFogFarDistance=10000.0f; + } + + ////////////////////////////////////////////////////////////////////////// + // Render State & TextureStageState + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000000); + STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + + STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, dwFogColor); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + +#ifdef WORLD_EDITOR + if (GetAsyncKeyState(VK_CAPITAL)) + { + CSpeedTreeWrapper::ms_bSelfShadowOn = false; + STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_GAUSSIANCUBIC); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_GAUSSIANCUBIC); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_GAUSSIANCUBIC); + STATEMANAGER.SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_GAUSSIANCUBIC); + STATEMANAGER.SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_GAUSSIANCUBIC); + STATEMANAGER.SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_GAUSSIANCUBIC); + } + else + { + CSpeedTreeWrapper::ms_bSelfShadowOn = true; + STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + } +#else + CSpeedTreeWrapper::ms_bSelfShadowOn = true; + STATEMANAGER.SetBestFiltering(0); + STATEMANAGER.SetBestFiltering(1); +#endif m_matWorldForCommonUse._41 = 0.0f; m_matWorldForCommonUse._42 = 0.0f; STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldForCommonUse); - STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); - STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &m_matWorldForCommonUse); + STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matWorldForCommonUse); - STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); - STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - STATEMANAGER.SetTexture(1, NULL); - - STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE); - STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0); - STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); - STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, fogColor); - STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, TRUE); + // Render State & TextureStageState + ////////////////////////////////////////////////////////////////////////// STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL); @@ -58,113 +104,168 @@ void CMapOutdoor::__RenderTerrain_RenderHardwareTransformPatch() m_iRenderedSplatNum = 0; m_RenderedTextureNumVector.clear(); - WORD wPrimitiveCount = 0; - D3DPRIMITIVETYPE ePrimitiveType = D3DPT_TRIANGLESTRIP; + std::pair fog_far(fFogFarDistance+1600.0f, 0); + std::pair fog_near(fFogNearDistance-3200.0f, 0); + + std::vector >::iterator far_it = std::upper_bound(m_PatchVector.begin(),m_PatchVector.end(),fog_far); + std::vector >::iterator near_it = std::upper_bound(m_PatchVector.begin(),m_PatchVector.end(),fog_near); + + // NOTE: Word Editor 툴에서는 fog far보다 멀리있는 물체를 텍스쳐 없이 그리는 작업을 하지 않음 +#ifdef WORLD_EDITOR + near_it = m_PatchVector.begin(); + far_it = m_PatchVector.end(); +#endif + + WORD wPrimitiveCount; + D3DPRIMITIVETYPE ePrimitiveType; + + BYTE byCUrrentLODLevel = 0; + + float fLODLevel1Distance = __GetNoFogDistance(); + float fLODLevel2Distance = __GetFogDistance(); + SelectIndexBuffer(0, &wPrimitiveCount, &ePrimitiveType); - const auto nearIt = std::upper_bound(m_PatchVector.begin(), m_PatchVector.end(), - std::pair(fogNear - 3200.0f, 0)); - const auto farIt = std::upper_bound(m_PatchVector.begin(), m_PatchVector.end(), - std::pair(fogFar + 1600.0f, 0)); - const float lod1 = __GetNoFogDistance(); - const float lod2 = __GetFogDistance(); - BYTE lod = 0; - auto updateLod = [&](float distance) { - if (lod == 0 && lod1 <= distance) { - lod = 1; + + DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE); + std::vector >::iterator it = m_PatchVector.begin(); + + // NOTE: 맵툴에서는 view ~ fog near 사이의 지형을 fog disabled 상태로 그리는 작업을 하지 않음. +#ifndef WORLD_EDITOR + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); + + for( ; it != near_it; ++it) + { + if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first) + { + byCUrrentLODLevel = 1; SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType); - } else if (lod == 1 && lod2 <= distance) { - lod = 2; + } + else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first) + { + byCUrrentLODLevel = 2; SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType); } - }; - const DWORD fogEnabled = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE); - STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); - for (auto it = m_PatchVector.begin(); it != nearIt; ++it) { - updateLod(it->first); + __HardwareTransformPatch_RenderPatchSplat(it->second, wPrimitiveCount, ePrimitiveType); - if (m_iRenderedSplatNum >= m_iSplatLimit) break; - if (m_bDrawWireFrame) DrawWireFrame(it->second, wPrimitiveCount, ePrimitiveType); + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + + if (m_bDrawWireFrame) + DrawWireFrame(it->second, wPrimitiveCount, ePrimitiveType); } - STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, fogEnabled); - if (m_iRenderedSplatNum < m_iSplatLimit) { - for (auto it = nearIt; it != farIt; ++it) { - updateLod(it->first); +#endif + + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable); + + if (m_iRenderedSplatNum < m_iSplatLimit) + { + for(it = near_it; it != far_it; ++it) + { + if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first) + { + byCUrrentLODLevel = 1; + SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType); + } + else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first) + { + byCUrrentLODLevel = 2; + SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType); + } + __HardwareTransformPatch_RenderPatchSplat(it->second, wPrimitiveCount, ePrimitiveType); - if (m_iRenderedSplatNum >= m_iSplatLimit) break; - if (m_bDrawWireFrame) DrawWireFrame(it->second, wPrimitiveCount, ePrimitiveType); + + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + + if (m_bDrawWireFrame) + DrawWireFrame(it->second, wPrimitiveCount, ePrimitiveType); } } + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + STATEMANAGER.SetTexture(0, NULL); - STATEMANAGER.SetTexture(1, NULL); STATEMANAGER.SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, FALSE); + + STATEMANAGER.SetTexture(1, NULL); STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, FALSE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); - STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - if (m_iRenderedSplatNum < m_iSplatLimit) { - for (auto it = farIt; it != m_PatchVector.end(); ++it) { - updateLod(it->first); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + if (m_iRenderedSplatNum < m_iSplatLimit) + { + for(it = far_it; it != m_PatchVector.end(); ++it) + { + if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first) + { + byCUrrentLODLevel = 1; + SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType); + } + else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first) + { + byCUrrentLODLevel = 2; + SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType); + } + __HardwareTransformPatch_RenderPatchNone(it->second, wPrimitiveCount, ePrimitiveType); - if (m_iRenderedSplatNum >= m_iSplatLimit) break; - if (m_bDrawWireFrame) DrawWireFrame(it->second, wPrimitiveCount, ePrimitiveType); + + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + + if (m_bDrawWireFrame) + DrawWireFrame(it->second, wPrimitiveCount, ePrimitiveType); } } - STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, fogEnabled); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable); STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); - std::sort(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end()); - m_matWorldForCommonUse._41 = 0.0f; - m_matWorldForCommonUse._42 = 0.0f; - STATEMANAGER.SetTexture(1, NULL); + std::sort(m_RenderedTextureNumVector.begin(),m_RenderedTextureNumVector.end()); - STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); - STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND); - STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND); + ////////////////////////////////////////////////////////////////////////// + // Render State & TextureStageState + + STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR); + + STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0); + STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS); + + STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE); STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF); STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC); - STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR); - STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); - STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV); - STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU); - STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAOP); - STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG1); - STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLOROP); - STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG1); - STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS); - STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX); - - STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV); - STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU); - STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); - STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1); - STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); - STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2); - STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); - STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS); - STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX); -} - -void CMapOutdoor::__HardwareTransformPatch_RenderPatchNone(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType) -{ - assert(NULL != m_pTerrainPatchProxyList); - CTerrainPatchProxy* patch = &m_pTerrainPatchProxyList[patchnum]; - if (!patch->isUsed()) return; - CGraphicVertexBuffer* vb = patch->HardwareTransformPatch_GetVertexBufferPtr(); - if (!vb) return; - STATEMANAGER.SetStreamSource(0, vb->GetD3DVertexBuffer(), m_iPatchTerrainVertexSize); - STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + // Render State & TextureStageState + ////////////////////////////////////////////////////////////////////////// } void CMapOutdoor::__HardwareTransformPatch_RenderPatchSplat(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType) { - assert(NULL != m_pTerrainPatchProxyList && "__HardwareTransformPatch_RenderPatchSplat"); + assert(NULL!=m_pTerrainPatchProxyList && "__HardwareTransformPatch_RenderPatchSplat"); CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum]; + if (!pTerrainPatchProxy->isUsed()) return; @@ -180,136 +281,425 @@ void CMapOutdoor::__HardwareTransformPatch_RenderPatchSplat(long patchnum, WORD if (!GetTerrainPointer(ucTerrainNum, &pTerrain)) return; - CGraphicVertexBuffer* pkVB = pTerrainPatchProxy->HardwareTransformPatch_GetVertexBufferPtr(); - if (!pkVB) - return; + DWORD dwFogColor; + if (mc_pEnvironmentData) + dwFogColor=mc_pEnvironmentData->FogColor; + else + dwFogColor=0xffffffff; WORD wCoordX, wCoordY; pTerrain->GetCoordinate(&wCoordX, &wCoordY); - m_matWorldForCommonUse._41 = -(float)(wCoordX * CTerrainImpl::XSIZE * CTerrainImpl::CELLSCALE); - m_matWorldForCommonUse._42 = (float)(wCoordY * CTerrainImpl::YSIZE * CTerrainImpl::CELLSCALE); - - D3DXMATRIX matTerrainTexTransform, matSplatAlphaTexTransform; - D3DXMatrixMultiply(&matTerrainTexTransform, &m_matViewInverse, &m_matWorldForCommonUse); - D3DXMatrixMultiply(&matSplatAlphaTexTransform, &matTerrainTexTransform, &m_matSplatAlpha); - STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &matSplatAlphaTexTransform); - - STATEMANAGER.SetStreamSource(0, pkVB->GetD3DVertexBuffer(), m_iPatchTerrainVertexSize); - // 40250 renders the terrain splats unlit; only its shadow pass enables lighting. - STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); TTerrainSplatPatch & rTerrainSplatPatch = pTerrain->GetTerrainSplatPatch(); - const DWORD texCount = m_TextureSet.GetTextureCount(); - bool isFirst = true; - int renderedSplatCount = 0; + + D3DXMATRIX matTexTransform, matSplatAlphaTexTransform, matSplatColorTexTransform; + m_matWorldForCommonUse._41 = -(float) (wCoordX * CTerrainImpl::TERRAIN_XSIZE); + m_matWorldForCommonUse._42 = (float) (wCoordY * CTerrainImpl::TERRAIN_YSIZE); + D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &m_matWorldForCommonUse); + D3DXMatrixMultiply(&matSplatAlphaTexTransform, &matTexTransform, &m_matSplatAlpha); + STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &matSplatAlphaTexTransform); - for (DWORD j = 1; j < texCount; ++j) + D3DXMATRIX matTiling; + D3DXMatrixScaling(&matTiling, 1.0f/640.0f, -1.0f/640.0f, 0.0f); + matTiling._41=0.0f; + matTiling._42=0.0f; + + D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &matTiling); + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform); + + CGraphicVertexBuffer* pkVB=pTerrainPatchProxy->HardwareTransformPatch_GetVertexBufferPtr(); + if (!pkVB) + return; + + STATEMANAGER.SetStreamSource(0, pkVB->GetD3DVertexBuffer(), m_iPatchTerrainVertexSize); + + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + + int iPrevRenderedSplatNum=m_iRenderedSplatNum; + +#ifdef WORLD_EDITOR + + int nRenderTextureCount = 0; + +// if (!m_bShowEntirePatchTextureCount && !(GetAsyncKeyState(VK_LCONTROL) & 0x8000) ) + if (1) { - TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j]; - if (!rSplat.Active || rTerrainSplatPatch.PatchTileCount[sPatchNum][j] == 0) - continue; - - const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j); - if (!rTexture.pd3dTexture) - continue; - - D3DXMATRIX matTexTransform; - D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &rTexture.m_matTransform); - STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matTexTransform); - STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); - - if (isFirst || !rSplat.pd3dTexture) + for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j) { - STATEMANAGER.SetTexture(1, NULL); - STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - STATEMANAGER.SetRenderState(D3DRS_ZWRITEENABLE, TRUE); - isFirst = false; + TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j]; + + if (!rSplat.Active) + continue; + + if (rTerrainSplatPatch.PatchTileCount[sPatchNum][j] == 0) + continue; + + ++nRenderTextureCount; + } + + DWORD dwTextureFactor = STATEMANAGER.GetRenderState(D3DRS_TEXTUREFACTOR); + + int TextureCountThreshold = 8; + DWORD dwTFactor = 0xFFFFFFFF; + + if (GetAsyncKeyState(VK_LSHIFT) & 0x8000) + { + if (GetAsyncKeyState(VK_1) & 0x8000) + { + TextureCountThreshold = 2; + dwTFactor = 0xFF0000FF; + } + else if (GetAsyncKeyState(VK_2) & 0x8000) + { + TextureCountThreshold = 3; + dwTFactor = 0xFF00FF00; + } + else if (GetAsyncKeyState(VK_3) & 0x8000) + { + TextureCountThreshold = 4; + dwTFactor = 0xFF00FFFF; + } + else if (GetAsyncKeyState(VK_4) & 0x8000) + { + TextureCountThreshold = 5; + dwTFactor = 0xFFFF0000; + } + else if (GetAsyncKeyState(VK_5) & 0x8000) + { + TextureCountThreshold = 6; + dwTFactor = 0xFFFFFF00; + } + else if (GetAsyncKeyState(VK_6) & 0x8000) + { + TextureCountThreshold = 7; + dwTFactor = 0xFFFF00ff; + } + + } + + if (nRenderTextureCount>=TextureCountThreshold) + { + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTFactor); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTextureFactor); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); } else { + // 0번 텍스처 + if ( 0 < rTerrainSplatPatch.PatchTileCount[sPatchNum][0] ) + { + DWORD dwTextureFactorFor0Texture = STATEMANAGER.GetRenderState(D3DRS_TEXTUREFACTOR); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xFF88FF88); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTextureFactorFor0Texture); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + } + + for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j) + { + TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j]; + + if (!rSplat.Active) + continue; + + DWORD dwTextureCount = rTerrainSplatPatch.PatchTileCount[sPatchNum][j]; + if (dwTextureCount == 0) + continue; + + DWORD dwTextureFactorForTextureBalance = 0xFFFFFFFF; + + if (!(GetAsyncKeyState(VK_LSHIFT) & 0x8000)) + { + const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j); + + D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform); + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform); + + STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + } + else + { + if (dwTextureCount < 71) + { + dwTextureFactorForTextureBalance = STATEMANAGER.GetRenderState(D3DRS_TEXTUREFACTOR); + if (dwTextureCount < 51) + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xFFFF0000); + else + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xFF0000FF); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTexture(0, NULL); + } + else + { + const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j); + + D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform); + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform); + + STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); + } + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + if (dwTextureCount < 71) + { + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTextureFactorForTextureBalance); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + } + } + + std::vector::iterator aIterator = std::find(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end(), (int)j); + if (aIterator == m_RenderedTextureNumVector.end()) + m_RenderedTextureNumVector.push_back(j); + ++m_iRenderedSplatNum; + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + } + } + } + else + { + int TextureCountThreshold = 6; + DWORD dwTFactor = 0xFFFF00FF; + + if (GetAsyncKeyState(VK_LSHIFT) & 0x8000) + { + if (GetAsyncKeyState(VK_1) & 0x8000) + { + TextureCountThreshold = 1; + dwTFactor = 0xFF0000FF; + } + else if (GetAsyncKeyState(VK_2) & 0x8000) + { + TextureCountThreshold = 2; + dwTFactor = 0xFF00FF00; + } + else if (GetAsyncKeyState(VK_3) & 0x8000) + { + TextureCountThreshold = 3; + dwTFactor = 0xFF00FFFF; + } + else if (GetAsyncKeyState(VK_4) & 0x8000) + { + TextureCountThreshold = 4; + dwTFactor = 0xFFFF0000; + } + else if (GetAsyncKeyState(VK_5) & 0x8000) + { + TextureCountThreshold = 5; + dwTFactor = 0xFFFFFF00; + } + } + + for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j) + { + TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j]; + + if (!rSplat.Active) + continue; + + if (rTerrainSplatPatch.PatchTileCount[sPatchNum][j] == 0) + continue; + + DWORD dwTextureFactor; + + if (nRenderTextureCount>=TextureCountThreshold) + { + dwTextureFactor = STATEMANAGER.GetRenderState(D3DRS_TEXTUREFACTOR); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTFactor); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTexture(0, NULL); + } + else + { + const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j); + + D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform); + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform); + + STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); + } STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); - STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - STATEMANAGER.SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + if (nRenderTextureCount>=TextureCountThreshold) + { + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTextureFactor); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + } + + ++nRenderTextureCount; + + std::vector::iterator aIterator = std::find(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end(), (int)j); + if (aIterator == m_RenderedTextureNumVector.end()) + m_RenderedTextureNumVector.push_back(j); + ++m_iRenderedSplatNum; + if (m_iRenderedSplatNum >= m_iSplatLimit) + break; + + } + } + +#else + bool isFirst=true; + for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j) + { + TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j]; + + if (!rSplat.Active) + continue; + + if (rTerrainSplatPatch.PatchTileCount[sPatchNum][j] == 0) + continue; + + const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j); + + D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform); + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform); + if (isFirst) + { + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + isFirst=false; + } + else + { + STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); } - STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); - ++renderedSplatCount; + std::vector::iterator aIterator = std::find(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end(), (int)j); + if (aIterator == m_RenderedTextureNumVector.end()) + m_RenderedTextureNumVector.push_back(j); ++m_iRenderedSplatNum; - if (std::find(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end(), int(j)) == m_RenderedTextureNumVector.end()) - m_RenderedTextureNumVector.push_back(int(j)); if (m_iRenderedSplatNum >= m_iSplatLimit) break; + } - if (renderedSplatCount == 0 && texCount > 1) +/* + if (GetAsyncKeyState(VK_CAPITAL) & 0x8000) { - const TTerrainTexture & rTexture = m_TextureSet.GetTexture(1); - if (rTexture.pd3dTexture) + TTerainSplat & rSplat = rTerrainSplatPatch.Splats[200]; + + if (rSplat.Active) { - D3DXMATRIX matTexTransform; - D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &rTexture.m_matTransform); - STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matTexTransform); - STATEMANAGER.SetTexture(0, rTexture.pd3dTexture); - STATEMANAGER.SetTexture(1, NULL); - STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - STATEMANAGER.SetRenderState(D3DRS_ZWRITEENABLE, TRUE); + const TTerrainTexture & rTexture = m_TextureSet.GetTexture(1); + + D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform); + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform); + + STATEMANAGER.SetTexture(0, NULL); + STATEMANAGER.SetTexture(1, rSplat.pd3dTexture); STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); - renderedSplatCount = 1; - ++m_iRenderedSplatNum; } } +*/ +#endif - if (m_bDrawShadow && pTerrain->GetShadowTexture()) + // 그림자 + if (m_bDrawShadow) { - const DWORD previousFogColor = STATEMANAGER.GetRenderState(D3DRS_FOGCOLOR); STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); + STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, 0xFFFFFFFF); - D3DXMATRIX matShadowTexTransform; - D3DXMatrixMultiply(&matShadowTexTransform, &matTerrainTexTransform, &m_matStaticShadow); - STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matShadowTexTransform); - STATEMANAGER.SetTexture(0, pTerrain->GetShadowTexture()); - STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - STATEMANAGER.SetTexture(1, NULL); - STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - if (m_bDrawChrShadow && m_lpCharacterShadowMapTexture) - { - STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &m_matDynamicShadow); - STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture); - 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_ADDRESSU, D3DTADDRESS_CLAMP); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - } - STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR); - STATEMANAGER.SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + + D3DXMATRIX matShadowTexTransform; + D3DXMatrixMultiply(&matShadowTexTransform, &matTexTransform, &m_matStaticShadow); + + STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matShadowTexTransform); + STATEMANAGER.SetTexture(0, pTerrain->GetShadowTexture()); + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + if (m_bDrawChrShadow) + { + STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &m_matDynamicShadow); + + STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture); + 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.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + } + else + { + STATEMANAGER.SetTexture(1, NULL); + } + + ms_faceCount += wPrimitiveCount; STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); - STATEMANAGER.SetTexture(1, NULL); - STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + ++m_iRenderedSplatNum; + + if (m_bDrawChrShadow) + { + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + } + + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + + STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, previousFogColor); - STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); - STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - ++renderedSplatCount; - ++m_iRenderedSplatNum; - } + STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, dwFogColor); + STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); + } ++m_iRenderedPatchNum; - m_iRenderedSplatNumSqSum += renderedSplatCount * renderedSplatCount; + + int iCurRenderedSplatNum=m_iRenderedSplatNum-iPrevRenderedSplatNum; + + m_iRenderedSplatNumSqSum+=iCurRenderedSplatNum*iCurRenderedSplatNum; + +} + +void CMapOutdoor::__HardwareTransformPatch_RenderPatchNone(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType) +{ + assert(NULL!=m_pTerrainPatchProxyList && "__HardwareTransformPatch_RenderPatchNone"); + CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum]; + + if (!pTerrainPatchProxy->isUsed()) + return; + + CGraphicVertexBuffer* pkVB=pTerrainPatchProxy->HardwareTransformPatch_GetVertexBufferPtr(); + if (!pkVB) + return; + + STATEMANAGER.SetStreamSource(0, pkVB->GetD3DVertexBuffer(), m_iPatchTerrainVertexSize); + STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); }