From 07068c071522b215434c8c33169466db51916218 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Thu, 9 Apr 2026 18:42:52 -0400 Subject: [PATCH] fix(rendering): Convert D3D8 ZBIAS integer values to D3D9 DEPTHBIAS floats --- .../Source/W3DDevice/GameClient/W3DScene.cpp | 14 +++++++------- .../Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp | 4 ++-- .../Libraries/Source/WWVegas/WW3D2/dx8wrapper.h | 10 ++++++++++ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp index c022808d92d..7d11e96906a 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp @@ -1000,7 +1000,7 @@ void RTS3DScene::Render(RenderInfoClass & rinfo) //wireframe should be visible. ///@todo: Clearing to black may not be needed if the scene already did the clear. DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_ALPHA); - DX8Wrapper::Set_DX8_Render_State (D3DRS_ZBIAS, 0); + DX8Wrapper::Set_DX8_ZBias(0); //Since all objects will be rendered with same material, disable resetting until all are done. m_maskMaterialPass->setAllowUninstall(FALSE); @@ -1025,7 +1025,7 @@ void RTS3DScene::Render(RenderInfoClass & rinfo) ///@todo: Clearing to black may not be needed if the scene already did the clear. DX8Wrapper::Clear(true, false, Vector3(0.0f,0.0f,0.0f),1.0f); // Clear color but not z DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_ALPHA); - DX8Wrapper::Set_DX8_Render_State (D3DRS_ZBIAS, 0); + DX8Wrapper::Set_DX8_ZBias(0); //We're only filling the z-buffer so ignore normal textures and state changes to speed things up. m_customPassMode = SCENE_PASS_ALPHA_MASK; @@ -1057,7 +1057,7 @@ void RTS3DScene::Render(RenderInfoClass & rinfo) rinfo.Camera.Set_Zbuffer_Range(nearZ, farZ); rinfo.Camera.Apply(); -// DX8Wrapper::Set_DX8_Render_State (D3DRS_ZBIAS, 0); +// DX8Wrapper::Set_DX8_ZBias(0); WW3D::Enable_Texturing(old_enable); WW3D::Enable_Coloring(0); @@ -1069,7 +1069,7 @@ void RTS3DScene::Render(RenderInfoClass & rinfo) //Disable writes to color buffer to save memory bandwidth - we only need Z. DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,0); - DX8Wrapper::Set_DX8_Render_State (D3DRS_ZBIAS, 0); + DX8Wrapper::Set_DX8_ZBias(0); Customized_Render(rinfo); Flush(rinfo); //Re-enable writes to color buffer. @@ -1079,7 +1079,7 @@ void RTS3DScene::Render(RenderInfoClass & rinfo) case EXTRA_PASS_LINE: WW3D::Enable_Texturing(false); DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_WIREFRAME); - DX8Wrapper::Set_DX8_Render_State (D3DRS_ZBIAS, 7); + DX8Wrapper::Set_DX8_ZBias(7); Customized_Render(rinfo); break; case EXTRA_PASS_CLEAR_LINE: @@ -1087,13 +1087,13 @@ void RTS3DScene::Render(RenderInfoClass & rinfo) WW3D::Enable_Texturing(false); WW3D::Enable_Coloring(0xff008000); DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_WIREFRAME); - DX8Wrapper::Set_DX8_Render_State (D3DRS_ZBIAS, 7); + DX8Wrapper::Set_DX8_ZBias(7); Customized_Render(rinfo); break; } Flush(rinfo); DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_SOLID); - DX8Wrapper::Set_DX8_Render_State (D3DRS_ZBIAS, 0); + DX8Wrapper::Set_DX8_ZBias(0); WW3D::Enable_Texturing(old_enable); WW3D::Enable_Coloring(0); ShaderClass::Invalidate(); diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp index 17d4b680d2c..51fff7c9cb4 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp @@ -2609,7 +2609,7 @@ void DX8MeshRendererClass::Render_Decal_Meshes() DecalMeshClass * decal_mesh = visible_decal_meshes; if (!decal_mesh) return; - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZBIAS,8); + DX8Wrapper::Set_DX8_ZBias(8); while (decal_mesh != nullptr) { decal_mesh->Render(); @@ -2617,7 +2617,7 @@ void DX8MeshRendererClass::Render_Decal_Meshes() } visible_decal_meshes = nullptr; - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZBIAS,0); + DX8Wrapper::Set_DX8_ZBias(0); } // ---------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h index 24f6997faf2..bd680bfdf27 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h @@ -659,6 +659,7 @@ class DX8Wrapper static void Set_DX8_Light(int index,D3DLIGHT9* light); static void Set_DX8_Render_State(D3DRENDERSTATETYPE state, unsigned value); + static void Set_DX8_ZBias(unsigned int zbias); static void Set_DX8_Clip_Plane(DWORD Index, CONST float* pPlane); static void Set_DX8_Texture_Stage_State(unsigned stage, D3DTEXTURESTAGESTATETYPE state, unsigned value); @@ -1335,6 +1336,15 @@ WWINLINE void DX8Wrapper::Set_DX8_Render_State(D3DRENDERSTATETYPE state, unsigne } +WWINLINE void DX8Wrapper::Set_DX8_ZBias(unsigned int zbias) +{ + // D3D8 D3DRS_ZBIAS accepted integer values 0-16. + // D3D9 D3DRS_DEPTHBIAS accepts a float encoded as a DWORD. + // Convert the legacy integer to a float depth bias value. + float bias = zbias * (-0.000005f); + Set_DX8_Render_State(D3DRS_DEPTHBIAS, *reinterpret_cast(&bias)); +} + WWINLINE void DX8Wrapper::Set_DX8_Clip_Plane(DWORD Index, CONST float* pPlane) { DX8CALL(SetClipPlane( Index, pPlane ));