W3DWater.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: W3DWater.h ///////////////////////////////////////////////////
  24. #pragma once
  25. #ifndef __W3DWater_H_
  26. #define __W3DWater_H_
  27. #include "always.h"
  28. #include "rendobj.h"
  29. #include "w3d_file.h"
  30. #include "dx8vertexbuffer.h"
  31. #include "dx8indexbuffer.h"
  32. #include "shader.h"
  33. #include "vertmaterial.h"
  34. #include "light.h"
  35. #include "Lib/BaseType.h"
  36. #include "Common/GameType.h"
  37. #include "Common/Snapshot.h"
  38. #define INVALID_WATER_HEIGHT 0.0f ///water height guaranteed to be below all terrain.
  39. #define NUM_BUMP_FRAMES 32 ///number of animation frames in bump map
  40. //Offsets in constant register file to Vertex shader constants
  41. #define CV_ZERO 0
  42. #define CV_ONE 1
  43. #define CV_WORLDVIEWPROJ_0 2
  44. #define CV_TEXPROJ_0 6
  45. #define CV_PATCH_SCALE_OFFSET 10
  46. class PolygonTrigger;
  47. class WaterTracksRenderSystem;
  48. class Xfer;
  49. /// Custom render object that draws mirrors, water, and skies.
  50. /**
  51. This render object handles drawing reflected W3D scenes. It will only work
  52. with rectangular planar surfaces and was tuned with an emphasis on water.
  53. Since skies are only visible in reflections, this code will also
  54. render clouds and sky bodies.
  55. */
  56. class WaterRenderObjClass : public Snapshot,
  57. public RenderObjClass
  58. {
  59. public:
  60. enum WaterType
  61. {
  62. WATER_TYPE_0_TRANSLUCENT = 0, //translucent water, no reflection
  63. WATER_TYPE_1_FB_REFLECTION, //legacy frame buffer reflection (non translucent)
  64. WATER_TYPE_2_PVSHADER, //pixel/vertex shader, texture reflection
  65. WATER_TYPE_3_GRIDMESH, //3D Mesh based water
  66. WATER_TYPE_MAX // end of enumeration
  67. };
  68. WaterRenderObjClass(void);
  69. ~WaterRenderObjClass(void);
  70. /////////////////////////////////////////////////////////////////////////////
  71. // Render Object Interface (W3D methods)
  72. /////////////////////////////////////////////////////////////////////////////
  73. virtual RenderObjClass * Clone(void) const;
  74. virtual int Class_ID(void) const;
  75. virtual void Render(RenderInfoClass & rinfo);
  76. /// @todo: Add methods for collision detection with water surface
  77. // virtual Bool Cast_Ray(RayCollisionTestClass & raytest);
  78. // virtual Bool Cast_AABox(AABoxCollisionTestClass & boxtest);
  79. // virtual Bool Cast_OBBox(OBBoxCollisionTestClass & boxtest);
  80. // virtual Bool Intersect_AABox(AABoxIntersectionTestClass & boxtest);
  81. // virtual Bool Intersect_OBBox(OBBoxIntersectionTestClass & boxtest);
  82. virtual void Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const;
  83. virtual void Get_Obj_Space_Bounding_Box(AABoxClass & aabox) const;
  84. // Get and set static sort level
  85. virtual int Get_Sort_Level(void) const { return m_sortLevel; }
  86. virtual void Set_Sort_Level(int level) { m_sortLevel = level;}
  87. ///allocate W3D resources needed to render water
  88. void renderWater(void); ///<draw the water surface (flat)
  89. Int init(Real waterLevel, Real dx, Real dy, SceneClass *parentScene, WaterType type);
  90. void reset( void ); ///< reset any resources we need to
  91. void load(void); ///< load/setup any map dependent features
  92. void update( void ); ///< update phase of the water
  93. void enableWaterGrid(Bool state); ///< used to active custom water for special maps. (i.e DAM).
  94. void updateMapOverrides(void); ///< used to update any map specific map overrides for water appearance.
  95. void setTimeOfDay(TimeOfDay tod); ///<change sky/water for time of day
  96. void toggleCloudLayer(Bool state) { m_useCloudLayer=state;} ///<enables/disables the cloud layer
  97. void updateRenderTargetTextures(CameraClass *cam); ///< renders into any required textures.
  98. void ReleaseResources(void); ///< Release all dx8 resources so the device can be reset.
  99. void ReAcquireResources(void); ///< Reacquire all resources after device reset.
  100. Real getWaterHeight(Real x, Real y); ///<return water height at given point - for use by WB.
  101. void setGridHeightClamps(Real minz, Real maxz); ///<set min/max height values alllowed in grid
  102. void addVelocity( Real worldX, Real worldY, Real zVelocity, Real preferredHeight ); ///< add velocity value
  103. void changeGridHeight(Real x, Real y, Real delta); ///<change height of grid at world point including neighbors within falloff.
  104. void setGridChangeAttenuationFactors(Real a, Real b, Real c, Real range); ///<adjust falloff parameters for grid change method.
  105. void setGridTransform(Real angle, Real x, Real y, Real z); ///<positoin/orientation of grid in space
  106. void setGridTransform(const Matrix3D *transform); ///< set transform by matrix
  107. void getGridTransform(Matrix3D *transform); ///< get grid transform matrix
  108. void setGridResolution(Real gridCellsX, Real gridCellsY, Real cellSize); ///<grid resolution and spacing
  109. void getGridResolution(Real *gridCellsX, Real *gridCellsY, Real *cellSize); ///<get grid resolution params
  110. inline void setGridVertexHeight(Int x, Int y, Real value);
  111. inline void getGridVertexHeight(Int x, Int y, Real *value)
  112. { if (m_meshData) *value=m_meshData[(y+1)*(m_gridCellsX+1+2)+x+1].height+ Get_Position().Z;}
  113. inline Bool worldToGridSpace(Real worldX, Real worldY, Real &gridX, Real &gridY); ///<convert from world coordinates to grid's local coordinate system.
  114. void replaceSkyboxTexture(const AsciiString& oldTexName, const AsciiString& newTextName);
  115. protected:
  116. DX8IndexBufferClass *m_indexBuffer; ///<indices defining quad
  117. SceneClass *m_parentScene; ///<scene to be reflected
  118. ShaderClass m_shaderClass; ///<shader or rendering state for heightmap
  119. VertexMaterialClass *m_vertexMaterialClass; ///<vertex lighting material
  120. VertexMaterialClass *m_meshVertexMaterialClass; ///<vertex lighting marial for 3D water.
  121. LightClass *m_meshLight; ///<light used for 3D Mesh Water.
  122. TextureClass *m_alphaClippingTexture; ///<used for faked clipping using alpha
  123. Real m_dx; ///<x extent of water surface (offset from local center)
  124. Real m_dy; ///<y extent of water surface (offset from local center)
  125. Vector3 m_planeNormal; ///<water plane normal
  126. Real m_planeDistance; ///<water plane distance
  127. Real m_level; ///<level of water (hack for water)
  128. Real m_uOffset; ///<current texture offset on u axis
  129. Real m_vOffset; ///<current texture offset on v axis
  130. Real m_uScrollPerMs; ///<texels per/ms scroll rate in u direction
  131. Real m_vScrollPerMs; ///<texels per/ms scroll rate in v direction
  132. Int m_LastUpdateTime; ///<time of last cloud update
  133. Bool m_useCloudLayer; ///<flag if clouds are on/off
  134. WaterType m_waterType; ///<type of water being used
  135. Int m_sortLevel; ///<sort order after main scene is rendered
  136. //Data used in GeForce3 bump-mapped water (uses direct D3D resources for better
  137. //performance and compatibility (most of these featues are not supported by W3D).
  138. struct SEA_PATCH_VERTEX //vertex structure passed to D3D
  139. {
  140. float x,y,z;
  141. unsigned int c;
  142. float tu, tv;
  143. };
  144. LPDIRECT3DDEVICE8 m_pDev; ///<pointer to D3D Device
  145. LPDIRECT3DVERTEXBUFFER8 m_vertexBufferD3D; ///<D3D vertex buffer
  146. LPDIRECT3DINDEXBUFFER8 m_indexBufferD3D; ///<D3D index buffer
  147. Int m_vertexBufferD3DOffset; ///<location to start writing vertices
  148. DWORD m_dwWavePixelShader; ///<handle to D3D pixel shader
  149. DWORD m_dwWaveVertexShader; ///<handle to D3D vertex shader
  150. Int m_numVertices; ///<number of vertices in D3D vertex buffer
  151. Int m_numIndices; ///<number of indices in D3D index buffer
  152. LPDIRECT3DTEXTURE8 m_pBumpTexture[NUM_BUMP_FRAMES]; ///<animation frames
  153. LPDIRECT3DTEXTURE8 m_pBumpTexture2[NUM_BUMP_FRAMES]; ///<animation frames
  154. Int m_iBumpFrame; ///<current animation frame
  155. Real m_fBumpScale; ///<scales bump map uv perturbation
  156. TextureClass * m_pReflectionTexture; ///<render target for reflection
  157. RenderObjClass *m_skyBox; ///<box around level
  158. WaterTracksRenderSystem *m_waterTrackSystem; ///<object responsible for rendering water wakes
  159. enum WaterMeshStatus
  160. {
  161. AT_REST = 0x00,
  162. IN_MOTION = 0x01
  163. };
  164. struct WaterMeshData
  165. {
  166. Real height; ///< height of the 3D mesh at this point
  167. Real velocity; ///< velocity in Z that this point is moving up and down
  168. UnsignedByte status; ///< status for this grid point
  169. UnsignedByte preferredHeight; ///< the hight we prefer to be
  170. };
  171. WaterMeshData *m_meshData; ///< heightmap data for 3D Mesh based water.
  172. UnsignedInt m_meshDataSize; ///< size of m_meshData
  173. Bool m_meshInMotion; ///< TRUE once we've messed with velocities and are in motion
  174. Bool m_doWaterGrid; ///< allows/prevents water grid rendering.
  175. Vector2 m_gridDirectionX; ///<vector along water grid's x-axis (scaled to world-space)
  176. Vector2 m_gridDirectionY; ///<vector along water grid's y-axis (scaled to world-space)
  177. Vector2 m_gridOrigin; ///<unit vector along water grid's x-axis
  178. Real m_gridWidth; ///<object-space width of water grid
  179. Real m_gridHeight; ///<object-space width of water grid
  180. Real m_minGridHeight; ///<minimum height value allowed for water mesh
  181. Real m_maxGridHeight; ///<maximum height value allowed for water mesh
  182. Real m_gridChangeMaxRange; ///<maximum range of changeGridHeight() method
  183. Real m_gridChangeAtt0;
  184. Real m_gridChangeAtt1;
  185. Real m_gridChangeAtt2;
  186. Real m_gridCellSize; ///<world-space width/height of each cell.
  187. Int m_gridCellsX; ///<number of cells along width
  188. Int m_gridCellsY; ///<number of cells along height
  189. Real m_riverVOrigin;
  190. TextureClass *m_riverTexture;
  191. TextureClass *m_whiteTexture; ///< a texture containing only white used for NULL pixel shader stages.
  192. TextureClass *m_waterNoiseTexture;
  193. DWORD m_waterPixelShader; ///<D3D handle to pixel shader.
  194. DWORD m_riverWaterPixelShader; ///<D3D handle to pixel shader.
  195. DWORD m_trapezoidWaterPixelShader; ///<handle to D3D vertex shader
  196. TextureClass *m_waterSparklesTexture;
  197. Real m_riverXOffset;
  198. Real m_riverYOffset;
  199. Bool m_drawingRiver;
  200. Bool m_disableRiver;
  201. TextureClass *m_riverAlphaEdge;
  202. TimeOfDay m_tod; ///<time of day setting for reflected cloud layer
  203. struct Setting
  204. {
  205. TextureClass *skyTexture;
  206. TextureClass *waterTexture;
  207. Int waterRepeatCount;
  208. Real skyTexelsPerUnit; //texel density of sky plane (higher value repeats texture more).
  209. DWORD vertex00Diffuse;
  210. DWORD vertex10Diffuse;
  211. DWORD vertex11Diffuse;
  212. DWORD vertex01Diffuse;
  213. DWORD waterDiffuse;
  214. DWORD transparentWaterDiffuse;
  215. Real uScrollPerMs;
  216. Real vScrollPerMs;
  217. };
  218. Setting m_settings[ TIME_OF_DAY_COUNT ]; ///< settings for each time of day
  219. void drawRiverWater(PolygonTrigger *pTrig);
  220. void drawTrapezoidWater(Vector3 points[4]);
  221. void loadSetting ( Setting *skySetting, TimeOfDay timeOfDay ); ///<init sky/water settings from GDF
  222. void renderSky(void); ///<draw the sky layer (clouds, stars, etc.)
  223. void testCurvedWater(void); ///<draw the sky layer (clouds, stars, etc.)
  224. void renderSkyBody(Matrix3D *mat); ///<draw the sky body (sun, moon, etc.)
  225. void renderWaterMesh(void); ///<draw the water surface mesh (deformed 3d mesh).
  226. HRESULT initBumpMap(LPDIRECT3DTEXTURE8 *pTex, TextureClass *pBumpSource); ///<copies data into bump-map format.
  227. void renderMirror(CameraClass *cam); ///< Draw reflected scene into texture
  228. void drawSea(RenderInfoClass & rinfo); ///< Draw the surface of the water
  229. ///bounding box of frustum clipped polygon plane
  230. Bool getClippedWaterPlane(CameraClass *cam, AABoxClass *box);
  231. void setupFlatWaterShader(void);
  232. void setupJbaWaterShader(void);
  233. void cleanupJbaWaterShader(void);
  234. //Methods used for GeForce3 specific water
  235. HRESULT WaterRenderObjClass::generateIndexBuffer(int sizeX, int sizeY); ///<Generate static index buufer
  236. HRESULT WaterRenderObjClass::generateVertexBuffer( Int sizeX, Int sizeY, Int vertexSize, Bool doFill);///<Generate static vertex buffer
  237. // snapshot methods for save/load
  238. virtual void crc( Xfer *xfer );
  239. virtual void xfer( Xfer *xfer );
  240. virtual void loadPostProcess( void );
  241. };
  242. //Public inline function declerations
  243. inline Bool WaterRenderObjClass::worldToGridSpace(Real worldX, Real worldY, Real &gridX, Real &gridY)
  244. {
  245. Real dx,dy;
  246. Real ooGridCellSize = 1.0f/m_gridCellSize;
  247. dx=worldX - m_gridOrigin.X;
  248. dy=worldY - m_gridOrigin.Y;
  249. gridX = ooGridCellSize * (dx * m_gridDirectionX.X + dy * m_gridDirectionX.Y);
  250. gridY = ooGridCellSize * (dx * m_gridDirectionY.X + dy * m_gridDirectionY.Y);
  251. if (gridX < 0)
  252. return FALSE;
  253. if (gridX > m_gridCellsX-1 )
  254. return FALSE;
  255. if (gridY < 0)
  256. return FALSE;
  257. if (gridY > m_gridCellsY-1 )
  258. return FALSE;
  259. return TRUE;
  260. }
  261. extern WaterRenderObjClass *TheWaterRenderObj; ///<global water rendering object
  262. #endif // end __W3DWater_H_