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 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-28 13:57:55 +09:00
co-authored by Claude Opus 5.5
parent 863f3771af
commit 6dffd1572a
3 changed files with 607 additions and 216 deletions
+1
View File
@@ -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"}
@@ -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."
}
}
}
@@ -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 <algorithm>
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<float, long> fog_far(fFogFarDistance+1600.0f, 0);
std::pair<float, long> fog_near(fFogNearDistance-3200.0f, 0);
std::vector<std::pair<float ,long> >::iterator far_it = std::upper_bound(m_PatchVector.begin(),m_PatchVector.end(),fog_far);
std::vector<std::pair<float ,long> >::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<float, long>(fogNear - 3200.0f, 0));
const auto farIt = std::upper_bound(m_PatchVector.begin(), m_PatchVector.end(),
std::pair<float, long>(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<std::pair<float, long> >::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<int>::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<int>::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<int>::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);
}