Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/world_entities/environments/mapped_water.cc @ 9818

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

Switching to new Shader layout, with Shader and ShaderData. Shaders do not render for the time being

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