Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/world_entities/environments/mapped_water.cc @ 9882

Last change on this file since 9882 was 9882, checked in by bensch, 18 years ago

trunk: gl_multi_texture check in the material. This should resolve the Material::select() bug

File size: 30.0 KB
RevLine 
[7796]1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Stefan Lienard
13   co-programmer: ...
14*/
15
16#include "mapped_water.h"
17#include "util/loading/load_param.h"
18#include "util/loading/factory.h"
[8037]19#include "state.h"
[9006]20#include "t_animation.h"
[9110]21#include <cmath>
[9006]22#include "glgui.h"
23#include "shell_command.h"
24#include "script_class.h"
[7796]25
[9869]26#include "resource_shader.h"
[7796]27
[9869]28#include "class_id_DEPRECATED.h"
29ObjectListDefinitionID(MappedWater, CL_MAPPED_WATER);
30CREATE_FACTORY(MappedWater);
31
[9021]32SHELL_COMMAND(gui, MappedWater, toggleGui);
[9006]33SHELL_COMMAND(output, MappedWater, saveParams);
34
[9869]35CREATE_SCRIPTABLE_CLASS(MappedWater,
36                        addMethod("waterUV", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeWaterUV))
37                        ->addMethod("waterFlow", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeWaterFlow))
38                        ->addMethod("shineSize", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeShineSize))
39                        ->addMethod("shineStrength", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeShineStrength))
40                        ->addMethod("reflStrength", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeReflStrength))
41                        ->addMethod("refraction", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeRefraction))
42                        ->addMethod("waterHeight", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeWaterHeight))
43                        ->addMethod("waterColor", Executor4<MappedWater, lua_State*, float, float, float, float>(&MappedWater::fadeWaterColor)));
[9006]44
45
[8719]46/**
47 * @brief constructor
48 * @param root xml data
49 */
[7796]50MappedWater::MappedWater(const TiXmlElement* root)
51{
[9869]52  this->registerObject(this, MappedWater::_objectList);
[7796]53  this->toList(OM_ENVIRON);
54
[8719]55  /// sets start values and parameters
56  this->initParams();
57  // now the standard values were loaded, if the values are specified in the .oxw file
58  // loadParams will overwrite the standard values with the specified values
[7796]59  if (root != NULL)
60    this->loadParams(root);
61
[8719]62  /// initialization of the textures
63  this->initTextures();
[8037]64
[8719]65  /// initialization of the shaders
66  this->initShaders();
[9006]67
68  /// calculation of the 4 verts of the water quad
69  this->calcVerts();
70
71  // init gui
72  this->box = NULL;
[8719]73}
74
75/**
76 * @brief deltes shader and the uniform used by the camera
77 */
78MappedWater::~MappedWater()
79{
80  delete cam_uni;
[8792]81  delete color_uni;
82  delete light_uni;
[9006]83  delete shineSize_uni;
84  delete shineStrength_uni;
85  delete reflStrength_uni;
86  delete refr_uni;
[8719]87}
88
89/**
90 * @brief initialization of loadable parameters, sets start standard values
91 */
92void MappedWater::initParams()
93{
94  // those standardvalues will be overwritten if they're also set in the oxw file
95  this->setWaterPos(0, 0, 0);
96  this->setWaterSize(100, 100);
97  this->setWaterUV(9);
[9006]98  this->setWaterFlow(0.08f);
[8719]99  this->setLightPos(0, 10, 0);
100  this->setWaterAngle(0);
101  this->setNormalMapScale(0.25f);
[8792]102  this->setWaterColor(0.1f, 0.2f, 0.4f);
[9006]103  this->setShineSize(128);
104  this->setShineStrength(0.7f);
105  this->setReflStrength(1.0f);
106  this->setRefraction(0.009f);
[8719]107
108  // initialization of the texture coords, speeds etc...
109  // normalUV wont change anymore
110  this->normalUV = this->waterUV * this->kNormalMapScale;
111  // move and move2 are used for the reflection and refraction, the values are changed in tick()
112  this->move = 0;
113  this->move2 = this->move * this->kNormalMapScale;
[8792]114
[9006]115  // initalize fading bools
116  this->bFadeWaterHeight = false;
117  this->bFadeWaterUV = false;
118  this->bFadeWaterFlow = false;
119  this->bFadeShineSize = false;
120  this->bFadeShineStrength = false;
121  this->bFadeReflStrength = false;
122  this->bFadeRefraction = false;
123  this->bFadeWaterColor = false;
[8719]124}
125
126/**
127 * @brief initialization of the textures
128 */
129void MappedWater::initTextures()
130{
131  // sets parameters for the textures
132  this->textureSize = 512;
133  unsigned int channels = 32;
134  GLenum type = GL_RGBA;
135
[7796]136  // set up refleciton texture
[8719]137  Texture reflTex(GL_TEXTURE_2D, this->textureSize, this->textureSize, channels, type);
138  mat.setDiffuseMap(reflTex, 0);
139  // set up refraction texture
140  Texture refrTex(GL_TEXTURE_2D, this->textureSize, this->textureSize, channels, type);
141  mat.setDiffuseMap(refrTex, 1);
[7796]142  // load normal map
[9006]143  mat.setDiffuseMap("pictures/water_normalmap.bmp", GL_TEXTURE_2D, 2);
[7796]144  // load dudv map
[9006]145  mat.setDiffuseMap("pictures/water_dudvmap.bmp", GL_TEXTURE_2D, 3);
[7796]146
[8719]147  // sets texture parameters for reflection texture
[8619]148  glBindTexture(GL_TEXTURE_2D, this->mat.diffuseTextureID(0));
[8312]149  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
150  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
151  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
152  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[8719]153  // sets texture parameters for refraction texture
[8619]154  glBindTexture(GL_TEXTURE_2D, this->mat.diffuseTextureID(1));
[7796]155  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
156  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
157  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
158  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[8719]159}
[7796]160
[8719]161/**
162 * @brief initialization of the shaders
163 */
164void MappedWater::initShaders()
165{
[8037]166  // load shader files
[9882]167  shader = ResourceShader( "shaders/mapped_water.vert", "shaders/mapped_water.frag");
[8037]168
[9869]169  this->shader.activateShader();
[8037]170  // Set the variable "reflection" to correspond to the first texture unit
171  Shader::Uniform(shader, "reflection").set(0);
172  // Set the variable "refraction" to correspond to the second texture unit
173  Shader::Uniform(shader, "refraction").set(1);
174  // Set the variable "normalMap" to correspond to the third texture unit
175  Shader::Uniform(shader, "normalMap").set(2);
176  // Set the variable "dudvMap" to correspond to the fourth texture unit
177  Shader::Uniform(shader, "dudvMap").set(3);
178  // Set the variable "depthMap" to correspond to the fifth texture unit
[9006]179  Shader::Uniform(shader, "depthMap").set(1);
[8037]180  // Give the variable "waterColor" a blue color
[8792]181  color_uni = new Shader::Uniform(shader, "waterColor");
182  color_uni->set(waterColor.x, waterColor.y, waterColor.z, 1.0f);
[8037]183  // Give the variable "lightPos" our hard coded light position
[8792]184  light_uni = new Shader::Uniform(shader, "lightPos");
185  light_uni->set(lightPos.x, lightPos.y, lightPos.z, 1.0f);
186  // Set the variable "shine"
[9006]187  shineSize_uni = new Shader::Uniform(shader, "kShine");
188  shineSize_uni->set(this->shineSize);
189  // Set the variable "shineStrength"
190  shineStrength_uni = new Shader::Uniform(shader, "shineStrength");
191  shineStrength_uni->set(this->shineStrength);
192  // Set the variable "reflStrength"
193  reflStrength_uni = new Shader::Uniform(shader, "reflStrength");
194  reflStrength_uni->set(this->reflStrength);
195  // Set the variable "refraction"
196  refr_uni = new Shader::Uniform(shader, "kRefraction");
197  refr_uni->set(this->refraction);
[8037]198  // uniform for the camera position
199  cam_uni = new Shader::Uniform(shader, "cameraPos");
200
[9869]201  this->shader.deactivateShader();
[7796]202}
203
[8719]204/**
[9006]205 * @brief calculates the 4 verts of the water quad
206 */
207void MappedWater::calcVerts()
208{
209  float deg2radtemp = this->waterAngle / 180 * PI;
210
211  this->waterVerts[2] = this->waterVerts[0] + cos(deg2radtemp) * this->xWidth;
212  this->waterVerts[3] = this->waterVerts[1] + sin(deg2radtemp) * this->xWidth;
213  this->waterVerts[4] = this->waterVerts[0] + cos(deg2radtemp) * this->xWidth - sin(deg2radtemp) * this->zWidth;
214  this->waterVerts[5] = this->waterVerts[1] + sin(deg2radtemp) * this->xWidth + cos(deg2radtemp) * this->zWidth;
215  this->waterVerts[6] = this->waterVerts[0] - sin(deg2radtemp) * this->zWidth;
216  this->waterVerts[7] = this->waterVerts[1] + cos(deg2radtemp) * this->zWidth;
217}
218
219/**
[8792]220 * @brief resets the waterColor in the Shader
221 * @param r new value for red
222 * @param g new value for green
223 * @param b new value for blue
224 */
225void MappedWater::resetWaterColor(float r, float g, float b)
226{
[9869]227  this->shader.activateShader();
[8792]228  this->waterColor = Vector(r, g, b);
229
230  // Give the variable "waterColor" a color
231  color_uni->set(waterColor.x, waterColor.y, waterColor.z, 1.0f);
232
[9869]233  this->shader.deactivateShader();
[9006]234}
[8792]235
236/**
237 * @brief resets the shininess in the Shader
238 * @param shine new value for the shininess
239 */
[9006]240void MappedWater::resetShineSize(float shine)
[8792]241{
[9869]242  this->shader.activateShader();
[9006]243  this->shineSize = shine;
[8792]244
245  // Set the variable "shine"
[9006]246  shineSize_uni->set(this->shineSize);
[8792]247
[9869]248  this->shader.deactivateShader();
[9006]249}
[8792]250
251/**
[9006]252 * @brief resets the strength of the specular reflection in the Shader
253 * @param strength new value for the strength of the specular reflection
254 */
255void MappedWater::resetShineStrength(float strength)
256{
[9869]257  this->shader.activateShader();
[9006]258  this->shineStrength = strength;
259
260  // Set the variable "shine"
261  shineStrength_uni->set(this->shineStrength);
262
[9869]263  this->shader.deactivateShader();
[9006]264}
265
266/**
267 * @brief resets the strength of the reflection in the Shader
268 * @param strength new value for the strength of the reflection
269 */
270void MappedWater::resetReflStrength(float strength)
271{
[9869]272  this->shader.activateShader();
[9006]273  this->reflStrength = strength;
274
275  // Set the variable "shine"
276  reflStrength_uni->set(this->reflStrength);
277
[9869]278  this->shader.deactivateShader();
[9006]279}
280
281/**
282 * @brief resets the refraction in the Shader
283 * @param refraction new value for the refraction
284 */
285void MappedWater::resetRefraction(float refraction)
286{
[9869]287  this->shader.activateShader();
[9006]288  this->refraction = refraction;
289
290  // Set the variable "shine"
291  refr_uni->set(this->refraction);
292
[9869]293  this->shader.deactivateShader();
[9006]294}
295
296/**
[8792]297 * @brief resets the lightPos in the Shader
298 * @param x new x value
299 * @param y new y value
300 * @param z new z value
301 */
302void MappedWater::resetLightPos(float x, float y, float z)
303{
[9869]304  this->shader.activateShader();
[8792]305  this->lightPos = Vector(x, y, z);
306
307  // Give the variable "lightPos" our hard coded light position
308  light_uni->set(lightPos.x, lightPos.y, lightPos.z, 1.0f);
309
[9869]310  this->shader.deactivateShader();
[9006]311}
[8792]312
313/**
[8719]314 * @brief ends the refraction and saves the graphic buffer into a texture
315 * @param root xml data
316 */
[7796]317void MappedWater::loadParams(const TiXmlElement* root)
318{
319  WorldEntity::loadParams(root);
320
[8719]321  LoadParam(root, "waterpos", this, MappedWater, setWaterPos);
322  LoadParam(root, "watersize", this, MappedWater, setWaterSize);
323  LoadParam(root, "wateruv", this, MappedWater, setWaterUV);
324  LoadParam(root, "waterflow", this, MappedWater, setWaterFlow);
[9006]325  LoadParam(root, "lightpos", this, MappedWater, setLightPos);
326  LoadParam(root, "waterangle", this, MappedWater, setWaterAngle);
[8719]327  LoadParam(root, "normalmapscale", this, MappedWater, setNormalMapScale);
[9006]328  LoadParam(root, "shinesize", this, MappedWater, setShineSize);
329  LoadParam(root, "shinestrength", this, MappedWater, setShineStrength);
330  LoadParam(root, "reflstrength", this, MappedWater, setReflStrength);
331  LoadParam(root, "refraction", this, MappedWater, setRefraction);
[8792]332  LoadParam(root, "watercolor", this, MappedWater, setWaterColor);
[7796]333}
334
[8719]335/**
[9006]336 * @brief prints the xml code of the water params
337 */
338void MappedWater::saveParams()
339{
340  // it's not too nice, but it works fine
[9235]341  PRINT(0)("\nMappedWater XML Code:\n<MappedWater>\n");
342
343  PRINT(0)("  <waterpos>%f, %f, %f</waterpos>\n", this->waterVerts[0], this->waterHeight, this->waterVerts[1]);
344  PRINT(0)("  <watersize>%f, %f</watersize>\n", this->xWidth, this->zWidth);
345  PRINT(0)("  <wateruv>%f</wateruv>\n", this->waterUV);
346  PRINT(0)("  <waterflow>%f</waterflow>\n", this->waterFlow);
347  PRINT(0)("  <lightpos>%f, %f, %f</lightpos>\n", this->lightPos.x, this->lightPos.y, this->lightPos.z);
348  PRINT(0)("  <waterangle>%f</waterangle>\n", this->waterAngle);
349  PRINT(0)("  <normalmapscale>%f</normalmapscale>\n", this->kNormalMapScale);
350  PRINT(0)("  <shinesize>%f</shinesize>\n", this->shineSize);
351  PRINT(0)("  <shinestrength>%f</shinestrength>\n", this->shineStrength);
352  PRINT(0)("  <reflstrength>%f</reflstrength>\n", this->reflStrength);
353  PRINT(0)("  <refraction>%f</refraction>\n", this->refraction);
354  PRINT(0)("  <watercolor>%f, %f, %f</watercolor>\n", this->waterColor.x, this->waterColor.y, this->waterColor.z);
355
356  PRINT(0)("</MappedWater>\n");
[9006]357}
358
359/**
360 * @brief starts the slider gui that lets you edit all water parameters
361 */
[9021]362void MappedWater::toggleGui()
[9006]363{
364  if (this->box == NULL)
365  {
366    this->box = new OrxGui::GLGuiBox(OrxGui::Vertical);
367    {
368      OrxGui::GLGuiBox* waterColorBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
369      {
[9019]370        OrxGui::GLGuiText* waterColorText = new OrxGui::GLGuiText();
[9006]371        waterColorText->setText("WaterColor");
372        waterColorBox->pack(waterColorText);
373
374        OrxGui::GLGuiSlider* waterColorR = new OrxGui::GLGuiSlider();
375        waterColorR->setRange(0, 1.0f);
376        waterColorR->setValue(this->waterColor.x);
377        waterColorR->setStep(0.1f);
[9406]378        waterColorR->valueChanged.connect(this, &MappedWater::resetWaterColorR);
[9006]379        waterColorBox->pack(waterColorR);
380
381        OrxGui::GLGuiSlider* waterColorG = new OrxGui::GLGuiSlider();
382        waterColorG->setRange(0, 1.0f);
383        waterColorG->setStep(0.1f);
384        waterColorG->setValue(this->waterColor.y);
[9406]385        waterColorG->valueChanged.connect(this, &MappedWater::resetWaterColorG);
[9006]386        waterColorBox->pack(waterColorG);
387
388        OrxGui::GLGuiSlider* waterColorB = new OrxGui::GLGuiSlider();
389        waterColorB->setRange(0, 1.0f);
390        waterColorB->setStep(0.1f);
391        waterColorB->setValue(this->waterColor.z);
[9406]392        waterColorB->valueChanged.connect(this, &MappedWater::resetWaterColorB);
[9006]393        waterColorBox->pack(waterColorB);
394      }
395      this->box->pack(waterColorBox);
396
397      OrxGui::GLGuiBox* waterUVBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
398      {
[9019]399        OrxGui::GLGuiText* waterUVText = new OrxGui::GLGuiText();
[9006]400        waterUVText->setText("WaterUV");
401        waterUVBox->pack(waterUVText);
402
403        OrxGui::GLGuiSlider* waterUV = new OrxGui::GLGuiSlider();
404        waterUV->setRange(1, 20);
405        waterUV->setValue(this->waterUV);
406        waterUV->setStep(1);
[9406]407        waterUV->valueChanged.connect(this, &MappedWater::setWaterUV);
[9006]408        waterUVBox->pack(waterUV);
409      }
410      this->box->pack(waterUVBox);
411
412      OrxGui::GLGuiBox* waterFlowBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
413      {
[9019]414        OrxGui::GLGuiText* waterFlowText = new OrxGui::GLGuiText();
[9006]415        waterFlowText->setText("WaterFlow");
416        waterFlowBox->pack(waterFlowText);
417
418        OrxGui::GLGuiSlider* waterFlow = new OrxGui::GLGuiSlider();
419        waterFlow->setRange(0.01f, 2);
420        waterFlow->setValue(this->waterFlow);
421        waterFlow->setStep(0.02f);
[9406]422        waterFlow->valueChanged.connect(this, &MappedWater::setWaterFlow);
[9006]423        waterFlowBox->pack(waterFlow);
424      }
425      this->box->pack(waterFlowBox);
426
427      OrxGui::GLGuiBox* shineSizeBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
428      {
[9019]429        OrxGui::GLGuiText* shineSizeText = new OrxGui::GLGuiText();
[9006]430        shineSizeText->setText("ShineSize");
431        shineSizeBox->pack(shineSizeText);
432
433        OrxGui::GLGuiSlider* shineSize = new OrxGui::GLGuiSlider();
434        shineSize->setRange(1, 128);
435        shineSize->setValue(this->shineSize);
436        shineSize->setStep(1);
[9406]437        shineSize->valueChanged.connect(this, &MappedWater::resetShineSize);
[9006]438        shineSizeBox->pack(shineSize);
439      }
440      this->box->pack(shineSizeBox);
441
442      OrxGui::GLGuiBox* shineStrengthBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
443      {
[9019]444        OrxGui::GLGuiText* shineStrengthText = new OrxGui::GLGuiText();
[9006]445        shineStrengthText->setText("ShineStrength");
446        shineStrengthBox->pack(shineStrengthText);
447
448        OrxGui::GLGuiSlider* shineStrength = new OrxGui::GLGuiSlider();
449        shineStrength->setRange(0, 1);
450        shineStrength->setValue(this->shineStrength);
451        shineStrength->setStep(0.1f);
[9406]452        shineStrength->valueChanged.connect(this, &MappedWater::resetShineStrength);
[9006]453        shineStrengthBox->pack(shineStrength);
454      }
455      this->box->pack(shineStrengthBox);
456
457      OrxGui::GLGuiBox* reflStrengthBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
458      {
[9019]459        OrxGui::GLGuiText* reflStrengthText = new OrxGui::GLGuiText();
[9006]460        reflStrengthText->setText("ReflStrength");
461        reflStrengthBox->pack(reflStrengthText);
462
463        OrxGui::GLGuiSlider* reflStrength = new OrxGui::GLGuiSlider();
464        reflStrength->setRange(0, 1);
465        reflStrength->setValue(this->reflStrength);
466        reflStrength->setStep(0.1f);
[9406]467        reflStrength->valueChanged.connect(this, &MappedWater::resetReflStrength);
[9006]468        reflStrengthBox->pack(reflStrength);
469      }
470      this->box->pack(reflStrengthBox);
471
472      OrxGui::GLGuiBox* refractionBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
473      {
[9019]474        OrxGui::GLGuiText* refractionText = new OrxGui::GLGuiText();
[9006]475        refractionText->setText("Refraction");
476        refractionBox->pack(refractionText);
477
478        OrxGui::GLGuiSlider* refraction = new OrxGui::GLGuiSlider();
479        refraction->setRange(0.001f, 0.1f);
480        refraction->setValue(this->refraction);
481        refraction->setStep(0.004f);
[9406]482        refraction->valueChanged.connect(this, &MappedWater::resetRefraction);
[9006]483        refractionBox->pack(refraction);
484      }
485      this->box->pack(refractionBox);
486
487      OrxGui::GLGuiBox* lightPosBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
488      {
[9019]489        OrxGui::GLGuiText* lightPosText = new OrxGui::GLGuiText();
[9006]490        lightPosText->setText("LightPos");
491        lightPosBox->pack(lightPosText);
492
493        OrxGui::GLGuiSlider* lightPosX = new OrxGui::GLGuiSlider();
[9235]494        lightPosX->setRange(-4000, 4000);
[9006]495        lightPosX->setValue(this->lightPos.x);
496        lightPosX->setStep(15);
[9406]497        lightPosX->valueChanged.connect(this, &MappedWater::resetLightPosX);
[9006]498        lightPosBox->pack(lightPosX);
499
500        OrxGui::GLGuiSlider* lightPosY = new OrxGui::GLGuiSlider();
[9235]501        lightPosY->setRange(-4000, 4000);
[9006]502        lightPosY->setStep(15);
503        lightPosY->setValue(this->lightPos.y);
[9406]504        lightPosY->valueChanged.connect(this, &MappedWater::resetLightPosY);
[9006]505        lightPosBox->pack(lightPosY);
506
507        OrxGui::GLGuiSlider* lightPosZ = new OrxGui::GLGuiSlider();
[9235]508        lightPosZ->setRange(-4000, 4000);
[9006]509        lightPosZ->setStep(15);
510        lightPosZ->setValue(this->lightPos.z);
[9406]511        lightPosZ->valueChanged.connect(this, &MappedWater::resetLightPosZ);
[9006]512        lightPosBox->pack(lightPosZ);
513      }
514      this->box->pack(lightPosBox);
515
516      OrxGui::GLGuiBox* waterHeightBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
517      {
[9019]518        OrxGui::GLGuiText* waterHeightText = new OrxGui::GLGuiText();
[9006]519        waterHeightText->setText("WaterHeight");
520        waterHeightBox->pack(waterHeightText);
521
522        OrxGui::GLGuiSlider* waterHeight = new OrxGui::GLGuiSlider();
[9235]523        waterHeight->setRange(100, 370);
[9006]524        waterHeight->setValue(this->waterHeight);
[9235]525        waterHeight->setStep(4);
[9406]526        waterHeight->valueChanged.connect(this, &MappedWater::setWaterHeight);
[9006]527        waterHeightBox->pack(waterHeight);
528      }
529      this->box->pack(waterHeightBox);
530    }
531
532    this->box->showAll();
533    this->box->setAbsCoor2D(300, 40);
534    OrxGui::GLGuiHandler::getInstance()->activate();
535    OrxGui::GLGuiHandler::getInstance()->activateCursor();
536  }
[9021]537  else
538  {
539    OrxGui::GLGuiHandler::getInstance()->deactivate();
540    OrxGui::GLGuiHandler::getInstance()->deactivateCursor();
541    delete this->box;
542    this->box = NULL;
543  }
[9006]544}
545
546/**
[8719]547 * @brief activates the water shader and draws a quad with four textures on it
548 */
[7796]549void MappedWater::draw() const
550{
[8312]551  glMatrixMode(GL_MODELVIEW);
[7796]552  glPushMatrix();
553
[9006]554  // don't use glRotate or glTranslate here... the shader won't work anymore
555
[7796]556  mat.select();
557
[9869]558  this->shader.activateShader();
[7796]559
[8037]560  // reset the camera uniform to the current cam position
561  Vector pos = State::getCameraNode()->getAbsCoor();
[8312]562  cam_uni->set(pos.x, pos.y, pos.z, 1.0f);
[7796]563
[8719]564  glDisable(GL_BLEND);
[8312]565
[9235]566  // TODO change texture coords, so water doesnt look distorted when xWidth != zWidth
[8037]567  glBegin(GL_QUADS);
568  // The back left vertice for the water
[9006]569  glMultiTexCoord2f(GL_TEXTURE0, 0, waterUV);                   // Reflection texture
570  glMultiTexCoord2f(GL_TEXTURE1, 0, waterUV - move);            // Refraction texture
571  glMultiTexCoord2f(GL_TEXTURE2, 0, normalUV + move2);          // Normal map texture
572  glMultiTexCoord2f(GL_TEXTURE3, 0, 0);                         // DUDV map texture
573  glVertex3f(this->waterVerts[0], this->waterHeight, this->waterVerts[1]);
[7796]574
[8037]575  // The front left vertice for the water
[9006]576  glMultiTexCoord2f(GL_TEXTURE0, 0, 0);                         // Reflection texture
577  glMultiTexCoord2f(GL_TEXTURE1, 0, -move);                     // Refraction texture
578  glMultiTexCoord2f(GL_TEXTURE2, 0, move2);                     // Normal map texture
579  glMultiTexCoord2f(GL_TEXTURE3, 0, 0);                         // DUDV map texture
580  glVertex3f(this->waterVerts[2], this->waterHeight, this->waterVerts[3]);
[7796]581
[8037]582  // The front right vertice for the water
[9006]583  glMultiTexCoord2f(GL_TEXTURE0, waterUV, 0);                   // Reflection texture
584  glMultiTexCoord2f(GL_TEXTURE1, waterUV, -move);               // Refraction texture
585  glMultiTexCoord2f(GL_TEXTURE2, normalUV, move2);              // Normal map texture
586  glMultiTexCoord2f(GL_TEXTURE3, 0, 0);                         // DUDV map texture
587  glVertex3f(this->waterVerts[4], this->waterHeight, this->waterVerts[5]);
[7796]588
[8037]589  // The back right vertice for the water
[9006]590  glMultiTexCoord2f(GL_TEXTURE0, waterUV, waterUV);             // Reflection texture
591  glMultiTexCoord2f(GL_TEXTURE1, waterUV, waterUV - move);      // Refraction texture
592  glMultiTexCoord2f(GL_TEXTURE2, normalUV, normalUV + move2);   // Normal map texture
593  glMultiTexCoord2f(GL_TEXTURE3, 0, 0);                         // DUDV map texture
594  glVertex3f(this->waterVerts[6], this->waterHeight, this->waterVerts[7]);
[8037]595  glEnd();
[7796]596
[9869]597  this->shader.deactivateShader();
[7796]598
[8037]599  mat.unselect();
[7796]600
601  glPopMatrix();
602}
603
[8719]604/**
605 * @brief tick tack, calculates the flow of the water
606 */
[7796]607void MappedWater::tick(float dt)
608{
[8037]609  // makes the water flow
[8719]610  this->move += this->waterFlow * dt;
[8037]611  this->move2 = this->move * this->kNormalMapScale;
[8792]612
[9006]613  // fading TODO fix this so it isnt hacky anymore
614  if(bFadeWaterUV)
615  {
616    this->waterUVFader = new tAnimation<MappedWater>(this, &MappedWater::setWaterUV);
617    this->waterUVFader->setInfinity(ANIM_INF_CONSTANT);
618
619    this->waterUVFader->addKeyFrame(this->waterUV, this->waterUVFadeTime, ANIM_LINEAR);
620    this->waterUVFader->addKeyFrame(this->newWaterUV, 0, ANIM_LINEAR);
621
622    bFadeWaterUV = false;
623    this->waterUVFader->replay();
624  }
625
626  if(bFadeWaterFlow)
627  {
628    this->waterFlowFader = new tAnimation<MappedWater>(this, &MappedWater::setWaterFlow);
629    this->waterFlowFader->setInfinity(ANIM_INF_CONSTANT);
630
631    this->waterFlowFader->addKeyFrame(this->waterFlow, this->waterFlowFadeTime, ANIM_LINEAR);
632    this->waterFlowFader->addKeyFrame(this->newWaterFlow, 0, ANIM_LINEAR);
633
634    bFadeWaterFlow = false;
635    this->waterFlowFader->replay();
636  }
637
638  if(bFadeShineSize)
639  {
640    this->shineSizeFader = new tAnimation<MappedWater>(this, &MappedWater::resetShineSize);
641    this->shineSizeFader->setInfinity(ANIM_INF_CONSTANT);
642
643    this->shineSizeFader->addKeyFrame(this->shineSize, this->shineSizeFadeTime, ANIM_LINEAR);
644    this->shineSizeFader->addKeyFrame(this->newShineSize, 0, ANIM_LINEAR);
645
646    bFadeShineSize = false;
647    this->shineSizeFader->replay();
648  }
649
650  if(bFadeShineStrength)
651  {
652    this->shineStrengthFader = new tAnimation<MappedWater>(this, &MappedWater::resetShineStrength);
653    this->shineStrengthFader->setInfinity(ANIM_INF_CONSTANT);
654
655    this->shineStrengthFader->addKeyFrame(this->shineStrength, this->shineStrengthFadeTime, ANIM_LINEAR);
656    this->shineStrengthFader->addKeyFrame(this->newShineStrength, 0, ANIM_LINEAR);
657
658    bFadeShineStrength = false;
659    this->shineStrengthFader->replay();
660  }
661
662  if(bFadeReflStrength)
663  {
664    this->reflStrengthFader = new tAnimation<MappedWater>(this, &MappedWater::resetReflStrength);
665    this->reflStrengthFader->setInfinity(ANIM_INF_CONSTANT);
666
667    this->reflStrengthFader->addKeyFrame(this->reflStrength, this->reflStrengthFadeTime, ANIM_LINEAR);
668    this->reflStrengthFader->addKeyFrame(this->newReflStrength, 0, ANIM_LINEAR);
669
670    bFadeReflStrength = false;
671    this->reflStrengthFader->replay();
672  }
673
674  if(bFadeRefraction)
675  {
676    this->refractionFader = new tAnimation<MappedWater>(this, &MappedWater::resetRefraction);
677    this->refractionFader->setInfinity(ANIM_INF_CONSTANT);
678
679    this->refractionFader->addKeyFrame(this->refraction, this->refractionFadeTime, ANIM_LINEAR);
680    this->refractionFader->addKeyFrame(this->newRefraction, 0, ANIM_LINEAR);
681
682    bFadeRefraction = false;
683    this->refractionFader->replay();
684  }
685
686  if(bFadeWaterHeight)
687  {
688    this->waterHeightFader = new tAnimation<MappedWater>(this, &MappedWater::setWaterHeight);
689    this->waterHeightFader->setInfinity(ANIM_INF_CONSTANT);
690
691    this->waterHeightFader->addKeyFrame(this->waterHeight, this->waterHeightFadeTime, ANIM_LINEAR);
692    this->waterHeightFader->addKeyFrame(this->newWaterHeight, 0, ANIM_LINEAR);
693
694    bFadeWaterHeight = false;
695    this->waterHeightFader->replay();
696  }
697
698  if(bFadeWaterColor)
699  {
700    this->waterColorRFader = new tAnimation<MappedWater>(this, &MappedWater::resetWaterColorR);
701    this->waterColorRFader->setInfinity(ANIM_INF_CONSTANT);
702
703    this->waterColorRFader->addKeyFrame(this->waterColor.x, this->waterColorFadeTime, ANIM_LINEAR);
704    this->waterColorRFader->addKeyFrame(this->newWaterColor.x, 0, ANIM_LINEAR);
705
706    this->waterColorRFader->replay();
707
708    this->waterColorGFader = new tAnimation<MappedWater>(this, &MappedWater::resetWaterColorG);
709    this->waterColorGFader->setInfinity(ANIM_INF_CONSTANT);
710
711    this->waterColorGFader->addKeyFrame(this->waterColor.y, this->waterColorFadeTime, ANIM_LINEAR);
712    this->waterColorGFader->addKeyFrame(this->newWaterColor.y, 0, ANIM_LINEAR);
713
714    this->waterColorGFader->replay();
715
716    this->waterColorBFader = new tAnimation<MappedWater>(this, &MappedWater::resetWaterColorB);
717    this->waterColorBFader->setInfinity(ANIM_INF_CONSTANT);
718
719    this->waterColorBFader->addKeyFrame(this->waterColor.z, this->waterColorFadeTime, ANIM_LINEAR);
720    this->waterColorBFader->addKeyFrame(this->newWaterColor.z, 0, ANIM_LINEAR);
721
722    this->waterColorBFader->replay();
723
724    bFadeWaterColor = false;
725  }
[7796]726}
727
[8719]728/**
729 * @brief prepares everything to render the reflection texutre
730 */
731void MappedWater::activateReflection()
[7796]732{
[8719]733  // To create the reflection texture we just need to set the view port
734  // to our texture map size, then render the current scene our camera
735  // is looking at to the already allocated texture unit.  Since this
736  // is a reflection of the top of the water surface we use clipping
737  // planes to only render the top of the world as a reflection.  If
738  // we are below the water we don't flip the reflection but just use
739  // the current view of the top as we are seeing through the water.
740  // When you look through water at the surface it isn't really reflected,
741  // only when looking down from above the water on the surface.
[7796]742
[8037]743  // save viewport matrix and change the viewport size
[7796]744  glPushAttrib(GL_VIEWPORT_BIT);
745  glViewport(0,0, textureSize, textureSize);
746
[8312]747  glMatrixMode(GL_MODELVIEW);
[8037]748  glPushMatrix();
[7796]749
750  // If our camera is above the water we will render the scene flipped upside down.
751  // In order to line up the reflection nicely with the world we have to translate
752  // the world to the position of our reflected surface, multiplied by two.
[8037]753  glEnable(GL_CLIP_PLANE0);
754  Vector pos = State::getCameraNode()->getAbsCoor();
[8719]755
[9006]756  if(pos.y > waterHeight)
[8037]757  {
758    // Translate the world, then flip it upside down
[9006]759    glTranslatef(0, waterHeight * 2, 0);
[8719]760    glScalef(1, -1, 1);
[7796]761
[8037]762    // Since the world is updside down we need to change the culling to FRONT
763    glCullFace(GL_FRONT);
[7796]764
[8037]765    // Set our plane equation and turn clipping on
[9006]766    double plane[4] = {0, 1, 0, -waterHeight};
[8037]767    glClipPlane(GL_CLIP_PLANE0, plane);
768  }
769  else
[7796]770  {
[8037]771    // If the camera is below the water we don't want to flip the world,
772    // but just render it clipped so only the top is drawn.
[9006]773    double plane[4] = {0, 1, 0, waterHeight};
[8037]774    glClipPlane(GL_CLIP_PLANE0, plane);
775  }
[7796]776}
777
[8719]778/**
779 * @brief ends the reflection and saves the graphic buffer into a texture
780 */
[7796]781void MappedWater::deactivateReflection()
782{
[8037]783  glDisable(GL_CLIP_PLANE0);
784  glCullFace(GL_BACK);
[7796]785
[8312]786  // Create the texture and store it on the video card
[8719]787  mat.renderToTexture(0, GL_TEXTURE_2D, 0, 0, 0, 0, 0, textureSize, textureSize);
[8312]788
[8037]789  glPopMatrix();
[7796]790  glPopAttrib();
791}
792
[8719]793/**
794 * @brief prepares everything to render the refraction texutre
795 */
[7796]796void MappedWater::activateRefraction()
[8719]797{
[8037]798  // To create the refraction and depth textures we do the same thing
799  // we did for the reflection texture, except we don't need to turn
800  // the world upside down.  We want to find the depth of the water,
801  // not the depth of the sky and above water terrain.
802
803  // save viewport matrix and change the viewport size
804  glPushAttrib(GL_VIEWPORT_BIT);
805  glViewport(0,0, textureSize, textureSize);
806
[8312]807  glMatrixMode(GL_MODELVIEW);
[8037]808  glPushMatrix();
809
810  // If our camera is above the water we will render only the parts that
811  // are under the water.  If the camera is below the water we render
812  // only the stuff above the water.  Like the reflection texture, we
813  // incorporate clipping planes to only render what we need.
814
815  // If the camera is above water, render the data below the water
816  glEnable(GL_CLIP_PLANE0);
817  Vector pos = State::getCameraNode()->getAbsCoor();
[9006]818  if(pos.y > waterHeight)
[8037]819  {
[9006]820    double plane[4] = {0, -1, 0, waterHeight};
[8037]821    glClipPlane(GL_CLIP_PLANE0, plane);
822  }
823  // If the camera is below the water, only render the data above the water
824  else
825  {
826    glCullFace(GL_FRONT);
[9006]827    double plane[4] = {0, 1, 0, -waterHeight};
[8037]828    glClipPlane(GL_CLIP_PLANE0, plane);
829  }
[7796]830}
831
[8719]832/**
833 * @brief ends the refraction and saves the graphic buffer into a texture
834 */
[7796]835void MappedWater::deactivateRefraction()
836{
[8037]837  glDisable(GL_CLIP_PLANE0);
838  glCullFace(GL_BACK);
839
[8312]840  // Create the texture and store it on the video card
[8719]841  mat.renderToTexture(1, GL_TEXTURE_2D, 0, 0, 0, 0, 0, textureSize, textureSize);
[8312]842
843  glPopMatrix();
844  glPopAttrib();
[7796]845}
Note: See TracBrowser for help on using the repository browser.