Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/heathaze/src/world_entities/environments/mapped_water.cc @ 10755

Last change on this file since 10755 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
Line 
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"
19#include "state.h"
20#include "t_animation.h"
21#include <cmath>
22#include "glgui.h"
23#include "shell_command.h"
24#include "script_class.h"
25
26#include "resource_shader.h"
27
28#include "class_id_DEPRECATED.h"
29ObjectListDefinitionID(MappedWater, CL_MAPPED_WATER);
30CREATE_FACTORY(MappedWater);
31
32SHELL_COMMAND(gui, MappedWater, toggleGui);
33SHELL_COMMAND(output, MappedWater, saveParams);
34
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)));
44
45
46/**
47 * @brief constructor
48 * @param root xml data
49 */
50MappedWater::MappedWater(const TiXmlElement* root)
51{
52  this->registerObject(this, MappedWater::_objectList);
53  this->toList(OM_ENVIRON);
54
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
59  if (root != NULL)
60    this->loadParams(root);
61
62  /// initialization of the textures
63  this->initTextures();
64
65  /// initialization of the shaders
66  this->initShaders();
67
68  /// calculation of the 4 verts of the water quad
69  this->calcVerts();
70
71  // init gui
72  this->box = NULL;
73}
74
75/**
76 * @brief deltes shader and the uniform used by the camera
77 */
78MappedWater::~MappedWater()
79{
80  delete cam_uni;
81  delete color_uni;
82  delete light_uni;
83  delete shineSize_uni;
84  delete shineStrength_uni;
85  delete reflStrength_uni;
86  delete refr_uni;
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);
98  this->setWaterFlow(0.08f);
99  this->setLightPos(0, 10, 0);
100  this->setWaterAngle(0);
101  this->setNormalMapScale(0.25f);
102  this->setWaterColor(0.1f, 0.2f, 0.4f);
103  this->setShineSize(128);
104  this->setShineStrength(0.7f);
105  this->setReflStrength(1.0f);
106  this->setRefraction(0.009f);
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;
114
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;
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
136  // set up refleciton texture
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);
142  // load normal map
143  mat.setDiffuseMap("pictures/water_normalmap.bmp", GL_TEXTURE_2D, 2);
144  // load dudv map
145  mat.setDiffuseMap("pictures/water_dudvmap.bmp", GL_TEXTURE_2D, 3);
146
147  // sets texture parameters for reflection texture
148  glBindTexture(GL_TEXTURE_2D, this->mat.diffuseTextureID(0));
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);
153  // sets texture parameters for refraction texture
154  glBindTexture(GL_TEXTURE_2D, this->mat.diffuseTextureID(1));
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);
159}
160
161/**
162 * @brief initialization of the shaders
163 */
164void MappedWater::initShaders()
165{
166  // load shader files
167  shader = ResourceShader( "shaders/mapped_water.vert", "shaders/mapped_water.frag");
168
169  this->shader.activateShader();
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
179  Shader::Uniform(shader, "depthMap").set(1);
180  // Give the variable "waterColor" a blue color
181  color_uni = new Shader::Uniform(shader, "waterColor");
182  color_uni->set(waterColor.x, waterColor.y, waterColor.z, 1.0f);
183  // Give the variable "lightPos" our hard coded light position
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"
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);
198  // uniform for the camera position
199  cam_uni = new Shader::Uniform(shader, "cameraPos");
200
201  this->shader.deactivateShader();
202}
203
204/**
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/**
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{
227  this->shader.activateShader();
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
233  this->shader.deactivateShader();
234}
235
236/**
237 * @brief resets the shininess in the Shader
238 * @param shine new value for the shininess
239 */
240void MappedWater::resetShineSize(float shine)
241{
242  this->shader.activateShader();
243  this->shineSize = shine;
244
245  // Set the variable "shine"
246  shineSize_uni->set(this->shineSize);
247
248  this->shader.deactivateShader();
249}
250
251/**
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{
257  this->shader.activateShader();
258  this->shineStrength = strength;
259
260  // Set the variable "shine"
261  shineStrength_uni->set(this->shineStrength);
262
263  this->shader.deactivateShader();
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{
272  this->shader.activateShader();
273  this->reflStrength = strength;
274
275  // Set the variable "shine"
276  reflStrength_uni->set(this->reflStrength);
277
278  this->shader.deactivateShader();
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{
287  this->shader.activateShader();
288  this->refraction = refraction;
289
290  // Set the variable "shine"
291  refr_uni->set(this->refraction);
292
293  this->shader.deactivateShader();
294}
295
296/**
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{
304  this->shader.activateShader();
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
310  this->shader.deactivateShader();
311}
312
313/**
314 * @brief ends the refraction and saves the graphic buffer into a texture
315 * @param root xml data
316 */
317void MappedWater::loadParams(const TiXmlElement* root)
318{
319  WorldEntity::loadParams(root);
320
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);
325  LoadParam(root, "lightpos", this, MappedWater, setLightPos);
326  LoadParam(root, "waterangle", this, MappedWater, setWaterAngle);
327  LoadParam(root, "normalmapscale", this, MappedWater, setNormalMapScale);
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);
332  LoadParam(root, "watercolor", this, MappedWater, setWaterColor);
333}
334
335/**
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
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");
357}
358
359/**
360 * @brief starts the slider gui that lets you edit all water parameters
361 */
362void MappedWater::toggleGui()
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      {
370        OrxGui::GLGuiText* waterColorText = new OrxGui::GLGuiText();
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);
378        waterColorR->valueChanged.connect(this, &MappedWater::resetWaterColorR);
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);
385        waterColorG->valueChanged.connect(this, &MappedWater::resetWaterColorG);
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);
392        waterColorB->valueChanged.connect(this, &MappedWater::resetWaterColorB);
393        waterColorBox->pack(waterColorB);
394      }
395      this->box->pack(waterColorBox);
396
397      OrxGui::GLGuiBox* waterUVBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
398      {
399        OrxGui::GLGuiText* waterUVText = new OrxGui::GLGuiText();
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);
407        waterUV->valueChanged.connect(this, &MappedWater::setWaterUV);
408        waterUVBox->pack(waterUV);
409      }
410      this->box->pack(waterUVBox);
411
412      OrxGui::GLGuiBox* waterFlowBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
413      {
414        OrxGui::GLGuiText* waterFlowText = new OrxGui::GLGuiText();
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);
422        waterFlow->valueChanged.connect(this, &MappedWater::setWaterFlow);
423        waterFlowBox->pack(waterFlow);
424      }
425      this->box->pack(waterFlowBox);
426
427      OrxGui::GLGuiBox* shineSizeBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
428      {
429        OrxGui::GLGuiText* shineSizeText = new OrxGui::GLGuiText();
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);
437        shineSize->valueChanged.connect(this, &MappedWater::resetShineSize);
438        shineSizeBox->pack(shineSize);
439      }
440      this->box->pack(shineSizeBox);
441
442      OrxGui::GLGuiBox* shineStrengthBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
443      {
444        OrxGui::GLGuiText* shineStrengthText = new OrxGui::GLGuiText();
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);
452        shineStrength->valueChanged.connect(this, &MappedWater::resetShineStrength);
453        shineStrengthBox->pack(shineStrength);
454      }
455      this->box->pack(shineStrengthBox);
456
457      OrxGui::GLGuiBox* reflStrengthBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
458      {
459        OrxGui::GLGuiText* reflStrengthText = new OrxGui::GLGuiText();
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);
467        reflStrength->valueChanged.connect(this, &MappedWater::resetReflStrength);
468        reflStrengthBox->pack(reflStrength);
469      }
470      this->box->pack(reflStrengthBox);
471
472      OrxGui::GLGuiBox* refractionBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
473      {
474        OrxGui::GLGuiText* refractionText = new OrxGui::GLGuiText();
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);
482        refraction->valueChanged.connect(this, &MappedWater::resetRefraction);
483        refractionBox->pack(refraction);
484      }
485      this->box->pack(refractionBox);
486
487      OrxGui::GLGuiBox* lightPosBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
488      {
489        OrxGui::GLGuiText* lightPosText = new OrxGui::GLGuiText();
490        lightPosText->setText("LightPos");
491        lightPosBox->pack(lightPosText);
492
493        OrxGui::GLGuiSlider* lightPosX = new OrxGui::GLGuiSlider();
494        lightPosX->setRange(-4000, 4000);
495        lightPosX->setValue(this->lightPos.x);
496        lightPosX->setStep(15);
497        lightPosX->valueChanged.connect(this, &MappedWater::resetLightPosX);
498        lightPosBox->pack(lightPosX);
499
500        OrxGui::GLGuiSlider* lightPosY = new OrxGui::GLGuiSlider();
501        lightPosY->setRange(-4000, 4000);
502        lightPosY->setStep(15);
503        lightPosY->setValue(this->lightPos.y);
504        lightPosY->valueChanged.connect(this, &MappedWater::resetLightPosY);
505        lightPosBox->pack(lightPosY);
506
507        OrxGui::GLGuiSlider* lightPosZ = new OrxGui::GLGuiSlider();
508        lightPosZ->setRange(-4000, 4000);
509        lightPosZ->setStep(15);
510        lightPosZ->setValue(this->lightPos.z);
511        lightPosZ->valueChanged.connect(this, &MappedWater::resetLightPosZ);
512        lightPosBox->pack(lightPosZ);
513      }
514      this->box->pack(lightPosBox);
515
516      OrxGui::GLGuiBox* waterHeightBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
517      {
518        OrxGui::GLGuiText* waterHeightText = new OrxGui::GLGuiText();
519        waterHeightText->setText("WaterHeight");
520        waterHeightBox->pack(waterHeightText);
521
522        OrxGui::GLGuiSlider* waterHeight = new OrxGui::GLGuiSlider();
523        waterHeight->setRange(100, 370);
524        waterHeight->setValue(this->waterHeight);
525        waterHeight->setStep(4);
526        waterHeight->valueChanged.connect(this, &MappedWater::setWaterHeight);
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  }
537  else
538  {
539    OrxGui::GLGuiHandler::getInstance()->deactivate();
540    OrxGui::GLGuiHandler::getInstance()->deactivateCursor();
541    delete this->box;
542    this->box = NULL;
543  }
544}
545
546/**
547 * @brief activates the water shader and draws a quad with four textures on it
548 */
549void MappedWater::draw() const
550{
551  glMatrixMode(GL_MODELVIEW);
552  glPushMatrix();
553
554  // don't use glRotate or glTranslate here... the shader won't work anymore
555
556  mat.select();
557
558  this->shader.activateShader();
559
560  // reset the camera uniform to the current cam position
561  Vector pos = State::getCameraNode()->getAbsCoor();
562  cam_uni->set(pos.x, pos.y, pos.z, 1.0f);
563
564  glDisable(GL_BLEND);
565
566  // TODO change texture coords, so water doesnt look distorted when xWidth != zWidth
567  glBegin(GL_QUADS);
568  // The back left vertice for the water
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]);
574
575  // The front left vertice for the water
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]);
581
582  // The front right vertice for the water
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]);
588
589  // The back right vertice for the water
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]);
595  glEnd();
596
597  this->shader.deactivateShader();
598
599  mat.unselect();
600
601  glPopMatrix();
602}
603
604/**
605 * @brief tick tack, calculates the flow of the water
606 */
607void MappedWater::tick(float dt)
608{
609  // makes the water flow
610  this->move += this->waterFlow * dt;
611  this->move2 = this->move * this->kNormalMapScale;
612
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  }
726}
727
728/**
729 * @brief prepares everything to render the reflection texutre
730 */
731void MappedWater::activateReflection()
732{
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.
742
743  // save viewport matrix and change the viewport size
744  glPushAttrib(GL_VIEWPORT_BIT);
745  glViewport(0,0, textureSize, textureSize);
746
747  glMatrixMode(GL_MODELVIEW);
748  glPushMatrix();
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.
753  glEnable(GL_CLIP_PLANE0);
754  Vector pos = State::getCameraNode()->getAbsCoor();
755
756  if(pos.y > waterHeight)
757  {
758    // Translate the world, then flip it upside down
759    glTranslatef(0, waterHeight * 2, 0);
760    glScalef(1, -1, 1);
761
762    // Since the world is updside down we need to change the culling to FRONT
763    glCullFace(GL_FRONT);
764
765    // Set our plane equation and turn clipping on
766    double plane[4] = {0, 1, 0, -waterHeight};
767    glClipPlane(GL_CLIP_PLANE0, plane);
768  }
769  else
770  {
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.
773    double plane[4] = {0, 1, 0, waterHeight};
774    glClipPlane(GL_CLIP_PLANE0, plane);
775  }
776}
777
778/**
779 * @brief ends the reflection and saves the graphic buffer into a texture
780 */
781void MappedWater::deactivateReflection()
782{
783  glDisable(GL_CLIP_PLANE0);
784  glCullFace(GL_BACK);
785
786  // Create the texture and store it on the video card
787  mat.renderToTexture(0, GL_TEXTURE_2D, 0, 0, 0, 0, 0, textureSize, textureSize);
788
789  glPopMatrix();
790  glPopAttrib();
791}
792
793/**
794 * @brief prepares everything to render the refraction texutre
795 */
796void MappedWater::activateRefraction()
797{
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
807  glMatrixMode(GL_MODELVIEW);
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();
818  if(pos.y > waterHeight)
819  {
820    double plane[4] = {0, -1, 0, waterHeight};
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);
827    double plane[4] = {0, 1, 0, -waterHeight};
828    glClipPlane(GL_CLIP_PLANE0, plane);
829  }
830}
831
832/**
833 * @brief ends the refraction and saves the graphic buffer into a texture
834 */
835void MappedWater::deactivateRefraction()
836{
837  glDisable(GL_CLIP_PLANE0);
838  glCullFace(GL_BACK);
839
840  // Create the texture and store it on the video card
841  mat.renderToTexture(1, GL_TEXTURE_2D, 0, 0, 0, 0, 0, textureSize, textureSize);
842
843  glPopMatrix();
844  glPopAttrib();
845}
Note: See TracBrowser for help on using the repository browser.