Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Shaders now fully support the ResourceShader Paradigm

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