diff --git a/Core/GameEngine/CMakeLists.txt b/Core/GameEngine/CMakeLists.txt
index 8c720b62385..e486efe32e7 100644
--- a/Core/GameEngine/CMakeLists.txt
+++ b/Core/GameEngine/CMakeLists.txt
@@ -230,7 +230,7 @@ set(GAMEENGINE_SRC
# Include/GameClient/TerrainVisual.h
Include/GameClient/VideoPlayer.h
Include/GameClient/View.h
-# Include/GameClient/Water.h
+ Include/GameClient/Water.h
# Include/GameClient/WindowLayout.h
Include/GameClient/WindowVideoManager.h
# Include/GameClient/WindowXlat.h
@@ -835,7 +835,7 @@ set(GAMEENGINE_SRC
Source/GameClient/VideoPlayer.cpp
Source/GameClient/VideoStream.cpp
Source/GameClient/View.cpp
-# Source/GameClient/Water.cpp
+ Source/GameClient/Water.cpp
# Source/GameLogic/AI/AI.cpp
# Source/GameLogic/AI/AIDock.cpp
# Source/GameLogic/AI/AIGroup.cpp
diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Water.h b/Core/GameEngine/Include/GameClient/Water.h
similarity index 100%
rename from GeneralsMD/Code/GameEngine/Include/GameClient/Water.h
rename to Core/GameEngine/Include/GameClient/Water.h
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Water.cpp b/Core/GameEngine/Source/GameClient/Water.cpp
similarity index 100%
rename from GeneralsMD/Code/GameEngine/Source/GameClient/Water.cpp
rename to Core/GameEngine/Source/GameClient/Water.cpp
diff --git a/Core/GameEngineDevice/CMakeLists.txt b/Core/GameEngineDevice/CMakeLists.txt
index c53c29220fb..66dff03ecc0 100644
--- a/Core/GameEngineDevice/CMakeLists.txt
+++ b/Core/GameEngineDevice/CMakeLists.txt
@@ -13,7 +13,7 @@ set(GAMEENGINEDEVICE_SRC
# Include/W3DDevice/GameClient/Module/W3DDebrisDraw.h
# Include/W3DDevice/GameClient/Module/W3DDefaultDraw.h
# Include/W3DDevice/GameClient/Module/W3DDependencyModelDraw.h
-# Include/W3DDevice/GameClient/Module/W3DLaserDraw.h
+ Include/W3DDevice/GameClient/Module/W3DLaserDraw.h
# Include/W3DDevice/GameClient/Module/W3DModelDraw.h
# Include/W3DDevice/GameClient/Module/W3DOverlordAircraftDraw.h
# Include/W3DDevice/GameClient/Module/W3DOverlordTankDraw.h
@@ -73,8 +73,8 @@ set(GAMEENGINEDEVICE_SRC
Include/W3DDevice/GameClient/W3DVideoBuffer.h
Include/W3DDevice/GameClient/W3DView.h
# Include/W3DDevice/GameClient/W3DVolumetricShadow.h
-# Include/W3DDevice/GameClient/W3DWater.h
-# Include/W3DDevice/GameClient/W3DWaterTracks.h
+ Include/W3DDevice/GameClient/W3DWater.h
+ Include/W3DDevice/GameClient/W3DWaterTracks.h
# Include/W3DDevice/GameClient/W3DWaypointBuffer.h
# Include/W3DDevice/GameClient/W3DWebBrowser.h
# Include/W3DDevice/GameClient/WorldHeightMap.h
@@ -102,7 +102,7 @@ set(GAMEENGINEDEVICE_SRC
# Source/W3DDevice/GameClient/Drawable/Draw/W3DDebrisDraw.cpp
# Source/W3DDevice/GameClient/Drawable/Draw/W3DDefaultDraw.cpp
# Source/W3DDevice/GameClient/Drawable/Draw/W3DDependencyModelDraw.cpp
-# Source/W3DDevice/GameClient/Drawable/Draw/W3DLaserDraw.cpp
+ Source/W3DDevice/GameClient/Drawable/Draw/W3DLaserDraw.cpp
# Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp
# Source/W3DDevice/GameClient/Drawable/Draw/W3DOverlordAircraftDraw.cpp
# Source/W3DDevice/GameClient/Drawable/Draw/W3DOverlordTankDraw.cpp
@@ -176,8 +176,8 @@ set(GAMEENGINEDEVICE_SRC
Source/W3DDevice/GameClient/W3DView.cpp
# Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp
# Source/W3DDevice/GameClient/W3DWebBrowser.cpp
-# Source/W3DDevice/GameClient/Water/W3DWater.cpp
-# Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
+ Source/W3DDevice/GameClient/Water/W3DWater.cpp
+ Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
# Source/W3DDevice/GameClient/WorldHeightMap.cpp
# Source/W3DDevice/GameLogic/W3DGameLogic.cpp
# Source/W3DDevice/GameLogic/W3DGhostObject.cpp
diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DLaserDraw.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DLaserDraw.h
similarity index 100%
rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DLaserDraw.h
rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DLaserDraw.h
diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DWater.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DWater.h
similarity index 100%
rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DWater.h
rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DWater.h
diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DWaterTracks.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DWaterTracks.h
similarity index 100%
rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DWaterTracks.h
rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DWaterTracks.h
diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DLaserDraw.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DLaserDraw.cpp
similarity index 100%
rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DLaserDraw.cpp
rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DLaserDraw.cpp
diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp
similarity index 99%
rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp
rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp
index f3189e931e9..2addc0e8ba6 100644
--- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp
+++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp
@@ -619,8 +619,8 @@ HRESULT WaterRenderObjClass::generateVertexBuffer( Int sizeX, Int sizeY, Int ver
{
m_numVertices=sizeX*sizeY;
//Assuming dynamic vertex buffer, allocate maximum multiple of required size to allow rendering from
- //different parts of the buffer. 5-15-03: Disabled this since we use DISCARD mode instead to avoid Nvidia Runtime bug. -MW
- //m_numVertices=(65536 / (sizeX*sizeY))*sizeX*sizeY;
+ //different parts of the buffer. 5-15-03: Disabled this since we use DISCARD mode instead to avoid Nvidia Runtime bug. -MW
+ //m_numVertices=(65536 / (sizeX*sizeY))*sizeX*sizeY;
SEA_PATCH_VERTEX* pVertices;
@@ -2229,9 +2229,9 @@ void WaterRenderObjClass::renderWaterMesh(void)
if (!m_doWaterGrid)
return; //the water grid is disabled.
- //According to Nvidia there's a D3D bug that happens if you don't start with a
- //new dynamic VB each frame - so we force a DISCARD by overflowing the counter.
- m_vertexBufferD3DOffset = 0xffff;
+ //According to Nvidia there's a D3D bug that happens if you don't start with a
+ //new dynamic VB each frame - so we force a DISCARD by overflowing the counter.
+ m_vertexBufferD3DOffset = 0xffff;
Setting *setting=&m_settings[m_tod];
diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
similarity index 99%
rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
index 964eb896ac3..afc6ed90131 100644
--- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
+++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
@@ -867,9 +867,9 @@ Try improving the fit to vertical surfaces like cliffs.
if (!m_usedModules || ShaderClass::Is_Backface_Culling_Inverted())
return; //don't render track marks in reflections.
- //According to Nvidia there's a D3D bug that happens if you don't start with a
- //new dynamic VB each frame - so we force a DISCARD by overflowing the counter.
- m_batchStart = 0xffff;
+ //According to Nvidia there's a D3D bug that happens if you don't start with a
+ //new dynamic VB each frame - so we force a DISCARD by overflowing the counter.
+ m_batchStart = 0xffff;
// adjust shading for time of day.
Real shadeR, shadeG, shadeB;
diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvp
similarity index 100%
rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvp
rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvp
diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvv b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvv
similarity index 100%
rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvv
rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvv
diff --git a/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
index 29a8f9a3bad..35c7ff4bd6e 100644
--- a/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
+++ b/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
@@ -15,8 +15,8 @@ set(WW3D2_SRC
assetstatus.h
bitmaphandler.cpp
bitmaphandler.h
- #bmp2d.cpp
- #bmp2d.h
+ bmp2d.cpp
+ bmp2d.h
#boxrobj.cpp
#boxrobj.h
bwrender.cpp
@@ -56,8 +56,8 @@ set(WW3D2_SRC
#dx8renderer.h
#dx8rendererdebugger.cpp
#dx8rendererdebugger.h
- #dx8texman.cpp
- #dx8texman.h
+ dx8texman.cpp
+ dx8texman.h
#dx8vertexbuffer.cpp
#dx8vertexbuffer.h
dx8webbrowser.cpp
@@ -108,8 +108,8 @@ set(WW3D2_SRC
#mapper.h
matinfo.cpp
matinfo.h
- #matpass.cpp
- #matpass.h
+ matpass.cpp
+ matpass.h
#matrixmapper.cpp
#matrixmapper.h
#mesh.cpp
@@ -200,18 +200,18 @@ set(WW3D2_SRC
stripoptimizer.h
surfaceclass.cpp
surfaceclass.h
- #texproject.cpp
- #texproject.h
+ texproject.cpp
+ texproject.h
#textdraw.cpp # unused
textdraw.h
- #texture.cpp
- #texture.h
- #texturefilter.cpp
- #texturefilter.h
- #textureloader.cpp
- #textureloader.h
- #texturethumbnail.cpp
- #texturethumbnail.h
+ texture.cpp
+ texture.h
+ texturefilter.cpp
+ texturefilter.h
+ textureloader.cpp
+ textureloader.h
+ texturethumbnail.cpp
+ texturethumbnail.h
#vertmaterial.cpp
#vertmaterial.h
visrasterizer.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/bmp2d.cpp b/Core/Libraries/Source/WWVegas/WW3D2/bmp2d.cpp
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/bmp2d.cpp
rename to Core/Libraries/Source/WWVegas/WW3D2/bmp2d.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/bmp2d.h b/Core/Libraries/Source/WWVegas/WW3D2/bmp2d.h
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/bmp2d.h
rename to Core/Libraries/Source/WWVegas/WW3D2/bmp2d.h
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8texman.cpp b/Core/Libraries/Source/WWVegas/WW3D2/dx8texman.cpp
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8texman.cpp
rename to Core/Libraries/Source/WWVegas/WW3D2/dx8texman.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8texman.h b/Core/Libraries/Source/WWVegas/WW3D2/dx8texman.h
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8texman.h
rename to Core/Libraries/Source/WWVegas/WW3D2/dx8texman.h
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/matpass.cpp b/Core/Libraries/Source/WWVegas/WW3D2/matpass.cpp
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/matpass.cpp
rename to Core/Libraries/Source/WWVegas/WW3D2/matpass.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/matpass.h b/Core/Libraries/Source/WWVegas/WW3D2/matpass.h
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/matpass.h
rename to Core/Libraries/Source/WWVegas/WW3D2/matpass.h
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texproject.cpp b/Core/Libraries/Source/WWVegas/WW3D2/texproject.cpp
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texproject.cpp
rename to Core/Libraries/Source/WWVegas/WW3D2/texproject.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texproject.h b/Core/Libraries/Source/WWVegas/WW3D2/texproject.h
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texproject.h
rename to Core/Libraries/Source/WWVegas/WW3D2/texproject.h
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texture.cpp b/Core/Libraries/Source/WWVegas/WW3D2/texture.cpp
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texture.cpp
rename to Core/Libraries/Source/WWVegas/WW3D2/texture.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texture.h b/Core/Libraries/Source/WWVegas/WW3D2/texture.h
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texture.h
rename to Core/Libraries/Source/WWVegas/WW3D2/texture.h
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp b/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp
rename to Core/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.h b/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.h
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.h
rename to Core/Libraries/Source/WWVegas/WW3D2/texturefilter.h
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/textureloader.cpp b/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/textureloader.cpp
rename to Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/textureloader.h b/Core/Libraries/Source/WWVegas/WW3D2/textureloader.h
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/textureloader.h
rename to Core/Libraries/Source/WWVegas/WW3D2/textureloader.h
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp b/Core/Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp
rename to Core/Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.h b/Core/Libraries/Source/WWVegas/WW3D2/texturethumbnail.h
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.h
rename to Core/Libraries/Source/WWVegas/WW3D2/texturethumbnail.h
diff --git a/Generals/Code/GameEngine/CMakeLists.txt b/Generals/Code/GameEngine/CMakeLists.txt
index 730e1ec6be8..357a3a48b61 100644
--- a/Generals/Code/GameEngine/CMakeLists.txt
+++ b/Generals/Code/GameEngine/CMakeLists.txt
@@ -215,7 +215,7 @@ set(GAMEENGINE_SRC
Include/GameClient/TerrainVisual.h
# Include/GameClient/VideoPlayer.h
# Include/GameClient/View.h
- Include/GameClient/Water.h
+# Include/GameClient/Water.h
Include/GameClient/WindowLayout.h
# Include/GameClient/WindowVideoManager.h
Include/GameClient/WindowXlat.h
@@ -777,7 +777,7 @@ set(GAMEENGINE_SRC
Source/GameClient/Terrain/TerrainVisual.cpp
# Source/GameClient/VideoPlayer.cpp
# Source/GameClient/View.cpp
- Source/GameClient/Water.cpp
+# Source/GameClient/Water.cpp
Source/GameLogic/AI/AI.cpp
Source/GameLogic/AI/AIDock.cpp
Source/GameLogic/AI/AIGroup.cpp
diff --git a/Generals/Code/GameEngine/Include/GameClient/Water.h b/Generals/Code/GameEngine/Include/GameClient/Water.h
deleted file mode 100644
index 7814c543bd0..00000000000
--- a/Generals/Code/GameEngine/Include/GameClient/Water.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: Water.h //////////////////////////////////////////////////////////////////////////////////
-// Author: Colin Day, December 2001
-// Desc: Water settings
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-// INLCLUDES //////////////////////////////////////////////////////////////////////////////////////
-#include "Common/GameType.h"
-#include "Common/Overridable.h"
-#include "Common/Override.h"
-
-//-------------------------------------------------------------------------------------------------
-struct FieldParse;
-
-//-------------------------------------------------------------------------------------------------
-/** This structures keeps the settings for how our water will look */
-//-------------------------------------------------------------------------------------------------
-class WaterSetting
-{
-
-public:
-
- WaterSetting( void );
- virtual ~WaterSetting( void );
-
- /// Get the INI parsing table for loading
- const FieldParse *getFieldParse( void ) { return m_waterSettingFieldParseTable; }
-
- static const FieldParse m_waterSettingFieldParseTable[]; ///< the parse table for INI definition
- AsciiString m_skyTextureFile;
- AsciiString m_waterTextureFile;
- Int m_waterRepeatCount;
- Real m_skyTexelsPerUnit; //texel density of sky plane (higher value repeats texture more).
- RGBAColorInt m_vertex00Diffuse;
- RGBAColorInt m_vertex10Diffuse;
- RGBAColorInt m_vertex11Diffuse;
- RGBAColorInt m_vertex01Diffuse;
- RGBAColorInt m_waterDiffuseColor;
- RGBAColorInt m_transparentWaterDiffuse;
- Real m_uScrollPerMs;
- Real m_vScrollPerMs;
-
-};
-
-//-------------------------------------------------------------------------------------------------
-/** This structure keeps the transparency and vertex settings, which are the same regardless of the
- time of day. They can be overridden on a per-map basis. */
-//-------------------------------------------------------------------------------------------------
-class WaterTransparencySetting : public Overridable
-{
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( WaterTransparencySetting, "WaterTransparencySetting" )
-
- public:
- Real m_transparentWaterDepth;
- Real m_minWaterOpacity;
- RGBColor m_standingWaterColor;
- RGBColor m_radarColor;
- Bool m_additiveBlend;
- AsciiString m_standingWaterTexture;
-
- AsciiString m_skyboxTextureN;
- AsciiString m_skyboxTextureE;
- AsciiString m_skyboxTextureS;
- AsciiString m_skyboxTextureW;
- AsciiString m_skyboxTextureT;
-
- public:
- WaterTransparencySetting()
- {
- m_transparentWaterDepth = 3.0f;
- m_minWaterOpacity = 1.0f;
- m_standingWaterColor.red = 1.0f;
- m_standingWaterColor.green = 1.0f;
- m_standingWaterColor.blue = 1.0f;
- m_radarColor.red = 0.55f;
- m_radarColor.green = 0.55f;
- m_radarColor.blue = 1.0f;
- m_standingWaterTexture = "TWWater01.tga";
- m_additiveBlend = FALSE;
-
- m_skyboxTextureN = "TSMorningN.tga";
- m_skyboxTextureE = "TSMorningE.tga";
- m_skyboxTextureS = "TSMorningS.tga";
- m_skyboxTextureW = "TSMorningW.tga";
- m_skyboxTextureT = "TSMorningT.tga";
- }
-
- static const FieldParse m_waterTransparencySettingFieldParseTable[]; ///< the parse table for INI definition
-
- /// Get the INI parsing table for loading
- const FieldParse *getFieldParse( void ) const { return m_waterTransparencySettingFieldParseTable; }
-};
-
-EMPTY_DTOR(WaterTransparencySetting)
-
-// EXTERNAL ///////////////////////////////////////////////////////////////////////////////////////
-extern WaterSetting WaterSettings[ TIME_OF_DAY_COUNT ];
-
-extern OVERRIDE TheWaterTransparency;
diff --git a/Generals/Code/GameEngine/Source/GameClient/Water.cpp b/Generals/Code/GameEngine/Source/GameClient/Water.cpp
deleted file mode 100644
index f59a942086f..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/Water.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: Water.cpp ////////////////////////////////////////////////////////////////////////////////
-// Author: Colin Day, December 2001
-// Desc: Map water settings
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine
-
-#include "GameClient/Water.h"
-#include "Common/INI.h"
-
-// GLOBALS ////////////////////////////////////////////////////////////////////////////////////////
-WaterSetting WaterSettings[ TIME_OF_DAY_COUNT ];
-OVERRIDE TheWaterTransparency = NULL;
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-const FieldParse WaterSetting::m_waterSettingFieldParseTable[] =
-{
-
- { "SkyTexture", INI::parseAsciiString, NULL, offsetof( WaterSetting, m_skyTextureFile ) },
- { "WaterTexture", INI::parseAsciiString, NULL, offsetof( WaterSetting, m_waterTextureFile ) },
- { "Vertex00Color", INI::parseRGBAColorInt, NULL, offsetof( WaterSetting, m_vertex00Diffuse ) },
- { "Vertex10Color", INI::parseRGBAColorInt, NULL, offsetof( WaterSetting, m_vertex10Diffuse ) },
- { "Vertex01Color", INI::parseRGBAColorInt, NULL, offsetof( WaterSetting, m_vertex01Diffuse ) },
- { "Vertex11Color", INI::parseRGBAColorInt, NULL, offsetof( WaterSetting, m_vertex11Diffuse ) },
- { "DiffuseColor", INI::parseRGBAColorInt, NULL, offsetof( WaterSetting, m_waterDiffuseColor ) },
- { "TransparentDiffuseColor", INI::parseRGBAColorInt, NULL, offsetof( WaterSetting, m_transparentWaterDiffuse ) },
- { "UScrollPerMS", INI::parseReal, NULL, offsetof( WaterSetting, m_uScrollPerMs ) },
- { "VScrollPerMS", INI::parseReal, NULL, offsetof( WaterSetting, m_vScrollPerMs ) },
- { "SkyTexelsPerUnit", INI::parseReal, NULL, offsetof( WaterSetting, m_skyTexelsPerUnit ) },
- { "WaterRepeatCount", INI::parseInt, NULL, offsetof( WaterSetting, m_waterRepeatCount ) },
-
- { NULL, NULL, NULL, 0 },
-
-};
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-const FieldParse WaterTransparencySetting::m_waterTransparencySettingFieldParseTable[] =
-{
-
- { "TransparentWaterDepth", INI::parseReal, NULL, offsetof( WaterTransparencySetting, m_transparentWaterDepth ) },
- { "TransparentWaterMinOpacity", INI::parseReal, NULL, offsetof( WaterTransparencySetting, m_minWaterOpacity ) },
- { "StandingWaterColor", INI::parseRGBColor, NULL, offsetof( WaterTransparencySetting, m_standingWaterColor ) },
- { "StandingWaterTexture",INI::parseAsciiString, NULL, offsetof( WaterTransparencySetting, m_standingWaterTexture ) },
- { "AdditiveBlending", INI::parseBool, NULL, offsetof( WaterTransparencySetting, m_additiveBlend) },
- { "RadarWaterColor", INI::parseRGBColor, NULL, offsetof( WaterTransparencySetting, m_radarColor) },
- { "SkyboxTextureN", INI::parseAsciiString,NULL, offsetof( WaterTransparencySetting, m_skyboxTextureN ) },
- { "SkyboxTextureE", INI::parseAsciiString,NULL, offsetof( WaterTransparencySetting, m_skyboxTextureE ) },
- { "SkyboxTextureS", INI::parseAsciiString,NULL, offsetof( WaterTransparencySetting, m_skyboxTextureS ) },
- { "SkyboxTextureW", INI::parseAsciiString,NULL, offsetof( WaterTransparencySetting, m_skyboxTextureW ) },
- { "SkyboxTextureT", INI::parseAsciiString,NULL, offsetof( WaterTransparencySetting, m_skyboxTextureT ) },
-
-
- { 0, 0, 0, 0 },
-};
-
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-WaterSetting::WaterSetting( void )
-{
-
- m_skyTextureFile.clear();
- m_waterTextureFile.clear();
- m_waterRepeatCount = 0;
- m_skyTexelsPerUnit = 0.0f;
-
- m_vertex00Diffuse.red = 0;
- m_vertex00Diffuse.green = 0;
- m_vertex00Diffuse.blue = 0;
- m_vertex00Diffuse.alpha = 0;
-
- m_vertex01Diffuse.red = 0;
- m_vertex01Diffuse.green = 0;
- m_vertex01Diffuse.blue = 0;
- m_vertex01Diffuse.alpha = 0;
-
- m_vertex10Diffuse.red = 0;
- m_vertex10Diffuse.green = 0;
- m_vertex10Diffuse.blue = 0;
- m_vertex10Diffuse.alpha = 0;
-
- m_vertex11Diffuse.red = 0;
- m_vertex11Diffuse.green = 0;
- m_vertex11Diffuse.blue = 0;
- m_vertex11Diffuse.alpha = 0;
-
- m_waterDiffuseColor.red = 0;
- m_waterDiffuseColor.green = 0;
- m_waterDiffuseColor.blue = 0;
- m_waterDiffuseColor.alpha = 0;
-
- m_transparentWaterDiffuse.red = 0;
- m_transparentWaterDiffuse.green = 0;
- m_transparentWaterDiffuse.blue = 0;
- m_transparentWaterDiffuse.alpha = 0;
-
- m_uScrollPerMs = 0.0f;
- m_vScrollPerMs = 0.0f;
-
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-WaterSetting::~WaterSetting( void )
-{
-
-}
-
-
diff --git a/Generals/Code/GameEngineDevice/CMakeLists.txt b/Generals/Code/GameEngineDevice/CMakeLists.txt
index de6e7bd69a9..37a9ed23340 100644
--- a/Generals/Code/GameEngineDevice/CMakeLists.txt
+++ b/Generals/Code/GameEngineDevice/CMakeLists.txt
@@ -10,7 +10,7 @@ set(GAMEENGINEDEVICE_SRC
Include/W3DDevice/GameClient/Module/W3DDebrisDraw.h
Include/W3DDevice/GameClient/Module/W3DDefaultDraw.h
Include/W3DDevice/GameClient/Module/W3DDependencyModelDraw.h
- Include/W3DDevice/GameClient/Module/W3DLaserDraw.h
+# Include/W3DDevice/GameClient/Module/W3DLaserDraw.h
Include/W3DDevice/GameClient/Module/W3DModelDraw.h
Include/W3DDevice/GameClient/Module/W3DOverlordTankDraw.h
Include/W3DDevice/GameClient/Module/W3DPoliceCarDraw.h
@@ -62,8 +62,8 @@ set(GAMEENGINEDEVICE_SRC
# Include/W3DDevice/GameClient/W3DVideoBuffer.h
# Include/W3DDevice/GameClient/W3DView.h
Include/W3DDevice/GameClient/W3DVolumetricShadow.h
- Include/W3DDevice/GameClient/W3DWater.h
- Include/W3DDevice/GameClient/W3DWaterTracks.h
+# Include/W3DDevice/GameClient/W3DWater.h
+# Include/W3DDevice/GameClient/W3DWaterTracks.h
Include/W3DDevice/GameClient/W3DWaypointBuffer.h
Include/W3DDevice/GameClient/W3DWebBrowser.h
Include/W3DDevice/GameClient/WorldHeightMap.h
@@ -88,7 +88,7 @@ set(GAMEENGINEDEVICE_SRC
Source/W3DDevice/GameClient/Drawable/Draw/W3DDebrisDraw.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DDefaultDraw.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DDependencyModelDraw.cpp
- Source/W3DDevice/GameClient/Drawable/Draw/W3DLaserDraw.cpp
+# Source/W3DDevice/GameClient/Drawable/Draw/W3DLaserDraw.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DOverlordTankDraw.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DPoliceCarDraw.cpp
@@ -161,10 +161,10 @@ set(GAMEENGINEDEVICE_SRC
# Source/W3DDevice/GameClient/W3DView.cpp
Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp
Source/W3DDevice/GameClient/W3DWebBrowser.cpp
- Source/W3DDevice/GameClient/Water/W3DWater.cpp
- Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
- Source/W3DDevice/GameClient/Water/wave.nvp
- Source/W3DDevice/GameClient/Water/wave.nvv
+# Source/W3DDevice/GameClient/Water/W3DWater.cpp
+# Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
+# Source/W3DDevice/GameClient/Water/wave.nvp
+# Source/W3DDevice/GameClient/Water/wave.nvv
Source/W3DDevice/GameClient/WorldHeightMap.cpp
Source/W3DDevice/GameLogic/W3DGameLogic.cpp
Source/W3DDevice/GameLogic/W3DGhostObject.cpp
diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DLaserDraw.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DLaserDraw.h
deleted file mode 100644
index 122af0b5aab..00000000000
--- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DLaserDraw.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: W3DLaserDraw.h ///////////////////////////////////////////////////////////////////////////
-// Author:
-// Desc:
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "Common/DrawModule.h"
-//#include "WW3D2/Line3D.h"
-#include "GameClient/Color.h"
-
-class SegmentedLineClass;
-class TextureClass;
-
-class W3DLaserDrawModuleData : public ModuleData
-{
-public:
-
- Color m_innerColor;
- Color m_outerColor;
- Real m_innerBeamWidth;
- Real m_outerBeamWidth;
- Real m_scrollRate;
- Bool m_tile;
- UnsignedInt m_numBeams;
- UnsignedInt m_maxIntensityFrames;
- UnsignedInt m_fadeFrames;
- AsciiString m_textureName;
- UnsignedInt m_segments;
- Real m_arcHeight;
- Real m_segmentOverlapRatio;
- Real m_tilingScalar;
-
- W3DLaserDrawModuleData();
- ~W3DLaserDrawModuleData();
- static void buildFieldParse(MultiIniFieldParse& p);
-};
-
-//-------------------------------------------------------------------------------------------------
-/** W3D laser draw */
-//-------------------------------------------------------------------------------------------------
-class W3DLaserDraw : public DrawModule, public LaserDrawInterface
-{
-
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( W3DLaserDraw, "W3DLaserDraw" )
- MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( W3DLaserDraw, W3DLaserDrawModuleData )
-
-public:
-
- W3DLaserDraw( Thing *thing, const ModuleData* moduleData );
- // virtual destructor prototype provided by memory pool declaration
-
- virtual void doDrawModule(const Matrix3D* transformMtx);
- virtual void releaseShadows(void) {}; ///< we don't care about preserving temporary shadows.
- virtual void allocateShadows(void) {}; ///< we don't care about preserving temporary shadows.
- virtual void setShadowsEnabled(Bool enable) { }
- virtual void setFullyObscuredByShroud(Bool fullyObscured) { };
- virtual void reactToTransformChange(const Matrix3D* oldMtx, const Coord3D* oldPos, Real oldAngle) { }
- virtual void reactToGeometryChange() { }
- virtual Bool isLaser() const { return true; }
- Real getLaserTemplateWidth() const;
-
- virtual LaserDrawInterface* getLaserDrawInterface() { return this; }
- virtual const LaserDrawInterface* getLaserDrawInterface() const { return this; }
-
-protected:
-
- SegmentedLineClass **m_line3D; ///< line 3D for effect
- TextureClass *m_texture;
- Real m_textureAspectRatio; ///< aspect ratio of texture
- Bool m_selfDirty; // not saved
-
-};
diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DWater.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DWater.h
deleted file mode 100644
index 42e71a3fbc4..00000000000
--- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DWater.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: W3DWater.h ///////////////////////////////////////////////////
-
-#pragma once
-
-#include "always.h"
-#include "rendobj.h"
-#include "w3d_file.h"
-#include "dx8vertexbuffer.h"
-#include "dx8indexbuffer.h"
-#include "shader.h"
-#include "vertmaterial.h"
-#include "light.h"
-#include "Lib/BaseType.h"
-#include "Common/GameType.h"
-#include "Common/Snapshot.h"
-
-#define INVALID_WATER_HEIGHT 0.0f ///water height guaranteed to be below all terrain.
-
-#define NUM_BUMP_FRAMES 32 ///number of animation frames in bump map
-//Offsets in constant register file to Vertex shader constants
-#define CV_ZERO 0
-#define CV_ONE 1
-#define CV_WORLDVIEWPROJ_0 2
-#define CV_TEXPROJ_0 6
-#define CV_PATCH_SCALE_OFFSET 10
-
-class PolygonTrigger;
-class WaterTracksRenderSystem;
-class Xfer;
-/// Custom render object that draws mirrors, water, and skies.
-/**
-This render object handles drawing reflected W3D scenes. It will only work
-with rectangular planar surfaces and was tuned with an emphasis on water.
-Since skies are only visible in reflections, this code will also
-render clouds and sky bodies.
-*/
-class WaterRenderObjClass : public Snapshot,
- public RenderObjClass
-{
-
-public:
-
- enum WaterType
- {
- WATER_TYPE_0_TRANSLUCENT = 0, //translucent water, no reflection
- WATER_TYPE_1_FB_REFLECTION, //legacy frame buffer reflection (non translucent)
- WATER_TYPE_2_PVSHADER, //pixel/vertex shader, texture reflection
- WATER_TYPE_3_GRIDMESH, //3D Mesh based water
- };
-
- WaterRenderObjClass(void);
- ~WaterRenderObjClass(void);
-
- /////////////////////////////////////////////////////////////////////////////
- // Render Object Interface (W3D methods)
- /////////////////////////////////////////////////////////////////////////////
- virtual RenderObjClass * Clone(void) const;
- virtual int Class_ID(void) const;
- virtual void Render(RenderInfoClass & rinfo);
-/// @todo: Add methods for collision detection with water surface
-// virtual Bool Cast_Ray(RayCollisionTestClass & raytest);
-// virtual Bool Cast_AABox(AABoxCollisionTestClass & boxtest);
-// virtual Bool Cast_OBBox(OBBoxCollisionTestClass & boxtest);
-// virtual Bool Intersect_AABox(AABoxIntersectionTestClass & boxtest);
-// virtual Bool Intersect_OBBox(OBBoxIntersectionTestClass & boxtest);
-
- virtual void Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const;
- virtual void Get_Obj_Space_Bounding_Box(AABoxClass & aabox) const;
- // Get and set static sort level
- virtual int Get_Sort_Level(void) const { return m_sortLevel; }
- virtual void Set_Sort_Level(int level) { m_sortLevel = level;}
-
- ///allocate W3D resources needed to render water
- void renderWater(void); /// m_gridCellsX-1 )
- return FALSE;
- if (gridY < 0)
- return FALSE;
- if (gridY > m_gridCellsY-1 )
- return FALSE;
-
- return TRUE;
-}
-
-extern WaterRenderObjClass *TheWaterRenderObj; ///.
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-enum waveType CPP_11(: Int); //forward reference
-
-/// Custom render object that draws animated tracks/waves on the water.
-/**
- This is an object which draws a small breaking wave or splash animation. These objects are
- to be managed/accessed only by the WaterTracksRenderObjClassSystem
-*/
-class WaterTracksObj
-{
- friend class WaterTracksRenderSystem;
-
-public:
-
- WaterTracksObj(void);
- ~WaterTracksObj(void);
-
- virtual void Render(void) {}; ///.
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: W3DLaserDraw.cpp /////////////////////////////////////////////////////////////////////////
-// Author: Colin Day, May 2001
-// Desc: W3DLaserDraw
-// Updated: Kris Morness July 2002 -- made it data driven and added new features to make it flexible.
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include
-
-#include "Common/Thing.h"
-#include "Common/ThingTemplate.h"
-#include "Common/Xfer.h"
-#include "GameClient/Color.h"
-#include "GameClient/Drawable.h"
-#include "GameClient/GameClient.h"
-#include "GameClient/RayEffect.h"
-#include "GameLogic/GameLogic.h"
-#include "GameLogic/Object.h"
-#include "GameLogic/TerrainLogic.h"
-#include "GameLogic/Module/LaserUpdate.h"
-#include "W3DDevice/GameClient/Module/W3DLaserDraw.h"
-#include "W3DDevice/GameClient/W3DDisplay.h"
-#include "W3DDevice/GameClient/W3DScene.h"
-#include "WW3D2/rinfo.h"
-#include "WW3D2/camera.h"
-#include "WW3D2/segline.h"
-#include "WWMath/vector3.h"
-#include "WW3D2/assetmgr.h"
-
-
-
-// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////////////////////////
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-W3DLaserDrawModuleData::W3DLaserDrawModuleData()
-{
- m_innerBeamWidth = 0.0f; //The total width of beam
- m_outerBeamWidth = 1.0f; //The total width of beam
- m_numBeams = 1; //Number of overlapping cylinders that make the beam. 1 beam will just use inner data.
- m_maxIntensityFrames = 0; //Laser stays at max intensity for specified time in ms.
- m_fadeFrames = 0; //Laser will fade and delete.
- m_scrollRate = 0.0f;
- m_tile = false;
- m_segments = 1;
- m_arcHeight = 0.0f;
- m_segmentOverlapRatio = 0.0f;
- m_tilingScalar = 1.0f;
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-W3DLaserDrawModuleData::~W3DLaserDrawModuleData()
-{
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void W3DLaserDrawModuleData::buildFieldParse(MultiIniFieldParse& p)
-{
- ModuleData::buildFieldParse(p);
-
- static const FieldParse dataFieldParse[] =
- {
- { "NumBeams", INI::parseUnsignedInt, NULL, offsetof( W3DLaserDrawModuleData, m_numBeams ) },
- { "InnerBeamWidth", INI::parseReal, NULL, offsetof( W3DLaserDrawModuleData, m_innerBeamWidth ) },
- { "OuterBeamWidth", INI::parseReal, NULL, offsetof( W3DLaserDrawModuleData, m_outerBeamWidth ) },
- { "InnerColor", INI::parseColorInt, NULL, offsetof( W3DLaserDrawModuleData, m_innerColor ) },
- { "OuterColor", INI::parseColorInt, NULL, offsetof( W3DLaserDrawModuleData, m_outerColor ) },
- { "MaxIntensityLifetime", INI::parseDurationUnsignedInt, NULL, offsetof( W3DLaserDrawModuleData, m_maxIntensityFrames ) },
- { "FadeLifetime", INI::parseDurationUnsignedInt, NULL, offsetof( W3DLaserDrawModuleData, m_fadeFrames ) },
- { "Texture", INI::parseAsciiString, NULL, offsetof( W3DLaserDrawModuleData, m_textureName ) },
- { "ScrollRate", INI::parseReal, NULL, offsetof( W3DLaserDrawModuleData, m_scrollRate ) },
- { "Tile", INI::parseBool, NULL, offsetof( W3DLaserDrawModuleData, m_tile ) },
- { "Segments", INI::parseUnsignedInt, NULL, offsetof( W3DLaserDrawModuleData, m_segments ) },
- { "ArcHeight", INI::parseReal, NULL, offsetof( W3DLaserDrawModuleData, m_arcHeight ) },
- { "SegmentOverlapRatio", INI::parseReal, NULL, offsetof( W3DLaserDrawModuleData, m_segmentOverlapRatio ) },
- { "TilingScalar", INI::parseReal, NULL, offsetof( W3DLaserDrawModuleData, m_tilingScalar ) },
- { 0, 0, 0, 0 }
- };
- p.add(dataFieldParse);
-}
-
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-W3DLaserDraw::W3DLaserDraw( Thing *thing, const ModuleData* moduleData ) :
- DrawModule( thing, moduleData ),
- m_line3D(NULL),
- m_texture(NULL),
- m_textureAspectRatio(1.0f),
- m_selfDirty(TRUE)
-{
- Vector3 dummyPos1( 0.0f, 0.0f, 0.0f );
- Vector3 dummyPos2( 1.0f, 1.0f, 1.0f );
- Int i;
-
- const W3DLaserDrawModuleData *data = getW3DLaserDrawModuleData();
-
- m_texture = WW3DAssetManager::Get_Instance()->Get_Texture( data->m_textureName.str() );
- if (m_texture)
- {
- SurfaceClass::SurfaceDescription surfaceDesc;
- m_texture->Get_Level_Description(surfaceDesc);
- m_textureAspectRatio = (Real)surfaceDesc.Width/(Real)surfaceDesc.Height;
- }
-
- //Get the color components for calculation purposes.
- Real innerRed, innerGreen, innerBlue, innerAlpha, outerRed, outerGreen, outerBlue, outerAlpha;
- GameGetColorComponentsReal( data->m_innerColor, &innerRed, &innerGreen, &innerBlue, &innerAlpha );
- GameGetColorComponentsReal( data->m_outerColor, &outerRed, &outerGreen, &outerBlue, &outerAlpha );
-
- //Make sure our beams range between 1 and the maximum cap.
-#ifdef I_WANT_TO_BE_FIRED
-// srj sez: this data is const for a reason. casting away the constness because we don't like the values
-// isn't an acceptable solution. if you need to constrain the values, do so at parsing time, when
-// it's still legal to modify these values. (In point of fact, there's not even really any reason to limit
-// the numBeams or segments anymore.)
- data->m_numBeams = __min( __max( 1, data->m_numBeams ), MAX_LASER_LINES );
- data->m_segments = __min( __max( 1, data->m_segments ), MAX_SEGMENTS );
- data->m_tilingScalar = __max( 0.01f, data->m_tilingScalar );
-#endif
-
- //Allocate an array of lines equal to the number of beams * segments
- m_line3D = NEW SegmentedLineClass *[ data->m_numBeams * data->m_segments ];
-
- for( UnsignedInt segment = 0; segment < data->m_segments; segment++ )
- {
- //We don't care about segment positioning yet until we actually set the position
-
- // create all the lines we need at the right transparency level
- for( i = data->m_numBeams - 1; i >= 0; i-- )
- {
- int index = segment * data->m_numBeams + i;
-
- Real red, green, blue, alpha, width;
-
- if( data->m_numBeams == 1 )
- {
- width = data->m_innerBeamWidth;
- alpha = innerAlpha;
- red = innerRed * innerAlpha;
- green = innerGreen * innerAlpha;
- blue = innerBlue * innerAlpha;
- }
- else
- {
- //Calculate the scale between min and max values
- //0 means use min value, 1 means use max value
- //0.2 means min value + 20% of the diff between min and max
- Real scale = i / ( data->m_numBeams - 1.0f);
-
- width = data->m_innerBeamWidth + scale * (data->m_outerBeamWidth - data->m_innerBeamWidth);
- alpha = innerAlpha + scale * (outerAlpha - innerAlpha);
- red = innerRed + scale * (outerRed - innerRed) * innerAlpha;
- green = innerGreen + scale * (outerGreen - innerGreen) * innerAlpha;
- blue = innerBlue + scale * (outerBlue - innerBlue) * innerAlpha;
- }
-
- m_line3D[ index ] = NEW SegmentedLineClass;
-
- SegmentedLineClass *line = m_line3D[ index ];
- if( line )
- {
- line->Set_Texture( m_texture );
- line->Set_Shader( ShaderClass::_PresetAdditiveShader ); //pick the alpha blending mode you want - see shader.h for others.
- line->Set_Width( width );
- line->Set_Color( Vector3( red, green, blue ) );
- line->Set_UV_Offset_Rate( Vector2(0.0f, data->m_scrollRate) ); //amount to scroll texture on each draw
- if( m_texture )
- {
- line->Set_Texture_Mapping_Mode(SegLineRendererClass::TILED_TEXTURE_MAP); //this tiles the texture across the line
- }
-
- // add to scene
- if (W3DDisplay::m_3DScene != NULL)
- W3DDisplay::m_3DScene->Add_Render_Object( line ); //add it to our scene so it gets rendered with other objects.
-
- // hide the render object until the first time we come to draw it and
- // set the correct position
- line->Set_Visible( 0 );
- }
-
-
- }
-
- }
-
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-W3DLaserDraw::~W3DLaserDraw( void )
-{
- const W3DLaserDrawModuleData *data = getW3DLaserDrawModuleData();
-
- for( UnsignedInt i = 0; i < data->m_numBeams * data->m_segments; i++ )
- {
-
- // remove line from scene
- if (W3DDisplay::m_3DScene != NULL)
- W3DDisplay::m_3DScene->Remove_Render_Object( m_line3D[ i ] );
-
- // delete line
- REF_PTR_RELEASE( m_line3D[ i ] );
-
- }
-
- delete [] m_line3D;
- // TheSuperHackers @fix Mauller 11/03/2025 Free reference counted material
- REF_PTR_RELEASE(m_texture);
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-Real W3DLaserDraw::getLaserTemplateWidth() const
-{
- const W3DLaserDrawModuleData *data = getW3DLaserDrawModuleData();
- return data->m_outerBeamWidth * 0.5f;
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void W3DLaserDraw::doDrawModule(const Matrix3D* transformMtx)
-{
- //UnsignedInt currentFrame = TheGameClient->getFrame();
- const W3DLaserDrawModuleData *data = getW3DLaserDrawModuleData();
-
- //Get the updatemodule that drives it...
- Drawable *draw = getDrawable();
- static NameKeyType key_LaserUpdate = NAMEKEY( "LaserUpdate" );
- LaserUpdate *update = (LaserUpdate*)draw->findClientUpdateModule( key_LaserUpdate );
- if( !update )
- {
- DEBUG_ASSERTCRASH( 0, ("W3DLaserDraw::doDrawModule() expects its owner drawable %s to have a ClientUpdate = LaserUpdate module.", draw->getTemplate()->getName().str() ));
- return;
- }
-
- //If the update has moved the laser, it requires a reset of the laser.
- if (update->isDirty() || m_selfDirty)
- {
- update->setDirty(false);
- m_selfDirty = false;
-
- Vector3 laserPoints[ 2 ];
-
- for( UnsignedInt segment = 0; segment < data->m_segments; segment++ )
- {
- if( data->m_arcHeight > 0.0f && data->m_segments > 1 )
- {
- //CALCULATE A CURVED LINE BASED ON TOTAL LENGTH AND DESIRED HEIGHT INCREASE
- //To do this we will use a portion of the cos wave ranging between -0.25PI
- //and +0.25PI. 0PI is 1.0 and 0.25PI is 0.70 -- resulting in a somewhat
- //gentle curve depending on the line height and length. We also have to make
- //the line *level* for this phase of the calculations.
-
- //Get the desired direct line
- Coord3D lineStart, lineEnd, lineVector;
- lineStart.set( update->getStartPos() );
- lineEnd.set( update->getEndPos() );
- //This is critical -- in the case we have sloped lines (at the end, we'll fix it)
-// lineEnd.z = lineStart.z;
-
- //Get the length of the line
- lineVector.set( &lineEnd );
- lineVector.sub( &lineStart );
- Real lineLength = lineVector.length();
-
- //Get the middle point (we'll use this to determine how far we are from
- //that to calculate our height -- middle point is the highest).
- Coord3D lineMiddle;
- lineMiddle.set( &lineStart );
- lineMiddle.add( &lineEnd );
- lineMiddle.scale( 0.5 );
-
- //The half length is used to scale with the distance from middle to
- //get our cos( 0 to 0.25 PI) cos value
- Real halfLength = lineLength * 0.5f;
-
- //Now calculate which segment we will use.
- Real startSegmentRatio = segment / ((Real)data->m_segments);
- Real endSegmentRatio = (segment + 1.0f) / ((Real)data->m_segments);
-
- //Offset the segment ever-so-slightly to minimize overlap -- only apply
- //to segments that are not the start/end point
- if( segment > 0 )
- {
- startSegmentRatio -= data->m_segmentOverlapRatio;
- }
- if( segment < data->m_segments - 1 )
- {
- endSegmentRatio += data->m_segmentOverlapRatio;
- }
-
- //Calculate our start segment position on the *ground*.
- Coord3D segmentStart, segmentEnd, vector;
- vector.set( &lineVector );
- vector.scale( startSegmentRatio );
- segmentStart.set( &lineStart );
- segmentStart.add( &vector );
-
- //Calculate our end segment position on the *ground*.
- vector.set( &lineVector );
- vector.scale( endSegmentRatio );
- segmentEnd.set( &lineStart );
- segmentEnd.add( &vector );
-
- //--------------------------------------------------------------------------------
- //Now at this point, we have our segment line in the level positions that we want.
- //Calculate the raised height for the start/end segment positions using cosine.
- //--------------------------------------------------------------------------------
-
- //Calculate the distance from midpoint for the start positions.
- vector.set( &lineMiddle );
- vector.sub( &segmentStart );
- Real dist = vector.length();
- Real scaledRadians = dist / halfLength * PI * 0.5f;
- Real height = cos( scaledRadians );
- height *= data->m_arcHeight;
- segmentStart.z += height;
-
- //Now do the same thing for the end position.
- vector.set( &lineMiddle );
- vector.sub( &segmentEnd );
- dist = vector.length();
- scaledRadians = dist / halfLength * PI * 0.5f;
- height = cos( scaledRadians );
- height *= data->m_arcHeight;
- segmentEnd.z += height;
-
- //This makes the laser skim the ground rather than penetrate it!
- laserPoints[ 0 ].Set( segmentStart.x, segmentStart.y,
- MAX( segmentStart.z, 2.0f + TheTerrainLogic->getGroundHeight(segmentStart.x, segmentStart.y) ) );
- laserPoints[ 1 ].Set( segmentEnd.x, segmentEnd.y,
- MAX( segmentEnd.z, 2.0f + TheTerrainLogic->getGroundHeight(segmentEnd.x, segmentEnd.y) ) );
-
- }
- else
- {
- //No arc -- way simpler!
- laserPoints[ 0 ].Set( update->getStartPos()->x, update->getStartPos()->y, update->getStartPos()->z );
- laserPoints[ 1 ].Set( update->getEndPos()->x, update->getEndPos()->y, update->getEndPos()->z );
- }
-
- //Get the color components for calculation purposes.
- Real innerRed, innerGreen, innerBlue, innerAlpha, outerRed, outerGreen, outerBlue, outerAlpha;
- GameGetColorComponentsReal( data->m_innerColor, &innerRed, &innerGreen, &innerBlue, &innerAlpha );
- GameGetColorComponentsReal( data->m_outerColor, &outerRed, &outerGreen, &outerBlue, &outerAlpha );
-
- for( Int i = data->m_numBeams - 1; i >= 0; i-- )
- {
-
- Real alpha, width;
- int index = segment * data->m_numBeams + i;
-
- if( data->m_numBeams == 1 )
- {
- width = data->m_innerBeamWidth * update->getWidthScale();
- alpha = innerAlpha;
- }
- else
- {
- //Calculate the scale between min and max values
- //0 means use min value, 1 means use max value
- //0.2 means min value + 20% of the diff between min and max
- Real scale = i / ( data->m_numBeams - 1.0f);
- Real ultimateScale = update->getWidthScale();
- width = (data->m_innerBeamWidth + scale * (data->m_outerBeamWidth - data->m_innerBeamWidth));
- width *= ultimateScale;
- alpha = innerAlpha + scale * (outerAlpha - innerAlpha);
- }
-
-
- //Calculate the number of times to tile the line based on the height of the texture used.
- if( m_texture && data->m_tile )
- {
- //Calculate the length of the line.
- Vector3 lineVector;
- Vector3::Subtract( laserPoints[1], laserPoints[0], &lineVector );
- Real length = lineVector.Length();
-
- //Adjust tile factor so texture is NOT stretched but tiled equally in both width and length.
- Real tileFactor = length/width*m_textureAspectRatio*data->m_tilingScalar;
-
- //Set the tile factor
- m_line3D[ index ]->Set_Texture_Tile_Factor( tileFactor ); //number of times to tile texture across each segment
- }
-
- m_line3D[ index ]->Set_Width( width );
- m_line3D[ index ]->Set_Points( 2, &laserPoints[0] );
- }
- }
- }
-
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-/** CRC */
-// ------------------------------------------------------------------------------------------------
-void W3DLaserDraw::crc( Xfer *xfer )
-{
-
- // extend base class
- DrawModule::crc( xfer );
-
-}
-
-// ------------------------------------------------------------------------------------------------
-/** Xfer method
- * Version Info:
- * 1: Initial version */
-// ------------------------------------------------------------------------------------------------
-void W3DLaserDraw::xfer( Xfer *xfer )
-{
-
- // version
- const XferVersion currentVersion = 1;
- XferVersion version = currentVersion;
- xfer->xferVersion( &version, currentVersion );
-
- // extend base class
- DrawModule::xfer( xfer );
-
- // Kris says there is no data to save for these, go ask him.
- // m_selfDirty is not saved, is runtime only
-
-}
-
-// ------------------------------------------------------------------------------------------------
-/** Load post process */
-// ------------------------------------------------------------------------------------------------
-void W3DLaserDraw::loadPostProcess( void )
-{
-
- // extend base class
- DrawModule::loadPostProcess();
-
- m_selfDirty = true; // so we update the first time after reload
-
-}
diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp
index 7466599e104..49c3c00e9b5 100644
--- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp
+++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp
@@ -261,7 +261,7 @@ Bool W3DProjectedShadowManager::ReAcquireResources(void)
DEBUG_ASSERTCRASH(m_dynamicRenderTarget == NULL, ("Acquire of existing shadow render target"));
m_renderTargetHasAlpha=TRUE;
- if ((m_dynamicRenderTarget=DX8Wrapper::Create_Render_Target (DEFAULT_RENDER_TARGET_WIDTH, DEFAULT_RENDER_TARGET_HEIGHT, true)) == NULL)
+ if ((m_dynamicRenderTarget=DX8Wrapper::Create_Render_Target (DEFAULT_RENDER_TARGET_WIDTH, DEFAULT_RENDER_TARGET_HEIGHT, WW3D_FORMAT_A8R8G8B8)) == NULL)
{
m_renderTargetHasAlpha=FALSE;
diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DAssetManager.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DAssetManager.cpp
index 55a53a8596d..a0143fd001a 100644
--- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DAssetManager.cpp
+++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DAssetManager.cpp
@@ -627,7 +627,7 @@ TextureClass * W3DAssetManager::Recolor_Texture_One_Time(TextureClass *texture,
// make sure texture is loaded
if (!texture->Is_Initialized())
- TextureLoader::Request_High_Priority_Loading(texture, (MipCountType)texture->Get_Mip_Level_Count());
+ TextureLoader::Request_Foreground_Loading(texture);
SurfaceClass::SurfaceDescription desc;
SurfaceClass *newsurf, *oldsurf;
diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp
index b8ce435c769..88b25cd33ae 100644
--- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp
+++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp
@@ -402,7 +402,6 @@ W3DDisplay::~W3DDisplay()
// shutdown
Debug_Statistics::Shutdown_Statistics();
- TextureLoadTaskClass::shutdown();
if (!TheGlobalData->m_headless)
W3DShaderManager::shutdown();
m_assetManager->Free_Assets();
diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp
deleted file mode 100644
index 258bf46c868..00000000000
--- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp
+++ /dev/null
@@ -1,3455 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: W3DWater.cpp /////////////////////////////////////////////////////////////////////////////
-// Created: Mark Wilczynski, June 2001
-// Desc: Draw reflective water surface. Also handles drawing of waves/ripples
-// on the surface.
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#define SCROLL_UV
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "W3DDevice/GameClient/W3DWater.h"
-#include "W3DDevice/GameClient/HeightMap.h"
-#include "W3DDevice/GameClient/W3DShroud.h"
-#include "W3DDevice/GameClient/W3DWaterTracks.h"
-#include "W3DDevice/GameClient/W3DAssetManager.h"
-#include "texture.h"
-#include "assetmgr.h"
-#include "rinfo.h"
-#include "camera.h"
-#include "scene.h"
-#include "dx8wrapper.h"
-#include "light.h"
-#include "d3dx8math.h"
-#include "simplevec.h"
-#include "mesh.h"
-#include "matinfo.h"
-
-#include "Common/FramePacer.h"
-#include "Common/GameState.h"
-#include "Common/GlobalData.h"
-#include "Common/PerfTimer.h"
-#include "Common/Xfer.h"
-#include "Common/GameLOD.h"
-
-#include "GameClient/Water.h"
-#include "GameLogic/GameLogic.h"
-#include "GameLogic/PolygonTrigger.h"
-#include "GameLogic/ScriptEngine.h"
-#include "W3DDevice/GameClient/W3DShaderManager.h"
-#include "W3DDevice/GameClient/W3DDisplay.h"
-#include "W3DDevice/GameClient/W3DPoly.h"
-#include "W3DDevice/GameClient/W3DScene.h"
-#include "W3DDevice/GameClient/W3DCustomScene.h"
-
-
-
-#define MIPMAP_BUMP_TEXTURE
-
-// DEFINES ////////////////////////////////////////////////////////////////////////////////////////
-#define SKYPLANE_SIZE (384.0f*MAP_XY_FACTOR)
-#define SKYPLANE_HEIGHT (30.0f)
-
-#define SKYBODY_TEXTURE "TSMoonLarg.tga"
-#define SKYBODY_SIZE 45.0f //extent or radius of sky body
-
-#define SKYBODY_X 150.0f //location of skybody
-#define SKYBODY_Y 550.0f //location of skybody
-
-/* in the bay
-#define SKYBODY_X 120.0f //location of skybody
-#define SKYBODY_Y 75.0f //location of skybody
-*/
-
-#define SKYBODY_HEIGHT SKYPLANE_HEIGHT //altitude of sky body (z-buffer disabled, so can equal sky height).
-
-//GeForce3 water system defines
-#define PATCH_SIZE 15 //number of vertices on patch edge. Large patches may waste vertices off edge of screen.
-#define PATCH_UV_TILES 42 //number of times the bump map texture is tiled across patch (must be integer!).
-#define PATCH_SCALE (4.0f * MAP_XY_FACTOR) //horizontal scale factor. Adjust this and size to get desired vertex density.
-#define SEA_REFLECTION_SIZE 256 //dimensions of reflection texture
-
-#define SEA_BUMP_SCALE (0.06f) //scales the du/dv offsets stored in bump map (~ amount to perturb)
-#define BUMP_SIZE (50.f)
-#define REFLECTION_FACTOR 0.1f
-
-#define PATCH_WIDTH (PATCH_SIZE-1) //internal defines
-#define PATCH_UV_SCALE ((Real)PATCH_UV_TILES/(Real)PATCH_WIDTH)
-
-//3D Grid Mesh Water defines.
-#define WATER_MESH_OPACITY 0.5f
-#define WATER_MESH_X_VERTICES 128
-#define WATER_MESH_Y_VERTICES 128
-#define WATER_MESH_SPACING MAP_XY_FACTOR //same as terrain
-
-#ifdef USE_MESH_NORMALS
-#define WATER_MESH_FVF DX8_FVF_XYZNDUV2
-typedef VertexFormatXYZNDUV2 MaterMeshVertexFormat;
-#else
-#define WATER_MESH_FVF DX8_FVF_XYZDUV2
-typedef VertexFormatXYZDUV2 MaterMeshVertexFormat;
-#endif
-
-// Converts a FLOAT to a DWORD for use in SetRenderState() calls
-static inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); }
-
-#define DRAW_WATER_WAKES
-/// @todo: Fix clipping of objects that intersect the mirror surface
-//#define CLIP_GEOMETRY_TO_PLANE // this enables clipping of objects that intersect the mirror surfaces
-
-// Some shader combinations that can be useful in rendering water:
-
-// Modulate stage0 with stage1 texture. Also modulate stage 0 with vertex color.
-#define SC_DETAIL_BLEND ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_ENABLE, ShaderClass::COLOR_WRITE_ENABLE,\
- ShaderClass::SRCBLEND_SRC_ALPHA,ShaderClass::DSTBLEND_ONE_MINUS_SRC_ALPHA, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_MODULATE, ShaderClass::SECONDARY_GRADIENT_DISABLE, \
- ShaderClass::TEXTURING_ENABLE, ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_ENABLE, ShaderClass::DETAILCOLOR_DETAILBLEND, ShaderClass::DETAILALPHA_DISABLE) )
-
-// Just a z-buffer fill, nothing is written to the color buffer.
-#define SC_ZFILL_BLEND ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_ENABLE, ShaderClass::COLOR_WRITE_DISABLE, ShaderClass::SRCBLEND_ZERO, \
- ShaderClass::DSTBLEND_ONE, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_MODULATE, ShaderClass::SECONDARY_GRADIENT_DISABLE, ShaderClass::TEXTURING_ENABLE, \
- ShaderClass::DETAILCOLOR_SCALE, ShaderClass::DETAILALPHA_DISABLE, ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_ENABLE, \
- ShaderClass::DETAILCOLOR_SCALE, ShaderClass::DETAILALPHA_DISABLE) )
-
-// No texturing, just vertex color with vertex alpha
-#define SC_ZFILL_BLENDx ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_ENABLE, ShaderClass::COLOR_WRITE_ENABLE, \
- ShaderClass::SRCBLEND_ZERO, ShaderClass::DSTBLEND_SRC_COLOR, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_MODULATE, ShaderClass::SECONDARY_GRADIENT_DISABLE, \
- ShaderClass::TEXTURING_DISABLE, ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE, ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_ENABLE, \
- ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) )
-
-// Modulate blended with vertex alpha modulation
-#define SC_ZFILL_MODULATE_TEX ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_ENABLE, ShaderClass::COLOR_WRITE_ENABLE,\
- ShaderClass::SRCBLEND_ZERO, ShaderClass::DSTBLEND_SRC_COLOR, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_MODULATE, ShaderClass::SECONDARY_GRADIENT_DISABLE, \
- ShaderClass::TEXTURING_ENABLE, ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_DISABLE, ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) )
-
-// Alpha blended with vertex alpha modulation
-#define SC_ZFILL_ALPHA_TEX ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_ENABLE, ShaderClass::COLOR_WRITE_ENABLE,\
- ShaderClass::SRCBLEND_SRC_ALPHA, ShaderClass::DSTBLEND_ONE_MINUS_SRC_ALPHA, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_DISABLE, ShaderClass::SECONDARY_GRADIENT_DISABLE, \
- ShaderClass::TEXTURING_ENABLE, ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_DISABLE, ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) )
-
-// Alpha blended with vertex alpha modulation
-#define SC_OPAQUE_TEXONLY ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_ENABLE, ShaderClass::COLOR_WRITE_ENABLE,\
- ShaderClass::SRCBLEND_ONE, ShaderClass::DSTBLEND_ZERO, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_DISABLE, ShaderClass::SECONDARY_GRADIENT_DISABLE, \
- ShaderClass::TEXTURING_ENABLE, ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_DISABLE, ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) )
-
-// Alpha blended with vertex alpha modulation
-#define SC_ZFILL_BLEND3 ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_ENABLE, ShaderClass::COLOR_WRITE_ENABLE,\
- ShaderClass::SRCBLEND_SRC_ALPHA, ShaderClass::DSTBLEND_ONE_MINUS_SRC_ALPHA, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_MODULATE, ShaderClass::SECONDARY_GRADIENT_DISABLE, \
- ShaderClass::TEXTURING_ENABLE, ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_DISABLE, ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) )
-
-static ShaderClass zFillAlphaShader(SC_ZFILL_BLEND3);
-static ShaderClass blendStagesShader(SC_DETAIL_BLEND);
-
-WaterRenderObjClass *TheWaterRenderObj=NULL; ///Release(); (p)=NULL; } }
-
-void doSkyBoxSet(Bool startDraw)
-{
- if (TheWritableGlobalData)
- TheWritableGlobalData->m_drawSkyBox = startDraw;
-}
-
-
-#define DONUT_SIDES 90
-#define INNER_RADIUS 200.0f
-#define OUTER_RADIUS 250.0f
-#define TEXTURE_REPEAT_COUNT 16
-#define DONUT_HEIGHT 15.0f
-//#define DO_FLAT_DONUT
-#define AMP_SCALE (30.0f/120.0f)
-#define WAVE_FREQ 0.3f
-#define AMP_SCALE2 (10.0f/120.0f)
-#define NOISE_FREQ (2.0f*PI/WAVE_FREQ)
-
-#define NOISE_REPEAT_FACTOR ((float)(1.0f/(16.0f)))
-
-
-static Bool wireframeForDebug = 0;
-
-void WaterRenderObjClass::setupJbaWaterShader(void)
-{
- if (!TheWaterTransparency->m_additiveBlend)
- DX8Wrapper::Set_Shader(ShaderClass::_PresetAlphaShader);
- else
- DX8Wrapper::Set_Shader(ShaderClass::_PresetAdditiveShader);
-
- VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- DX8Wrapper::Set_Material(vmat);
- REF_PTR_RELEASE(vmat);
- m_riverTexture->Get_Filter().Set_Mag_Filter(TextureFilterClass::FILTER_TYPE_BEST);
- m_riverTexture->Get_Filter().Set_Min_Filter(TextureFilterClass::FILTER_TYPE_BEST);
- m_riverTexture->Get_Filter().Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_BEST);
-
-
-// Setting *setting=&m_settings[m_tod];
-
-
- DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_ADD );
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(3,m_riverAlphaEdge->Peek_D3D_Texture());
- DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, 0);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXCOORDINDEX, 0);
- DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_TEXCOORDINDEX, 1);
-
- Bool doSparkles = true;
-
- if (m_riverWaterPixelShader && doSparkles) {
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1,m_waterSparklesTexture->Peek_D3D_Texture());
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(2,m_waterNoiseTexture->Peek_D3D_Texture());
-
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
-
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- D3DXMATRIX inv;
- float det;
-
- Matrix4x4 curView;
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
- D3DXMATRIX scale;
-
- D3DXMatrixScaling(&scale, NOISE_REPEAT_FACTOR, NOISE_REPEAT_FACTOR,1);
- D3DXMATRIX destMatrix = inv * scale;
- D3DXMatrixTranslation(&scale, m_riverVOrigin, m_riverVOrigin,0);
- destMatrix = destMatrix*scale;
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE2, *(Matrix4x4*)&destMatrix);
-
- }
- m_pDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 2, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 3, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- if (m_riverWaterPixelShader){
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(0, D3DXVECTOR4(REFLECTION_FACTOR, REFLECTION_FACTOR, REFLECTION_FACTOR, 1.0f), 1);
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_riverWaterPixelShader);
- }
-}
-
-
-
-
-//-------------------------------------------------------------------------------------------------
-/** Destructor. Releases w3d assets. */
-//-------------------------------------------------------------------------------------------------
-WaterRenderObjClass::~WaterRenderObjClass(void)
-{
- REF_PTR_RELEASE(m_meshVertexMaterialClass);
- REF_PTR_RELEASE(m_vertexMaterialClass);
- REF_PTR_RELEASE(m_meshLight);
- REF_PTR_RELEASE(m_alphaClippingTexture);
- REF_PTR_RELEASE (m_skyBox);
-
- REF_PTR_RELEASE (m_riverTexture);
- REF_PTR_RELEASE (m_whiteTexture);
- REF_PTR_RELEASE (m_waterNoiseTexture);
- REF_PTR_RELEASE (m_riverAlphaEdge);
- REF_PTR_RELEASE (m_waterSparklesTexture);
-
- Int i;
-
- for(i=0; iGet_Level_Description(d3dsd);
-
- if (Get_Bytes_Per_Pixel(d3dsd.Format) != 4)
- {
- // LORENZEN WAS BUGGED BY THIS,
- // DEBUG_CRASH(("WaterRenderObjClass::Invalid BumpMap format - Was it compressed?") );
- return S_OK;
- }
-
- if (pBumpSource->Peek_D3D_Texture())
- {
- numLevels=pBumpSource->Peek_D3D_Texture()->GetLevelCount();
- }
- else
- return S_OK;
-
- pTex[0]=DX8Wrapper::_Create_DX8_Texture(d3dsd.Width,d3dsd.Height,WW3D_FORMAT_U8V8,MIP_LEVELS_ALL,D3DPOOL_MANAGED,false);
-
- for (Int level=0; level < numLevels; level++)
- {
- surf=pBumpSource->Get_Surface_Level(level);
- surf->Get_Description(d3dsd);
- pSrc=(unsigned char *)surf->Lock((int *)&dwSrcPitch);
-
- pTex[0]->LockRect( level, &d3dlr, 0, 0 );
- DWORD dwDstPitch = (DWORD)d3dlr.Pitch;
- BYTE* pDst = (BYTE*)d3dlr.pBits;
-
- for( DWORD y=0; y1 ) ? 63 : 127;
-
- switch( D3DFMT_V8U8)//m_BumpMapFormat )
- {
- case D3DFMT_V8U8:
- *pDstT++ = (BYTE)iDu;
- *pDstT++ = (BYTE)iDv;
- break;
-
- case D3DFMT_L6V5U5:
- *(WORD*)pDstT = (WORD)( ( (iDu>>3) & 0x1f ) << 0 );
- *(WORD*)pDstT |= (WORD)( ( (iDv>>3) & 0x1f ) << 5 );
- *(WORD*)pDstT |= (WORD)( ( ( uL>>2) & 0x3f ) << 10 );
- pDstT += 2;
- break;
-
- case D3DFMT_X8L8V8U8:
- *pDstT++ = (BYTE)iDu;
- *pDstT++ = (BYTE)iDv;
- *pDstT++ = (BYTE)uL;
- *pDstT++ = (BYTE)0L;
- break;
- }
-
- // Move one pixel to the left (src is 32-bpp)
- pSrcB0+=4; pSrcB1+=4; pSrcB2+=4;
- }
-
- // Move to the next line
- pSrc += dwSrcPitch; pDst += dwDstPitch;
- }
-
- pTex[0]->UnlockRect(level);
- surf->Unlock();
- REF_PTR_RELEASE (surf);
- }
-
-#else
- surf=pBumpSource->Get_Surface_Level();
- surf->Get_Description(d3dsd);
- pSrc=(unsigned char *)surf->Lock((int *)&dwSrcPitch);
-
- // Create the bumpmap's surface and texture objects
- m_pBumpTexture[i]=DX8Wrapper::_Create_DX8_Texture(d3dsd.Width,d3dsd.Height,WW3D_FORMAT_U8V8,MIP_LEVELS_1,D3DPOOL_MANAGED,false);
-
- // Fill the bits of the new texture surface with bits from
- // a private format.
-
- m_pBumpTexture[i]->LockRect( 0, &d3dlr, 0, 0 );
- DWORD dwDstPitch = (DWORD)d3dlr.Pitch;
- BYTE* pDst = (BYTE*)d3dlr.pBits;
-
- for( DWORD y=0; y1 ) ? 63 : 127;
-
- switch( D3DFMT_V8U8)//m_BumpMapFormat )
- {
- case D3DFMT_V8U8:
- *pDstT++ = (BYTE)iDu;
- *pDstT++ = (BYTE)iDv;
- break;
-
- case D3DFMT_L6V5U5:
- *(WORD*)pDstT = (WORD)( ( (iDu>>3) & 0x1f ) << 0 );
- *(WORD*)pDstT |= (WORD)( ( (iDv>>3) & 0x1f ) << 5 );
- *(WORD*)pDstT |= (WORD)( ( ( uL>>2) & 0x3f ) << 10 );
- pDstT += 2;
- break;
-
- case D3DFMT_X8L8V8U8:
- *pDstT++ = (BYTE)iDu;
- *pDstT++ = (BYTE)iDv;
- *pDstT++ = (BYTE)uL;
- *pDstT++ = (BYTE)0L;
- break;
- }
-
- // Move one pixel to the left (src is 32-bpp)
- pSrcB0+=4; pSrcB1+=4; pSrcB2+=4;
- }
-
- // Move to the next line
- pSrc += dwSrcPitch; pDst += dwDstPitch;
- }
-
- m_pBumpTexture[i]->UnlockRect(0);
- surf->Unlock();
-#endif
-
- return S_OK;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Create and fill a D3D vertex buffer with water surface vertices */
-//-------------------------------------------------------------------------------------------------
-HRESULT WaterRenderObjClass::generateVertexBuffer( Int sizeX, Int sizeY, Int vertexSize, Bool doStatic)
-{
- m_numVertices=sizeX*sizeY;
- //Assuming dynamic vertex buffer, allocate maximum multiple of required size to allow rendering from
- //different parts of the buffer. 5-15-03: Disabled this since we use DISCARD mode instead to avoid Nvidia Runtime bug. -MW
- //m_numVertices=(65536 / (sizeX*sizeY))*sizeX*sizeY;
-
- SEA_PATCH_VERTEX* pVertices;
-
- Setting *setting=&m_settings[m_tod];
-
- HRESULT hr;
-
- //default setting for a dynamic vertex buffer
- D3DPOOL pool = D3DPOOL_DEFAULT;
- DWORD usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC;
- DWORD fvf = WATER_MESH_FVF;
-
- if (doStatic)
- { //change settings for a static vertex buffer
- pool = D3DPOOL_MANAGED;
- usage = D3DUSAGE_WRITEONLY;
- fvf=0;// DX8 Docs confusing on this. Say no FVF for vertex shaders. Else DX8_FVF_XYZDUV1;
- m_numVertices=sizeX*sizeY;
- }
-
- if (m_vertexBufferD3D == NULL)
- { // Create vertex buffer
-
- if (FAILED(hr=m_pDev->CreateVertexBuffer
- (
- m_numVertices*vertexSize,
- usage,
- fvf,
- pool,
- &m_vertexBufferD3D
- )))
- return hr;
- }
-
- m_vertexBufferD3DOffset=0;
-
- if (!doStatic)
- return S_OK; //only create the buffer, other code will fill it.
-
- // load results into buffer
- if (FAILED(hr=m_vertexBufferD3D->Lock
- (
- 0,
- m_numVertices*sizeof(SEA_PATCH_VERTEX),
- (BYTE**)&pVertices,
- 0//D3DLOCK_DISCARD
- )))
- return hr;
-
- Int x,z;
- for (z=0; zx=(float)x;
- pVertices->y=m_level;
- pVertices->z=(float)z;
-
- pVertices->tu=(float)x*PATCH_UV_SCALE;
- pVertices->tv=(float)z*PATCH_UV_SCALE;
- pVertices->c=setting->transparentWaterDiffuse; //vertex alpha/color
- pVertices++;
- }
- }
-
- if (FAILED(hr=m_vertexBufferD3D->Unlock())) return hr;
-
- return S_OK;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Create and fill a D3D index buffer with water surface strip indices */
-//-------------------------------------------------------------------------------------------------
-HRESULT WaterRenderObjClass::generateIndexBuffer(Int sizeX, Int sizeY)
-{
- HRESULT hr;
-
- //Will need SizeY-1 strips, each of length SizeX*2 (2 indices per strip segment).
- //Will also need 2 extra indices to connect each strip to next one (except last strip)
- //Total index buffer size = (SizeY-1)*(SizeX*2+2) - 2 (drop the extra 2 indices from last strip)
-
- m_numIndices=(sizeY-1)*(sizeX*2+2) - 2;
-
- //old way
-
- // Create index buffer
- WORD* pIndices;
-
- if (FAILED(hr=m_pDev->CreateIndexBuffer
- (
- (m_numIndices+2)*sizeof(WORD),
- D3DUSAGE_WRITEONLY,
- D3DFMT_INDEX16,
- D3DPOOL_MANAGED,
- &m_indexBufferD3D
- )))
- return hr;
-
- if (FAILED(hr=m_indexBufferD3D->Lock
- (
- 0,
- m_numIndices*sizeof(WORD),
- (BYTE**)&pIndices,
- 0
- )))
- return hr;
-
- Int i,j,k;
-
- for (i=0,j=0,k=0; i0; x-=step)
- {
- *pIndices++=(WORD)((z-step)*size+(x-step));
- *pIndices++=(WORD)((z-0)*size+(x-step));
- }
- // insert additional degenerate to start next row
- *pIndices++=pIndices[-1];
- *pIndices++=pIndices[-1];
- }
-
- s_toggle=!s_toggle;
- }
-*/
- if (FAILED(hr=m_indexBufferD3D->Unlock())) return hr;
-
- return S_OK;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Releases all w3d assets, to prepare for Reset device call. */
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::ReleaseResources(void)
-{
-
- REF_PTR_RELEASE(m_indexBuffer);
-
- REF_PTR_RELEASE(m_pReflectionTexture);
- SAFE_RELEASE(m_vertexBufferD3D);
- SAFE_RELEASE(m_indexBufferD3D);
-
- if (m_waterTrackSystem)
- m_waterTrackSystem->ReleaseResources();
-
- if (m_dwWavePixelShader)
- m_pDev->DeletePixelShader(m_dwWavePixelShader);
-
- if (m_dwWaveVertexShader)
- m_pDev->DeleteVertexShader(m_dwWaveVertexShader);
-
- if (m_waterPixelShader)
- m_pDev->DeletePixelShader(m_waterPixelShader);
-
- if (m_trapezoidWaterPixelShader)
- m_pDev->DeletePixelShader(m_trapezoidWaterPixelShader);
-
- if (m_riverWaterPixelShader)
- m_pDev->DeletePixelShader(m_riverWaterPixelShader);
-
- m_dwWavePixelShader=0;
- m_dwWaveVertexShader=0;
- m_waterPixelShader = 0;
- m_trapezoidWaterPixelShader=0;
- m_riverWaterPixelShader=0;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** (Re)allocates all W3D assets after a reset.. */
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::ReAcquireResources(void)
-{
- HRESULT hr;
-
- m_indexBuffer=NEW_REF(DX8IndexBufferClass,(6));
- // Fill up the IB
- {
- DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexBuffer);
- UnsignedShort *ib=lockIdxBuffer.Get_Index_Array();
- //quad of 2 triangles:
- // 3-----2
- // | /|
- // | / |
- // |/ |
- // 0-----1
- ib[0]=3;
- ib[1]=0;
- ib[2]=2;
- ib[3]=2;
- ib[4]=0;
- ib[5]=1;
- }
-
- m_pDev=DX8Wrapper::_Get_D3D_Device8();
-
- //We're using the same grid for either 3D Water Mesh or Pixel/Vertex shader. Just
- //allocate the right size depending on usage
- if (m_meshData)
- {
- //Create new grid data
- if (FAILED(generateIndexBuffer(m_gridCellsX+1,m_gridCellsY+1)))
- return;
- if (FAILED(generateVertexBuffer(m_gridCellsX+1,m_gridCellsY+1,sizeof(MaterMeshVertexFormat),false)))
- return;
- }
- else
- if (m_waterType == WATER_TYPE_2_PVSHADER)
- { //pixel/vertex shader based water assets.
- if (FAILED(hr=generateIndexBuffer(PATCH_SIZE,PATCH_SIZE)))
- return;
-
- if (FAILED(hr=generateVertexBuffer(PATCH_SIZE,PATCH_SIZE,sizeof(SEA_PATCH_VERTEX),true)))
- return;
-
- //shader decleration
- DWORD Declaration[]=
- {
- (D3DVSD_STREAM(0)),
- (D3DVSD_REG(0, D3DVSDT_FLOAT3)), // Position
- (D3DVSD_REG(1, D3DVSDT_D3DCOLOR)), // Diffuse
- (D3DVSD_REG(2, D3DVSDT_FLOAT2)), // Bump map texture
- (D3DVSD_END())
- };
-
- hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\wave.pso", &Declaration[0], 0, false, &m_dwWavePixelShader);
- if (FAILED(hr))
- return;
-
- hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\wave.vso", &Declaration[0], 0, true, &m_dwWaveVertexShader);
- if (FAILED(hr))
- return;
-
- // Create reflection texture
- m_pReflectionTexture = DX8Wrapper::Create_Render_Target (SEA_REFLECTION_SIZE, SEA_REFLECTION_SIZE);
- }
-
- if (m_waterTrackSystem)
- m_waterTrackSystem->ReAcquireResources();
-
- if (W3DShaderManager::getChipset() >= DC_GENERIC_PIXEL_SHADER_1_1)
- {
- ID3DXBuffer *compiledShader;
- const char *shader =
- "ps.1.1\n \
- tex t0 \n\
- tex t1 \n\
- tex t2 \n\
- tex t3\n\
- mul r0,v0,t0 ; blend vertex color into t0. \n\
- mul r1, t1, t2 ; mul\n\
- add r0.rgb, r0, t3\n\
- +mul r0.a, r0, t3\n\
- add r0.rgb, r0, r1\n";
- hr = D3DXAssembleShader( shader, strlen(shader), 0, NULL, &compiledShader, NULL);
- if (hr==0) {
- hr = DX8Wrapper::_Get_D3D_Device8()->CreatePixelShader((DWORD*)compiledShader->GetBufferPointer(), &m_riverWaterPixelShader);
- compiledShader->Release();
- }
- shader =
- "ps.1.1\n \
- tex t0 \n\
- tex t1 \n\
- texbem t2, t1 ; use t1 as env map adjustment on t2.\n\
- mul r0,v0,t0 ; blend vertex color into t0. \n\
- mul r1.rgb,t2,c0 ; reduce t2 (environment mapped reflection) by constant\n\
- add r0.rgb, r0, r1";
- hr = D3DXAssembleShader( shader, strlen(shader), 0, NULL, &compiledShader, NULL);
- if (hr==0) {
- hr = DX8Wrapper::_Get_D3D_Device8()->CreatePixelShader((DWORD*)compiledShader->GetBufferPointer(), &m_waterPixelShader);
- compiledShader->Release();
- }
- shader =
- "ps.1.1\n \
- tex t0 ;get water texture\n\
- tex t1 ;get white highlights on black background\n\
- tex t2 ;get white highlights with more tiling\n\
- tex t3 ; get black shroud \n\
- mul r0,v0,t0 ; blend vertex color and alpha into base texture. \n\
- mad r0.rgb, t1, t2, r0 ; blend sparkles and noise \n\
- mul r0.rgb, r0, t3 ; blend in black shroud \n\
- ;\n";
- hr = D3DXAssembleShader( shader, strlen(shader), 0, NULL, &compiledShader, NULL);
- if (hr==0) {
- hr = DX8Wrapper::_Get_D3D_Device8()->CreatePixelShader((DWORD*)compiledShader->GetBufferPointer(), &m_trapezoidWaterPixelShader);
- compiledShader->Release();
- }
- }
-
-}
-
-void WaterRenderObjClass::load(void)
-{
- if (m_waterTrackSystem)
- m_waterTrackSystem->loadTracks();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initializes water with dimensions and parent scene.
- * During rendering, we will render a water surface of given dimensions
- * and reflect the parent scene in its surface. For now, waters are
- * forced to be rectangles. */
-//-------------------------------------------------------------------------------------------------
-Int WaterRenderObjClass::init(Real waterLevel, Real dx, Real dy, SceneClass *parentScene, WaterType type)
-{
-
- m_fBumpFrame=0;
- m_fBumpScale=SEA_BUMP_SCALE;
-
- m_dx=dx;
- m_dy=dy;
- m_level=waterLevel;
-
- m_LastUpdateTime=timeGetTime();
- m_uScrollPerMs=0.001f;
- m_vScrollPerMs=0.001f;
- m_uOffset=0;
- m_vOffset=0;
-
- m_parentScene=parentScene;
- m_waterType = type;
-
- /// Hack for now
- //m_waterType = WATER_TYPE_0_TRANSLUCENT;
-
- ///@todo: calculate a real normal/distance for arbitrary planes.
- m_planeNormal=Vector3(0,0,1); //water plane normal
- m_planeDistance=m_level; //water plane distance(always at zero for now)
-
- m_meshLight=NEW_REF(LightClass,(LightClass::DIRECTIONAL));
- m_meshLight->Set_Ambient(Vector3(0.1f,0.1f,0.1f));
- m_meshLight->Set_Diffuse(Vector3(1.0f,1.0f,1.0f));
- m_meshLight->Set_Specular(Vector3(1.0f,1.0f,1.0f));
- m_meshLight->Set_Position(Vector3(1000,1000,1000));
- //testLight->Set_Spot_Direction(Vector3(TheGlobalData->m_terrainLightX,TheGlobalData->m_terrainLightY,TheGlobalData->m_terrainLightZ));
- m_meshLight->Set_Spot_Direction(Vector3(-0.57f,-0.57f,-0.57f));
-
- //Setup material for 3D Mesh water.
- m_meshVertexMaterialClass=NEW_REF(VertexMaterialClass,());
- m_meshVertexMaterialClass->Set_Shininess(20.0);
- m_meshVertexMaterialClass->Set_Ambient(1.0f,1.0f,1.0f);
- m_meshVertexMaterialClass->Set_Diffuse(1.0f,1.0f,1.0f);
- m_meshVertexMaterialClass->Set_Specular(0.5,0.5,0.5);
- m_meshVertexMaterialClass->Set_Opacity(WATER_MESH_OPACITY);
- m_meshVertexMaterialClass->Set_Lighting(true);
-
- //
- // assign the data from the WaterSettings[] global to the data for this
- // render object (we at present only have one water plane)
- //
- loadSetting( &m_settings[ TIME_OF_DAY_MORNING ], TIME_OF_DAY_MORNING );
- loadSetting( &m_settings[ TIME_OF_DAY_AFTERNOON ], TIME_OF_DAY_AFTERNOON );
- loadSetting( &m_settings[ TIME_OF_DAY_EVENING ], TIME_OF_DAY_EVENING );
- loadSetting( &m_settings[ TIME_OF_DAY_NIGHT ], TIME_OF_DAY_NIGHT );
-
- Set_Sort_Level(2); //force water to be drawn after all other non translucent objects in scene.
- Set_Force_Visible(TRUE); //water is always visible since it's a composite object made of multiple planes all over the map.
-
- ReAcquireResources();
-#if 0 //MD does not support the old bump-mapped water at all so no point loading textures. -MW 8-11-03
- if (type == WATER_TYPE_2_PVSHADER || (W3DShaderManager::getChipset() >= DC_GENERIC_PIXEL_SHADER_1_1))
- { //geforce3 specific water requires some extra D3D assets
- m_pDev=DX8Wrapper::_Get_D3D_Device8();
- //save previous thumbnail mode
- bool thumbnails_enabled = WW3D::Get_Thumbnail_Enabled();
- WW3D::Set_Thumbnail_Enabled(false);
-
- //load bump map textures off disk
- TextureClass *pBumpSource; //temporary textures in a format W3D understands
- TextureClass *pBumpSource2; //temporary textures in a format W3D understands
- Int i;
- i=NUM_BUMP_FRAMES;
- while (i--)
- {
- char bump_name[128];
-
- sprintf(bump_name,"caust%.2d.tga",i);
- pBumpSource=WW3DAssetManager::Get_Instance()->Get_Texture(bump_name);
- sprintf(bump_name,"caustS%.2d.tga",i);
- pBumpSource2=WW3DAssetManager::Get_Instance()->Get_Texture(bump_name);
- initBumpMap(m_pBumpTexture+i, pBumpSource);
- initBumpMap(m_pBumpTexture2+i, pBumpSource2);
- WW3DAssetManager::Get_Instance()->Release_Texture(pBumpSource);
- WW3DAssetManager::Get_Instance()->Release_Texture(pBumpSource2);
- REF_PTR_RELEASE(pBumpSource);
- REF_PTR_RELEASE(pBumpSource2);
- }
- //restore previous thumpnail mode
- WW3D::Set_Thumbnail_Enabled(thumbnails_enabled);
- }
-#endif
-
- //Setup material for regular water
- m_vertexMaterialClass=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
-
-
-
- m_shaderClass = zFillAlphaShader;//ShaderClass::_PresetAlphaShader;ShaderClass::_PresetOpaqueShader;//detailOpaqueShader;
- m_shaderClass.Set_Cull_Mode(ShaderClass::CULL_MODE_DISABLE); //water should be visible from both sides
-
- //Assets used for all types of water
- m_alphaClippingTexture=WW3DAssetManager::Get_Instance()->Get_Texture(SKYBODY_TEXTURE);
-
-#ifdef CLIP_GEOMETRY_TO_PLANE
- m_alphaClippingTexture=WW3DAssetManager::Get_Instance()->Get_Texture("alphaclip.tga");
-#endif
-
- m_skyBox = ((W3DAssetManager*)W3DAssetManager::Get_Instance())->Create_Render_Obj( "new_skybox", TheGlobalData->m_skyBoxScale, 0);
-
- //Enable clamping on all textures used by the skybox (to reduce corner seams).
- if (m_skyBox && m_skyBox->Class_ID() == RenderObjClass::CLASSID_MESH)
- {
- MeshClass *mesh=(MeshClass*) m_skyBox;
- MaterialInfoClass *material = mesh->Get_Material_Info();
-
- for (Int i=0; iTexture_Count(); i++)
- {
- if (material->Peek_Texture(i))
- {
- material->Peek_Texture(i)->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- material->Peek_Texture(i)->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- }
- }
-
- REF_PTR_RELEASE(material);
- }
-
- m_riverTexture=WW3DAssetManager::Get_Instance()->Get_Texture(TheWaterTransparency->m_standingWaterTexture.str());
-
- //For some reason setting a NULL texture does not result in 0xffffffff for pixel shaders so using explicit "white" texture.
- m_whiteTexture=MSGNEW("TextureClass") TextureClass(1,1,WW3D_FORMAT_A4R4G4B4,MIP_LEVELS_1);
- SurfaceClass *surface=m_whiteTexture->Get_Surface_Level();
- surface->DrawPixel(0,0,0xffffffff);
- REF_PTR_RELEASE(surface);
-
- m_waterNoiseTexture=WW3DAssetManager::Get_Instance()->Get_Texture("Noise0000.tga");
- m_riverAlphaEdge=WW3DAssetManager::Get_Instance()->Get_Texture("TWAlphaEdge.tga");
- m_waterSparklesTexture=WW3DAssetManager::Get_Instance()->Get_Texture("WaterSurfaceBubbles.tga");
-#ifdef DRAW_WATER_WAKES
- m_waterTrackSystem = NEW WaterTracksRenderSystem;
- m_waterTrackSystem->init();
-#endif
-
- return 0;
-}
-
-void WaterRenderObjClass::updateMapOverrides(void)
-{
- if (m_riverTexture && TheWaterTransparency->m_standingWaterTexture.compareNoCase(m_riverTexture->Get_Texture_Name()) != 0)
- {
- REF_PTR_RELEASE(m_riverTexture);
- m_riverTexture = WW3DAssetManager::Get_Instance()->Get_Texture(TheWaterTransparency->m_standingWaterTexture.str());
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::reset( void )
-{
-
- // for vertex animated water mesh reset the values
- if( m_meshData)
- {
- Int i, j;
- WaterMeshData *pData;
- Int mx = m_gridCellsX + 1;
- Int my = m_gridCellsY + 1;
-
- // go through each mesh point and adjust the height according to the velocity
- for( j = 0, pData = m_meshData; j < (my + 2); j++ )
- {
-
- for( i = 0; i < (mx + 2); i++ )
- {
-
- // areset grid values for this cell
- pData->velocity = 0.0f;
- pData->height = 0.0f;
- pData->preferredHeight = 0.0f;
- pData->status = WaterRenderObjClass::AT_REST;
-
- // on to the next one
- pData++;
-
- }
-
- }
-
- // mesh data is no longer in motion
- m_meshInMotion = FALSE;
-
- }
-
- if (m_waterTrackSystem)
- m_waterTrackSystem->reset();
-}
-
-void WaterRenderObjClass::enableWaterGrid(Bool state)
-{
- m_doWaterGrid = state;
-
- m_drawingRiver = false;
- m_disableRiver = false;
-
- if (state && m_meshData == NULL)
- { //water type has changed, must allocate necessary assets for new water.
- //contains the current deformed water surface z(height) values. With 1 vertex invisible border
- //around surface to speed up normal calculations.
- m_meshDataSize = (m_gridCellsX+1+2)*(m_gridCellsY+1+2);
- m_meshData=NEW WaterMeshData[ m_meshDataSize ];
- memset(m_meshData,0,sizeof(WaterMeshData)*(m_gridCellsX+1+2)*(m_gridCellsY+1+2));
- reset();
-
- //Release existing grid data
- SAFE_RELEASE(m_vertexBufferD3D);
- SAFE_RELEASE(m_indexBufferD3D);
-
- //Create new grid data
- if (FAILED(generateIndexBuffer(m_gridCellsX+1,m_gridCellsY+1)))
- return;
- if (FAILED(generateVertexBuffer(m_gridCellsX+1,m_gridCellsY+1,sizeof(MaterMeshVertexFormat),false)))
- return;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-/** Update phase for water if we need it. */
-// ------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::update( void )
-{
- // TheSuperHackers @tweak The water movement time step is now decoupled from the render update.
- const Real timeScale = TheFramePacer->getActualLogicTimeScaleOverFpsRatio();
-
- {
- constexpr const Real MagicOffset = 0.0125f * 33 / 5000; ///< the work of top Munkees; do not question it
-
- m_riverVOrigin += 0.002f * timeScale;
- m_riverXOffset += (Real)(MagicOffset * timeScale);
- m_riverYOffset += (Real)(2 * MagicOffset * timeScale);
-
- // This moves offsets towards zero when smaller -1.0 or larger 1.0
- m_riverXOffset -= (Int)m_riverXOffset;
- m_riverYOffset -= (Int)m_riverYOffset;
-
- m_fBumpFrame += timeScale;
- if (m_fBumpFrame >= NUM_BUMP_FRAMES)
- m_fBumpFrame = 0.0f;
-
- // for vertex animated water we need to update the vector field
- if( m_doWaterGrid && m_meshInMotion == TRUE )
- {
- const Real PREFERRED_HEIGHT_FUDGE = 1.0f; ///< this is close enough to at rest
- const Real AT_REST_VELOCITY_FUDGE = 1.0f; ///< when we're close enough to at rest height and velocity we will stop
- const Real WATER_DAMPENING = 0.93f; ///< use with up force of 15.0
- Int i, j;
- Int mx = m_gridCellsX+1;
- Int my = m_gridCellsY+1;
- WaterMeshData *pData;
-
- //
- // we will mark the mesh as clean now ... if any of the fields are still in motion
- // they will continue to mark the mesh as dirty so processing continues next frame
- //
- m_meshInMotion = FALSE;
-
- // go through each mesh point and adjust the height according to the velocity
- for( j = 0, pData = m_meshData; j < (my + 2); j++ )
- {
-
- for( i = 0; i < (mx + 2); i++ )
- {
-
- // only pay attention to mesh points that are in motion
- if( BitIsSet( pData->status, WaterRenderObjClass::IN_MOTION ) )
- {
-
- // DAMPENING to slow the changes down
- pData->velocity *= WATER_DAMPENING;
-
- // if the height here is below our preferred height, we want to add upward force to counteract it
- if( pData->height < pData->preferredHeight )
- pData->velocity -= TheGlobalData->m_gravity * 3.0f;
- else
- pData->velocity += TheGlobalData->m_gravity * 3.0f;
-
- // adjust the height at this grid location according to the current velocity
- pData->height = pData->height + pData->velocity;
-
- //
- // if we are close enough to our preferred height and our velocity is small enough
- // this will be our resting location
- //
- if( fabs( pData->height - pData->preferredHeight ) < PREFERRED_HEIGHT_FUDGE &&
- fabs( pData->velocity ) < AT_REST_VELOCITY_FUDGE )
- {
-
- BitClear( pData->status, WaterRenderObjClass::IN_MOTION );
- pData->height = pData->preferredHeight;
- pData->velocity = 0.0f;
-
- }
- else
- {
-
- // there is still motion in the mesh, we need to process next frame
- m_meshInMotion = TRUE;
-
- }
-
- }
-
- // on to the next one
- pData++;
-
- }
-
- }
-
- }
-
- }
-
-}
-
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::replaceSkyboxTexture(const AsciiString& oldTexName, const AsciiString& newTextName)
-{
- W3DAssetManager* assetManager = ((W3DAssetManager*)W3DAssetManager::Get_Instance());
-
- assetManager->replacePrototypeTexture(m_skyBox, oldTexName.str(), newTextName.str());
-
- //Enable clamping on all textures used by the skybox (to reduce corner seams).
- if (m_skyBox && m_skyBox->Class_ID() == RenderObjClass::CLASSID_MESH)
- {
- MeshClass *mesh=(MeshClass*) m_skyBox;
- MaterialInfoClass *material = mesh->Get_Material_Info();
-
- for (Int i=0; iTexture_Count(); i++)
- {
- if (material->Peek_Texture(i))
- {
- material->Peek_Texture(i)->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- material->Peek_Texture(i)->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- }
- }
- }
-
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Adjusts various water/sky rendering settings that depend on time of day. */
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::setTimeOfDay(TimeOfDay tod)
-{
- m_tod=tod;
- if (m_waterType == WATER_TYPE_2_PVSHADER)
- generateVertexBuffer(PATCH_SIZE,PATCH_SIZE,sizeof(SEA_PATCH_VERTEX),true); //update the water mesh with new lighting/alpha
-}
-
-//-------------------------------------------------------------------------------------------------
-/**Copies GDF settings dealing with a particular time of day into our own
- * structures. Also allocates any required W3D assets (textures). */
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::loadSetting( Setting *setting, TimeOfDay timeOfDay )
-{
- SurfaceClass::SurfaceDescription surfaceDesc;
-
- // sanity
- DEBUG_ASSERTCRASH( setting, ("WaterRenderObjClass::loadSetting, NULL setting") );
-
- // textures
- setting->skyTexture = WW3DAssetManager::Get_Instance()->Get_Texture( WaterSettings[ timeOfDay ].m_skyTextureFile.str() );
- setting->waterTexture = WW3DAssetManager::Get_Instance()->Get_Texture( WaterSettings[ timeOfDay ].m_waterTextureFile.str() );
-
- // texelss per unit
- setting->skyTexelsPerUnit = WaterSettings[ timeOfDay ].m_skyTexelsPerUnit;
- setting->waterTexture->Get_Level_Description( surfaceDesc, 0 );
- setting->skyTexelsPerUnit /= (Real)surfaceDesc.Width;
-
- // water repeat
- setting->waterRepeatCount = WaterSettings[ timeOfDay ].m_waterRepeatCount;
-
- // U and V scroll per ms
- setting->uScrollPerMs = WaterSettings[ timeOfDay ].m_uScrollPerMs;
- setting->vScrollPerMs = WaterSettings[ timeOfDay ].m_vScrollPerMs;
-
- //
- // vertex colors
- //
- // bottom left
- setting->vertex00Diffuse = (WaterSettings[ timeOfDay ].m_vertex00Diffuse.red << 16) |
- (WaterSettings[ timeOfDay ].m_vertex00Diffuse.green << 8) |
- WaterSettings[ timeOfDay ].m_vertex00Diffuse.blue;
- // top left
- setting->vertex01Diffuse = (WaterSettings[ timeOfDay ].m_vertex01Diffuse.red << 16) |
- (WaterSettings[ timeOfDay ].m_vertex01Diffuse.green << 8) |
- WaterSettings[ timeOfDay ].m_vertex01Diffuse.blue;
- // bottom right
- setting->vertex10Diffuse = (WaterSettings[ timeOfDay ].m_vertex10Diffuse.red << 16) |
- (WaterSettings[ timeOfDay ].m_vertex10Diffuse.green << 8) |
- WaterSettings[ timeOfDay ].m_vertex10Diffuse.blue;
- // top right
- setting->vertex11Diffuse = (WaterSettings[ timeOfDay ].m_vertex11Diffuse.red << 16) |
- (WaterSettings[ timeOfDay ].m_vertex11Diffuse.green << 8) |
- WaterSettings[ timeOfDay ].m_vertex11Diffuse.blue;
-
- // diffuse water color
- setting->waterDiffuse = (WaterSettings[ timeOfDay ].m_waterDiffuseColor.alpha << 24) |
- (WaterSettings[ timeOfDay ].m_waterDiffuseColor.red << 16) |
- (WaterSettings[ timeOfDay ].m_waterDiffuseColor.green << 8) |
- WaterSettings[ timeOfDay ].m_waterDiffuseColor.blue;
-
- // transparent water color
- setting->transparentWaterDiffuse = (WaterSettings[ timeOfDay ].m_transparentWaterDiffuse.alpha << 24) |
- (WaterSettings[ timeOfDay ].m_transparentWaterDiffuse.red << 16) |
- (WaterSettings[ timeOfDay ].m_transparentWaterDiffuse.green << 8) |
- WaterSettings[ timeOfDay ].m_transparentWaterDiffuse.blue;
-
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Our water may use effects that require run-time rendered textures. These
- * textures need to be updated before we start rendering to the main screen
- * render target because D3D doesn't multiple render targets. */
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::updateRenderTargetTextures(CameraClass *cam)
-{
- if (m_waterType == WATER_TYPE_2_PVSHADER && getClippedWaterPlane(cam, NULL) &&
- TheTerrainRenderObject && TheTerrainRenderObject->getMap())
- renderMirror(cam); //generate texture containing reflected scene
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Renders the reflected scene into an offscreen texture. */
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::renderMirror(CameraClass *cam)
-{
-#ifdef EXTENDED_STATS
- if (DX8Wrapper::stats.m_disableWater) {
- return;
- }
-#endif
- Matrix3D OldCameraMatrix=cam->Get_Transform();
- Matrix4x4 FullMatrix4(cam->Get_Transform()); //copy 3x4 matrix into a 4x4
- Vector3 WaterNormal(0,0,1); //normal of plane used for reflection
- Vector4 WaterPlane(WaterNormal.X,WaterNormal.Y,WaterNormal.Z,m_level);
- Vector3 rRight,rUp,rN,rPos; //orientation and translation vectors of camera
-
- Matrix4x4 FullMatrix(FullMatrix4.Transpose()); //swap rows/columns
-
- //reflect camera right vector
- Real axis_distance=Vector3::Dot_Product((Vector3&)FullMatrix[0],WaterNormal);
- rRight = (Vector3&)FullMatrix[0] - (2.0f*axis_distance*WaterNormal);
-
- //reflect camera up vector
- axis_distance=Vector3::Dot_Product((Vector3&)FullMatrix[1],WaterNormal);
- rUp = (Vector3&)FullMatrix[1] - (2.0f*axis_distance*WaterNormal);
-
- //reflect camera n vector
- axis_distance=Vector3::Dot_Product((Vector3&)FullMatrix[2],WaterNormal);
- rN = (Vector3&)FullMatrix[2] - (2.0f*axis_distance*WaterNormal);
-
- //reflect camera position
- axis_distance=Vector3::Dot_Product((Vector3&)FullMatrix[3],WaterNormal); //distance cam to origin
- axis_distance -= WaterPlane.W; // subtract mirror plane distance to get distance camera to plane
- rPos = (Vector3&)FullMatrix[3] - (2.0f*axis_distance*WaterNormal);
-
- //generate a new camera matrix from reflected vectors
- Matrix3D reflectedTransform(rRight,rUp,rN,rPos);
-
-
- DX8Wrapper::Set_Render_Target(m_pReflectionTexture);
-
- // Clear the backbuffer
- WW3D::Begin_Render(false,true,Vector3(0.0f,0.0f,0.0f)); //clearing only z-buffer since background always filled with clouds
-
- cam->Set_Transform( reflectedTransform );
-
- //Force reflected image to be drawn into full texture size - not a viewport inside texture.
- Vector2 vMin,vMax,vOldMax,vOldMin;
- cam->Get_Viewport(vOldMin,vOldMax);
- vMax.X=vMax.Y=1.0f;
- vMin.X=vMin.Y=0.0f;
- cam->Set_Viewport(vMin,vMax);
-
- cam->Apply(); //force an update of all the camera dependent parameters like frustum clip planes
-
- //flip the winding order of polygons to draw the reflected back sides.
- ShaderClass::Invert_Backface_Culling(true);
-
- // Render the scene
- renderSky();
- if (m_tod == TIME_OF_DAY_NIGHT)
- renderSkyBody(&reflectedTransform);
-
- WW3D::Render(m_parentScene,cam);
-
- cam->Set_Transform(OldCameraMatrix); //restore original non-reflected matrix
- cam->Set_Viewport(vOldMin,vOldMax);
-
- cam->Apply(); //force an update of all the camera dependent parameters like frustum clip planes
-
- ShaderClass::Invert_Backface_Culling(false);
-
- WW3D::End_Render(false);
-
- // Change the rendertarget back to the main backbuffer
- DX8Wrapper::Set_Render_Target((IDirect3DSurface8 *)NULL);
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Renders (draws) the water.
- * Algorithm:
- * Draw reflected scene.
- * Draw reflected sky layer(s) and bodies.
- * Clear Zbuffer
- * Fill Zbuffer by drawing water surface (allows proper sorting into regular scene).
- * Draw non-reflected scene (done in regular app render loop).
- *
- * This algorithm doesn't apply to translucent water, which is rendered into a
- * texture and rendered at end of scene. */
-//-------------------------------------------------------------------------------------------------
-//DECLARE_PERF_TIMER(Water)
-void WaterRenderObjClass::Render(RenderInfoClass & rinfo)
-{
- //USE_PERF_TIMER(Water)
- if (TheTerrainRenderObject && !TheTerrainRenderObject->getMap())
- return; //no map has been loaded yet.
-
- if (((RTS3DScene *)rinfo.Camera.Get_User_Data())->getCustomPassMode() == SCENE_PASS_ALPHA_MASK ||
- ((SceneClass *)rinfo.Camera.Get_User_Data())->Get_Extra_Pass_Polygon_Mode() == SceneClass::EXTRA_PASS_CLEAR_LINE)
- return; //water is not drawn in wireframe or custom scene passes
-
-#ifdef EXTENDED_STATS
- if (DX8Wrapper::stats.m_disableWater) {
- return;
- }
-#endif
- if (ShaderClass::Is_Backface_Culling_Inverted())
- return; //the water object will not reflect in itself, so don't do anything if rendering a mirror.
-
- //this water type needs to rendered after the rest of scene, so buffer it up for later
-
- // If static sort lists are enabled and this mesh has a sort level, put it on the list instead
- // of rendering it.
- unsigned int sort_level = (unsigned int)Get_Sort_Level();
-
- if (WW3D::Are_Static_Sort_Lists_Enabled() && sort_level != SORT_LEVEL_NONE)
- {
- WW3D::Add_To_Static_Sort_List(this, sort_level);
- return;
- }
-
- switch(m_waterType)
- {
- case WATER_TYPE_0_TRANSLUCENT:
- case WATER_TYPE_3_GRIDMESH:
- //Draw the water surface as a bunch of alpha blended tiles covering areas where water is visible
- renderWater();
- if (!m_drawingRiver || m_disableRiver) {
- renderWaterMesh(); //Draw water surface as 3D deforming mesh if it's enabled on this map.
- }
- break;
-
- case WATER_TYPE_2_PVSHADER:
- //Pixel/Vertex Shader based water which uses an off-screen rendered reflection texture
- drawSea(rinfo); //draw water surface
- break;
-
- case WATER_TYPE_1_FB_REFLECTION:
- {
- //Normal frame buffer reflection water type. Non translucent. Legacy code we're not using anymore.
- Matrix3D OldCameraMatrix=rinfo.Camera.Get_Transform();
- Matrix4x4 FullMatrix4(rinfo.Camera.Get_Transform()); //copy 3x4 matrix into a 4x4
- Vector3 WaterNormal(0,0,1); //normal of plane used for reflection
- Vector4 WaterPlane(WaterNormal.X,WaterNormal.Y,WaterNormal.Z,m_level); //assume distance to origin 0
- Vector3 rRight,rUp,rN,rPos; //orientation and translation vectors of camera
-
- Matrix4x4 FullMatrix(FullMatrix4.Transpose()); //swap rows/columns
-
- //reflect camera right vector
- Real axis_distance=Vector3::Dot_Product((Vector3&)FullMatrix[0],WaterNormal);
- rRight = (Vector3&)FullMatrix[0] - (2.0f*axis_distance*WaterNormal);
-
- //reflect camera up vector
- axis_distance=Vector3::Dot_Product((Vector3&)FullMatrix[1],WaterNormal);
- rUp = (Vector3&)FullMatrix[1] - (2.0f*axis_distance*WaterNormal);
-
- //reflect camera n vector
- axis_distance=Vector3::Dot_Product((Vector3&)FullMatrix[2],WaterNormal);
- rN = (Vector3&)FullMatrix[2] - (2.0f*axis_distance*WaterNormal);
-
- //reflect camera position
- axis_distance=Vector3::Dot_Product((Vector3&)FullMatrix[3],WaterNormal); //distance cam to origin
- axis_distance -= WaterPlane.W; // subtract mirror plane distance to get distance camera to plane
- rPos = (Vector3&)FullMatrix[3] - (2.0f*axis_distance*WaterNormal);
-
- //generate a new camera matrix from reflected vectors
- Matrix3D reflectedTransform(rRight,rUp,rN,rPos);
-
- //flip the winding order of polygons to draw the reflected back sides.
- ShaderClass::Invert_Backface_Culling(true);
-
- #ifdef CLIP_GEOMETRY_TO_PLANE
- // Set a clip plane, so that only objects above the water are reflected
- WaterPlane.W *= -1.0f; //flip sign of plane distance for D3D use.
-
- // DX8Wrapper::Set_DX8_Clip_Plane( 0, &WaterPlane.X );
- // DX8Wrapper::Set_DX8_Render_State(D3DRS_CLIPPLANEENABLE, D3DCLIPPLANE0 ); //turn on first clip plane
-
- // Alternate Clipping Method using alpha testing hack!
- /**************************************************************************************/
-
- D3DXMATRIX inv;
- D3DXMATRIX clipMatrix;
- Real det;
- Matrix4x4 curView;
-
- //get current view matrix
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
-
- //get inverse of view matrix(= view to world matrix)
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
-
- //create clipping matrix by inserting our plane equation into the 1st column
- D3DXMatrixIdentity(&clipMatrix);
- clipMatrix(0,0)=WaterNormal.X;
- clipMatrix(1,0)=WaterNormal.Y;
- clipMatrix(2,0)=WaterNormal.Z;
- clipMatrix(3,0)=WaterPlane.W+0.5f;
- inv *=clipMatrix;
-
- // Change texture wrapping mode to 'clamp' for texture stage 1
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
-
- // Use CameraSpace vertices as input to matrix and use texture wrap mode from stage 1
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION|1);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
-
- // Set texture generation matrix for stage 1
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, *((Matrix4*)&inv));
-
- // Disable bilinear filtering
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
-
- // Pass stage 0 texture data untouched(by modulating with white)
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); //stage 1 texture
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); //previous stage texture
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); //module with white => does nothing
-
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); //stage 1 texture
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT ); //previous stage texture
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); //modulate with clipping texture
-
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHAREF,0x00);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHAFUNC,D3DCMP_NOTEQUAL); //pass pixels who's alpha is not zero
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHATESTENABLE, true); //test pixels if transparent(clipped) before rendering.
-
- // Set clipping texture
- m_alphaClippingTexture->Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- m_alphaClippingTexture->Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- m_alphaClippingTexture->Set_Min_Filter(TextureFilterClass::FILTER_TYPE_NONE);
- m_alphaClippingTexture->Set_Mag_Filter(TextureFilterClass::FILTER_TYPE_NONE);
- m_alphaClippingTexture->Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_NONE);
-
- DX8Wrapper::Set_Texture(0,m_alphaClippingTexture);
-
- //TODO: Will have to make sure that the shader system is not resetting my stage 1 setup
- //while rendering the scene
-
- /*************************************************************************************/
- #endif
-
- #if 0 // No longer do simple rendering.
- if (TheGlobalData->m_useWaterPlane)
- {
- //@todo : Would it be better to create a new camera or change the transform of the
- //existing one?
- rinfo.Camera.Set_Transform( reflectedTransform );
- rinfo.Camera.Apply(); //force an update of all the camera dependent parameters like frustum clip planes
-
- if(m_useCloudLayer)
- {
- if (TheGlobalData && TheGlobalData->m_drawEntireTerrain)
- m_skyBox->Render(rinfo);
- else
- {
- renderSky();
- if (m_tod == TIME_OF_DAY_NIGHT)
- renderSkyBody(&reflectedTransform);
- }
- }
-
- WW3D::Render(m_parentScene,&rinfo.Camera);
-
- rinfo.Camera.Set_Transform(OldCameraMatrix); //restore original non-reflected matrix
- rinfo.Camera.Apply(); //force an update of all the camera dependent parameters like frustum clip planes
-
- //clear the z-buffer to remove changes made by objects inside mirror
- DX8Wrapper::Clear(false,true,Vector3(0.1f,0.1f,0.1f));
- }
- #endif
-
- #ifdef CLIP_GEOMETRY_TO_PLANE
- //restore default culling mode
- // DX8Wrapper::Set_DX8_Render_State(D3DRS_CLIPPLANEENABLE, 0 ); //turn off first clip plane
-
- //disable texture coordinate generation
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHATESTENABLE, false); //disable alpha testing
- #endif
-
- ShaderClass::Invert_Backface_Culling(false); //return culling back to normal
-
- ShaderClass::Invalidate(); //reset shading system so it forces full state set.
-
- renderWater();
- }
- break;
-
- default:
- break;
- }
-
- if (TheGlobalData && TheGlobalData->m_drawSkyBox)
- { //center skybox around camera
- Vector3 pos=rinfo.Camera.Get_Position();
- pos.Z = TheGlobalData->m_skyBoxPositionZ;
- m_skyBox->Set_Position(pos);
- m_skyBox->Render(rinfo);
- }
-
- //Clean up after any pixel shaders.
- //Force render state apply so that the "NULL" texture gets applied to D3D, thus releasing shroud reference count.
- DX8Wrapper::Apply_Render_State_Changes();
- DX8Wrapper::Invalidate_Cached_Render_States();
-
- if (m_waterTrackSystem)
- m_waterTrackSystem->flush(rinfo);
-
-// renderWaterMesh();
-// renderWaterWave();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Clips the water plane to the current camera frustum and returns a bounding
- * box enclosing the clipped plane. Returns false if water plane is not visible. */
-//-------------------------------------------------------------------------------------------------
-Bool WaterRenderObjClass::getClippedWaterPlane(CameraClass *cam, AABoxClass *box)
-{
- const FrustumClass & frustum = cam->Get_Frustum();
-
- ClipPolyClass ClippedPoly0;
- ClipPolyClass ClippedPoly1;
-
- ///@todo: generate proper sized polygon
- ClippedPoly0.Reset();
- ClippedPoly0.Add_Vertex(Vector3(0,0,m_level));
- ClippedPoly0.Add_Vertex(Vector3(0,m_dy,m_level));
- ClippedPoly0.Add_Vertex(Vector3(m_dx,m_dy,m_level));
- ClippedPoly0.Add_Vertex(Vector3(m_dx,0,m_level));
-
- //clip against all 6 frustum planes
- ClippedPoly0.Clip(frustum.Planes[0],ClippedPoly1);
- ClippedPoly1.Clip(frustum.Planes[1],ClippedPoly0);
- ClippedPoly0.Clip(frustum.Planes[2],ClippedPoly1);
- ClippedPoly1.Clip(frustum.Planes[3],ClippedPoly0);
- ClippedPoly0.Clip(frustum.Planes[4],ClippedPoly1);
- ClippedPoly1.Clip(frustum.Planes[5],ClippedPoly0);
-
- Int final_vcount = ClippedPoly0.Verts.Count();
-
- //make sure the polygon is visible
- if (final_vcount >= 3)
- {
- //find axis aligned bounding box around visible polygon
- if (box)
- box->Init(&(ClippedPoly0.Verts[0]),final_vcount);
- return TRUE;
- }
-
- return FALSE; //water plane is not visible
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Draws the water surface using a custom D3D vertex/pixel shader and a
- * reflection texture. Only tested to work on GeForce3. */
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::drawSea(RenderInfoClass & rinfo)
-{
- AABoxClass seaBox;
-
- if (!getClippedWaterPlane(&rinfo.Camera,&seaBox))
- return; //the sea is not visible
-
- D3DXMATRIX matProj, matView, matWW3D;
-
- //create a transform which will flip the y and z coordinates to fit our system
- memset(&matWW3D,0,sizeof(D3DMATRIX));
- matWW3D._11=1.0f;
- matWW3D._32=1.0f;
- matWW3D._23=1.0f;
- matWW3D._44=1.0f;
-
- Matrix3D tm(Transform);
-
- DX8Wrapper::Set_Transform(D3DTS_WORLD,tm); //position the water surface
- DX8Wrapper::Set_Texture(0,NULL); //we'll be setting our own textures, so reset W3D
- DX8Wrapper::Set_Texture(1,NULL); //we'll be setting our own textures, so reset W3D
-
-
- DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
-
- Vector3 camTran;
-
- rinfo.Camera.Get_Transform().Get_Translation(&camTran);
-
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, *(Matrix4x4*)&matView);
- DX8Wrapper::_Get_DX8_Transform(D3DTS_PROJECTION, *(Matrix4x4*)&matProj);
-
- //default setup from Kenny's demo
- m_pDev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- m_pDev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
- m_pDev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
- m_pDev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- m_pDev->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
-
- m_pDev->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- m_pDev->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
- m_pDev->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
- m_pDev->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- m_pDev->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
-
- m_pDev->SetTextureStageState( 2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- m_pDev->SetTextureStageState( 2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|2);
-
- m_pDev->SetTextureStageState( 3, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- m_pDev->SetTextureStageState( 3, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|3);
-
-// m_pDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
-// m_pDev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
-// m_pDev->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_POINT );
-
-// m_pDev->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTEXF_POINT );
-// m_pDev->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTEXF_POINT );
-// m_pDev->SetTextureStageState( 1, D3DTSS_MIPFILTER, D3DTEXF_NONE );
- //end of default setup
-
- m_pDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- m_pDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- m_pDev->SetRenderState( D3DRS_WRAP0, D3DWRAP_U | D3DWRAP_V);
-
- m_pDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- m_pDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
-
- m_pDev->SetTexture( 0, m_pBumpTexture[(Int)m_fBumpFrame]);
-#ifdef MIPMAP_BUMP_TEXTURE
- m_pDev->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_POINT );
- m_pDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
-#endif
- m_pDev->SetTextureStageState( 1, D3DTSS_BUMPENVMAT00, F2DW(m_fBumpScale) );
- m_pDev->SetTextureStageState( 1, D3DTSS_BUMPENVMAT01, F2DW(0.0f) );
- m_pDev->SetTextureStageState( 1, D3DTSS_BUMPENVMAT10, F2DW(0.0f) );
- m_pDev->SetTextureStageState( 1, D3DTSS_BUMPENVMAT11, F2DW(m_fBumpScale) );
- m_pDev->SetTextureStageState( 1, D3DTSS_BUMPENVLSCALE, F2DW(1.0f) );
- m_pDev->SetTextureStageState( 1, D3DTSS_BUMPENVLOFFSET, F2DW(0.0f) );
-
- m_pDev->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
- m_pDev->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
-
- m_pDev->SetRenderState(D3DRS_ZWRITEENABLE , FALSE);
-
- D3DXMATRIX mat;
- memset(&mat,0,sizeof(D3DXMATRIX));
-
- mat._11 = 0.5f; mat._12 = -0.5f; mat._13 = 0.5f; mat._14=0.5f;
- mat._21 = 0.5f; mat._22 = 0.5f; mat._23 = 0.0f; mat._24=0.0f;
- mat._31 = 0.0f; mat._32 = 0.0f; mat._33 = 0.0f; mat._34=1.0f;
- mat._41 = 0.0f; mat._42 = 0.0f; mat._43 = 0.0f; mat._44=1.0f;
-
- m_pDev->SetVertexShaderConstant(CV_TEXPROJ_0, &mat, 4);
-
- // Setup constants
- m_pDev->SetVertexShaderConstant(CV_ZERO, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1);
- m_pDev->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1);
-
- m_pDev->SetVertexShader(m_dwWaveVertexShader);
- m_pDev->SetPixelShader(m_dwWavePixelShader);
-
-// Make reflection brighter to compensate for darker coloring on sea floor
-// m_pDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
-// m_pDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR );
-
- m_pDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
- m_pDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
-
- m_pDev->SetRenderState(D3DRS_ALPHABLENDENABLE , TRUE);
- m_pDev->SetTexture( 1, m_pReflectionTexture->Peek_D3D_Texture());
-
-// m_pDev->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);//LORENZEN
-
- Int patchX,patchY,startX,startY;
-
- D3DXMATRIX patchMatrix;
- memset(&patchMatrix,0,sizeof(D3DXMATRIX));
- patchMatrix._11=PATCH_SCALE;
- patchMatrix._22=1.0f;
- patchMatrix._33=PATCH_SCALE;
- patchMatrix._44=1.0f;
-
- m_pDev->SetStreamSource(0,m_vertexBufferD3D,sizeof(WaterRenderObjClass::SEA_PATCH_VERTEX));
- m_pDev->SetIndices(m_indexBufferD3D,0);
-
- for (startY=patchY=(seaBox.Center.Y-seaBox.Extent.Y)/(PATCH_WIDTH*PATCH_SCALE); (patchY*PATCH_WIDTH*PATCH_SCALE)<(seaBox.Center.Y+seaBox.Extent.Y); patchY++)
- {
- for (startX=patchX=(seaBox.Center.X-seaBox.Extent.X)/(PATCH_WIDTH*PATCH_SCALE); (patchX*PATCH_WIDTH*PATCH_SCALE)<(seaBox.Center.X+seaBox.Extent.X); patchX++)
- {
- D3DXMATRIX matWorldViewProj, matTemp, matTempWorld;
- patchMatrix._41=(float)(patchX*PATCH_WIDTH*PATCH_SCALE );
- patchMatrix._43=(float)(patchY*PATCH_WIDTH*PATCH_SCALE );
- //convert the default D3D coordinate system into ours
- D3DXMatrixMultiply(&matTempWorld, &patchMatrix, &matWW3D);
-
- D3DXMatrixMultiply(&matTemp, &matTempWorld, &matView);
- D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProj);
- //matrices must be transposed before loading into vertex shader registers
- D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
- m_pDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj, 4); //pass transform matrix into shader
-
- m_pDev->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,0,m_numVertices,0,m_numIndices);
- }
- }
-// m_pDev->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
- m_pDev->SetRenderState(D3DRS_ALPHABLENDENABLE , FALSE);
- m_pDev->SetTexture( 0, NULL); //release reference to bump texture
- m_pDev->SetTexture( 1, NULL); //release reference to reflection texture
- m_pDev->SetTexture( 2, NULL); //release reference to reflection texture
-
- m_pDev->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- m_pDev->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0);
- m_pDev->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- m_pDev->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1);
- m_pDev->SetRenderState(D3DRS_ZWRITEENABLE , TRUE);
-
- m_pDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- m_pDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
-
- m_pDev->SetRenderState( D3DRS_WRAP0, 0); //turn off texture wrapping
-
- m_pDev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_DISABLE );
- m_pDev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- m_pDev->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
- m_pDev->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
- m_pDev->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
- m_pDev->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
-
- //Restore old transforms
- DX8Wrapper::_Set_DX8_Transform(D3DTS_VIEW, *(Matrix4x4*)&matView);
- DX8Wrapper::_Set_DX8_Transform(D3DTS_PROJECTION, *(Matrix4x4*)&matProj);
-
- m_pDev->SetPixelShader(0); //turn off pixel shader
- m_pDev->SetVertexShader(DX8_FVF_XYZDUV1); //turn off custom vertex shader
-
- DX8Wrapper::Invalidate_Cached_Render_States();
-
- if (TheTerrainRenderObject->getShroud())
- {
- //do second pass to apply the shroud on water plane
- W3DShaderManager::setTexture(0,TheTerrainRenderObject->getShroud()->getShroudTexture());
- W3DShaderManager::setShader(W3DShaderManager::ST_SHROUD_TEXTURE, 0);
- m_pDev->SetStreamSource(0,m_vertexBufferD3D,sizeof(WaterRenderObjClass::SEA_PATCH_VERTEX));
- m_pDev->SetIndices(m_indexBufferD3D,0);
- for (startY=patchY=(seaBox.Center.Y-seaBox.Extent.Y)/(PATCH_WIDTH*PATCH_SCALE); (patchY*PATCH_WIDTH*PATCH_SCALE)<(seaBox.Center.Y+seaBox.Extent.Y); patchY++)
- {
- for (startX=patchX=(seaBox.Center.X-seaBox.Extent.X)/(PATCH_WIDTH*PATCH_SCALE); (patchX*PATCH_WIDTH*PATCH_SCALE)<(seaBox.Center.X+seaBox.Extent.X); patchX++)
- {
- D3DXMATRIX matTemp;
- patchMatrix._41=(float)(patchX*PATCH_WIDTH*PATCH_SCALE);
- patchMatrix._43=(float)(patchY*PATCH_WIDTH*PATCH_SCALE);
-
- D3DXMatrixMultiply(&matTemp, &patchMatrix, &matWW3D);
-
- DX8Wrapper::_Set_DX8_Transform(D3DTS_WORLD, *(Matrix4x4*)&matTemp);
-
- m_pDev->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,0,m_numVertices,0,m_numIndices);
- }
- }
- W3DShaderManager::resetShader(W3DShaderManager::ST_SHROUD_TEXTURE);
- }
-
-}
-
-
-#define FEATHER_LAYER_COUNT (5.0f)
-#define FEATHER_THICKNESS (4.0f)
-
-//-------------------------------------------------------------------------------------------------
-/** Renders (draws) the water surface.*/
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::renderWater(void)
-{
- for (PolygonTrigger *pTrig=PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext()) {
- if (pTrig->isWaterArea()) {
- if (pTrig->getNumPoints()>2) {
- if (pTrig->isRiver()) {
- drawRiverWater(pTrig);
- continue;
- }
- Int k;
- for (k=1; kgetNumPoints()-1; k=k+2) {
- ICoord3D pt3 = *pTrig->getPoint(0);
- ICoord3D pt2 = *pTrig->getPoint(k);
- ICoord3D pt1 = *pTrig->getPoint(k+1);
- ICoord3D pt0 = *pTrig->getPoint(k+1);
- if (k+2getNumPoints()) {
- pt0 = *pTrig->getPoint(k+2);
- }
- Vector3 points[4];
- points[0].Set(pt0.x, pt0.y, pt0.z);
- points[1].Set(pt1.x, pt1.y, pt1.z);
- points[2].Set(pt2.x, pt2.y, pt2.z);
- points[3].Set(pt3.x, pt3.y, pt3.z);
-
- if ( TheGlobalData->m_featherWater )
- {
- for (int r = 0; r < TheGlobalData->m_featherWater; ++r)
- {
- drawTrapezoidWater(points);
- points[0].Z += (FEATHER_THICKNESS/TheGlobalData->m_featherWater);
- }
- }
-
- else
- drawTrapezoidWater(points);
-
-
- }
- }
- }
- }
-
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Renders (draws) the sky plane. Will apply current time-of-day settings including
- * some simple UV scrolling animation. */
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::renderSky(void)
-{
- Int timeNow,timeDiff;
- Real fu,fv;
-
- Setting *setting=&m_settings[m_tod];
-
- timeNow=timeGetTime();
-
- timeDiff=timeNow-m_LastUpdateTime;
- m_LastUpdateTime=timeNow;
-
- m_uOffset += timeDiff * setting->uScrollPerMs * setting->skyTexelsPerUnit;
- m_vOffset += timeDiff * setting->vScrollPerMs * setting->skyTexelsPerUnit;
-
- //clamp uv coordinate into 0,1 range
- m_uOffset = m_uOffset - (Real)((Int) m_uOffset);
- m_vOffset = m_vOffset - (Real)((Int) m_vOffset);
-
- fu= m_uOffset + (SKYPLANE_SIZE * 2) * setting->skyTexelsPerUnit;
- fv= m_vOffset + (SKYPLANE_SIZE * 2) * setting->skyTexelsPerUnit;
-
-
- VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- DX8Wrapper::Set_Material(vmat);
- REF_PTR_RELEASE(vmat);
-
- ShaderClass m_shader2=ShaderClass::_PresetOpaqueShader;
- m_shader2.Set_Cull_Mode(ShaderClass::CULL_MODE_DISABLE);
- m_shader2.Set_Depth_Compare(ShaderClass::PASS_ALWAYS); //no need to check against z-buffer, sky always rendered first.
- m_shader2.Set_Depth_Mask(ShaderClass::DEPTH_WRITE_DISABLE); //sky is always behind everything so no need to update z-buffer
-
- DX8Wrapper::Set_Shader(m_shader2);
-
- DX8Wrapper::Set_Texture(0,setting->skyTexture);
-
- //draw an infinite sky plane
- DynamicVBAccessClass vb_access(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,4);
- {
- DynamicVBAccessClass::WriteLockClass lock(&vb_access);
- VertexFormatXYZNDUV2* verts=lock.Get_Formatted_Vertex_Array();
- if(verts)
- {
- verts[0].x=-SKYPLANE_SIZE;
- verts[0].y=SKYPLANE_SIZE;
- verts[0].z=SKYPLANE_HEIGHT;
- verts[0].u1=m_uOffset;
- verts[0].v1=fv;
- verts[0].diffuse=setting->vertex01Diffuse;
-
- verts[1].x=SKYPLANE_SIZE;
- verts[1].y=SKYPLANE_SIZE;
- verts[1].z=SKYPLANE_HEIGHT;
- verts[1].u1=fu;
- verts[1].v1=fv;
- verts[1].diffuse=setting->vertex11Diffuse;
-
- verts[2].x=SKYPLANE_SIZE;
- verts[2].y=-SKYPLANE_SIZE;
- verts[2].z=SKYPLANE_HEIGHT;
- verts[2].u1=fu;
- verts[2].v1=m_vOffset;
- verts[2].diffuse=setting->vertex10Diffuse;
-
- verts[3].x=-SKYPLANE_SIZE;
- verts[3].y=-SKYPLANE_SIZE;
- verts[3].z=SKYPLANE_HEIGHT;
- verts[3].u1=m_uOffset;
- verts[3].v1=m_vOffset;
- verts[3].diffuse=setting->vertex00Diffuse;
- }
- }
-
- DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
- DX8Wrapper::Set_Vertex_Buffer(vb_access);
-
- Matrix3D tm(1);
- tm.Set_Translation(Vector3(0,0,0));
- DX8Wrapper::Set_Transform(D3DTS_WORLD,tm);
-
- DX8Wrapper::Draw_Triangles( 0,2, 0, 4); //draw a quad, 2 triangles, 4 verts
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Renders (draws) the sky body. Used for moon and sun. We rotate the image
- * so that it always faces the camera. This removes perspective and helps hide that
- * it's a flat image. */
-//-------------------------------------------------------------------------------------------------
-/// @todo: Add code to render properly sorted sun sky body.
-void WaterRenderObjClass::renderSkyBody(Matrix3D *mat)
-{
- Vector3 cPos;
-
- Vector3 pView,pRight,pUp,pPos(SKYBODY_X,SKYBODY_Y,SKYBODY_HEIGHT);
-
- mat->Get_Translation(&cPos);
-
- pView=cPos-pPos; //billboard to camera
- pView.Normalize(); //particle view direction
-
- Vector3 WorldUp(0,0,-1); ///@todo: hacked so only works for reflections across xy plane
-
-#ifdef ALLOW_TEMPORARIES
- Vector3 rotAxis=Vector3::Cross_Product(WorldUp,pView); //get axis of rotation.
- rotAxis.Normalize();
-#else
- Vector3 rotAxis;
- Vector3::Normalized_Cross_Product(WorldUp, pView, &rotAxis);
-#endif
-
- Real angle=Vector3::Dot_Product(WorldUp,pView);
-
- angle = acos(angle);
-
-
- Matrix3D tm(1);
- tm.Set(rotAxis,angle);
- tm.Adjust_Translation(Vector3(SKYBODY_X,SKYBODY_Y,SKYBODY_HEIGHT));
-
-
- DX8Wrapper::Set_Transform(D3DTS_WORLD,tm);
-
-
- VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- DX8Wrapper::Set_Material(vmat);
- REF_PTR_RELEASE(vmat);
-
- ShaderClass m_shader2=ShaderClass::_PresetAlphaShader;
- m_shader2.Set_Cull_Mode(ShaderClass::CULL_MODE_DISABLE);
- m_shader2.Set_Depth_Compare(ShaderClass::PASS_ALWAYS); //no need to check against z-buffer, sky always rendered first.
- m_shader2.Set_Depth_Mask(ShaderClass::DEPTH_WRITE_DISABLE); //sky is always behind everything so no need to update z-buffer
-
- DX8Wrapper::Set_Shader(m_shader2);
-
-
-// DX8Wrapper::Set_Shader(ShaderClass::/*_PresetAdditiveShader*//*_PresetOpaqueShader*/_PresetAlphaShader);
-// DX8Wrapper::Set_Texture(0,setting->skyBodyTexture);
-
- DX8Wrapper::Set_Texture(0,m_alphaClippingTexture);
-
- //draw an infinite sky plane
- DynamicVBAccessClass vb_access(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,4);
- {
- DynamicVBAccessClass::WriteLockClass lock(&vb_access);
- VertexFormatXYZNDUV2* verts=lock.Get_Formatted_Vertex_Array();
- if(verts)
- {
- verts[0].x=-SKYBODY_SIZE;
- verts[0].y=SKYBODY_SIZE;
- verts[0].z=0;
- verts[0].u2=0;
- verts[0].v2=1;
- verts[0].diffuse=0xffffffff;
-
- verts[1].x=SKYBODY_SIZE;
- verts[1].y=SKYBODY_SIZE;
- verts[1].z=0;
- verts[1].u2=1;
- verts[1].v2=1;
- verts[1].diffuse=0xffffffff;
-
- verts[2].x=SKYBODY_SIZE;
- verts[2].y=-SKYBODY_SIZE;
- verts[2].z=0;
- verts[2].u2=1;
- verts[2].v2=0;
- verts[2].diffuse=0xffffffff;
-
- verts[3].x=-SKYBODY_SIZE;
- verts[3].y=-SKYBODY_SIZE;
- verts[3].z=0;
- verts[3].u2=0;
- verts[3].v2=0;
- verts[3].diffuse=0xffffffff;
- }
- }
-
- DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
- DX8Wrapper::Set_Vertex_Buffer(vb_access);
-
- DX8Wrapper::Draw_Triangles( 0,2, 0, 4); //draw a quad, 2 triangles, 4 verts
-}
-
-//Defines for procedural water animation.
-#define WATER_FREQ (2.0*3.2831/4.0) //2pi (full cycle) cover 4 units
-#define WATER_AMP (1.0f)
-#define WATER_OFFSET (0.1f)
-
-//-------------------------------------------------------------------------------------------------
-/** Renders (draws) the water surface mesh geometry.
- * This is a work-in-progress! Do not use this code! */
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::renderWaterMesh(void)
-{
-
- if (!m_doWaterGrid)
- return; //the water grid is disabled.
-
- //According to Nvidia there's a D3D bug that happens if you don't start with a
- //new dynamic VB each frame - so we force a DISCARD by overflowing the counter.
- m_vertexBufferD3DOffset = 0xffff;
-
- Setting *setting=&m_settings[m_tod];
-
- WaterMeshData *pData;
- Int mx=m_gridCellsX+1;
- Int my=m_gridCellsY+1;
- Int i,j;
-
- Real cellSizeX=m_gridCellSize;
- Real cellSizeY=m_gridCellSize;
-// Real uScale2=5.0f*setting->waterRepeatCount/(128.0f)*cellSizeX/10.0f;
-// Real vScale2=5.0f*setting->waterRepeatCount/(128.0f)*cellSizeY/10.0f;
-
- //Old waterRepeatCount settings in INI were based on 128x128 water grid of cellsize=10
- //Scale values to correct size.
- Real uScale=setting->waterRepeatCount/(128.0f)*cellSizeX/10.0f*0.2f;
- Real vScale=setting->waterRepeatCount/(128.0f)*cellSizeY/10.0f*0.2f;
-
- Vector3 nx(cellSizeX*2.0f,0,0);
- Vector3 ny(0,cellSizeY*2.0f,0);
- Vector3 C;
-
-#ifdef DO_WATER_SIMULATION //Debug code used to create a dummy water animation
- //
- // Mark: If you re-enable this water simulation, you might want to consider moving
- // this code to the update() method of the water render object (Colin)
- //
-
- static Real PhasePerFrameX=0.1f;
- static Real PhasePerFrameY=0.1f;
-
- //update the mesh heights for this frame (update buffer is 2 samples wider/taller due to border)
- for (j=0,pData=m_meshData; j<(my+2); j++)
- {
- for (i=0; i<(mx+2); i++)
- {
- //*pData = WATER_AMP * sin(WATER_FREQ*(0.7f*i + 0.7f*j) - PhasePerFrame);
-
- pData->height=WATER_OFFSET+WATER_AMP*(sin((float)i*WATER_FREQ*0.4+PhasePerFrameX*0.5)+sin((float)i*WATER_FREQ*0.6+PhasePerFrameX*0.2)+sin((float)j*WATER_FREQ+PhasePerFrameX)+sin((float)j*WATER_FREQ*0.7+PhasePerFrameX*0.3));
-// *pData=WATER_OFFSET+WATER_AMP*(sin((float)i*WATER_FREQ*0.4+PhasePerFrameX*0.5)+sin((float)i*WATER_FREQ*0.6+PhasePerFrameX*0.2)+sin((float)j*WATER_FREQ+PhasePerFrameX)+sin((float)j*WATER_FREQ*0.7+PhasePerFrameX*0.3));
- pData++;
- }
- }
-
- PhasePerFrameX -= 0.08f;
- PhasePerFrameY -= 0.1f;
-#endif
-
- MaterMeshVertexFormat *vb;
- if (m_vertexBufferD3DOffset < m_numVertices)
- { //we have room in current VB, append new verts
- if(m_vertexBufferD3D->Lock(m_vertexBufferD3DOffset*sizeof(MaterMeshVertexFormat),mx*my*sizeof(MaterMeshVertexFormat),(unsigned char**)&vb,D3DLOCK_NOOVERWRITE) != D3D_OK)
- return;
- }
- else
- { //ran out of room in last VB, request a substitute VB.
- if(m_vertexBufferD3D->Lock(0,mx*my*sizeof(MaterMeshVertexFormat),(unsigned char**)&vb,D3DLOCK_DISCARD) != D3D_OK)
- return;
- m_vertexBufferD3DOffset=0; //reset start of page to first vertex
- }
- Int diffuse;
- diffuse = setting->waterDiffuse&0x00ffffff;
- Int alpha = (setting->waterDiffuse & 0xff000000)>>24;
- // Reduce alpha for wave mesh
- alpha -= 0x20;
- diffuse |= alpha<<24;
-
- //I pulled some of these constants out of the loops for speed:
- Real uvCosScale=0.02*cos(3*m_riverVOrigin);
- Real sinOffset=25*m_riverVOrigin;
- Real originScale=m_riverVOrigin/vScale;
- Real bumpSizeDiv=cellSizeY/BUMP_SIZE;
- Real bumpSizeDiv2=0.3f*cellSizeY/BUMP_SIZE;
-
- //Data has a 1 vertex padding all around it so we don't need to special-case edges. Improves performance
- for (j=0,pData=m_meshData+mx+2+1; jheight - (pData-1)->height;
- ny.Z=(pData+mx+2)->height - (pData-mx-2)->height;
-// nx.Z=*(pData+1)-*(pData-1);
-// ny.Z=*(pData+mx+2)-*(pData-mx-2);
- Vector3::Cross_Product(nx,ny,&C);
- C.Normalize();
- vb->nx = C.X;
- vb->ny = C.X;
- vb->nz = C.X;
-#endif
- Real x = (float)i*cellSizeX;
- vb->x= x;
- vb->y= y;
- vb->z= pData->height;//WATER_OFFSET+WATER_AMP*(sin((float)i*WATER_FREQ+PhasePerFrame)+cos((float)j*WATER_FREQ+PhasePerFrame));
-
- vb->diffuse = diffuse;
-#ifdef SCROLL_UV
-// vb->diffuse=0x80ffffff;
- vb->u1=(float)i*uScale;
- vb->v1=v1Offset;
-
- //old slow version
- //vb->v1=m_riverVOrigin+(float)j*vScale + 0.02*cos(3*m_riverVOrigin)*sin(25*m_riverVOrigin+y*PI/(8*MAP_XY_FACTOR));
-
-// vb->u2=m_initialGridU2+(float)i*uScale2;
-// vb->v2=m_initialGridV2+(float)j*vScale2;
-#else
- vb->u1=(float)i*uScale;
- vb->v1=(float)j*vScale;
-#endif
- vb->u2=(float)(i)*cellSizeX/BUMP_SIZE;
- vb->v2=v2Offset;
- //old slow code
- //vb->v2=(float)(j+m_riverVOrigin/vScale )*cellSizeY/BUMP_SIZE+ 0.3f*(float)j*cellSizeY/BUMP_SIZE;
- vb++;
- pData++;
- }
- }
-
- m_vertexBufferD3D->Unlock();
-
- Matrix3D tm(Transform);
-
- DX8Wrapper::Set_Transform(D3DTS_WORLD,tm); //position the water surface
- DX8Wrapper::Set_Material(m_meshVertexMaterialClass);
-
- ShaderClass::CullModeType oldCullMode=m_shaderClass.Get_Cull_Mode();
-
- ShaderClass::DepthMaskType oldDepthMask=m_shaderClass.Get_Depth_Mask();
- m_shaderClass.Set_Depth_Mask(ShaderClass::DEPTH_WRITE_DISABLE); //disable writing to z-buffer to prevent particle clipping.
-
- m_shaderClass.Set_Cull_Mode(ShaderClass::CULL_MODE_ENABLE); //water should be visible from both sides
-
- DX8Wrapper::Set_Shader(m_shaderClass);
-#if 1
- setupFlatWaterShader();
-#else
- //DX8Wrapper::Set_Shader(ShaderClass::_PresetOpaqueShader);
- DX8Wrapper::Set_Texture(0,setting->waterTexture);
- DX8Wrapper::Set_Texture(1,setting->waterTexture);
-
- DX8Wrapper::Set_Light(0,*m_meshLight);
- DX8Wrapper::Set_Light(1,NULL);
- DX8Wrapper::Set_Light(2,NULL);
- DX8Wrapper::Set_Light(3,NULL);
-/*
- DX8Wrapper::Set_DX8_Render_State(D3DRS_AMBIENT,0); //turn off scene ambient
- DX8Wrapper::Set_DX8_Render_State(D3DRS_SPECULARENABLE,TRUE);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_LOCALVIEWER,TRUE);
-*/
-
- DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
-#endif
-
-
-// m_pDev->SetRenderState(D3DRS_ZFUNC,D3DCMP_ALWAYS); //used to display grid under map.
-
- m_pDev->SetIndices(m_indexBufferD3D,m_vertexBufferD3DOffset);
- m_pDev->SetStreamSource(0,m_vertexBufferD3D,sizeof(MaterMeshVertexFormat));
- m_pDev->SetVertexShader(WATER_MESH_FVF);
-
-
- if (TheTerrainRenderObject->getShroud() && !m_trapezoidWaterPixelShader)
- { //we have a shroud to apply and can't do it inside the pixel shader.
- //so do it in stage1
- W3DShaderManager::setTexture(0,TheTerrainRenderObject->getShroud()->getShroudTexture());
- W3DShaderManager::setShader(W3DShaderManager::ST_SHROUD_TEXTURE, 1);
-
- //modulate with shroud texture
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); //stage 1 texture
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); //previous stage texture
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );
- DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
-
- //Shroud shader uses z-compare of EQUAL which wouldn't work on water because it doesn't
- //write to the zbuffer. Change to LESSEQUAL.
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
- m_pDev->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,0,mx*my,0,m_numIndices-2);
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL);
- W3DShaderManager::resetShader(W3DShaderManager::ST_SHROUD_TEXTURE);
- }
- else
- m_pDev->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,0,mx*my,0,m_numIndices-2);
-
- Debug_Statistics::Record_DX8_Polys_And_Vertices(m_numIndices-2,mx*my,ShaderClass::_PresetOpaqueShader);
-
-// m_pDev->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
-
- if (m_trapezoidWaterPixelShader) DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(NULL);
-
- m_vertexBufferD3DOffset += mx*my; //advance past vertices already in buffer
-
- DX8Wrapper::Set_Texture(0,NULL);
- DX8Wrapper::Set_Texture(1,NULL);
- ShaderClass::Invalidate();
- m_shaderClass.Set_Cull_Mode(oldCullMode); //water should be visible from both sides
-
- // restore shader to old mask
- m_shaderClass.Set_Depth_Mask(oldDepthMask);
-
- //W3DShaderManager::resetShader(W3DShaderManager::ST_SHROUD_TEXTURE);
-
-}
-
-inline void WaterRenderObjClass::setGridVertexHeight(Int x, Int y, Real value)
-{
- DEBUG_ASSERTCRASH( x < (m_gridCellsX+1) && y < (m_gridCellsY+1), ("Invalid Water Mesh Coordinates") );
-
- if (m_meshData)
- {
- m_meshData[(y+1)*(m_gridCellsX+1+2)+x+1].height = value;
- }
-}
-
-void WaterRenderObjClass::setGridHeightClamps(Real minz, Real maxz)
-{
- m_minGridHeight = minz;
- m_maxGridHeight = maxz;
-}
-
-void WaterRenderObjClass::addVelocity( Real worldX, Real worldY,
- Real zVelocity, Real preferredHeight )
-{
-
- if( m_doWaterGrid)
- {
- Real gx,gy;
- Real minX,maxX,minY,maxY;
- Int x,y;
- WaterMeshData *meshPoint;
- m_disableRiver = true;
-
- //check if center falls within grid bounds
- if (worldToGridSpace(worldX, worldY, gx, gy))
- {
-
- //find extents of influence
- minX = floorf(gx - m_gridChangeMaxRange);
- if (minX < 0 )
- minX = 0; //clamp extent to fall within box
- maxX = ceilf(gx + m_gridChangeMaxRange);
- if (maxX > m_gridCellsX)
- maxX = m_gridCellsX; //clamp extent to fall within box
-
- minY = floorf(gy - m_gridChangeMaxRange);
- if (minY < 0 )
- minY = 0; //clamp extent to fall within box
- maxY = ceilf(gy + m_gridChangeMaxRange);
- if (maxY > m_gridCellsY)
- maxY = m_gridCellsY; //clamp extent to fall within box
-
- for (y=minY; y<=maxY; y++)
- {
- for (x=minX; x<=maxX; x++)
- {
-
- // get the mesh point that we're concerned with
- meshPoint = &m_meshData[ (y + 1) * (m_gridCellsX + 1 + 2) + x + 1 ];
-
- // we now have a new preferred height
- meshPoint->preferredHeight = preferredHeight;
-
- //
- // set the velocity of this point based on the distance from the center of the
- // "core" point for this call
- //
- meshPoint->velocity = meshPoint->velocity + zVelocity;
-
- // this point is now "in motion"
- BitSet( meshPoint->status, WaterRenderObjClass::IN_MOTION );
-
- }
- }
-
- //
- // the mesh data is now dirty, we need to pass through the velocity field
- // during an update phase to update the positions
- //
- m_meshInMotion = TRUE;
-
- }
-
- }
-
-}
-
-void WaterRenderObjClass::changeGridHeight(Real wx, Real wy, Real delta)
-{
- Real gx,gy;
- Real *oldData;
- Real newData;
- Real distance;
- Real minX,maxX,minY,maxY;
- Int x,y;
-
- //check if center falls within grid bounds
- if (worldToGridSpace(wx, wy, gx, gy))
- { //find extents of influence
- minX = floorf(gx - m_gridChangeMaxRange);
- if (minX < 0 )
- minX = 0; //clamp extent to fall within box
- maxX = ceilf(gx + m_gridChangeMaxRange);
- if (maxX > m_gridCellsX)
- maxX = m_gridCellsX; //clamp extent to fall within box
-
- minY = floorf(gy - m_gridChangeMaxRange);
- if (minY < 0 )
- minY = 0; //clamp extent to fall within box
- maxY = ceilf(gy + m_gridChangeMaxRange);
- if (maxY > m_gridCellsY)
- maxY = m_gridCellsY; //clamp extent to fall within box
-
- for (y=minY; y<=maxY; y++)
- {
- for (x=minX; x<=maxX; x++)
- { oldData = &m_meshData[(y+1)*(m_gridCellsX+1+2)+x+1].height;
- distance = (gx - (Real)x)*(gx - (Real)x) + (gy - (Real)y)*(gy - (Real)y);
- distance = sqrt(distance);
- newData = *oldData + 1.0f/(m_gridChangeAtt0+m_gridChangeAtt1*distance+distance*distance*m_gridChangeAtt2)*delta;
- //Clamp to min/max values
- if (newData < m_minGridHeight)
- newData = m_minGridHeight;
- if (newData > m_maxGridHeight)
- newData = m_maxGridHeight;
- *oldData = newData;
- }
- }
- }
-}
-
-void WaterRenderObjClass::setGridChangeAttenuationFactors(Real a, Real b, Real c, Real range)
-{
- m_gridChangeAtt0 = a;
- m_gridChangeAtt1 = b;
- m_gridChangeAtt2 = c;
- m_gridChangeMaxRange = range/m_gridCellSize; //convert range to grid space
-}
-
-void WaterRenderObjClass::setGridTransform(Real angle, Real x, Real y, Real z)
-{
- m_gridDirectionX = Vector2(1.0f,0.0f);
-
- m_gridOrigin.X = x;
- m_gridOrigin.Y = y;
-
- Matrix3D xform(1);
- xform.Rotate_Z(angle);
-
- m_gridDirectionX.X = xform.Get_X_Vector().X;
- m_gridDirectionX.Y = xform.Get_X_Vector().Y;
-
- m_gridDirectionY.X = xform.Get_Y_Vector().X;
- m_gridDirectionY.Y = xform.Get_Y_Vector().Y;
-
- xform.Set_Translation(Vector3(x,y,z));
- Set_Transform(xform);
-}
-
-void WaterRenderObjClass::setGridTransform(const Matrix3D *transform )
-{
-
- if( transform )
- Set_Transform( *transform );
-
-}
-
-void WaterRenderObjClass::getGridTransform(Matrix3D *transform )
-{
-
- if( transform )
- *transform = Get_Transform();
-
-}
-
-void WaterRenderObjClass::setGridResolution(Real gridCellsX, Real gridCellsY, Real cellSize)
-{
- m_gridCellSize=cellSize;
-
- if (m_gridCellsX != gridCellsX || m_gridCellsY != gridCellsY)
- { //resolution has changed
- m_gridCellsX=gridCellsX;
- m_gridCellsY=gridCellsY;
-
- if (m_meshData)
- {
-
- delete [] m_meshData;//free previously allocated grid and allocate new size
- m_meshData = NULL; // must set to NULL so that we properly re-allocate
- m_meshDataSize = 0;
-
- Bool enable = m_doWaterGrid;
- enableWaterGrid(true); // allocates buffers.
- m_doWaterGrid = enable;
-
- }
- }
-}
-
-void WaterRenderObjClass::getGridResolution( Real *gridCellsX, Real *gridCellsY, Real *cellSize )
-{
-
- if( gridCellsX )
- *gridCellsX = m_gridCellsX;
- if( gridCellsY )
- *gridCellsY = m_gridCellsY;
- if( cellSize )
- *cellSize = m_gridCellSize;
-
-}
-
-static Real wobble(Real baseV, Real offset, Bool wobble)
-{
- if (!wobble) return 0;
- offset = sin(2*PI*baseV - 3*offset);
- return offset/22;
-}
-
-/**Utility function used to query water heights in a manner that works in both RTS and WB.*/
-Real WaterRenderObjClass::getWaterHeight(Real x, Real y)
-{
- const WaterHandle *waterHandle = NULL;
- Real waterZ = 0.0f;
- ICoord3D iLoc;
-
- iLoc.x = REAL_TO_INT_FLOOR( x + 0.5f );
- iLoc.y = REAL_TO_INT_FLOOR( y + 0.5f );
- iLoc.z = 0;
-
- for( PolygonTrigger *pTrig = PolygonTrigger::getFirstPolygonTrigger(); pTrig; pTrig = pTrig->getNext() )
- {
-
- if( !pTrig->isWaterArea() )
- continue;
-
- // See if point is in a water area
- if( pTrig->pointInTrigger( iLoc ) )
- {
-
- if( pTrig->getPoint( 0 )->z >= waterZ )
- {
-
- waterZ = pTrig->getPoint( 0 )->z;
- waterHandle = pTrig->getWaterHandle();
-
- }
-
- }
-
- }
-
- if (waterHandle)
- return waterHandle->m_polygon->getPoint( 0 )->z;
- return INVALID_WATER_HEIGHT; //point not underwater
-}
-
-//-------------------------------------------------------------------------------------------------
-//Draw a many sided river polygon.
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::drawRiverWater(PolygonTrigger *pTrig)
-{
- DX8Wrapper::Invalidate_Cached_Render_States(); ///@todo: Figure out why rivers don't draw without reset of all states.
-
- Int rectangleCount = pTrig->getNumPoints()/2;
- rectangleCount--;
-
- Real bumpFactor = 5;
- static Bool doWobble = true;
-
- if (m_disableRiver) return;
- m_drawingRiver = true;
-
- //allocate 2 triangles per side with 3 indices per triangle
- DynamicIBAccessClass ib_access(BUFFER_TYPE_DYNAMIC_DX8,(rectangleCount+1)*2*3);
- {
- DynamicIBAccessClass::WriteLockClass lockib(&ib_access);
- UnsignedShort *curIb = lockib.Get_Index_Array();
- for (Int i=0; im_standingWaterColor.red;
- Real shadeG=TheWaterTransparency->m_standingWaterColor.green;
- Real shadeB=TheWaterTransparency->m_standingWaterColor.blue;
-
- //If the water color is not overridden, use legacy lighting code.
- if ( shadeR==1.0f && shadeG==1.0f && shadeB==1.0f)
- {
- shadeR = TheGlobalData->m_terrainAmbient[0].red;
- shadeG = TheGlobalData->m_terrainAmbient[0].green;
- shadeB = TheGlobalData->m_terrainAmbient[0].blue;
-
- //Add in diffuse lighting from each terrain light
- for (Int lightIndex=0; lightIndex < TheGlobalData->m_numGlobalLights; lightIndex++)
- {
- if (-TheGlobalData->m_terrainLightPos[lightIndex].z > 0)
- { shadeR += -TheGlobalData->m_terrainLightPos[lightIndex].z * TheGlobalData->m_terrainDiffuse[lightIndex].red;
- shadeG += -TheGlobalData->m_terrainLightPos[lightIndex].z * TheGlobalData->m_terrainDiffuse[lightIndex].green;
- shadeB += -TheGlobalData->m_terrainLightPos[lightIndex].z * TheGlobalData->m_terrainDiffuse[lightIndex].blue;
- }
- }
-
- //Get water material colors
- Real waterShadeR = (m_settings[m_tod].waterDiffuse & 0xff) / 255.0f;
- Real waterShadeG = ((m_settings[m_tod].waterDiffuse >> 8) & 0xff) / 255.0f;
- Real waterShadeB = ((m_settings[m_tod].waterDiffuse >> 16) & 0xff) / 255.0f;
-
- shadeR=shadeR*waterShadeR*255.0f;
- shadeG=shadeG*waterShadeG*255.0f;
- shadeB=shadeB*waterShadeB*255.0f;
- }
- else
- {
- shadeR=shadeR*255.0f;
- shadeG=shadeG*255.0f;
- shadeB=shadeB*255.0f;
-
- if (shadeR == 0 && shadeG == 0 && shadeB == 0)
- { //special case where we disable lighting
- shadeR=255;
- shadeG=255;
- shadeB=255;
- }
- }
-
- Int diffuse=REAL_TO_INT(shadeB) | (REAL_TO_INT(shadeG) << 8) | (REAL_TO_INT(shadeR) << 16);
-
- //Keep diffuse from lighting calculations but substitute custom alpha
- diffuse |= m_settings[m_tod].waterDiffuse & 0xff000000; //copy alpha/opacity from ini setting
-
- Int innerNdx = pTrig->getRiverStart();
- Int outerNdx = innerNdx+1;
-
- Real endLen=0;
- Real totalLen=0;
- Int i;
- for (i=0; igetNumPoints()-1; i++) {
- ICoord3D innerPt = *pTrig->getPoint(i);
- ICoord3D outerPt = *pTrig->getPoint(i+1);
- Real dx = innerPt.x-outerPt.x;
- Real dy = innerPt.y-outerPt.y;
- Real curLen = sqrt(dx*dx+dy*dy);
- totalLen += curLen;
- if ( i==innerNdx) {
- endLen = curLen;
- }
- }
- bumpFactor = endLen/BUMP_SIZE;
-
- Real lengthOfRiver = (totalLen/2)-endLen;
- Real repeatCount = lengthOfRiver / (endLen);
-
- Real vScale=(Real)repeatCount/(Real)rectangleCount;
-
-#define HEIGHT_TO_USE (0.5f)
- if (innerNdx >= pTrig->getNumPoints()-1) return;
- //allocate 2 vertices per side
- DynamicVBAccessClass vb_access(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,(rectangleCount+1)*2);
- {
- DynamicVBAccessClass::WriteLockClass lock(&vb_access);
- VertexFormatXYZNDUV2* vb=lock.Get_Formatted_Vertex_Array();
-
- Real constA=3*m_riverVOrigin;
-
- for (i=0; i<(pTrig->getNumPoints()/2); i++)
- {
- Real x,y;
- ICoord3D innerPt = *pTrig->getPoint(outerNdx);
- ICoord3D outerPt = *pTrig->getPoint(innerNdx);
- outerNdx++;
- innerNdx--;
- if (innerNdx<0) {
- innerNdx = pTrig->getNumPoints()-1;
- }
- if (outerNdx >= pTrig->getNumPoints()) {
- outerNdx = 0;
- }
- x=innerPt.x;
- y=innerPt.y;
-
- vb->x=x;
- vb->y=y;
-
- vb->z=innerPt.z;
- vb->diffuse= diffuse;
-
- Real wobbleConst=-m_riverVOrigin+vScale*(Real)i + WWMath::Fast_Sin(2*PI*(vScale*(Real)i) - constA)/22.0f;
- //old slower version
- //vb->v1=-m_riverVOrigin+vScale*(Real)i + wobble(vScale*i, m_riverVOrigin, doWobble);
- vb->v1=wobbleConst;
- vb->u1=HEIGHT_TO_USE ;
- //old slower version
- //vb->v2 = -m_riverVOrigin+vScale*(Real)i + wobble(vScale*i, m_riverVOrigin, doWobble);
- vb->v2=wobbleConst;
- vb->u2 = 1.0f;
- vb->nx = 0;
- vb->ny = 0;
- vb->nz = 1.0f;
- vb++;
-
- x=outerPt.x;
- y=outerPt.y;
-
- vb->x=x;
- vb->y=y;
- vb->z=outerPt.z;
- vb->diffuse= diffuse;
- //old slower version
- //vb->v1=-m_riverVOrigin+vScale*(Real)i + wobble(vScale*i, m_riverVOrigin, doWobble);
- vb->v1=wobbleConst;
- vb->u1=0;
- //old slower version
- //vb->v2 = -m_riverVOrigin+vScale*(Real)i + wobble(vScale*i, m_riverVOrigin, doWobble);
- vb->v2 =wobbleConst;
- vb->u2 = 0;
- vb->nx = 0;
- vb->ny = 0;
- vb->nz = 1.0f;
- vb++;
-
- }
- }
-
- Matrix3D tm(1);
-
- DX8Wrapper::Set_Transform(D3DTS_WORLD,tm); //position the water surface
- DX8Wrapper::Set_Index_Buffer(ib_access,0);
- DX8Wrapper::Set_Vertex_Buffer(vb_access);
- DX8Wrapper::Set_Texture(0,m_riverTexture); //set to blue
-
- setupJbaWaterShader();
-
- //In additive blending we need to use the alpha at the edges of river to darken
- //rgb instead.
- if (TheWaterTransparency->m_additiveBlend)
- DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
-
- if (m_riverWaterPixelShader) DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_riverWaterPixelShader);
- DWORD cull;
- DX8Wrapper::_Get_D3D_Device8()->GetRenderState(D3DRS_CULLMODE, &cull);
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
-
-
-
- if (wireframeForDebug) {
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
- }
- DX8Wrapper::Draw_Triangles( 0,rectangleCount*2, 0, (rectangleCount+1)*2);
- if (wireframeForDebug) {
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
- }
-
- if (m_riverWaterPixelShader) DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(NULL);
-
- //restore blend mode to what W3D expects.
- if (TheWaterTransparency->m_additiveBlend)
- DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND, D3DBLEND_ONE );
-
- //do second pass to apply the shroud on water plane
- if (TheTerrainRenderObject->getShroud())
- {
- W3DShaderManager::setTexture(0,TheTerrainRenderObject->getShroud()->getShroudTexture());
- W3DShaderManager::setShader(W3DShaderManager::ST_SHROUD_TEXTURE, 0);
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
- //Shroud shader uses z-compare of EQUAL which wouldn't work on water because it doesn't
- //write to the zbuffer. Change to LESSEQUAL.
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
- DX8Wrapper::Draw_Triangles( 0,rectangleCount*2, 0, (rectangleCount+1)*2);
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL);
- W3DShaderManager::resetShader(W3DShaderManager::ST_SHROUD_TEXTURE);
- }
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_CULLMODE, cull);
-
-
-}
-
-void WaterRenderObjClass::setupFlatWaterShader(void)
-{
- //Setup shroud to render in same pass as water
- if (m_trapezoidWaterPixelShader)
- { if (TheTerrainRenderObject->getShroud())
- {
- W3DShaderManager::setTexture(0,TheTerrainRenderObject->getShroud()->getShroudTexture());
- //Use stage 3 to apply the shroud
- W3DShaderManager::setShader(W3DShaderManager::ST_SHROUD_TEXTURE, 3);
- m_pDev->SetTextureStageState( 3, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 3, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- m_pDev->SetTextureStageState( 3, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- //Shroud shader uses z-compare of EQUAL which wouldn't work on water because it doesn't
- //write to the zbuffer. Change to LESSEQUAL.
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
- }
- else
- { //Assume no shroud, so stage 3 will be "NULL" texture but using actual white because
- //pixel shader on GF4 generates random colors with SetTexture(3,NULL).
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(3,m_whiteTexture->Peek_D3D_Texture());
- }
- }
-
- DX8Wrapper::Set_Texture(0,m_riverTexture);
- if (!TheWaterTransparency->m_additiveBlend)
- DX8Wrapper::Set_Shader(ShaderClass::_PresetAlphaShader);
- else
- DX8Wrapper::Set_Shader(ShaderClass::_PresetAdditiveShader);
-
- VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- DX8Wrapper::Set_Material(vmat);
- REF_PTR_RELEASE(vmat);
- m_riverTexture->Get_Filter().Set_Mag_Filter(TextureFilterClass::FILTER_TYPE_BEST);
- m_riverTexture->Get_Filter().Set_Min_Filter(TextureFilterClass::FILTER_TYPE_BEST);
- m_riverTexture->Get_Filter().Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_BEST);
-
- DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices
-
- DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_ADD );
- DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, 0);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXCOORDINDEX, 0);
-
- Bool doSparkles = true;
-
- if (m_trapezoidWaterPixelShader && doSparkles) {
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(1,m_waterSparklesTexture->Peek_D3D_Texture());
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(2,m_waterNoiseTexture->Peek_D3D_Texture());
-
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
-
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
- // Two output coordinates are used.
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- D3DXMATRIX inv;
- float det;
-
- Matrix4x4 curView;
- DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
- D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
- D3DXMATRIX scale;
-
- D3DXMatrixScaling(&scale, NOISE_REPEAT_FACTOR, NOISE_REPEAT_FACTOR,1);
- D3DXMATRIX destMatrix = inv * scale;
- D3DXMatrixTranslation(&scale, m_riverVOrigin, m_riverVOrigin,0);
- destMatrix = destMatrix*scale;
- DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE2, *(Matrix4x4*)&destMatrix);
-
- }
- m_pDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 2, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- m_pDev->SetTextureStageState( 2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- if (m_trapezoidWaterPixelShader){
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(0, D3DXVECTOR4(REFLECTION_FACTOR, REFLECTION_FACTOR, REFLECTION_FACTOR, 1.0f), 1);
- DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_trapezoidWaterPixelShader);
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-//Draw a 4 sided flat water area.
-//-------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::drawTrapezoidWater(Vector3 points[4])
-{
- Vector3 origin(points[0]);
- Vector3 uVec1(points[1]);
- Vector3 vVec1(points[3]);
- Vector3 uVec2(points[2]);
- Vector3 vVec2(points[2]);
- uVec2 -= vVec1;
- vVec2 -= uVec1;
- uVec1 -= origin;
- vVec1 -= origin;
- Int uCount = (uVec1.Length()+uVec2.Length()) / (8*MAP_XY_FACTOR);
- if (uCount<1) uCount = 1;
- Int vCount = (vVec1.Length()+vVec2.Length()) / (8*MAP_XY_FACTOR);
- if (vCount<1) vCount = 1;
-
- if (uCount>50) uCount = 50;
- if (vCount>50) vCount = 50;
-
- static Bool doWobble = true;
-
- Int rectangleCount = uCount*vCount;
-
- uCount++;
- vCount++;
-
- Int i, j;
- //allocate 2 triangles per side with 3 indices per triangle
- DynamicIBAccessClass ib_access(BUFFER_TYPE_DYNAMIC_DX8,(rectangleCount+1)*2*3);
- {
- DynamicIBAccessClass::WriteLockClass lockib(&ib_access);
- UnsignedShort *curIb = lockib.Get_Index_Array();
- for (j=0; jm_standingWaterColor.red;
- Real shadeG=TheWaterTransparency->m_standingWaterColor.green;
- Real shadeB=TheWaterTransparency->m_standingWaterColor.blue;
-
- //If the water color is not overridden, use legacy lighting code.
- if ( shadeR==1.0f && shadeG==1.0f && shadeB==1.0f)
- {
- shadeR = TheGlobalData->m_terrainAmbient[0].red;
- shadeG = TheGlobalData->m_terrainAmbient[0].green;
- shadeB = TheGlobalData->m_terrainAmbient[0].blue;
-
- //Add in diffuse lighting from each terrain light
- for (Int lightIndex=0; lightIndex < TheGlobalData->m_numGlobalLights; lightIndex++)
- {
- if (-TheGlobalData->m_terrainLightPos[lightIndex].z > 0)
- { shadeR += -TheGlobalData->m_terrainLightPos[lightIndex].z * TheGlobalData->m_terrainDiffuse[lightIndex].red;
- shadeG += -TheGlobalData->m_terrainLightPos[lightIndex].z * TheGlobalData->m_terrainDiffuse[lightIndex].green;
- shadeB += -TheGlobalData->m_terrainLightPos[lightIndex].z * TheGlobalData->m_terrainDiffuse[lightIndex].blue;
- }
- }
-
- //Get water material colors
- Real waterShadeR = (m_settings[m_tod].waterDiffuse & 0xff) / 255.0f;
- Real waterShadeG = ((m_settings[m_tod].waterDiffuse >> 8) & 0xff) / 255.0f;
- Real waterShadeB = ((m_settings[m_tod].waterDiffuse >> 16) & 0xff) / 255.0f;
-
- shadeR=shadeR*waterShadeR*255.0f;
- shadeG=shadeG*waterShadeG*255.0f;
- shadeB=shadeB*waterShadeB*255.0f;
- }
- else
- {
- shadeR=shadeR*255.0f;
- shadeG=shadeG*255.0f;
- shadeB=shadeB*255.0f;
-
- if (shadeR == 0 && shadeG == 0 && shadeB == 0)
- { //special case where we disable lighting
- shadeR=255;
- shadeG=255;
- shadeB=255;
- }
- }
-
- Int diffuse=REAL_TO_INT(shadeB) | (REAL_TO_INT(shadeG) << 8) | (REAL_TO_INT(shadeR) << 16);
-
- //Keep diffuse from lighting calculations but substitute custom alpha
- diffuse |= m_settings[m_tod].waterDiffuse & 0xff000000; //copy alpha/opacity from ini setting
-
- DynamicVBAccessClass vb_access(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,(rectangleCount+1)*2);
-
-//#define WAVY_WATER
-//#define FEATHER_LAYER_COUNT (3) //LORENZEN
-//#define FEATHER_LAYER_THICKNESS (2.5f)
-//#define FEATHER_WATER
-
-//#ifdef WAVY_WATER // the NEW WATER a'la LORENZEN
- if ( TheGlobalData->m_featherWater )
- {
-
- DynamicVBAccessClass::WriteLockClass lock(&vb_access);
- VertexFormatXYZNDUV2* vb=lock.Get_Formatted_Vertex_Array();
-
- Real phase = 0;
- Real mapCoeff = PI/(4*MAP_XY_FACTOR);
- Real wave = 0;
- Real amplitude = 0.5f;
-
- //The first (high order) byte is the Alpha value for this patch
- // It needs to be set proportional to the number of feather layers
- // this comes from TheGlobalData->m_featherWater, which is a count of layers
-
-
- Int Alpha = 0;
- if ( TheGlobalData->m_featherWater == 5) Alpha = 80;
- if ( TheGlobalData->m_featherWater == 4) Alpha = 110;
- if ( TheGlobalData->m_featherWater == 3) Alpha = 140;
- if ( TheGlobalData->m_featherWater == 2) Alpha = 200;
- if ( TheGlobalData->m_featherWater == 1) Alpha = 255;
-
- //Keep diffuse from lighting calculations but substitute custom alpha
- Int customDiffuse = (diffuse & 0x00ffffff) | (Alpha<< 24);//(0x80 << 16)|(0x90 << 8)|0xa0;
-
- for (j=0; jx=vertex.X;
- vb->y=vertex.Y;
-
- // common to all the waving effects
- phase = 25 * m_riverVOrigin + vertex.X * mapCoeff;
- wave = (sin(phase) - 1.0f) * amplitude;
-
- vb->z = (vertex.Z + wave);
- vb->diffuse = customDiffuse;
- vb->u1 = (vertex.X/waterFactor) + 0.02*cos(11*m_riverVOrigin)*wave;
- vb->v1 = (vertex.Y/waterFactor) + 0.02*cos(5*m_riverVOrigin)*wave;
- vb->u2 = vertex.X/BUMP_SIZE;
- vb->v2 = vertex.Y/BUMP_SIZE + 0.3f*vertex.X/BUMP_SIZE;
- vb->nx = 0;
- vb->ny = 0;
- vb->nz = 1.0f;
- vb++;
- }
- }
- }
-//#else // STILL THE OLD FLAT WATER
- else
-
- {
- DynamicVBAccessClass::WriteLockClass lock(&vb_access);
- VertexFormatXYZNDUV2* vb=lock.Get_Formatted_Vertex_Array();
-
- //Pulling some constants out of the inner loops to improve performance -MW
- Real constA=0.02*cos(11*m_riverVOrigin);
- Real constB=0.02*cos(5*m_riverVOrigin);
- Real constC=25*m_riverVOrigin;
- Real ooWaterFactor = 1.0f/waterFactor;
- const Real constD=PI/(4*MAP_XY_FACTOR);
- Real constE=1.0f/(Real)(vCount-1);
- Real constF=1.0f/(Real)(uCount-1);
-
- for (j=0; jx=vertex.X;
- vb->y=vertex.Y;
- vb->z=vertex.Z;
-
- vb->diffuse= diffuse;
- //Old slower version
- //vb->u1=(vertex.X/waterFactor) + 0.02*cos(11*m_riverVOrigin)*sin(25*m_riverVOrigin+vertex.X*PI/(4*MAP_XY_FACTOR));
- //vb->v1=(vertex.Y/waterFactor) + 0.02*cos(5*m_riverVOrigin)*sin(25*m_riverVOrigin+vertex.Y*PI/(4*MAP_XY_FACTOR));
- vb->u1=vertex.X*ooWaterFactor + constA*WWMath::Fast_Sin(constC+vertex.X*constD);
- vb->v1=vertex.Y*ooWaterFactor + constB*WWMath::Fast_Sin(constC+vertex.Y*constD);
- vb->u2 = vertex.X/BUMP_SIZE;
- //Old slower version
- //vb->v2 = vertex.Y/BUMP_SIZE + 0.3f*vertex.X/BUMP_SIZE;
- vb->v2 = (vertex.Y+0.3f*vertex.X)/BUMP_SIZE;
- vb->nx = 0;
- vb->ny = 0;
- vb->nz = 1.0f;
- vb++;
- }
- }
- }
-
-//#endif // OLD VS NEW WATER
-
-
-
- Matrix3D tm(1);
-
- DX8Wrapper::Set_Transform(D3DTS_WORLD,tm); //position the water surface
- DX8Wrapper::Set_Index_Buffer(ib_access,0);
- DX8Wrapper::Set_Vertex_Buffer(vb_access);
-
- setupFlatWaterShader();// lorenzen sez use the alpha shader
-
- //If video card supports it and it's enabled, feather the water edge using destination alpha
- if (DX8Wrapper::getBackBufferFormat() == WW3D_FORMAT_A8R8G8B8 && TheGlobalData->m_showSoftWaterEdge && TheWaterTransparency->m_transparentWaterDepth !=0)
- { DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND, D3DBLEND_DESTALPHA );
- if (!TheWaterTransparency->m_additiveBlend)
- DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA );
- }
-
-
- DWORD cull;
- DX8Wrapper::_Get_D3D_Device8()->GetRenderState(D3DRS_CULLMODE, &cull);
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
-
-
-
-//#ifdef FEATHER_WATER // the NEW WATER a'la LORENZEN
-
-// int layer = 0;//LORENZEN
-// for (layer = 0; layer < FEATHER_LAYER_COUNT; ++layer)//LORENZEN
-//#endif // FEATHER_WATER
- {
-//#ifdef WAVY_WATER // the NEW WATER a'la LORENZEN
-
- //increment the depth of the water's surface for every vert in the buffer
-//#ifdef FEATHER_WATER
-// VertexFormatXYZNDUV2 *vertBuf = vertexBufferStart;
-// while (vertBuf < vertexBufferStart + vCount * uCount)
-// {
-// vertBuf->z *= FEATHER_LAYER_THICKNESS;
-// ++vertBuf;
-// }
-//#endif // FEATHER_WATER
-//#endif //WAVY_WATER
- DX8Wrapper::Draw_Triangles( 0,rectangleCount*2, 0, (rectangleCount+1)*2);//lorenzen thinks this is where to itereate the soft shoreline effect
- }
-
-
-
-
- if (false) {
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
- m_pDev->SetRenderState(D3DRS_ALPHABLENDENABLE , false);
- DX8Wrapper::Draw_Triangles( 0,rectangleCount*2, 0, (rectangleCount+1)*2);
- m_pDev->SetRenderState(D3DRS_ALPHABLENDENABLE , true);
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
- }
-
- if (m_riverWaterPixelShader) DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(NULL);
- //Restore alpha blend to default values since we may have changed them to feather edges.
- if (!TheWaterTransparency->m_additiveBlend)
- { DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
- DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
- }
- else
- {
- DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND, D3DBLEND_ONE );
- DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND, D3DBLEND_ONE );
- }
-
- if (TheTerrainRenderObject->getShroud())
- {
- if (m_trapezoidWaterPixelShader)
- { //shroud was applied in stage3 of main pass so just need to restore state here.
- W3DShaderManager::resetShader(W3DShaderManager::ST_SHROUD_TEXTURE);
- DX8Wrapper::_Get_D3D_Device8()->SetTexture(3,NULL); //free possible reference to shroud texture
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL);
- }
- else
- { //do second pass to apply the shroud on water plane for cards that can't do it in main pass.
- W3DShaderManager::setTexture(0,TheTerrainRenderObject->getShroud()->getShroudTexture());
- W3DShaderManager::setShader(W3DShaderManager::ST_SHROUD_TEXTURE, 0);
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
- //Shroud shader uses z-compare of EQUAL which wouldn't work on water because it doesn't
- //write to the zbuffer. Change to LESSEQUAL.
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
- DX8Wrapper::Draw_Triangles( 0,rectangleCount*2, 0, (rectangleCount+1)*2);
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL);
- W3DShaderManager::resetShader(W3DShaderManager::ST_SHROUD_TEXTURE);
- }
- }
- DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_CULLMODE, cull);
-}
-
-
-
-//-------------------------------------------------------------------------------------------------
-//debug version where moon rotates with the camera (always upright on screen)
-//-------------------------------------------------------------------------------------------------
-#if 0
-void WaterRenderObjClass::renderSkyBody(Matrix3D *mat)
-{
- Vector3 vRight,vUp,V0,V1,V2,V3;
-
- mat->Get_X_Vector(&vRight);
- mat->Get_Y_Vector(&vUp);
-
- //calculate offsets from quad center to each of the 4 corners
- // 0-----1
- // | /|
- // | / |
- // |/ |
- // 3-----2
- V0=-vRight+vUp;
- V2=vRight+vUp;
- V2=vRight-vUp;
- V3=-vRight-vUp;
-
- VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- DX8Wrapper::Set_Material(vmat);
- REF_PTR_RELEASE(vmat);
- DX8Wrapper::Set_Shader(ShaderClass::/*_PresetAdditiveShader*//*_PresetOpaqueShader*/_PresetAlphaShader);
-// DX8Wrapper::Set_Texture(0,setting->skyBodyTexture);
-
- DX8Wrapper::Set_Texture(0,m_alphaClippingTexture);
-
- //draw an infinite sky plane
- DynamicVBAccessClass vb_access(BUFFER_TYPE_DYNAMIC_DX8,4);
- {
- DynamicVBAccessClass::WriteLockClass lock(&vb_access);
- VertexFormatXYZNDUV2* verts=lock.Get_Formatted_Vertex_Array();
- if(verts)
- {
- verts[0].x=SKYBODY_SIZE*V0.X;
- verts[0].y=SKYBODY_SIZE*V0.Y;
- verts[0].z=SKYBODY_SIZE*V0.Z;
- verts[0].u2=0;
- verts[0].v2=1;
- verts[0].diffuse=0xffffffff;
-
- verts[1].x=SKYBODY_SIZE*V1.X;
- verts[1].y=SKYBODY_SIZE*V1.Y;
- verts[1].z=SKYBODY_SIZE*V1.Z;
- verts[1].u2=1;
- verts[1].v2=1;
- verts[1].diffuse=0xffffffff;
-
- verts[2].x=SKYBODY_SIZE*V2.X;
- verts[2].y=SKYBODY_SIZE*V2.Y;
- verts[2].z=SKYBODY_SIZE*V2.Z;
- verts[2].u2=1;
- verts[2].v2=0;
- verts[2].diffuse=0xffffffff;
-
- verts[3].x=SKYBODY_SIZE*V3.X;
- verts[3].y=SKYBODY_SIZE*V3.Y;
- verts[3].z=SKYBODY_SIZE*V3.Z;
- verts[3].u2=0;
- verts[3].v2=0;
- verts[3].diffuse=0xffffffff;
- }
- }
-
- DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0);
- DX8Wrapper::Set_Vertex_Buffer(vb_access);
-
- Matrix3D tm(1);
- //set postion of skybody in world
-// tm.Set_Translation(Vector3(40,0,0));
- DX8Wrapper::Set_Transform(D3DTS_WORLD,tm);
-
- DX8Wrapper::Draw_Triangles( 0,2, 0, 4); //draw a quad, 2 triangles, 4 verts
-}
-#endif
-
-// ------------------------------------------------------------------------------------------------
-/** CRC */
-// ------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::crc( Xfer *xfer )
-{
-
-}
-
-// ------------------------------------------------------------------------------------------------
-/** Xfer
- * Version Info:
- * 1: Initial version */
-// ------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::xfer( Xfer *xfer )
-{
-
- // version
- XferVersion currentVersion = 1;
- XferVersion version = currentVersion;
- xfer->xferVersion( &version, currentVersion );
-
- // grid cells x
- Int cellsX = m_gridCellsX;
- xfer->xferInt( &cellsX );
- if( cellsX != m_gridCellsX )
- {
-
- DEBUG_CRASH(( "WaterRenderObjClass::xfer - cells X mismatch" ));
- throw SC_INVALID_DATA;
-
- }
-
- // grid cells Y
- Int cellsY = m_gridCellsY;
- xfer->xferInt( &cellsY );
- if( cellsY != m_gridCellsY )
- {
-
- DEBUG_CRASH(( "WaterRenderObjClass::xfer - cells Y mismatch" ));
- throw SC_INVALID_DATA;
-
- }
-
- // xfer each of the mesh data points
- for( UnsignedInt i = 0; i < m_meshDataSize; ++i )
- {
-
- // height
- xfer->xferReal( &m_meshData[ i ].height );
-
- // velocity
- xfer->xferReal( &m_meshData[ i ].velocity );
-
- // status
- xfer->xferUnsignedByte( &m_meshData[ i ].status );
-
- // preferred height
- xfer->xferUnsignedByte( &m_meshData[ i ].preferredHeight );
-
- }
-
-}
-
-// ------------------------------------------------------------------------------------------------
-/** Load post process */
-// ------------------------------------------------------------------------------------------------
-void WaterRenderObjClass::loadPostProcess( void )
-{
-
-}
-
-
diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
deleted file mode 100644
index c5cb7e41686..00000000000
--- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
+++ /dev/null
@@ -1,1279 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: W3DWaterTracks.cpp ////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-//
-// Westwood Studios Pacific.
-//
-// Confidential Information
-// Copyright (C) 2001 - All Rights Reserved
-//
-//-----------------------------------------------------------------------------
-//
-// Project: RTS3
-//
-// File name: W3DWaterTracks.cpp
-//
-// Created: Mark Wilczynski, July 2001
-//
-// Desc: Draw waves and splash marks on water surface. System allows for
-// some simple animation : dynamic uv coordinates, scaling, scrolling,
-// and alpha.
-//-----------------------------------------------------------------------------
-
-#include "W3DDevice/GameClient/HeightMap.h"
-#include "W3DDevice/GameClient/W3DWaterTracks.h"
-#include "GameClient/InGameUI.h"
-#include "GameLogic/TerrainLogic.h"
-#include "Common/FramePacer.h"
-#include "Common/GlobalData.h"
-#include "Common/UnicodeString.h"
-#include "Common/file.h"
-#include "Common/FileSystem.h"
-#include "texture.h"
-#include "colmath.h"
-#include "coltest.h"
-#include "rinfo.h"
-#include "camera.h"
-#include "assetmgr.h"
-#include "WW3D2/dx8wrapper.h"
-
-//number of vertex pages allocated - allows double buffering of vertex updates.
-//while one is being rendered, another is being updated. Improves HW parallelism.
-#define WATER_VB_PAGES 1000
-#define WATER_STRIP_X 2 //vertex resolution of each strip
-#define WATER_STRIP_Y 2
-#define SYNC_WAVES //all the waves are in sync - movement resets at same time.
-//#define DEFAULT_FINAL_WAVE_WIDTH 28.0f
-//#define DEFAULT_FINAL_WAVE_HEIGHT 18.0f
-//#define DEFAULT_SECOND_WAVE_TIME_OFFSET 6267 //should always be half of totalMs
-
-WaterTracksRenderSystem *TheWaterTracksRenderSystem=NULL; ///< singleton for track drawing system.
-
-static Bool pauseWaves=FALSE;
-
-enum waveType CPP_11(: Int)
-{
- WaveTypeFirst,
- WaveTypePond=WaveTypeFirst,
- WaveTypeOcean,
- WaveTypeCloseOcean, //same as above but appears much closer to beach.
- WaveTypeCloseOceanDouble, //same as above but waves much sloser together.
- WaveTypeRadial,
- WaveTypeLast = WaveTypeRadial,
- WaveTypeStationary,
- WaveTypeMax,
-};
-
-struct waveInfo
-{
- Real m_finalWidth; //final width of of wave when it reaches beach.
- Real m_finalHeight; //final height of wave after it stretched out on beach.
- Real m_waveDistance; //distance away from beach where wave starts.
- Real m_initialVelocity;
- Int m_fadeMs; //time to fade out wave after it stops on shore.
- Real m_initialWidthFraction; //fraction of m_finalWidth when wave first appears.
- Real m_initialHeightWidthFraction; //fraction of initial width to use as the initial height.
- Int m_timeToCompress; //time for back of wave to continue moving forward after front starts retreating.
- Int m_secondWaveTimeOffset; //time for second wave to start. Should always be half of first wave's TotalMs.
- const char *m_textureName; //name of texture to use on wave.
- const char *m_waveTypeName; //name of this wave type.
-};
-
-waveInfo waveTypeInfo[WaveTypeMax]=
-{
- {28.0f, 18.0f, 25.0f, 0.018f, 900, 0.01f, 0.18f, 1500, 0,"wave256.tga","Pond"}, //pond
- {55.0f, 36.0f, 80.0f, 0.015f, 2000, 0.5f, 0.18f, 1000, 6267,"wave256.tga","Ocean"}, //ocean
- {55.0f, 36.0f, 80.0f, 0.015f, 2000, 0.05f, 0.18f, 1000, 6267,"wave256.tga","Close Ocean"},
- {55.0f, 36.0f, 80.0f, 0.015f, 4000, 0.01f, 0.18f, 2000, 6267,"wave256.tga","Close Ocean Double"},
- {55.0f, 27.0f, 80.0f, 0.015f, 2000, 0.01f, 8.0f, 2000, 5367,"wave256.tga","Radial"},
-};
-
-//=============================================================================
-// WaterTracksObj::~WaterTracksObj
-//=============================================================================
-/** Destructor. Releases w3d assets. */
-//=============================================================================
-WaterTracksObj::~WaterTracksObj(void)
-{
- freeWaterTracksResources();
-}
-
-//=============================================================================
-// WaterTracksObj::WaterTracksObj
-//=============================================================================
-/** Constructor. Just nulls out some variables. */
-//=============================================================================
-WaterTracksObj::WaterTracksObj(void)
-{
- m_stageZeroTexture=NULL;
- m_bound=false;
- m_initTimeOffset=0;
-}
-
-//=============================================================================
-// WaterTracksObj::Get_Obj_Space_Bounding_Sphere
-//=============================================================================
-/** WW3D method that returns object bounding sphere used in frustum culling*/
-//=============================================================================
-void WaterTracksObj::Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const
-{ /// @todo: Add code to cull track marks to screen by constantly updating bounding volumes
- sphere=m_boundingSphere;
-}
-
-//=============================================================================
-// WaterTracksObj::Get_Obj_Space_Bounding_Box
-//=============================================================================
-/** WW3D method that returns object bounding box used in collision detection*/
-//=============================================================================
-void WaterTracksObj::Get_Obj_Space_Bounding_Box(AABoxClass & box) const
-{
- box=m_boundingBox;
-}
-
-//=============================================================================
-// WaterTracksObj::freeWaterTracksResources
-//=============================================================================
-/** Free any W3D resources associated with this object */
-//=============================================================================
-Int WaterTracksObj::freeWaterTracksResources(void)
-{
- REF_PTR_RELEASE(m_stageZeroTexture);
- return 0;
-}
-
-//=============================================================================
-// WaterTracksObj::init
-//=============================================================================
-/** Setup size settings and allocate W3D texture
-* The width/length define the size of the polygon quad which will contain
-* the specified texture.
- */
-//=============================================================================
-void WaterTracksObj::init( Real width, Real length, const Vector2 &start, const Vector2 &end, const Char *texturename, Int waveTimeOffset)
-{
- freeWaterTracksResources(); //free old resources used by this track
-
- //save original settings used to create this wave
- m_initStartPos = start;
- m_initEndPos = end;
- m_initTimeOffset = waveTimeOffset;
-
- m_boundingSphere.Init(Vector3(0,0,0),400);
- m_boundingBox.Center.Set(0.0f, 0.0f, 0.0f);
- m_boundingBox.Extent.Set(400.0f, 400.0f, 1.0f);
- m_x=WATER_STRIP_X;
- m_y=WATER_STRIP_Y;
- m_elapsedMs=m_initTimeOffset;
- m_startPos=start;
- m_perpDir=m_waveDir=end-start;
- m_perpDir.Rotate(-1.57079632679f); //get vector perpendicular to wave motion.
- m_perpDir.Normalize();
-
- m_waveDir=m_perpDir;
- m_waveDir.Rotate(PI/2); //get vector along wave travel direction.
- //move back by width of wave so start point turns into maximum reach of wave.
- //m_startPos -= m_waveDir*m_width;
- //move back initial tip off of wave a couple units off the final position
- //to give it some room to travel. Travel vector is stored in m_waveDir.
- m_waveDistance = waveTypeInfo[m_type].m_waveDistance; //total distance traveled by wave front
-
- m_waveDir *= m_waveDistance;
- m_startPos -= m_waveDir; //move start point down away from shoreline
-
- m_initialVelocity=waveTypeInfo[m_type].m_initialVelocity; //velocity per ms
- m_totalMs = m_waveDistance/m_initialVelocity; //amount of time for wave to travel complete distance
-
- m_fadeMs = waveTypeInfo[m_type].m_fadeMs; //time for wave to fade out after it stops on beach
-
- m_waveInitialWidth=length * waveTypeInfo[m_type].m_initialWidthFraction;///Get_Texture(texturename);
-}
-
-//=============================================================================
-// WaterTracksObj::init
-//=============================================================================
-/** Setup size settings and allocate W3D texture
-* Alternate version of init where:
-* (start, end) define a vector perpendicular to wave travel. The length of this
-* vector is used as the length of the wave segment. The line between start-end
-* defines the maximum distance the wave will reach.
- */
-//=============================================================================
-void WaterTracksObj::init( Real width, const Vector2 &start, const Vector2 &end, const Char *texturename)
-{
- freeWaterTracksResources(); //free old resources used by this track
- m_boundingSphere.Init(Vector3(0,0,0),400);
- m_boundingBox.Center.Set(0.0f, 0.0f, 0.0f);
- m_boundingBox.Extent.Set(400.0f, 400.0f, 1.0f);
- m_perpDir=end-start;
- m_startPos=start + m_perpDir*0.5f; //move start point to middle
- Real length=m_perpDir.Length();
- m_perpDir *= 1.0f/length; //normalize it.
- m_waveDir=m_perpDir;
- m_waveDir.Rotate(PI/2); //get vector along wave travel direction.
- m_startPos -= m_waveDir*width; //move back by width of wave
- m_waveDir *= 1.3f*MAP_XY_FACTOR; //travel 4 units
- m_startPos -= m_waveDir; //move start point down away from shoreline
- m_x=WATER_STRIP_X;
- m_y=WATER_STRIP_Y;
- m_elapsedMs=0;
- m_initialVelocity=0.001f*MAP_XY_FACTOR; //velocity per ms
- m_totalMs=m_waveDir.Length()/m_initialVelocity;
- m_fadeMs = 3000; //time for wave to fade out after it stops on beach
-
- m_stageZeroTexture=WW3DAssetManager::Get_Instance()->Get_Texture(texturename);
-}
-
-//=============================================================================
-// WaterTracksObj::update
-//=============================================================================
-/** Update state of object - advance animations and other states.
- */
-//=============================================================================
-Int WaterTracksObj::update(Int msElapsed)
-{
- return TRUE; //assume we had an update
-}
-
-#define waveInitialV = 0.01f
-#define waveAcceleration = -0.01f
-
-//=============================================================================
-// WaterTracksObj::render
-//=============================================================================
-/** Draws the object in it's current state.
- */
-//=============================================================================
-
-Int WaterTracksObj::render(DX8VertexBufferClass *vertexBuffer, Int batchStart)
-{
- // TheSuperHackers @tweak The wave movement time step is now decoupled from the render update.
- m_elapsedMs += TheFramePacer->getLogicTimeStepMilliseconds();
-
- VertexFormatXYZDUV1 *vb;
- Vector2 waveTailOrigin,waveFrontOrigin;
- Real ooWaveDirLen=1.0f/m_waveDir.Length(); //one over length
- Real waterHeight;
- Real waveAlpha;
- Real widthFrac;
- Real heightFrac;
-
- if (batchStart < (WATER_VB_PAGES*WATER_STRIP_X*WATER_STRIP_Y-m_x*m_y))
- { //we have room in current VB, append new verts
- if(vertexBuffer->Get_DX8_Vertex_Buffer()->Lock(batchStart*vertexBuffer->FVF_Info().Get_FVF_Size(),m_x*m_y*vertexBuffer->FVF_Info().Get_FVF_Size(),(unsigned char**)&vb,D3DLOCK_NOOVERWRITE) != D3D_OK)
- return batchStart;
- }
- else
- { //ran out of room in last VB, request a substitute VB.
- if(vertexBuffer->Get_DX8_Vertex_Buffer()->Lock(0,m_x*m_y*vertexBuffer->FVF_Info().Get_FVF_Size(),(unsigned char**)&vb,D3DLOCK_DISCARD) != D3D_OK)
- return batchStart;
- batchStart=0; //reset start of page to first vertex
- }
-
- //Adjust wave position in a non-linear way so that it slows down as it hits the target. Using 1/4 sine wave
- //seems to work okay since it maxes out at 1.0 at our final position.
- //Real timeFrac=(Real)m_elapsedMs/(Real)m_totalMs;//sinf(0.5f*3.14159f*(Real)m_elapsedMs/(Real)m_totalMs);
-
- //Real displacement=m_elapsedMs*waveInitialV+0.5*waveAcceleration*m_elapsed*m_elapsed;
-
- heightFrac=1.0f;
- widthFrac = 1.0f;
-
- if (m_type == WaveTypeStationary)
- { //stationary wave
- waveFrontOrigin = m_startPos;
- waveFrontOrigin -= m_perpDir*m_waveFinalWidth*0.5f; //offset to left edge of wave
- waveTailOrigin = waveFrontOrigin - m_waveFinalHeight * ooWaveDirLen*m_waveDir;
- waveAlpha = 0.0f;
-
- if (m_elapsedMs >= m_totalMs)
- m_elapsedMs = 0; //done with effect*/
- if (m_elapsedMs > (m_timeToReachBeach + m_timeToStop -1000 + m_fadeMs))
- { //fading out
- waveAlpha = m_elapsedMs-(m_timeToReachBeach + m_timeToStop - 1000 +m_fadeMs);//(m_totalMs-m_timeToRetreat -m_fadeMs - m_elapsedMs)/m_fadeMs;
- waveAlpha = waveAlpha / m_timeToRetreat;
- waveAlpha = 1.0f - waveAlpha;
- if (waveAlpha < 0.0f)
- waveAlpha = 0.0f;
- }
- else
- if (m_elapsedMs > (m_timeToReachBeach + m_timeToStop - 1000))
- { //start fading up
-
- waveAlpha = m_elapsedMs-(m_timeToReachBeach + m_timeToStop - 1000);//(m_totalMs-m_timeToRetreat -m_fadeMs - m_elapsedMs)/m_fadeMs;
- waveAlpha = waveAlpha / m_fadeMs;
- if (waveAlpha > 1.0f)
- waveAlpha = 1.0f;
- }
- }
- else
- { //moving wave
-
- //get coordinate of top left of wave strip
- if (m_elapsedMs < m_timeToReachBeach)
- { //wave has not reached beach yet so position only depends on velocity
- waveAlpha = m_elapsedMs / m_timeToReachBeach;
- widthFrac = waveAlpha;
- widthFrac=(m_waveInitialWidth + widthFrac* (m_waveFinalWidth-m_waveInitialWidth))/m_waveFinalWidth;
-
- waveFrontOrigin = m_startPos + m_initialVelocity*m_elapsedMs*ooWaveDirLen*m_waveDir;
- waveFrontOrigin -= m_perpDir*m_waveFinalWidth*0.5f*widthFrac; //offset to left edge of wave
- //Tail of wave will be behind the front by fixed amount.
- waveTailOrigin = waveFrontOrigin - m_waveInitialHeight * ooWaveDirLen*m_waveDir;
- }
- else //wave has reached beach and is decelerating
- if (m_elapsedMs < m_totalMs)
- { waveAlpha = 1.0f;
- widthFrac = 1.0f;
- //Get position of wave when it hit the beach
- waveFrontOrigin = m_startPos + m_initialVelocity*m_timeToReachBeach*ooWaveDirLen*m_waveDir;
- waveTailOrigin = waveFrontOrigin; //store position for calculating tail position
- //Add movement after it hit the beach
- Real elapsedMs=m_elapsedMs - m_timeToReachBeach;
- waveFrontOrigin += (m_initialVelocity*elapsedMs+0.5f*m_frontSlowDownAcc*elapsedMs*elapsedMs)*ooWaveDirLen*m_waveDir;
- waveFrontOrigin -= m_perpDir*m_waveFinalWidth*0.5f*widthFrac; //offset to left edge of wave
-
- Real timeSinceBacktrack = m_elapsedMs - m_timeToReachBeach - m_timeToStop;
- if (timeSinceBacktrack < 0)
- timeSinceBacktrack = 0;
- waveAlpha = timeSinceBacktrack/m_fadeMs;
- if (waveAlpha > 1.0f)
- waveAlpha = 1.0f;
-
- waveAlpha = 1.0f - waveAlpha;
-
- //Get position of tail when front hits the beach.
- waveTailOrigin -= m_waveInitialHeight * ooWaveDirLen*m_waveDir;
-
- if (m_elapsedMs > (m_timeToReachBeach+m_timeToStop+m_timeToCompress))
- { elapsedMs=elapsedMs; ///@todo: bug?
- waveTailOrigin += (0.5f*m_backSlowDownAcc*(m_timeToStop+m_timeToCompress)*(m_timeToStop+m_timeToCompress))*ooWaveDirLen*m_waveDir;
- //get time since wave should have stopped moving forward
- Real newElapsed = m_elapsedMs - (m_timeToReachBeach+m_timeToStop+m_timeToCompress);
- waveTailOrigin += (0.5f*m_frontSlowDownAcc*newElapsed*newElapsed)*ooWaveDirLen*m_waveDir;
- }
- else
- // if (m_elapsedMs < (m_totalMs-m_timeToRetreat))
- //find position of tail including slowdown after it hit the beach
- // waveTailOrigin += (m_initialVelocity*elapsedMs+0.5f*m_backSlowDownAcc*elapsedMs*elapsedMs)*ooWaveDirLen*m_waveDir;
- waveTailOrigin += (0.5f*m_backSlowDownAcc*elapsedMs*elapsedMs)*ooWaveDirLen*m_waveDir;
-
- waveTailOrigin -= m_perpDir*m_waveFinalWidth*0.5f*widthFrac; //offset to left edge of wave
- }
- else
- { m_elapsedMs = 0;
- waveAlpha = m_elapsedMs / m_timeToReachBeach;
- widthFrac = waveAlpha;
- widthFrac=(m_waveInitialWidth + widthFrac* (m_waveFinalWidth-m_waveInitialWidth))/m_waveFinalWidth;
-
- waveFrontOrigin = m_startPos + m_initialVelocity*m_elapsedMs*ooWaveDirLen*m_waveDir;
- waveFrontOrigin -= m_perpDir*m_waveFinalWidth*0.5f*widthFrac; //offset to left edge of wave
- //Tail of wave will be behind the front by fixed amount.
- waveTailOrigin = waveFrontOrigin - m_waveInitialHeight * ooWaveDirLen*m_waveDir;
- }
- }
-
- //First insert tail of wave:
- Vector2 testPoint(waveTailOrigin);
- TheTerrainLogic->isUnderwater(testPoint.X,testPoint.Y,&waterHeight);
- vb->x= testPoint.X;
- vb->y= testPoint.Y;
- vb->z=waterHeight+1.5f;
- vb->diffuse=(REAL_TO_INT(waveAlpha*255.0f)<<24) |0xffffff;
- if (m_flipU)
- vb->u1=1;
- else
- vb->u1=0;
- vb->v1=0;
- vb++;
- testPoint.Set(waveTailOrigin + m_perpDir*m_waveFinalWidth*widthFrac);
- vb->x= testPoint.X;
- vb->y= testPoint.Y;
- vb->z=waterHeight+1.5f;
- vb->diffuse=(REAL_TO_INT(waveAlpha*255.0f)<<24) |0xffffff;
- if (m_flipU)
- vb->u1=0.0f;
- else
- vb->u1=1.0f;
- vb->v1=0;
- vb++;
- //insert front of wave
- testPoint.Set(waveFrontOrigin);
- vb->x= testPoint.X;
- vb->y= testPoint.Y;
- vb->z=waterHeight+1.5f;
- vb->diffuse=(REAL_TO_INT(waveAlpha*255.0f)<<24) |0xffffff;
- if (m_flipU)
- vb->u1=1;
- else
- vb->u1=0;
- vb->v1=1.0f;
- vb++;
- testPoint.Set(waveFrontOrigin + m_perpDir*m_waveFinalWidth*widthFrac);
- vb->x= testPoint.X;
- vb->y= testPoint.Y;
- vb->z=waterHeight+1.5f;
- vb->diffuse=(REAL_TO_INT(waveAlpha*255.0f)<<24) |0xffffff;
- if (m_flipU)
- vb->u1=0;
- else
- vb->u1=1.0f;
- vb->v1=1.0f;
- vb++;
-
- vertexBuffer->Get_DX8_Vertex_Buffer()->Unlock();
-
- Int idxCount=(m_y-1)*(m_x*2+2) - 2; //index count
-
- DX8Wrapper::Set_Index_Buffer(TheWaterTracksRenderSystem->m_indexBuffer,batchStart);
- DX8Wrapper::Draw_Strip(0,idxCount-2,0,m_x*m_y); //there are always n-2 primitives for n index strip.
-
- return batchStart+m_x*m_y; //return new offset into unused area of vertex buffer
-}
-
-//=============================================================================
-//WaterTracksRenderSystem::bindTrack
-//=============================================================================
-/** Grab a track from the free store. If no free tracks exist, return NULL.
- As long as a track is bound to an object (like a tank) it is ready to accept
- updates with additional edges. Once it is unbound, it will expire and return
- to the free store once all tracks have faded out.
-*/
-//=============================================================================
-WaterTracksObj *WaterTracksRenderSystem::bindTrack(waveType type)
-{
- WaterTracksObj *mod,*nextmod,*prevmod;
-
- mod = m_freeModules;
- if( mod )
- {
- // take module off the free list
- if( mod->m_nextSystem )
- mod->m_nextSystem->m_prevSystem = mod->m_prevSystem;
- if( mod->m_prevSystem )
- mod->m_prevSystem->m_nextSystem = mod->m_nextSystem;
- else
- m_freeModules = mod->m_nextSystem;
-
- mod->m_type=type;
-
- // put module on the used list (sorted next to similar types)
- nextmod=NULL,prevmod=NULL;
- for( nextmod = m_usedModules; nextmod; prevmod=nextmod,nextmod = nextmod->m_nextSystem )
- {
- if (nextmod->m_type==type)
- { //found start of other shadows using same texture, insert new shadow here.
- mod->m_nextSystem=nextmod;
- mod->m_prevSystem=prevmod;
- nextmod->m_prevSystem=mod;
- if (prevmod)
- { prevmod->m_nextSystem=mod;
- }
- else
- m_usedModules=mod;
- break;
- }
- }
-
- if (nextmod==NULL)
- { //shadow with new texture. Add to top of list.
- mod->m_nextSystem = m_usedModules;
- if (m_usedModules)
- m_usedModules->m_prevSystem=mod;
- m_usedModules = mod;
- }
-
- mod->m_bound=true;
- }
-
- #ifdef SYNC_WAVES
- nextmod=m_usedModules;
-
- while(nextmod)
- {
- nextmod->m_elapsedMs=nextmod->m_initTimeOffset;
- nextmod=nextmod->m_nextSystem;
- }
- #endif
-
- return mod;
-}
-
-//=============================================================================
-//WaterTracksRenderSystem::unbindTrack
-//=============================================================================
-/** Called when an object (i.e Tank) will not lay down any more tracks and
-doesn't need this object anymore. The track-laying object will be returned
-to pool of available tracks as soon as any remaining track edges have faded out.
-*/
-//=============================================================================
-void WaterTracksRenderSystem::unbindTrack( WaterTracksObj *mod )
-{
- //this object should return to free store as soon as there is nothing
- //left to render.
- mod->m_bound=false;
- releaseTrack(mod);
-}
-
-//=============================================================================
-//WaterTracksRenderSystem::releaseTrack
-//=============================================================================
-/** Returns a track laying object to free store to be used again later.
-*/
-void WaterTracksRenderSystem::releaseTrack( WaterTracksObj *mod )
-{
- if (mod==NULL)
- return;
-
- assert(mod->m_bound == false);
-
- // remove module from used list
- if( mod->m_nextSystem )
- mod->m_nextSystem->m_prevSystem = mod->m_prevSystem;
- if( mod->m_prevSystem )
- mod->m_prevSystem->m_nextSystem = mod->m_nextSystem;
- else
- m_usedModules = mod->m_nextSystem;
-
- // add module to free list
- mod->m_prevSystem = NULL;
- mod->m_nextSystem = m_freeModules;
- if( m_freeModules )
- m_freeModules->m_prevSystem = mod;
- m_freeModules = mod;
- mod->freeWaterTracksResources();
-}
-
-//=============================================================================
-// WaterTracksRenderSystem::WaterTracksRenderSystem
-//=============================================================================
-/** Constructor. Just nulls out some variables. */
-//=============================================================================
-WaterTracksRenderSystem::WaterTracksRenderSystem()
-{
- m_usedModules = NULL;
- m_freeModules = NULL;
- m_indexBuffer = NULL;
- m_vertexMaterialClass = NULL;
- m_vertexBuffer = NULL;
- m_stripSizeX=WATER_STRIP_X;
- m_stripSizeY=WATER_STRIP_Y;
- m_batchStart=0;
- TheWaterTracksRenderSystem = this; //only allow one instance of this object.
-}
-
-//=============================================================================
-// WaterTracksRenderSystem::~WaterTracksRenderSystem
-//=============================================================================
-/** Destructor. Free all pre-allocated track laying render objects*/
-//=============================================================================
-WaterTracksRenderSystem::~WaterTracksRenderSystem( void )
-{
-
- // free all data
- shutdown();
-
- m_vertexMaterialClass=NULL;
-
-}
-
-//=============================================================================
-// WaterTracksRenderSystem::ReAcquireResources
-//=============================================================================
-/** (Re)allocates all W3D assets after a reset.. */
-//=============================================================================
-void WaterTracksRenderSystem::ReAcquireResources(void)
-{
- Int i,j,k;
-// const Int numModules=16; ///@todo: Get a value out of gdf
-
- // just for paranoia's sake.
- REF_PTR_RELEASE(m_indexBuffer);
- REF_PTR_RELEASE(m_vertexBuffer);
-
- //Will need m_y-1 strips, each of length m_x*2.
- //Will also need 2 extra indices to connect each strip to next one (except last strip)
- //Total index buffer size = (m_y-1)*(m_x*2+2) - 2 (drop the extra 2 indices from last strip)
-
- Int idxCount=(m_stripSizeY-1)*(m_stripSizeX*2+2) - 2;
-
- m_indexBuffer=NEW_REF(DX8IndexBufferClass,(idxCount));
-
- // Fill up the IB
- {
- DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexBuffer);
- UnsignedShort *ib=lockIdxBuffer.Get_Index_Array();
-
- for (i=0,j=0,k=0; im_waterPositionZ;
-
- ReAcquireResources();
- //go with a preset material for now.
- m_vertexMaterialClass=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
-
- //use a multi-texture shader:
- m_shaderClass = ShaderClass::_PresetAlphaShader;
- m_shaderClass.Set_Cull_Mode(ShaderClass::CULL_MODE_DISABLE); //water should be visible from both sides
-
- // we cannot initialize a system that is already initialized
- if( m_freeModules || m_usedModules )
- {
-
- // system already online!
- assert( 0 );
- return;
-
- }
-
- // allocate our modules for this system
- for( i = 0; i < numModules; i++ )
- {
-
- mod = NEW WaterTracksObj;
-
- if( mod == NULL )
- {
-
- // unable to allocate modules needed
- assert( 0 );
- return;
-
- }
-
- mod->m_prevSystem = NULL;
- mod->m_nextSystem = m_freeModules;
- if( m_freeModules )
- m_freeModules->m_prevSystem = mod;
- m_freeModules = mod;
-
- }
-
-}
-
-void WaterTracksRenderSystem::reset(void)
-{
- WaterTracksObj *nextMod,*mod;
-
- //release unbound tracks that may still be fading out
- mod=m_usedModules;
-
- while(mod)
- {
- nextMod=mod->m_nextSystem;
- mod->m_bound=false;
- releaseTrack(mod);
-
- mod = nextMod;
- }
-
-
- // free all attached things and used modules
- assert( m_usedModules == NULL );
-}
-
-//=============================================================================
-// WaterTracksRenderSystem::shutdown
-//=============================================================================
-/** Shutdown and free all memory for this system */
-//=============================================================================
-void WaterTracksRenderSystem::shutdown( void )
-{
- WaterTracksObj *nextMod,*mod;
-
- //release unbound tracks that may still be fading out
- mod=m_usedModules;
-
- while(mod)
- {
- nextMod=mod->m_nextSystem;
-
- if (!mod->m_bound)
- releaseTrack(mod);
-
- mod = nextMod;
- }
-
-
- // free all attached things and used modules
- assert( m_usedModules == NULL );
-
- // free all module storage
- while( m_freeModules )
- {
-
- nextMod = m_freeModules->m_nextSystem;
- delete m_freeModules;
- m_freeModules = nextMod;
-
- }
-
- REF_PTR_RELEASE(m_indexBuffer);
- REF_PTR_RELEASE(m_vertexMaterialClass);
- REF_PTR_RELEASE(m_vertexBuffer);
-
-}
-
-//=============================================================================
-// WaterTracksRenderSystem::update
-//=============================================================================
-/** Update the state of all active track marks - fade, expire, etc. */
-//=============================================================================
-void WaterTracksRenderSystem::update()
-{
-
- static Int iLastTime=timeGetTime();
- WaterTracksObj *mod=m_usedModules,*nextMod;
-
- Int timeDiff = timeGetTime()-iLastTime;
- iLastTime += timeDiff;
-
- //first update all the tracks
- while( mod )
- {
- nextMod = mod->m_nextSystem;
-
- if (!mod->m_bound || (!mod->update(timeDiff) && !mod->m_bound))
- { //object is not longer updating and is unbound so ok to release it.
- releaseTrack(mod);
- }
-
- mod = nextMod;
- }
-}
-
-
-void TestWaterUpdate(void);
-void setFPMode( void );
-
-//=============================================================================
-// WaterTracksRenderSystem::flush
-//=============================================================================
-/** Draw all active track marks for this frame */
-//=============================================================================
-void WaterTracksRenderSystem::flush(RenderInfoClass & rinfo)
-{
-/** @todo: Optimize system by drawing tracks as triangle strips and use dynamic vertex buffer access.
-May also try rendering all tracks with one call to W3D/D3D by grouping them by texture.
-Try improving the fit to vertical surfaces like cliffs.
-*/
- Int diffuseLight;
-
- if (TheGlobalData->m_usingWaterTrackEditor)
- TestWaterUpdate();
-
- update(); //update positions of all the tracks
-
- rinfo.Camera.Apply();
-
- if (!m_usedModules || ShaderClass::Is_Backface_Culling_Inverted())
- return; //don't render track marks in reflections.
-
- //According to Nvidia there's a D3D bug that happens if you don't start with a
- //new dynamic VB each frame - so we force a DISCARD by overflowing the counter.
- m_batchStart = 0xffff;
-
- // adjust shading for time of day.
- Real shadeR, shadeG, shadeB;
- shadeR = TheGlobalData->m_terrainAmbient[0].red;
- shadeG = TheGlobalData->m_terrainAmbient[0].green;
- shadeB = TheGlobalData->m_terrainAmbient[0].blue;
- shadeR += TheGlobalData->m_terrainDiffuse[0].red/2;
- shadeG += TheGlobalData->m_terrainDiffuse[0].green/2;
- shadeB += TheGlobalData->m_terrainDiffuse[0].blue/2;
- shadeR*=255.0f;
- shadeG*=255.0f;
- shadeB*=255.0f;
-
- diffuseLight=REAL_TO_INT(shadeB) | (REAL_TO_INT(shadeG) << 8) | (REAL_TO_INT(shadeR) << 16);
-
- Matrix3D tm(1); ///set to identity
- DX8Wrapper::Set_Transform(D3DTS_WORLD,tm); //position the water surface
-
- DX8Wrapper::Set_Material(m_vertexMaterialClass);
- DX8Wrapper::Set_Shader(m_shaderClass);
-
- DX8Wrapper::Set_Vertex_Buffer(m_vertexBuffer);
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZBIAS,8);
-
- Int LastTextureType=-1;
-
- WaterTracksObj *mod=m_usedModules;
-
- while( mod )
- {
- if (LastTextureType != mod->m_type)
- DX8Wrapper::Set_Texture(0,mod->m_stageZeroTexture);
-
- Int vertsRendered=mod->render(m_vertexBuffer,m_batchStart);
-
- m_batchStart = vertsRendered; //advance past vertices already in buffer
-
- mod = mod->m_nextSystem;
- }
-
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZBIAS,0);
-}
-
-WaterTracksObj *WaterTracksRenderSystem::findTrack(Vector2 &start, Vector2 &end, waveType type)
-{
- WaterTracksObj *mod=m_usedModules;
-
- while( mod )
- {
- if (mod->m_initEndPos == end &&
- mod->m_initStartPos == start &&
- mod->m_type == type)
- return mod;
- mod = mod->m_nextSystem;
- }
- return NULL;
-}
-void WaterTracksRenderSystem::saveTracks(void)
-{
-
- if (!TheTerrainLogic)
- return;
-
- AsciiString fileName=TheTerrainLogic->getSourceFilename();
- char path[256];
-
- strlcpy(path, fileName.str(), ARRAY_SIZE(path));
- strlcat(path, ".wak", ARRAY_SIZE(path));
-
- WaterTracksObj *umod;
- Int trackCount=0;
-
- FILE *fp=fopen(path,"wb");
-
- if (fp)
- {
- umod=m_usedModules;
- while(umod)
- { if (umod->m_initTimeOffset == 0)
- { //only save the primary wave front, second layer is added automatically.
- fwrite(&umod->m_initStartPos,sizeof(umod->m_startPos),1,fp);
- fwrite(&umod->m_initEndPos,sizeof(umod->m_perpDir),1,fp);
- fwrite(&umod->m_type,sizeof(umod->m_type),1,fp);
- // fwrite(&umod->m_initTimeOffset,sizeof(umod->m_initTimeOffset),1,fp);
- trackCount++;
- }
- umod=umod->m_nextSystem;
- }
- fwrite(&trackCount,sizeof(trackCount),1,fp);
- fclose(fp);
- }
-}
-
-void WaterTracksRenderSystem::loadTracks(void)
-{
-
- if (!TheTerrainLogic)
- return;
-
- AsciiString fileName=TheTerrainLogic->getSourceFilename();
- char path[256];
-
- strlcpy(path, fileName.str(), ARRAY_SIZE(path));
- strlcat(path, ".wak", ARRAY_SIZE(path));
-
- File *file = TheFileSystem->openFile(path, File::READ | File::BINARY);
- WaterTracksObj *umod;
- Int trackCount=0;
- Int flipU=0;
- Vector2 startPos,endPos;
- waveType wtype;
-
- if (file)
- {
- file->seek(-4,File::END);
- file->read(&trackCount,sizeof(trackCount));
- file->seek(0, File::START);
- for (Int i=0; iread(&startPos,sizeof(startPos));
- file->read(&endPos,sizeof(endPos));
- file->read(&wtype,sizeof(wtype));
- //Check if this track already exists.
- if (findTrack(startPos,endPos,wtype))
- { i++;
- goto tryagain;
- }
-
- umod=TheWaterTracksRenderSystem->bindTrack(wtype);
- if (umod)
- { //umod->init(1.5f*MAP_XY_FACTOR,Vector2(0,0),Vector2(1,1),"wave256.tga");
- flipU ^= 1; //toggle flip state
- umod->init(waveTypeInfo[wtype].m_finalHeight,waveTypeInfo[wtype].m_finalWidth,startPos,endPos,waveTypeInfo[wtype].m_textureName,0);
- umod->m_flipU=flipU;
-
- if (waveTypeInfo[wtype].m_secondWaveTimeOffset) //check if we need a second wave to follow
- {
- umod=TheWaterTracksRenderSystem->bindTrack(wtype);
- if (umod)
- {
- umod->init(waveTypeInfo[wtype].m_finalHeight,waveTypeInfo[wtype].m_finalWidth,startPos,endPos,waveTypeInfo[wtype].m_textureName,waveTypeInfo[wtype].m_secondWaveTimeOffset);
- umod->m_flipU = !flipU;
- }
- }
- }
- }
- file->close();
- }
-
-#if 0 //Obsolete code used before there was another editor to place waves.
- //Look for all waypoints that start with "waveStart_"
- for (Waypoint *way = TheTerrainLogic->getFirstWaypoint(); way; way = way->getNext())
- {
- if (way->getName().startsWith("waveStart_") && way->getNumLinks() == 1)
- {
- Waypoint *nextWay = way->getLink(0);
- Coord3D startPos = *way->getLocation();
- Coord3D endPos = *nextWay->getLocation();
-
- //initialize surface layer (1)
- WaterTracksObj *umod=TheWaterTracksRenderSystem->bindTrack(1);
- if (umod)
- {
- umod->init(DEFAULT_FINAL_WAVE_HEIGHT,DEFAULT_FINAL_WAVE_WIDTH,Vector2(startPos.x,startPos.y),Vector2(endPos.x,endPos.y),"wave1.tga",0);
- }
-/*
- //initialize foam layer (0)
- umod=TheWaterTracksRenderSystem->bindTrack(0);
- if (umod)
- {
- umod->init(2.5f*MAP_XY_FACTOR,5.0f*MAP_XY_FACTOR,Vector2(startPos.x,startPos.y),Vector2(endPos.x,endPos.y),"wave2.tga");
-// umod->m_fadeMs += 1500; //take extra 500 ms to fade out wave.
-// umod->m_retreatFrac = 1.0f; //don't move wave back after it hits final position.
- }*/
- }
- }
-#endif
-}
-
-/**@todo: this is a quick hack for adding/removing/testing breaking waves inside the client.
-Will need to move this code to an external editor at some pont. */
-#include "GameClient/Display.h"
-
-extern HWND ApplicationHWnd;
-
-//TODO: Fix editor so it actually draws the wave segment instead of line while editing
-//Could freeze all the water while editing? Or keep setting elapsed time on current segment.
-//Have to make it so seamless merge of segments at final position.
-static void TestWaterUpdate(void)
-{
- static Int doInit=1;
- static WaterTracksObj *track=NULL,*track2=NULL;
- static Int trackEditMode=0;
- static waveType currentWaveType = WaveTypeOcean;
- POINT screenPoint;
- POINT endPoint;
- static POINT mouseAnchor;
- static Int haveStart=0;
- static Int haveEnd=0;
- static Coord3D terrainPointStart,terrainPointEnd;
- //flags to tell me when the user lets go of a key
- static Int trackEditModeReset=1;
- static Int addPointReset=1;
- static Int deleteTrackReset=1;
- static Int saveTracksReset=1;
- static Int loadTracksReset=1;
- static Int changeTypeReset=1;
-
- pauseWaves=FALSE;
-
- if (doInit)
- { //create the system
- doInit=0;
-
-// TheWaterTracksRenderSystem = NEW (WaterTracksRenderSystem);
-// TheWaterTracksRenderSystem->init();
-
- //create a dummy track
-// track=TheWaterTracksRenderObjClassSystem->bindTrack(0);
-// track->init(1.5f,8.0f,Vector2(147.0f,67.0f),Vector2(146.9f,68.6f),"wave2.tga");
-
-// track=TheWaterTracksRenderObjClassSystem->bindTrack(0);
-// track->init(1.5f,8.0f,Vector2(139.0f,66.0f),Vector2(138.8f,67.6f),"wave2.tga");
- }
-
- if (GetAsyncKeyState(VK_F5) & 0x8001) //check if F5 pressed since last call
- {
- if (trackEditModeReset)
- {
- if (trackEditMode)
- {
- UnicodeString string;
- string.format(L"Leaving Water Track Edit Mode");
- TheInGameUI->message(string);
- }
- else
- {
- UnicodeString string;
- string.format(L"Entering Water Track Edit Mode");
- TheInGameUI->message(string);
-
- string.format(L"Wave Type: %hs",waveTypeInfo[currentWaveType].m_waveTypeName);
- TheInGameUI->message(string);
- }
-
- trackEditMode ^= 1; //toggle editor on/off
-
- if (trackEditMode == 0)
- { //editor was turned off, save changes
- haveStart=0;
- haveEnd=0;
- }
- trackEditModeReset=0;
- }
- }
- else
- trackEditModeReset=1;
-
- if (trackEditMode)
- { //we are in wave edit mode
-
- if (GetCursorPos(&screenPoint)) //read mouse position
- {
- ScreenToClient( ApplicationHWnd, &screenPoint);
-
- if (GetAsyncKeyState(VK_F6) & 0x8001)
- {
- if (addPointReset)
- {
- if (!haveStart)
- { mouseAnchor=screenPoint;
- TheTacticalView->screenToTerrain( (ICoord2D *)&screenPoint, &terrainPointStart);
- haveStart=1;
- UnicodeString string;
- string.format(L"Added Start");
- TheInGameUI->message(string);
- }
- else
- {
- endPoint=screenPoint;
- TheTacticalView->screenToTerrain( (ICoord2D *)&screenPoint, &terrainPointEnd);
- haveEnd=1;
- //Have enough info to add a wave now
- track=TheWaterTracksRenderSystem->bindTrack(currentWaveType);
- if (track)
- {// track->init(1.5f*MAP_XY_FACTOR,Vector2(terrainPointStart.x,terrainPointStart.y),Vector2(terrainPointEnd.x,terrainPointEnd.y),"wave256.tga");
- //Generate valid input for the 2 points
- Vector2 startPoint(terrainPointStart.x,terrainPointStart.y);
- Vector2 endPoint(terrainPointEnd.x,terrainPointEnd.y);
- Vector2 midPoint = endPoint - startPoint;
- Vector2 m_perpDir = midPoint;
- m_perpDir.Rotate(1.57079632679f); //get vector perpendicular to wave motion.
- m_perpDir.Normalize();
- midPoint = startPoint + (midPoint)*0.5f;
- Vector2 dirMidPoint = midPoint + m_perpDir;
-
- track->init(waveTypeInfo[currentWaveType].m_finalHeight,waveTypeInfo[currentWaveType].m_finalWidth,Vector2(midPoint.X,midPoint.Y),Vector2(dirMidPoint.X,dirMidPoint.Y),waveTypeInfo[currentWaveType].m_textureName,0);
-
- if (waveTypeInfo[currentWaveType].m_secondWaveTimeOffset)
- {
- //Add a second track slightly behind this one
- track2=TheWaterTracksRenderSystem->bindTrack(currentWaveType);
- if (track2)
- {
- track2->init(waveTypeInfo[currentWaveType].m_finalHeight,waveTypeInfo[currentWaveType].m_finalWidth,Vector2(midPoint.X,midPoint.Y),Vector2(dirMidPoint.X,dirMidPoint.Y),waveTypeInfo[currentWaveType].m_textureName,waveTypeInfo[currentWaveType].m_secondWaveTimeOffset);
- }
- }
-
- UnicodeString string;
- string.format(L"Added End");
- TheInGameUI->message(string);
- }
- haveStart=0; //reset for next segment
- haveEnd=0;
- }
- addPointReset=0;
- }
- }
- else
- addPointReset=1;
-
- if (GetAsyncKeyState(VK_DELETE) & 0x8001)
- { //delete last segment added
- if (deleteTrackReset && track)
- { deleteTrackReset=0;
- TheWaterTracksRenderSystem->unbindTrack(track);
- if (track2)
- TheWaterTracksRenderSystem->unbindTrack(track2);
- haveStart=0; //reset for next segment
- haveEnd=0;
- track=NULL;
- track2=NULL;
- }
- }
- else
- deleteTrackReset=1;
-
- if (GetAsyncKeyState(VK_INSERT) & 0x8001)
- { //change current wave type
- if (changeTypeReset)
- { changeTypeReset=0;
- currentWaveType = (waveType)((Int)currentWaveType + 1);
- if (currentWaveType > WaveTypeLast)
- currentWaveType = WaveTypeFirst;
-
- UnicodeString string;
- string.format(L"Wave Type: %hs",waveTypeInfo[currentWaveType].m_waveTypeName);
- TheInGameUI->message(string);
- }
- }
- else
- changeTypeReset=1;
-
- if (GetAsyncKeyState(VK_F7) & 0x8001)
- { //save all segments added
- if (saveTracksReset)
- { saveTracksReset=0;
- TheWaterTracksRenderSystem->saveTracks();
- haveStart=0; //reset for next segment
- haveEnd=0;
- track=NULL;
- track2=NULL;
- UnicodeString string;
- string.format(L"Saved Tracks");
- TheInGameUI->message(string);
- }
- }
- else
- saveTracksReset=1;
-
- if (GetAsyncKeyState(VK_F8) & 0x8001)
- { //load tracks for map
- if (loadTracksReset)
- { loadTracksReset=0;
- TheWaterTracksRenderSystem->reset();
- TheWaterTracksRenderSystem->loadTracks();
- haveStart=0; //reset for next segment
- haveEnd=0;
- track=NULL;
- track2=NULL;
- UnicodeString string;
- string.format(L"Loaded Tracks");
- TheInGameUI->message(string);
- }
- }
- else
- saveTracksReset=1;
- };
-
- if (haveStart && !haveEnd)
- { //draw a guide line
-// View *tacticalView = TheDisplay->getFirstView();
-// tacticalView->worldToScreen( &m_moveHint[i].pos, &pos );
-
- TheTacticalView->screenToTerrain( (ICoord2D *)&screenPoint, &terrainPointEnd);
- //Check if point is within correct distance of start
- Real xdiff=terrainPointEnd.x - terrainPointStart.x;
- Real ydiff=terrainPointEnd.y - terrainPointStart.y;
- if (sqrt (xdiff * xdiff + ydiff * ydiff) <= waveTypeInfo[currentWaveType].m_finalWidth)
- { TheDisplay->drawLine(mouseAnchor.x, mouseAnchor.y, screenPoint.x, screenPoint.y,1,0xffccccff);
- DX8Wrapper::Invalidate_Cached_Render_States();
- ShaderClass::Invalidate();
- }
-
- pauseWaves=TRUE;
-
-// char buffer[64];
-// sprintf(buffer,"\n%d,%d,%d,%d",mouseAnchor.x, mouseAnchor.y, screenPoint.x, screenPoint.y);
-// OutputDebugString (buffer);
- }
- }
-}
diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvp
deleted file mode 100644
index 6468dcd0df3..00000000000
--- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvp
+++ /dev/null
@@ -1,54 +0,0 @@
-;
-; Command & Conquer Generals(tm)
-; Copyright 2025 Electronic Arts Inc.
-;
-; This program is free software: you can redistribute it and/or modify
-; it under the terms of the GNU General Public License as published by
-; the Free Software Foundation, either version 3 of the License, or
-; (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with this program. If not, see .
-;
-
-;////////////////////////////////////////////////////////////////////////////////
-;// //
-;// (c) 2001-2003 Electronic Arts Inc. //
-;// //
-;////////////////////////////////////////////////////////////////////////////////
-
-; Waves pixel shader
-; Kenny Mitchell April 2001
-; Modified July 2001 Mark Wilczynski
-
-; Declare pixel shader version 1.1
-ps.1.1
-
-; Define t0 as a standard 3-vector from bumpmap
-tex t0
-
-; Perform EMBM to get a local normal bump reflection.
-texbem t1, t0 ; compute new (u,v) values
-
-#ifndef DO_WATER_ALPHA_TEXTURE
-
-; result goes in output color multiplied by diffuse
-mul r0, t1, v0
-
-#else
-
-;alternate version which uses a third texture which provides per-pixel alpha.
-; result goes in output color multiplied by diffuse
-tex t2 ; get alpha texture
-mul r0.rgb, t1, v0
-+mul r0.a, t2, v0
-
-#endif
-
-
-
diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvv b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvv
deleted file mode 100644
index c33486962fc..00000000000
--- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvv
+++ /dev/null
@@ -1,72 +0,0 @@
-;
-; Command & Conquer Generals(tm)
-; Copyright 2025 Electronic Arts Inc.
-;
-; This program is free software: you can redistribute it and/or modify
-; it under the terms of the GNU General Public License as published by
-; the Free Software Foundation, either version 3 of the License, or
-; (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with this program. If not, see .
-;
-
-;////////////////////////////////////////////////////////////////////////////////
-;// //
-;// (c) 2001-2003 Electronic Arts Inc. //
-;// //
-;////////////////////////////////////////////////////////////////////////////////
-
-; Waves vertex shader
-; Kenny Mitchell April 2001
-; Modified July 2001 Mark Wilczynski
-
-#define CV_ZERO 0
-#define CV_ONE 1
-
-#define CV_WORLDVIEWPROJ_0 2
-#define CV_WORLDVIEWPROJ_1 3
-#define CV_WORLDVIEWPROJ_2 4
-#define CV_WORLDVIEWPROJ_3 5
-
-#define CV_TEXPROJ_0 6
-#define CV_TEXPROJ_1 7
-#define CV_TEXPROJ_2 8
-#define CV_TEXPROJ_3 9
-#define CV_PATCH_SCALE_OFFSET 10
-
-#define V_POSITION v0
-#define V_DIFFUSE v1
-#define V_TEXTURE v2
-#define V_TEXTURE2 v3
-
-vs.1.1
-
-; Below is Kenny's new optimized version
-; Transform position to clip space and output it
-dp4 r0.x, V_POSITION, c[CV_WORLDVIEWPROJ_0]
-dp4 r0.y, V_POSITION, c[CV_WORLDVIEWPROJ_1]
-dp4 r0.z, V_POSITION, c[CV_WORLDVIEWPROJ_2]
-dp4 r0.w, V_POSITION, c[CV_WORLDVIEWPROJ_3]
-
-mov oPos, r0
-
-; get 1/w and multiply it onto x and y
-rcp r1.w, r0.w
-mul r1.xy, r0.xy, r1.w
-
-; scale/flip/offset tex coords to screen
-mad oT1.xy, r1.xy, c[CV_TEXPROJ_0].xy,c[CV_TEXPROJ_0].zw
-
-mov oT0, V_TEXTURE
-mov oD0, V_DIFFUSE
-
-#ifdef DO_WATER_ALPHA_TEXTURE
-;generate uv coordinates for a third texture (alpha channel)
-mad oT2.xy,v0.xz,c[CV_PATCH_SCALE_OFFSET].zw,c[CV_PATCH_SCALE_OFFSET].xy
-#endif
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
index 01148543c86..0a51c6d9648 100644
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
+++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
@@ -15,8 +15,8 @@ set(WW3D2_SRC
#assetstatus.h
#bitmaphandler.cpp
#bitmaphandler.h
- bmp2d.cpp
- bmp2d.h
+ #bmp2d.cpp
+ #bmp2d.h
boxrobj.cpp
boxrobj.h
#bwrender.cpp
@@ -54,8 +54,8 @@ set(WW3D2_SRC
#dx8polygonrenderer.h
dx8renderer.cpp
dx8renderer.h
- dx8texman.cpp
- dx8texman.h
+ #dx8texman.cpp
+ #dx8texman.h
dx8vertexbuffer.cpp
dx8vertexbuffer.h
#dx8webbrowser.cpp
@@ -104,8 +104,8 @@ set(WW3D2_SRC
mapper.h
#matinfo.cpp
#matinfo.h
- matpass.cpp
- matpass.h
+ #matpass.cpp
+ #matpass.h
matrixmapper.cpp
matrixmapper.h
mesh.cpp
@@ -195,18 +195,18 @@ set(WW3D2_SRC
#stripoptimizer.h
#surfaceclass.cpp
#surfaceclass.h
- texproject.cpp
- texproject.h
+ #texproject.cpp
+ #texproject.h
#textdraw.cpp
#textdraw.h
- texture.cpp
- texture.h
- texturefilter.cpp
- texturefilter.h
- textureloader.cpp
- textureloader.h
- texturethumbnail.cpp
- texturethumbnail.h
+ #texture.cpp
+ #texture.h
+ #texturefilter.cpp
+ #texturefilter.h
+ #textureloader.cpp
+ #textureloader.h
+ #texturethumbnail.cpp
+ #texturethumbnail.h
vertmaterial.cpp
vertmaterial.h
#visrasterizer.cpp
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp
index 40931555aa9..2afb91369db 100644
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp
+++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp
@@ -16,7 +16,7 @@
** along with this program. If not, see .
*/
-/* $Header: /Commando/Code/ww3d2/assetmgr.cpp 36 8/24/01 3:23p Jani_p $ */
+/* $Header: /Commando/Code/ww3d2/assetmgr.cpp 43 11/01/01 1:11a Jani_p $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
@@ -25,12 +25,16 @@
* *
* $Archive:: /Commando/Code/ww3d2/assetmgr.cpp $*
* *
- * Author:: Greg_h *
+ * Org Author:: Greg_h *
* *
- * $Modtime:: 8/22/01 6:54p $*
+ * Author : Kenny Mitchell *
* *
- * $Revision:: 36 $*
+ * $Modtime:: 08/05/02 10:14a $*
* *
+ * $Revision:: 46 $*
+ * *
+ * 06/27/02 KM Texture class abstraction *
+ * 08/05/02 KM Texture class redesign (revisited)
*---------------------------------------------------------------------------------------------*
* Functions: *
* WW3DAssetManager::WW3DAssetManager -- Constructor *
@@ -1040,46 +1044,6 @@ HTreeClass * WW3DAssetManager::Get_HTree(const char * name)
return htree;
}
-/***********************************************************************************************
- * WW3DAssetManager::Get_Bumpmap_Based_On_Texture -- Generate a bumpmap from texture. The *
- * resulting texture is stored to the hash table so that any further requests will share it. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/31/2001 NH : Created. *
- *=============================================================================================*/
-
-TextureClass* WW3DAssetManager::Get_Bumpmap_Based_On_Texture(TextureClass* texture)
-{
- WWASSERT(texture->Get_Texture_Name() && strlen(texture->Get_Texture_Name()));
- StringClass bump_name="__Bumpmap-";
- bump_name+=texture->Get_Texture_Name();
- _strlwr(bump_name.Peek_Buffer()); // lower case
-
- /*
- ** See if the texture has already been generated.
- */
-
- TextureClass* tex = TextureHash.Get(bump_name);
-
- /*
- ** Didn't have it so we have to create a new texture
- */
- if (!tex) {
- tex = NEW_REF(BumpmapTextureClass,(texture));
- tex->Set_Texture_Name(bump_name);
- TextureHash.Insert(tex->Get_Texture_Name(),tex);
- }
-
- tex->Add_Ref();
- return tex;
-}
-
/***********************************************************************************************
* WW3DAssetManager::Get_Texture -- get a TextureClass from the specified file *
* *
@@ -1127,7 +1091,7 @@ TextureClass * WW3DAssetManager::Get_Texture
** See if the texture has already been loaded.
*/
TextureClass* tex = TextureHash.Get(lower_case_name);
- if (tex && texture_format!=WW3D_FORMAT_UNKNOWN)
+ if (tex && (tex->Is_Initialized() == true) && (texture_format!=WW3D_FORMAT_UNKNOWN))
{
WWASSERT_PRINT(tex->Get_Texture_Format()==texture_format,("Texture %s has already been loaded with different format",filename));
}
@@ -1139,7 +1103,15 @@ TextureClass * WW3DAssetManager::Get_Texture
{
if (type==TextureBaseClass::TEX_REGULAR)
{
- tex = NEW_REF (TextureClass, (lower_case_name, NULL, mip_level_count, texture_format, allow_compression));
+ tex = NEW_REF (TextureClass, (lower_case_name, NULL, mip_level_count, texture_format, allow_compression, allow_reduction));
+ }
+ else if (type==TextureBaseClass::TEX_CUBEMAP)
+ {
+ tex = NEW_REF (CubeTextureClass, (lower_case_name, NULL, mip_level_count, texture_format, allow_compression, allow_reduction));
+ }
+ else if (type==TextureBaseClass::TEX_VOLUME)
+ {
+ tex = NEW_REF (VolumeTextureClass, (lower_case_name, NULL, mip_level_count, texture_format, allow_compression, allow_reduction));
}
else
{
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h
index c68dd00020d..f3f1ca83f79 100644
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h
+++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h
@@ -269,7 +269,6 @@ class WW3DAssetManager
TextureBaseClass::TexAssetType type=TextureBaseClass::TEX_REGULAR,
bool allow_reduction=true
);
- TextureClass* Get_Bumpmap_Based_On_Texture(TextureClass* texture);
virtual void Release_All_Textures(void);
virtual void Release_Unused_Textures(void);
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/bmp2d.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/bmp2d.cpp
deleted file mode 100644
index 0f72cdd87c9..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/bmp2d.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-/***************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***************************************************************************
- * *
- * Project Name : Commando/G *
- * *
- * $Archive:: /Commando/Code/ww3d2/bmp2d.cpp $*
- * *
- * $Author:: Naty_h $*
- * *
- * $Modtime:: 4/13/01 1:37p $*
- * *
- * $Revision:: 10 $*
- * *
- *-------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#include "bmp2d.h"
-#include "pot.h"
-#include "ww3d.h"
-#include "texture.h"
-#include "surfaceclass.h"
-
-Bitmap2DObjClass::Bitmap2DObjClass
-(
- const char *filename,
- float screen_x,
- float screen_y,
- bool center,
- bool additive,
- bool colorizable,
- int usable_width,
- int usable_height,
- bool ignore_alpha
-)
- : DynamicScreenMeshClass(2, 4)
-{
-
- int resw, resh, resbits;
- bool windowed;
-
- // find the resolution (for centering and pixel to pixel translation)
- WW3D::Get_Device_Resolution(resw, resh, resbits, windowed);
- // This should be the correct way to do things
- // but other code expects an aspect ratio of 1.0
- // Hector Yee 2/22/01
- // Set_Aspect(resh/(float)resw);
-
-
- // load up the surfaces file name
- SurfaceClass *surface=NEW_REF(SurfaceClass,(filename));
-
- SurfaceClass::SurfaceDescription sd;
- surface->Get_Description(sd);
-
- if (usable_width == -1)
- usable_width = sd.Width;
- if (usable_height == -1)
- usable_height = sd.Height;
-
- // if we requested the image to be centered around a point adjust the
- // coordinates accordingly.
- if (center) {
- screen_x -= ((float)usable_width / resw) / 2;
- screen_y -= ((float)usable_height / resh) / 2;
- }
-
- // The image will be broken down into square textures. The size of these
- // textures will be the smallest POT (power of two) which is equal or
- // greater than the smaller dimension of the image. Also, the pieces can
- // never be larger than 256 texels because some rendering devices don't
- // support textures larger than that.
- int surf_w = usable_width;
- int surf_h = usable_height;
- int piece = Find_POT(MIN(surf_w, surf_h));
- piece = MIN(piece, 256);
-
- // now take the image in question and break it down into
- // "piece"x"piece"-pixel polygons and calculate the number of textures
- // based from those calculations.
- int mw = (surf_w & (piece - 1)) ? (surf_w / piece)+1 : (surf_w /piece);
- int mh = (surf_h & (piece - 1)) ? (surf_h / piece)+1 : (surf_h /piece);
-
- // for every square texture it takes four vertexes to express the two
- // polygons.
- Resize(mw * mh *2, mw * mh * 4);
-
- // Set shader to additive if requested, else alpha or opaque depending on
- // whether the texture has an alpha channel. Sorting is always set so that
- // sortbias can be used to determine occlusion between the various 2D
- // elements.
- ShaderClass shader;
-
- if (additive) {
- shader = ShaderClass::_PresetAdditive2DShader;
- } else {
- if (ignore_alpha == false && Has_Alpha(sd.Format)) {
- shader = ShaderClass::_PresetAlpha2DShader;
- } else {
- shader = ShaderClass::_PresetOpaque2DShader;
- }
- }
-
- Enable_Sort();
-
-
- // If we want to be able to colorize this bitmap later (by setting
- // emissive color for the vertex material, or via a vertex emissive color
- // array) we need to enable the primary gradient in the shader (it is
- // disabled in the 2D presets), and set an appropriate vertex material.
- if (colorizable) {
- shader.Set_Primary_Gradient(ShaderClass::GRADIENT_MODULATE);
- VertexMaterialClass *vertex_material = NEW_REF( VertexMaterialClass, ());
- vertex_material->Set_Ambient(0.0f, 0.0f, 0.0f);
- vertex_material->Set_Diffuse(0.0f, 0.0f, 0.0f);
- vertex_material->Set_Specular(0.0f, 0.0f, 0.0f);
- vertex_material->Set_Emissive(1.0f, 1.0f, 1.0f);
- Set_Vertex_Material(vertex_material, true);
- vertex_material->Release_Ref();
- }
-
- // Set desired shader.
- Set_Shader(shader);
-
- // loop through the rows and columns of the image and make valid
- // textures from the pieces.
- for (int lpy = 0, tlpy=0; lpy < mh; lpy++, tlpy += piece) {
- for (int lpx = 0, tlpx = 0; lpx < mw; lpx++, tlpx += piece) {
-
- // figure the desired width and height of the texture (max "piece")
- int iw = MIN(piece, usable_width - (tlpx));
- int ih = MIN(piece, usable_height - (tlpy));
- int pot = MAX(Find_POT(iw), Find_POT(ih));
-
- // create the texture and turn MIP-mapping off.
- SurfaceClass *piece_surface=NEW_REF(SurfaceClass,(pot,pot,sd.Format));
- piece_surface->Copy(0,0,tlpx,tlpy,pot,pot,surface);
- TextureClass *piece_texture =NEW_REF(TextureClass,(piece_surface,MIP_LEVELS_1));
- piece_texture->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- piece_texture->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- REF_PTR_RELEASE(piece_surface);
-
- // calculate our actual texture coordinates based on the difference between
- // the width and height of the texture and the width and height the font
- // occupys.
- float tw = (float)iw / (float)pot;
- float th = (float)ih / (float)pot;
-
- // convert image width and image height to normalized values
- float vw = (float)iw / (float)resw;
- float vh = (float)ih / (float)resh;
-
- // figure out the screen space x and y positions of the object in question.
- float x = screen_x + (((float)tlpx) / (float)resw);
- float y = screen_y + (((float)tlpy) / (float)resh);
-
- Set_Texture(piece_texture);
- Begin_Tri_Strip();
- Vertex( x, y, 0, 0, 0);
- Vertex( x + vw, y, 0, tw, 0);
- Vertex( x, y + vh, 0, 0, th);
- Vertex( x + vw, y + vh, 0, tw, th);
- End_Tri_Strip();
-
- // release our reference to the texture
- REF_PTR_RELEASE(piece_texture);
- }
- }
- REF_PTR_RELEASE(surface);
-
- Set_Dirty();
-}
-
-Bitmap2DObjClass::Bitmap2DObjClass
-(
- TextureClass *texture,
- float screen_x,
- float screen_y,
- bool center,
- bool additive,
- bool colorizable,
- bool ignore_alpha
-)
- : DynamicScreenMeshClass(2, 4)
-{
- int resw, resh, resbits;
- bool windowed;
-
- // find the resolution (for centering and pixel to pixel translation)
- WW3D::Get_Device_Resolution(resw, resh, resbits, windowed);
- // This should be the correct way to do things
- // but other code expects an aspect ratio of 1.0
- // Hector Yee 2/22/01
- //Set_Aspect(resh/(float)resw);
-
- // Find the dimensions of the texture:
-// SurfaceClass::SurfaceDescription sd;
-// texture->Get_Level_Description(sd);
-
- // convert image width and image height to normalized values
- float vw = (float) texture->Get_Width() / (float)resw;
- float vh = (float) texture->Get_Height() / (float)resh;
-
- // if we requested the image to be centered around a point adjust the
- // coordinates accordingly.
- if (center) {
- screen_x -= vw / 2;
- screen_y -= vh / 2;
- }
-
- // Set shader to additive if requested, else alpha or opaque depending on whether the texture
- // has an alpha channel. Sorting is never set - if you wish to sort these types of objects you
- // should use static sort levels (note that static sort levels are not implemented for these
- // objects yet, but it should be very simple to do).
- ShaderClass shader;
-
- if (additive) {
- shader = ShaderClass::_PresetAdditive2DShader;
- } else {
- if (ignore_alpha == false && Has_Alpha(texture->Get_Texture_Format())) {
- shader = ShaderClass::_PresetAlpha2DShader;
- } else {
- shader = ShaderClass::_PresetOpaque2DShader;
- }
- }
- Disable_Sort();
-
- // If we want to be able to colorize this bitmap later (by setting
- // emissive color for the vertex material, or via a vertex emissive color
- // array) we need to enable the primary gradient in the shader (it is
- // disabled in the 2D presets), and set an appropriate vertex material.
- if (colorizable) {
- shader.Set_Primary_Gradient(ShaderClass::GRADIENT_MODULATE);
- VertexMaterialClass *vertex_material = NEW_REF( VertexMaterialClass, ());
- vertex_material->Set_Ambient(0.0f, 0.0f, 0.0f);
- vertex_material->Set_Diffuse(0.0f, 0.0f, 0.0f);
- vertex_material->Set_Specular(0.0f, 0.0f, 0.0f);
- vertex_material->Set_Emissive(1.0f, 1.0f, 1.0f);
- Set_Vertex_Material(vertex_material, true);
- vertex_material->Release_Ref();
- }
-
- // Set desired shader.
- Set_Shader(shader);
-
- // Set texture to requested texture:
- Set_Texture(texture);
-
- Begin_Tri_Strip();
- Vertex( screen_x, screen_y, 0, 0, 0);
- Vertex( screen_x + vw, screen_y, 0, 1.0, 0);
- Vertex( screen_x, screen_y + vh, 0, 0, 1.0);
- Vertex( screen_x + vw, screen_y + vh, 0, 1.0, 1.0);
- End_Tri_Strip();
-
- Set_Dirty();
-}
-
-RenderObjClass * Bitmap2DObjClass::Clone(void) const
-{
- return NEW_REF( Bitmap2DObjClass, (*this));
-}
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/bmp2d.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/bmp2d.h
deleted file mode 100644
index b09e595ecbe..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/bmp2d.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-/***************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***************************************************************************
- * *
- * Project Name : Commando/G *
- * *
- * $Archive:: /Commando/Code/ww3d2/bmp2d.h $*
- * *
- * $Author:: Hector_y $*
- * *
- * $Modtime:: 2/21/01 1:31p $*
- * *
- * $Revision:: 3 $*
- * *
- *-------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#pragma once
-
-#include "dynamesh.h"
-
-class Bitmap2DObjClass : public DynamicScreenMeshClass
-{
- public:
- Bitmap2DObjClass(const char *filename, float norm_x, float norm_y,
- bool center, bool additive, bool colorizable = false, int width = -1, int height = -1, bool ignore_alpha = false);
- Bitmap2DObjClass(TextureClass *texture, float norm_x, float norm_y,
- bool center, bool additive, bool colorizable = false, bool ignore_alpha = false);
- Bitmap2DObjClass( const Bitmap2DObjClass & src) : DynamicScreenMeshClass(src) {}
-
- virtual RenderObjClass * Clone(void) const;
- virtual int Class_ID(void) const { return CLASSID_BITMAP2D; }
-};
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp
index 7dd3dc6638b..38477273fe3 100644
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp
+++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp
@@ -539,6 +539,8 @@ void DX8Caps::Compute_Caps(WW3DFormat display_format, const D3DADAPTER_IDENTIFIE
MaxTexturesPerPass=MAX_TEXTURE_STAGES;
Check_Texture_Format_Support(display_format,caps);
+ Check_Render_To_Texture_Support(display_format,caps);
+ Check_Depth_Stencil_Support(display_format,caps);
Check_Texture_Compression_Support(caps);
Check_Bumpmap_Support(caps);
Check_Shader_Support(caps);
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8texman.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8texman.cpp
deleted file mode 100644
index 0d66a497ae6..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8texman.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-/***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : DX8 Texture Manager *
- * *
- * $Archive:: /Commando/Code/ww3d2/dx8texman.cpp $*
- * *
- * Original Author:: Hector Yee *
- * *
- * Author : Kenny Mitchell *
- * *
- * $Modtime:: 06/27/02 1:27p $*
- * *
- * $Revision:: 4 $*
- * *
- * 06/27/02 KM Texture class abstraction *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * DX8TextureManagerClass::Shutdown -- Shuts down the texture manager *
- * DX8TextureManagerClass::Add -- Adds a texture to be managed *
- * DX8TextureManagerClass::Remove -- Removes a texture from being managed *
- * DX8TextureManagerClass::Release_Textures -- Releases the internal d3d texture *
- * DX8TextureManagerClass::Recreate_Textures -- Reallocates lost textures *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-
-// This class manages textures that are in the default pool
-// ensuring that they are released on device loss
-// and created on device reset
-
-// Note: It does NOT addref to textures because it is called in the texture
-// destructor
-
-#include "dx8texman.h"
-
-TextureTrackerList DX8TextureManagerClass::Managed_Textures;
-
-
-/***********************************************************************************************
- * DX8TextureManagerClass::Shutdown -- Shuts down the texture manager *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/25/2001 hy : Created. *
- * 5/16/2002 km : Added depth stencil texture tracking and abstraction *
- *=============================================================================================*/
-void DX8TextureManagerClass::Shutdown()
-{
- while (!Managed_Textures.Is_Empty())
- {
- TextureTrackerClass *track=Managed_Textures.Remove_Head();
- delete track;
- }
-}
-
-/***********************************************************************************************
- * DX8TextureManagerClass::Add -- Adds a texture to be managed *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/25/2001 hy : Created. *
- * 5/16/2002 km : Added depth stencil texture tracking and abstraction *
- *=============================================================================================*/
-void DX8TextureManagerClass::Add(TextureTrackerClass *track)
-{
- // this function should only be called by the texture constructor
- Managed_Textures.Add(track);
-}
-
-
-/***********************************************************************************************
- * DX8TextureManagerClass::Remove -- Removes a texture from being managed *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/25/2001 hy : Created. *
- * 5/16/2002 km : Added depth stencil texture tracking and abstraction *
- *=============================================================================================*/
-void DX8TextureManagerClass::Remove(TextureBaseClass *tex)
-{
- // this function should only be called by the texture destructor
- TextureTrackerListIterator it(&Managed_Textures);
-
- while (!it.Is_Done())
- {
- TextureTrackerClass *track=it.Peek_Obj();
- if (track->Get_Texture()==tex)
- {
- it.Remove_Current_Object();
- delete track;
- break;
- }
- it.Next();
- }
-}
-
-
-/***********************************************************************************************
- * DX8TextureManagerClass::Release_Textures -- Releases the internal d3d texture *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/25/2001 hy : Created. *
- * 5/16/2002 km : Added depth stencil texture tracking and abstraction *
- *=============================================================================================*/
-void DX8TextureManagerClass::Release_Textures()
-{
- TextureTrackerListIterator it(&Managed_Textures);
-
- while (!it.Is_Done())
- {
- TextureTrackerClass *track=it.Peek_Obj();
- track->Release();
- it.Next();
- }
-}
-
-
-/***********************************************************************************************
- * DX8TextureManagerClass::Recreate_Textures -- Reallocates lost textures *
- * *
- * *
- * *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/25/2001 hy : Created. *
- * 5/16/2002 km : Added depth stencil texture tracking and abstraction *
- *=============================================================================================*/
-void DX8TextureManagerClass::Recreate_Textures()
-{
- TextureTrackerListIterator it(&Managed_Textures);
-
- while (!it.Is_Done())
- {
- TextureTrackerClass *track=it.Peek_Obj();
- track->Recreate();
- track->Get_Texture()->Set_Dirty();
- it.Next();
- }
-}
-
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8texman.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8texman.h
deleted file mode 100644
index f97ab5fb7fb..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8texman.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-/***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : DX8 Texture Manager *
- * *
- * $Archive:: /Commando/Code/ww3d2/dx8texman.h $*
- * *
- * Original Author:: Hector Yee *
- * *
- * $Author:: Jani_p $*
- * *
- * $Modtime:: 7/26/01 5:12p $*
- * *
- * $Revision:: 3 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#pragma once
-
-#include "always.h"
-#include "texture.h"
-#include "dx8wrapper.h"
-#include "ww3dformat.h"
-#include "dx8list.h"
-#include "multilist.h"
-
-class DX8TextureManagerClass;
-
-class TextureTrackerClass : public MultiListObjectClass
-{
-public:
- TextureTrackerClass
- (
- unsigned int w,
- unsigned int h,
- MipCountType count,
- TextureBaseClass *tex
- )
- : Width(w),
- Height(h),
- Mip_level_count(count),
- Texture(tex)
- {
- }
-
- virtual void Recreate() const =0;
-
- void Release()
- {
- Texture->Set_D3D_Base_Texture(NULL);
- }
-
- TextureBaseClass* Get_Texture() const { return Texture; }
-
-
-protected:
-
- unsigned int Width;
- unsigned int Height;
- MipCountType Mip_level_count;
- TextureBaseClass *Texture;
-};
-
-class DX8TextureTrackerClass : public TextureTrackerClass
-{
-public:
- DX8TextureTrackerClass
- (
- unsigned int w,
- unsigned int h,
- WW3DFormat format,
- MipCountType count,
- TextureBaseClass *tex,
- bool rt
- )
- : TextureTrackerClass(w,h,count,tex), Format(format), RenderTarget(rt)
- {
- }
-
- virtual void Recreate() const
- {
- WWASSERT(Texture->Peek_D3D_Base_Texture()==NULL);
- Texture->Poke_Texture
- (
- DX8Wrapper::_Create_DX8_Texture
- (
- Width,
- Height,
- Format,
- Mip_level_count,
- D3DPOOL_DEFAULT,
- RenderTarget
- )
- );
- }
-
-private:
- WW3DFormat Format;
- bool RenderTarget;
-};
-
-class DX8TextureManagerClass
-{
-public:
- static void Shutdown();
- static void Add(TextureTrackerClass *track);
- static void Remove(TextureBaseClass *tex);
- static void Release_Textures();
- static void Recreate_Textures();
-private:
- static TextureTrackerList Managed_Textures;
-};
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp
index 44b7056ff36..b6696957880 100644
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp
+++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp
@@ -32,6 +32,7 @@
* *
* $Revision:: 134 $*
* *
+ * 08/05/02 KM Texture class redesign
*---------------------------------------------------------------------------------------------*
* Functions: *
* DX8Wrapper::_Update_Texture -- Copies a texture from system memory to video memory *
@@ -125,8 +126,11 @@ LightEnvironmentClass* DX8Wrapper::Light_Environment = NULL;
RenderInfoClass* DX8Wrapper::Render_Info = NULL;
DWORD DX8Wrapper::Vertex_Processing_Behavior = 0;
+ZTextureClass* DX8Wrapper::Shadow_Map[MAX_SHADOW_MAPS];
+
Vector3 DX8Wrapper::Ambient_Color;
// shader system additions KJM ^
+
bool DX8Wrapper::world_identity;
unsigned DX8Wrapper::RenderStates[256];
unsigned DX8Wrapper::TextureStageStates[MAX_TEXTURE_STAGES][32];
@@ -140,7 +144,9 @@ D3DCOLOR DX8Wrapper::FogColor = 0;
IDirect3D8 * DX8Wrapper::D3DInterface = NULL;
IDirect3DDevice8 * DX8Wrapper::D3DDevice = NULL;
IDirect3DSurface8 * DX8Wrapper::CurrentRenderTarget = NULL;
+IDirect3DSurface8 * DX8Wrapper::CurrentDepthBuffer = NULL;
IDirect3DSurface8 * DX8Wrapper::DefaultRenderTarget = NULL;
+IDirect3DSurface8 * DX8Wrapper::DefaultDepthBuffer = NULL;
bool DX8Wrapper::IsRenderToTexture = false;
unsigned DX8Wrapper::matrix_changes = 0;
@@ -268,6 +274,7 @@ bool DX8Wrapper::Init(void * hwnd, bool lite)
memset(Vertex_Shader_Constants,0,sizeof(Vector4)*MAX_VERTEX_SHADER_CONSTANTS);
memset(Pixel_Shader_Constants,0,sizeof(Vector4)*MAX_PIXEL_SHADER_CONSTANTS);
memset(&render_state,0,sizeof(RenderStateStruct));
+ memset(Shadow_Map,0,sizeof(ZTextureClass*)*MAX_SHADOW_MAPS);
/*
** Initialize all variables!
@@ -396,7 +403,7 @@ void DX8Wrapper::Do_Onetime_Device_Dependent_Inits(void)
** Initalize any other subsystems inside of WW3D
*/
MissingTexture::_Init();
- TextureFilterClass::_Init_Filters();
+ TextureFilterClass::_Init_Filters((TextureFilterClass::TextureFilterMode)WW3D::Get_Texture_Filter());
TheDX8MeshRenderer.Init();
BoxRenderObjClass::Init();
VertexMaterialClass::Init();
@@ -603,6 +610,8 @@ bool DX8Wrapper::Reset_Device(bool reload_assets)
DX8_THREAD_ASSERT();
if ((IsInitted) && (D3DDevice != NULL)) {
// Release all non-MANAGED stuff
+ WW3D::_Invalidate_Textures();
+
Set_Vertex_Buffer (NULL);
Set_Index_Buffer (NULL, 0);
if (m_pCleanupHook) {
@@ -2378,6 +2387,305 @@ IDirect3DTexture8 * DX8Wrapper::_Create_DX8_Texture
}
+/*!
+ * KJM create depth stencil texture
+ */
+IDirect3DTexture8 * DX8Wrapper::_Create_DX8_ZTexture
+(
+ unsigned int width,
+ unsigned int height,
+ WW3DZFormat zformat,
+ MipCountType mip_level_count,
+ D3DPOOL pool
+)
+{
+ DX8_THREAD_ASSERT();
+ DX8_Assert();
+ IDirect3DTexture8* texture = NULL;
+
+ D3DFORMAT zfmt=WW3DZFormat_To_D3DFormat(zformat);
+
+ unsigned ret=DX8Wrapper::_Get_D3D_Device8()->CreateTexture
+ (
+ width,
+ height,
+ mip_level_count,
+ D3DUSAGE_DEPTHSTENCIL,
+ zfmt,
+ pool,
+ &texture
+ );
+
+ if (ret==D3DERR_NOTAVAILABLE)
+ {
+ Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__);
+ return NULL;
+ }
+
+ // If ran out of texture ram, try invalidating some textures and mesh cache.
+ if (ret==D3DERR_OUTOFVIDEOMEMORY)
+ {
+ WWDEBUG_SAY(("Error: Out of memory while creating render target. Trying to release assets..."));
+ // Free all textures that haven't been used in the last 5 seconds
+ TextureClass::Invalidate_Old_Unused_Textures(5000);
+
+ // Invalidate the mesh cache
+ WW3D::_Invalidate_Mesh_Cache();
+
+ ret=DX8Wrapper::_Get_D3D_Device8()->CreateTexture
+ (
+ width,
+ height,
+ mip_level_count,
+ D3DUSAGE_DEPTHSTENCIL,
+ zfmt,
+ pool,
+ &texture
+ );
+
+ if (SUCCEEDED(ret))
+ {
+ WWDEBUG_SAY(("...Render target creation succesful."));
+ }
+ else
+ {
+ WWDEBUG_SAY(("...Render target creation failed."));
+ }
+ if (ret==D3DERR_OUTOFVIDEOMEMORY)
+ {
+ Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__);
+ return NULL;
+ }
+ }
+
+ DX8_ErrorCode(ret);
+
+ texture->AddRef(); // don't release this texture
+
+ // Just return the texture, no reduction
+ // allowed for render targets.
+
+ return texture;
+}
+
+/*!
+ * KJM create cube map texture
+ */
+IDirect3DCubeTexture8* DX8Wrapper::_Create_DX8_Cube_Texture
+(
+ unsigned int width,
+ unsigned int height,
+ WW3DFormat format,
+ MipCountType mip_level_count,
+ D3DPOOL pool,
+ bool rendertarget
+)
+{
+ WWASSERT(width==height);
+ DX8_THREAD_ASSERT();
+ DX8_Assert();
+ IDirect3DCubeTexture8* texture=NULL;
+
+ // Paletted textures not supported!
+ WWASSERT(format!=D3DFMT_P8);
+
+ // NOTE: If 'format' is not supported as a texture format, this function will find the closest
+ // format that is supported and use that instead.
+
+ // Render target may return NOTAVAILABLE, in
+ // which case we return NULL.
+ if (rendertarget)
+ {
+ unsigned ret=D3DXCreateCubeTexture
+ (
+ DX8Wrapper::_Get_D3D_Device8(),
+ width,
+ mip_level_count,
+ D3DUSAGE_RENDERTARGET,
+ WW3DFormat_To_D3DFormat(format),
+ pool,
+ &texture
+ );
+
+ if (ret==D3DERR_NOTAVAILABLE)
+ {
+ Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__);
+ return NULL;
+ }
+
+ // If ran out of texture ram, try invalidating some textures and mesh cache.
+ if (ret==D3DERR_OUTOFVIDEOMEMORY)
+ {
+ WWDEBUG_SAY(("Error: Out of memory while creating render target. Trying to release assets..."));
+ // Free all textures that haven't been used in the last 5 seconds
+ TextureClass::Invalidate_Old_Unused_Textures(5000);
+
+ // Invalidate the mesh cache
+ WW3D::_Invalidate_Mesh_Cache();
+
+ ret=D3DXCreateCubeTexture
+ (
+ DX8Wrapper::_Get_D3D_Device8(),
+ width,
+ mip_level_count,
+ D3DUSAGE_RENDERTARGET,
+ WW3DFormat_To_D3DFormat(format),
+ pool,
+ &texture
+ );
+
+ if (SUCCEEDED(ret))
+ {
+ WWDEBUG_SAY(("...Render target creation succesful."));
+ }
+ else
+ {
+ WWDEBUG_SAY(("...Render target creation failed."));
+ }
+ if (ret==D3DERR_OUTOFVIDEOMEMORY)
+ {
+ Non_Fatal_Log_DX8_ErrorCode(ret,__FILE__,__LINE__);
+ return NULL;
+ }
+ }
+
+ DX8_ErrorCode(ret);
+ // Just return the texture, no reduction
+ // allowed for render targets.
+ return texture;
+ }
+
+ // We should never run out of video memory when allocating a non-rendertarget texture.
+ // However, it seems to happen sometimes when there are a lot of textures in memory and so
+ // if it happens we'll release assets and try again (anything is better than crashing).
+ unsigned ret=D3DXCreateCubeTexture
+ (
+ DX8Wrapper::_Get_D3D_Device8(),
+ width,
+ mip_level_count,
+ 0,
+ WW3DFormat_To_D3DFormat(format),
+ pool,
+ &texture
+ );
+
+ // If ran out of texture ram, try invalidating some textures and mesh cache.
+ if (ret==D3DERR_OUTOFVIDEOMEMORY)
+ {
+ WWDEBUG_SAY(("Error: Out of memory while creating texture. Trying to release assets..."));
+ // Free all textures that haven't been used in the last 5 seconds
+ TextureClass::Invalidate_Old_Unused_Textures(5000);
+
+ // Invalidate the mesh cache
+ WW3D::_Invalidate_Mesh_Cache();
+
+ ret=D3DXCreateCubeTexture
+ (
+ DX8Wrapper::_Get_D3D_Device8(),
+ width,
+ mip_level_count,
+ 0,
+ WW3DFormat_To_D3DFormat(format),
+ pool,
+ &texture
+ );
+ if (SUCCEEDED(ret))
+ {
+ WWDEBUG_SAY(("...Texture creation succesful."));
+ }
+ else
+ {
+ StringClass format_name(0,true);
+ Get_WW3D_Format_Name(format, format_name);
+ WWDEBUG_SAY(("...Texture creation failed. (%d x %d, format: %s, mips: %d",width,height,format_name.str(),mip_level_count));
+ }
+
+ }
+ DX8_ErrorCode(ret);
+
+ return texture;
+}
+
+/*!
+ * KJM create volume texture
+ */
+IDirect3DVolumeTexture8* DX8Wrapper::_Create_DX8_Volume_Texture
+(
+ unsigned int width,
+ unsigned int height,
+ unsigned int depth,
+ WW3DFormat format,
+ MipCountType mip_level_count,
+ D3DPOOL pool
+)
+{
+ DX8_THREAD_ASSERT();
+ DX8_Assert();
+ IDirect3DVolumeTexture8* texture=NULL;
+
+ // Paletted textures not supported!
+ WWASSERT(format!=D3DFMT_P8);
+
+ // NOTE: If 'format' is not supported as a texture format, this function will find the closest
+ // format that is supported and use that instead.
+
+
+ // We should never run out of video memory when allocating a non-rendertarget texture.
+ // However, it seems to happen sometimes when there are a lot of textures in memory and so
+ // if it happens we'll release assets and try again (anything is better than crashing).
+ unsigned ret=D3DXCreateVolumeTexture
+ (
+ DX8Wrapper::_Get_D3D_Device8(),
+ width,
+ height,
+ depth,
+ mip_level_count,
+ 0,
+ WW3DFormat_To_D3DFormat(format),
+ pool,
+ &texture
+ );
+
+ // If ran out of texture ram, try invalidating some textures and mesh cache.
+ if (ret==D3DERR_OUTOFVIDEOMEMORY)
+ {
+ WWDEBUG_SAY(("Error: Out of memory while creating texture. Trying to release assets..."));
+ // Free all textures that haven't been used in the last 5 seconds
+ TextureClass::Invalidate_Old_Unused_Textures(5000);
+
+ // Invalidate the mesh cache
+ WW3D::_Invalidate_Mesh_Cache();
+
+ ret=D3DXCreateVolumeTexture
+ (
+ DX8Wrapper::_Get_D3D_Device8(),
+ width,
+ height,
+ depth,
+ mip_level_count,
+ 0,
+ WW3DFormat_To_D3DFormat(format),
+ pool,
+ &texture
+ );
+ if (SUCCEEDED(ret))
+ {
+ WWDEBUG_SAY(("...Texture creation succesful."));
+ }
+ else
+ {
+ StringClass format_name(0,true);
+ Get_WW3D_Format_Name(format, format_name);
+ WWDEBUG_SAY(("...Texture creation failed. (%d x %d, format: %s, mips: %d",width,height,format_name.str(),mip_level_count));
+ }
+
+ }
+ DX8_ErrorCode(ret);
+
+ return texture;
+}
+
+
IDirect3DSurface8 * DX8Wrapper::_Create_DX8_Surface(unsigned int width, unsigned int height, WW3DFormat format)
{
DX8_THREAD_ASSERT();
@@ -2660,10 +2968,24 @@ SurfaceClass * DX8Wrapper::_Get_DX8_Back_Buffer(unsigned int num)
TextureClass *
-DX8Wrapper::Create_Render_Target (int width, int height, bool alpha)
+DX8Wrapper::Create_Render_Target (int width, int height, WW3DFormat format)
{
DX8_THREAD_ASSERT();
DX8_Assert();
+ number_of_DX8_calls++;
+
+ // Use the current display format if format isn't specified
+ if (format==WW3D_FORMAT_UNKNOWN) {
+ D3DDISPLAYMODE mode;
+ DX8CALL(GetDisplayMode(&mode));
+ format=D3DFormat_To_WW3DFormat(mode.Format);
+ }
+
+ // If render target format isn't supported return NULL
+ if (!Get_Current_Caps()->Support_Render_To_Texture_Format(format)) {
+ WWDEBUG_SAY(("DX8Wrapper - Render target format is not supported"));
+ return NULL;
+ }
//
// Note: We're going to force the width and height to be powers of two and equal
@@ -2685,49 +3007,81 @@ DX8Wrapper::Create_Render_Target (int width, int height, bool alpha)
width = height = poweroftwosize;
//
- // Get the current format of the display
+ // Attempt to create the render target
//
- D3DDISPLAYMODE mode;
- DX8CALL(GetDisplayMode(&mode));
+ TextureClass * tex = NEW_REF(TextureClass,(width,height,format,MIP_LEVELS_1,TextureClass::POOL_DEFAULT,true));
+
+ // 3dfx drivers are lying in the CheckDeviceFormat call and claiming
+ // that they support render targets!
+ if (tex->Peek_D3D_Base_Texture() == NULL)
+ {
+ WWDEBUG_SAY(("DX8Wrapper - Render target creation failed!"));
+ REF_PTR_RELEASE(tex);
+ }
+
+ return tex;
+}
+
+//**********************************************************************************************
+//! Create render target with associated depth stencil buffer
+/*! KJM
+*/
+void DX8Wrapper::Create_Render_Target
+(
+ int width,
+ int height,
+ WW3DFormat format,
+ WW3DZFormat zformat,
+ TextureClass** target,
+ ZTextureClass** depth_buffer
+)
+{
+ DX8_THREAD_ASSERT();
+ DX8_Assert();
+ number_of_DX8_calls++;
- // If the user requested a render-target texture and this device does not support that
- // feature, return NULL
- HRESULT hr;
+ // Use the current display format if format isn't specified
+ if (format==WW3D_FORMAT_UNKNOWN)
+ {
+ *target=NULL;
+ *depth_buffer=NULL;
+ return;
+/* D3DDISPLAYMODE mode;
+ DX8CALL(GetDisplayMode(&mode));
+ format=D3DFormat_To_WW3DFormat(mode.Format);*/
+ }
- if (alpha)
+ // If render target format isn't supported return NULL
+ if (!Get_Current_Caps()->Support_Render_To_Texture_Format(format) ||
+ !Get_Current_Caps()->Support_Depth_Stencil_Format(zformat))
{
- //user wants a texture with destination alpha channel - only 1 such format
- //ever exists on current hardware - D3DFMT_A8R8G8B8
- hr = D3DInterface->CheckDeviceFormat( D3DADAPTER_DEFAULT,
- WW3D_DEVTYPE,
- mode.Format,
- D3DUSAGE_RENDERTARGET,
- D3DRTYPE_TEXTURE,
- D3DFMT_A8R8G8B8 );
- mode.Format=D3DFMT_A8R8G8B8;
+ WWDEBUG_SAY(("DX8Wrapper - Render target with depth format is not supported"));
+ return;
}
- else
+
+ // Note: We're going to force the width and height to be powers of two and equal
+ const D3DCAPS8& dx8caps=Get_Current_Caps()->Get_DX8_Caps();
+ float poweroftwosize = width;
+ if (height > 0 && height < width)
{
- hr = D3DInterface->CheckDeviceFormat( D3DADAPTER_DEFAULT,
- WW3D_DEVTYPE,
- mode.Format,
- D3DUSAGE_RENDERTARGET,
- D3DRTYPE_TEXTURE,
- mode.Format );
+ poweroftwosize = height;
}
+ poweroftwosize = ::Find_POT (poweroftwosize);
- number_of_DX8_calls++;
- if (hr != D3D_OK) {
- WWDEBUG_SAY(("DX8Wrapper - Driver cannot create render target!"));
- return NULL;
+ if (poweroftwosize>dx8caps.MaxTextureWidth)
+ {
+ poweroftwosize=dx8caps.MaxTextureWidth;
}
- //
+ if (poweroftwosize>dx8caps.MaxTextureHeight)
+ {
+ poweroftwosize=dx8caps.MaxTextureHeight;
+ }
+
+ width = height = poweroftwosize;
+
// Attempt to create the render target
- //
- DX8_Assert();
- WW3DFormat format=D3DFormat_To_WW3DFormat(mode.Format);
- TextureClass * tex = NEW_REF(TextureClass,(width,height,format,MIP_LEVELS_1,TextureClass::POOL_DEFAULT,true));
+ TextureClass* tex=NEW_REF(TextureClass,(width,height,format,MIP_LEVELS_1,TextureClass::POOL_DEFAULT,true));
// 3dfx drivers are lying in the CheckDeviceFormat call and claiming
// that they support render targets!
@@ -2737,19 +3091,52 @@ DX8Wrapper::Create_Render_Target (int width, int height, bool alpha)
REF_PTR_RELEASE(tex);
}
- return tex;
-}
+ *target=tex;
+ // attempt to create the depth stencil buffer
+ *depth_buffer=NEW_REF
+ (
+ ZTextureClass,
+ (
+ width,
+ height,
+ zformat,
+ MIP_LEVELS_1,
+ TextureClass::POOL_DEFAULT
+ )
+ );
+}
-void
-DX8Wrapper::Set_Render_Target
-(TextureClass * texture)
+/*!
+ * Set render target
+ * KM Added optional custom z target
+ */
+void DX8Wrapper::Set_Render_Target_With_Z
+(
+ TextureClass* texture,
+ ZTextureClass* ztexture
+)
{
- WWASSERT(texture != NULL);
- SurfaceClass * surf = texture->Get_Surface_Level();
- WWASSERT(surf != NULL);
- Set_Render_Target(surf->Peek_D3D_Surface());
- REF_PTR_RELEASE(surf);
+ WWASSERT(texture!=NULL);
+ IDirect3DSurface8 * d3d_surf = texture->Get_D3D_Surface_Level();
+ WWASSERT(d3d_surf != NULL);
+
+ IDirect3DSurface8* d3d_zbuf=NULL;
+ if (ztexture!=NULL)
+ {
+
+ d3d_zbuf=ztexture->Get_D3D_Surface_Level();
+ WWASSERT(d3d_zbuf!=NULL);
+ Set_Render_Target(d3d_surf,d3d_zbuf);
+ d3d_zbuf->Release();
+ }
+ else
+ {
+ Set_Render_Target(d3d_surf,true);
+ }
+ d3d_surf->Release();
+
+ IsRenderToTexture = true;
}
void
@@ -2767,7 +3154,7 @@ DX8Wrapper::Set_Render_Target(IDirect3DSwapChain8 *swap_chain)
//
// Set this back buffer as the render targer
//
- Set_Render_Target (render_target);
+ Set_Render_Target (render_target, true);
//
// Release our hold on the back buffer
@@ -2783,31 +3170,36 @@ DX8Wrapper::Set_Render_Target(IDirect3DSwapChain8 *swap_chain)
}
void
-DX8Wrapper::Set_Render_Target(IDirect3DSurface8 *render_target)
+DX8Wrapper::Set_Render_Target(IDirect3DSurface8 *render_target, bool use_default_depth_buffer)
{
+//#ifndef _XBOX
DX8_THREAD_ASSERT();
DX8_Assert();
- //
- // We'll need the depth buffer later...
- //
- IDirect3DSurface8 *depth_buffer = NULL;
- DX8CALL(GetDepthStencilSurface (&depth_buffer));
-
//
// Should we restore the default render target set a new one?
//
if (render_target == NULL || render_target == DefaultRenderTarget)
{
+ // If there is currently a custom render target, default must NOT be NULL.
+ if (CurrentRenderTarget)
+ {
+ WWASSERT(DefaultRenderTarget!=NULL);
+ }
//
// Restore the default render target
//
if (DefaultRenderTarget != NULL)
{
- DX8CALL(SetRenderTarget (DefaultRenderTarget, depth_buffer));
+ DX8CALL(SetRenderTarget (DefaultRenderTarget, DefaultDepthBuffer));
DefaultRenderTarget->Release ();
DefaultRenderTarget = NULL;
+ if (DefaultDepthBuffer)
+ {
+ DefaultDepthBuffer->Release ();
+ DefaultDepthBuffer = NULL;
+ }
}
//
@@ -2819,9 +3211,25 @@ DX8Wrapper::Set_Render_Target(IDirect3DSurface8 *render_target)
CurrentRenderTarget = NULL;
}
+ if (CurrentDepthBuffer!=NULL)
+ {
+ CurrentDepthBuffer->Release();
+ CurrentDepthBuffer=NULL;
+ }
+
}
else if (render_target != CurrentRenderTarget)
{
+ WWASSERT(DefaultRenderTarget==NULL);
+
+ //
+ // We'll need the depth buffer later...
+ //
+ if (DefaultDepthBuffer == NULL)
+ {
+// IDirect3DSurface8 *depth_buffer = NULL;
+ DX8CALL(GetDepthStencilSurface (&DefaultDepthBuffer));
+ }
//
// Get a pointer to the default render target (if necessary)
@@ -2840,6 +3248,12 @@ DX8Wrapper::Set_Render_Target(IDirect3DSurface8 *render_target)
CurrentRenderTarget = NULL;
}
+ if (CurrentDepthBuffer!=NULL)
+ {
+ CurrentDepthBuffer->Release();
+ CurrentDepthBuffer=NULL;
+ }
+
//
// Keep a copy of the current render target (for housekeeping)
//
@@ -2852,20 +3266,142 @@ DX8Wrapper::Set_Render_Target(IDirect3DSurface8 *render_target)
//
// Switch render targets
//
- DX8CALL(SetRenderTarget (CurrentRenderTarget, depth_buffer));
+ if (use_default_depth_buffer)
+ {
+ DX8CALL(SetRenderTarget (CurrentRenderTarget, DefaultDepthBuffer));
+ }
+ else
+ {
+ DX8CALL(SetRenderTarget (CurrentRenderTarget, NULL));
+ }
}
}
//
// Free our hold on the depth buffer
//
- if (depth_buffer != NULL) {
- depth_buffer->Release ();
- depth_buffer = NULL;
- }
+// if (depth_buffer != NULL) {
+// depth_buffer->Release ();
+// depth_buffer = NULL;
+// }
IsRenderToTexture = false;
return ;
+//#endif // XBOX
+}
+
+
+//**********************************************************************************************
+//! Set render target with depth stencil buffer
+/*! KJM
+*/
+void DX8Wrapper::Set_Render_Target
+(
+ IDirect3DSurface8* render_target,
+ IDirect3DSurface8* depth_buffer
+)
+{
+//#ifndef _XBOX
+ DX8_THREAD_ASSERT();
+ DX8_Assert();
+
+ //
+ // Should we restore the default render target set a new one?
+ //
+ if (render_target == NULL || render_target == DefaultRenderTarget)
+ {
+ // If there is currently a custom render target, default must NOT be NULL.
+ if (CurrentRenderTarget)
+ {
+ WWASSERT(DefaultRenderTarget!=NULL);
+ }
+
+ //
+ // Restore the default render target
+ //
+ if (DefaultRenderTarget != NULL)
+ {
+ DX8CALL(SetRenderTarget (DefaultRenderTarget, DefaultDepthBuffer));
+ DefaultRenderTarget->Release ();
+ DefaultRenderTarget = NULL;
+ if (DefaultDepthBuffer)
+ {
+ DefaultDepthBuffer->Release ();
+ DefaultDepthBuffer = NULL;
+ }
+ }
+
+ //
+ // Release our hold on the "current" render target
+ //
+ if (CurrentRenderTarget != NULL)
+ {
+ CurrentRenderTarget->Release ();
+ CurrentRenderTarget = NULL;
+ }
+
+ if (CurrentDepthBuffer!=NULL)
+ {
+ CurrentDepthBuffer->Release();
+ CurrentDepthBuffer=NULL;
+ }
+ }
+ else if (render_target != CurrentRenderTarget)
+ {
+ WWASSERT(DefaultRenderTarget==NULL);
+
+ //
+ // We'll need the depth buffer later...
+ //
+ if (DefaultDepthBuffer == NULL)
+ {
+// IDirect3DSurface8 *depth_buffer = NULL;
+ DX8CALL(GetDepthStencilSurface (&DefaultDepthBuffer));
+ }
+
+ //
+ // Get a pointer to the default render target (if necessary)
+ //
+ if (DefaultRenderTarget == NULL)
+ {
+ DX8CALL(GetRenderTarget (&DefaultRenderTarget));
+ }
+
+ //
+ // Release our hold on the old "current" render target
+ //
+ if (CurrentRenderTarget != NULL)
+ {
+ CurrentRenderTarget->Release ();
+ CurrentRenderTarget = NULL;
+ }
+
+ if (CurrentDepthBuffer!=NULL)
+ {
+ CurrentDepthBuffer->Release();
+ CurrentDepthBuffer=NULL;
+ }
+
+ //
+ // Keep a copy of the current render target (for housekeeping)
+ //
+ CurrentRenderTarget = render_target;
+ CurrentDepthBuffer = depth_buffer;
+ WWASSERT (CurrentRenderTarget != NULL);
+ if (CurrentRenderTarget != NULL)
+ {
+ CurrentRenderTarget->AddRef ();
+ CurrentDepthBuffer->AddRef();
+
+ //
+ // Switch render targets
+ //
+ DX8CALL(SetRenderTarget (CurrentRenderTarget, CurrentDepthBuffer));
+ }
+ }
+
+ IsRenderToTexture=true;
+//#endif // XBOX
}
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h
index c5404ad3ff7..f72ce2e13ee 100644
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h
+++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h
@@ -349,6 +349,37 @@ class DX8Wrapper
** Resources
*/
+ static IDirect3DVolumeTexture8* _Create_DX8_Volume_Texture
+ (
+ unsigned int width,
+ unsigned int height,
+ unsigned int depth,
+ WW3DFormat format,
+ MipCountType mip_level_count,
+ D3DPOOL pool=D3DPOOL_MANAGED
+ );
+
+ static IDirect3DCubeTexture8* _Create_DX8_Cube_Texture
+ (
+ unsigned int width,
+ unsigned int height,
+ WW3DFormat format,
+ MipCountType mip_level_count,
+ D3DPOOL pool=D3DPOOL_MANAGED,
+ bool rendertarget=false
+ );
+
+
+ static IDirect3DTexture8* _Create_DX8_ZTexture
+ (
+ unsigned int width,
+ unsigned int height,
+ WW3DZFormat zformat,
+ MipCountType mip_level_count,
+ D3DPOOL pool=D3DPOOL_MANAGED
+ );
+
+
static IDirect3DTexture8 * _Create_DX8_Texture
(
unsigned int width,
@@ -436,15 +467,32 @@ class DX8Wrapper
static IDirect3DSwapChain8 * Create_Additional_Swap_Chain (HWND render_window);
/*
- ** Render target interface
+ ** Render target interface. If render target format is WW3D_FORMAT_UNKNOWN, current display format is used.
*/
- static TextureClass * Create_Render_Target (int width, int height, bool alpha=false);
+ static TextureClass * Create_Render_Target (int width, int height, WW3DFormat format = WW3D_FORMAT_UNKNOWN);
+
+ static void Set_Render_Target (IDirect3DSurface8 *render_target, bool use_default_depth_buffer = false);
+ static void Set_Render_Target (IDirect3DSurface8* render_target, IDirect3DSurface8* dpeth_buffer);
- static void Set_Render_Target (TextureBaseClass * texture);
- static void Set_Render_Target (IDirect3DSurface8 *render_target);
static void Set_Render_Target (IDirect3DSwapChain8 *swap_chain);
static bool Is_Render_To_Texture(void) { return IsRenderToTexture; }
+ // for depth map support KJM V
+ static void Create_Render_Target
+ (
+ int width,
+ int height,
+ WW3DFormat format,
+ WW3DZFormat zformat,
+ TextureClass** target,
+ ZTextureClass** depth_buffer
+ );
+ static void Set_Render_Target_With_Z (TextureClass * texture, ZTextureClass* ztexture=NULL);
+
+ static void Set_Shadow_Map(int idx, ZTextureClass* ztex) { Shadow_Map[idx]=ztex; }
+ static ZTextureClass* Get_Shadow_Map(int idx) { return Shadow_Map[idx]; }
+ // for depth map support KJM ^
+
// shader system udpates KJM v
static void Apply_Default_State();
@@ -597,6 +645,9 @@ class DX8Wrapper
static RenderInfoClass* Render_Info;
static DWORD Vertex_Processing_Behavior;
+
+ static ZTextureClass* Shadow_Map[MAX_SHADOW_MAPS];
+
static Vector3 Ambient_Color;
// shader system updates KJM ^
@@ -631,7 +682,10 @@ class DX8Wrapper
static IDirect3DDevice8 * D3DDevice; //d3ddevice8;
static IDirect3DSurface8 * CurrentRenderTarget;
+ static IDirect3DSurface8 * CurrentDepthBuffer;
static IDirect3DSurface8 * DefaultRenderTarget;
+ static IDirect3DSurface8 * DefaultDepthBuffer;
+
static unsigned DrawPolygonLowBoundLimit;
static bool IsRenderToTexture;
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/matpass.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/matpass.cpp
deleted file mode 100644
index d7fc3aa660a..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/matpass.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-/***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WW3d *
- * *
- * $Archive:: /Commando/Code/ww3d2/matpass.cpp $*
- * *
- * Original Author:: Greg Hjelstrom *
- * *
- * Author : Kenny Mitchell *
- * *
- * $Modtime:: 06/27/02 1:27p $*
- * *
- * $Revision:: 8 $*
- * *
- * 06/27/02 KM Changes to max texture stage caps *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * MaterialPassClass::MaterialPassClass -- Constructor *
- * MaterialPassClass::~MaterialPassClass -- Destructor *
- * MaterialPassClass::Install_Materials -- Plug our material settings into D3D *
- * MaterialPassClass::Set_Texture -- Set texture to use *
- * MaterialPassClass::Set_Shader -- Set the shader to use *
- * MaterialPassClass::Set_Material -- set vertex material to use *
- * MaterialPassClass::Get_Texture -- Get a pointer to the texture *
- * MaterialPassClass::Get_Material -- get the vertex material *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-
-#include "matpass.h"
-#include "vertmaterial.h"
-#include "shader.h"
-#include "texture.h"
-#include "statistics.h"
-#include "dx8wrapper.h"
-
-
-bool MaterialPassClass::EnablePerPolygonCulling = true;
-
-
-/***********************************************************************************************
- * MaterialPassClass::MaterialPassClass -- Constructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 2/26/2001 gth : Created. *
- *=============================================================================================*/
-MaterialPassClass::MaterialPassClass(void) :
- Shader(0),
- Material(NULL),
- CullVolume(NULL),
- EnableOnTranslucentMeshes(true)
-{
- for (int i=0; iGet_Max_Textures_Per_Pass();++i)
- {
- DX8Wrapper::Set_Texture(i,Peek_Texture(i));
- }
-}
-
-
-/***********************************************************************************************
- * MaterialPassClass::Set_Texture -- Set texture to use *
- * *
- * INPUT: *
- * tex - pointer to the texture for this material pass (or NULL) *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/9/99 gth : Created. *
- *=============================================================================================*/
-void MaterialPassClass::Set_Texture(TextureClass * tex,int stage)
-{
- WWASSERT(stage >= 0);
- WWASSERT(stage < MAX_TEX_STAGES);
-
- REF_PTR_SET(Texture[stage],tex);
-}
-
-
-/***********************************************************************************************
- * MaterialPassClass::Set_Shader -- Set the shader to use *
- * *
- * INPUT: *
- * shader - shader for this material pass *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/9/99 gth : Created. *
- *=============================================================================================*/
-void MaterialPassClass::Set_Shader(ShaderClass shader)
-{
- Shader = shader;
- Shader.Enable_Fog ("MaterialPassClass");
-}
-
-
-/***********************************************************************************************
- * MaterialPassClass::Set_Material -- set vertex material to use *
- * *
- * INPUT: *
- * mat - pointer to the vertex material this material pass uses *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/9/99 gth : Created. *
- *=============================================================================================*/
-void MaterialPassClass::Set_Material(VertexMaterialClass * mat)
-{
- REF_PTR_SET(Material,mat);
-}
-
-
-/***********************************************************************************************
- * MaterialPassClass::Get_Texture -- Get a pointer to the texture *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * reference counted pointer to the texture this material pass is using *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/9/99 gth : Created. *
- *=============================================================================================*/
-TextureClass * MaterialPassClass::Get_Texture(int stage) const
-{
- WWASSERT(stage >= 0);
- WWASSERT(stage < MAX_TEX_STAGES);
-
- if (Texture[stage]) {
- Texture[stage]->Add_Ref();
- }
- return Texture[stage];
-}
-
-
-/***********************************************************************************************
- * MaterialPassClass::Get_Material -- get the vertex material *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * reference counted pointer to the vertex material being used by this material pass *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/9/99 gth : Created. *
- *=============================================================================================*/
-VertexMaterialClass * MaterialPassClass::Get_Material(void) const
-{
- if (Material) {
- Material->Add_Ref();
- }
- return Material;
-}
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/matpass.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/matpass.h
deleted file mode 100644
index afa22264645..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/matpass.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-/***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : ww3d *
- * *
- * $Archive:: /Commando/Code/ww3d2/matpass.h $*
- * *
- * Original Author:: Greg Hjelstrom *
- * *
- * Author : Kenny Mitchell *
- * *
- * $Modtime:: 06/27/02 1:27p $*
- * *
- * $Revision:: 6 $*
- * *
- * 06/27/02 KM Texture class abstraction *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#pragma once
-
-#include "always.h"
-#include "shader.h"
-
-class TextureClass;
-class VertexMaterialClass;
-class MeshModelClass;
-class OBBoxClass;
-
-/**
-** MaterialPassClass
-**
-** This class wraps all of the data needed to describe an additional
-** material pass for any object. The motivation for this class is to
-** implement certain types of special effects. All data needed to
-** apply the pass should be generated procedurally. Typically a
-** vertex processor will be used to generate any needed u-v's or vertex
-** colors. Alternatively, we could add the option to request to
-** re-use the model's existing u-v's or vertex colors.
-**
-**
-*/
-class MaterialPassClass : public RefCountClass
-{
-public:
-
- MaterialPassClass(void);
- ~MaterialPassClass(void);
-
- /// MW: Had to make this virtual so app can perform direct/custom D3D setup.
- virtual void Install_Materials(void) const;
- virtual void UnInstall_Materials(void) const { }; ///< reset/cleanup D3D states
-
- void Set_Texture(TextureClass * Texture,int stage = 0);
- void Set_Shader(ShaderClass shader);
- void Set_Material(VertexMaterialClass * mat);
-
- TextureClass * Get_Texture(int stage = 0) const;
- VertexMaterialClass * Get_Material(void) const;
-
- TextureClass * Peek_Texture(int stage = 0) const;
- ShaderClass Peek_Shader(void) const { return Shader; }
- VertexMaterialClass * Peek_Material(void) const { return Material; }
-
- void Set_Cull_Volume(OBBoxClass * volume) { CullVolume = volume; }
- OBBoxClass * Get_Cull_Volume(void) const { return CullVolume; }
-
- void Enable_On_Translucent_Meshes(bool onoff) { EnableOnTranslucentMeshes = onoff; }
- bool Is_Enabled_On_Translucent_Meshes(void) { return EnableOnTranslucentMeshes; }
-
- static void Enable_Per_Polygon_Culling(bool onoff) { EnablePerPolygonCulling = onoff; }
- static bool Is_Per_Polygon_Culling_Enabled(void) { return EnablePerPolygonCulling; }
-
-protected:
-
- enum { MAX_TEX_STAGES = 8 };
-
- TextureClass * Texture[MAX_TEX_STAGES];
- ShaderClass Shader;
- VertexMaterialClass * Material;
- bool EnableOnTranslucentMeshes;
-
- OBBoxClass * CullVolume;
- static bool EnablePerPolygonCulling;
-
-};
-
-
-inline TextureClass * MaterialPassClass::Peek_Texture(int stage) const
-{
- WWASSERT(stage >= 0);
- WWASSERT(stage < MAX_TEX_STAGES);
- return Texture[stage];
-}
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.cpp
deleted file mode 100644
index 2e819962eb0..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.cpp
+++ /dev/null
@@ -1,1355 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-/***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WW3D *
- * *
- * $Archive:: /Commando/Code/ww3d2/texproject.cpp $*
- * *
- * Original Author:: Greg Hjelstrom *
- * *
- * $Author:: Jani_p $*
- * *
- * $Modtime:: 7/23/01 5:31p $*
- * *
- * $Revision:: 15 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * TexProjectClass::TexProjectClass -- Constructor *
- * TexProjectClass::~TexProjectClass -- Destructor *
- * TexProjectClass::Set_Texture_Size -- Set the size of texture to use *
- * TexProjectClass::Get_Texture_Size -- Returns the stored texture size *
- * TexProjectClass::Set_Flag -- Turn specified flag on or off *
- * TexProjectClass::Get_Flag -- Get the current state of specified flag *
- * TexProjectClass::Set_Intensity -- Set the intensity of this projector *
- * TexProjectClass::Get_Intensity -- returns the current "desired" intensity *
- * TexProjectClass::Set_Attenuation -- Set the attenuation factor *
- * TexProjectClass::Get_Attenuation -- Returns the attenuation value *
- * TexProjectClass::Enable_Attenuation -- Set the state of the ATTENUATE flag *
- * TexProjectClass::Is_Attenuation_Enabled -- Get the state of the ATTENUATE flag *
- * TexProjectClass::Is_Depth_Gradient_Enabled -- returns whether the depth gradient is enabl *
- * TexProjectClass::Enable_Depth_Gradient -- enable/disable depth gradient *
- * TexProjectClass::Init_Multiplicative -- Initialize this to be a multiplicative texture pr *
- * TexProjectClass::Is_Intensity_Zero -- check if we can eliminate this projector *
- * TexProjectClass::Init_Additive -- Set up the projector to be additive *
- * TexProjectClass::Set_Perspective_Projection -- Set up a perspective projection *
- * TexProjectClass::Set_Ortho_Projection -- Set up an orthographic projection *
- * TexProjectClass::Set_Texture -- Set the texture to be projected *
- * TexProjectClass::Get_Texture -- Returns the texture being projected *
- * TexProjectClass::Peek_Texture -- Returns the texture being projected *
- * TexProjectClass::Peek_Material_Pass -- Returns the material pass object *
- * TexProjectClass::Compute_Perspective_Projection -- Set up a perspective projection of an *
- * TexProjectClass::Compute_Perspective_Projection -- Set up a perspective projection of an *
- * TexProjectClass::Compute_Ortho_Projection -- Automatic Orthographic projection *
- * TexProjectClass::Compute_Ortho_Projection -- Automatic Orthographic projection *
- * TexProjectClass::Compute_Texture -- Generates texture by rendering an object *
- * TexProjectClass::Configure_Camera -- setup a camera to match this projector *
- * TexProjectClass::Pre_Render_Update -- Prepare the projector for rendering *
- * TexProjectClass::Update_WS_Bounding_Volume -- Recalculate the world-space bounding box *
- * TexProjectClass::Get_Surface -- Returns pointer to the texture surface *
- * TexProjectClass::Set_Render_Target -- Install a render target for this projector to use *
- * TexProjectClass::Needs_Render_Target -- returns wheter this projector needs a render targ *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-
-#include "texproject.h"
-#include "vertmaterial.h"
-#include "shader.h"
-#include "texture.h"
-#include "rendobj.h"
-#include "rinfo.h"
-#include "camera.h"
-#include "matpass.h"
-#include "bwrender.h"
-#include "assetmgr.h"
-#include "dx8wrapper.h"
-
-
-// DEBUG DEBUG
-#include "MPU.h"
-
-#define DEBUG_SHADOW_RENDERING 0
-#define DEFAULT_TEXTURE_SIZE 64
-
-const float INTENSITY_RATE_OF_CHANGE = 1.0f; // change in intensity per second
-
-
-/*
-**
-** Shadow mapping: from pre-projected view coordinates back to world space
-** then to shadow space
-**
-** (1) Vshadow = PShadow * Mwrld-shadow * Vwrld
-**
-** (2) Vview = Mwrld-camera * Vwrld
-**
-** Using (2) to solve for Vwrld in terms of Vview
-** -1
-** (3) Mwrld-camera * Vview = Vwrld
-**
-** Substituting (3) into (1)
-** -1
-** (4) Vshadow = Pshadow * Mwrld-shadow * Mwrld-camera * Vview
-**
-** ---------------------------------------------------------------------------------
-**
-** Shadow mapping: from pre-projected view space to world space, to shadow space,
-** then projecting.
-**
-** (1) Vshadow = Mwrld-shadow * Vwrld
-**
-** (2) Vview = Mwrld-camera * Vwrld
-**
-** solving (2) for Vwrld:
-** -1
-** (3) Mwrld-camera * Vview = Vwrld
-**
-** substitute into (1)
-** -1
-** (4) Vshadow = Mwrld-shadow * Mwrld-camera * Vview
-**
-** project shadow
-** -1
-** (5) Vproj-shadow = Pshadow * (Mwrld-shadow * Mwrld-camera ) * Vview
-**
-** aaah! same thing :-)
-**
-** ---------------------------------------------------------------------------------
-**
-** Shadow mapping: from pre-projected view coordinates back to obj space
-** then to shadow space
-**
-** (1) Vshadow = PShadow * Mwrld-shadow * Mobj-wrld * Vobj
-**
-** (2) Vview = Mwrld-camera * Mobj-wrld * Vobj
-** -1 -1
-** (3) Mobj-wrld * Mwrld-camera * Vview = Vobj
-** -1 -1
-** (4) Vshadow = PShadow * Mwrld-shadow * Mobj-wrld * Mobj-wrld * Mwrld-camera * Vview
-** -1
-** (5) Vshadow = PShadow * Mwrld-shadow * Mvrld-camera * Vview
-**
-**
-** Ideas:
-** - Use Texture Projectors to implement spot lights and stained glass windows
-** - Attenuate texture projections with distance from the projector
-** - Should be able to handle lots of pre-calculated static texture projectors. They
-** should cull well and we can pre-generate the textures.
-**
-** Ideas maybe used in conjunction with texture projections:
-** - Light volumes: the problem is when the volume is cliped it looks funny, we can
-** fill in the clipped face of a non-translucent object by rendering the backfaces
-** - Use the backface-fill to make the camera slicing through the commando look like
-** its *really* slicing through the commando :-)
-** - The back-face-fill trick might be able to use el-cheapo screen mapping!
-**
-*/
-
-
-
-/***********************************************************************************************
- * TexProjectClass::TexProjectClass -- Constructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-TexProjectClass::TexProjectClass(void) :
- Flags(DEFAULT_FLAGS),
- DesiredIntensity(1.0f),
- Intensity(1.0f),
- Attenuation(1.0f),
- MaterialPass(NULL),
- Mapper1(NULL),
- RenderTarget(NULL),
- HFov(90.0f),
- VFov(90.0f),
- XMin(-10.0f),
- XMax(10.0f),
- YMin(-10.0f),
- YMax(10.0f),
- ZNear(1.0f),
- ZFar(1000.0f)
-{
- // set a default texture size
- Set_Texture_Size(DEFAULT_TEXTURE_SIZE);
-
- // create a material pass class
- MaterialPass = NEW_REF(MaterialPassClass,());
- MaterialPass->Set_Cull_Volume(&WorldBoundingVolume);
-
- // create a vertex material
- VertexMaterialClass * vmtl = NEW_REF(VertexMaterialClass,());
- WWASSERT(vmtl != NULL);
-
- // Plug our parent's mapper into our vertex material
- // the mapper for stage1 will be allocated as needed
- vmtl->Set_Mapper(Mapper);
-
- MaterialPass->Set_Material(vmtl);
- vmtl->Release_Ref();
- vmtl = NULL;
-
- // by default init our material pass to be multiplicative (shadow)
- Init_Multiplicative();
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::~TexProjectClass -- Destructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-TexProjectClass::~TexProjectClass(void)
-{
- REF_PTR_RELEASE(Mapper1);
- REF_PTR_RELEASE(MaterialPass);
- REF_PTR_RELEASE(RenderTarget);
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Set_Texture_Size -- Set the size of texture to use *
- * *
- * This function stores the desired texture size in this TexProjectClass. Note that *
- * this size is only used if you have the TexProjectClass generate a texture. *
- * *
- * INPUT: *
- * size - dimension of the texture in pixels *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Set_Texture_Size(int size)
-{
- WWASSERT(size > 0);
- WWASSERT(size <= 512);
- Flags &= ~SIZE_MASK;
- Flags |= (size << SIZE_SHIFT);
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Get_Texture_Size -- Returns the stored texture size *
- * *
- * Returns the size stored in the flags variable. This can be different than the actual *
- * texture's size if you manually installed a texture. This size is only used when *
- * automatically generating a texture as is the case when creating shadows. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-int TexProjectClass::Get_Texture_Size(void)
-{
- return (Flags & SIZE_MASK) >> SIZE_SHIFT;
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Set_Flag -- Turn specified flag on or off *
- * *
- * See the TexProjectClass header file for valid flags *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Set_Flag(uint32 flag,bool onoff)
-{
- if (onoff) {
- Flags |= flag;
- } else {
- Flags &= ~flag;
- }
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Get_Flag -- Get the current state of specified flag *
- * *
- * See the TexProjectClass header file for valid flags *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-bool TexProjectClass::Get_Flag(uint32 flag) const
-{
- return (Flags & flag) == flag;
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Set_Intensity -- Set the intensity of this projector *
- * *
- * The "intensity" is a value between 0 and 1. At 0, the projector will have no effect *
- * At 1, the projector will be at its highest strength. The intensity will automatically *
- * smoothly interpolate towards the value specified unless you use the immediate option. *
- * *
- * INPUT: *
- * intensity - desired intensity, 0 <= intensity <= 1 *
- * immediate - should the intensity be immediately set to the desired value? (default = false) *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Set_Intensity(float intensity,bool immediate)
-{
- WWASSERT(intensity <= 1.0f);
- WWASSERT(intensity >= 0.0f);
-
- DesiredIntensity = intensity;
- if (immediate) {
- Intensity = DesiredIntensity;
- }
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Get_Intensity -- returns the current "desired" intensity *
- * *
- * This will return the last value that was sent into this object through Set_Intensity. *
- * Note however that the actual intensity used in rendering may not have arrived at *
- * that value yet. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-float TexProjectClass::Get_Intensity(void)
-{
- return DesiredIntensity;
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Is_Intensity_Zero -- check if we can eliminate this projector *
- * *
- * Only returns true if the current intensity is zero AND the target intensity is zero *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-bool TexProjectClass::Is_Intensity_Zero(void)
-{
- return ((Intensity == 0.0f) && (DesiredIntensity == 0.0f));
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Set_Attenuation -- Set the attenuation factor *
- * *
- * Attenuation scales the intensity. I use attenuation to make shadows fade away as they *
- * get farther away from the light source or from the viewer. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Set_Attenuation(float attenuation)
-{
- WWASSERT(attenuation >= 0.0f);
- WWASSERT(attenuation <= 1.0f);
- Attenuation = attenuation;
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Get_Attenuation -- Returns the attenuation value *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-float TexProjectClass::Get_Attenuation(void)
-{
- return Attenuation;
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Enable_Attenuation -- Set the state of the ATTENUATE flag *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Enable_Attenuation(bool onoff)
-{
- Set_Flag(ATTENUATE,onoff);
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Is_Attenuation_Enabled -- Get the state of the ATTENUATE flag *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-bool TexProjectClass::Is_Attenuation_Enabled(void)
-{
- return Get_Flag(ATTENUATE);
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Enable_Depth_Gradient -- enable/disable depth gradient *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 2/25/2000 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Enable_Depth_Gradient(bool onoff)
-{
- Set_Flag(USE_DEPTH_GRADIENT,onoff);
-
- // re-setup the shader settings
- if (Get_Flag(ADDITIVE)) {
- Init_Additive();
- } else {
- Init_Multiplicative();
- }
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Is_Depth_Gradient_Enabled -- returns whether the depth gradient is enabled *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 2/25/2000 gth : Created. *
- *=============================================================================================*/
-bool TexProjectClass::Is_Depth_Gradient_Enabled(bool onoff)
-{
- return Get_Flag(USE_DEPTH_GRADIENT);
-}
-
-/***********************************************************************************************
- * TexProjectClass::Init_Multiplicative -- Initialize this to be a multiplicative texture proj *
- * *
- * Set up the internal materials so that the texture is multiplied with whatever it is *
- * projected onto. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/4/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Init_Multiplicative(void)
-{
- Set_Flag(ADDITIVE,false);
-
- /*
- ** Set up the shader
- */
- static ShaderClass mult_shader( SHADE_CNST( ShaderClass::PASS_LEQUAL, //depth_compare,
- ShaderClass::DEPTH_WRITE_DISABLE, //depth_mask,
- ShaderClass::COLOR_WRITE_ENABLE, //color_mask,
- ShaderClass::SRCBLEND_ZERO, //src_blend,
- ShaderClass::DSTBLEND_SRC_COLOR, //dst_blend,
- ShaderClass::FOG_DISABLE, //fog,
- ShaderClass::GRADIENT_ADD, //pri_grad,
- ShaderClass::SECONDARY_GRADIENT_DISABLE, //sec_grad,
- ShaderClass::TEXTURING_ENABLE, //texture,
-
- ShaderClass::ALPHATEST_DISABLE, //alpha_test,
- ShaderClass::CULL_MODE_ENABLE, //cull mode
- 0, //post_det_color,
- 0) ); //post_det_alpha
-
- if (WW3DAssetManager::Get_Instance()->Get_Activate_Fog_On_Load()) {
- mult_shader.Enable_Fog ("TexProjectClass");
- }
-
- if (Get_Flag(USE_DEPTH_GRADIENT)) {
-
- /*
- ** enable multi-texturing
- */
- mult_shader.Set_Post_Detail_Color_Func(ShaderClass::DETAILCOLOR_ADD);
-
- /*
- ** plug the gradient texture into the second stage
- */
- TextureClass * grad_tex = WW3DAssetManager::Get_Instance()->Get_Texture("MultProjectorGradient.tga");
- if (grad_tex) {
- grad_tex->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- grad_tex->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- MaterialPass->Set_Texture(grad_tex,1);
- grad_tex->Release_Ref();
- } else {
- WWDEBUG_SAY(("Could not find texture: MultProjectorGradient.tga!"));
- }
-
- } else {
-
- /*
- ** disable multi-texturing
- */
- mult_shader.Set_Post_Detail_Color_Func(ShaderClass::DETAILCOLOR_DISABLE);
-
- /*
- ** remove the texture from the second stage
- */
- MaterialPass->Set_Texture(NULL,1);
- }
-
-#if (DEBUG_SHADOW_RENDERING)
- // invert the shader so we can see what polygons it is hitting
- mult_shader.Set_Dst_Blend_Func(ShaderClass::DSTBLEND_ONE);
- mult_shader.Set_Src_Blend_Func(ShaderClass::SRCBLEND_ONE);
-#endif
-
- MaterialPass->Set_Shader(mult_shader);
-
- /*
- ** Set up the Vertex Material parameters
- */
- VertexMaterialClass * vmtl = MaterialPass->Peek_Material();
- vmtl->Set_Ambient(0,0,0);
- vmtl->Set_Diffuse(0,0,0);
- vmtl->Set_Specular(0,0,0);
- vmtl->Set_Emissive(0.0f,0.0f,0.0f);
- vmtl->Set_Opacity(1.0f);
- vmtl->Set_Lighting(true); // I need the emissive value to scale the intensity of the shadow
-
- /*
- ** Set up some mapper settings related to depth gradient
- */
- if (Get_Flag(USE_DEPTH_GRADIENT)) {
- if (Mapper1 == NULL) {
- Mapper1 = NEW_REF(MatrixMapperClass,(1));
- }
- Mapper1->Set_Type(MatrixMapperClass::DEPTH_GRADIENT);
- vmtl->Set_Mapper(Mapper1,1);
- } else {
- vmtl->Set_Mapper(NULL,1);
- }
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Init_Additive -- Set up the projector to be additive *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Init_Additive(void)
-{
- Set_Flag(ADDITIVE,true);
-
- /*
- ** Set up the shader
- */
- static ShaderClass add_shader( SHADE_CNST( ShaderClass::PASS_LEQUAL, //depth_compare,
- ShaderClass::DEPTH_WRITE_DISABLE, //depth_mask,
- ShaderClass::COLOR_WRITE_ENABLE, //color_mask,
- ShaderClass::SRCBLEND_ONE, //src_blend,
- ShaderClass::DSTBLEND_ONE, //dst_blend,
- ShaderClass::FOG_DISABLE, //fog,
- ShaderClass::GRADIENT_MODULATE, //pri_grad,
- ShaderClass::SECONDARY_GRADIENT_DISABLE, //sec_grad,
- ShaderClass::TEXTURING_ENABLE, //texture,
- ShaderClass::ALPHATEST_DISABLE, //alpha_test,
- ShaderClass::CULL_MODE_ENABLE, //cullmode,
- ShaderClass::DETAILCOLOR_DISABLE, //post_det_color,
- ShaderClass::DETAILALPHA_DISABLE) ); //post_det_alpha
-
- if (WW3DAssetManager::Get_Instance()->Get_Activate_Fog_On_Load()) {
- add_shader.Enable_Fog ("TexProjectClass");
- }
-
- /*
- ** Additive projectors always use the normal gradient so they need multi-texturing
- */
- add_shader.Set_Post_Detail_Color_Func(ShaderClass::DETAILCOLOR_SCALE);
-
- /*
- ** plug in the gradient texture
- */
- TextureClass * grad_tex = WW3DAssetManager::Get_Instance()->Get_Texture("AddProjectorGradient.tga");
- if (grad_tex) {
- grad_tex->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- grad_tex->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- MaterialPass->Set_Texture(grad_tex,1);
- grad_tex->Release_Ref();
- } else {
- WWDEBUG_SAY(("Could not find texture: AddProjectorGradient.tga!"));
- }
-
-#if (DEBUG_SHADOW_RENDERING)
- // invert the shader so we can see what polygons it is hitting
- add_shader.Set_Dst_Blend_Func(ShaderClass::DSTBLEND_SRC_COLOR);
- add_shader.Set_Src_Blend_Func(ShaderClass::SRCBLEND_ZERO);
-#endif
-
- MaterialPass->Set_Shader(add_shader);
-
- /*
- ** Set up the Vertex Material parameters
- */
- VertexMaterialClass * vmtl = MaterialPass->Peek_Material();
- vmtl->Set_Ambient(0,0,0);
- vmtl->Set_Diffuse(0,0,0);
- vmtl->Set_Specular(0,0,0);
- vmtl->Set_Emissive(1,1,1);
- vmtl->Set_Opacity(1.0f);
- vmtl->Set_Lighting(true); //need emissive to scale the intensity of the projector
-
- /*
- ** Set up some mapper settings related to depth gradient
- ** Additive texture projections always use the normal gradient
- */
- if (Mapper1 == NULL) {
- Mapper1 = NEW_REF(MatrixMapperClass,(1));
- }
- Mapper1->Set_Type(MatrixMapperClass::NORMAL_GRADIENT);
- vmtl->Set_Mapper(Mapper1,1);
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Set_Texture -- Set the texture to be projected *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Set_Texture(TextureClass * texture)
-{
- if (texture != NULL)
- {
- texture->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- texture->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- MaterialPass->Set_Texture(texture);
- }
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Get_Texture -- Returns the texture being projected *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * the pointer is ref-counted! make sure to keep track of your references *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-TextureClass * TexProjectClass::Get_Texture(void) const
-{
- return MaterialPass->Get_Texture();
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Peek_Texture -- Returns the texture being projected *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-TextureClass * TexProjectClass::Peek_Texture(void) const
-{
- return MaterialPass->Peek_Texture();
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Peek_Material_Pass -- Returns the material pass object *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-MaterialPassClass * TexProjectClass::Peek_Material_Pass(void)
-{
- return MaterialPass;
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Set_Perspective_Projection -- set up a perspective projection *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/27/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Set_Perspective_Projection(float hfov,float vfov,float znear,float zfar)
-{
- HFov = hfov;
- VFov = vfov;
- ZNear = znear;
- ZFar = zfar;
-
- ProjectorClass::Set_Perspective_Projection(hfov,vfov,znear,zfar);
- Set_Flag(PERSPECTIVE,true);
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Set_Ortho_Projection -- set up an orthographic projection *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/27/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Set_Ortho_Projection(float xmin,float xmax,float ymin,float ymax,float znear,float zfar)
-{
- XMin = xmin;
- XMax = xmax;
- YMin = ymin;
- YMax = ymax;
- ZNear = znear;
- ZFar = zfar;
-
- ProjectorClass::Set_Ortho_Projection(xmin,xmax,ymin,ymax,znear,zfar);
- Set_Flag(PERSPECTIVE,false);
-}
-
-/***********************************************************************************************
- * TexProjectClass::Compute_Perspective_Projection -- Set up a perspective projection of an ob *
- * *
- * This function automates the process of generating the perspective parameters needed to *
- * tightly bound the projection of an object. *
- * *
- * INPUT: *
- * model - object which we are created a projection of *
- * lightpos - positional light source *
- * znear - distance to near clipping plane for the projection (if -1.0, will be generated) *
- * zfar - distance to far clipping plane for the projection (if -1.0, will be generated) *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-bool TexProjectClass::Compute_Perspective_Projection
-(
- RenderObjClass * model,
- const Vector3 & lightpos,
- float znear,
- float zfar
-)
-{
- if (model == NULL) {
- WWDEBUG_SAY(("Attempting to generate projection for a NULL model"));
- return false;
- }
-
- AABoxClass box;
- model->Get_Obj_Space_Bounding_Box(box);
- const Matrix3D & tm = model->Get_Transform();
-
- return Compute_Perspective_Projection(box,tm,lightpos,znear,zfar);
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Compute_Perspective_Projection -- Set up a perspective projection of an ob *
- * *
- * This function automates the process of generating the perspective parameters needed to *
- * tightly bound the projection of an object. *
- * *
- * INPUT: *
- * obj_box - object space bounding box of the object we are projecting *
- * tm - transform of the object we are projecting *
- * lightpos - positional light source *
- * user_znear - distance to near clipping plane for the projection (if -1.0, will be generated)*
- * user_zfar - distance to far clipping plane for the projection (if -1.0, will be generated) *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-bool TexProjectClass::Compute_Perspective_Projection
-(
- const AABoxClass & obj_box,
- const Matrix3D & tm,
- const Vector3 & lightpos,
- float user_znear,
- float user_zfar
-)
-{
- /*
- ** Compute the center of the box in world-space
- */
- Vector3 wrld_center;
- Matrix3D::Transform_Vector(tm,obj_box.Center,&wrld_center);
-
- /*
- ** Create a camera transform looking at the object.
- ** Set this as our transform later in this routine.
- */
- Matrix3D texture_tm,texture_tm_inv;
- texture_tm.Look_At(lightpos,wrld_center,0.0f);
- texture_tm.Get_Orthogonal_Inverse(texture_tm_inv);
-
- /*
- ** Calculate the axis-aligned bounding box of the model in the camera's coordinate system.
- */
- AABoxClass box = obj_box;
- Matrix3D obj_to_world = tm;
- Matrix3D obj_to_texture;
- Matrix3D::Multiply(texture_tm_inv,obj_to_world,&obj_to_texture);
- box.Transform(obj_to_texture);
-
- /*
- ** If the box is behind the viewpoint or the viewpoint is inside the box
- ** our FOV will be > 180 degrees. Have to give up
- */
- if ((box.Center.Z > 0.0f) || (box.Extent.Z > WWMath::Fabs(box.Center.Z))) {
- return false;
- }
-
- /*
- ** Compute the frustum parameters. Remember that our z coordinates are negative but the
- ** projection code needs positive z distances.
- */
- float znear = -box.Center.Z; //-(box.Center.Z + obj_box.Extent.Quick_Length());
- float zfar = -(box.Center.Z - obj_box.Extent.Quick_Length()) * 2.0f;
-
- if (user_znear != -1.0f) {
- znear = box.Center.Z + user_znear;
- }
- if (user_zfar != -1.0f) {
- zfar = box.Center.Z + user_zfar;
- }
-
- float tan_hfov2 = WWMath::Fabs(box.Extent.X / (box.Center.Z + box.Extent.Z));
- float tan_vfov2 = WWMath::Fabs(box.Extent.Y / (box.Center.Z + box.Extent.Z));
- float hfov = 2.0f * WWMath::Atan(tan_hfov2);
- float vfov = 2.0f * WWMath::Atan(tan_vfov2);
-
- /*
- ** Plug in the results.
- */
- Set_Perspective_Projection(hfov,vfov,znear,zfar);
- Set_Transform(texture_tm);
- return true;
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Compute_Ortho_Projection -- Automatic Orthographic projection *
- * *
- * Generates the orthographic projection parameters to tightly bound an object *
- * *
- * INPUT: *
- * model - object which we are created a projection of *
- * lightdir - directional light source *
- * znear - distance to near clipping plane for the projection (if -1.0, will be generated) *
- * zfar - distance to far clipping plane for the projection (if -1.0, will be generated) *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-bool TexProjectClass::Compute_Ortho_Projection
-(
- RenderObjClass * model,
- const Vector3 & lightdir,
- float znear,
- float zfar
-)
-{
- if (model == NULL) {
- WWDEBUG_SAY(("Attempting to generate projection for a NULL model"));
- return false;
- }
-
- AABoxClass box;
- model->Get_Obj_Space_Bounding_Box(box);
- const Matrix3D & tm = model->Get_Transform();
-
- return Compute_Ortho_Projection(box,tm,lightdir,znear,zfar);
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Compute_Ortho_Projection -- Automatic Orthographic projection *
- * *
- * Generates the orthographic projection parameters to tightly bound an object *
- * *
- * INPUT: *
- * obj_box - object space bounding box of the object we are projecting *
- * tm - transform of the object we are projecting *
- * lightdir - directional light *
- * user_znear - distance to near clipping plane for the projection (if -1.0, will be generated)*
- * user_zfar - distance to far clipping plane for the projection (if -1.0, will be generated) *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-bool TexProjectClass::Compute_Ortho_Projection
-(
- const AABoxClass & obj_box,
- const Matrix3D & tm,
- const Vector3 & lightdir,
- float user_znear,
- float user_zfar
-)
-{
- /*
- ** Compute the center of the box in world-space
- */
- AABoxClass wrldbox = obj_box;
- wrldbox.Transform(tm);
-
- /*
- ** Create a camera transform looking at the object.
- ** Set this as our transform later in this routine.
- */
- Vector3 camera_target = wrldbox.Center;
- Vector3 camera_position = camera_target - 2.0f * wrldbox.Extent.Length() * lightdir;
-
- Matrix3D texture_tm,texture_tm_inv;
- texture_tm.Look_At(camera_position,camera_target,0.0f);
- texture_tm.Get_Orthogonal_Inverse(texture_tm_inv);
-
- /*
- ** Calculate the axis-aligned bounding box of the model in the camera's coordinate system.
- */
- AABoxClass box = obj_box;
- Matrix3D obj_to_world = tm;
- Matrix3D obj_to_texture;
- Matrix3D::Multiply(texture_tm_inv,obj_to_world,&obj_to_texture);
- box.Transform(obj_to_texture);
-
- /*
- ** Expand the box to help with bounding box errors
- */
- box.Extent *= 1.0f;
-
- /*
- ** Compute the frustum parameters. Note that znear and zfar are supposed to
- ** be positive distances for the projection code.
- */
- float znear = -box.Center.Z; //-(box.Center.Z + obj_box.Extent.Quick_Length());
- float zfar = -(box.Center.Z - obj_box.Extent.Quick_Length()) * 2.0f;
-
- if (user_znear != -1.0f) {
- znear = -box.Center.Z + user_znear;
- }
- if (user_zfar != -1.0f) {
- zfar = -box.Center.Z + user_zfar;
- }
-
- /*
- ** All done!
- */
- Set_Ortho_Projection( box.Center.X - box.Extent.X,
- box.Center.X + box.Extent.X,
- box.Center.Y - box.Extent.Y,
- box.Center.Y + box.Extent.Y,
- znear,
- zfar );
- Set_Transform(texture_tm);
- return true;
-}
-
-/***********************************************************************************************
- * TexProjectClass::Compute_Texture -- Generates texture by rendering an object *
- * *
- * INPUT: *
- * model - pointer to the render object to generate a shadow texture for *
- * context - shadow render context which has been initialized to resolution *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-bool TexProjectClass::Compute_Texture
-(
- RenderObjClass * model,
- SpecialRenderInfoClass * context
-)
-{
- if ((model == NULL) || (context == NULL))
- {
- return false;
- }
- /*
- ** Render to texture
- */
- TextureClass * rtarget = Peek_Render_Target();
-
- if (rtarget != NULL)
- {
-
- /*
- ** Set the render target
- */
- DX8Wrapper::Set_Render_Target(rtarget);
-
- /*
- ** Set up the camera
- */
- Configure_Camera(context->Camera);
-
- /*
- ** Render the object
- */
- Vector3 color(0.0f,0.0f,0.0f);
- if (Get_Flag(ADDITIVE) == false) {
- color.Set(1.0f,1.0f,1.0f);
- }
-
- WW3D::Begin_Render(true,true,color);
- WW3D::Render(*model,*context);
- WW3D::End_Render(false);
-
- DX8Wrapper::Set_Render_Target((IDirect3DSurface8 *)NULL);
-
- }
-
-#if 0
-
- /*
- ** Render the object with the BW Renderer into our color surface
- */
- BWRenderClass bwr((unsigned char*)shadow_surface->getDataPtr(),tex_size);
- bwr.Fill(0xff);
- context->BWRenderer = &bwr;
- model->Special_Render(*context);
- context->BWRenderer = NULL;
-#endif
- return true;
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Needs_Render_Target -- returns wheter this projector needs a render target *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/17/2001 gth : Created. *
- *=============================================================================================*/
-bool TexProjectClass::Needs_Render_Target(void)
-{
- return Get_Flag(TEXTURE_DIRTY);
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Set_Render_Target -- Install a render target for this projector to use *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/16/2001 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Set_Render_Target
-(
- TextureClass* render_target
-)
-{
- REF_PTR_SET(RenderTarget,render_target);
- Set_Texture(RenderTarget);
-}
-
-/***********************************************************************************************
- * TexProjectClass::Peek_Render_Target -- Returns pointer to the render target if we have one *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/5/2001 gth : Created. *
- *=============================================================================================*/
-TextureClass* TexProjectClass::Peek_Render_Target
-(
- void
-)
-{
- return RenderTarget;
-}
-
-/***********************************************************************************************
- * TexProjectClass::Configure_Camera -- set up a camera to match this projector *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Configure_Camera(CameraClass & camera)
-{
- camera.Set_Transform(Transform);
- camera.Set_Clip_Planes(0.01f,ZFar);
-
- if (Get_Flag(PERSPECTIVE)) {
- camera.Set_Projection_Type(CameraClass::PERSPECTIVE);
- camera.Set_View_Plane(HFov,VFov);
-
- } else {
- camera.Set_Projection_Type(CameraClass::ORTHO);
- camera.Set_View_Plane(Vector2(XMin,YMin),Vector2(XMax,YMax));
- }
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Pre_Render_Update -- Prepare the projector for rendering *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Pre_Render_Update(const Matrix3D & camera)
-{
- /*
- ** Mview-texture = PShadow * Mwrld-texture * Mcamera-vrld
- */
- Matrix3D world_to_texture;
- Matrix3D tmp;
- Matrix4x4 view_to_texture;
-
- Transform.Get_Orthogonal_Inverse(world_to_texture);
- Matrix3D::Multiply(world_to_texture,camera,&tmp);
- Matrix4x4::Multiply(Projection,tmp,&view_to_texture);
-
- /*
- ** update the current intensity by iterating it towards the desired intensity
- */
- float intensity_delta = DesiredIntensity - Intensity;
- float max_intensity_delta = INTENSITY_RATE_OF_CHANGE * WW3D::Get_Logic_Frame_Time_Seconds();
-
- if (intensity_delta > max_intensity_delta) {
- Intensity += max_intensity_delta;
- } else if (intensity_delta < -max_intensity_delta) {
- Intensity -= max_intensity_delta;
- } else {
- Intensity = DesiredIntensity;
- }
-
- float actual_intensity = Intensity * Attenuation;
-
- /*
- ** install the current intensity
- */
- VertexMaterialClass * vmat = MaterialPass->Peek_Material();
- if (Get_Flag(ADDITIVE)) {
- vmat->Set_Emissive(actual_intensity,actual_intensity,actual_intensity);
- } else {
- vmat->Set_Emissive(1.0f - actual_intensity,1.0f - actual_intensity,1.0f - actual_intensity);
- }
-
- /*
- ** update the mappers
- */
- if (Get_Flag(PERSPECTIVE)) {
- Mapper->Set_Type(MatrixMapperClass::PERSPECTIVE_PROJECTION);
- } else {
- Mapper->Set_Type(MatrixMapperClass::ORTHO_PROJECTION);
- }
-
- if (Get_Texture_Size() == 0) {
-// SurfaceClass::SurfaceDescription surface_desc;
-// MaterialPass->Peek_Texture()->Get_Level_Description(surface_desc);
- Set_Texture_Size(MaterialPass->Peek_Texture()->Get_Width());
- WWASSERT(Get_Texture_Size() != 0);
- }
-
- Mapper->Set_Texture_Transform(view_to_texture,Get_Texture_Size());
- if (Mapper1) {
- Mapper1->Set_Texture_Transform(view_to_texture,Get_Texture_Size());
- }
-}
-
-
-/***********************************************************************************************
- * TexProjectClass::Update_WS_Bounding_Volume -- Recalculate the world-space bounding box *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/11/00 gth : Created. *
- *=============================================================================================*/
-void TexProjectClass::Update_WS_Bounding_Volume(void)
-{
- ProjectorClass::Update_WS_Bounding_Volume();
-
- /*
- ** Tell our culling system that we've changed
- */
- Vector3 extent;
- WorldBoundingVolume.Compute_Axis_Aligned_Extent(&extent);
- Set_Cull_Box(AABoxClass(WorldBoundingVolume.Center,extent));
-}
-
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.h
deleted file mode 100644
index 88ebc09e646..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texproject.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-/***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WW3D *
- * *
- * $Archive:: /Commando/Code/ww3d2/texproject.h $*
- * *
- * Original Author:: Greg Hjelstrom *
- * *
- * $Author:: Greg_h $*
- * *
- * $Modtime:: 4/23/01 7:29p $*
- * *
- * $Revision:: 6 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#pragma once
-
-#include "always.h"
-#include "matrix3d.h"
-#include "matrix4.h"
-#include "obbox.h"
-#include "matpass.h"
-#include "matrixmapper.h"
-#include "cullsys.h"
-#include "multilist.h"
-#include "projector.h"
-
-
-class SpecialRenderInfoClass;
-class RenderObjClass;
-class MaterialPassClass;
-class SurfaceClass;
-
-
-
-/**
-** TexProjectClass
-** This class is used to project textures onto object in the world. It contains
-** a pointer to the texture to be projected, a bounding volume for the projection,
-** and a material pass which can perform the projection.
-**
-** Design Goals:
-** - Texture Projectors should be easy to place in the world and move around.
-** solution: Store the bounding volume and any other parameters in a coordinate
-** system local to the projector. Update the world-space cache whenever needed.
-** The automatically generated shadow texture projectors are a special case subset
-** of the general texture projection code. For this reason, a local bounding
-** volume will be stored and its world-space equivalent will be updated whenever
-** needed.
-**
-** - Texture projectors need to be compatible with the culling systems.
-** solution: inherit the Cullable interface.
-**
-** - Texture projectors need to be quickly pulled in and out of many lists during
-** the rendering process.
-** solution: list system similar to PhysListClass? I really need to templatize this.
-** - done: MultiListClass!
-**
-** - Dynamic Texture projectors need to be updated in stages. Update/recompute only the
-** bounding volume first, then defer computing the actual texture until it is
-** determined that the volume falls into the frustum and is applied to at least one
-** object.
-** solution: Code the bounding volume/projection paramter generation separate from
-** the texture generation code. A derived texture projection object. Let texture
-** projectors know about the object they are projecting so that they can have that
-** object rendered from the desired viewpoint. Need a 'Dirty' flag and a pointer to
-** a 'parent' object. Perhaps separate this code into a ShadowProjectClass since shadows
-** are the only case I can think of that need the ability to re-render their 'parent'
-** object. Everything else should be a static texture-map either generated 'artistically'
-** or generated off-line.
-**
-*/
-class TexProjectClass : public ProjectorClass, public CullableClass, public MultiListObjectClass
-{
-public:
-
- TexProjectClass(void);
- virtual ~TexProjectClass(void);
-
- /*
- ** Material settings
- */
- void Set_Texture_Size(int size);
- int Get_Texture_Size(void);
- void Init_Multiplicative(void);
- void Init_Additive(void);
- void Set_Intensity(float intensity,bool immediate = false); // 1.0 = on 100%, 0.0 = 'off'
- float Get_Intensity(void);
- bool Is_Intensity_Zero(void);
- void Set_Attenuation(float attenuation); // 1.0 = on, 0.0 = off
- float Get_Attenuation(void);
- void Enable_Attenuation(bool onoff);
- bool Is_Attenuation_Enabled(void);
- MaterialPassClass * Peek_Material_Pass(void);
-
- /*
- ** Options
- */
- void Enable_Affect_Dynamic_Objects(bool onoff) { Set_Flag(AFFECT_DYNAMIC_OBJS,onoff); }
- bool Is_Affect_Dynamic_Objects_Enabled(void) { return Get_Flag(AFFECT_DYNAMIC_OBJS); }
- void Enable_Affect_Static_Objects(bool onoff) { Set_Flag(AFFECT_STATIC_OBJS,onoff); }
- bool Is_Affect_Static_Objects_Enabled(void) { return Get_Flag(AFFECT_STATIC_OBJS); }
- void Enable_Depth_Gradient(bool onoff);
- bool Is_Depth_Gradient_Enabled(bool onoff);
-
- /*
- ** Manual initialization of a TexProjectClass
- ** 1 - call ProjectorClass::Set_Transform
- ** 2 - call Set_Projection_Perspective -or- Set_Projection_Ortho
- ** 3 - call Set_Texture.
- */
- virtual void Set_Perspective_Projection(float hfov,float vfov,float znear,float zfar);
- virtual void Set_Ortho_Projection(float xmin,float xmax,float ymin,float ymax,float znear,float zfar);
-
- void Set_Texture(TextureClass * texture);
- TextureClass * Get_Texture(void) const;
- TextureClass * Peek_Texture(void) const;
-
- /*
- ** Automatic initialization of a TexProjectClass.
- ** First set up your projection parameters, give the projector a render target, then call Compute_Texture
- */
- bool Compute_Perspective_Projection(RenderObjClass * obj,const Vector3 & lightpos,float znear=-1.0f,float zfar=-1.0f);
- bool Compute_Perspective_Projection(const AABoxClass & obj_box,const Matrix3D & tm,const Vector3 & lightpos,float znear=-1.0f,float zfar=-1.0f);
-
- bool Compute_Ortho_Projection(RenderObjClass * obj,const Vector3 & lightdir,float znear=-1.0f,float zfar=-1.0f);
- bool Compute_Ortho_Projection(const AABoxClass & obj_box,const Matrix3D & tm,const Vector3 & lightdir,float znear=-1.0f,float zfar=-1.0f);
-
- bool Needs_Render_Target(void);
- void Set_Render_Target(TextureClass * render_target);
- TextureClass * Peek_Render_Target(void);
-
- bool Compute_Texture(RenderObjClass * model,SpecialRenderInfoClass * context);
-
- /*
- ** Prep for rendering, called by the scene prior to usage.
- */
- virtual void Pre_Render_Update(const Matrix3D & camera);
-
- /*
- ** virtual interface for getting the pointer of the object that generated this shadow.
- ** defaults to returning NULL. This is implemented by some derived classes and used by
- ** the system to prevent a projection from being applied to the object that generated
- ** the projection...
- ** (gth) feels kludgy, this got a little messy when I moved this code into WW3D from WWPhys
- */
- virtual void * Get_Projection_Object_ID(void) const { return NULL; }
-
-protected:
-
- void Set_Flag(uint32 flag,bool onoff);
- bool Get_Flag(uint32 flag) const;
- virtual void Update_WS_Bounding_Volume(void);
- void Configure_Camera(CameraClass & camera);
-
- enum FlagsType
- {
- PERSPECTIVE = 0x00000001, // PERSPECTIVE or ORTHO
- ADDITIVE = 0x00000002, // ADDITIVE or MULTIPLICATIVE
- TEXTURE_DIRTY = 0x00000004, // used by derived DynTexProjectClass
- VOLATILE = 0x00000008, // this is a volatile texture.
- ATTENUATE = 0x00000010, // this projector should be attenuated based on distance to viewer
- AFFECT_DYNAMIC_OBJS = 0x00000020, // this projector affects dynamic objects
- AFFECT_STATIC_OBJS = 0x00000040, // this projector affects static objects
- USE_DEPTH_GRADIENT = 0x00000080, // fade the projection as a function of depth
- HAS_RENDER_TARGET = 0x00000100, // the texture we have can be a render target
- SIZE_MASK = 0xFFF00000, // desired texture size stored in upper 3 nibbles
- SIZE_SHIFT = 20,
-
- DEFAULT_FLAGS = ATTENUATE | AFFECT_DYNAMIC_OBJS | AFFECT_STATIC_OBJS | (64< TexProjListClass;
-typedef RefMultiListIterator TexProjListIterator;
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.cpp
deleted file mode 100644
index 8aa82bd6e58..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.cpp
+++ /dev/null
@@ -1,892 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-/***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WW3D *
- * *
- * $Archive:: /Commando/Code/ww3d2/texture.cpp $*
- * *
- * $Author:: Jani_p $*
- * *
- * $Modtime:: 8/29/01 7:06p $*
- * *
- * $Revision:: 65 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * FileListTextureClass::Load_Frame_Surface -- Load source texture *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#include "texture.h"
-
-#include
-#include
-#include "dx8wrapper.h"
-#include "TARGA.h"
-#include
-#include "w3d_file.h"
-#include "assetmgr.h"
-#include "formconv.h"
-#include "textureloader.h"
-#include "missingtexture.h"
-#include "ffactory.h"
-#include "dx8caps.h"
-#include "dx8texman.h"
-#include "meshmatdesc.h"
-
-/*
-** Definitions of static members:
-*/
-
-static unsigned unused_texture_id;
-
-// ----------------------------------------------------------------------------
-
-static int Calculate_Texture_Memory_Usage(const TextureClass* texture,int red_factor=0)
-{
- // Set performance statistics
-
- int size=0;
- IDirect3DTexture8* d3d_texture=const_cast(texture)->Peek_D3D_Texture();
- if (!d3d_texture) return 0;
- for (unsigned i=red_factor;iGetLevelCount();++i) {
- D3DSURFACE_DESC desc;
- DX8_ErrorCode(d3d_texture->GetLevelDesc(i,&desc));
- size+=desc.Size;
- }
- return size;
-}
-
-/*************************************************************************
-** TextureClass
-*************************************************************************/
-
-TextureClass::TextureClass(unsigned width, unsigned height, WW3DFormat format, MipCountType mip_level_count, PoolType pool,bool rendertarget)
- :
- D3DTexture(NULL),
- texture_id(unused_texture_id++),
- Initialized(true),
- Filter(mip_level_count),
- MipLevelCount(mip_level_count),
- Pool(pool),
- Dirty(false),
- IsLightmap(false),
- IsProcedural(true),
- Name(""),
- TextureFormat(format),
- IsCompressionAllowed(false),
- TextureLoadTask(NULL),
- Width(width),
- Height(height)
-{
- switch (format)
- {
- case WW3D_FORMAT_DXT1:
- case WW3D_FORMAT_DXT2:
- case WW3D_FORMAT_DXT3:
- case WW3D_FORMAT_DXT4:
- case WW3D_FORMAT_DXT5:
- IsCompressionAllowed=true;
- break;
- default : break;
- }
-
- D3DPOOL d3dpool=(D3DPOOL)0;
- switch(pool)
- {
- case POOL_DEFAULT : d3dpool=D3DPOOL_DEFAULT; break;
- case POOL_MANAGED : d3dpool=D3DPOOL_MANAGED; break;
- case POOL_SYSTEMMEM : d3dpool=D3DPOOL_SYSTEMMEM; break;
- default: WWASSERT(0);
- }
- D3DTexture = DX8Wrapper::_Create_DX8_Texture(width, height, format, mip_level_count,d3dpool,rendertarget);
- if (pool==POOL_DEFAULT)
- {
- Dirty=true;
- DX8TextureTrackerClass *track=W3DNEW DX8TextureTrackerClass
- (
- width,
- height,
- format,
- mip_level_count,
- this,
- rendertarget
- );
- DX8TextureManagerClass::Add(track);
- }
- LastAccessed=WW3D::Get_Sync_Time();
-}
-
-// ----------------------------------------------------------------------------
-
-TextureClass::TextureClass
-(
- const char *name,
- const char *full_path,
- MipCountType mip_level_count,
- WW3DFormat texture_format,
- bool allow_compression)
- :
- D3DTexture(NULL),
- texture_id(unused_texture_id++),
- Initialized(false),
- Filter(mip_level_count),
- MipLevelCount(mip_level_count),
- Pool(POOL_MANAGED),
- Dirty(false),
- IsLightmap(false),
- IsProcedural(false),
- TextureFormat(texture_format),
- IsCompressionAllowed(allow_compression),
- TextureLoadTask(NULL),
- Width(0),
- Height(0)
-{
- switch (TextureFormat)
- {
- case WW3D_FORMAT_DXT1:
- case WW3D_FORMAT_DXT2:
- case WW3D_FORMAT_DXT3:
- case WW3D_FORMAT_DXT4:
- case WW3D_FORMAT_DXT5:
- IsCompressionAllowed=true;
- break;
- case WW3D_FORMAT_U8V8: // Bumpmap
- case WW3D_FORMAT_L6V5U5: // Bumpmap
- case WW3D_FORMAT_X8L8V8U8: // Bumpmap
- // If requesting bumpmap format that isn't available we'll just return the surface in whatever color
- // format the texture file is in. (This is illegal case, the format support should always be queried
- // before creating a bump texture!)
- if (!DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(TextureFormat))
- {
- TextureFormat=WW3D_FORMAT_UNKNOWN;
- }
- // If bump format is valid, make sure compression is not allowed so that we don't even attempt to load
- // from a compressed file (quality isn't good enough for bump map). Also disable mipmapping.
- else
- {
- IsCompressionAllowed=false;
- MipLevelCount=MIP_LEVELS_1;
- Filter.Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_NONE);
- }
- break;
- default: break;
- }
-
- WWASSERT_PRINT(name && name[0], "TextureClass CTor: NULL or empty texture name");
- int len=strlen(name);
- for (int i=0;iGet_Surface_Format()),
- IsCompressionAllowed(false),
- TextureLoadTask(NULL),
- Width(0),
- Height(0)
-{
- SurfaceClass::SurfaceDescription sd;
- surface->Get_Description(sd);
- Width=sd.Width;
- Height=sd.Height;
- switch (sd.Format)
- {
- case WW3D_FORMAT_DXT1:
- case WW3D_FORMAT_DXT2:
- case WW3D_FORMAT_DXT3:
- case WW3D_FORMAT_DXT4:
- case WW3D_FORMAT_DXT5:
- IsCompressionAllowed=true;
- break;
- default: break;
- }
-
- D3DTexture = DX8Wrapper::_Create_DX8_Texture(surface->Peek_D3D_Surface(), mip_level_count);
- LastAccessed=WW3D::Get_Sync_Time();
-}
-
-// ----------------------------------------------------------------------------
-
-TextureClass::TextureClass(IDirect3DTexture8* d3d_texture)
- :
- D3DTexture(d3d_texture),
- texture_id(unused_texture_id++),
- Initialized(true),
- Filter((MipCountType)d3d_texture->GetLevelCount()),
- MipLevelCount((MipCountType)d3d_texture->GetLevelCount()),
- Pool(POOL_MANAGED),
- Dirty(false),
- IsLightmap(false),
- Name(""),
- IsProcedural(true),
- IsCompressionAllowed(false),
- TextureLoadTask(NULL),
- Width(0),
- Height(0)
-{
- D3DTexture->AddRef();
- IDirect3DSurface8* surface;
- DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0,&surface));
- D3DSURFACE_DESC d3d_desc;
- ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC));
- DX8_ErrorCode(surface->GetDesc(&d3d_desc));
- Width=d3d_desc.Width;
- Height=d3d_desc.Height;
- TextureFormat=D3DFormat_To_WW3DFormat(d3d_desc.Format);
- switch (TextureFormat)
- {
- case WW3D_FORMAT_DXT1:
- case WW3D_FORMAT_DXT2:
- case WW3D_FORMAT_DXT3:
- case WW3D_FORMAT_DXT4:
- case WW3D_FORMAT_DXT5:
- IsCompressionAllowed=true;
- break;
- default: break;
- }
-
- LastAccessed=WW3D::Get_Sync_Time();
-}
-
-// ----------------------------------------------------------------------------
-
-TextureClass::~TextureClass(void)
-{
- TextureLoadTaskClass::Release_Instance(TextureLoadTask);
- TextureLoadTask=NULL;
-
- if (!Initialized) {
- WWDEBUG_SAY(("Warning: Texture %s was loaded but never used",Get_Texture_Name().str()));
- }
-
- if (D3DTexture) {
- D3DTexture->Release();
- D3DTexture = NULL;
- }
- DX8TextureManagerClass::Remove(this);
-}
-
-// ----------------------------------------------------------------------------
-
-void TextureClass::Init()
-{
- // If the texture has already been initialised we should exit now
- if (Initialized) return;
-
- TextureLoader::Add_Load_Task(this);
- LastAccessed=WW3D::Get_Sync_Time();
-}
-
-void TextureClass::Invalidate()
-{
- // Don't invalidate procedural textures
- if (IsProcedural) return;
-
- // Don't invalidate missing texture
- if (Is_Missing_Texture()) return;
-
- if (D3DTexture) {
- D3DTexture->Release();
- D3DTexture = NULL;
- }
-
- if (!WW3D::Is_Texturing_Enabled()) {
- Initialized=true;
- D3DTexture=0;
- }
- else if (WW3D::Get_Thumbnail_Enabled()==false || MipLevelCount==MIP_LEVELS_1)
- {
- Initialized=true;
- D3DTexture=0;
- TextureLoader::Request_High_Priority_Loading(this,MipLevelCount);
- }
- else {
- Initialized=false;
- Load_Locked_Surface();
- }
-}
-
-//**********************************************************************************************
-//! Returns a pointer to the d3d texture
-/*!
-*/
-IDirect3DBaseTexture8 * TextureClass::Peek_D3D_Base_Texture() const
-{
- LastAccessed=WW3D::Get_Sync_Time();
- return D3DTexture;
-}
-
-//**********************************************************************************************
-//! Set the d3d texture pointer. Handles ref counts properly.
-/*!
-*/
-void TextureClass::Set_D3D_Base_Texture(IDirect3DBaseTexture8* tex)
-{
- // (gth) Generals does stuff directly with the D3DTexture pointer so lets
- // reset the access timer whenever someon messes with this pointer.
- LastAccessed=WW3D::Get_Sync_Time();
-
- if (D3DTexture != NULL) {
- D3DTexture->Release();
- }
- D3DTexture = tex;
- if (D3DTexture != NULL) {
- D3DTexture->AddRef();
- }
-}
-
-// ----------------------------------------------------------------------------
-
-void TextureClass::Load_Locked_Surface()
-{
- if (D3DTexture) D3DTexture->Release();
- D3DTexture=0;
- TextureLoader::Request_Thumbnail(this);
- Initialized=false;
-}
-
-// ----------------------------------------------------------------------------
-
-bool TextureClass::Is_Missing_Texture()
-{
- bool flag = false;
- IDirect3DTexture8 *missing_texture = MissingTexture::_Get_Missing_Texture();
-
- if(D3DTexture == missing_texture)
- flag = true;
-
- if(missing_texture)
- missing_texture->Release();
-
- return flag;
-}
-
-// ----------------------------------------------------------------------------
-
-void TextureClass::Set_Texture_Name(const char * name)
-{
- Name=name;
-}
-
-// ----------------------------------------------------------------------------
-
-unsigned int TextureClass::Get_Mip_Level_Count(void)
-{
- if (!D3DTexture) {
- WWASSERT_PRINT(0, "Get_Mip_Level_Count: D3DTexture is NULL!");
- return 0;
- }
-
- return D3DTexture->GetLevelCount();
-}
-
-// ----------------------------------------------------------------------------
-
-void TextureClass::Get_Level_Description(SurfaceClass::SurfaceDescription &surface_desc, unsigned int level)
-{
- if (!D3DTexture) {
- WWASSERT_PRINT(0, "Get_Surface_Description: D3DTexture is NULL!");
- }
-
- D3DSURFACE_DESC d3d_surf_desc;
- DX8_ErrorCode(Peek_D3D_Texture()->GetLevelDesc(level, &d3d_surf_desc));
- surface_desc.Format = D3DFormat_To_WW3DFormat(d3d_surf_desc.Format);
- surface_desc.Height = d3d_surf_desc.Height;
- surface_desc.Width = d3d_surf_desc.Width;
-}
-
-// ----------------------------------------------------------------------------
-
-SurfaceClass *TextureClass::Get_Surface_Level(unsigned int level)
-{
- IDirect3DSurface8 *d3d_surface = NULL;
- DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(level, &d3d_surface));
- SurfaceClass *surface = W3DNEW SurfaceClass(d3d_surface);
- d3d_surface->Release();
- return surface;
-}
-
-// ----------------------------------------------------------------------------
-
-unsigned int TextureClass::Get_Priority(void)
-{
- if (!D3DTexture) {
- WWASSERT_PRINT(0, "Get_Priority: D3DTexture is NULL!");
- return 0;
- }
-
- return D3DTexture->GetPriority();
-}
-
-// ----------------------------------------------------------------------------
-
-unsigned int TextureClass::Set_Priority(unsigned int priority)
-{
- if (!D3DTexture) {
- WWASSERT_PRINT(0, "Set_Priority: D3DTexture is NULL!");
- return 0;
- }
-
- return D3DTexture->SetPriority(priority);
-}
-
-unsigned TextureClass::Get_Reduction() const
-{
- if (MipLevelCount==MIP_LEVELS_1) return 0;
-
- int reduction=WW3D::Get_Texture_Reduction();
- if (MipLevelCount && reduction>MipLevelCount) {
- reduction=MipLevelCount;
- }
- return reduction;
-}
-
-// ----------------------------------------------------------------------------
-
-void TextureClass::Apply(unsigned int stage)
-{
- if (!Initialized)
- {
- Init();
- }
- LastAccessed=WW3D::Get_Sync_Time();
-
- DX8_RECORD_TEXTURE(this);
-
- // Set texture itself
- if (WW3D::Is_Texturing_Enabled())
- {
- DX8Wrapper::Set_DX8_Texture(stage, D3DTexture);
- }
- else
- {
- DX8Wrapper::Set_DX8_Texture(stage, NULL);
- }
-
- Filter.Apply(stage);
-}
-
-// ----------------------------------------------------------------------------
-
-void TextureClass::Apply_Null(unsigned int stage)
-{
- // This function sets the render states for a "NULL" texture
- DX8Wrapper::Set_DX8_Texture(stage, NULL);
-}
-
-// ----------------------------------------------------------------------------
-
-void TextureClass::Apply_New_Surface(bool initialized)
-{
- if (D3DTexture) D3DTexture->Release();
- D3DTexture=TextureLoadTask->Peek_D3D_Texture();
- D3DTexture->AddRef();
- if (initialized) Initialized=true;
-
- WWASSERT(D3DTexture);
- IDirect3DSurface8* surface;
- DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0,&surface));
- D3DSURFACE_DESC d3d_desc;
- ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC));
- DX8_ErrorCode(surface->GetDesc(&d3d_desc));
-// if (TextureFormat==WW3D_FORMAT_UNKNOWN) {
- TextureFormat=D3DFormat_To_WW3DFormat(d3d_desc.Format);
- Width=d3d_desc.Width;
- Height=d3d_desc.Height;
-// }
-// else {
-// WWASSERT(D3DFormat_To_WW3DFormat(d3d_desc.Format)==TextureFormat);
-// }
- surface->Release();
-}
-
-// ----------------------------------------------------------------------------
-
-unsigned TextureClass::Get_Texture_Memory_Usage() const
-{
- if (/*!ReductionEnabled || */!Initialized) return Calculate_Texture_Memory_Usage(this,0);
-// unsigned reduction=WW3D::Get_Texture_Reduction();
-// if (CurrentReductionFactor>reduction) reduction=CurrentReductionFactor;
- return Calculate_Texture_Memory_Usage(this,0);//reduction);
-}
-
-// ----------------------------------------------------------------------------
-
-int TextureClass::_Get_Total_Locked_Surface_Size()
-{
- int total_locked_surface_size=0;
-
- HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
-
- // Get the current texture
- TextureClass* tex=ite.Peek_Value();
- if (!tex->Initialized) {
-// total_locked_surface_size+=tex->Get_Non_Reduced_Texture_Memory_Usage();
- total_locked_surface_size+=tex->Get_Texture_Memory_Usage();
- }
- }
- return total_locked_surface_size;
-}
-
-// ----------------------------------------------------------------------------
-
-int TextureClass::_Get_Total_Texture_Size()
-{
- int total_texture_size=0;
-
- HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- // Get the current texture
- TextureClass* tex=ite.Peek_Value();
- total_texture_size+=tex->Get_Texture_Memory_Usage();
- }
- return total_texture_size;
-}
-
-// ----------------------------------------------------------------------------
-
-int TextureClass::_Get_Total_Lightmap_Texture_Size()
-{
- int total_texture_size=0;
-
- HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- // Get the current texture
- TextureClass* tex=ite.Peek_Value();
- if (tex->Is_Lightmap()) {
- total_texture_size+=tex->Get_Texture_Memory_Usage();
- }
- }
- return total_texture_size;
-}
-
-// ----------------------------------------------------------------------------
-
-int TextureClass::_Get_Total_Procedural_Texture_Size()
-{
- int total_texture_size=0;
-
- HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- // Get the current texture
- TextureClass* tex=ite.Peek_Value();
- if (tex->Is_Procedural()) {
- total_texture_size+=tex->Get_Texture_Memory_Usage();
- }
- }
- return total_texture_size;
-}
-
-// ----------------------------------------------------------------------------
-
-int TextureClass::_Get_Total_Texture_Count()
-{
- int texture_count=0;
-
- HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- texture_count++;
- }
-
- return texture_count;
-}
-
-// ----------------------------------------------------------------------------
-
-int TextureClass::_Get_Total_Lightmap_Texture_Count()
-{
- int texture_count=0;
-
- HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- if (ite.Peek_Value()->Is_Lightmap()) {
- texture_count++;
- }
- }
-
- return texture_count;
-}
-
-// ----------------------------------------------------------------------------
-
-int TextureClass::_Get_Total_Procedural_Texture_Count()
-{
- int texture_count=0;
-
- HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- if (ite.Peek_Value()->Is_Procedural()) {
- texture_count++;
- }
- }
-
- return texture_count;
-}
-
-// ----------------------------------------------------------------------------
-
-int TextureClass::_Get_Total_Locked_Surface_Count()
-{
- int texture_count=0;
-
- HashTemplateIterator ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- // Get the current texture
- TextureClass* tex=ite.Peek_Value();
- if (!tex->Initialized) {
- texture_count++;
- }
- }
-
- return texture_count;
-}
-/*
-bool Validate_Filters(unsigned type)
-{
- ShaderClass shader=ShaderClass::_PresetOpaqueShader;
- shader.Apply();
- DX8Wrapper::Set_DX8_Texture(0, MissingTexture::_Get_Missing_Texture());
- DX8Wrapper::Set_DX8_Texture_Stage_State(0,D3DTSS_MINFILTER,_MinTextureFilters[type]);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0,D3DTSS_MAGFILTER,_MagTextureFilters[type]);
- DX8Wrapper::Set_DX8_Texture_Stage_State(0,D3DTSS_MIPFILTER,_MipMapFilters[type]);
- unsigned long passes;
- HRESULT hres=DX8Wrapper::_Get_D3D_Device8()->ValidateDevice(&passes);
- return !FAILED(hres);
-}
-*/
-
-
-// Utility functions
-TextureClass* Load_Texture(ChunkLoadClass & cload)
-{
- // Assume failure
- TextureClass *newtex = NULL;
-
- char name[256];
- if (cload.Open_Chunk () && (cload.Cur_Chunk_ID () == W3D_CHUNK_TEXTURE))
- {
-
- W3dTextureInfoStruct texinfo;
- bool hastexinfo = false;
-
- /*
- ** Read in the texture filename, and a possible texture info structure.
- */
- while (cload.Open_Chunk()) {
- switch (cload.Cur_Chunk_ID()) {
- case W3D_CHUNK_TEXTURE_NAME:
- cload.Read(&name,cload.Cur_Chunk_Length());
- break;
-
- case W3D_CHUNK_TEXTURE_INFO:
- cload.Read(&texinfo,sizeof(W3dTextureInfoStruct));
- hastexinfo = true;
- break;
- };
- cload.Close_Chunk();
- }
- cload.Close_Chunk();
-
- /*
- ** Get the texture from the asset manager
- */
- if (hastexinfo)
- {
-
- MipCountType mipcount;
-
- bool no_lod = ((texinfo.Attributes & W3DTEXTURE_NO_LOD) == W3DTEXTURE_NO_LOD);
-
- if (no_lod)
- {
- mipcount = MIP_LEVELS_1;
- }
- else
- {
- switch (texinfo.Attributes & W3DTEXTURE_MIP_LEVELS_MASK) {
-
- case W3DTEXTURE_MIP_LEVELS_ALL:
- mipcount = MIP_LEVELS_ALL;
- break;
-
- case W3DTEXTURE_MIP_LEVELS_2:
- mipcount = MIP_LEVELS_2;
- break;
-
- case W3DTEXTURE_MIP_LEVELS_3:
- mipcount = MIP_LEVELS_3;
- break;
-
- case W3DTEXTURE_MIP_LEVELS_4:
- mipcount = MIP_LEVELS_4;
- break;
-
- default:
- WWASSERT (false);
- mipcount = MIP_LEVELS_ALL;
- break;
- }
- }
- newtex = WW3DAssetManager::Get_Instance()->Get_Texture (name, mipcount);
-
- if (no_lod)
- {
- newtex->Get_Filter().Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_NONE);
- }
- bool u_clamp = ((texinfo.Attributes & W3DTEXTURE_CLAMP_U) != 0);
- newtex->Get_Filter().Set_U_Addr_Mode(u_clamp ? TextureFilterClass::TEXTURE_ADDRESS_CLAMP : TextureFilterClass::TEXTURE_ADDRESS_REPEAT);
- bool v_clamp = ((texinfo.Attributes & W3DTEXTURE_CLAMP_V) != 0);
- newtex->Get_Filter().Set_V_Addr_Mode(v_clamp ? TextureFilterClass::TEXTURE_ADDRESS_CLAMP : TextureFilterClass::TEXTURE_ADDRESS_REPEAT);
-
- switch (texinfo.Attributes & W3DTEXTURE_TYPE_MASK)
- {
-
- case W3DTEXTURE_TYPE_COLORMAP:
- // Do nothing.
- break;
-
- case W3DTEXTURE_TYPE_BUMPMAP:
- {
- TextureClass *releasetex = newtex;
-
- // Format is assumed to be a grayscale heightmap. Convert it to a bump map.
- newtex = WW3DAssetManager::Get_Instance()->Get_Bumpmap_Based_On_Texture (newtex);
- WW3DAssetManager::Get_Instance()->Release_Texture (releasetex);
- break;
- }
-
- default:
- WWASSERT (false);
- break;
- }
-
- } else {
- newtex = WW3DAssetManager::Get_Instance()->Get_Texture(name);
- }
-
- WWASSERT(newtex);
- }
-
- // Return a pointer to the new texture
- return newtex;
-}
-
-// Utility function used by Save_Texture
-void setup_texture_attributes(TextureClass * tex, W3dTextureInfoStruct * texinfo)
-{
- texinfo->Attributes = 0;
-
- if (tex->Get_Filter().Get_Mip_Mapping() == TextureFilterClass::FILTER_TYPE_NONE) texinfo->Attributes |= W3DTEXTURE_NO_LOD;
- if (tex->Get_Filter().Get_U_Addr_Mode() == TextureFilterClass::TEXTURE_ADDRESS_CLAMP) texinfo->Attributes |= W3DTEXTURE_CLAMP_U;
- if (tex->Get_Filter().Get_V_Addr_Mode() == TextureFilterClass::TEXTURE_ADDRESS_CLAMP) texinfo->Attributes |= W3DTEXTURE_CLAMP_V;
-}
-
-
-void Save_Texture(TextureClass * texture,ChunkSaveClass & csave)
-{
- const char * filename;
- W3dTextureInfoStruct texinfo;
- memset(&texinfo,0,sizeof(texinfo));
-
- filename = texture->Get_Full_Path();
-
- setup_texture_attributes(texture, &texinfo);
-
- csave.Begin_Chunk(W3D_CHUNK_TEXTURE_NAME);
- csave.Write(filename,strlen(filename)+1);
- csave.End_Chunk();
-
- if ((texinfo.Attributes != 0) || (texinfo.AnimType != 0) || (texinfo.FrameCount != 0)) {
- csave.Begin_Chunk(W3D_CHUNK_TEXTURE_INFO);
- csave.Write(&texinfo, sizeof(texinfo));
- csave.End_Chunk();
- }
-}
-
-// ----------------------------------------------------------------------------
-
-BumpmapTextureClass::BumpmapTextureClass(TextureClass* texture)
- :
-// TextureClass(texture->Get_Width(),texture->Get_Height(),texture->Get_Textur4e_Format(),MIP_LEVELS_1)
- TextureClass(TextureLoader::Generate_Bumpmap(texture))
-{
-// D3DTexture=TextureLoader::Generate_Bumpmap(texture);
-// TextureLoader:::Generage_Bumpmap
-}
-
-BumpmapTextureClass::~BumpmapTextureClass()
-{
-}
-
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.h
deleted file mode 100644
index 2efaef8a16d..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texture.h
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-/***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WW3D *
- * *
- * $Archive:: /Commando/Code/ww3d2/texture.h $*
- * *
- * $Author:: Jani_p $*
- * *
- * $Modtime:: 8/17/01 9:41a $*
- * *
- * $Revision:: 35 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#pragma once
-
-#include "always.h"
-#include "chunkio.h"
-#include "surfaceclass.h"
-#include "ww3dformat.h"
-#include "wwstring.h"
-#include "texturefilter.h"
-
-struct IDirect3DBaseTexture8;
-struct IDirect3DTexture8;
-
-class DX8Wrapper;
-class TextureLoader;
-class LoaderThreadClass;
-class DX8TextureManagerClass;
-class TextureLoadTaskClass;
-
-/*************************************************************************
-** TextureClass
-**
-** This is our texture class. For legacy reasons it contains some
-** information beyond the D3D texture itself, such as texture addressing
-** modes.
-**
-*************************************************************************/
-class TextureClass : public W3DMPO, public RefCountClass
-{
- W3DMPO_GLUE(TextureClass)
-
- friend class DX8TextureTrackerClass; //(gth) so it can call Poke_Texture,
-
- friend DX8Wrapper;
- friend TextureLoader;
- friend LoaderThreadClass;
- friend DX8TextureManagerClass;
-
- public:
-
- enum PoolType {
- POOL_DEFAULT=0,
- POOL_MANAGED,
- POOL_SYSTEMMEM
- };
-
- enum TexAssetType
- {
- TEX_REGULAR,
- };
-
- // Create texture with desired height, width and format.
- TextureClass(
- unsigned width,
- unsigned height,
- WW3DFormat format,
- MipCountType mip_level_count=MIP_LEVELS_ALL,
- PoolType pool=POOL_MANAGED,
- bool rendertarget=false);
-
- // Create texture from a file. If format is specified the texture is converted to that format.
- // Note that the format must be supported by the current device and that a texture can't exist
- // in the system with the same name in multiple formats.
- TextureClass(
- const char *name,
- const char *full_path=NULL,
- MipCountType mip_level_count=MIP_LEVELS_ALL,
- WW3DFormat texture_format=WW3D_FORMAT_UNKNOWN,
- bool allow_compression=true);
-
- // Create texture from a surface.
- TextureClass(
- SurfaceClass *surface,
- MipCountType mip_level_count=MIP_LEVELS_ALL);
-
- TextureClass(IDirect3DTexture8* d3d_texture);
-
- virtual TexAssetType Get_Asset_Type() const { return TEX_REGULAR; }
-
- virtual ~TextureClass(void);
-
- // Names
- void Set_Texture_Name(const char * name);
- void Set_Full_Path(const char * path) { FullPath = path; }
- const StringClass& Get_Texture_Name(void) const { return Name; }
- const StringClass& Get_Full_Path(void) const { if (FullPath.Is_Empty ()) return Name; return FullPath; }
-
- unsigned Get_ID() const { return texture_id; } // Each textrure has a unique id
-
- // The number of Mip levels in the texture
- unsigned int Get_Mip_Level_Count(void);
-
- // Note! Width and Height may be zero and may change if texture uses mipmaps
- int Get_Width() const
- {
- return Width;
- }
- int Get_Height() const
- {
- return Height;
- }
-
- // Get surface description of a Mip level (defaults to the highest-resolution one)
- void Get_Level_Description(SurfaceClass::SurfaceDescription &surface_desc, unsigned int level = 0);
-
- TextureFilterClass& Get_Filter() { return Filter; }
-
- // Get the surface of one of the mipmap levels (defaults to highest-resolution one)
- SurfaceClass *Get_Surface_Level(unsigned int level = 0);
-
- // Texture priority affects texture management and caching.
- unsigned int Get_Priority(void);
- unsigned int Set_Priority(unsigned int priority); // Returns previous priority
-
- // Debug utility functions for returning the texture memory usage
- unsigned Get_Texture_Memory_Usage() const;
- bool Is_Initialized() const { return Initialized; }
- bool Is_Lightmap() const { return IsLightmap; }
- bool Is_Procedural() const { return IsProcedural; }
-
- static int _Get_Total_Locked_Surface_Size();
- static int _Get_Total_Texture_Size();
- static int _Get_Total_Lightmap_Texture_Size();
- static int _Get_Total_Procedural_Texture_Size();
- static int _Get_Total_Locked_Surface_Count();
- static int _Get_Total_Texture_Count();
- static int _Get_Total_Lightmap_Texture_Count();
- static int _Get_Total_Procedural_Texture_Count();
-
- static void _Set_Default_Min_Filter(TextureFilterClass::FilterType filter);
- static void _Set_Default_Mag_Filter(TextureFilterClass::FilterType filter);
- static void _Set_Default_Mip_Filter(TextureFilterClass::FilterType filter);
-
- // This utility function processes the texture reduction (used during rendering)
- void Invalidate();
-
- IDirect3DTexture8 *Peek_D3D_Texture() const { return (IDirect3DTexture8 *)Peek_D3D_Base_Texture(); }
-
- // texture accessors (dx8)
- IDirect3DBaseTexture8 *Peek_D3D_Base_Texture() const;
- void Set_D3D_Base_Texture(IDirect3DBaseTexture8* tex);
-
- PoolType Get_Pool() const { return Pool; }
-
- bool Is_Missing_Texture();
-
- // Support for self managed textures
- bool Is_Dirty() { WWASSERT(Pool==POOL_DEFAULT); return Dirty; };
- void Set_Dirty() { WWASSERT(Pool==POOL_DEFAULT); Dirty=true; }
- void Clean() { Dirty=false; };
-
- unsigned Get_Reduction() const;
- WW3DFormat Get_Texture_Format() const { return TextureFormat; }
- bool Is_Compression_Allowed() const { return IsCompressionAllowed; }
-
- protected:
- void Poke_Texture(IDirect3DBaseTexture8* tex) { D3DTexture = tex; }
-
- // Apply this texture's settings into D3D
- virtual void Apply(unsigned int stage);
- void Load_Locked_Surface();
-
- void Init();
-
- // Apply a Null texture's settings into D3D
- static void Apply_Null(unsigned int stage);
-
- // State not contained in the Direct3D texture object:
- TextureFilterClass Filter;
-
- // Direct3D texture object
- IDirect3DBaseTexture8 *D3DTexture;
- bool Initialized;
-
- // Name
- StringClass Name;
- StringClass FullPath;
-
- // Unique id
- unsigned texture_id;
-
- // NOTE: Since "texture wrapping" (NOT TEXTURE WRAP MODE - THIS IS
- // SOMETHING ELSE) is a global state that affects all texture stages,
- // and this class only affects its own stage, we will not worry about
- // it for now. Later (probably when we implement world-oriented
- // environment maps) we will consider where to put it.
-
- // For debug purposes the texture sets this true if it is a lightmap texture
- bool IsLightmap;
- bool IsProcedural;
- bool IsCompressionAllowed;
-
- mutable unsigned LastAccessed;
- WW3DFormat TextureFormat;
-
- int Width;
- int Height;
-
- // Support for self-managed textures
-
- PoolType Pool;
- bool Dirty;
-public:
- MipCountType MipLevelCount;
- TextureLoadTaskClass* TextureLoadTask;
- // Background texture loader will call this when texture has been loaded
- void Apply_New_Surface(bool initialized); // If the parameter is true, the texture will be flagged as initialised
-
-};
-
-class BumpmapTextureClass : public TextureClass
-{
-public:
- // Generate bumpmap texture procedurally from the source texture
- BumpmapTextureClass(TextureClass* texture);
- virtual ~BumpmapTextureClass();
-};
-
-// Utility functions for loading and saving texture descriptions from/to W3D files
-TextureClass *Load_Texture(ChunkLoadClass & cload);
-void Save_Texture(TextureClass * texture, ChunkSaveClass & csave);
-
-// TheSuperHackers @todo TextureBaseClass abstraction
-typedef TextureClass TextureBaseClass;
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp
deleted file mode 100644
index 6ccbabc5c3c..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-/***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WW3D *
- * *
- * $Archive:: ww3d2/texturefilter.cpp $*
- * *
- * $Org Author:: Kenny Mitchell $*
- * *
- * Author : Kenny Mitchell *
- * *
- * $Modtime:: 08/05/02 1:27p $*
- * *
- * $Revision:: 1 $*
- * *
- * 08/05/02 KM Texture filter class abstraction *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#include "texturefilter.h"
-#include "dx8wrapper.h"
-#include "meshmatdesc.h"
-
-unsigned _MinTextureFilters[TextureFilterClass::FILTER_TYPE_COUNT];
-unsigned _MagTextureFilters[TextureFilterClass::FILTER_TYPE_COUNT];
-unsigned _MipMapFilters[TextureFilterClass::FILTER_TYPE_COUNT];
-
-/*************************************************************************
-** TextureFilterClass
-*************************************************************************/
-TextureFilterClass::TextureFilterClass(MipCountType mip_level_count)
-: TextureMinFilter(FILTER_TYPE_DEFAULT),
- TextureMagFilter(FILTER_TYPE_DEFAULT),
- UAddressMode(TEXTURE_ADDRESS_REPEAT),
- VAddressMode(TEXTURE_ADDRESS_REPEAT)
-{
- if (mip_level_count!=MIP_LEVELS_1)
- {
- MipMapFilter=FILTER_TYPE_DEFAULT;
- }
- else
- {
- MipMapFilter=FILTER_TYPE_NONE;
- }
-}
-
-//**********************************************************************************************
-//! Apply filters (legacy)
-/*!
-*/
-void TextureFilterClass::Apply(unsigned int stage)
-{
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage,D3DTSS_MINFILTER,_MinTextureFilters[TextureMinFilter]);
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage,D3DTSS_MAGFILTER,_MagTextureFilters[TextureMagFilter]);
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage,D3DTSS_MIPFILTER,_MipMapFilters[MipMapFilter]);
-
- switch (Get_U_Addr_Mode())
- {
- case TEXTURE_ADDRESS_REPEAT:
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- break;
-
- case TEXTURE_ADDRESS_CLAMP:
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- break;
- }
-
- switch (Get_V_Addr_Mode())
- {
- case TEXTURE_ADDRESS_REPEAT:
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- break;
-
- case TEXTURE_ADDRESS_CLAMP:
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- break;
- }
-}
-
-//**********************************************************************************************
-//! Init filters (legacy)
-/*!
-*/
-void TextureFilterClass::_Init_Filters(void)
-{
- const D3DCAPS8& dx8caps=DX8Wrapper::Get_Current_Caps()->Get_DX8_Caps();
-
- _MinTextureFilters[FILTER_TYPE_NONE]=D3DTEXF_POINT;
- _MagTextureFilters[FILTER_TYPE_NONE]=D3DTEXF_POINT;
- _MipMapFilters[FILTER_TYPE_NONE]=D3DTEXF_NONE;
-
- _MinTextureFilters[FILTER_TYPE_FAST]=D3DTEXF_LINEAR;
- _MagTextureFilters[FILTER_TYPE_FAST]=D3DTEXF_LINEAR;
- _MipMapFilters[FILTER_TYPE_FAST]=D3DTEXF_POINT;
-
- // Jani: Disabling anisotropic filtering as it doesn't seem to work with the latest nVidia drivers.
- if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MAGFAFLATCUBIC) _MagTextureFilters[FILTER_TYPE_BEST]=D3DTEXF_FLATCUBIC;
- else if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MAGFANISOTROPIC) _MagTextureFilters[FILTER_TYPE_BEST]=D3DTEXF_ANISOTROPIC;
- else if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC) _MagTextureFilters[FILTER_TYPE_BEST]=D3DTEXF_GAUSSIANCUBIC;
- else if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MAGFLINEAR) _MagTextureFilters[FILTER_TYPE_BEST]=D3DTEXF_LINEAR;
- else if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MAGFPOINT) _MagTextureFilters[FILTER_TYPE_BEST]=D3DTEXF_POINT;
- else {
- WWASSERT_PRINT(0,("No magnification filter found!"));
- }
-
- if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MINFANISOTROPIC) _MinTextureFilters[FILTER_TYPE_BEST]=D3DTEXF_ANISOTROPIC;
- else if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MINFLINEAR) _MinTextureFilters[FILTER_TYPE_BEST]=D3DTEXF_LINEAR;
- else if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MINFPOINT) _MinTextureFilters[FILTER_TYPE_BEST]=D3DTEXF_POINT;
- else {
- WWASSERT_PRINT(0,("No minification filter found!"));
- }
-
- if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MIPFLINEAR) _MipMapFilters[FILTER_TYPE_BEST]=D3DTEXF_LINEAR;
- else if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MIPFPOINT) _MipMapFilters[FILTER_TYPE_BEST]=D3DTEXF_POINT;
- else {
- WWASSERT_PRINT(0,("No mip filter found!"));
- }
-
-//_MagTextureFilters[FILTER_TYPE_BEST]=D3DTEXF_FLATCUBIC;
-// WWASSERT(Validate_Filters(FILTER_TYPE_BEST));
-
- _MinTextureFilters[FILTER_TYPE_DEFAULT]=_MinTextureFilters[FILTER_TYPE_BEST];
- _MagTextureFilters[FILTER_TYPE_DEFAULT]=_MagTextureFilters[FILTER_TYPE_BEST];
- _MipMapFilters[FILTER_TYPE_DEFAULT]=_MipMapFilters[FILTER_TYPE_BEST];
-
- for (int stage=0;stage.
-*/
-
-/***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WW3D *
- * *
- * $Archive:: ww3d2/texturefilter.h $*
- * *
- * $Org Author:: Kenny Mitchell $*
- * *
- * Author : Kenny Mitchell *
- * *
- * $Modtime:: 08/05/02 1:27p $*
- * *
- * $Revision:: 1 $*
- * *
- * 08/05/02 KM Texture filter class abstraction *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#pragma once
-
-#ifndef DX8_WRAPPER_H
-//#include "dx8wrapper.h"
-#endif
-
-enum MipCountType
-{
- MIP_LEVELS_ALL=0, // generate all mipmap levels down to 1x1 size
- MIP_LEVELS_1, // no mipmapping at all (just one mip level)
- MIP_LEVELS_2,
- MIP_LEVELS_3,
- MIP_LEVELS_4,
- MIP_LEVELS_5,
- MIP_LEVELS_6,
- MIP_LEVELS_7,
- MIP_LEVELS_8,
- MIP_LEVELS_10,
- MIP_LEVELS_11,
- MIP_LEVELS_12,
- MIP_LEVELS_MAX // This isn't to be used (use MIP_LEVELS_ALL instead), it is just an enum for creating static tables etc.
-};
-
-
-// NOTE: Since "texture wrapping" (NOT TEXTURE WRAP MODE - THIS IS
-// SOMETHING ELSE) is a global state that affects all texture stages,
-// and this class only affects its own stage, we will not worry about
-// it for now. Later (probably when we implement world-oriented
-// environment maps) we will consider where to put it.
-
-// This is legacy and should be phased out into wwshade shader states
-// keeping as an abstracted class for now to support this transition later
-class TextureFilterClass
-{
-public:
-
- enum FilterType
- {
- FILTER_TYPE_NONE,
- FILTER_TYPE_FAST,
- FILTER_TYPE_BEST,
- FILTER_TYPE_DEFAULT,
- FILTER_TYPE_COUNT
- };
-
- enum TextureFilterMode
- {
- TEXTURE_FILTER_BILINEAR,
- TEXTURE_FILTER_TRILINEAR,
- TEXTURE_FILTER_ANISOTROPIC
- };
-
- enum TxtAddrMode
- {
- TEXTURE_ADDRESS_REPEAT=0,
- TEXTURE_ADDRESS_CLAMP
- };
-
- TextureFilterClass(MipCountType mip_level_count=MIP_LEVELS_1);
-
- void Apply(unsigned int stage);
-
- // Filter and MIPmap settings:
- FilterType Get_Min_Filter(void) const { return TextureMinFilter; }
- FilterType Get_Mag_Filter(void) const { return TextureMagFilter; }
- FilterType Get_Mip_Mapping(void) const { return MipMapFilter; }
- void Set_Min_Filter(FilterType filter) { TextureMinFilter=filter; }
- void Set_Mag_Filter(FilterType filter) { TextureMagFilter=filter; }
- void Set_Mip_Mapping(FilterType mipmap);
-
- // Texture address mode
- TxtAddrMode Get_U_Addr_Mode(void) const { return UAddressMode; }
- TxtAddrMode Get_V_Addr_Mode(void) const { return VAddressMode; }
- void Set_U_Addr_Mode(TxtAddrMode mode) { UAddressMode=mode; }
- void Set_V_Addr_Mode(TxtAddrMode mode) { VAddressMode=mode; }
-
- // This needs to be called after device has been created
- static void _Init_Filters(void);
-
- static void _Set_Default_Min_Filter(FilterType filter);
- static void _Set_Default_Mag_Filter(FilterType filter);
- static void _Set_Default_Mip_Filter(FilterType filter);
-
-private:
- // State not contained in the Direct3D texture object:
- FilterType TextureMinFilter;
- FilterType TextureMagFilter;
- FilterType MipMapFilter;
- TxtAddrMode UAddressMode;
- TxtAddrMode VAddressMode;
-};
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.cpp
deleted file mode 100644
index ced18c40aa5..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.cpp
+++ /dev/null
@@ -1,1389 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-#include "textureloader.h"
-#include "mutex.h"
-#include "thread.h"
-#include "wwdebug.h"
-#include "texture.h"
-#include "ffactory.h"
-#include "wwstring.h"
-#include "bufffile.h"
-#include "ww3d.h"
-#include "assetmgr.h"
-#include "dx8wrapper.h"
-#include "dx8caps.h"
-#include "missingtexture.h"
-#include "TARGA.h"
-#include
-#include "wwmemlog.h"
-#include "formconv.h"
-#include "texturethumbnail.h"
-#include "ddsfile.h"
-#include "bitmaphandler.h"
-
-static TextureLoadTaskClass* LoadListHead;
-static TextureLoadTaskClass* DeferredListHead;
-static TextureLoadTaskClass* FinishedListHead;
-static TextureLoadTaskClass* ThumbnailListHead;
-static TextureLoadTaskClass* DeleteTaskListHead;
-
-TextureLoadTaskClass* TextureLoadTaskClass::FreeTaskListHead;
-
-static bool Is_Format_Compressed(WW3DFormat texture_format,bool allow_compression)
-{
- // Verify that the user isn't requesting compressed texture without hardware support
-
- bool compressed=false;
- if (texture_format!=WW3D_FORMAT_UNKNOWN) {
- if (!DX8Wrapper::Get_Current_Caps()->Support_DXTC() || !allow_compression) {
- WWASSERT(texture_format!=WW3D_FORMAT_DXT1);
- WWASSERT(texture_format!=WW3D_FORMAT_DXT2);
- WWASSERT(texture_format!=WW3D_FORMAT_DXT3);
- WWASSERT(texture_format!=WW3D_FORMAT_DXT4);
- WWASSERT(texture_format!=WW3D_FORMAT_DXT5);
- }
- if (texture_format==WW3D_FORMAT_DXT1 ||
- texture_format==WW3D_FORMAT_DXT2 ||
- texture_format==WW3D_FORMAT_DXT3 ||
- texture_format==WW3D_FORMAT_DXT4 ||
- texture_format==WW3D_FORMAT_DXT5) {
- compressed=true;
- }
- }
-
- // If hardware supports DXTC compression, load a compressed texture. Proceed only if the texture format hasn't been
- // defined as non-compressed.
- compressed|=(
- texture_format==WW3D_FORMAT_UNKNOWN &&
- DX8Wrapper::Get_Current_Caps()->Support_DXTC() &&
- allow_compression);
-
- return compressed;
-}
-
-// ----------------------------------------------------------------------------
-
-static CriticalSectionClass mutex;
-static class LoaderThreadClass : public ThreadClass
-{
- TextureLoadTaskClass* Get_Task_From_Load_List();
-
- static void Add_Task_To_Finished_List(TextureLoadTaskClass* task);
-
-public:
- LoaderThreadClass() : ThreadClass() {}
-
- void Thread_Function();
-
- static void Add_Task_To_Load_List(TextureLoadTaskClass* task);
-
-} thread;
-
-// ----------------------------------------------------------------------------
-
-void TextureLoader::Init()
-{
- WWASSERT(!thread.Is_Running());
-
- ThumbnailClass::Init();
-
- thread.Execute();
- thread.Set_Priority(-3);
-}
-
-// ----------------------------------------------------------------------------
-
-void TextureLoader::Deinit()
-{
- CriticalSectionClass::LockClass m(mutex);
- thread.Stop();
-
- ThumbnailClass::Deinit();
-}
-
-// ----------------------------------------------------------------------------
-//
-// Modify given texture size to nearest valid size on current hardware.
-//
-// ----------------------------------------------------------------------------
-
-void TextureLoader::Validate_Texture_Size
-(
- unsigned& width,
- unsigned& height,
- unsigned& depth
-)
-{
- const D3DCAPS8& dx8caps=DX8Wrapper::Get_Current_Caps()->Get_DX8_Caps();
-
- unsigned poweroftwowidth = 1;
- while (poweroftwowidth < width)
- {
- poweroftwowidth <<= 1;
- }
-
- unsigned poweroftwoheight = 1;
- while (poweroftwoheight < height)
- {
- poweroftwoheight <<= 1;
- }
-
- unsigned poweroftwodepth = 1;
- while (poweroftwodepth< depth)
- {
- poweroftwodepth <<= 1;
- }
-
- if (poweroftwowidth>dx8caps.MaxTextureWidth)
- {
- poweroftwowidth=dx8caps.MaxTextureWidth;
- }
- if (poweroftwoheight>dx8caps.MaxTextureHeight)
- {
- poweroftwoheight=dx8caps.MaxTextureHeight;
- }
- if (poweroftwodepth>dx8caps.MaxVolumeExtent)
- {
- poweroftwodepth=dx8caps.MaxVolumeExtent;
- }
-
- if (poweroftwowidth>poweroftwoheight)
- {
- while (poweroftwowidth/poweroftwoheight>8)
- {
- poweroftwoheight*=2;
- }
- }
- else
- {
- while (poweroftwoheight/poweroftwowidth>8)
- {
- poweroftwowidth*=2;
- }
- }
-
- width=poweroftwowidth;
- height=poweroftwoheight;
- depth=poweroftwodepth;
-}
-
-IDirect3DTexture8* TextureLoader::Load_Thumbnail(const StringClass& filename,WW3DFormat texture_format)
-{
- ThumbnailClass* thumb=ThumbnailClass::Peek_Instance(filename);
- if (!thumb) {
- thumb=W3DNEW ThumbnailClass(filename);
- // If load failed, return missing texture
- if (!thumb->Peek_Bitmap()) {
- delete thumb;
- return MissingTexture::_Get_Missing_Texture();
- }
- }
-
- unsigned src_pitch=thumb->Get_Width()*4; // Thumbs are always 32 bits
- WW3DFormat dest_format;
- if (texture_format==WW3D_FORMAT_UNKNOWN) {
- dest_format=Get_Valid_Texture_Format(WW3D_FORMAT_A8R8G8B8,false); // no compressed formats please
- }
- else {
- dest_format=Get_Valid_Texture_Format(texture_format,false); // no compressed formats please
- WWASSERT(dest_format==texture_format);
- }
-
- IDirect3DTexture8* d3d_texture = DX8Wrapper::_Create_DX8_Texture(
- thumb->Get_Width(),
- thumb->Get_Height(),
- dest_format,
- MIP_LEVELS_ALL);
-
- unsigned level=0;
- D3DLOCKED_RECT locked_rects[12]={0};
- WWASSERT(d3d_texture->GetLevelCount()<=12);
-
- // Lock all surfaces
- for (level=0;levelGetLevelCount();++level) {
- DX8_ErrorCode(
- d3d_texture->LockRect(
- level,
- &locked_rects[level],
- NULL,
- 0));
- }
-
- unsigned char* src_surface=thumb->Peek_Bitmap();
- WW3DFormat src_format=WW3D_FORMAT_A8R8G8B8;
- unsigned width=thumb->Get_Width();
- unsigned height=thumb->Get_Height();
-
- for (level=0;levelGetLevelCount()-1;++level) {
- BitmapHandlerClass::Copy_Image_Generate_Mipmap(
- width,
- height,
- (unsigned char*)locked_rects[level].pBits,
- locked_rects[level].Pitch,
- dest_format,
- src_surface,
- src_pitch,
- src_format,
- (unsigned char*)locked_rects[level+1].pBits, // mipmap
- locked_rects[level+1].Pitch);// mipmap
-
- src_format=dest_format;
- src_surface=(unsigned char*)locked_rects[level].pBits;
- src_pitch=locked_rects[level].Pitch;
- width>>=1;
- height>>=1;
- }
-
- // Unlock all surfaces
- for (level=0;levelGetLevelCount();++level) {
- DX8_ErrorCode(d3d_texture->UnlockRect(level));
- }
-
- return d3d_texture;
-}
-
-static bool Is_Power_Of_Two(unsigned i)
-{
- if (!i) return false;
- unsigned n=i;
- unsigned shift=0;
- while (n) {
- shift++;
- n>>=1;
- }
- return ((i>>(shift-1))<<(shift-1))==i;
-}
-
-// ----------------------------------------------------------------------------
-
-// TODO: Legacy - remove this call!
-IDirect3DTexture8* Load_Compressed_Texture(
- const StringClass& filename,
- unsigned reduction_factor,
- MipCountType mip_level_count,
- WW3DFormat dest_format)
-{
- // If DDS file isn't available, use TGA file to convert to DDS.
-
- DDSFileClass dds_file(filename,reduction_factor);
- if (!dds_file.Is_Available()) return NULL;
- if (!dds_file.Load()) return NULL;
-
- unsigned width=dds_file.Get_Width(0);
- unsigned height=dds_file.Get_Height(0);
- unsigned mips=dds_file.Get_Mip_Level_Count();
-
- // If format isn't defined get the nearest valid texture format to the compressed file format
- // Note that the nearest valid format could be anything, even uncompressed.
- if (dest_format==WW3D_FORMAT_UNKNOWN) dest_format=Get_Valid_Texture_Format(dds_file.Get_Format(),true);
-
- IDirect3DTexture8* d3d_texture = DX8Wrapper::_Create_DX8_Texture(
- width,
- height,
- dest_format,
- (MipCountType)mips);
-
- for (unsigned level=0;levelGetSurfaceLevel(level/*-reduction_factor*/,&d3d_surface));
- dds_file.Copy_Level_To_Surface(level,d3d_surface);
- d3d_surface->Release();
- }
- return d3d_texture;
-}
-
-// ----------------------------------------------------------------------------
-//
-// Load image to a surface. The function tries to create texture that matches
-// targa format. If suitable format is not available, it selects closest matching
-// format and performs color space conversion.
-//
-// ----------------------------------------------------------------------------
-IDirect3DSurface8* TextureLoader::Load_Surface_Immediate(
- const StringClass& filename,
- WW3DFormat texture_format,
- bool allow_compression)
-{
- bool compressed=Is_Format_Compressed(texture_format,allow_compression);
-
- if (compressed) {
- IDirect3DTexture8* comp_tex=Load_Compressed_Texture(filename,0,MIP_LEVELS_1,WW3D_FORMAT_UNKNOWN);
- if (comp_tex) {
- IDirect3DSurface8* d3d_surface=NULL;
- DX8_ErrorCode(comp_tex->GetSurfaceLevel(0,&d3d_surface));
- comp_tex->Release();
- return d3d_surface;
- }
- }
-
- // Make sure the file can be opened. If not, return missing texture.
- Targa targa;
- if (TARGA_ERROR_HANDLER(targa.Open(filename, TGA_READMODE),filename)) return MissingTexture::_Create_Missing_Surface();
-
- // DX8 uses image upside down compared to TGA
- targa.Header.ImageDescriptor ^= TGAIDF_YORIGIN;
-
- WW3DFormat src_format,dest_format;
- unsigned src_bpp=0;
- Get_WW3D_Format(dest_format,src_format,src_bpp,targa);
-
- if (texture_format!=WW3D_FORMAT_UNKNOWN) {
- dest_format=texture_format;
- }
-
- // Destination size will be the next power of two square from the larger width and height...
- unsigned width, height;
- width=targa.Header.Width;
- height=targa.Header.Height;
- unsigned src_width=targa.Header.Width;
- unsigned src_height=targa.Header.Height;
-
- // NOTE: We load the palette but we do not yet support paletted textures!
- char palette[256*4];
- targa.SetPalette(palette);
- if (TARGA_ERROR_HANDLER(targa.Load(filename, TGAF_IMAGE, false),filename)) return MissingTexture::_Create_Missing_Surface();
-
- unsigned char* src_surface=(unsigned char*)targa.GetImage();
-
- // No paletted destination format allowed
- unsigned char* converted_surface=NULL;
- if (src_format==WW3D_FORMAT_A1R5G5B5 || src_format==WW3D_FORMAT_R5G6B5 || src_format==WW3D_FORMAT_A4R4G4B4 ||
- src_format==WW3D_FORMAT_P8 || src_format==WW3D_FORMAT_L8 || src_width!=width || src_height!=height) {
- converted_surface=W3DNEWARRAY unsigned char[width*height*4];
- dest_format=Get_Valid_Texture_Format(WW3D_FORMAT_A8R8G8B8,false);
- BitmapHandlerClass::Copy_Image(
- converted_surface,
- width,
- height,
- width*4,
- WW3D_FORMAT_A8R8G8B8,//dest_format,
- src_surface,
- src_width,
- src_height,
- src_width*src_bpp,
- src_format,
- (unsigned char*)targa.GetPalette(),
- targa.Header.CMapDepth>>3,
- false);
- src_surface=converted_surface;
- src_format=WW3D_FORMAT_A8R8G8B8;//dest_format;
- src_width=width;
- src_height=height;
- src_bpp=Get_Bytes_Per_Pixel(src_format);
- }
-
- unsigned src_pitch=src_width*src_bpp;
-
- IDirect3DSurface8* d3d_surface = DX8Wrapper::_Create_DX8_Surface(width,height,dest_format);
- WWASSERT(d3d_surface);
- D3DLOCKED_RECT locked_rect;
- DX8_ErrorCode(
- d3d_surface->LockRect(
- &locked_rect,
- NULL,
- 0));
-
- BitmapHandlerClass::Copy_Image(
- (unsigned char*)locked_rect.pBits,
- width,
- height,
- locked_rect.Pitch,
- dest_format,
- src_surface,
- src_width,
- src_height,
- src_pitch,
- src_format,
- (unsigned char*)targa.GetPalette(),
- targa.Header.CMapDepth>>3,
- false); // No mipmap
-
- DX8_ErrorCode(d3d_surface->UnlockRect());
-
- delete[] converted_surface;
-
- return d3d_surface;
-}
-
-
-// ----------------------------------------------------------------------------
-//
-// Load mipmap levels to a pre-generated and locked texture object based on
-// information in load task object. Try loading from a DDS file first and if
-// that fails try a TGA.
-//
-// ----------------------------------------------------------------------------
-
-void TextureLoader::Load_Mipmap_Levels(TextureLoadTaskClass* task)
-{
- WWASSERT(task->Peek_D3D_Texture());
- WWMEMLOG(MEM_TEXTURE);
-
- if (task->Peek_Texture()->Is_Compression_Allowed()) {
- DDSFileClass dds_file(task->Peek_Texture()->Get_Full_Path(),task->Get_Reduction());
- if (dds_file.Is_Available() && dds_file.Load()) {
- unsigned width=task->Get_Width();
- unsigned height=task->Get_Height();
- for (unsigned level=0;levelGet_Mip_Level_Count();++level) {
- WWASSERT(width && height);
- dds_file.Copy_Level_To_Surface(
- level,
- task->Get_Format(),
- width,
- height,
- task->Get_Locked_Surface_Ptr(level),
- task->Get_Locked_Surface_Pitch(level));
- width>>=1;
- height>>=1;
- }
- return;
- }
- }
- if (Load_Uncompressed_Mipmap_Levels_From_TGA(task)) return;
-}
-
-// ----------------------------------------------------------------------------
-//
-// Use load task to load texture surface from a targa file. Calculate mipmaps
-// if needed.
-//
-// ----------------------------------------------------------------------------
-
-bool TextureLoader::Load_Uncompressed_Mipmap_Levels_From_TGA(TextureLoadTaskClass* task)
-{
- if (!task->Get_Mip_Level_Count()) return false;
- TextureBaseClass* texture=task->Peek_Texture();
-
- Targa targa;
- if (TARGA_ERROR_HANDLER(targa.Open(texture->Get_Full_Path(), TGA_READMODE),texture->Get_Full_Path())) {
- task->Set_Fail(true);
- return false;
- }
- // DX8 uses image upside down compared to TGA
- targa.Header.ImageDescriptor ^= TGAIDF_YORIGIN;
-
- WW3DFormat src_format,dest_format;
- unsigned src_bpp=0;
- Get_WW3D_Format(dest_format,src_format,src_bpp,targa);
-// WWASSERT(task->Get_Format()==dest_format);
- dest_format=task->Get_Format(); // Texture can be requested in different format than the most obvious from the TGA
-
- char palette[256*4];
- targa.SetPalette(palette);
-
- unsigned src_width=targa.Header.Width;
- unsigned src_height=targa.Header.Height;
- unsigned width=task->Get_Width();
- unsigned height=task->Get_Height();
-
- // NOTE: We load the palette but we do not yet support paletted textures!
- if (TARGA_ERROR_HANDLER(targa.Load(texture->Get_Full_Path(), TGAF_IMAGE, false),texture->Get_Full_Path())) {
- task->Set_Fail(true);
- return false;
- }
- unsigned char* src_surface=(unsigned char*)targa.GetImage();
-
- // No paletted format allowed when generating mipmaps
- unsigned char* converted_surface=NULL;
- if (src_format==WW3D_FORMAT_A1R5G5B5 || src_format==WW3D_FORMAT_R5G6B5 || src_format==WW3D_FORMAT_A4R4G4B4 ||
- src_format==WW3D_FORMAT_P8 || src_format==WW3D_FORMAT_L8 || src_width!=width || src_height!=height) {
- converted_surface=W3DNEWARRAY unsigned char[width*height*4];
- dest_format=Get_Valid_Texture_Format(WW3D_FORMAT_A8R8G8B8,false);
- BitmapHandlerClass::Copy_Image(
- converted_surface,
- width,
- height,
- width*4,
- WW3D_FORMAT_A8R8G8B8, //dest_format,
- src_surface,
- src_width,
- src_height,
- src_width*src_bpp,
- src_format,
- (unsigned char*)targa.GetPalette(),
- targa.Header.CMapDepth>>3,
- false);
- src_surface=converted_surface;
- src_format=WW3D_FORMAT_A8R8G8B8; //dest_format;
- src_width=width;
- src_height=height;
- src_bpp=Get_Bytes_Per_Pixel(src_format);
- }
-
- unsigned src_pitch=src_width*src_bpp;
-
- for (unsigned level=0;levelGet_Mip_Level_Count();++level) {
- WWASSERT(task->Get_Locked_Surface_Ptr(level));
- BitmapHandlerClass::Copy_Image(
- task->Get_Locked_Surface_Ptr(level),
- width,
- height,
- task->Get_Locked_Surface_Pitch(level),
- task->Get_Format(),
- src_surface,
- src_width,
- src_height,
- src_pitch,
- src_format,
- NULL,
- 0,
- true);
-
- width>>=1;
- height>>=1;
- src_width>>=1;
- src_height>>=1;
- if (!width || !height || !src_width || !src_height) break;
- }
-
- delete[] converted_surface;
-
- return true;
-}
-
-// ----------------------------------------------------------------------------
-//
-// Return a task from the load list head. The loading thread uses this function
-// to retrieve tasks from the load list.
-//
-// ----------------------------------------------------------------------------
-
-TextureLoadTaskClass* LoaderThreadClass::Get_Task_From_Load_List()
-{
- CriticalSectionClass::LockClass m(mutex);
-
- TextureLoadTaskClass* task=LoadListHead;
- if (task) {
- LoadListHead=task->Peek_Succ();
- task->Set_Succ(NULL);
- }
- return task;
-}
-
-// ----------------------------------------------------------------------------
-//
-// This function adds a load task to the head of the loading thread task list.
-// The latest added task will be the next processed (There are good reasons
-// for such ordering). The loading thread will process tasks from this list
-// as soons as it can and then move the tasks to finished list.
-//
-// ----------------------------------------------------------------------------
-
-void LoaderThreadClass::Add_Task_To_Load_List(TextureLoadTaskClass* task)
-{
- CriticalSectionClass::LockClass m(mutex);
-
- WWASSERT(task->Peek_Succ()==NULL);
-
- task->Set_Succ(LoadListHead);
- LoadListHead=task;
-}
-
-// ----------------------------------------------------------------------------
-//
-// After the loading thread is done with the texture, it is moved to the list
-// of finished tasks so that the main thread can then finish up by unlocking
-// the surfaces and applying the changes to the texture class object.
-//
-// ----------------------------------------------------------------------------
-
-void LoaderThreadClass::Add_Task_To_Finished_List(TextureLoadTaskClass* task)
-{
- CriticalSectionClass::LockClass m(mutex);
-
- WWASSERT(task->Peek_Succ()==NULL);
-
- task->Set_Succ(FinishedListHead);
- FinishedListHead=task;
-}
-
-// ----------------------------------------------------------------------------
-//
-// If we need to find out if the load task list is empty this is the function
-// to use. We can't use Get_Task_From_Load_List() as if the list isn't empty
-// it also removes the head node from the list.
-//
-// ----------------------------------------------------------------------------
-
-bool Is_Load_List_Empty()
-{
- return !LoadListHead;
-}
-// ----------------------------------------------------------------------------
-//
-// Texture loading thread loads textures that appear in loading_task_list.
-// If the list is empty the thread sleeps.
-//
-// ----------------------------------------------------------------------------
-
-void LoaderThreadClass::Thread_Function()
-{
- while (running) {
- TextureLoadTaskClass* task=Get_Task_From_Load_List();
- if (task) {
- TextureLoader::Load_Mipmap_Levels(task);
- Add_Task_To_Finished_List(task);
- }
-
- Switch_Thread();
- }
-}
-
-// ----------------------------------------------------------------------------
-//
-// Update refreshes all completed texture loading tasks
-//
-// ----------------------------------------------------------------------------
-
-TextureLoadTaskClass* Get_Finished_Task()
-{
- CriticalSectionClass::LockClass m(mutex);
-
- TextureLoadTaskClass* task=FinishedListHead;
- if (task) {
- FinishedListHead=task->Peek_Succ();
- task->Set_Succ(NULL);
- }
- return task;
-}
-
-TextureLoadTaskClass* Get_Thumbnail_Task()
-{
- CriticalSectionClass::LockClass m(mutex);
-
- TextureLoadTaskClass* task=ThumbnailListHead;
- if (task) {
- ThumbnailListHead=task->Peek_Succ();
- task->Set_Succ(NULL);
- }
- return task;
-}
-
-void Add_Thumbnail_Task(TextureLoadTaskClass* task)
-{
- CriticalSectionClass::LockClass m(mutex);
-
- WWASSERT(task->Peek_Succ()==NULL);
-
- task->Set_Succ(ThumbnailListHead);
- ThumbnailListHead=task;
-
-}
-
-// ----------------------------------------------------------------------------
-//
-// The main thread's update function deletes tasks from the load task list
-// once a frame.
-//
-// ----------------------------------------------------------------------------
-
-TextureLoadTaskClass* Get_Task_From_Delete_List()
-{
- WWASSERT(ThreadClass::_Get_Current_Thread_ID()==DX8Wrapper::_Get_Main_Thread_ID());
-
- TextureLoadTaskClass* task=DeleteTaskListHead;
- if (task) {
- DeleteTaskListHead=task->Peek_Succ();
- task->Set_Succ(NULL);
- }
- return task;
-}
-
-// ----------------------------------------------------------------------------
-//
-// When task wants to delete itself it adds itself to a delete list. This list
-// can only be accessed from the main thread.
-//
-// ----------------------------------------------------------------------------
-
-void Add_Task_To_Delete_List(TextureLoadTaskClass* task)
-{
- WWASSERT(ThreadClass::_Get_Current_Thread_ID()==DX8Wrapper::_Get_Main_Thread_ID());
-
- WWASSERT(task->Peek_Succ()==NULL);
-
- task->Set_Succ(DeleteTaskListHead);
- DeleteTaskListHead=task;
-}
-
-TextureLoadTaskClass* Get_Deferred_Task()
-{
- CriticalSectionClass::LockClass m(mutex);
-
- TextureLoadTaskClass* task=DeferredListHead;
- if (task) {
- DeferredListHead=task->Peek_Succ();
- task->Set_Succ(NULL);
- }
- return task;
-}
-
-void Add_Deferred_Task(TextureLoadTaskClass* task)
-{
- CriticalSectionClass::LockClass m(mutex);
-
- WWASSERT(task->Peek_Succ()==NULL);
- task->Set_Succ(DeferredListHead);
- DeferredListHead=task;
-}
-
-void TextureLoader::Flush_Pending_Load_Tasks()
-{
- while (!Is_Load_List_Empty()) {
- Update();
- ThreadClass::Switch_Thread();
- }
-}
-
-void TextureLoader::Update()
-{
- WWASSERT_PRINT(DX8Wrapper::_Get_Main_Thread_ID()==ThreadClass::_Get_Current_Thread_ID(),"TextureLoader::Update must be called from the main thread!");
-
- while (TextureLoadTaskClass* task=Get_Deferred_Task()) {
- task->Begin_Texture_Load(); // This will add the task to load list
- }
-
- while (TextureLoadTaskClass* task=Get_Finished_Task()) {
- task->End_Load();
- task->Apply(true);
- TextureLoadTaskClass::Release_Instance(task);
- }
-
- while (TextureLoadTaskClass* task=Get_Thumbnail_Task()) {
- task->Begin_Thumbnail_Load();
- }
-
- while (TextureLoadTaskClass* task=Get_Task_From_Delete_List()) {
-// delete task;
- TextureLoadTaskClass::Release_Instance(task);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-static DWORD VectortoRGBA( D3DXVECTOR3* v, FLOAT fHeight )
-{
- DWORD r = (DWORD)( 127.0f * v->x + 128.0f );
- DWORD g = (DWORD)( 127.0f * v->y + 128.0f );
- DWORD b = (DWORD)( 127.0f * v->z + 128.0f );
- DWORD a = (DWORD)( 255.0f * fHeight );
-
- return( (a<<24L) + (r<<16L) + (g<<8L) + (b<<0L) );
-}
-
-IDirect3DTexture8* TextureLoader::Generate_Bumpmap(TextureBaseClass* texture)
-{
- WW3DFormat bump_format=WW3D_FORMAT_U8V8;
- if (!DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(bump_format)) {
- return MissingTexture::_Get_Missing_Texture();
- }
-
- D3DSURFACE_DESC desc;
- IDirect3DTexture8* src_d3d_tex=texture->Peek_D3D_Texture();
- WWASSERT(src_d3d_tex);
- DX8_ErrorCode(src_d3d_tex->GetLevelDesc(0,&desc));
- unsigned width=desc.Width;
- unsigned height=desc.Height;
-
- IDirect3DTexture8* d3d_texture = DX8Wrapper::_Create_DX8_Texture(
- width,
- height,
- bump_format,
- MIP_LEVELS_1);
-
- D3DLOCKED_RECT src_locked_rect;
- DX8_ErrorCode(
- texture->Peek_D3D_Texture()->LockRect(
- 0,
- &src_locked_rect,
- NULL,
- D3DLOCK_READONLY));
-
- D3DLOCKED_RECT dest_locked_rect;
- DX8_ErrorCode(
- d3d_texture->LockRect(
- 0,
- &dest_locked_rect,
- NULL,
- 0));
-
- WW3DFormat format=D3DFormat_To_WW3DFormat(desc.Format);
- unsigned bpp=Get_Bytes_Per_Pixel(format);
-
- for( unsigned y=0; y1 ) ? 63 : 127;
-
- switch( bump_format )
- {
- case WW3D_FORMAT_U8V8:
- *dest_ptr++ = (unsigned char)iDu;
- *dest_ptr++ = (unsigned char)iDv;
- break;
-
- case WW3D_FORMAT_L6V5U5:
- *(unsigned short*)dest_ptr = (unsigned short)( ( (iDu>>3) & 0x1f ) << 0 );
- *(unsigned short*)dest_ptr |= (unsigned short)( ( (iDv>>3) & 0x1f ) << 5 );
- *(unsigned short*)dest_ptr |= (unsigned short)( ( ( uL>>2) & 0x3f ) << 10 );
- dest_ptr += 2;
- break;
-
- case WW3D_FORMAT_X8L8V8U8:
- *dest_ptr++ = (unsigned char)iDu;
- *dest_ptr++ = (unsigned char)iDv;
- *dest_ptr++ = (unsigned char)uL;
- *dest_ptr++ = (unsigned char)0L;
- break;
- }
-
- // Move one pixel to the left (src is 32-bpp)
- src_ptr_mid+=bpp;
- src_ptr_prev_line+=bpp;
- src_ptr_next_line+=bpp;
- }
- }
-
- DX8_ErrorCode(d3d_texture->UnlockRect(0));
- DX8_ErrorCode(texture->Peek_D3D_Texture()->UnlockRect(0));
- return d3d_texture;
-}
-
-// ----------------------------------------------------------------------------
-//
-// Public texture request functions. These functions can be used to request
-// texture loading.
-//
-// ----------------------------------------------------------------------------
-
-void TextureLoader::Add_Load_Task(TextureBaseClass* tc)
-{
- // If the texture is already being loaded we just exit here.
- if (tc->TextureLoadTask) return;
-
- TextureLoadTaskClass* task=TextureLoadTaskClass::Get_Instance(tc,false);
- task->Begin_Texture_Load();
-}
-
-// ----------------------------------------------------------------------------
-
-void TextureLoader::Request_High_Priority_Loading(
- TextureBaseClass* tc,
- MipCountType mip_level_count)
-{
- TextureLoadTaskClass* task=TextureLoadTaskClass::Get_Instance(tc,true);
- task->Begin_Texture_Load();
-}
-
-// ----------------------------------------------------------------------------
-
-void TextureLoader::Request_Thumbnail(TextureBaseClass* tc)
-{
- // If the texture is already being loaded we just exit here.
- if (tc->TextureLoadTask) return;
-
- TextureLoadTaskClass* task=TextureLoadTaskClass::Get_Instance(tc,false);
- task->Begin_Thumbnail_Load();
-}
-
-// ----------------------------------------------------------------------------
-//
-// Texture loader task handler
-//
-// ----------------------------------------------------------------------------
-
-TextureLoadTaskClass::TextureLoadTaskClass()
- :
- Texture(0),
- Succ(0),
- D3DTexture(0),
- Width(0),
- Height(0),
- Format(WW3D_FORMAT_UNKNOWN),
- IsLoading(false),
- HasFailed(false),
- MipLevelCount(0),
- HighPriorityRequested(false),
- Reduction(0)
-{
-}
-
-// ----------------------------------------------------------------------------
-//
-// Destruct texture load task. The load task deinitialization will fail from
-// any other than the main thread so the task must be either deleted from the
-// main thread or deinitialized in the main thread prior to deleting it in
-// another thread.
-//
-// ----------------------------------------------------------------------------
-
-TextureLoadTaskClass::~TextureLoadTaskClass()
-{
- Deinit();
-}
-
-void TextureLoadTaskClass::Init(TextureBaseClass* tc,bool high_priority)
-{
- // Make sure texture has a filename.
- REF_PTR_SET(Texture,tc);
- //WWASSERT(!Texture->Get_Full_Path().Is_Empty());
-
- Reduction=Texture->Get_Reduction();
- HighPriorityRequested=high_priority;
- IsLoading=false;
- HasFailed=false;
- MipLevelCount=tc->MipLevelCount;
- D3DTexture=0;
- Width=0;
- Height=0;
- Format=Texture->Get_Texture_Format();
-
- Texture->TextureLoadTask=this;
- for (int i=0;iTextureLoadTask==this);
- Texture->TextureLoadTask=NULL;
- }
-
- REF_PTR_RELEASE(Texture);
- WWASSERT(!D3DTexture);
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-void TextureLoadTaskClass::Begin_Texture_Load()
-{
- // If we're in main thread, init for loading and add to the load list
- if (ThreadClass::_Get_Current_Thread_ID()==DX8Wrapper::_Get_Main_Thread_ID()) {
-
- bool loaded=false;
- if (Texture->Is_Compression_Allowed()) {
- DDSFileClass dds_file(Texture->Get_Full_Path(),Get_Reduction());
- if (dds_file.Is_Available()) {
- // Destination size will be the next power of two square from the larger width and height...
- unsigned width=0, height=0, depth=1;
- width=dds_file.Get_Width(0);
- height=dds_file.Get_Height(0);
- TextureLoader::Validate_Texture_Size(width,height,depth);
-
- // If the size doesn't match, try and see if texture reduction would help... (mainly for
- // cases where loaded texture is larger than hardware limit)
- if (width!=dds_file.Get_Width(0) || height!=dds_file.Get_Height(0)) {
- for (unsigned i=1;iIs_Compression_Allowed());
-
- unsigned mip_level_count=Get_Mip_Level_Count();
- // If texture wants all mip levels, take as many as the file contains (not necessarily all)
- // Otherwise take as many mip levels as the texture wants, not to exceed the count in file...
- if (!mip_level_count) mip_level_count=dds_file.Get_Mip_Level_Count();
- else if (mip_level_count>dds_file.Get_Mip_Level_Count()) mip_level_count=dds_file.Get_Mip_Level_Count();
-
- // Once more, verify that the mip level count is correct (in case it was changed here it might not
- // match the size...well actually it doesn't have to match but it can't be bigger than the size)
- unsigned max_mip_level_count=1;
- unsigned w=4;
- unsigned h=4;
- while (wmax_mip_level_count) mip_level_count=max_mip_level_count;
-
- D3DTexture=DX8Wrapper::_Create_DX8_Texture(Width,Height,Format,(MipCountType)mip_level_count);
- MipLevelCount=mip_level_count;
- //Texture->MipLevelCount);
- loaded=true;
- }
- }
-
- if (!loaded) {
- Targa targa;
- if (TARGA_ERROR_HANDLER(targa.Open(Texture->Get_Full_Path(), TGA_READMODE),Texture->Get_Full_Path())) {
- D3DTexture=MissingTexture::_Get_Missing_Texture();
- HasFailed=true;
- IsLoading=false;
- End_Load();
- Apply(true);
- Add_Task_To_Delete_List(this);
- return;
- }
-
-
- unsigned bpp;
- WW3DFormat src_format,dest_format;
- Get_WW3D_Format(dest_format,src_format,bpp,targa);
- if (src_format!=WW3D_FORMAT_A8R8G8B8 &&
- src_format!=WW3D_FORMAT_R8G8B8 &&
- src_format!=WW3D_FORMAT_X8R8G8B8) {
- WWDEBUG_SAY(("Invalid TGA format used in %s - only 24 and 32 bit formats should be used!",Texture->Get_Full_Path().str()));
- }
-
- // Destination size will be the next power of two square from the larger width and height...
- unsigned width=targa.Header.Width, height=targa.Header.Height, depth=1;
- int ReductionFactor=Get_Reduction();
- int MipLevels=0;
-
- //Figure out how many mip levels this texture will occupy
- for (int i=width, j=height; i > 0 && j > 0; i>>=1, j>>=1)
- MipLevels++;
-
- //Adjust the reduction factor to keep textures above some minimum dimensions
- if (MipLevels <= WW3D::Get_Texture_Min_Dimension())
- ReductionFactor=0;
- else
- { int mipToDrop=MipLevels-WW3D::Get_Texture_Min_Dimension();
- if (ReductionFactor >= mipToDrop)
- ReductionFactor=mipToDrop;
- }
-
- width=targa.Header.Width>>ReductionFactor;
- height=targa.Header.Height>>ReductionFactor;
- unsigned ow=width;
- unsigned oh=height;
- TextureLoader::Validate_Texture_Size(width,height,depth);
- if (width!=ow || height!=oh) {
- WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d",Texture->Get_Full_Path().str(),ow,oh,width,height));
- }
-
- IsLoading=true;
- Width=width;
- Height=height;
-
- if (Format==WW3D_FORMAT_UNKNOWN) {
- Format=Get_Valid_Texture_Format(dest_format,false);
- }
- else {
- Format=Get_Valid_Texture_Format(Format,false);
- }
-
- D3DTexture=DX8Wrapper::_Create_DX8_Texture(Width,Height,Format,Texture->MipLevelCount);
- }
-
- MipLevelCount=D3DTexture->GetLevelCount();
- for (unsigned i=0;iLockRect(
- i,
- &locked_rect,
- NULL,
- 0));
- LockedSurfacePtr[i]=(unsigned char*)locked_rect.pBits;
- LockedSurfacePitch[i]=locked_rect.Pitch;
- }
-
- if (HighPriorityRequested) {
- TextureLoader::Load_Mipmap_Levels(this);
- End_Load();
- Apply(true);
- Add_Task_To_Delete_List(this);
- }
- else {
- LoaderThreadClass::Add_Task_To_Load_List(this);
- }
- }
- // Otherwise add to deferred list which will be handled by main thread
- else {
- Add_Deferred_Task(this);
- }
-}
-
-/* file_auto_ptr my_tga_file(_TheFileFactory,Texture->Get_Full_Path());
- if (my_tga_file->Is_Available()) {
- my_tga_file->Open();
- unsigned size=my_tga_file->Size();
- char* tga_memory=W3DNEWARRAY char[size];
- my_tga_file->Read(tga_memory,size);
- my_tga_file->Close();
-
- StringClass pth("data\\");
- pth+=Texture->Get_Texture_Name();
- RawFileClass tmp_tga_file(pth);
- tmp_tga_file.Create();
- tmp_tga_file.Write(tga_memory,size);
- tmp_tga_file.Close();
- delete[] tga_memory;
-
- }
-*/
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-void TextureLoadTaskClass::Begin_Thumbnail_Load()
-{
-// CriticalSectionClass::LockClass m(mutex);
-
- unsigned thread_id=ThreadClass::_Get_Current_Thread_ID();
- if (thread_id==DX8Wrapper::_Get_Main_Thread_ID()) {
- WW3DFormat format=Texture->Get_Texture_Format();
- // No compressed thumbnails
- switch (format) {
- case WW3D_FORMAT_DXT1:
- case WW3D_FORMAT_DXT2:
- case WW3D_FORMAT_DXT3:
- case WW3D_FORMAT_DXT4:
- case WW3D_FORMAT_DXT5:
- format=WW3D_FORMAT_A8R8G8B8; break;
- default:
- break;
- }
- D3DTexture=TextureLoader::Load_Thumbnail(Texture->Get_Full_Path(),format);
-
- // Thumbnail loads are always high priority, so apply immediatelly
- End_Load();
- Apply(false);
- Add_Task_To_Delete_List(this);
- return;
- }
- else {
- Add_Thumbnail_Task(this);
- }
-}
-
-// ----------------------------------------------------------------------------
-//
-// Deinit can be called multiple times. If any surfaces are locked this call
-// can only be called from the main thread.
-//
-// ----------------------------------------------------------------------------
-
-void TextureLoadTaskClass::End_Load()
-{
- for (unsigned i=0;iUnlockRect(i));
- }
- LockedSurfacePtr[i]=NULL;
- }
- IsLoading=false;
-
-}
-
-// ----------------------------------------------------------------------------
-//
-// Link the node to another task node. This can only be done if the node isn't
-// linked to something else already. If the node is linked to some other node,
-// the only acceptable parameter to this function is NULL, which will unlink
-// the connection.
-//
-// ----------------------------------------------------------------------------
-
-void TextureLoadTaskClass::Set_Succ(TextureLoadTaskClass* succ)
-{
- WWASSERT((succ && !Succ) || (!succ)); // Can't set successor pointer if it has been set already
- Succ=succ;
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-void TextureLoadTaskClass::Set_D3D_Texture(IDirect3DTexture8* texture)
-{
- WWASSERT(D3DTexture==0);
- D3DTexture=texture;
-}
-
-// ----------------------------------------------------------------------------
-//
-// Apply the D3D texture surface to the client texture. The parameter 'initialize'
-// determines whether the client texture will be set to initialized state or
-// not. Generally thumbnail tasks will not set texture to initialised state but
-// all other loads do.
-//
-// ----------------------------------------------------------------------------
-
-void TextureLoadTaskClass::Apply(bool initialize)
-{
- WWASSERT(D3DTexture);
- // Verify that none of the mip levels are locked
- for (unsigned i=0;iApply_New_Surface(initialize);
-
- D3DTexture->Release();
- D3DTexture=NULL;
-}
-
-// ----------------------------------------------------------------------------
-//
-// Return locked surface pointer at a specific level. The call will
-// assert if level is greater or equal to the number of mip levels or if the
-// requested level has not been locked.
-//
-// ----------------------------------------------------------------------------
-
-unsigned char* TextureLoadTaskClass::Get_Locked_Surface_Ptr(unsigned level)
-{
- WWASSERT(levelPeek_Succ();
- task->Set_Succ(NULL);
- }
- else {
- task=W3DNEW TextureLoadTaskClass();
- }
- task->Init(tc,high_priority);
- return task;
-}
-
-// ----------------------------------------------------------------------------
-//
-// When task is no longer needed it is returned to the pool.
-//
-// ----------------------------------------------------------------------------
-
-void TextureLoadTaskClass::Release_Instance(TextureLoadTaskClass* task)
-{
- if (!task) return;
-
- CriticalSectionClass::LockClass m(mutex);
-
- task->Deinit();
-
- // Task must not be in any list when it is being freed
- WWASSERT(task->Peek_Succ()==NULL);
-
- task->Set_Succ(FreeTaskListHead);
- FreeTaskListHead=task;
-}
-
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.h
deleted file mode 100644
index 534dc470187..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/textureloader.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-#pragma once
-
-#include "always.h"
-#include "texture.h"
-
-class StringClass;
-struct IDirect3DTexture8;
-class TextureLoadTaskClass;
-
-class TextureLoader
-{
- static void Init_Load_Task(TextureBaseClass* tc);
-
- static bool Load_Uncompressed_Mipmap_Levels_From_TGA(TextureLoadTaskClass* texture);
-
-public:
- static void Init();
- static void Deinit();
-
- // Modify given texture size to nearest valid size on current hardware.
- static void Validate_Texture_Size(unsigned& width, unsigned& height, unsigned& depth);
-
- // Adds a loading task to the system. The task if processed in a separate
- // thread as soon as possible. The task will appear in finished tasks list
- // when it's been completed. The texture will be refreshed on the next
- // update call after appearing to the finished tasks list.
- static void Add_Load_Task(TextureBaseClass* tc);
- static IDirect3DTexture8* Load_Thumbnail(
- const StringClass& filename,
- WW3DFormat texture_format); // Pass WW3D_FORMAT_UNKNOWN if you don't care
- static void Load_Mipmap_Levels(TextureLoadTaskClass* texture);
-
- static IDirect3DSurface8* Load_Surface_Immediate(
- const StringClass& filename,
- WW3DFormat surface_format, // Pass WW3D_FORMAT_UNKNOWN if you don't care
- bool allow_compression);
-
- // Textures can only be created and locked by the main thread so this function sends a request to the texture
- // handling system to load the texture immediatelly next time it enters the main thread. If this function
- // is called from the main thread the texture is loaded immediatelly.
- static void Request_High_Priority_Loading(
- TextureBaseClass* texture,
- MipCountType mip_level_count);
- static void Request_Thumbnail(TextureBaseClass* tc);
-
- static void Update();
- static void Flush_Pending_Load_Tasks();
-
- static IDirect3DTexture8* Generate_Bumpmap(TextureBaseClass* texture);
-
-};
-
-// ----------------------------------------------------------------------------
-//
-// Texture loader task handler
-//
-// ----------------------------------------------------------------------------
-
-class TextureLoadTaskClass : public W3DMPO
-{
- W3DMPO_GLUE(TextureLoadTaskClass)
-
- static TextureLoadTaskClass* FreeTaskListHead;
-
- TextureBaseClass* Texture;
- IDirect3DTexture8 *D3DTexture;
- unsigned Width;
- unsigned Height;
- WW3DFormat Format;
- unsigned char* LockedSurfacePtr[MIP_LEVELS_MAX];
- unsigned LockedSurfacePitch[MIP_LEVELS_MAX];
- unsigned MipLevelCount;
- unsigned Reduction;
- TextureLoadTaskClass* Succ;
- bool IsLoading;
- bool HasFailed;
- bool HighPriorityRequested;
-
- ~TextureLoadTaskClass();
- TextureLoadTaskClass();
-public:
- static TextureLoadTaskClass* Get_Instance(TextureBaseClass* tc, bool high_priority);
- static void Release_Instance(TextureLoadTaskClass* task);
- static void shutdown(void) {TextureLoadTaskClass *pT; while (FreeTaskListHead) {pT = FreeTaskListHead; FreeTaskListHead = pT->Peek_Succ(); pT->Set_Succ(NULL); delete pT;} };
-
- void Init(TextureBaseClass* tc,bool high_priority);
- void Deinit();
-
- unsigned Get_Mip_Level_Count() const { return MipLevelCount; }
- unsigned Get_Width() const { return Width; }
- unsigned Get_Height() const { return Height; }
- WW3DFormat Get_Format() const { return Format; }
- unsigned Get_Reduction() const { return Reduction; }
-
- unsigned char* Get_Locked_Surface_Ptr(unsigned level);
- unsigned Get_Locked_Surface_Pitch(unsigned level) const;
-
- bool Has_Failed() const { return HasFailed; }
- void Set_Fail(bool b) { HasFailed=b; }
-
- // Init the task or put it to a deferred init list if called from outside the main thread
- void Begin_Texture_Load();
- void Begin_Thumbnail_Load();
- void End_Load(); // Deinit must be called before Applying()
-
- void Apply(bool initialize);
-
- TextureLoadTaskClass* Peek_Succ() { return Succ; }
- void Set_Succ(TextureLoadTaskClass* succ);
-
- TextureBaseClass* Peek_Texture() { return Texture; }
- IDirect3DTexture8* Peek_D3D_Texture() { return D3DTexture; }
-
- void Set_D3D_Texture(IDirect3DTexture8* texture);
-};
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp
deleted file mode 100644
index 65744fb9136..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-#include "texturethumbnail.h"
-#include "hashtemplate.h"
-#include "missingtexture.h"
-#include "TARGA.h"
-#include "ww3dformat.h"
-#include "ddsfile.h"
-#include "textureloader.h"
-#include "bitmaphandler.h"
-#include "ffactory.h"
-
-static HashTemplateClass thumbnail_hash;
-static bool _ThumbHashModified;
-static unsigned char* _ThumbnailMemory;
-static const char *THUMBNAIL_FILENAME = "thumbnails.dat";
-
-ThumbnailClass::ThumbnailClass(const char* name, unsigned char* bitmap, unsigned w, unsigned h, bool allocated)
- :
- Name(name),
- Bitmap(bitmap),
- Allocated(allocated),
- Width(w),
- Height(h)
-{
- thumbnail_hash.Insert(Name,this);
-}
-
-// ----------------------------------------------------------------------------
-//
-// Load texture and generate mipmap levels if requested. The function tries
-// to create texture that matches targa format. If suitable format is not
-// available, it selects closest matching format and performs color space
-// conversion.
-//
-// ----------------------------------------------------------------------------
-
-ThumbnailClass::ThumbnailClass(const StringClass& filename)
- :
- Bitmap(0),
- Name(filename),
- Allocated(false),
- Width(0),
- Height(0)
-{
- unsigned reduction_factor=3;
-
- // First, try loading image from a DDS file
- DDSFileClass dds_file(filename,reduction_factor);
- if (dds_file.Is_Available() && dds_file.Load()) {
- Width=dds_file.Get_Width(0);
- Height=dds_file.Get_Height(0);
- Bitmap=W3DNEWARRAY unsigned char[Width*Height*4];
- Allocated=true;
- dds_file.Copy_Level_To_Surface(
- 0, // Level
- WW3D_FORMAT_A8R8G8B8,
- Width,
- Height,
- Bitmap,
- Width*4);
- }
- // If DDS file can't be used try loading from TGA
- else {
- // Make sure the file can be opened. If not, return missing texture.
- Targa targa;
- if (TARGA_ERROR_HANDLER(targa.Open(filename,TGA_READMODE),filename)) return;
-
- // DX8 uses image upside down compared to TGA
- targa.Header.ImageDescriptor ^= TGAIDF_YORIGIN;
-
- WW3DFormat src_format,dest_format;
- unsigned src_bpp=0;
- Get_WW3D_Format(dest_format,src_format,src_bpp,targa);
-
- // Destination size will be the next power of two square from the larger width and height...
- Width=targa.Header.Width>>reduction_factor;
- Height=targa.Header.Height>>reduction_factor;
- unsigned depth=1;
- TextureLoader::Validate_Texture_Size(Width,Height,depth);
- unsigned src_width=targa.Header.Width;
- unsigned src_height=targa.Header.Height;
-
- // NOTE: We load the palette but we do not yet support paletted textures!
- char palette[256*4];
- targa.SetPalette(palette);
- if (TARGA_ERROR_HANDLER(targa.Load(filename, TGAF_IMAGE, false),filename)) return;
-
- unsigned char* src_surface=(unsigned char*)targa.GetImage();
-
- Bitmap=W3DNEWARRAY unsigned char[Width*Height*4];
- Allocated=true;
-
- dest_format=WW3D_FORMAT_A8R8G8B8;
- BitmapHandlerClass::Copy_Image(
- Bitmap,
- Width,
- Height,
- Width*4,
- WW3D_FORMAT_A8R8G8B8,
- src_surface,
- src_width,
- src_height,
- src_width*src_bpp,
- src_format,
- (unsigned char*)targa.GetPalette(),
- targa.Header.CMapDepth>>3,
- false);
- }
-
- _ThumbHashModified=true;
- thumbnail_hash.Insert(Name,this);
-}
-
-ThumbnailClass::~ThumbnailClass()
-{
- if (Allocated) delete[] Bitmap;
- thumbnail_hash.Remove(Name);
-}
-
-ThumbnailClass* ThumbnailClass::Peek_Instance(const StringClass& name)
-{
- return thumbnail_hash.Get(name);
-}
-
-void ThumbnailClass::Init()
-{
- WWASSERT(!_ThumbnailMemory);
-
- // If the thumbnail hash table file is available, init hash table
-#if 0 // don't do thumbnail file.
- file_auto_ptr thumb_file(_TheFileFactory, THUMBNAIL_FILENAME);
- if (thumb_file->Is_Available()) {
- thumb_file->Open(FileClass::READ);
-
- char tmp[4];
- thumb_file->Read(tmp,4);
- if (tmp[0]=='T' && tmp[1]=='M' && tmp[2]=='B' && tmp[3]=='1') {
-
- int total_thumb_count;
- int total_header_length;
- int total_data_length;
- thumb_file->Read(&total_thumb_count,sizeof(int));
- thumb_file->Read(&total_header_length,sizeof(int));
- thumb_file->Read(&total_data_length,sizeof(int));
- if (total_thumb_count) {
- WWASSERT(total_data_length && total_header_length);
- _ThumbnailMemory=W3DNEWARRAY unsigned char[total_data_length];
- // Load thumbs
- for (int i=0;iRead(&offset,sizeof(int));
- thumb_file->Read(&width,sizeof(int));
- thumb_file->Read(&height,sizeof(int));
- thumb_file->Read(&date_time,sizeof(unsigned long));
- thumb_file->Read(&name_len,sizeof(int));
- WWASSERT(name_len<255);
- thumb_file->Read(name,name_len);
- name[name_len]='\0';
-
-
- // Make sure the file is available and the timestamp matches
- file_auto_ptr myfile(_TheFileFactory,name);
- if (myfile->Is_Available()) {
- myfile->Open(FileClass::READ);
- if (date_time==myfile->Get_Date_Time()) {
- W3DNEW ThumbnailClass(
- name,
- _ThumbnailMemory+offset-total_header_length,
- width,
- height,
- false);
- }
- myfile->Close();
- }
- }
- thumb_file->Read(_ThumbnailMemory,total_data_length);
- }
- }
- thumb_file->Close();
- }
-#endif
-}
-
-void ThumbnailClass::Deinit()
-{
- // If the thumbnail hash table was modified, save it to disk
- HashTemplateIterator ite(thumbnail_hash);
- if (_ThumbHashModified) {
-#if 0 // don't write thumbnails. jba.
- int total_header_length=0;
- int total_data_length=0;
- int total_thumb_count=0;
- total_header_length+=4; // header 'TMB1'
- total_header_length+=4; // thumb count
- total_header_length+=4; // header size
- total_header_length+=4; // data length
-
- for (ite.First();!ite.Is_Done();ite.Next()) {
- total_header_length+=4; // int bitmap offset
- total_header_length+=4; // int bitmap width
- total_header_length+=4; // int bitmap height
- total_header_length+=4; // unsigned long date_time
- total_header_length+=4; // int name string length
- ThumbnailClass* thumb=ite.Peek_Value();
- total_header_length+=strlen(thumb->Get_Name());
- total_data_length+=thumb->Get_Width()*thumb->Get_Height()*4;
- total_thumb_count++;
- }
- int offset=total_header_length;
-
- file_auto_ptr thumb_file(_TheWritingFileFactory, THUMBNAIL_FILENAME);
- if (thumb_file->Is_Available()) {
- thumb_file->Delete();
- }
- thumb_file->Create();
- thumb_file->Open(FileClass::WRITE);
-
- char* header="TMB1";
- thumb_file->Write(header,4);
- thumb_file->Write(&total_thumb_count,sizeof(int));
- thumb_file->Write(&total_header_length,sizeof(int));
- thumb_file->Write(&total_data_length,sizeof(int));
-
- // Save names and offsets
- for (ite.First();!ite.Is_Done();ite.Next()) {
- ThumbnailClass* thumb=ite.Peek_Value();
- const char* name=thumb->Get_Name();
- int name_len=strlen(name);
- int width=thumb->Get_Width();
- int height=thumb->Get_Height();
- unsigned long date_time=0;
- file_auto_ptr myfile(_TheFileFactory,name);
- if (myfile->Is_Available()) {
- myfile->Open(FileClass::READ);
- date_time=myfile->Get_Date_Time();
- myfile->Close();
- }
- thumb_file->Write(&offset,sizeof(int));
- thumb_file->Write(&width,sizeof(int));
- thumb_file->Write(&height,sizeof(int));
- thumb_file->Write(&date_time,sizeof(unsigned long));
- thumb_file->Write(&name_len,sizeof(int));
- thumb_file->Write(name,name_len);
- offset+=width*height*4;
- }
-
- // Save bitmaps
- offset=total_header_length;
- for (ite.First();!ite.Is_Done();ite.Next()) {
- ThumbnailClass* thumb=ite.Peek_Value();
- int width=thumb->Get_Width();
- int height=thumb->Get_Height();
- thumb_file->Write(thumb->Peek_Bitmap(),width*height*4);
- }
-
- thumb_file->Close();
-#endif
- }
-
- ite.First();
- while (!ite.Is_Done()) {
- ThumbnailClass* thumb=ite.Peek_Value();
- delete thumb;
- ite.First();
- }
-
- delete [] _ThumbnailMemory;
- _ThumbnailMemory=NULL;
-}
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.h
deleted file mode 100644
index b61e4271176..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/texturethumbnail.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-#pragma once
-
-#include "always.h"
-#include "wwstring.h"
-
-// ----------------------------------------------------------------------------
-
-class ThumbnailClass
-{
- StringClass Name;
- unsigned char* Bitmap;
- unsigned Width;
- unsigned Height;
- bool Allocated; // if true, destructor will free the memory
-public:
- ThumbnailClass(const char* name, unsigned char* bitmap, unsigned w, unsigned h, bool allocated);
- ThumbnailClass(const StringClass& filename);
- ~ThumbnailClass();
-
- unsigned char* Peek_Bitmap() { return Bitmap; }
- unsigned Get_Width() const { return Width; }
- unsigned Get_Height() const { return Height; }
- const StringClass& Get_Name() const { return Name; }
-
- static ThumbnailClass* Peek_Instance(const StringClass& name);
- static void Init();
- static void Deinit();
-};
-
-// ----------------------------------------------------------------------------
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp
index dac6fcc1ae4..38d966e5130 100644
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp
+++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp
@@ -248,14 +248,6 @@ void WW3D::Set_NPatches_Level(unsigned level)
NPatchesLevel = level;
}
-void WW3D::Set_Thumbnail_Enabled (bool b)
-{
- if (ThumbnailEnabled!=b) {
- ThumbnailEnabled = b;
- _Invalidate_Textures();
- }
-}
-
/***********************************************************************************************
* WW3D::Init -- Initialize the WW3D Library *
* *
@@ -775,7 +767,7 @@ void WW3D::Set_Texture_Filter(int texture_filter)
if (texture_filter<0) texture_filter=0;
if (texture_filter>TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC) texture_filter=TextureFilterClass::TEXTURE_FILTER_ANISOTROPIC;
TextureFilter=texture_filter;
- TextureFilterClass::_Init_Filters();
+ TextureFilterClass::_Init_Filters((TextureFilterClass::TextureFilterMode)TextureFilter);
}
@@ -826,7 +818,7 @@ WW3DErrorType WW3D::Begin_Render(bool clear,bool clearz,const Vector3 & color, f
LastFrameMemoryFrees=WWMemoryLogClass::Get_Free_Count();
WWMemoryLogClass::Reset_Counters();
- TextureLoader::Update();
+ TextureLoader::Update(network_callback);
// TextureClass::_Reset_Time_Stamp();
DynamicVBAccessClass::_Reset(true);
DynamicIBAccessClass::_Reset(true);
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h
index 1e0c158cec8..f169690b695 100644
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h
+++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h
@@ -228,7 +228,7 @@ class WW3D
static void _Invalidate_Mesh_Cache();
static void _Invalidate_Textures();
- static void Set_Thumbnail_Enabled(bool b);// { ThumbnailEnabled=b; }
+ static void Set_Thumbnail_Enabled(bool b) { ThumbnailEnabled=b; }
static bool Get_Thumbnail_Enabled() { return ThumbnailEnabled; }
static void Enable_Sorting(bool onoff);
diff --git a/Generals/Code/Tools/WorldBuilder/src/ObjectPreview.cpp b/Generals/Code/Tools/WorldBuilder/src/ObjectPreview.cpp
index 7be46780dd7..0e3cc1618fe 100644
--- a/Generals/Code/Tools/WorldBuilder/src/ObjectPreview.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/ObjectPreview.cpp
@@ -218,7 +218,7 @@ static UnsignedByte * generatePreview( const ThingTemplate *tt )
}
// Set the render target
- DX8Wrapper::Set_Render_Target(objectTexture);
+ DX8Wrapper::Set_Render_Target_With_Z(objectTexture);
// create the camera
Bool orthoCamera = false;
diff --git a/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp b/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp
index 07591396655..9603cd1ec85 100644
--- a/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp
+++ b/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp
@@ -637,7 +637,6 @@ int CWorldBuilderApp::ExitInstance()
delete TheFileSystem;
TheFileSystem = NULL;
- TextureLoadTaskClass::shutdown();
delete TheW3DFileSystem;
TheW3DFileSystem = NULL;
diff --git a/GeneralsMD/Code/GameEngine/CMakeLists.txt b/GeneralsMD/Code/GameEngine/CMakeLists.txt
index b77b4292e52..065d37a8fb3 100644
--- a/GeneralsMD/Code/GameEngine/CMakeLists.txt
+++ b/GeneralsMD/Code/GameEngine/CMakeLists.txt
@@ -225,7 +225,7 @@ set(GAMEENGINE_SRC
Include/GameClient/TerrainVisual.h
# Include/GameClient/VideoPlayer.h
# Include/GameClient/View.h
- Include/GameClient/Water.h
+# Include/GameClient/Water.h
Include/GameClient/WindowLayout.h
# Include/GameClient/WindowVideoManager.h
Include/GameClient/WindowXlat.h
@@ -825,7 +825,7 @@ set(GAMEENGINE_SRC
# Source/GameClient/VideoPlayer.cpp
# Source/GameClient/VideoStream.cpp
# Source/GameClient/View.cpp
- Source/GameClient/Water.cpp
+# Source/GameClient/Water.cpp
Source/GameLogic/AI/AI.cpp
Source/GameLogic/AI/AIDock.cpp
Source/GameLogic/AI/AIGroup.cpp
diff --git a/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt b/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt
index e1bb05cdb10..c96e1f0b278 100644
--- a/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt
+++ b/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt
@@ -13,7 +13,7 @@ set(GAMEENGINEDEVICE_SRC
Include/W3DDevice/GameClient/Module/W3DDebrisDraw.h
Include/W3DDevice/GameClient/Module/W3DDefaultDraw.h
Include/W3DDevice/GameClient/Module/W3DDependencyModelDraw.h
- Include/W3DDevice/GameClient/Module/W3DLaserDraw.h
+# Include/W3DDevice/GameClient/Module/W3DLaserDraw.h
Include/W3DDevice/GameClient/Module/W3DModelDraw.h
Include/W3DDevice/GameClient/Module/W3DOverlordAircraftDraw.h
Include/W3DDevice/GameClient/Module/W3DOverlordTankDraw.h
@@ -73,8 +73,8 @@ set(GAMEENGINEDEVICE_SRC
# Include/W3DDevice/GameClient/W3DVideoBuffer.h
# Include/W3DDevice/GameClient/W3DView.h
Include/W3DDevice/GameClient/W3DVolumetricShadow.h
- Include/W3DDevice/GameClient/W3DWater.h
- Include/W3DDevice/GameClient/W3DWaterTracks.h
+# Include/W3DDevice/GameClient/W3DWater.h
+# Include/W3DDevice/GameClient/W3DWaterTracks.h
Include/W3DDevice/GameClient/W3DWaypointBuffer.h
Include/W3DDevice/GameClient/W3DWebBrowser.h
Include/W3DDevice/GameClient/WorldHeightMap.h
@@ -102,7 +102,7 @@ set(GAMEENGINEDEVICE_SRC
Source/W3DDevice/GameClient/Drawable/Draw/W3DDebrisDraw.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DDefaultDraw.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DDependencyModelDraw.cpp
- Source/W3DDevice/GameClient/Drawable/Draw/W3DLaserDraw.cpp
+# Source/W3DDevice/GameClient/Drawable/Draw/W3DLaserDraw.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DOverlordAircraftDraw.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DOverlordTankDraw.cpp
@@ -176,8 +176,8 @@ set(GAMEENGINEDEVICE_SRC
# Source/W3DDevice/GameClient/W3DView.cpp
Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp
Source/W3DDevice/GameClient/W3DWebBrowser.cpp
- Source/W3DDevice/GameClient/Water/W3DWater.cpp
- Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
+# Source/W3DDevice/GameClient/Water/W3DWater.cpp
+# Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp
Source/W3DDevice/GameClient/WorldHeightMap.cpp
Source/W3DDevice/GameLogic/W3DGameLogic.cpp
Source/W3DDevice/GameLogic/W3DGhostObject.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
index eb4e80cee01..13f5bc1ef6e 100644
--- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
+++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
@@ -15,8 +15,8 @@ set(WW3D2_SRC
#assetstatus.h
#bitmaphandler.cpp
#bitmaphandler.h
- bmp2d.cpp
- bmp2d.h
+ #bmp2d.cpp
+ #bmp2d.h
boxrobj.cpp
boxrobj.h
#bwrender.cpp
@@ -56,8 +56,8 @@ set(WW3D2_SRC
dx8renderer.h
dx8rendererdebugger.cpp
dx8rendererdebugger.h
- dx8texman.cpp
- dx8texman.h
+ #dx8texman.cpp
+ #dx8texman.h
dx8vertexbuffer.cpp
dx8vertexbuffer.h
#dx8webbrowser.cpp
@@ -108,8 +108,8 @@ set(WW3D2_SRC
mapper.h
#matinfo.cpp
#matinfo.h
- matpass.cpp
- matpass.h
+ #matpass.cpp
+ #matpass.h
matrixmapper.cpp
matrixmapper.h
mesh.cpp
@@ -200,18 +200,18 @@ set(WW3D2_SRC
#stripoptimizer.h
#surfaceclass.cpp
#surfaceclass.h
- texproject.cpp
- texproject.h
+ #texproject.cpp
+ #texproject.h
#textdraw.cpp
#textdraw.h
- texture.cpp
- texture.h
- texturefilter.cpp
- texturefilter.h
- textureloader.cpp
- textureloader.h
- texturethumbnail.cpp
- texturethumbnail.h
+ #texture.cpp
+ #texture.h
+ #texturefilter.cpp
+ #texturefilter.h
+ #textureloader.cpp
+ #textureloader.h
+ #texturethumbnail.cpp
+ #texturethumbnail.h
vertmaterial.cpp
vertmaterial.h
#visrasterizer.cpp
diff --git a/scripts/cpp/unify_move_files.py b/scripts/cpp/unify_move_files.py
index 6d401ef28f2..42ec8582a26 100644
--- a/scripts/cpp/unify_move_files.py
+++ b/scripts/cpp/unify_move_files.py
@@ -190,6 +190,34 @@ def main():
#unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h")
#unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/bmp2d.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/bmp2d.cpp")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/bmp2d.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/bmp2d.h")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/dx8texman.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/dx8texman.cpp")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/dx8texman.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/dx8texman.h")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/matpass.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/matpass.cpp")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/matpass.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/matpass.h")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/texproject.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/texproject.cpp")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/texproject.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/texproject.h")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/texture.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/texture.cpp")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/texture.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/texture.h")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/texturefilter.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/texturefilter.cpp")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/texturefilter.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/texturefilter.h")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/textureloader.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/textureloader.cpp")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/textureloader.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/textureloader.h")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/texturethumbnail.cpp")
+ #unify_file(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/texturethumbnail.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/texturethumbnail.h")
+
+ #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameClient/Water.h", Game.CORE, "GameEngine/Include/GameClient/Water.h")
+ #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/Water.cpp", Game.CORE, "GameEngine/Source/GameClient/Water.cpp")
+ #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DLaserDraw.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DLaserDraw.h")
+ #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DWater.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DWater.h")
+ #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DWaterTracks.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DWaterTracks.h")
+ #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DLaserDraw.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DLaserDraw.cpp")
+ #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWater.cpp")
+ #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp")
+ #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvp")
+ #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvv", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvv")
+
return