Waterflow
Visualize water in terrain
src/myDrawable.cpp
Go to the documentation of this file.
00001 
00002 
00003 
00004 #include "myDrawable.h"
00005 #include "GL_utilities.h"
00006 
00007 #include "Utilities.h"
00008 #include "LoadTGA.h"
00009 
00010 #include "gtx/transform.hpp"
00011 #include "gtx/rotate_vector.hpp"
00012 #include "gtc/type_ptr.hpp"
00013 
00014 myDrawable::myDrawable(GLuint program)
00015 : program(program) {}
00016 
00017 GLuint myDrawable::lightBuffer;
00018 LightParams myDrawable::lightParam[2];
00019 GLuint myDrawable::texIDs[TOTAL_TEXTURES];
00020 
00021 void myDrawable::setLights() {
00022     // =========== Lights information ==========
00023 
00024     // Sun
00025     myDrawable::lightParam[0].position = { 0.58f, 0.58f, 0.58f }; // Since the sun is a directional source, this is the negative direction, not the position.
00026     myDrawable::lightParam[0].isDirectional = 1.0f;
00027     myDrawable::lightParam[0].color = { 1.0f, 1.0f, 1.0f };
00028     myDrawable::lightParam[0].specularComponent = 50.0f;
00029 
00030     // Calculating modified incoming light.
00031 
00032     // ---This should NOT be done here when inModel is not a plane. This should at that point be moved to watershader.frag.---
00033     // However, that is absolutely not trivial, since it requires information
00034     // about the surface fragment where the incident light refracted. If that
00035     // ends up being too complicated, this could be a decent approximation.
00036     float waterRefInd = 1.34451f;
00037     float airRefInd = 1.0f;
00038     glm::vec3 up = glm::vec3(0, 1, 0);
00039     glm::vec3 right = glm::cross(normalize(lightParam[0].position), up);
00040     // Snell's law.
00041     float theta1 = asinf(glm::length(right));
00042     float theta2 = asinf(airRefInd * sinf(theta1) / waterRefInd);
00043     glm::vec3 waterSunPos = glm::rotate(lightParam[0].position, theta1, right);
00044     waterSunPos = glm::rotate(waterSunPos, -theta2, right);
00045     // -----------------------------------------------------------------------------------------------------------------------
00046 
00047     // Sun under the surface
00048     myDrawable::lightParam[1].position = waterSunPos;
00049     myDrawable::lightParam[1].isDirectional = 1.0f;
00050     myDrawable::lightParam[1].color = { 1.0f, 1.0f, 1.0f };
00051     myDrawable::lightParam[1].specularComponent = 50.0f;
00052 
00053 
00054     glGenBuffers(1, &myDrawable::lightBuffer);
00055 
00056     glBindBuffer(GL_UNIFORM_BUFFER, myDrawable::lightBuffer);
00057     glBufferData(GL_UNIFORM_BUFFER, sizeof(LightParams)* 2, &myDrawable::lightParam, GL_STATIC_DRAW);
00058     glBindBuffer(GL_UNIFORM_BUFFER, 0);
00059 
00060     glBindBufferBase(GL_UNIFORM_BUFFER, 0, myDrawable::lightBuffer);
00061 
00062     printError("Create Light");
00063 }
00064 
00065 void myDrawable::setTextures(GLuint* size) {
00066     glGenTextures(5, texIDs);
00067 
00068     TextureData tempTex;
00069     memset(&tempTex, 0, sizeof(tempTex));
00070 
00071     // ===== Skybox Texture =====
00072 
00073     glActiveTexture(GL_TEXTURE0 + SKYBOX_TEXUNIT);
00074     glBindTexture(GL_TEXTURE_CUBE_MAP, texIDs[SKYBOX_TEXUNIT]);
00075 
00076     GLuint cubeSide[] = { GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_TEXTURE_CUBE_MAP_POSITIVE_Z };
00077     const char *cubeImage[] = { "resources/Skycube/Xn.tga", "resources/Skycube/Xp.tga", "resources/Skycube/Yn.tga", "resources/Skycube/Yp.tga", "resources/Skycube/Zn.tga", "resources/Skycube/Zp.tga" };
00078 
00079     for (size_t i = 0; i < 6; i++) {
00080         LoadTGATextureData(cubeImage[i], &tempTex);
00081 
00082         glTexImage2D(cubeSide[i], 0, GL_RGB, tempTex.width, tempTex.height, 0, GL_RGB, GL_UNSIGNED_BYTE, tempTex.imageData);
00083     }
00084 
00085     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00086     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00087     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
00088     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00089     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00090 
00091     // ===== Terrain Data Texture =====
00092 
00093     glActiveTexture(GL_TEXTURE0 + TERRAINDATA_TEXUNIT);
00094     glBindTexture(GL_TEXTURE_2D, texIDs[TERRAINDATA_TEXUNIT]);
00095     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00096     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00097     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00098     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00099     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, size[0], size[1]);
00100 
00101     // ===== Grass/terrain color Texture =====
00102     glActiveTexture(GL_TEXTURE0 + GRASS_TEXUNIT);
00103 #ifdef _WINDOWS
00104     // Path to the terrain color image file.
00105     std::string terrainColorPath = "resources/terrainColor.jpg";
00106     sdlTexture* terrainColorTex = new sdlTexture(terrainColorPath, texIDs[GRASS_TEXUNIT]);
00107     if(terrainColorTex->getTexID() == -1)
00108     {
00109         // The texture ID of the sdlTexture will be -1 if the image could not be loaded.
00110         glBindTexture(GL_TEXTURE_2D, texIDs[GRASS_TEXUNIT]);
00111         // Below should be placeholder.tga once someone can convert better than I can.
00112         LoadTGATextureData("resources/grass.tga", &tempTex);
00113         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tempTex.width, tempTex.height, 0, GL_RGB, GL_UNSIGNED_BYTE, tempTex.imageData);
00114     }
00115 #else
00116     glBindTexture(GL_TEXTURE_2D, texIDs[GRASS_TEXUNIT]);
00117     LoadTGATextureData("resources/grass.tga", &tempTex);
00118     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tempTex.width, tempTex.height, 0, GL_RGB, GL_UNSIGNED_BYTE, tempTex.imageData);
00119 #endif
00120     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00121     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00122     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00123     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00124 
00125     // ===== Dotted Texture =====
00126 
00127     glActiveTexture(GL_TEXTURE0 + DOTTED_TEXUNIT);
00128     glBindTexture(GL_TEXTURE_2D, texIDs[DOTTED_TEXUNIT]);
00129     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00130     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00131     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00132     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00133     LoadTGATextureData("resources/prickig.tga", &tempTex);
00134     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tempTex.width, tempTex.height, 0, GL_RGB, GL_UNSIGNED_BYTE, tempTex.imageData);
00135 
00136     // ===== Noise Texture =====
00137 
00138     glActiveTexture(GL_TEXTURE0 + NOISE_TEXUNIT);
00139     glBindTexture(GL_TEXTURE_2D, texIDs[NOISE_TEXUNIT]);
00140     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00141     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00142     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00143     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00144     LoadTGATextureData("resources/noise.tga", &tempTex);
00145     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tempTex.width, tempTex.height, 0, GL_RGB, GL_UNSIGNED_BYTE, tempTex.imageData);
00146 
00147     // ===== Grass Texture =====
00148 
00149     /*glActiveTexture(GL_TEXTURE0 + GRASS_TEXUNIT);
00150     glBindTexture(GL_TEXTURE_2D, texIDs[GRASS_TEXUNIT]);
00151     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00152     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00153     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00154     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00155     LoadTGATextureData("resources/grass.tga", &tempTex);
00156     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tempTex.width, tempTex.height, 0, GL_RGB, GL_UNSIGNED_BYTE, tempTex.imageData);*/
00157 
00158     // Just set this to not interfere (possible bug to look into)
00159     glActiveTexture(GL_TEXTURE0  + TOTAL_TEXTURES);
00160 
00161     printError("Create textures!");
00162 }
00163 
00164 
00165 SkyCube::SkyCube(GLuint program)
00166 : myDrawable(program) {
00167     /* Initialize skycube */
00168     model = generateCube(10.0f);
00169 }
00170 
00171 void SkyCube::draw() {
00172     glUniform1i(glGetUniformLocation(program, "cube_texture"), SKYBOX_TEXUNIT);
00173 
00174     DrawModel(model, program, "in_Position", NULL, NULL);
00175 }
00176 
00177 // ================================================================
00178 
00179 HeightMap::HeightMap(GLuint drawProgram, GLuint* sizes, GLfloat maxHeight, GLuint inputHeightBuffer)
00180 : myDrawable(drawProgram) {
00181 
00182     dataWidth = sizes[0];
00183     dataHeight = sizes[1];
00184     dataTerrainHeight = maxHeight;
00185     numData = dataWidth * dataHeight;
00186     numIndices = (dataWidth - 1) * (dataHeight - 1) * 2 * 3;
00187 
00188     heightBuffer = inputHeightBuffer;
00189 
00190     texnum = 0;
00191 
00192     initUpdate();
00193 
00194     initDraw();
00195 }
00196 
00197 void HeightMap::initUpdate() {
00198 
00199     glGenBuffers(4, drawBuffers);
00200 
00201     normalsProgram = compileComputeShader("src/shaders/normals.comp");
00202 
00203     glBindBuffer(GL_SHADER_STORAGE_BUFFER, drawBuffers[3]); // Normals
00204     glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat)* 3 * numData, NULL, GL_STATIC_DRAW);
00205     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
00206 
00207     printError("init normals");
00208 
00209     heightMapProgram = compileComputeShader("src/shaders/heightMap.comp");
00210 
00211     glBindBuffer(GL_SHADER_STORAGE_BUFFER, drawBuffers[0]); // Vertex positions
00212     glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat)* 3 * numData, NULL, GL_STATIC_DRAW);
00213     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
00214 
00215     glBindBuffer(GL_SHADER_STORAGE_BUFFER, drawBuffers[1]); // Texture coordinates
00216     glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat)* 2 * numData, NULL, GL_STATIC_DRAW);
00217     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
00218 
00219     glBindBuffer(GL_SHADER_STORAGE_BUFFER, drawBuffers[2]); // Indices
00220     glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLint)* numIndices, NULL, GL_STATIC_DRAW);
00221     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
00222 
00223     printError("init heightmap");
00224 
00225     textureProgram = compileComputeShader("src/shaders/textureData.comp");
00226 
00227     printError("init texturedata");
00228 }
00229 
00230 void HeightMap::initDraw() {
00231 
00232     glGenVertexArrays(1, &drawVAO);
00233 
00234     glUseProgram(program);
00235 
00236     printError("init draw uniforms");
00237 
00238     GLint posAttrib = glGetAttribLocation(program, "in_Position");
00239     GLint inNormAttrib = glGetAttribLocation(program, "in_Normal");
00240     GLint inTexAttrib = glGetAttribLocation(program, "in_TexCoord");
00241 
00242     glBindVertexArray(drawVAO);
00243 
00244     glBindBuffer(GL_ARRAY_BUFFER, drawBuffers[0]); //vertexBufferID
00245     glEnableVertexAttribArray(posAttrib);
00246     glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)* 3, 0);
00247 
00248     printError("init draw1");
00249 
00250     glBindBuffer(GL_ARRAY_BUFFER, drawBuffers[1]); //texBufferID
00251     glEnableVertexAttribArray(inTexAttrib);
00252     glVertexAttribPointer(inTexAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)* 2, 0);
00253 
00254     printError("init draw2");
00255 
00256     glBindBuffer(GL_ARRAY_BUFFER, drawBuffers[3]); //normalsBufferID
00257     glEnableVertexAttribArray(inNormAttrib);
00258     glVertexAttribPointer(inNormAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)* 3, 0);
00259 
00260     printError("init draw3");
00261 
00262     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawBuffers[2]);//indicesBufferID
00263 
00264     printError("init draw4");
00265 
00266     glBindVertexArray(0);
00267 
00268     glBindBuffer(GL_ARRAY_BUFFER, 0);
00269     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
00270 
00271     printError("init draw5");
00272 
00273     glUniform1i(glGetUniformLocation(program, "height_texUnit"), TERRAINDATA_TEXUNIT);
00274     glUniform1i(glGetUniformLocation(program, "sky_texUnit"), SKYBOX_TEXUNIT);
00275     glUniform1i(glGetUniformLocation(program, "terr_texUnit"), texnum + TERRAIN_FIRST_TEXUNIT);
00276     glUniform3f(glGetUniformLocation(program, "size"), (float)dataWidth, dataTerrainHeight, (float)dataHeight);
00277 
00278     printError("init draw");
00279 }
00280 
00281 void HeightMap::generateHeightTexture() {
00282 
00283     glUseProgram(textureProgram);
00284 
00285     glBindImageTexture(0, myDrawable::texIDs[TERRAINDATA_TEXUNIT], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
00286 
00287     glUniform2i(glGetUniformLocation(textureProgram, "size"), dataWidth, dataHeight);
00288     glUniform1f(glGetUniformLocation(textureProgram, "maxHeight"), dataTerrainHeight);
00289 
00290     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, heightBuffer);
00291     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, drawBuffers[3]);
00292 
00293     glDispatchCompute((GLuint)ceil((GLfloat)dataWidth / 16.0f), (GLuint)ceil((GLfloat)dataHeight / 16.0f), 1);
00294     
00295     printError("Generate terrain texture data");
00296 }
00297 
00298 void HeightMap::update() {
00299 
00300     glUseProgram(normalsProgram);
00301 
00302     glUniform2i(glGetUniformLocation(normalsProgram, "size"), dataWidth, dataHeight);
00303 
00304     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, heightBuffer);
00305     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, drawBuffers[3]);
00306 
00307     glDispatchCompute((GLuint)ceil((GLfloat)dataWidth / 16.0f), (GLuint)ceil((GLfloat)dataHeight / 16.0f), 1);
00308 
00309     printError("Update normals");
00310 
00311     glBindBuffersBase(GL_SHADER_STORAGE_BUFFER, 0, 3, drawBuffers);
00312     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, heightBuffer);
00313     
00314     glBindImageTexture(0, myDrawable::texIDs[TERRAINDATA_TEXUNIT], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
00315     
00316     glUseProgram(heightMapProgram);
00317     
00318     if(dynamic_cast<Water*>(this) != nullptr){
00319         glUniform1f(glGetUniformLocation(heightMapProgram, "scale"), dataTerrainHeight);
00320     }else{
00321         glUniform1f(glGetUniformLocation(heightMapProgram, "scale"), -1.0f);
00322     }
00323     
00324     
00325     glUniform2i(glGetUniformLocation(heightMapProgram, "size"), dataWidth, dataHeight);
00326     glDispatchCompute((GLuint)ceil((GLfloat)dataWidth / 16.0f), (GLuint)ceil((GLfloat)dataHeight / 16.0f), 1);
00327 
00328     printError("Update vertices");
00329 }
00330 
00331 void HeightMap::draw() {
00332     glUseProgram(program);
00333     glBindVertexArray(drawVAO);
00334     glUniform1i(glGetUniformLocation(program, "terr_texUnit"), texnum + TERRAIN_FIRST_TEXUNIT);
00335     glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, 0L);
00336 
00337     printError("Draw Heightmap");
00338 }
00339 
00340 void TW_CALL HeightMap::SetTextureCB(const void* value, void* clientData) {
00341     static_cast<HeightMap*>(clientData)->texnum = *static_cast<const GLuint*>(value);
00342 }
00343 void TW_CALL HeightMap::GetTextureCB(void* value, void* clientData) {
00344     *static_cast<int*>(value) = static_cast<Water*>(clientData)->texnum;
00345 }
00346 
00347 
00348 Water::Water(GLuint* drawPrograms, GLuint* sizes, GLfloat maxHeight, GLuint inputHeightBuffer)
00349 : HeightMap(drawPrograms[0], sizes, maxHeight, inputHeightBuffer) {
00350     transparency = 0.7f;
00351     maxDepth = 50.0f;
00352 
00353     programToDraw = 0;
00354     programs[0] = drawPrograms[0];
00355     programs[1] = drawPrograms[1];
00356 
00357     vaos[0] = drawVAO;
00358 
00359     glUseProgram(programs[0]);
00360     glUniform1f(glGetUniformLocation(programs[0], "transparency"), transparency);
00361     glUseProgram(programs[1]);
00362     glUniform1f(glGetUniformLocation(programs[1], "maxDepth"), maxDepth);
00363 
00364     initDepthProgram();
00365 }
00366 
00367 void Water::initDepthProgram() {
00368     GLuint tempVAO;
00369     glGenVertexArrays(1, &tempVAO);
00370     vaos[1] = tempVAO;
00371 
00372     glUseProgram(programs[1]);
00373 
00374     printError("init draw uniforms");
00375 
00376     GLint posAttrib = glGetAttribLocation(programs[1], "in_Position");
00377     GLint inTexAttrib = glGetAttribLocation(programs[1], "in_TexCoord");
00378 
00379     glBindVertexArray(vaos[1]);
00380 
00381     glBindBuffer(GL_ARRAY_BUFFER, drawBuffers[0]); //vertexBufferID
00382     glEnableVertexAttribArray(posAttrib);
00383     glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)* 3, 0);
00384 
00385     printError("init draw1");
00386 
00387     glBindBuffer(GL_ARRAY_BUFFER, drawBuffers[1]); //texBufferID
00388     glEnableVertexAttribArray(inTexAttrib);
00389     glVertexAttribPointer(inTexAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)* 2, 0);
00390 
00391     printError("init draw3");
00392 
00393     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawBuffers[2]);//indicesBufferID
00394 
00395     printError("init draw4");
00396 
00397     glBindVertexArray(0);
00398 
00399     glBindBuffer(GL_ARRAY_BUFFER, 0);
00400     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
00401 
00402     printError("init draw5");
00403 
00404     glUniform1i(glGetUniformLocation(programs[1], "height_texUnit"), TERRAINDATA_TEXUNIT);
00405     glUniform3f(glGetUniformLocation(programs[1], "size"), (float)dataWidth, dataTerrainHeight, (float)dataHeight);
00406 
00407     printError("init draw");
00408 }
00409 
00410 
00411 void TW_CALL Water::SetTransparencyCB(const void* value, void* clientData) {
00412     Water* obj = static_cast<Water*>(clientData);
00413     obj->transparency = *static_cast<const float*>(value);
00414     glUseProgram(obj->programs[0]);
00415     glUniform1f(glGetUniformLocation(obj->programs[0], "transparency"), obj->transparency);
00416 }
00417 
00418 void TW_CALL Water::SetDrawProgramCB(const void* value, void* clientData) {
00419     Water* obj = static_cast<Water*>(clientData);
00420     obj->programToDraw = *static_cast<const int*>(value);
00421     obj->program = obj->programs[obj->programToDraw];
00422     obj->drawVAO = obj->vaos[obj->programToDraw];
00423 }
00424 
00425 void TW_CALL Water::SetMaxDepthCB(const void* value, void* clientData) {
00426     Water* obj = static_cast<Water*>(clientData);
00427     obj->maxDepth = *static_cast<const float*>(value);
00428     glUseProgram(obj->programs[1]);
00429     glUniform1f(glGetUniformLocation(obj->programs[1], "maxDepth"), obj->maxDepth);
00430 }
00431 
00432 
00433 void TW_CALL Water::GetTransparencyCB(void* value, void* clientData) {
00434     *static_cast<float*>(value) = static_cast<Water*>(clientData)->transparency;
00435 }
00436 
00437 void TW_CALL Water::GetDrawProgramCB(void* value, void* clientData) {
00438     *static_cast<int*>(value) = static_cast<Water*>(clientData)->programToDraw;
00439 }
00440 
00441 void TW_CALL Water::GetMaxDepthCB(void* value, void* clientData) {
00442     *static_cast<float*>(value) = static_cast<Water*>(clientData)->maxDepth;
00443 }
 All Classes Files Functions Variables Enumerations