temp commit
[SARndbox.git] / WaterTable2.h
blob630dd6e23632a035712166161c49ba64979dc60b
1 /***********************************************************************
2 WaterTable2 - Class to simulate water flowing over a surface using
3 improved water flow simulation based on Saint-Venant system of partial
4 differenctial equations.
5 Copyright (c) 2012-2016 Oliver Kreylos
7 This file is part of the Augmented Reality Sandbox (SARndbox).
9 The Augmented Reality Sandbox is free software; you can redistribute it
10 and/or modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
14 The Augmented Reality Sandbox is distributed in the hope that it will be
15 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License along
20 with the Augmented Reality Sandbox; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 ***********************************************************************/
24 #ifndef WATERTABLE2_INCLUDED
25 #define WATERTABLE2_INCLUDED
27 #include <vector>
28 #include <Misc/FunctionCalls.h>
29 #include <Geometry/Point.h>
30 #include <Geometry/Box.h>
31 #include <Geometry/OrthonormalTransformation.h>
32 #include <GL/gl.h>
33 #include <GL/Extensions/GLARBShaderObjects.h>
34 #include <GL/GLObject.h>
35 #include <GL/GLContextData.h>
37 #include "Types.h"
39 /* Forward declarations: */
40 class DepthImageRenderer;
42 typedef Misc::FunctionCall<GLContextData&>
43 AddWaterFunction; // Type for render functions called to locally add water to the water table
45 class WaterTable2: public GLObject {
46 /* Embedded classes: */
47 public:
48 typedef Geometry::Box<Scalar, 3> Box;
49 typedef Geometry::OrthonormalTransformation<Scalar, 3> ONTransform;
51 private:
52 struct DataItem: public GLObject::DataItem { // Structure holding per-context state
53 /* Elements: */
54 public:
55 GLuint bathymetryTextureObjects[2]; // Double-buffered one-component float color texture object holding the vertex-centered bathymetry grid
56 int currentBathymetry; // Index of bathymetry texture containing the most recent bathymetry grid
57 unsigned int bathymetryVersion; // Version number of the most recent bathymetry grid
58 GLuint quantityTextureObjects[3]; // Double-buffered three-component color texture object holding the cell-centered conserved quantity grid (w, hu, hv)
59 int currentQuantity; // Index of quantity texture containing the most recent conserved quantity grid
60 GLuint derivativeTextureObject; // Three-component color texture object holding the cell-centered temporal derivative grid
61 GLuint maxStepSizeTextureObjects[2]; // Double-buffered one-component color texture objects to gather the maximum step size for Runge-Kutta integration steps
62 GLuint waterTextureObject; // One-component color texture object to add or remove water to/from the conserved quantity grid
63 GLuint bathymetryFramebufferObject; // Frame buffer used to render the bathymetry surface into the bathymetry grid
64 GLuint derivativeFramebufferObject; // Frame buffer used for temporal derivative computation
65 GLuint maxStepSizeFramebufferObject; // Frame buffer used to calculate the maximum integration step size
66 GLuint integrationFramebufferObject; // Frame buffer used for the Euler and Runge-Kutta integration steps
67 GLuint waterFramebufferObject; // Frame buffer used for the water rendering step
68 GLhandleARB
69 bathymetryShader; // Shader to update cell-centered conserved quantities after a change to the bathymetry grid
70 GLint bathymetryShaderUniformLocations[3];
71 GLhandleARB
72 waterAdaptShader; // Shader to adapt a new conserved quantity grid to the current bathymetry grid
73 GLint waterAdaptShaderUniformLocations[2];
74 GLhandleARB
75 derivativeShader; // Shader to compute face-centered partial fluxes and cell-centered temporal derivatives
76 GLint derivativeShaderUniformLocations[6];
77 GLhandleARB
78 maxStepSizeShader; // Shader to compute a maximum step size for a subsequent Runge-Kutta integration step
79 GLint maxStepSizeShaderUniformLocations[2];
80 GLhandleARB boundaryShader; // Shader to enforce boundary conditions on the quantities grid
81 GLint boundaryShaderUniformLocations[1];
82 GLhandleARB eulerStepShader; // Shader to compute an Euler integration step
83 GLint eulerStepShaderUniformLocations[4];
84 GLhandleARB rungeKuttaStepShader; // Shader to compute a Runge-Kutta integration step
85 GLint rungeKuttaStepShaderUniformLocations[5];
86 GLhandleARB waterAddShader; // Shader to render water adder objects
87 GLint waterAddShaderUniformLocations[3];
88 GLhandleARB waterShader; // Shader to add or remove water from the conserved quantities grid
89 GLint waterShaderUniformLocations[3];
91 /* Constructors and destructors: */
92 DataItem(void);
93 virtual ~DataItem(void);
96 /* Elements: */
97 GLsizei size[2]; // Width and height of water table in pixels
98 const DepthImageRenderer*
99 depthImageRenderer; // Renderer object used to update the water table's bathymetry grid
100 ONTransform baseTransform; // Transformation from camera space to upright elevation map space
101 Box domain; // Domain of elevation map space in rotated camera space
102 GLfloat cellSize[2]; // Width and height of water table cells in world coordinate units
103 PTransform
104 bathymetryPmv; // Combined projection and modelview matrix to render the current surface into the bathymetry grid
105 PTransform
106 waterAddPmv; // Combined projection and modelview matrix to render water-adding geometry into the water grid
107 GLfloat waterAddPmvMatrix[16]; // Same, in GLSL-compatible format
108 GLfloat theta; // Coefficient for minmod flux-limiting differential operator
109 GLfloat g; // Gravitiational acceleration constant
110 GLfloat epsilon; // Coefficient for desingularizing division operator
111 GLfloat attenuation; // Attenuation factor for partial discharges
112 GLfloat maxStepSize; // Maximum step size for each Runge-Kutta integration step
113 PTransform
114 waterTextureTransform; // Projective transformation from camera space to water level texture space
115 GLfloat waterTextureTransformMatrix[16]; // Same in GLSL-compatible format
116 std::vector<const AddWaterFunction*>
117 renderFunctions; // A list of functions that are called after each water flow simulation step to locally add or remove water from the water table
118 GLfloat waterDeposit; // A fixed amount of water added at every iteration of the flow simulation, for evaporation etc.
119 bool dryBoundary; // Flag whether to enforce dry boundary conditions at the end of each simulation step
120 unsigned int
121 readBathymetryRequest; // Request token to read back the current bathymetry grid from the GPU
122 mutable GLfloat* readBathymetryBuffer; // Buffer into which to read the current bathymetry grid
123 mutable unsigned int
124 readBathymetryReply; // Reply token after reading back the current bathymetry grid
126 /* Private methods: */
127 void calcTransformations(void); // Calculates derived transformations
128 GLfloat calcDerivative(DataItem* dataItem, GLuint quantityTextureObject,
129 bool calcMaxStepSize)
130 const; // Calculates the temporal derivative of the conserved quantities in the given texture object and returns maximum step size if flag is true
132 /* Constructors and destructors: */
133 public:
134 WaterTable2(GLsizei width, GLsizei height,
135 const GLfloat sCellSize[2]); // Creates water table for offline simulation
136 WaterTable2(GLsizei width, GLsizei height, const DepthImageRenderer* sDepthImageRenderer,
137 const Point
138 basePlaneCorners[4]); // Creates a water table of the given size in pixels, for the base plane quadrilateral defined by the depth image renderer's plane equation and four corner points
139 virtual ~WaterTable2(void);
141 /* Methods from GLObject: */
142 virtual void initContext(GLContextData& contextData) const;
144 /* New methods: */
145 const GLsizei* getSize(void) const { // Returns the size of the water table
146 return size;
148 const ONTransform& getBaseTransform(void)
149 const { // Returns the transformation from camera space to upright elevation map space
150 return baseTransform;
152 const Box& getDomain(void) const { // Returns the water table's domain in rotated camera space
153 return domain;
155 const GLfloat* getCellSize(void) const { // Returns the water table's cell size
156 return cellSize;
158 GLfloat getAttenuation(void) const { // Returns the attenuation factor for partial discharges
159 return attenuation;
161 bool getDryBoundary(void)
162 const { // Returns true if dry boundaries are enforced after every simulation step
163 return dryBoundary;
165 void setElevationRange(Scalar newMin,
166 Scalar newMax); // Sets the range of possible elevations in the water table
167 void setAttenuation(GLfloat newAttenuation); // Sets the attenuation factor for partial discharges
168 void setMaxStepSize(GLfloat
169 newMaxStepSize); // Sets the maximum step size for all subsequent integration steps
170 const PTransform& getWaterTextureTransform(void)
171 const { // Returns the matrix transforming from camera space into water texture space
172 return waterTextureTransform;
174 void addRenderFunction(const AddWaterFunction*
175 newRenderFunction); // Adds a render function to the list; object remains owned by caller
176 void removeRenderFunction(const AddWaterFunction*
177 removeRenderFunction); // Removes the given render function from the list but does not delete it
178 GLfloat getWaterDeposit(void)
179 const { // Returns the current amount of water deposited on every simulation step
180 return waterDeposit;
182 void setWaterDeposit(GLfloat newWaterDeposit); // Sets the amount of deposited water
183 void setDryBoundary(bool newDryBoundary); // Enables or disables enforcement of dry boundaries
184 void updateBathymetry(GLContextData& contextData)
185 const; // Prepares the water table for subsequent calls to the runSimulationStep() method
186 void updateBathymetry(const GLfloat* bathymetryGrid,
187 GLContextData& contextData)
188 const; // Updates the bathymetry directly with a vertex-centered elevation grid of grid size minus 1
189 void setWaterLevel(const GLfloat* waterGrid,
190 GLContextData& contextData)
191 const; // Sets the current water level to the given grid, and resets flux components to zero
192 GLfloat runSimulationStep(bool forceStepSize,
193 GLContextData& contextData)
194 const; // Runs a water flow simulation step, always uses maxStepSize if flag is true (may lead to instability); returns step size taken by Runge-Kutta integration step
195 void bindBathymetryTexture(GLContextData& contextData)
196 const; // Binds the bathymetry texture object to the active texture unit
197 void bindQuantityTexture(GLContextData& contextData)
198 const; // Binds the most recent conserved quantities texture object to the active texture unit
199 void uploadWaterTextureTransform(GLint location)
200 const; // Uploads the water texture transformation into the GLSL 4x4 matrix at the given uniform location
201 GLsizei getBathymetrySize(int index) const { // Returns the width or height of the bathymetry grid
202 return size[index] - 1;
204 bool requestBathymetry(GLfloat*
205 newReadBathymetryBuffer); // Requests reading back the current bathymetry grid from the GPU during the next rendering cycle; returns true if request can be granted
206 bool haveBathymetry(void)
207 const { // Returns true if the most recent bathymetry request has been fulfilled
208 return readBathymetryReply == readBathymetryRequest;
212 #endif