| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- /*
- ** 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 <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // FILE: W3DWater.h ///////////////////////////////////////////////////
- #pragma once
- #ifndef __W3DWater_H_
- #define __W3DWater_H_
- #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
- WATER_TYPE_MAX // end of enumeration
- };
- 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); ///<draw the water surface (flat)
- Int init(Real waterLevel, Real dx, Real dy, SceneClass *parentScene, WaterType type);
- void reset( void ); ///< reset any resources we need to
- void load(void); ///< load/setup any map dependent features
- void update( void ); ///< update phase of the water
- void enableWaterGrid(Bool state); ///< used to active custom water for special maps. (i.e DAM).
- void setTimeOfDay(TimeOfDay tod); ///<change sky/water for time of day
- void toggleCloudLayer(Bool state) { m_useCloudLayer=state;} ///<enables/disables the cloud layer
- void updateRenderTargetTextures(CameraClass *cam); ///< renders into any required textures.
- void ReleaseResources(void); ///< Release all dx8 resources so the device can be reset.
- void ReAcquireResources(void); ///< Reacquire all resources after device reset.
- Real getWaterHeight(Real x, Real y); ///<return water height at given point - for use by WB.
- void setGridHeightClamps(Real minz, Real maxz); ///<set min/max height values alllowed in grid
- void addVelocity( Real worldX, Real worldY, Real zVelocity, Real preferredHeight ); ///< add velocity value
- void changeGridHeight(Real x, Real y, Real delta); ///<change height of grid at world point including neighbors within falloff.
- void setGridChangeAttenuationFactors(Real a, Real b, Real c, Real range); ///<adjust falloff parameters for grid change method.
- void setGridTransform(Real angle, Real x, Real y, Real z); ///<positoin/orientation of grid in space
- void setGridTransform(const Matrix3D *transform); ///< set transform by matrix
- void getGridTransform(Matrix3D *transform); ///< get grid transform matrix
- void setGridResolution(Real gridCellsX, Real gridCellsY, Real cellSize); ///<grid resolution and spacing
- void getGridResolution(Real *gridCellsX, Real *gridCellsY, Real *cellSize); ///<get grid resolution params
- inline void setGridVertexHeight(Int x, Int y, Real value);
- inline void getGridVertexHeight(Int x, Int y, Real *value)
- { if (m_meshData) *value=m_meshData[(y+1)*(m_gridCellsX+1+2)+x+1].height+ Get_Position().Z;}
- inline Bool worldToGridSpace(Real worldX, Real worldY, Real &gridX, Real &gridY); ///<convert from world coordinates to grid's local coordinate system.
- void replaceSkyboxTexture(const AsciiString& oldTexName, const AsciiString& newTextName);
- protected:
- DX8IndexBufferClass *m_indexBuffer; ///<indices defining quad
- SceneClass *m_parentScene; ///<scene to be reflected
- ShaderClass m_shaderClass; ///<shader or rendering state for heightmap
- VertexMaterialClass *m_vertexMaterialClass; ///<vertex lighting material
- VertexMaterialClass *m_meshVertexMaterialClass; ///<vertex lighting marial for 3D water.
- LightClass *m_meshLight; ///<light used for 3D Mesh Water.
- TextureClass *m_alphaClippingTexture; ///<used for faked clipping using alpha
- Real m_dx; ///<x extent of water surface (offset from local center)
- Real m_dy; ///<y extent of water surface (offset from local center)
- Vector3 m_planeNormal; ///<water plane normal
- Real m_planeDistance; ///<water plane distance
- Real m_level; ///<level of water (hack for water)
- Real m_uOffset; ///<current texture offset on u axis
- Real m_vOffset; ///<current texture offset on v axis
- Real m_uScrollPerMs; ///<texels per/ms scroll rate in u direction
- Real m_vScrollPerMs; ///<texels per/ms scroll rate in v direction
- Int m_LastUpdateTime; ///<time of last cloud update
- Bool m_useCloudLayer; ///<flag if clouds are on/off
- WaterType m_waterType; ///<type of water being used
- Int m_sortLevel; ///<sort order after main scene is rendered
- //Data used in GeForce3 bump-mapped water (uses direct D3D resources for better
- //performance and compatibility (most of these featues are not supported by W3D).
- struct SEA_PATCH_VERTEX //vertex structure passed to D3D
- {
- float x,y,z;
- unsigned int c;
- float tu, tv;
- };
- LPDIRECT3DDEVICE8 m_pDev; ///<pointer to D3D Device
- LPDIRECT3DVERTEXBUFFER8 m_vertexBufferD3D; ///<D3D vertex buffer
- LPDIRECT3DINDEXBUFFER8 m_indexBufferD3D; ///<D3D index buffer
- Int m_vertexBufferD3DOffset; ///<location to start writing vertices
- DWORD m_dwWavePixelShader; ///<handle to D3D pixel shader
- DWORD m_dwWaveVertexShader; ///<handle to D3D vertex shader
- Int m_numVertices; ///<number of vertices in D3D vertex buffer
- Int m_numIndices; ///<number of indices in D3D index buffer
- LPDIRECT3DTEXTURE8 m_pBumpTexture[NUM_BUMP_FRAMES]; ///<animation frames
- LPDIRECT3DTEXTURE8 m_pBumpTexture2[NUM_BUMP_FRAMES]; ///<animation frames
- Int m_iBumpFrame; ///<current animation frame
- Real m_fBumpScale; ///<scales bump map uv perturbation
- TextureClass * m_pReflectionTexture; ///<render target for reflection
- RenderObjClass *m_skyBox; ///<box around level
- WaterTracksRenderSystem *m_waterTrackSystem; ///<object responsible for rendering water wakes
- enum WaterMeshStatus
- {
- AT_REST = 0x00,
- IN_MOTION = 0x01
- };
- struct WaterMeshData
- {
- Real height; ///< height of the 3D mesh at this point
- Real velocity; ///< velocity in Z that this point is moving up and down
- UnsignedByte status; ///< status for this grid point
- UnsignedByte preferredHeight; ///< the hight we prefer to be
- };
- WaterMeshData *m_meshData; ///< heightmap data for 3D Mesh based water.
- UnsignedInt m_meshDataSize; ///< size of m_meshData
- Bool m_meshInMotion; ///< TRUE once we've messed with velocities and are in motion
- Bool m_doWaterGrid; ///< allows/prevents water grid rendering.
- Vector2 m_gridDirectionX; ///<vector along water grid's x-axis (scaled to world-space)
- Vector2 m_gridDirectionY; ///<vector along water grid's y-axis (scaled to world-space)
- Vector2 m_gridOrigin; ///<unit vector along water grid's x-axis
- Real m_gridWidth; ///<object-space width of water grid
- Real m_gridHeight; ///<object-space width of water grid
- Real m_minGridHeight; ///<minimum height value allowed for water mesh
- Real m_maxGridHeight; ///<maximum height value allowed for water mesh
- Real m_gridChangeMaxRange; ///<maximum range of changeGridHeight() method
- Real m_gridChangeAtt0;
- Real m_gridChangeAtt1;
- Real m_gridChangeAtt2;
- Real m_gridCellSize; ///<world-space width/height of each cell.
- Int m_gridCellsX; ///<number of cells along width
- Int m_gridCellsY; ///<number of cells along height
- Real m_riverVOrigin;
- TextureClass *m_riverTexture;
- TextureClass *m_whiteTexture; ///< a texture containing only white used for NULL pixel shader stages.
- TextureClass *m_waterNoiseTexture;
- DWORD m_waterPixelShader; ///<D3D handle to pixel shader.
- DWORD m_riverWaterPixelShader; ///<D3D handle to pixel shader.
- DWORD m_trapezoidWaterPixelShader; ///<handle to D3D vertex shader
- TextureClass *m_waterSparklesTexture;
- Real m_riverXOffset;
- Real m_riverYOffset;
- Bool m_drawingRiver;
- Bool m_disableRiver;
- TextureClass *m_riverAlphaEdge;
- TimeOfDay m_tod; ///<time of day setting for reflected cloud layer
- struct Setting
- {
- TextureClass *skyTexture;
- TextureClass *waterTexture;
- Int waterRepeatCount;
- Real skyTexelsPerUnit; //texel density of sky plane (higher value repeats texture more).
- DWORD vertex00Diffuse;
- DWORD vertex10Diffuse;
- DWORD vertex11Diffuse;
- DWORD vertex01Diffuse;
- DWORD waterDiffuse;
- DWORD transparentWaterDiffuse;
- Real uScrollPerMs;
- Real vScrollPerMs;
- };
- Setting m_settings[ TIME_OF_DAY_COUNT ]; ///< settings for each time of day
- void drawRiverWater(PolygonTrigger *pTrig);
- void drawTrapezoidWater(Vector3 points[4]);
- void loadSetting ( Setting *skySetting, TimeOfDay timeOfDay ); ///<init sky/water settings from GDF
- void renderSky(void); ///<draw the sky layer (clouds, stars, etc.)
- void testCurvedWater(void); ///<draw the sky layer (clouds, stars, etc.)
- void renderSkyBody(Matrix3D *mat); ///<draw the sky body (sun, moon, etc.)
- void renderWaterMesh(void); ///<draw the water surface mesh (deformed 3d mesh).
- HRESULT initBumpMap(LPDIRECT3DTEXTURE8 *pTex, TextureClass *pBumpSource); ///<copies data into bump-map format.
- void renderMirror(CameraClass *cam); ///< Draw reflected scene into texture
- void drawSea(RenderInfoClass & rinfo); ///< Draw the surface of the water
- ///bounding box of frustum clipped polygon plane
- Bool getClippedWaterPlane(CameraClass *cam, AABoxClass *box);
- void setupFlatWaterShader(void);
- void setupJbaWaterShader(void);
- void cleanupJbaWaterShader(void);
- //Methods used for GeForce3 specific water
- HRESULT WaterRenderObjClass::generateIndexBuffer(int sizeX, int sizeY); ///<Generate static index buufer
- HRESULT WaterRenderObjClass::generateVertexBuffer( Int sizeX, Int sizeY, Int vertexSize, Bool doFill);///<Generate static vertex buffer
- // snapshot methods for save/load
- virtual void crc( Xfer *xfer );
- virtual void xfer( Xfer *xfer );
- virtual void loadPostProcess( void );
- };
- //Public inline function declerations
- inline Bool WaterRenderObjClass::worldToGridSpace(Real worldX, Real worldY, Real &gridX, Real &gridY)
- {
- Real dx,dy;
- Real ooGridCellSize = 1.0f/m_gridCellSize;
- dx=worldX - m_gridOrigin.X;
- dy=worldY - m_gridOrigin.Y;
- gridX = ooGridCellSize * (dx * m_gridDirectionX.X + dy * m_gridDirectionX.Y);
- gridY = ooGridCellSize * (dx * m_gridDirectionY.X + dy * m_gridDirectionY.Y);
-
- if (gridX < 0)
- return FALSE;
- if (gridX > m_gridCellsX-1 )
- return FALSE;
- if (gridY < 0)
- return FALSE;
- if (gridY > m_gridCellsY-1 )
- return FALSE;
- return TRUE;
- }
- extern WaterRenderObjClass *TheWaterRenderObj; ///<global water rendering object
- #endif // end __W3DWater_H_
|