RigsofRods
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
MaterialManager.cpp
Go to the documentation of this file.
1 /*
2 --------------------------------------------------------------------------------
3 This source file is part of Hydrax.
4 Visit ---
5 
6 Copyright (C) 2008 Xavier Vergu�n Gonz�lez <xavierverguin@hotmail.com>
7  <xavyiy@gmail.com>
8 
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU Lesser General Public License as published by the Free Software
11 Foundation; either version 2 of the License, or (at your option) any later
12 version.
13 
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public License along with
19 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21 http://www.gnu.org/copyleft/lesser.txt.
22 --------------------------------------------------------------------------------
23 
24 --------------------------------------------------------------------------------
25 Contributors:
26  Jose Luis Cerc�s Pita <jlcercos@alumnos.upm.es>
27 --------------------------------------------------------------------------------
28 */
29 
30 #include <OgreString.h>
31 
32 #include <MaterialManager.h>
33 
34 #include <Hydrax.h>
35 
36 #define _def_Water_Material_Name "_Hydrax_Water_Material"
37 #define _def_Water_Shader_VP_Name "_Hydrax_Water_VP"
38 #define _def_Water_Shader_FP_Name "_Hydrax_Water_FP"
39 
40 #define _def_Depth_Material_Name "_Hydrax_Depth_Material"
41 #define _def_Depth_Shader_VP_Name "_Hydrax_Depth_VP"
42 #define _def_Depth_Shader_FP_Name "_Hydrax_Depth_FP"
43 
44 #define _def_DepthTexture_Shader_VP_Name "_Hydrax_DepthTexture_VP"
45 #define _def_DepthTexture_Shader_FP_Name "_Hydrax_DepthTexture_FP"
46 
47 #define _def_Underwater_Material_Name "_Hydrax_Underwater_Material"
48 #define _def_Underwater_Shader_VP_Name "_Hydrax_Underwater_Shader_VP"
49 #define _def_Underwater_Shader_FP_Name "_Hydrax_Underwater_Shader_FP"
50 
51 #define _def_Underwater_Compositor_Material_Name "_Hydrax_Underwater_Compositor_Material"
52 #define _def_Underwater_Compositor_Shader_VP_Name "_Hydrax_Underwater_Compositor_Shader_VP"
53 #define _def_Underwater_Compositor_Shader_FP_Name "_Hydrax_Underwater_Compositor_Shader_FP"
54 
55 #define _def_Underwater_Compositor_Name "_Hydrax_Underwater_Compositor_Name"
56 
57 #define _def_Simple_Red_Material_Name "_Hydrax_Simple_Red_Material"
58 #define _def_Simple_Black_Material_Name "_Hydrax_Simple_Black_Material"
59 
60 namespace Hydrax
61 {
63  : mCreated(false)
64  , mComponents(HYDRAX_COMPONENTS_NONE)
65  , mHydrax(h)
66  {
67  for (int k = 0; k < 6; k++)
68  {
69  mMaterials[k].reset();
70  }
71 
72  for (int k = 0; k < 1; k++)
73  {
74  mCompositorsEnable[k] = false;
76  }
77 
79  }
80 
82  {
84  }
85 
87  {
88  if (Ogre::MaterialManager::getSingleton().resourceExists(_def_Water_Material_Name))
89  {
90  Ogre::MaterialManager::getSingleton().remove(_def_Water_Material_Name);
91 
92  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_Water_Shader_VP_Name);
93  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_Water_Shader_FP_Name);
94  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_Water_Shader_VP_Name);
95  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_Water_Shader_FP_Name);
96  }
97 
98  if (Ogre::MaterialManager::getSingleton().resourceExists(_def_Depth_Material_Name))
99  {
100  Ogre::MaterialManager::getSingleton().remove(_def_Depth_Material_Name);
101 
102  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_Depth_Shader_VP_Name);
103  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_Depth_Shader_FP_Name);
104  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_Depth_Shader_VP_Name);
105  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_Depth_Shader_FP_Name);
106  }
107 
108  if (Ogre::MaterialManager::getSingleton().resourceExists(_def_Underwater_Material_Name))
109  {
110  Ogre::MaterialManager::getSingleton().remove(_def_Underwater_Material_Name);
111 
112  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_Underwater_Shader_VP_Name);
113  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_Underwater_Shader_FP_Name);
114  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_Underwater_Shader_VP_Name);
115  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_Underwater_Shader_FP_Name);
116  }
117 
118  if (Ogre::MaterialManager::getSingleton().resourceExists(_def_Simple_Red_Material_Name))
119  {
120  Ogre::MaterialManager::getSingleton().remove(_def_Simple_Red_Material_Name);
121  }
122 
123  if (Ogre::MaterialManager::getSingleton().resourceExists(_def_Simple_Black_Material_Name))
124  {
125  Ogre::MaterialManager::getSingleton().remove(_def_Simple_Black_Material_Name);
126  }
127 
128  Ogre::String AlphaChannels[] = {"x","y","z","w",
129  "r","g","b","a"};
130 
131  for (int k = 0; k<8; k++)
132  {
133  if (Ogre::HighLevelGpuProgramManager::getSingleton().resourceExists(_def_DepthTexture_Shader_VP_Name + AlphaChannels[k]))
134  {
135  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_DepthTexture_Shader_VP_Name + AlphaChannels[k]);
136  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_DepthTexture_Shader_FP_Name + AlphaChannels[k]);
137  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_DepthTexture_Shader_VP_Name + AlphaChannels[k]);
138  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_DepthTexture_Shader_FP_Name + AlphaChannels[k]);
139  }
140  }
141 
143 
144  mCreated = false;
145  }
146 
148  {
149  if (Ogre::MaterialManager::getSingleton().resourceExists(_def_Underwater_Compositor_Material_Name))
150  {
152  Ogre::CompositorManager::getSingleton().remove(_def_Underwater_Compositor_Name);
153 
154  Ogre::MaterialManager::getSingleton().remove(_def_Underwater_Compositor_Material_Name);
155 
156  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_Underwater_Compositor_Shader_VP_Name);
157  Ogre::HighLevelGpuProgramManager::getSingleton().unload(_def_Underwater_Compositor_Shader_FP_Name);
158  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_Underwater_Compositor_Shader_VP_Name);
159  Ogre::HighLevelGpuProgramManager::getSingleton().remove(_def_Underwater_Compositor_Shader_FP_Name);
160  }
161  }
162 
164  {
165  removeMaterials();
166 
167  HydraxLOG("Creating water material...");
168  if (!_createWaterMaterial(Components, Options))
169  {
170  return false;
171  }
173  HydraxLOG("Water material created.");
174 
175  if (_isComponent(Components, HYDRAX_COMPONENT_DEPTH))
176  {
177  HydraxLOG("Creating depth material...");
178  if(!_createDepthMaterial(Components, Options))
179  {
180  return false;
181  }
182  HydraxLOG("Depth material created.");
183  }
184 
185  if (_isComponent(Components, HYDRAX_COMPONENT_UNDERWATER))
186  {
187  HydraxLOG("Creating underwater material...");
188  if(!_createUnderwaterMaterial(Components, Options))
189  {
190  return false;
191  }
192  if(!_createUnderwaterCompositor(Components, Options))
193  {
194  return false;
195  }
196  if(!_createSimpleColorMaterial(Ogre::ColourValue::Red, MAT_SIMPLE_RED, _def_Simple_Red_Material_Name, false))
197  {
198  return false;
199  }
200  HydraxLOG("Underwater material created.");
201  }
202 
203  mComponents = Components;
204  mOptions = Options;
205  mCreated = true;
206 
207  std::vector<Ogre::Technique*>::iterator TechIt;
208 
209  for(TechIt = mDepthTechniques.begin(); TechIt != mDepthTechniques.end(); TechIt++)
210  {
211  if (!(*TechIt))
212  {
213  mDepthTechniques.erase(TechIt);
214  // TechIt-- ?
215  continue;
216  }
217 
218  bool isTextureDepthTechnique =
219  ((*TechIt)->getName() == "_Hydrax_Depth_Technique") ? false : true;
220 
221  if (isTextureDepthTechnique)
222  {
223  Ogre::String DepthTextureName =
224  ((*TechIt)->getPass(0)->getTextureUnitState(0)->getName() == "_DetphTexture_Hydrax") ?
225  (*TechIt)->getPass(0)->getTextureUnitState(0)->getTextureName() : (*TechIt)->getPass(0)->getTextureUnitState(1)->getTextureName();
226 
227  // Alpha channel will be stored in pass 0 name
228  addDepthTextureTechnique((*TechIt), DepthTextureName, (*TechIt)->getPass(0)->getName() , false);
229  }
230  else
231  {
232  addDepthTechnique((*TechIt), false);
233  }
234  }
235 
236  return true;
237  }
238 
240  const Ogre::String GpuProgramNames[2],
241  const ShaderMode& SM,
242  const Ogre::String EntryPoints[2],
243  const Ogre::String Data[2])
244  {
245  GpuProgram GpuPrograms[2] = {GPUP_VERTEX, GPUP_FRAGMENT};
246 
247  for (int k = 0; k < 2; k++)
248  {
249  if (!createGpuProgram(GpuProgramNames[k], SM, GpuPrograms[k], EntryPoints[k], Data[k]))
250  {
251  return false;
252  }
253  }
254 
255  Pass->setVertexProgram(GpuProgramNames[0]);
256  Pass->setFragmentProgram(GpuProgramNames[1]);
257 
258  return true;
259  }
260 
261  bool MaterialManager::createGpuProgram(const Ogre::String &Name,
262  const ShaderMode& SM,
263  const GpuProgram& GPUP,
264  const Ogre::String& EntryPoint,
265  const Ogre::String& Data)
266  {
267  if (Ogre::HighLevelGpuProgramManager::getSingleton().resourceExists(Name))
268  {
269  HydraxLOG("Error in bool MaterialManager::createGpuProgram(): "+ Name + " exists.");
270  return false;
271  }
272 
273  Ogre::String ShaderModesStr[3] = {"hlsl", "cg", "glsl"};
274  Ogre::String Profiles[2];
275 
276  switch (SM)
277  {
278  case SM_HLSL:
279  {
280  Profiles[0] = "target";
281 
282  if (GPUP == GPUP_VERTEX)
283  {
284  Profiles[1] = "vs_1_1";
285  }
286  else
287  {
288  Profiles[1] = "ps_2_0";
289  }
290  }
291  break;
292 
293  case SM_CG:
294  {
295  Profiles[0] = "profiles";
296 
297  if (GPUP == GPUP_VERTEX)
298  {
299  Profiles[1] = "vs_1_1 arbvp1";
300  }
301  else
302  {
303  Profiles[1] = "ps_2_0 arbfp1 fp20";
304  }
305  }
306  break;
307 
308  case SM_GLSL:
309  {
310  Profiles[0] = ""; // Dont needed
311  if (GPUP == GPUP_VERTEX)
312  {
313  Profiles[1] = ""; // Dont needed
314  }
315  else
316  {
317  Profiles[1] = ""; // Dont needed
318  }
319  }
320  break;
321  }
322 
323  Ogre::GpuProgramType GpuPType;
324 
325  if (GPUP == GPUP_VERTEX)
326  {
327  GpuPType = Ogre::GPT_VERTEX_PROGRAM;
328  }
329  else
330  {
331  GpuPType = Ogre::GPT_FRAGMENT_PROGRAM;
332  }
333 
334  Ogre::HighLevelGpuProgramPtr HLGpuProgram =
335  Ogre::HighLevelGpuProgramManager::getSingleton().
336  createProgram(Name,
337  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
338  ShaderModesStr[SM],
339  GpuPType);
340 
341  HLGpuProgram->setSource(Data);
342  HLGpuProgram->setParameter("entry_point", EntryPoint);
343  HLGpuProgram->setParameter(Profiles[0], Profiles[1]);
344  HLGpuProgram->load();
345 
346  return true;
347  }
348 
350  {
351  const bool cDepth = _isComponent(Components, HYDRAX_COMPONENT_DEPTH );
352  const bool cSmooth = _isComponent(Components, HYDRAX_COMPONENT_SMOOTH );
353  const bool cSun = _isComponent(Components, HYDRAX_COMPONENT_SUN );
354  const bool cFoam = _isComponent(Components, HYDRAX_COMPONENT_FOAM );
355  const bool cCaustics = _isComponent(Components, HYDRAX_COMPONENT_CAUSTICS);
356 
357  Ogre::String VertexProgramData, FragmentProgramData;
358 
359  // Vertex program
360 
361  switch (Options.NM)
362  {
363  case NM_TEXTURE:
364  {
365  switch (Options.SM)
366  {
367  case SM_HLSL: case SM_CG:
368  {
369  VertexProgramData +=
370  Ogre::String(
371  "void main_vp(\n") +
372  // IN
373  "float4 iPosition : POSITION,\n" +
374  "float2 iUv : TEXCOORD0,\n" +
375  // OUT
376  "out float4 oPosition : POSITION,\n" +
377  "out float4 oPosition_ : TEXCOORD0,\n" +
378  "out float2 oUvNoise : TEXCOORD1,\n" +
379  "out float4 oUvProjection : TEXCOORD2,\n";
380  // UNIFORM
381  if (cFoam)
382  {
383  VertexProgramData += Ogre::String(
384  "out float4 oWorldPosition : TEXCOORD3,\n") +
385  "uniform float4x4 uWorld,\n";
386  }
387  VertexProgramData += Ogre::String(
388  "uniform float4x4 uWorldViewProj)\n") +
389  "{\n" +
390  "oPosition_ = iPosition;\n";
391  if (cFoam)
392  {
393  VertexProgramData += "oWorldPosition = mul(uWorld, iPosition);\n";
394  }
395  VertexProgramData +=
396  Ogre::String(
397  "oPosition = mul(uWorldViewProj, iPosition);\n") +
398  // Projective texture coordinates, adjust for mapping
399  "float4x4 scalemat = float4x4(0.5, 0, 0, 0.5,"+
400  "0,-0.5, 0, 0.5,"+
401  "0, 0, 0.5, 0.5,"+
402  "0, 0, 0, 1);\n" +
403  "oUvProjection = mul(scalemat, oPosition);\n" +
404  "oUvNoise = iUv;\n" +
405  "}\n";
406  }
407  break;
408 
409  case SM_GLSL:
410  {
411  VertexProgramData += Ogre::String( "\n");
412  // UNIFORMS
413  if(cFoam)
414  {
415  VertexProgramData += "uniform mat4 uWorld;\n";
416  }
417  // IN
418  // OUT
419  VertexProgramData += Ogre::String(
420  "varying vec4 Position_;\n") +
421  "varying vec4 UVProjection;\n";
422  if(cFoam)
423  {
424  VertexProgramData += "varying vec4 WorldPosition;\n";
425  }
426  // PROGRAM
427  VertexProgramData += Ogre::String(
428  "void main()\n") +
429  "{\n" +
430  "Position_ = gl_Vertex;\n";
431  if(cFoam)
432  {
433  VertexProgramData += "WorldPosition = uWorld * gl_Vertex;\n";
434  }
435  VertexProgramData += Ogre::String(
436  "gl_Position = ftransform();\n") +
437  "mat4 scalemat = mat4( 1.0, 0.0, 0.0, 0.0,\n" +
438  " 0.0, -1.0, 0.0, 0.0,\n" +
439  " 0.0, 0.0, 1.0, 0.0,\n" +
440  " 0.0, 0.0, 0.0, 1.0);\n" +
441  "UVProjection = scalemat * gl_Position;\n" +
442  "gl_TexCoord[0] = gl_MultiTexCoord0;\n" +
443  "}\n";
444  }
445  break;
446  }
447  }
448  break;
449 
450  case NM_VERTEX:
451  {
452  switch (Options.SM)
453  {
454  case SM_HLSL: case SM_CG:
455  {
456  VertexProgramData +=
457  Ogre::String(
458  "void main_vp(\n") +
459  // IN
460  "float4 iPosition : POSITION,\n" +
461  "float3 iNormal : NORMAL,\n"+
462  // OUT
463  "out float4 oPosition : POSITION,\n" +
464  "out float4 oPosition_ : TEXCOORD0,\n" +
465  "out float4 oUvProjection : TEXCOORD1,\n" +
466  "out float3 oNormal : TEXCOORD2,\n";
467  if (cFoam)
468  {
469  VertexProgramData += "out float4 oWorldPosition : TEXCOORD3,\n uniform float4x4 uWorld,\n";
470  }
471  VertexProgramData +=
472  Ogre::String(
473  // UNIFORM
474  "uniform float4x4 uWorldViewProj)\n") +
475  "{\n" +
476  "oPosition_ = iPosition;\n";
477  if (cFoam)
478  {
479  VertexProgramData += "oWorldPosition = mul(uWorld, iPosition);\n";
480  }
481  VertexProgramData +=
482  Ogre::String(
483  "oPosition = mul(uWorldViewProj, iPosition);\n") +
484  // Projective texture coordinates, adjust for mapping
485  "float4x4 scalemat = float4x4(0.5, 0, 0, 0.5,"+
486  "0,-0.5, 0, 0.5,"+
487  "0, 0, 0.5, 0.5,"+
488  "0, 0, 0, 1);\n" +
489  "oUvProjection = mul(scalemat, oPosition);\n" +
490  "oNormal = normalize(iNormal);\n"+
491  "}\n";
492  }
493  break;
494 
495  case SM_GLSL:
496  {
497  VertexProgramData += Ogre::String( "\n");
498  // UNIFORMS
499  if(cFoam)
500  {
501  VertexProgramData += "uniform mat4 uWorld;\n";
502  }
503  // IN
504  // OUT
505  VertexProgramData += Ogre::String(
506  "varying vec4 Position_;\n") +
507  "varying vec4 UVProjection;\n" +
508  "varying vec3 Normal;\n";
509  if(cFoam)
510  {
511  VertexProgramData += "varying vec4 WorldPosition;\n";
512  }
513  // PROGRAM
514  VertexProgramData += Ogre::String(
515  "void main()\n") +
516  "{\n" +
517  "Position_ = gl_Vertex;\n";
518  if(cFoam)
519  {
520  VertexProgramData += "WorldPosition = uWorld * gl_Vertex;\n";
521  }
522  VertexProgramData += Ogre::String(
523  "gl_Position = ftransform();\n") +
524  "mat4 scalemat = mat4( 1.0, 0.0, 0.0, 0.0,\n" +
525  " 0.0, -1.0, 0.0, 0.0,\n" +
526  " 0.0, 0.0, 1.0, 0.0,\n" +
527  " 0.0, 0.0, 0.0, 1.0);\n" +
528  "UVProjection = scalemat * gl_Position;\n" +
529  "Normal = normalize(gl_Normal);\n" +
530  "}\n";
531  }
532  break;
533  }
534  }
535  break;
536 
537  case NM_RTT:
538  {
539  switch (Options.SM)
540  {
541  case SM_HLSL: case SM_CG:
542  {
543  VertexProgramData +=
544  Ogre::String(
545  "void main_vp(\n") +
546  // IN
547  "float4 iPosition : POSITION,\n" +
548  // OUT
549  "out float4 oPosition : POSITION,\n" +
550  "out float4 oPosition_ : TEXCOORD0,\n" +
551  "out float4 oUvProjection : TEXCOORD1,\n";
552  if (cFoam)
553  {
554  VertexProgramData += "out float4 oWorldPosition : TEXCOORD2,\n uniform float4x4 uWorld,\n";
555  }
556  VertexProgramData +=
557  Ogre::String(
558  // UNIFORM
559  "uniform float4x4 uWorldViewProj)\n") +
560  "{\n" +
561  "oPosition_ = iPosition;\n";
562  if (cFoam)
563  {
564  VertexProgramData += "oWorldPosition = mul(uWorld, iPosition);\n";
565  }
566  VertexProgramData +=
567  Ogre::String(
568  "oPosition = mul(uWorldViewProj, iPosition);\n") +
569  // Projective texture coordinates, adjust for mapping
570  "float4x4 scalemat = float4x4(0.5, 0, 0, 0.5,"+
571  "0,-0.5, 0, 0.5,"+
572  "0, 0, 0.5, 0.5,"+
573  "0, 0, 0, 1);\n" +
574  "oUvProjection = mul(scalemat, oPosition);\n" +
575  "}\n";
576  }
577  break;
578 
579  case SM_GLSL:
580  {
581  VertexProgramData += Ogre::String( "\n");
582  // UNIFORMS
583  if(cFoam)
584  {
585  VertexProgramData += "uniform mat4 uWorld;\n";
586  }
587  // IN
588  // OUT
589  VertexProgramData += Ogre::String(
590  "varying vec4 Position_;\n") +
591  "varying vec4 UVProjection;\n";
592  if(cFoam)
593  {
594  VertexProgramData += "varying vec4 WorldPosition;\n";
595  }
596  // PROGRAM
597  VertexProgramData +=Ogre::String(
598  "void main()\n") +
599  "{\n" +
600  "Position_ = gl_Vertex;\n";
601  if(cFoam)
602  {
603  VertexProgramData += "WorldPosition = uWorld * gl_Vertex;\n";
604  }
605  VertexProgramData += Ogre::String(
606  "gl_Position = ftransform();\n") +
607  "mat4 scalemat = mat4( 1.0, 0.0, 0.0, 0.0,\n" +
608  " 0.0, -1.0, 0.0, 0.0,\n" +
609  " 0.0, 0.0, 1.0, 0.0,\n" +
610  " 0.0, 0.0, 0.0, 1.0);\n" +
611  "UVProjection = scalemat * gl_Position;\n" +
612  "}\n";
613  }
614  break;
615  }
616  }
617  break;
618  }
619 
620 
621  // Fragment program
622 
623  switch (Options.NM)
624  {
625  case NM_TEXTURE: case NM_VERTEX: case NM_RTT:
626  {
627  switch (Options.SM)
628  {
629  case SM_HLSL: case SM_CG:
630  {
631  FragmentProgramData +=
632  Ogre::String("float3 expand(float3 v)\n") +
633  "{\n" +
634  "return (v - 0.5) * 2;\n" +
635  "}\n\n" +
636 
637  "void main_fp(" +
638  // IN
639  "float4 iPosition : TEXCOORD0,\n";
640  int TEXCOORDNUM = 1;
641  if (Options.NM == NM_TEXTURE)
642  {
643  FragmentProgramData +=
644  "float2 iUvNoise : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
645  TEXCOORDNUM++;
646  }
647  FragmentProgramData +=
648  "float4 iUvProjection : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
649  TEXCOORDNUM++;
650  if (Options.NM == NM_VERTEX)
651  {
652  FragmentProgramData +=
653  "float4 iNormal : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
654  TEXCOORDNUM++;
655  }
656  if (cFoam)
657  {
658  FragmentProgramData +=
659  "float4 iWorldPosition : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
660  }
661  FragmentProgramData +=
662  Ogre::String(
663  // OUT
664  "out float4 oColor : COLOR,\n") +
665  // UNIFORM
666  "uniform float3 uEyePosition,\n" +
667  "uniform float uFullReflectionDistance,\n" +
668  "uniform float uGlobalTransparency,\n" +
669  "uniform float uNormalDistortion,\n";
670 
671  if (cDepth)
672  {
673  FragmentProgramData +=
674  "uniform float3 uWaterColor,\n";
675  }
676  if (cSmooth)
677  {
678  FragmentProgramData +=
679  "uniform float uSmoothPower,\n";
680  }
681  if (cSun)
682  {
683  FragmentProgramData += Ogre::String(
684  "uniform float3 uSunPosition,\n") +
685  "uniform float uSunStrength,\n" +
686  "uniform float uSunArea,\n" +
687  "uniform float3 uSunColor,\n";
688  }
689  if (cFoam)
690  {
691  FragmentProgramData += Ogre::String(
692  "uniform float uFoamRange,\n") +
693  "uniform float uFoamMaxDistance,\n" +
694  "uniform float uFoamScale,\n" +
695  "uniform float uFoamStart,\n" +
696  "uniform float uFoamTransparency,\n";
697  }
698  if (cCaustics)
699  {
700  FragmentProgramData +=
701  "uniform float uCausticsPower,\n";
702  }
703 
704  int TexNum = 0;
705 
706  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
707  {
708  FragmentProgramData +=
709  "uniform sampler2D uNormalMap : register(s" + Ogre::StringConverter::toString(TexNum) + "),\n";
710  TexNum++;
711  }
712 
713  FragmentProgramData +=
714  Ogre::String(
715  "uniform sampler2D uReflectionMap : register(s" + Ogre::StringConverter::toString(TexNum) + "),\n") +
716  "uniform sampler2D uRefractionMap : register(s" + Ogre::StringConverter::toString(TexNum+1) + "),\n";
717 
718  TexNum += 2;
719 
720  if (cDepth)
721  {
722  FragmentProgramData +=
723  "uniform sampler2D uDepthMap : register(s" + Ogre::StringConverter::toString(TexNum) + "),\n";
724  TexNum++;
725  }
726 
727  FragmentProgramData +=
728  #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
729  "uniform sampler1D uFresnelMap : register(s" + Ogre::StringConverter::toString(TexNum) + ")";
730  #else
731  "uniform sampler2D uFresnelMap : register(s" + Ogre::StringConverter::toString(TexNum) + ")";
732  #endif
733  TexNum++;
734 
735  if (cFoam)
736  {
737  FragmentProgramData += Ogre::String(
738  ",\nuniform sampler2D uFoamMap : register(s" + Ogre::StringConverter::toString(TexNum) + ")\n");
739  }
740 
741  FragmentProgramData +=
742  Ogre::String( ")\n") +
743  "{\n" +
744  "float2 ProjectionCoord = iUvProjection.xy / iUvProjection.w;\n" +
745  "float3 camToSurface = iPosition.xyz - uEyePosition;\n" +
746  "float additionalReflection=camToSurface.x*camToSurface.x+camToSurface.z*camToSurface.z;\n";
747 
748  if (cFoam)
749  {
750  // Calculate the foam visibility as a function fo distance specified by user
751  FragmentProgramData +=
752  "float foamVisibility=1.0f-saturate(additionalReflection/uFoamMaxDistance);\n";
753  }
754 
755  FragmentProgramData +=
756  Ogre::String(
757  "additionalReflection/=uFullReflectionDistance;\n") +
758  "camToSurface=normalize(-camToSurface);\n";
759  if (Options.NM == NM_TEXTURE)
760  {
761  FragmentProgramData += Ogre::String(
762  "float3 pixelNormal = tex2D(uNormalMap,iUvNoise);\n") +
763  // Inverte y with z, because at creation our local normal to the plane was z
764  "pixelNormal.yz=pixelNormal.zy;\n" +
765  // Remap from [0,1] to [-1,1]
766  "pixelNormal.xyz=expand(pixelNormal.xyz);\n";
767  }
768  else if (Options.NM == NM_VERTEX)
769  {
770  FragmentProgramData +=
771  "float3 pixelNormal = iNormal;\n";
772  }
773  else // NM_RTT
774  {
775  FragmentProgramData +=
776  "float3 pixelNormal = 2.0*tex2D(uNormalMap, ProjectionCoord.xy) - 1.0;\n";
777  }
778  FragmentProgramData +=
779  "float2 pixelNormalModified = uNormalDistortion*pixelNormal.zx;\n";
780  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
781  {
782  FragmentProgramData +=
783  "float dotProduct=dot(camToSurface,pixelNormal);\n";
784  }
785  else
786  {
787  FragmentProgramData +=
788  "float dotProduct=dot(-camToSurface,pixelNormal);\n";
789  }
790  FragmentProgramData +=
791  Ogre::String(
792  "dotProduct=saturate(dotProduct);\n") +
793  #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
794  "float fresnel = tex1D(uFresnelMap,dotProduct);\n" +
795  #else
796  "float fresnel = tex2D(uFresnelMap,float2(dotProduct,dotProduct));\n" +
797  #endif
798  // Add additional reflection and saturate
799  "fresnel+=additionalReflection;\n" +
800  "fresnel=saturate(fresnel);\n" +
801  // Decrease the transparency and saturate
802  "fresnel-=uGlobalTransparency;\n" +
803  "fresnel=saturate(fresnel);\n" +
804  #if OGRE_PLATFORM != OGRE_PLATFORM_WIN32
805  // Reversing projection if underwater
806  "if(uEyePosition.y < 0.0)\n" +
807  "{\n" +
808  "ProjectionCoord.y = 1.0 - ProjectionCoord.y;\n" +
809  "}\n" +
810  #endif
811  // Get the reflection/refraction pixels. Make sure to disturb the texcoords by pixelnormal
812  "float3 reflection=tex2D(uReflectionMap,ProjectionCoord.xy+pixelNormalModified);\n" +
813  "float3 refraction=tex2D(uRefractionMap,ProjectionCoord.xy-pixelNormalModified);\n";
814 
815  if (cDepth)
816  {
817  if (cCaustics)
818  {
819  FragmentProgramData += Ogre::String(
820  "float2 depth = tex2D(uDepthMap,ProjectionCoord.xy-pixelNormalModified).rg;\n") +
821  "refraction *= 1+depth.y*uCausticsPower;\n" +
822  "refraction = lerp(uWaterColor,refraction,depth.x);\n";
823  }
824  else
825  {
826  FragmentProgramData += Ogre::String(
827  "float depth = tex2D(uDepthMap,ProjectionCoord.xy-pixelNormalModified).r;\n") +
828  "refraction = lerp(uWaterColor,refraction,depth);\n";
829  }
830  }
831 
832  FragmentProgramData +=
833  "oColor = float4(lerp(refraction,reflection,fresnel),1);\n";
834 
835  if (cSun)
836  {
837  FragmentProgramData += Ogre::String(
838  "float3 relfectedVector = normalize(reflect(-camToSurface,pixelNormal.xyz));\n") +
839  "float3 surfaceToSun=normalize(uSunPosition-iPosition.xyz);\n" +
840  "float3 sunlight = uSunStrength*pow(saturate(dot(relfectedVector,surfaceToSun)),uSunArea)*uSunColor;\n" +
841  "oColor.xyz+=sunlight;\n";
842  }
843 
844  if (cFoam)
845  {
846  FragmentProgramData += Ogre::String(
847  "float hmap = iPosition.y/uFoamRange*foamVisibility;\n") +
848  "float2 foamTex=iWorldPosition.xz*uFoamScale+pixelNormalModified;\n" +
849  "float foam=tex2D(uFoamMap,foamTex).r;\n" +
850  "float foamTransparency=saturate(hmap-uFoamStart)*uFoamTransparency;\n" +
851  "oColor.xyz=lerp(oColor.xyz,1,foamTransparency*foam);\n";
852  }
853 
854  if (cSmooth)
855  {
856  FragmentProgramData +=
857  "oColor.xyz = lerp(tex2D(uRefractionMap,ProjectionCoord.xy).xyz,oColor.xyz,saturate((1-tex2D(uDepthMap,ProjectionCoord.xy).r)*uSmoothPower));\n";
858  }
859 
860  FragmentProgramData +=
861  "}\n";
862  }
863  break;
864 
865  case SM_GLSL:
866  FragmentProgramData += Ogre::String("\n") +
867  // UNIFORMS
868  "uniform vec3 uEyePosition;\n" +
869  "uniform float uFullReflectionDistance;\n" +
870  "uniform float uGlobalTransparency;\n" +
871  "uniform float uNormalDistortion;\n" +
872  "uniform vec3 uWaterColor;\n";
873 
874  if (cSmooth)
875  {
876  FragmentProgramData +=
877  "uniform float uSmoothPower;\n";
878  }
879  if (cSun)
880  {
881  FragmentProgramData += Ogre::String(
882  "uniform vec3 uSunPosition;\n") +
883  "uniform float uSunStrength;\n" +
884  "uniform float uSunArea;\n" +
885  "uniform vec3 uSunColor;\n";
886  }
887  if (cFoam)
888  {
889  FragmentProgramData += Ogre::String(
890  "uniform float uFoamRange;\n") +
891  "uniform float uFoamMaxDistance;\n" +
892  "uniform float uFoamScale;\n" +
893  "uniform float uFoamStart;\n" +
894  "uniform float uFoamTransparency;\n";
895  }
896  if (cCaustics)
897  {
898  FragmentProgramData +=
899  "uniform float uCausticsPower;\n";
900  }
901 
902  int TexNum = 0;
903  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
904  {
905  FragmentProgramData +=
906  "uniform sampler2D uNormalMap;\n";
907  TexNum++;
908  }
909 
910  FragmentProgramData += Ogre::String(
911  "uniform sampler2D uReflectionMap;\n") +
912  "uniform sampler2D uRefractionMap;\n";
913  TexNum += 2;
914 
915  if (cDepth)
916  {
917  FragmentProgramData +=
918  "uniform sampler2D uDepthMap;\n";
919  TexNum++;
920  }
921 
922  FragmentProgramData +=
923  #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
924  "uniform sampler1D uFresnelMap;\n";
925  #else
926  "uniform sampler2D uFresnelMap;\n";
927  #endif
928  TexNum++;
929 
930  if (cFoam)
931  {
932  FragmentProgramData +=
933  "uniform sampler2D uFoamMap;\n";
934  }
935  // IN
936  FragmentProgramData +=
937  "varying vec4 Position_;\n";
938  int TEXCOORDNUM = 1;
939  if (Options.NM == NM_TEXTURE)
940  {
941  TEXCOORDNUM++;
942  }
943  FragmentProgramData +=
944  "varying vec4 UVProjection;\n";
945  TEXCOORDNUM++;
946  if (Options.NM == NM_VERTEX)
947  {
948  FragmentProgramData +=
949  "varying vec3 Normal;\n";
950  TEXCOORDNUM++;
951  }
952  if (cFoam)
953  {
954  FragmentProgramData +=
955  "varying vec4 WorldPosition;\n";
956  }
957  // Expand function
958  FragmentProgramData += Ogre::String(
959  "vec3 expand(vec3 v)\n") +
960  "{\n" +
961  "return (v - 0.5) * 2.0;\n" +
962  "}\n\n" +
963  // main function
964  "void main()\n" +
965  "{\n" +
966  "vec2 ProjectionCoord = UVProjection.xy / UVProjection.w;\n" +
967  "ProjectionCoord += 1.0;\n" +
968  "ProjectionCoord *= 0.5;\n" +
969  "vec3 camToSurface = Position_.xyz - uEyePosition;\n" +
970  "float additionalReflection=camToSurface.x*camToSurface.x+camToSurface.z*camToSurface.z;\n";
971  if (cFoam)
972  {
973  // Calculate the foam visibility as a function fo distance specified by user
974  FragmentProgramData +=
975  "float foamVisibility=1.0-clamp(additionalReflection/uFoamMaxDistance, 0.0, 1.0);\n";
976  }
977  FragmentProgramData += Ogre::String(
978  "additionalReflection/=uFullReflectionDistance;\n") +
979  "camToSurface=normalize(-camToSurface);\n";
980  if (Options.NM == NM_TEXTURE)
981  {
982  FragmentProgramData += Ogre::String(
983  "vec3 pixelNormal = texture2D(uNormalMap,gl_TexCoord[0].xy).xyz;\n") +
984  // Inverte y with z, because at creation our local normal to the plane was z
985  "pixelNormal.yz=pixelNormal.zy;\n" +
986  // Remap from [0,1] to [-1,1]
987  "pixelNormal.xyz=expand(pixelNormal.xyz);\n";
988  }
989  else if (Options.NM == NM_VERTEX)
990  {
991  FragmentProgramData +=
992  "vec3 pixelNormal = Normal;\n";
993  }
994  else // NM_RTT
995  {
996  FragmentProgramData +=
997  "vec3 pixelNormal = 2.0*texture2D(uNormalMap, ProjectionCoord.xy).xyz - 1.0;\n";
998  }
999  FragmentProgramData +=
1000  "vec2 pixelNormalModified = uNormalDistortion*pixelNormal.zx;\n";
1001  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
1002  {
1003  FragmentProgramData +=
1004  "float dotProduct=dot(camToSurface,pixelNormal);\n";
1005  }
1006  else
1007  {
1008  FragmentProgramData +=
1009  "float dotProduct=dot(-camToSurface,pixelNormal);\n";
1010  }
1011  FragmentProgramData += Ogre::String(
1012  "dotProduct=clamp(dotProduct, 0.0, 1.0);\n") +
1013  #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
1014  "float fresnel = texture1D(uFresnelMap,dotProduct).x;\n" +
1015  #else
1016  "float fresnel = texture2D(uFresnelMap,vec2(dotProduct,dotProduct)).x;\n" +
1017  #endif
1018  // Add additional reflection and saturate
1019  "fresnel +=additionalReflection;\n" +
1020  "fresnel = clamp(fresnel, 0.0, 1.0);\n" +
1021  // Decrease the transparency and saturate
1022  "fresnel -= uGlobalTransparency;\n" +
1023  "fresnel = clamp(fresnel*fresnel, 0.0, 1.0);\n" +
1024  // Get the reflection/refraction pixels. Make sure to disturb the texcoords by pixelnormal
1025  "vec3 reflection=texture2D(uReflectionMap,ProjectionCoord.xy+pixelNormalModified).xyz;\n" +
1026  "vec3 refraction=texture2D(uRefractionMap,ProjectionCoord.xy-pixelNormalModified).xyz;\n";
1027  if (cDepth)
1028  {
1029  if (cCaustics)
1030  {
1031  FragmentProgramData += Ogre::String(
1032  "vec2 depth = texture2D(uDepthMap,ProjectionCoord.xy-pixelNormalModified).xy;\n") +
1033  "refraction *= 1.0 + depth.y*uCausticsPower;\n" +
1034  "refraction = mix(uWaterColor,refraction,depth.x);\n";
1035  }
1036  else
1037  {
1038  FragmentProgramData += Ogre::String(
1039  "float depth = texture2D(uDepthMap,ProjectionCoord.xy-pixelNormalModified).x;\n") +
1040  "refraction = mix(uWaterColor,refraction,depth);\n";
1041  }
1042  }
1043  FragmentProgramData += Ogre::String(
1044  "gl_FragColor = vec4(mix(refraction,reflection,fresnel),1.0);\n") +
1045  "gl_FragColor.xyz = mix(gl_FragColor.xyz, uWaterColor, uGlobalTransparency);\n";
1046  if (cSun)
1047  {
1048  FragmentProgramData += Ogre::String(
1049  "vec3 relfectedVector = normalize(reflect(-camToSurface,pixelNormal.xyz));\n") +
1050  "vec3 surfaceToSun=normalize(uSunPosition-Position_.xyz);\n" +
1051  "vec3 sunlight = uSunStrength*pow(clamp(dot(relfectedVector,surfaceToSun),0.0,1.0),uSunArea)*uSunColor;\n" +
1052  "gl_FragColor.xyz+=sunlight;\n";
1053  }
1054  if (cFoam)
1055  {
1056  FragmentProgramData += Ogre::String(
1057  "float hmap = Position_.y/uFoamRange*foamVisibility;\n") +
1058  "vec2 foamTex=WorldPosition.xz*uFoamScale+pixelNormalModified;\n" +
1059  "float foam=texture2D(uFoamMap,foamTex).x;\n" +
1060  "float foamTransparency=clamp(hmap-uFoamStart, 0.0, 1.0)*uFoamTransparency;\n" +
1061  "gl_FragColor.xyz=mix(gl_FragColor.xyz,vec3(1.0,1.0,1.0),foamTransparency*foam);\n";
1062  }
1063  if (cSmooth)
1064  {
1065  FragmentProgramData +=
1066  "gl_FragColor.xyz = mix(texture2D(uRefractionMap,ProjectionCoord.xy).xyz,gl_FragColor.xyz,clamp((1.0-texture2D(uDepthMap,ProjectionCoord.xy).x)*uSmoothPower, 0.0, 1.0));\n";
1067  }
1068  FragmentProgramData +=
1069  "}\n";
1070  break;
1071  }
1072  }
1073  break;
1074  }
1075 
1076  // Build our material
1077  Ogre::MaterialPtr &WaterMaterial = getMaterial(MAT_WATER);
1078  WaterMaterial = Ogre::MaterialManager::getSingleton().
1079  create(_def_Water_Material_Name,
1080  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
1081 
1082  Ogre::Pass *WM_Technique0_Pass0 = WaterMaterial->getTechnique(0)->getPass(0);
1083 
1084  WM_Technique0_Pass0->setCullingMode(Ogre::CULL_NONE);
1085  WM_Technique0_Pass0->setDepthWriteEnabled(true);
1086 
1087  Ogre::String GpuProgramsData[2] = {VertexProgramData, FragmentProgramData};
1088  Ogre::String GpuProgramNames[2] = {_def_Water_Shader_VP_Name, _def_Water_Shader_FP_Name};
1089  Ogre::String EntryPoints[2];
1090  if(Options.SM == SM_GLSL)
1091  {
1092  EntryPoints[0] = Ogre::String("main");
1093  EntryPoints[1] = Ogre::String("main");
1094  }
1095  else
1096  {
1097  EntryPoints[0] = Ogre::String("main_vp");
1098  EntryPoints[1] = Ogre::String("main_fp");
1099  }
1100 
1101  fillGpuProgramsToPass(WM_Technique0_Pass0, GpuProgramNames, Options.SM, EntryPoints, GpuProgramsData);
1102 
1103  Ogre::GpuProgramParametersSharedPtr VP_Parameters = WM_Technique0_Pass0->getVertexProgramParameters();
1104  Ogre::GpuProgramParametersSharedPtr FP_Parameters = WM_Technique0_Pass0->getFragmentProgramParameters();
1105 
1106  if(Options.SM != SM_GLSL)
1107  {
1108  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
1109  }
1110  if (cFoam)
1111  {
1112  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
1113  }
1114  FP_Parameters->setNamedAutoConstant("uEyePosition", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
1115 
1116  FP_Parameters->setNamedConstant("uFullReflectionDistance", mHydrax->getFullReflectionDistance());
1117  FP_Parameters->setNamedConstant("uGlobalTransparency", mHydrax->getGlobalTransparency());
1118  FP_Parameters->setNamedConstant("uNormalDistortion", mHydrax->getNormalDistortion());
1119 
1120  FP_Parameters->setNamedConstant("uWaterColor", mHydrax->getWaterColor());
1121  if (cSmooth)
1122  {
1123  FP_Parameters->setNamedConstant("uSmoothPower", mHydrax->getSmoothPower());
1124  }
1125  if (cSun)
1126  {
1127  FP_Parameters->setNamedConstant("uSunPosition", mHydrax->getMesh()->getObjectSpacePosition(mHydrax->getSunPosition()));
1128  FP_Parameters->setNamedConstant("uSunStrength", mHydrax->getSunStrength());
1129  FP_Parameters->setNamedConstant("uSunArea", mHydrax->getSunArea());
1130  FP_Parameters->setNamedConstant("uSunColor", mHydrax->getSunColor());
1131  }
1132  if (cFoam)
1133  {
1134  FP_Parameters->setNamedConstant("uFoamRange", mHydrax->getMesh()->getOptions().MeshStrength);
1135  FP_Parameters->setNamedConstant("uFoamMaxDistance", mHydrax->getFoamMaxDistance());
1136  FP_Parameters->setNamedConstant("uFoamScale", mHydrax->getFoamScale());
1137  FP_Parameters->setNamedConstant("uFoamStart", mHydrax->getFoamStart());
1138  FP_Parameters->setNamedConstant("uFoamTransparency", mHydrax->getFoamTransparency());
1139  }
1140  if (cCaustics)
1141  {
1142  FP_Parameters->setNamedConstant("uCausticsPower", mHydrax->getCausticsPower());
1143  }
1144 
1145  int GLSLTextUnit = 0;
1146  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
1147  {
1148  if(Options.SM == SM_GLSL)
1149  {
1150  FP_Parameters->setNamedConstant("uNormalMap", GLSLTextUnit);
1151  GLSLTextUnit++;
1152  }
1153  WM_Technique0_Pass0->createTextureUnitState("HydraxNormalMap")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
1154  }
1155 
1156  if(Options.SM == SM_GLSL)
1157  {
1158  FP_Parameters->setNamedConstant("uReflectionMap", GLSLTextUnit);
1159  GLSLTextUnit++;
1160  }
1161  WM_Technique0_Pass0->createTextureUnitState("HydraxReflectionMap")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
1162  if(Options.SM == SM_GLSL)
1163  {
1164  FP_Parameters->setNamedConstant("uRefractionMap", GLSLTextUnit);
1165  GLSLTextUnit++;
1166  }
1167  WM_Technique0_Pass0->createTextureUnitState("HydraxRefractionMap")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
1168 
1169  if (cDepth)
1170  {
1171  if(Options.SM == SM_GLSL)
1172  {
1173  FP_Parameters->setNamedConstant("uDepthMap", GLSLTextUnit);
1174  GLSLTextUnit++;
1175  }
1176  WM_Technique0_Pass0->createTextureUnitState("HydraxDepthMap")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
1177  }
1178 
1179  if(Options.SM == SM_GLSL)
1180  {
1181  FP_Parameters->setNamedConstant("uFresnelMap", GLSLTextUnit);
1182  GLSLTextUnit++;
1183  }
1184  WM_Technique0_Pass0->createTextureUnitState("Fresnel.bmp")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
1185 
1186  if (cFoam)
1187  {
1188  if(Options.SM == SM_GLSL)
1189  {
1190  FP_Parameters->setNamedConstant("uFoamMap", GLSLTextUnit);
1191  GLSLTextUnit++;
1192  }
1193  WM_Technique0_Pass0->createTextureUnitState("Foam.png")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
1194  }
1195 
1196  WaterMaterial->setReceiveShadows(false);
1197  WaterMaterial->load();
1198 
1199  return true;
1200  }
1201 
1203  {
1204  const bool cCaustics = _isComponent(Components, HYDRAX_COMPONENT_CAUSTICS);
1205 
1206  Ogre::String VertexProgramData, FragmentProgramData;
1207 
1208  // Vertex program
1209 
1210  switch (Options.SM)
1211  {
1212  case SM_HLSL: case SM_CG:
1213  {
1214  // No caustics
1215  if (!cCaustics)
1216  {
1217  VertexProgramData +=
1218  Ogre::String(
1219  "void main_vp(\n") +
1220  // IN
1221  "float4 iPosition : POSITION,\n" +
1222  // OUT
1223  "out float4 oPosition : POSITION,\n" +
1224  "out float oPosition_ : TEXCOORD0,\n" +
1225  "out float2 oDistance : TEXCOORD1,\n" +
1226  // UNIFORM
1227  "uniform float uPlaneYPos,\n" +
1228  "uniform float uPlanesError,\n" +
1229  "uniform float3 uCameraPos,\n" +
1230  "uniform float4x4 uWorld,\n" +
1231  "uniform float4x4 uWorldView,\n" +
1232  "uniform float4x4 uWorldViewProj)\n" +
1233  "{\n" +
1234  "oPosition = mul(uWorldViewProj, iPosition);\n" +
1235  "float3 wPos = mul(uWorld, iPosition).xyz;\n" +
1236  "float3 wCam = uCameraPos;\n" +
1237  "wPos.y -= uPlaneYPos;\n" +
1238  "wCam.y -= uPlaneYPos;\n" +
1239  "oPosition_ = wPos.y;\n" +
1240  // Distance
1241  "oDistance.x = distance(wPos, wCam);\n" +
1242  "oDistance.y = 1.0;\n" +
1243  // If exist water plane between points, occlusion effect must be changed.
1244  "if(wCam.y > 0.0) {\n" +
1245  "oDistance.x *= 1.0 - wCam.y/(wCam.y + abs(wPos.y));\n" +
1246  "}\n" +
1247  "if(wPos.y > uPlanesError) {\n" +
1248  "oDistance.x *= abs(wCam.y)/(abs(wCam.y) + wPos.y);\n" +
1249  "oDistance.y = 0.0;\n" +
1250  "}\n" +
1251  "}\n";
1252  }
1253  else // Caustics
1254  {
1255  VertexProgramData +=
1256  Ogre::String(
1257  "void main_vp(\n") +
1258  // IN
1259  "float4 iPosition : POSITION,\n" +
1260  // OUT
1261  "out float4 oPosition : POSITION,\n" +
1262  "out float oPosition_ : TEXCOORD0,\n" +
1263  "out float2 oDistance : TEXCOORD1,\n" +
1264  "out float2 oUvWorld : TEXCOORD2,\n" +
1265  // UNIFORM
1266  "uniform float uPlaneYPos,\n" +
1267  "uniform float uPlanesError,\n" +
1268  "uniform float3 uCameraPos,\n" +
1269  "uniform float4x4 uWorld,\n" +
1270  "uniform float4x4 uWorldViewProj)\n" +
1271  "{\n" +
1272  "oPosition = mul(uWorldViewProj, iPosition);\n" +
1273  "float3 wPos = mul(uWorld, iPosition).xyz;\n" +
1274  "float3 wCam = uCameraPos;\n" +
1275  "wPos.y -= uPlaneYPos;\n" +
1276  "wCam.y -= uPlaneYPos;\n" +
1277  "oPosition_ = wPos.y;\n" +
1278  // Distance
1279  "oDistance.x = distance(wPos, wCam);\n" +
1280  "oDistance.y = 1.0;\n" +
1281  // If exist water plane between points, occlusion effect must be changed.
1282  "if(wCam.y > 0.0) {\n" +
1283  "oDistance.x *= 1.0 - wCam.y/(wCam.y + abs(wPos.y));\n" +
1284  "}\n" +
1285  "if(wPos.y > uPlanesError) {\n" +
1286  "oDistance.x *= abs(wCam.y)/(abs(wCam.y) + wPos.y);\n" +
1287  "oDistance.y = 0.0;\n" +
1288  "}\n" +
1289  "oUvWorld = wPos.xz;\n" +
1290  "}\n";
1291  }
1292  }
1293  break;
1294 
1295  case SM_GLSL:
1296  // No caustics
1297  if (!cCaustics)
1298  {
1299  VertexProgramData += Ogre::String( "\n" ) +
1300  // UNIFORMS
1301  "uniform float uPlaneYPos;\n" +
1302  "uniform float uPlanesError;\n" +
1303  "uniform mat4 uWorld;\n" +
1304  // IN
1305  // OUT
1306  "varying float Position_;\n" +
1307  "varying vec2 Distance_;\n" +
1308  // main function
1309  "void main()\n" +
1310  "{\n" +
1311  // Point and camera position
1312  "vec3 wPos = ( uWorld * gl_Vertex ).xyz;\n" +
1313  "vec3 wCam = ( uWorld * gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0) ).xyz;\n" +
1314  "wPos.y -= uPlaneYPos;\n" +
1315  "wCam.y -= uPlaneYPos;\n" +
1316  "Position_ = wPos.y;\n" +
1317  // Distance
1318  "vec4 mwPos = gl_ModelViewMatrix * gl_Vertex;\n" +
1319  "Distance_.x = abs(mwPos.z);\n" +
1320  "Distance_.y = 1.0;\n" +
1321  // If exist water plane between points, occlusion effect must be changed.
1322  "if(wCam.y > 0.0) {\n" +
1323  "Distance_.x *= 1.0 - wCam.y/(wCam.y + abs(wPos.y));\n" +
1324  "}\n" +
1325  "if(wPos.y > uPlanesError) {\n" +
1326  "Distance_.x *= abs(wCam.y)/(abs(wCam.y) + wPos.y);\n" +
1327  "Distance_.y = 0.0;\n" +
1328  "}\n" +
1329  "}\n";
1330  }
1331  else // Caustics
1332  {
1333  VertexProgramData += Ogre::String( "\n" ) +
1334  // UNIFORMS
1335  "uniform float uPlaneYPos;\n" +
1336  "uniform float uPlanesError;\n" +
1337  "uniform mat4 uWorld;\n" +
1338  // IN
1339  // OUT
1340  "varying float Position_;\n" +
1341  "varying vec2 Distance_;\n" +
1342  "varying vec2 UVWorld;\n" +
1343  // main function
1344  "void main()\n" +
1345  "{\n" +
1346  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" +
1347  // Point and camera position
1348  "vec3 wPos = ( uWorld * gl_Vertex ).xyz;\n" +
1349  "vec3 wCam = ( uWorld * gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0) ).xyz;\n" +
1350  "wPos.y -= uPlaneYPos;\n" +
1351  "wCam.y -= uPlaneYPos;\n" +
1352  "Position_ = wPos.y;\n" +
1353  // Distance
1354  "vec4 mwPos = gl_ModelViewMatrix * gl_Vertex;\n" +
1355  "Distance_.x = abs(mwPos.z);\n" +
1356  "Distance_.y = 1.0;\n" +
1357  // If exist water plane between points, occlusion effect must be changed.
1358  "if(wCam.y > 0.0) {\n" +
1359  "Distance_.x *= 1.0 - wCam.y/(wCam.y + abs(wPos.y));\n" +
1360  "}\n" +
1361  "if(wPos.y > uPlanesError) {\n" +
1362  /*
1363  "vec3 wFocus = ( uWorld * gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.1, 1.0) ).xyz;\n" +
1364  "vec3 CamToFreeSurface = wFocus - wCam;\n" +
1365  "CamToFreeSurface *= wCam.y / CamToFreeSurface.y;\n" +
1366  "Distance_.x = length(CamToFreeSurface);\n" +
1367  */
1368  "Distance_.x *= abs(wCam.y)/(abs(wCam.y) + wPos.y);\n" +
1369  "Distance_.y = 0.0;\n" +
1370  "}\n" +
1371  "UVWorld = wPos.xz;\n" +
1372  "}\n";
1373  }
1374  break;
1375  }
1376 
1377  // Fragment program
1378  switch (Options.SM)
1379  {
1380  case SM_HLSL: case SM_CG:
1381  {
1382  // No caustics
1383  if (!cCaustics)
1384  {
1385  FragmentProgramData +=
1386  Ogre::String(
1387  "void main_fp(\n") +
1388  // IN
1389  "float iPosition : TEXCOORD0,\n" +
1390  "float2 iDistance : TEXCOORD1,\n" +
1391  // OUT
1392  "out float4 oColor : COLOR,\n" +
1393  // UNIFORM
1394  "uniform float uDepthLimit,\n" +
1395  "uniform float uDistLimit)\n" +
1396  "{\n" +
1397  "float pixelYDepth = saturate(iPosition*uDepthLimit + 1.0);\n" +
1398  "float pixelDepth = saturate(1.0 - iDistance.x*uDistLimit);\n" +
1399  "pixelDepth = min(pixelYDepth, pixelDepth);\n" +
1400  "oColor = float4(pixelDepth,0,0,0);\n" +
1401  "}\n";
1402  }
1403  else // Caustics
1404  {
1405  FragmentProgramData +=
1406  Ogre::String(
1407  "void main_fp(\n") +
1408  // IN
1409  "float iPosition : TEXCOORD0,\n" +
1410  "float2 iDistance : TEXCOORD1,\n" +
1411  "float2 iUvWorld : TEXCOORD2,\n" +
1412  // OUT
1413  "out float4 oColor : COLOR,\n" +
1414  // UNIFORM
1415  "uniform float uDepthLimit,\n" +
1416  "uniform float uDistLimit,\n" +
1417  "uniform float uCausticsScale,\n" +
1418  "uniform float uCausticsEnd,\n" +
1419  "uniform sampler2D uCaustics : register(s0))\n" +
1420  "{\n" +
1421  "float pixelYDepth = saturate(iPosition*uDepthLimit + 1.0);\n" +
1422  // "float pixelDepth = saturate(1.0 - iDistance.x*uDistLimit);\n" +
1423  "float pixelDepth = saturate(1.0 - iDistance.x*uDistLimit);\n" +
1424  "pixelDepth = min(pixelYDepth, pixelDepth);\n" +
1425  "oColor = float4(pixelDepth,0.0,0.0,0.0);\n" +
1426  "oColor.g = iDistance.y*saturate((pixelYDepth-uCausticsEnd)/(1.0-uCausticsEnd))*tex2D(uCaustics, iUvWorld/uCausticsScale).x;\n" +
1427  "}\n";
1428  }
1429  }
1430  break;
1431 
1432  case SM_GLSL:
1433  // No caustics
1434  if (!cCaustics)
1435  {
1436  FragmentProgramData += Ogre::String( "\n" ) +
1437  // UNIFORMS
1438  "uniform float uDepthLimit;\n" +
1439  "uniform float uDistLimit;\n" +
1440  // IN
1441  "varying float Position_;\n" +
1442  "varying float Distance_;\n" +
1443  // OUT
1444  // main function
1445  "void main()" +
1446  "{\n" +
1447  "float pixelYDepth = clamp(1.0 + Position_*uDepthLimit, 0.0, 1.0);\n" +
1448  "float pixelDepth = clamp(1.0 - Distance_.x*uDistLimit, 0.0, 1.0);\n" +
1449  "pixelDepth = min(pixelYDepth,pixelDepth);\n" +
1450  "gl_FragColor = vec4(pixelDepth,0.0,0.0,1.0);\n" +
1451  "}\n";
1452  }
1453  else // Caustics
1454  {
1455  FragmentProgramData += Ogre::String( "\n" ) +
1456  // UNIFORMS
1457  "uniform float uDepthLimit;\n" +
1458  "uniform float uDistLimit;\n" +
1459  "uniform float uCausticsScale;\n" +
1460  "uniform float uCausticsEnd;\n" +
1461  "uniform sampler2D uCaustics;\n" +
1462  // IN
1463  "varying float Position_;\n" +
1464  "varying vec2 Distance_;\n" +
1465  "varying vec2 UVWorld;\n" +
1466  // OUT
1467  // main function
1468  "void main()" +
1469  "{\n" +
1470  "float pixelYDepth = clamp(1.0 + Position_*uDepthLimit, 0.0, 1.0);\n" +
1471  "float pixelDepth = clamp(1.0 - Distance_.x*uDistLimit, 0.0, 1.0);\n" +
1472  "pixelDepth = min(pixelYDepth,pixelDepth);\n" +
1473  "gl_FragColor = vec4(pixelDepth,0.0,0.0,1.0);\n" +
1474  "gl_FragColor.y = Distance_.y*clamp((pixelYDepth-uCausticsEnd)/(1.0-uCausticsEnd), 0.0, 1.0)*texture2D(uCaustics, UVWorld/uCausticsScale).x;\n" +
1475  "}\n";
1476  }
1477  break;
1478  }
1479 
1480  // Build our material
1481  Ogre::MaterialPtr &DepthMaterial = getMaterial(MAT_DEPTH);
1482  DepthMaterial = Ogre::MaterialManager::getSingleton().
1483  create(_def_Depth_Material_Name,
1484  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
1485 
1486  DepthMaterial->getTechnique(0)->setSchemeName("HydraxDepth");
1487 
1488  Ogre::Pass *DM_Technique0_Pass0 = DepthMaterial->getTechnique(0)->getPass(0);
1489 
1490  Ogre::String GpuProgramsData[2] = {VertexProgramData, FragmentProgramData};
1491  Ogre::String GpuProgramNames[2] = {_def_Depth_Shader_VP_Name, _def_Depth_Shader_FP_Name};
1492  Ogre::String EntryPoints[2];
1493  if(Options.SM == SM_GLSL)
1494  {
1495  EntryPoints[0] = Ogre::String("main");
1496  EntryPoints[1] = Ogre::String("main");
1497  }
1498  else
1499  {
1500  EntryPoints[0] = Ogre::String("main_vp");
1501  EntryPoints[1] = Ogre::String("main_fp");
1502  }
1503 
1504  fillGpuProgramsToPass(DM_Technique0_Pass0, GpuProgramNames, Options.SM, EntryPoints, GpuProgramsData);
1505 
1506  Ogre::GpuProgramParametersSharedPtr VP_Parameters = DM_Technique0_Pass0->getVertexProgramParameters();
1507  Ogre::GpuProgramParametersSharedPtr FP_Parameters = DM_Technique0_Pass0->getFragmentProgramParameters();
1508 
1509  if(Options.SM != SM_GLSL)
1510  {
1511  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
1512  // VP_Parameters->setNamedAutoConstant("uWorldView", Ogre::GpuProgramParameters::ACT_WORLDVIEW_MATRIX);
1513  VP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION);
1514  }
1515  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
1516  VP_Parameters->setNamedConstant("uPlaneYPos", mHydrax->getPosition().y);
1517  VP_Parameters->setNamedConstant("uPlanesError", (float) mHydrax->getPlanesError());
1518 
1519  FP_Parameters->setNamedConstant("uDepthLimit", 1.f/mHydrax->getDepthLimit());
1520  FP_Parameters->setNamedConstant("uDistLimit", 1.f/mHydrax->getDistLimit());
1521 
1522  if (cCaustics)
1523  {
1524  FP_Parameters->setNamedConstant("uCausticsScale", mHydrax->getCausticsScale());
1525  FP_Parameters->setNamedConstant("uCausticsEnd", 1.f - mHydrax->getCausticsEnd());
1526 
1527  if(Options.SM == SM_GLSL)
1528  {
1529  FP_Parameters->setNamedConstant("uCaustics", 0);
1530  }
1531  Ogre::TextureUnitState* TUS_Caustics = DM_Technique0_Pass0->createTextureUnitState("Caustics.bmp");
1532  TUS_Caustics->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
1533  // To account for variable sim. time, we must update animation manually.
1534  TUS_Caustics->setAnimatedTextureName("Caustics.bmp", 32);
1535  mCausticsAnimTexVec.push_back(TUS_Caustics);
1536  }
1537 
1538  DepthMaterial->setReceiveShadows(false);
1539  DepthMaterial->load();
1540 
1541  return true;
1542  }
1543 
1544  const float CAUSTICS_FRAME_DURATION = 1.5f / 32.f; // 1.5sec is the original hardcoded total duration.
1545  const unsigned int CAUSTICS_NUM_FRAMES = 32;
1546 
1548  {
1551  {
1552  // advance anim frame
1555  {
1557  }
1558  // update time
1560  }
1561 
1562  // Update frame on registered anims
1563  for (Ogre::TextureUnitState* tus : mCausticsAnimTexVec)
1564  {
1565  tus->setCurrentFrame(mCausticsAnimCurrentFrame);
1566  }
1567  }
1568 
1569  bool MaterialManager::_createDepthTextureGPUPrograms(const HydraxComponent &Components, const Options &Options, const Ogre::String& AlphaChannel)
1570  {
1571  const bool cCaustics = _isComponent(Components, HYDRAX_COMPONENT_CAUSTICS);
1572 
1573  Ogre::String VertexProgramData, FragmentProgramData;
1574 
1575  // Vertex program
1576 
1577  switch (Options.SM)
1578  {
1579  case SM_HLSL: case SM_CG:
1580  {
1581  // No caustics
1582  if (!cCaustics)
1583  {
1584  VertexProgramData +=
1585  Ogre::String(
1586  "void main_vp(\n") +
1587  // IN
1588  "float4 iPosition : POSITION,\n" +
1589  "float2 iUV : TEXCOORD0,\n" +
1590  // OUT
1591  "out float4 oPosition : POSITION,\n" +
1592  "out float3 oPosition_UV : TEXCOORD0,\n" +
1593  // UNIFORM
1594  "uniform float uPlaneYPos,\n" +
1595  "uniform float4x4 uWorld,\n" +
1596  "uniform float4x4 uWorldViewProj)\n" +
1597  "{\n" +
1598  "oPosition = mul(uWorldViewProj, iPosition);\n" +
1599  "oPosition_UV.x = mul(uWorld, iPosition).y;\n" +
1600  "oPosition_UV.x-=uPlaneYPos;\n" +
1601  "oPosition_UV.yz = iUV;\n" +
1602  "}\n";
1603  }
1604  else // Caustics
1605  {
1606  VertexProgramData +=
1607  Ogre::String(
1608  "void main_vp(\n") +
1609  // IN
1610  "float4 iPosition : POSITION,\n" +
1611  "float2 iUV : TEXCOORD0,\n" +
1612  // OUT
1613  "out float4 oPosition : POSITION,\n" +
1614  "out float3 oPosition_UV : TEXCOORD0,\n" +
1615  "out float2 oUvWorld : TEXCOORD1,\n" +
1616  // UNIFORM
1617  "uniform float uPlaneYPos,\n" +
1618  "uniform float4x4 uWorld,\n" +
1619  "uniform float4x4 uWorldViewProj)\n" +
1620  "{\n" +
1621  "oPosition = mul(uWorldViewProj, iPosition);\n" +
1622  "float3 wPos = mul(uWorld, iPosition);\n" +
1623  "oPosition_UV.x = wPos.y;\n" +
1624  "oPosition_UV.x-=uPlaneYPos;\n" +
1625  "oPosition_UV.yz = iUV;\n" +
1626  "oUvWorld = wPos.xz;\n" +
1627  "}\n";
1628  }
1629  }
1630  break;
1631 
1632  case SM_GLSL:
1633  // No caustics
1634  if (!cCaustics)
1635  {
1636  VertexProgramData += Ogre::String( "\n" ) +
1637  // UNIFORMS
1638  "uniform float uPlaneYPos;\n" +
1639  "uniform mat4 uWorld;\n" +
1640  // IN
1641  // OUT
1642  "varying vec3 Position_UV;\n" +
1643  // main function
1644  "void main()\n" +
1645  "{\n" +
1646  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" +
1647  "Position_UV.x = (uWorld * gl_Vertex).y;\n" +
1648  "Position_UV.x -= uPlaneYPos;\n" +
1649  "Position_UV.yz = gl_MultiTexCoord0;\n" +
1650  "}\n";
1651  }
1652  else // Caustics
1653  {
1654  VertexProgramData += Ogre::String( "\n" ) +
1655  // UNIFORMS
1656  "uniform float uPlaneYPos;\n" +
1657  "uniform mat4 uWorld;\n" +
1658  // IN
1659  // OUT
1660  "varying vec3 Position_UV;\n" +
1661  "varying vec2 UVWorld;\n" +
1662  // main function
1663  "void main()\n" +
1664  "{\n" +
1665  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" +
1666  "vec3 wPos = uWorld * iPosition;\n" +
1667  "Position_UV.x = wPos.y;\n" +
1668  "Position_UV.x -= uPlaneYPos;\n" +
1669  "Position_UV.yz = gl_MultiTexCoord0;\n" +
1670  "UVWorld = wPos.xz;\n" +
1671  "}\n";
1672  }
1673  break;
1674  }
1675 
1676  // Fragment program
1677 
1678  switch (Options.SM)
1679  {
1680  case SM_HLSL: case SM_CG:
1681  {
1682  // No caustics
1683  if (!cCaustics)
1684  {
1685  FragmentProgramData +=
1686  Ogre::String(
1687  "void main_fp(\n") +
1688  // IN
1689  "float3 iPosition_UV : TEXCOORD0,\n" +
1690  // OUT
1691  "out float4 oColor : COLOR,\n" +
1692  // UNIFORM
1693  "uniform float uDepthLimit,\n" +
1694  "uniform sampler2D uAlphaTex : register(s0))\n" +
1695  "{\n" +
1696  "float pixelYDepth = (iPosition_UV.x*uDepthLimit+1);\n" +
1697  "pixelYDepth = saturate(pixelYDepth);\n" +
1698  "oColor = float4(pixelYDepth,0,0,0);\n" +
1699  "oColor.a = tex2D(uAlphaTex, iPosition_UV.yz)."+AlphaChannel+";" +
1700  "}\n";
1701  }
1702  else // Caustics
1703  {
1704  FragmentProgramData +=
1705  Ogre::String(
1706  "void main_fp(\n") +
1707  // IN
1708  "float3 iPosition_UV : TEXCOORD0,\n" +
1709  "float2 iUvWorld : TEXCOORD1,\n" +
1710  // OUT
1711  "out float4 oColor : COLOR,\n" +
1712  // UNIFORM
1713  "uniform float uDepthLimit,\n" +
1714  "uniform float uCausticsScale,\n" +
1715  "uniform float uCausticsEnd,\n" +
1716  "uniform sampler2D uCaustics : register(s0),\n" +
1717  "uniform sampler2D uAlphaTex : register(s1))\n" +
1718  "{\n" +
1719  "float pixelYDepth = (iPosition_UV.x*uDepthLimit+1);\n" +
1720  "pixelYDepth = saturate(pixelYDepth);\n" +
1721  "oColor = float4(pixelYDepth,0,0,0);\n" +
1722  "oColor.g = saturate(uCausticsEnd-pixelYDepth)*tex2D(uCaustics, iUvWorld/uCausticsScale).r;\n" +
1723  "oColor.a = tex2D(uAlphaTex, iPosition_UV.yz)."+AlphaChannel+";" +
1724  "}\n";
1725  }
1726  }
1727  break;
1728 
1729  case SM_GLSL:
1730  {
1731  Ogre::String AlphaChannelGLSL = AlphaChannel;
1732  std::replace( AlphaChannelGLSL.begin(), AlphaChannelGLSL.end(), 'r', 'x' );
1733  std::replace( AlphaChannelGLSL.begin(), AlphaChannelGLSL.end(), 'g', 'y' );
1734  std::replace( AlphaChannelGLSL.begin(), AlphaChannelGLSL.end(), 'b', 'z' );
1735  std::replace( AlphaChannelGLSL.begin(), AlphaChannelGLSL.end(), 'a', 'w' );
1736  // No caustics
1737  if (!cCaustics)
1738  {
1739  FragmentProgramData += Ogre::String( "\n" ) +
1740  // UNIFORMS
1741  "uniform float uDepthLimit;\n" +
1742  "uniform float uDistLimit;\n" +
1743  "uniform sampler2D uAlphaTex;\n" +
1744  // IN
1745  "variying vec3 Position_UV;\n" +
1746  // OUT
1747  // main function
1748  "void main()\n" +
1749  "{\n" +
1750  "float pixelYDepth = clamp(Position_UV.x*uDepthLimit + 1.0, 0.0, 1.0);\n" +
1751  "gl_FragColor = vec4(pixelYDepth,0.0,0.0,0.0);\n" +
1752  "gl_FragColor.w = texture2D(uAlphaTex, iPosition_UV.yz)."+AlphaChannelGLSL+";" +
1753  "}\n";
1754  }
1755  else // Caustics
1756  {
1757  FragmentProgramData += Ogre::String( "\n" ) +
1758  // UNIFORMS
1759  "uniform float uDistLimit;\n" +
1760  "uniform float uCausticsScale;\n" +
1761  "uniform float uCausticsEnd;\n" +
1762  "uniform sampler2D uCaustics;\n" +
1763  "uniform sampler2D uAlphaTex;\n" +
1764  // IN
1765  "variying vec3 Position_UV;\n" +
1766  "variying vec2 UVWorld;\n" +
1767  // OUT
1768  // main function
1769  "void main()\n" +
1770  "{\n" +
1771  "float pixelYDepth = clamp(Position_UV.x*uDepthLimit + 1.0, 0.0, 1.0);\n" +
1772  "gl_FragColor = vec4(pixelYDepth,0.0,0.0,0.0);\n" +
1773  "gl_FragColor.y = clamp(uCausticsEnd-pixelYDepth, 0.0, 1.0)*texture2D(uCaustics, UVWorld/uCausticsScale).x;\n" +
1774  "gl_FragColor.w = texture2D(uAlphaTex, iPosition_UV.yz)."+AlphaChannelGLSL+";" +
1775  "}\n";
1776  }
1777  }
1778  break;
1779  }
1780 
1781  Ogre::String GpuProgramsData[2] = {VertexProgramData, FragmentProgramData};
1782  Ogre::String GpuProgramNames[2] = {_def_DepthTexture_Shader_VP_Name+AlphaChannel, _def_DepthTexture_Shader_FP_Name+AlphaChannel};
1783  Ogre::String EntryPoints[2];
1784  if(Options.SM == SM_GLSL)
1785  {
1786  EntryPoints[0] = Ogre::String("main");
1787  EntryPoints[1] = Ogre::String("main");
1788  }
1789  else
1790  {
1791  EntryPoints[0] = Ogre::String("main_vp");
1792  EntryPoints[1] = Ogre::String("main_fp");
1793  }
1794 
1795  GpuProgram GpuPrograms[2] = {GPUP_VERTEX, GPUP_FRAGMENT};
1796 
1797  for (int k = 0; k < 2; k++)
1798  {
1799  if (!createGpuProgram(GpuProgramNames[k], Options.SM, GpuPrograms[k], EntryPoints[k], GpuProgramsData[k]))
1800  {
1801  return false;
1802  }
1803  }
1804 
1805  return true;
1806  }
1807 
1809  {
1810  const bool cDepth = _isComponent(Components, HYDRAX_COMPONENT_DEPTH );
1811  //const bool cSmooth = _isComponent(Components, HYDRAX_COMPONENT_SMOOTH ); // cSmooth uneeded underwater
1812  const bool cSun = _isComponent(Components, HYDRAX_COMPONENT_SUN );
1813  //const bool cFoam = _isComponent(Components, HYDRAX_COMPONENT_FOAM );
1814  const bool cCaustics = _isComponent(Components, HYDRAX_COMPONENT_CAUSTICS);
1815  const bool cUReflections = _isComponent(Components, HYDRAX_COMPONENT_UNDERWATER_REFLECTIONS);
1816 
1817  Ogre::String VertexProgramData, FragmentProgramData;
1818 
1819  // Vertex program
1820 
1821  switch (Options.NM)
1822  {
1823  case NM_TEXTURE:
1824  {
1825  switch (Options.SM)
1826  {
1827  case SM_HLSL: case SM_CG:
1828  {
1829  VertexProgramData +=
1830  Ogre::String(
1831  "void main_vp(\n") +
1832  // IN
1833  "float4 iPosition : POSITION,\n" +
1834  "float2 iUv : TEXCOORD0,\n" +
1835  // OUT
1836  "out float4 oPosition : POSITION,\n" +
1837  "out float4 oPosition_ : TEXCOORD0,\n" +
1838  "out float2 oUvNoise : TEXCOORD1,\n" +
1839  "out float4 oUvProjection : TEXCOORD2,\n" +
1840  "out float2 oDistance : TEXCOORD3,\n";
1841  /* Foam is not visible underwater
1842  if (cFoam)
1843  {
1844  VertexProgramData +=
1845  "out float4 oWorldPosition : TEXCOORD4,\n";
1846  }
1847  */
1848  VertexProgramData += Ogre::String(
1849  // UNIFORM
1850  "uniform float4x4 uWorldViewProj,\n") +
1851  "uniform float4x4 uWorldView,\n" +
1852  "uniform float4x4 uWorld,\n" +
1853  "uniform float3 uCameraPos)\n" +
1854  "{\n" +
1855  "oPosition_ = iPosition;\n";
1856  /* Foam is not visible underwater
1857  if (cFoam)
1858  {
1859  VertexProgramData +=
1860  "oWorldPosition = mul(uWorld, iPosition);\n";
1861  }
1862  */
1863  VertexProgramData += Ogre::String(
1864  "oPosition = mul(uWorldViewProj, iPosition);\n") +
1865  // Projective texture coordinates, adjust for mapping
1866  "float4x4 scalemat = float4x4(0.5, 0, 0, 0.5,"+
1867  "0,-0.5, 0, 0.5,"+
1868  "0, 0, 0.5, 0.5,"+
1869  "0, 0, 0, 1);\n" +
1870  "oUvProjection = mul(scalemat, oPosition);\n" +
1871  "oUvNoise = iUv;\n" +
1872  // Distance
1873  "float4 mwPos = mul(uWorldView, iPosition);\n" +
1874  "oDistance.x = abs(mwPos.z);\n" +
1875  "oDistance.y = -mul( uWorld, float4(uCameraPos, 1.0) ).y;\n" +
1876  "}\n";
1877  }
1878  break;
1879 
1880  case SM_GLSL:
1881  {
1882  VertexProgramData += Ogre::String( "\n" );
1883  // UNIFORMS
1884  VertexProgramData += "uniform mat4 uWorld;\n";
1885  // IN
1886  // OUT
1887  VertexProgramData += Ogre::String(
1888  "varying vec4 Position_;\n") +
1889  "varying vec4 UVProjection;\n" +
1890  "varying vec2 Distance_;\n";
1891  /* Foam is not visible underwater
1892  if (cFoam)
1893  {
1894  VertexProgramData += "varying vec4 WorldPosition;\n";
1895  }
1896  */
1897  // main function
1898  VertexProgramData += Ogre::String(
1899  "void main()\n") +
1900  "{\n" +
1901  "Position_ = gl_Vertex;\n";
1902  /* Foam is not visible underwater
1903  if (cFoam)
1904  {
1905  VertexProgramData += "WorldPosition = uWorld * gl_Vertex;\n";
1906  }
1907  */
1908  VertexProgramData += Ogre::String(
1909  // Projective texture coordinates, adjust for mapping
1910  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n") +
1911  "mat4 scalemat = mat4( 1.0, 0.0, 0.0, 0.0,\n" +
1912  " 0.0, -1.0, 0.0, 0.0,\n" +
1913  " 0.0, 0.0, 1.0, 0.0,\n" +
1914  " 0.0, 0.0, 0.0, 1.0);\n" +
1915  "UVProjection = scalemat * gl_Position;\n" +
1916  "gl_TexCoord[0] = gl_MultiTexCoord0;\n" +
1917  // Distance
1918  "vec4 mwPos = gl_ModelViewMatrix * gl_Vertex;\n" +
1919  "Distance_.x = abs(mwPos.z);\n" +
1920  "Distance_.y = -( uWorld * gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0) ).y;\n" +
1921  "}\n";
1922  }
1923  break;
1924  }
1925  }
1926  break;
1927 
1928  case NM_VERTEX:
1929  {
1930  switch (Options.SM)
1931  {
1932  case SM_HLSL: case SM_CG:
1933  {
1934  VertexProgramData +=
1935  Ogre::String(
1936  "void main_vp(\n") +
1937  // IN
1938  "float4 iPosition : POSITION,\n" +
1939  "float3 iNormal : NORMAL,\n"+
1940  // OUT
1941  "out float4 oPosition : POSITION,\n" +
1942  "out float4 oPosition_ : TEXCOORD0,\n" +
1943  "out float4 oUvProjection : TEXCOORD1,\n" +
1944  "out float3 oNormal : TEXCOORD2,\n" +
1945  "out float2 oDistance : TEXCOORD3,\n";
1946  /* Foam is not visible underwater
1947  if (cFoam)
1948  {
1949  VertexProgramData +=
1950  "out float4 oWorldPosition : TEXCOORD4,\n";
1951  }
1952  */
1953  VertexProgramData += Ogre::String(
1954  // UNIFORM
1955  "uniform float4x4 uWorldViewProj,\n") +
1956  "uniform float4x4 uWorldView,\n" +
1957  "uniform float4x4 uWorld,\n" +
1958  "uniform float3 uCameraPos)\n" +
1959  "{\n" +
1960  "oPosition_ = iPosition;\n";
1961  /* Foam is not visible underwater
1962  if (cFoam)
1963  {
1964  VertexProgramData += "oWorldPosition = mul(uWorld, iPosition);\n";
1965  }
1966  */
1967  VertexProgramData += Ogre::String(
1968  "oPosition = mul(uWorldViewProj, iPosition);\n") +
1969  // Projective texture coordinates, adjust for mapping
1970  "float4x4 scalemat = float4x4(0.5, 0, 0, 0.5,"+
1971  "0,-0.5, 0, 0.5,"+
1972  "0, 0, 0.5, 0.5,"+
1973  "0, 0, 0, 1);\n" +
1974  "oUvProjection = mul(scalemat, oPosition);\n" +
1975  "oNormal = normalize(iNormal);\n"+
1976  // Distance
1977  "float4 mwPos = mul(uWorldView, iPosition);\n" +
1978  "oDistance.x = abs(mwPos.z);\n" +
1979  "oDistance.y = -mul( uWorld, float4(uCameraPos, 1.0) ).y;\n" +
1980  "}\n";
1981  }
1982  break;
1983 
1984  case SM_GLSL:
1985  {
1986  VertexProgramData += Ogre::String( "\n");
1987  // UNIFORMS
1988  VertexProgramData += "uniform mat4 uWorld;\n";
1989  // IN
1990  // OUT
1991  VertexProgramData += Ogre::String(
1992  "varying vec4 Position_;\n") +
1993  "varying vec4 UVProjection;\n" +
1994  "varying vec3 Normal;\n" +
1995  "varying vec2 Distance_;\n";
1996  /* Foam is not visible underwater
1997  if(cFoam)
1998  {
1999  VertexProgramData += "varying vec4 WorldPosition;\n";
2000  }
2001  */
2002  // PROGRAM
2003  VertexProgramData += Ogre::String(
2004  "void main()\n") +
2005  "{\n" +
2006  "Position_ = gl_Vertex;\n";
2007  /* Foam is not visible underwater
2008  if(cFoam)
2009  {
2010  VertexProgramData += "WorldPosition = uWorld * gl_Vertex;\n";
2011  }
2012  */
2013  VertexProgramData += Ogre::String(
2014  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n") +
2015  "mat4 scalemat = mat4( 1.0, 0.0, 0.0, 0.0,\n" +
2016  " 0.0, -1.0, 0.0, 0.0,\n" +
2017  " 0.0, 0.0, 1.0, 0.0,\n" +
2018  " 0.0, 0.0, 0.0, 1.0);\n" +
2019  "UVProjection = scalemat * gl_Position;\n" +
2020  "Normal = normalize(gl_Normal);\n" +
2021  // Distance
2022  "vec4 mwPos = gl_ModelViewMatrix * gl_Vertex;\n" +
2023  "Distance_.x = abs(mwPos.z);\n" +
2024  "Distance_.y = -( uWorld * gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0) ).y;\n" +
2025  "}\n";
2026  }
2027  break;
2028  }
2029  }
2030  break;
2031 
2032  case NM_RTT:
2033  {
2034  switch (Options.SM)
2035  {
2036  case SM_HLSL: case SM_CG:
2037  {
2038  VertexProgramData +=
2039  Ogre::String(
2040  "void main_vp(\n") +
2041  // IN
2042  "float4 iPosition : POSITION,\n" +
2043  // OUT
2044  "out float4 oPosition : POSITION,\n" +
2045  "out float4 oPosition_ : TEXCOORD0,\n" +
2046  "out float4 oUvProjection : TEXCOORD1,\n" +
2047  "out float2 oDistance : TEXCOORD2,\n";
2048  /* Foam is not visible underwater
2049  if (cFoam)
2050  {
2051  VertexProgramData +=
2052  "out float4 oWorldPosition : TEXCOORD3,\n";
2053  }
2054  */
2055  VertexProgramData += Ogre::String(
2056  // UNIFORM
2057  "uniform float4x4 uWorldViewProj,\n") +
2058  "uniform float4x4 uWorldView,\n" +
2059  "uniform float4x4 uWorld,\n" +
2060  "uniform float3 uCameraPos)\n" +
2061  "{\n" +
2062  "oPosition_ = iPosition;\n";
2063  /* Foam is not visible underwater
2064  if (cFoam)
2065  {
2066  VertexProgramData += "oWorldPosition = mul(uWorld, iPosition);\n";
2067  }
2068  */
2069  VertexProgramData += Ogre::String(
2070  "oPosition = mul(uWorldViewProj, iPosition);\n") +
2071  // Projective texture coordinates, adjust for mapping
2072  "float4x4 scalemat = float4x4(0.5, 0, 0, 0.5,"+
2073  "0,-0.5, 0, 0.5,"+
2074  "0, 0, 0.5, 0.5,"+
2075  "0, 0, 0, 1);\n" +
2076  "oUvProjection = mul(scalemat, oPosition);\n" +
2077  // Distance
2078  "float4 mwPos = mul(uWorldView, iPosition);\n" +
2079  "oDistance.x = abs(mwPos.z);\n" +
2080  "oDistance.y = -mul( uWorld, float4(uCameraPos, 1.0) ).y;\n" +
2081  "}\n";
2082  }
2083  break;
2084 
2085  case SM_GLSL:
2086  {
2087  VertexProgramData += Ogre::String( "\n");
2088  // UNIFORMS
2089  VertexProgramData += "uniform mat4 uWorld;\n";
2090  // IN
2091  // OUT
2092  VertexProgramData += Ogre::String(
2093  "varying vec4 Position_;\n") +
2094  "varying vec4 UVProjection;\n" +
2095  "varying vec2 Distance_;\n";
2096  /* Foam is not visible underwater
2097  if(cFoam)
2098  {
2099  VertexProgramData += "varying vec4 WorldPosition;\n";
2100  }
2101  */
2102  // PROGRAM
2103  VertexProgramData +=Ogre::String(
2104  "void main()\n") +
2105  "{\n" +
2106  "Position_ = gl_Vertex;\n";
2107  /* Foam is not visible underwater
2108  if(cFoam)
2109  {
2110  VertexProgramData += "WorldPosition = uWorld * gl_Vertex;\n";
2111  }
2112  */
2113  VertexProgramData += Ogre::String(
2114  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n") +
2115  "mat4 scalemat = mat4( 1.0, 0.0, 0.0, 0.0,\n" +
2116  " 0.0, -1.0, 0.0, 0.0,\n" +
2117  " 0.0, 0.0, 1.0, 0.0,\n" +
2118  " 0.0, 0.0, 0.0, 1.0);\n" +
2119  "UVProjection = scalemat * gl_Position;\n" +
2120  // Distance
2121  "vec4 mwPos = gl_ModelViewMatrix * gl_Vertex;\n" +
2122  "Distance_.x = abs(mwPos.z);\n" +
2123  "Distance_.y = -( uWorld * gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0) ).y;\n" +
2124  "}\n";
2125  }
2126  break;
2127  }
2128  }
2129  break;
2130  }
2131 
2132  // Fragment program
2133 
2134  switch (Options.NM)
2135  {
2136  case NM_TEXTURE: case NM_VERTEX: case NM_RTT:
2137  {
2138  switch (Options.SM)
2139  {
2140  case SM_HLSL: case SM_CG:
2141  {
2142  FragmentProgramData +=
2143  Ogre::String("float3 expand(float3 v)\n") +
2144  "{\n" +
2145  "return (v - 0.5) * 2;\n" +
2146  "}\n\n" +
2147 
2148  "void main_fp(" +
2149  // IN
2150  "float4 iPosition : TEXCOORD0,\n";
2151  int TEXCOORDNUM = 1;
2152  if (Options.NM == NM_TEXTURE)
2153  {
2154  FragmentProgramData +=
2155  "float2 iUvNoise : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
2156  TEXCOORDNUM++;
2157  }
2158  FragmentProgramData +=
2159  "float4 iUvProjection : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
2160  TEXCOORDNUM++;
2161  if (Options.NM == NM_VERTEX)
2162  {
2163  FragmentProgramData +=
2164  "float3 iNormal : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
2165  TEXCOORDNUM++;
2166  }
2167  FragmentProgramData +=
2168  "float2 iDistance : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
2169  TEXCOORDNUM++;
2170  /* Foam is not visible underwater
2171  if (cFoam)
2172  {
2173  FragmentProgramData +=
2174  "float4 iWorldPosition : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
2175  }
2176  */
2177 
2178  FragmentProgramData += Ogre::String(
2179  // OUT
2180  "out float4 oColor : COLOR,\n") +
2181  // UNIFORM
2182  "uniform float3 uEyePosition,\n" +
2183  "uniform float uFullReflectionDistance,\n" +
2184  "uniform float uGlobalTransparency,\n" +
2185  "uniform float uNormalDistortion,\n" +
2186  "uniform float uDistLimit,\n" +
2187  "uniform float3 uWaterColor,\n";
2188  if (cSun)
2189  {
2190  FragmentProgramData += Ogre::String(
2191  "uniform float3 uSunPosition,\n") +
2192  "uniform float uSunStrength,\n" +
2193  "uniform float uSunArea,\n" +
2194  "uniform float3 uSunColor,\n" +
2195  "uniform float uDepthLimit,\n";
2196  }
2197  /* Foam is not visible underwater
2198  if (cFoam)
2199  {
2200  FragmentProgramData += Ogre::String(
2201  "uniform float uFoamRange,\n") +
2202  "uniform float uFoamMaxDistance,\n" +
2203  "uniform float uFoamScale,\n" +
2204  "uniform float uFoamStart,\n" +
2205  "uniform float uFoamTransparency,\n";
2206  }
2207  */
2208  if (cCaustics && cUReflections)
2209  {
2210  FragmentProgramData +=
2211  "uniform float uCausticsPower,\n";
2212  }
2213 
2214  int TexNum = 0;
2215 
2216  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
2217  {
2218  FragmentProgramData +=
2219  "uniform sampler2D uNormalMap : register(s" + Ogre::StringConverter::toString(TexNum) + "),\n";
2220  TexNum++;
2221  }
2222  if (cUReflections)
2223  {
2224  FragmentProgramData +=
2225  "uniform sampler2D uReflectionMap : register(s" + Ogre::StringConverter::toString(TexNum) + "),\n";
2226  TexNum++;
2227  }
2228 
2229  FragmentProgramData +=
2230  "uniform sampler2D uRefractionMap : register(s" + Ogre::StringConverter::toString(TexNum) + "),\n";
2231  TexNum++;
2232 
2233  if (cDepth && cUReflections)
2234  {
2235  FragmentProgramData +=
2236  "uniform sampler2D uDepthReflectionMap : register(s" + Ogre::StringConverter::toString(TexNum) + "),\n";
2237  TexNum++;
2238  }
2239 
2240  FragmentProgramData +=
2241  #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
2242  "uniform sampler1D uFresnelMap : register(s" + Ogre::StringConverter::toString(TexNum) + ")";
2243  #else
2244  "uniform sampler2D uFresnelMap : register(s" + Ogre::StringConverter::toString(TexNum) + ")";
2245  #endif
2246  TexNum++;
2247 
2248  /* Foam is not visible underwater
2249  if (cFoam)
2250  {
2251  FragmentProgramData += Ogre::String(
2252  ",\nuniform sampler2D uFoamMap : register(s" + Ogre::StringConverter::toString(TexNum) + ")\n");
2253  }
2254  */
2255  FragmentProgramData += Ogre::String(
2256  ")\n") +
2257  "{\n" +
2258  "float2 ProjectionCoord = iUvProjection.xy / iUvProjection.w;\n" +
2259  "float3 camToSurface = iPosition.xyz - uEyePosition;\n" +
2260  "float additionalReflection=camToSurface.x*camToSurface.x+camToSurface.z*camToSurface.z;\n";
2261 
2262  /* Foam is not visible underwater
2263  if (cFoam)
2264  {
2265  // Calculate the foam visibility as a function fo distance specified by user
2266  FragmentProgramData +=
2267  "float foamVisibility=1.0f-saturate(additionalReflection/uFoamMaxDistance);\n";
2268  }
2269  */
2270 
2271  FragmentProgramData += Ogre::String(
2272  "additionalReflection/=uFullReflectionDistance;\n") +
2273  "camToSurface=normalize(-camToSurface);\n";
2274  if (Options.NM == NM_TEXTURE)
2275  {
2276  FragmentProgramData += Ogre::String(
2277  "float3 pixelNormal = tex2D(uNormalMap,iUvNoise).xyz;\n") +
2278  // Inverte y with z, because at creation our local normal to the plane was z
2279  "pixelNormal.yz=pixelNormal.zy;\n" +
2280  // Remap from [0,1] to [-1,1]
2281  "pixelNormal.xyz=-expand(pixelNormal.xyz);\n";
2282  }
2283  else if (Options.NM == NM_VERTEX)
2284  {
2285  FragmentProgramData +=
2286  "float3 pixelNormal = -iNormal;\n";
2287  }
2288  else // NM_RTT
2289  {
2290  FragmentProgramData +=
2291  "float3 pixelNormal = -(2.0*tex2D(uNormalMap, ProjectionCoord.xy).xyz - 1.0);\n";
2292  }
2293  FragmentProgramData +=
2294  "float2 pixelNormalModified = uNormalDistortion*pixelNormal.zx;\n";
2295 
2296  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
2297  {
2298  FragmentProgramData +=
2299  "float dotProduct=dot(camToSurface,pixelNormal);\n";
2300  }
2301  else
2302  {
2303  FragmentProgramData +=
2304  "float dotProduct=dot(-camToSurface,pixelNormal);\n";
2305  }
2306  FragmentProgramData += Ogre::String(
2307  "dotProduct=saturate(dotProduct);\n") +
2308  #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
2309  "float fresnel = tex1D(uFresnelMap,dotProduct);\n" +
2310  #else
2311  "float fresnel = tex2D(uFresnelMap,float2(dotProduct,dotProduct));\n" +
2312  #endif
2313  // Add additional reflection and saturate
2314  "fresnel+=additionalReflection;\n" +
2315  "fresnel=saturate(fresnel);\n" +
2316  // Decrease the transparency and saturate
2317  "fresnel-=uGlobalTransparency;\n" +
2318  "fresnel=saturate(fresnel);\n" +
2319  "float3 reflection;\n" +
2320  #if OGRE_PLATFORM != OGRE_PLATFORM_WIN32
2321  // Reversing projection if underwater
2322  "if(uEyePosition.y < 0.0)\n" +
2323  "{\n" +
2324  "ProjectionCoord.y = 1.0 - ProjectionCoord.y;\n" +
2325  "}\n" +
2326  #endif
2327  // Get the reflection/refraction pixels. Make sure to disturb the texcoords by pixelnormal
2328  "float3 refraction=tex2D(uRefractionMap,ProjectionCoord.xy-pixelNormalModified).xyz;\n";
2329  if (cUReflections)
2330  {
2331  FragmentProgramData +=
2332  "reflection=tex2D(uReflectionMap,ProjectionCoord.xy+pixelNormalModified).xyz;\n";
2333  }
2334  else
2335  {
2336  FragmentProgramData +=
2337  "reflection=uWaterColor;\n";
2338  }
2339 
2340  if (cDepth && cUReflections)
2341  {
2342  if (cCaustics)
2343  {
2344  FragmentProgramData += Ogre::String(
2345  "float2 depth = tex2D(uDepthReflectionMap,ProjectionCoord.xy+pixelNormalModified).rg;\n") +
2346  "reflection *= 1+depth.y*uCausticsPower;\n" +
2347  "reflection = lerp(uWaterColor,reflection,depth.x);\n";
2348  }
2349  else
2350  {
2351  FragmentProgramData += Ogre::String(
2352  "float depth = tex2D(uDepthReflectionMap,ProjectionCoord.xy-pixelNormalModified).r;\n") +
2353  "reflection = lerp(uWaterColor,reflection,depth);\n";
2354  }
2355  }
2356  FragmentProgramData += Ogre::String(
2357  "float4 Color = float4(lerp(refraction,reflection,fresnel),1);\n" ) +
2358  "float Distance = saturate(1.0 - iDistance.x*uDistLimit);\n" +
2359  "Color.xyz = lerp(uWaterColor, Color.xyz, Distance);\n" +
2360  "Color.xyz = lerp(Color.xyz, uWaterColor, uGlobalTransparency);\n";
2361 
2362  if (cSun)
2363  {
2364  FragmentProgramData += Ogre::String(
2365  "float3 refractedVector = normalize(reflect(camToSurface, pixelNormal.xyz));\n") +
2366  "float3 surfaceToSun=normalize(uSunPosition-iPosition.xyz);\n" +
2367  // Temporally solution, fix this
2368  "surfaceToSun.xz = -surfaceToSun.xz;" +
2369  "float3 sunlight = uSunStrength*pow(saturate(dot(refractedVector,surfaceToSun)),uSunArea)*uSunColor;\n" +
2370  "Distance = saturate(1.0 - iDistance.y*uDepthLimit);\n" +
2371  "Color.xyz+=Distance*sunlight*saturate(1.0-additionalReflection);\n";
2372  }
2373 
2374  /* Foam is not visible underwater
2375  if (cFoam)
2376  {
2377  FragmentProgramData += Ogre::String(
2378  "float hmap = iPosition.y/uFoamRange*foamVisibility;\n") +
2379  "float2 foamTex=iWorldPosition.xz*uFoamScale+pixelNormalModified;\n" +
2380  "float foam=tex2D(uFoamMap,foamTex).r;\n" +
2381  "float foamTransparency=saturate(hmap-uFoamStart)*uFoamTransparency;\n" +
2382  "Color.xyz=lerp(Color.xyz,1,foamTransparency*foam);\n";
2383  }
2384  */
2385  FragmentProgramData += Ogre::String(
2386  "oColor = Color;\n") +
2387  "}\n";
2388  }
2389  break;
2390 
2391  case SM_GLSL:
2392  FragmentProgramData += Ogre::String("\n") +
2393  // UNIFORMS
2394  "uniform vec3 uEyePosition;\n" +
2395  "uniform float uFullReflectionDistance;\n" +
2396  "uniform float uGlobalTransparency;\n" +
2397  "uniform float uNormalDistortion;\n" +
2398  "uniform float uDistLimit;\n" +
2399  "uniform vec3 uWaterColor;\n";
2400 
2401  if (cSun)
2402  {
2403  FragmentProgramData += Ogre::String(
2404  "uniform vec3 uSunPosition;\n") +
2405  "uniform float uSunStrength;\n" +
2406  "uniform float uSunArea;\n" +
2407  "uniform vec3 uSunColor;\n" +
2408  "uniform float uDepthLimit;\n";
2409  }
2410  /* Foam is not visible underwater
2411  if (cFoam)
2412  {
2413  FragmentProgramData += Ogre::String(
2414  "uniform float uFoamRange;\n") +
2415  "uniform float uFoamMaxDistance;\n" +
2416  "uniform float uFoamScale;\n" +
2417  "uniform float uFoamStart;\n" +
2418  "uniform float uFoamTransparency;\n";
2419  }
2420  */
2421  if (cCaustics && cUReflections)
2422  {
2423  FragmentProgramData +=
2424  "uniform float uCausticsPower;\n";
2425  }
2426 
2427  int TexNum = 0;
2428  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
2429  {
2430  FragmentProgramData +=
2431  "uniform sampler2D uNormalMap;\n";
2432  TexNum++;
2433  }
2434 
2435  if (cUReflections)
2436  {
2437  FragmentProgramData += Ogre::String(
2438  "uniform sampler2D uReflectionMap;\n");
2439  TexNum++;
2440  }
2441  FragmentProgramData += Ogre::String(
2442  "uniform sampler2D uRefractionMap;\n");
2443  TexNum++;
2444 
2445  if (cDepth && cUReflections)
2446  {
2447  FragmentProgramData +=
2448  "uniform sampler2D uDepthReflectionMap;\n";
2449  TexNum++;
2450  }
2451 
2452  FragmentProgramData +=
2453  #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
2454  "uniform sampler1D uFresnelMap;\n";
2455  #else
2456  "uniform sampler2D uFresnelMap;\n";
2457  #endif
2458  TexNum++;
2459 
2460  /* Foam is not visible underwater
2461  if (cFoam)
2462  {
2463  FragmentProgramData +=
2464  "uniform sampler2D uFoamMap;\n";
2465  }
2466  */
2467  // IN
2468  FragmentProgramData +=
2469  "varying vec4 Position_;\n";
2470  int TEXCOORDNUM = 1;
2471  if (Options.NM == NM_TEXTURE)
2472  {
2473  TEXCOORDNUM++;
2474  }
2475  FragmentProgramData +=
2476  "varying vec4 UVProjection;\n";
2477  TEXCOORDNUM++;
2478  if (Options.NM == NM_VERTEX)
2479  {
2480  FragmentProgramData +=
2481  "varying vec3 Normal;\n";
2482  TEXCOORDNUM++;
2483  }
2484  /* Foam is not visible underwater
2485  if (cFoam)
2486  {
2487  FragmentProgramData +=
2488  "varying vec4 WorldPosition;\n";
2489  }
2490  */
2491  FragmentProgramData +=
2492  "varying vec2 Distance_;\n";
2493  // Expand function
2494  FragmentProgramData += Ogre::String(
2495  "vec3 expand(vec3 v)\n") +
2496  "{\n" +
2497  "return (v - 0.5) * 2.0;\n" +
2498  "}\n\n" +
2499  // main function
2500  "void main()\n" +
2501  "{\n" +
2502  "vec2 ProjectionCoord = UVProjection.xy / UVProjection.w;\n" +
2503  "ProjectionCoord += 1.0;\n" +
2504  "ProjectionCoord *= 0.5;\n" +
2505  "vec3 camToSurface = Position_.xyz - uEyePosition;\n" +
2506  "float additionalReflection=camToSurface.x*camToSurface.x+camToSurface.z*camToSurface.z;\n";
2507  /* Must not view foam underwater
2508  if (cFoam)
2509  {
2510  // Calculate the foam visibility as a function fo distance specified by user
2511  FragmentProgramData +=
2512  "float foamVisibility=1.0-clamp(additionalReflection/uFoamMaxDistance, 0.0, 1.0);\n";
2513  }
2514  */
2515  FragmentProgramData += Ogre::String(
2516  "additionalReflection/=uFullReflectionDistance;\n") +
2517  "camToSurface=normalize(-camToSurface);\n";
2518  if (Options.NM == NM_TEXTURE)
2519  {
2520  FragmentProgramData += Ogre::String(
2521  "vec3 pixelNormal = texture2D(uNormalMap,gl_TexCoord[0].xy).xyz;\n") +
2522  // Inverte y with z, because at creation our local normal to the plane was z
2523  "pixelNormal.yz=pixelNormal.zy;\n" +
2524  // Remap from [0,1] to [-1,1]
2525  "pixelNormal.xyz=-expand(pixelNormal.xyz);\n";
2526  }
2527  else if (Options.NM == NM_VERTEX)
2528  {
2529  FragmentProgramData +=
2530  "vec3 pixelNormal = -Normal;\n";
2531  }
2532  else // NM_RTT
2533  {
2534  FragmentProgramData +=
2535  "vec3 pixelNormal = -2.0*texture2D(uNormalMap, ProjectionCoord.xy).xyz - 1.0;\n";
2536  }
2537  FragmentProgramData +=
2538  "vec2 pixelNormalModified = uNormalDistortion*pixelNormal.zx;\n";
2539  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
2540  {
2541  FragmentProgramData +=
2542  "float dotProduct=dot(camToSurface,pixelNormal);\n";
2543  }
2544  else
2545  {
2546  FragmentProgramData +=
2547  "float dotProduct=dot(-camToSurface,pixelNormal);\n";
2548  }
2549  FragmentProgramData += Ogre::String(
2550  "dotProduct=clamp(dotProduct, 0.0, 1.0);\n") +
2551  #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
2552  "float fresnel = texture1D(uFresnelMap,dotProduct).x;\n" +
2553  #else
2554  "float fresnel = texture2D(uFresnelMap,vec2(dotProduct,dotProduct)).x;\n" +
2555  #endif
2556  // Add additional reflection and saturate
2557  "fresnel +=additionalReflection;\n" +
2558  "fresnel = clamp(fresnel, 0.0, 1.0);\n" +
2559  // Decrease the transparency and saturate
2560  "fresnel -= uGlobalTransparency;\n" +
2561  "fresnel = clamp(fresnel, 0.0, 1.0);\n" +
2562  // Get the reflection/refraction pixels. Make sure to disturb the texcoords by pixelnormal
2563  "vec3 reflection;\n" +
2564  #if OGRE_PLATFORM != OGRE_PLATFORM_WIN32
2565  // Reversing projection if underwater
2566  "if(uEyePosition.y < 0.0)\n" +
2567  "{\n" +
2568  "ProjectionCoord.y = 1.0 - ProjectionCoord.y;\n" +
2569  "}\n" +
2570  #endif
2571  "vec3 refraction=texture2D(uRefractionMap,ProjectionCoord.xy-pixelNormalModified).xyz;\n";
2572  if (cUReflections)
2573  {
2574  FragmentProgramData +=
2575  "reflection=texture2D(uReflectionMap,ProjectionCoord.xy+pixelNormalModified).xyz;\n";
2576  }
2577  else
2578  {
2579  FragmentProgramData +=
2580  "reflection=uWaterColor;\n";
2581  }
2582  if (cDepth && cUReflections)
2583  {
2584  if (cCaustics)
2585  {
2586  FragmentProgramData += Ogre::String(
2587  "vec2 depth = texture2D(uDepthReflectionMap,ProjectionCoord.xy+pixelNormalModified).xy;\n") +
2588  "reflection *= 1.0 + depth.y*uCausticsPower;\n" +
2589  "reflection = mix(uWaterColor,reflection,depth.x);\n";
2590  }
2591  else
2592  {
2593  FragmentProgramData += Ogre::String(
2594  "float depth = texture2D(uDepthReflectionMap,ProjectionCoord.xy+pixelNormalModified).x;\n") +
2595  "reflection = mix(uWaterColor,reflection,depth);\n";
2596  }
2597  }
2598  FragmentProgramData += Ogre::String(
2599  "gl_FragColor = vec4(mix(refraction,reflection,fresnel),1.0);\n") +
2600  "float Distance = clamp(1.0 - Distance_.x*uDistLimit, 0.0, 1.0);\n" +
2601  "gl_FragColor.xyz = mix(uWaterColor, gl_FragColor.xyz, Distance);\n" +
2602  "gl_FragColor.xyz = mix(gl_FragColor.xyz, uWaterColor, uGlobalTransparency);\n";
2603  if (cSun)
2604  {
2605  FragmentProgramData += Ogre::String(
2606  "vec3 refractedVector = normalize(reflect(-camToSurface,pixelNormal.xyz));\n") +
2607  "vec3 surfaceToSun=normalize(uSunPosition-Position_.xyz);\n" +
2608  // Temporally solution, fix this
2609  "surfaceToSun.xz = -surfaceToSun.xz;" +
2610  "vec3 sunlight = uSunStrength*pow(clamp(dot(refractedVector,surfaceToSun),0.0,1.0),uSunArea)*uSunColor;\n" +
2611  "Distance = clamp(1.0 - Distance_.y*uDepthLimit, 0.0, 1.0);\n";
2612  "gl_FragColor.xyz+=Distance*sunlight*clamp(1.0 - additionalReflection, 0.0, 1.0);\n";
2613  }
2614  /* Must not view foam underwater
2615  if (cFoam)
2616  {
2617  FragmentProgramData += Ogre::String(
2618  "float hmap = Position_.y/uFoamRange*foamVisibility;\n") +
2619  "vec2 foamTex=WorldPosition.xz*uFoamScale+pixelNormalModified;\n" +
2620  "float foam=texture2D(uFoamMap,foamTex).x;\n" +
2621  "float foamTransparency=clamp(hmap-uFoamStart, 0.0, 1.0)*uFoamTransparency;\n" +
2622  "gl_FragColor.xyz=mix(gl_FragColor.xyz,vec3(1.0,1.0,1.0),foamTransparency*foam);\n";
2623  }
2624  */
2625  FragmentProgramData +=
2626  "}\n";
2627  break;
2628  }
2629  }
2630  break;
2631  }
2632 
2633  // Second: build our material
2634  Ogre::MaterialPtr &UnderwaterMaterial = getMaterial(MAT_UNDERWATER);
2635  UnderwaterMaterial = Ogre::MaterialManager::getSingleton().
2637  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
2638 
2639  Ogre::Pass *UM_Technique0_Pass0 = UnderwaterMaterial->getTechnique(0)->getPass(0);
2640 
2641  UM_Technique0_Pass0->setDepthWriteEnabled(true);
2642  UM_Technique0_Pass0->setCullingMode(Ogre::CULL_NONE);
2643 
2644  Ogre::String GpuProgramsData[2] = {VertexProgramData, FragmentProgramData};
2645  Ogre::String GpuProgramNames[2] = {_def_Underwater_Shader_VP_Name, _def_Underwater_Shader_FP_Name};
2646  Ogre::String EntryPoints[2];
2647  if(Options.SM == SM_GLSL)
2648  {
2649  EntryPoints[0] = Ogre::String("main");
2650  EntryPoints[1] = Ogre::String("main");
2651  }
2652  else
2653  {
2654  EntryPoints[0] = Ogre::String("main_vp");
2655  EntryPoints[1] = Ogre::String("main_fp");
2656  }
2657 
2658  fillGpuProgramsToPass(UM_Technique0_Pass0, GpuProgramNames, Options.SM, EntryPoints, GpuProgramsData);
2659 
2660  Ogre::GpuProgramParametersSharedPtr VP_Parameters = UM_Technique0_Pass0->getVertexProgramParameters();
2661  Ogre::GpuProgramParametersSharedPtr FP_Parameters = UM_Technique0_Pass0->getFragmentProgramParameters();
2662 
2663  if(Options.SM != SM_GLSL)
2664  {
2665  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
2666  VP_Parameters->setNamedAutoConstant("uWorldView", Ogre::GpuProgramParameters::ACT_WORLDVIEW_MATRIX);
2667  VP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
2668  }
2669  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
2670  FP_Parameters->setNamedAutoConstant("uEyePosition", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
2671 
2672  FP_Parameters->setNamedConstant("uFullReflectionDistance", mHydrax->getFullReflectionDistance());
2673  FP_Parameters->setNamedConstant("uGlobalTransparency", mHydrax->getGlobalTransparency());
2674  FP_Parameters->setNamedConstant("uNormalDistortion", mHydrax->getNormalDistortion());
2675  FP_Parameters->setNamedConstant("uDistLimit", 1.f/mHydrax->getDistLimit());
2676  if (cSun)
2677  {
2678  }
2679  FP_Parameters->setNamedConstant("uWaterColor", mHydrax->getWaterColor());
2680 
2681  if (cSun)
2682  {
2683  FP_Parameters->setNamedConstant("uSunPosition", mHydrax->getMesh()->getObjectSpacePosition(mHydrax->getSunPosition()));
2684  FP_Parameters->setNamedConstant("uSunStrength", mHydrax->getSunStrength());
2685  FP_Parameters->setNamedConstant("uSunArea", mHydrax->getSunArea());
2686  FP_Parameters->setNamedConstant("uSunColor", mHydrax->getSunColor());
2687  FP_Parameters->setNamedConstant("uDepthLimit", 1.f/mHydrax->getDepthLimit());
2688  }
2689  /* Foam is not visible underwater
2690  if (cFoam)
2691  {
2692  FP_Parameters->setNamedConstant("uFoamRange", mHydrax->getMesh()->getOptions().MeshStrength);
2693  FP_Parameters->setNamedConstant("uFoamMaxDistance", mHydrax->getFoamMaxDistance());
2694  FP_Parameters->setNamedConstant("uFoamScale", mHydrax->getFoamScale());
2695  FP_Parameters->setNamedConstant("uFoamStart", mHydrax->getFoamStart());
2696  FP_Parameters->setNamedConstant("uFoamTransparency", mHydrax->getFoamTransparency());
2697  }
2698  */
2699  if (cCaustics && cDepth && cUReflections)
2700  {
2701  FP_Parameters->setNamedConstant("uCausticsPower", mHydrax->getCausticsPower());
2702  }
2703 
2704  int GLSLTextUnit = 0;
2705 
2706  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
2707  {
2708  if(Options.SM == SM_GLSL)
2709  {
2710  FP_Parameters->setNamedConstant("uNormalMap", GLSLTextUnit);
2711  GLSLTextUnit++;
2712  }
2713  UM_Technique0_Pass0->createTextureUnitState("HydraxNormalMap")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
2714  }
2715 
2716  if (cUReflections)
2717  {
2718  if(Options.SM == SM_GLSL)
2719  {
2720  FP_Parameters->setNamedConstant("uReflectionMap", GLSLTextUnit);
2721  GLSLTextUnit++;
2722  }
2723  UM_Technique0_Pass0->createTextureUnitState("HydraxReflectionMap")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
2724  }
2725  if(Options.SM == SM_GLSL)
2726  {
2727  FP_Parameters->setNamedConstant("uRefractionMap", GLSLTextUnit);
2728  GLSLTextUnit++;
2729  }
2730  UM_Technique0_Pass0->createTextureUnitState("HydraxRefractionMap")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
2731 
2732  if (cDepth && cUReflections)
2733  {
2734  if(Options.SM == SM_GLSL)
2735  {
2736  FP_Parameters->setNamedConstant("uDepthReflectionMap", GLSLTextUnit);
2737  GLSLTextUnit++;
2738  }
2739  UM_Technique0_Pass0->createTextureUnitState()->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
2740  }
2741 
2742  if(Options.SM == SM_GLSL)
2743  {
2744  FP_Parameters->setNamedConstant("uFresnelMap", GLSLTextUnit);
2745  GLSLTextUnit++;
2746  }
2747  UM_Technique0_Pass0->createTextureUnitState("Fresnel.bmp")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
2748 
2749  /* Foam is not visible underwater
2750  if (cFoam)
2751  {
2752  if(Options.SM == SM_GLSL)
2753  {
2754  FP_Parameters->setNamedConstant("uFoamMap", GLSLTextUnit);
2755  GLSLTextUnit++;
2756  }
2757  UM_Technique0_Pass0->createTextureUnitState("Foam.png")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
2758  }
2759  */
2760 
2761  UnderwaterMaterial->setReceiveShadows(false);
2762  UnderwaterMaterial->load();
2763 
2764  return true;
2765  }
2766 
2768  {
2769  const bool cCaustics = _isComponent(Components, HYDRAX_COMPONENT_CAUSTICS);
2770  const bool cDepth = _isComponent(Components, HYDRAX_COMPONENT_DEPTH);
2771  const bool cGodRays = _isComponent(Components, HYDRAX_COMPONENT_UNDERWATER_GODRAYS);
2772 
2773  Ogre::String VertexProgramData, FragmentProgramData;
2774 
2775  // Vertex program
2776  switch (Options.SM)
2777  {
2778  case SM_HLSL: case SM_CG:
2779  {
2780  VertexProgramData +=
2781  Ogre::String(
2782  "void main_vp(\n") +
2783  // IN
2784  "float4 iPosition : POSITION,\n" +
2785  // OUT
2786  "out float4 oPosition : POSITION,\n" +
2787  "out float3 oPosition_ : TEXCOORD0,\n" +
2788  "out float2 oUV : TEXCOORD1,\n";
2789  // UNIFORM
2790  if (cGodRays)
2791  {
2792  VertexProgramData +=
2793  Ogre::String(
2794  "uniform float3 uCorner0,\n") +
2795  "uniform float3 uCorner01,\n" +
2796  "uniform float3 uCorner02,\n";
2797  }
2798  VertexProgramData +=
2799  Ogre::String(
2800  "uniform float4x4 uWorldViewProj)\n") +
2801  "{\n" +
2802  "oPosition = mul(uWorldViewProj, iPosition);\n"+
2803  "iPosition.xy = sign(iPosition.xy);\n"+
2804  "oUV = (float2(iPosition.x, -iPosition.y) + 1.0f) * 0.5f;";
2805  if (cGodRays)
2806  {
2807  VertexProgramData += Ogre::String(
2808  "uCorner01 *= oUV.x;\n")+
2809  "uCorner02 *= oUV.y;\n"+
2810  "oPosition_ = uCorner0+uCorner01+uCorner02;";
2811  }
2812  VertexProgramData +=
2813  "}\n";
2814  }
2815  break;
2816 
2817  case SM_GLSL:
2818  {
2819  VertexProgramData += Ogre::String( "\n" );
2820  // UNIFORMS
2821  if (cGodRays)
2822  {
2823  VertexProgramData += Ogre::String(
2824  "uniform vec3 uCorner0;\n") +
2825  "uniform vec3 uCorner01;\n" +
2826  "uniform vec3 uCorner02;\n";
2827  }
2828  // IN
2829  // OUT
2830  VertexProgramData += Ogre::String(
2831  "varying vec3 Position_;\n") +
2832  "varying vec2 UV;\n" +
2833  // main function
2834  "void main()\n" +
2835  "{\n" +
2836  "gl_Position = ftransform();\n" +
2837  "vec2 iPosition = sign(gl_Vertex.xy);\n"+
2838  "UV = (vec2(iPosition.x, -iPosition.y) + 1.0) * 0.5;\n";
2839  if (cGodRays)
2840  {
2841  VertexProgramData += Ogre::String(
2842  "vec3 vCorner01 = uCorner01 * UV.x;\n")+
2843  "vec3 vCorner02 = uCorner02 * UV.y;\n"+
2844  "Position_ = uCorner0+vCorner01+vCorner02;\n";
2845  }
2846  VertexProgramData +=
2847  "}\n";
2848  }
2849  break;
2850  }
2851 
2852  // Fragment program
2853  switch (Options.SM)
2854  {
2855  case SM_HLSL: case SM_CG:
2856  {
2857  FragmentProgramData +=
2858  Ogre::String(
2859  "void main_fp(\n") +
2860  // IN
2861  "float3 iPosition : TEXCOORD0,\n" +
2862  "float2 iUV : TEXCOORD1,\n" +
2863  // OUT
2864  "out float4 oColor : COLOR,\n";
2865  // UNIFORM
2866  if (cCaustics)
2867  {
2868  FragmentProgramData +=
2869  "uniform float uCausticsPower,\n";
2870  }
2871  if (cGodRays)
2872  {
2873  FragmentProgramData += Ogre::String(
2874  "uniform float3 uSunColor,\n") +
2875  "uniform float3 uLightDirection,\n"+
2876  "uniform float uIntensity,\n"+
2877  "uniform float3 uHGg,\n"+
2878  "uniform float3 uCameraPos,\n";
2879  }
2880  FragmentProgramData += Ogre::String(
2881  "uniform float uTime,\n") +
2882  "uniform float3 uWaterColor,\n" +
2883  "uniform sampler2D uOriginalMap : register(s0),\n" +
2884  "uniform sampler2D uDistortMap : register(s1)\n";
2885  if (cDepth)
2886  {
2887  FragmentProgramData +=
2888  ",\nuniform sampler2D uDepthMap : register(s2)";
2889  }
2890  FragmentProgramData += Ogre::String(
2891  ")\n" ) +
2892  "{\n" +
2893  "float2 distortUV = (tex2D(uDistortMap, float2(iUV.x + uTime, iUV.y + uTime)).xy - 0.5)/50.0;\n";
2894  if (cCaustics) // Depth, caustics
2895  {
2896  FragmentProgramData += Ogre::String(
2897  "float2 depth = tex2D(uDepthMap, iUV+distortUV).xy;\n") +
2898  "float4 Color = float4(lerp(uWaterColor,tex2D(uOriginalMap, iUV+distortUV)*(1.0+depth.y*uCausticsPower), depth.x),1.0);\n";
2899  if (cGodRays)
2900  {
2901  FragmentProgramData += Ogre::String(
2902  "float3 view_vector = normalize(iPosition-uCameraPos);\n") +
2903  "float dot_product = dot(view_vector, -uLightDirection);\n"+
2904  "float num = uHGg.x;\n"+
2905  "float den = (uHGg.y - uHGg.z*dot_product);\n"+
2906  "den = rsqrt(den);\n"+
2907  "float phase = num * (den*den*den);\n" +
2908  "Color.xyz += (0.15 + uIntensity*tex2D(uDepthMap, iUV).z)*phase*uSunColor;\n";
2909  }
2910  }
2911  else if (cDepth) // Depth, no caustics
2912  {
2913  FragmentProgramData +=
2914  "float4 Color = float4(lerp(uWaterColor,tex2D(uOriginalMap, iUV+distortUV).xyz,tex2D(uDepthMap, iUV+distortUV).r),1.0);\n";
2915  if (cGodRays)
2916  {
2917  FragmentProgramData += Ogre::String(
2918  "float3 view_vector = normalize(iPosition-uCameraPos);") +
2919  "float dot_product = dot(view_vector, -uLightDirection);"+
2920  "float num = uHGg.x;"+
2921  "float den = (uHGg.y - uHGg.z*dot_product); "+
2922  "den = rsqrt(den); "+
2923  "float phase = num * (den*den*den);"+
2924  "Color.xyz += (0.15 + uIntensity*tex2D(uDepthMap, iUV).y)*phase*uSunColor;";
2925  }
2926  }
2927  else // No depth, no caustics
2928  {
2929  FragmentProgramData +=
2930  "float4 Color = tex2D(uOriginalMap, iUV+distortUV);";
2931  }
2932  FragmentProgramData += Ogre::String(
2933  "oColor = Color;\n") +
2934  "}\n";
2935  }
2936  break;
2937 
2938  case SM_GLSL:
2939  {
2940  FragmentProgramData += Ogre::String( "\n" );
2941  // UNIFORM
2942  if (cCaustics)
2943  {
2944  FragmentProgramData +=
2945  "uniform float uCausticsPower;\n";
2946  }
2947  if (cGodRays)
2948  {
2949  FragmentProgramData += Ogre::String(
2950  "uniform vec3 uSunColor;\n") +
2951  "uniform vec3 uLightDirection;\n"+
2952  "uniform float uIntensity;\n"+
2953  "uniform vec3 uHGg;\n"+
2954  "uniform vec3 uCameraPos;\n";
2955  }
2956  FragmentProgramData += Ogre::String(
2957  "uniform float uTime;\n") +
2958  "uniform float uGlobalTransparency;\n" +
2959  "uniform vec3 uWaterColor;\n" +
2960  "uniform sampler2D uOriginalMap;\n" +
2961  "uniform sampler2D uDistortMap;\n";
2962  if (cDepth)
2963  {
2964  FragmentProgramData +=
2965  "uniform sampler2D uDepthMap;\n";
2966  }
2967  // IN
2968  FragmentProgramData += Ogre::String(
2969  "varying vec3 Position_;\n") +
2970  "varying vec2 UV;\n" +
2971  // OUT
2972  // main function
2973  "void main()\n" +
2974  "{\n" +
2975  "vec2 distortUV = (texture2D(uDistortMap, vec2(UV.x + uTime, UV.y + uTime)).xy - 0.5)*0.02;\n";
2976  // "vec2 distortUV = vec2(0.0,0.0);\n";
2977  if (cCaustics) // Depth, caustics
2978  {
2979  FragmentProgramData += Ogre::String(
2980  "vec2 depth = texture2D(uDepthMap, UV+distortUV).xy;\n") +
2981  "gl_FragColor = vec4(mix(uWaterColor,texture2D(uOriginalMap, UV+distortUV).xyz*(1.0+depth.y*uCausticsPower), depth.x),1.0);\n";
2982  if (cGodRays)
2983  {
2984  FragmentProgramData += Ogre::String(
2985  "vec3 view_vector = normalize(Position_-uCameraPos);\n") +
2986  "float dot_product = dot(view_vector, -uLightDirection);\n"+
2987  "float num = uHGg.x;\n"+
2988  "float den = (uHGg.y - uHGg.z*dot_product);\n"+
2989  "den = inversesqrt(den);\n"+
2990  "float phase = num * pow(den, 3.0);\n"+
2991  "gl_FragColor.xyz += (0.15 + uIntensity*texture2D(uDepthMap, UV).z)*phase*uSunColor;";
2992  }
2993  }
2994  else if (cDepth) // Depth, no caustics
2995  {
2996  FragmentProgramData +=
2997  "gl_FragColor = vec4(mix(uWaterColor,texture2D(uOriginalMap, UV+distortUV).xyz,texture2D(uDepthMap, UV+distortUV).r),1.0);\n";
2998  if (cGodRays)
2999  {
3000  FragmentProgramData += Ogre::String(
3001  "vec3 view_vector = normalize(Position_-uCameraPos);\n") +
3002  "float dot_product = dot(view_vector, -uLightDirection);\n"+
3003  "float num = uHGg.x;\n"+
3004  "float den = (uHGg.y - uHGg.z*dot_product);\n"+
3005  "den = inversesqrt(den);\n"+
3006  "float phase = num * pow(den, 3.0);\n"+
3007  "gl_FragColor.xyz += (0.15 + uIntensity*texture2D(uDepthMap, UV).z)*phase*uSunColor;\n";
3008  }
3009  }
3010  else // No depth, no caustics
3011  {
3012  FragmentProgramData +=
3013  "gl_FragColor = texture2D(uOriginalMap, UV+distortUV);\n";
3014  }
3015  FragmentProgramData +=
3016  "}\n";
3017  }
3018  break;
3019  }
3020 
3021  // Build our material
3022  Ogre::MaterialPtr &UnderwaterCompositorMaterial = getMaterial(MAT_UNDERWATER_COMPOSITOR);
3023  UnderwaterCompositorMaterial = Ogre::MaterialManager::getSingleton().
3025  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
3026 
3027  Ogre::Pass *DM_Technique0_Pass0 = UnderwaterCompositorMaterial->getTechnique(0)->getPass(0);
3028 
3029  DM_Technique0_Pass0->setCullingMode(Ogre::CULL_NONE);
3030  DM_Technique0_Pass0->setDepthFunction(Ogre::CMPF_ALWAYS_PASS);
3031 
3032  Ogre::String GpuProgramsData[2] = {VertexProgramData, FragmentProgramData};
3034  Ogre::String EntryPoints[2];
3035  if(Options.SM == SM_GLSL)
3036  {
3037  EntryPoints[0] = Ogre::String("main");
3038  EntryPoints[1] = Ogre::String("main");
3039  }
3040  else
3041  {
3042  EntryPoints[0] = Ogre::String("main_vp");
3043  EntryPoints[1] = Ogre::String("main_fp");
3044  }
3045 
3046  fillGpuProgramsToPass(DM_Technique0_Pass0, GpuProgramNames, Options.SM, EntryPoints, GpuProgramsData);
3047 
3048  Ogre::GpuProgramParametersSharedPtr VP_Parameters = DM_Technique0_Pass0->getVertexProgramParameters();
3049  Ogre::GpuProgramParametersSharedPtr FP_Parameters = DM_Technique0_Pass0->getFragmentProgramParameters();
3050 
3051  if(Options.SM != SM_GLSL)
3052  {
3053  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
3054  }
3055 
3056  FP_Parameters->setNamedConstantFromTime("uTime", 0.1f);
3057  FP_Parameters->setNamedConstant("uWaterColor", mHydrax->getWaterColor());
3058 
3059  if (cCaustics)
3060  {
3061  FP_Parameters->setNamedConstant("uCausticsPower", mHydrax->getCausticsPower());
3062  }
3063 
3064  if (cGodRays)
3065  {
3066  FP_Parameters->setNamedConstant("uSunColor", mHydrax->getSunColor());
3067  FP_Parameters->setNamedConstant("uLightDirection",
3068  (mHydrax->getMesh()->getObjectSpacePosition(mHydrax->getCamera()->getPosition()) -
3070  .normalisedCopy());
3071  FP_Parameters->setNamedConstant("uIntensity", mHydrax->getGodRaysIntensity());
3072  FP_Parameters->setNamedConstant("uHGg", mHydrax->getGodRaysExposure());
3073  FP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION);
3074  }
3075 
3076  // From compositor, original scene
3077  int GLSLTextUnit = 0;
3078  if(Options.SM == SM_GLSL)
3079  {
3080  FP_Parameters->setNamedConstant("uOriginalMap", GLSLTextUnit);
3081  GLSLTextUnit++;
3082  }
3083  DM_Technique0_Pass0->createTextureUnitState()->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
3084  if(Options.SM == SM_GLSL)
3085  {
3086  FP_Parameters->setNamedConstant("uDistortMap", GLSLTextUnit);
3087  GLSLTextUnit++;
3088  }
3089  DM_Technique0_Pass0->createTextureUnitState("UnderwaterDistortion.jpg")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
3090  if (cDepth)
3091  {
3092  if(Options.SM == SM_GLSL)
3093  {
3094  FP_Parameters->setNamedConstant("uDepthMap", GLSLTextUnit);
3095  GLSLTextUnit++;
3096  }
3097  DM_Technique0_Pass0->createTextureUnitState("HydraxDepthMap")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
3098  //Ogre::Viewport *Viewport = mHydrax->getCamera()->getViewport();
3099  }
3100 
3101  UnderwaterCompositorMaterial->setReceiveShadows(false);
3102  UnderwaterCompositorMaterial->load();
3103 
3104  Ogre::CompositorPtr &UnderwaterCompositor = getCompositor(COMP_UNDERWATER);
3105  UnderwaterCompositor = Ogre::CompositorManager::getSingleton().
3106  create(_def_Underwater_Compositor_Name, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
3107 
3108  Ogre::CompositionTechnique* UnderWaterComp_Technique = UnderwaterCompositor->createTechnique();
3109 
3110  // Create the texture definition to render the original scene
3111  Ogre::CompositionTechnique::TextureDefinition* TDef = UnderWaterComp_Technique->createTextureDefinition("OriginalScene");
3112  TDef->width = 0;
3113  TDef->height = 0;
3114  Ogre::PixelFormatList l;
3115  l.push_back(Ogre::PF_A8R8G8B8);
3116  TDef->formatList = l;
3117 
3118  // Render the original scene
3119  Ogre::CompositionTargetPass* CTPass = UnderWaterComp_Technique->createTargetPass();
3120  CTPass->setInputMode(Ogre::CompositionTargetPass::IM_NONE);
3121  CTPass->setOutputName("OriginalScene");
3122  Ogre::CompositionPass* CPassClear = CTPass->createPass();
3123  CPassClear->setType(Ogre::CompositionPass::PT_CLEAR);
3124 
3125  const Ogre::Vector3& WC = mHydrax->getWaterColor();
3126  CPassClear->setClearColour(Ogre::ColourValue(WC.x, WC.y, WC.z));
3127 
3128  Ogre::CompositionPass* CPass = CTPass->createPass();
3129  CPass->setType(Ogre::CompositionPass::PT_RENDERSCENE);
3130  CPass->setFirstRenderQueue(Ogre::RENDER_QUEUE_SKIES_EARLY+1);
3131 
3132  // Build the output target pass
3133  Ogre::CompositionTargetPass* CTOutputPass = UnderWaterComp_Technique->getOutputTargetPass();
3134  CTOutputPass->setInputMode(Ogre::CompositionTargetPass::IM_NONE);
3135 
3136  // Final composition pass
3137  Ogre::CompositionPass* COutputPass = CTOutputPass->createPass();
3138  COutputPass->setType(Ogre::CompositionPass::PT_RENDERQUAD);
3139  COutputPass->setMaterial(getMaterial(MAT_UNDERWATER_COMPOSITOR));
3140  COutputPass->setInput(0, "OriginalScene");
3141  COutputPass->setLastRenderQueue(0);
3142 
3143  Ogre::CompositorManager::getSingleton().
3145  addListener(&mUnderwaterCompositorListener);
3146 
3147  return true;
3148  }
3149 
3150  bool MaterialManager::_createSimpleColorMaterial(const Ogre::ColourValue& Color, const MaterialType& MT, const Ogre::String& Name, const bool& DepthCheck, const bool& DepthWrite)
3151  {
3152  Ogre::MaterialPtr &SimpleColorMaterial = getMaterial(MT);
3153  SimpleColorMaterial = Ogre::MaterialManager::getSingleton().
3154  create(Name,
3155  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
3156 
3157  Ogre::Pass *SCM_T0_Pass0 = SimpleColorMaterial->getTechnique(0)->getPass(0);
3158  SCM_T0_Pass0->setLightingEnabled(false);
3159  SCM_T0_Pass0->setDepthCheckEnabled(DepthCheck);
3160  SCM_T0_Pass0->setDepthWriteEnabled(DepthWrite);
3161  SCM_T0_Pass0->setCullingMode(Ogre::CULL_NONE);
3162  SCM_T0_Pass0->createTextureUnitState()->setColourOperationEx(Ogre::LBX_MODULATE,Ogre::LBS_MANUAL,Ogre::LBS_CURRENT, Color);
3163 
3164  SimpleColorMaterial->setReceiveShadows(false);
3165  SimpleColorMaterial->load();
3166 
3167  return true;
3168  }
3169 
3171  {
3172  Ogre::MaterialPtr &Mat = getMaterial(Material);
3173 
3174  if (!Mat)
3175  {
3176  return;
3177  }
3178 
3179  Mat->reload();
3180 
3181  const bool cDepth = _isComponent(mComponents, HYDRAX_COMPONENT_DEPTH );
3182  const bool cSmooth = _isComponent(mComponents, HYDRAX_COMPONENT_SMOOTH );
3183  const bool cSun = _isComponent(mComponents, HYDRAX_COMPONENT_SUN );
3184  const bool cFoam = _isComponent(mComponents, HYDRAX_COMPONENT_FOAM );
3185  const bool cCaustics = _isComponent(mComponents, HYDRAX_COMPONENT_CAUSTICS);
3187 
3188  switch (Material)
3189  {
3190  case MAT_WATER:
3191  {
3192  Ogre::Pass *M_Technique0_Pass0 = Mat->getTechnique(0)->getPass(0);
3193 
3194  switch (mOptions.NM)
3195  {
3196  case NM_TEXTURE: case NM_RTT:
3197  {
3198  M_Technique0_Pass0->getTextureUnitState(0)->setTextureName("HydraxNormalMap");
3199  M_Technique0_Pass0->getTextureUnitState(1)->setTextureName("HydraxReflectionMap");
3200  M_Technique0_Pass0->getTextureUnitState(2)->setTextureName("HydraxRefractionMap");
3201  if (cDepth)
3202  {
3203  M_Technique0_Pass0->getTextureUnitState(3)->setTextureName("HydraxDepthMap");
3204  }
3205  }
3206  break;
3207 
3208  case NM_VERTEX:
3209  {
3210  M_Technique0_Pass0->getTextureUnitState(0)->setTextureName("HydraxReflectionMap");
3211  M_Technique0_Pass0->getTextureUnitState(1)->setTextureName("HydraxRefractionMap");
3212  if (cDepth)
3213  {
3214  M_Technique0_Pass0->getTextureUnitState(2)->setTextureName("HydraxDepthMap");
3215  }
3216  }
3217  break;
3218  }
3219 
3220  Ogre::GpuProgramParametersSharedPtr VP_Parameters = M_Technique0_Pass0->getVertexProgramParameters();
3221  Ogre::GpuProgramParametersSharedPtr FP_Parameters = M_Technique0_Pass0->getFragmentProgramParameters();
3222 
3223  if(mOptions.SM != SM_GLSL)
3224  {
3225  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
3226  }
3227  if (cFoam)
3228  {
3229  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
3230  }
3231  FP_Parameters->setNamedAutoConstant("uEyePosition", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
3232 
3233  FP_Parameters->setNamedConstant("uFullReflectionDistance", mHydrax->getFullReflectionDistance());
3234  FP_Parameters->setNamedConstant("uGlobalTransparency", mHydrax->getGlobalTransparency());
3235  FP_Parameters->setNamedConstant("uNormalDistortion", mHydrax->getNormalDistortion());
3236 
3237  FP_Parameters->setNamedConstant("uWaterColor", mHydrax->getWaterColor());
3238  if (cSmooth)
3239  {
3240  FP_Parameters->setNamedConstant("uSmoothPower", mHydrax->getSmoothPower());
3241  }
3242  if (cSun)
3243  {
3244  FP_Parameters->setNamedConstant("uSunPosition", mHydrax->getMesh()->getObjectSpacePosition(mHydrax->getSunPosition()));
3245  FP_Parameters->setNamedConstant("uSunStrength", mHydrax->getSunStrength());
3246  FP_Parameters->setNamedConstant("uSunArea", mHydrax->getSunArea());
3247  FP_Parameters->setNamedConstant("uSunColor", mHydrax->getSunColor());
3248  }
3249  if (cFoam)
3250  {
3251  FP_Parameters->setNamedConstant("uFoamRange", mHydrax->getMesh()->getOptions().MeshStrength);
3252  FP_Parameters->setNamedConstant("uFoamMaxDistance", mHydrax->getFoamMaxDistance());
3253  FP_Parameters->setNamedConstant("uFoamScale", mHydrax->getFoamScale());
3254  FP_Parameters->setNamedConstant("uFoamStart", mHydrax->getFoamStart());
3255  FP_Parameters->setNamedConstant("uFoamTransparency", mHydrax->getFoamTransparency());
3256  }
3257  if (cCaustics)
3258  {
3259  FP_Parameters->setNamedConstant("uCausticsPower", mHydrax->getCausticsPower());
3260  }
3261  }
3262  break;
3263 
3264  case MAT_DEPTH:
3265  {
3266  Ogre::Pass *M_Technique0_Pass0 = Mat->getTechnique(0)->getPass(0);
3267 
3268  Ogre::GpuProgramParametersSharedPtr VP_Parameters = M_Technique0_Pass0->getVertexProgramParameters();
3269  Ogre::GpuProgramParametersSharedPtr FP_Parameters = M_Technique0_Pass0->getFragmentProgramParameters();
3270 
3271  if(mOptions.SM != SM_GLSL)
3272  {
3273  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
3274  // VP_Parameters->setNamedAutoConstant("uWorldView", Ogre::GpuProgramParameters::ACT_WORLDVIEW_MATRIX);
3275  VP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION);
3276  }
3277  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
3278  VP_Parameters->setNamedConstant("uPlaneYPos", mHydrax->getPosition().y);
3279  VP_Parameters->setNamedConstant("uPlanesError", (float) mHydrax->getPlanesError());
3280 
3281  FP_Parameters->setNamedConstant("uDepthLimit", 1.f/mHydrax->getDepthLimit());
3282  FP_Parameters->setNamedConstant("uDistLimit", 1.f/mHydrax->getDistLimit());
3283 
3284  if (cCaustics)
3285  {
3286  FP_Parameters->setNamedConstant("uCausticsScale", mHydrax->getCausticsScale());
3287  FP_Parameters->setNamedConstant("uCausticsEnd", mHydrax->getCausticsEnd());
3288  }
3289  }
3290  break;
3291 
3292  case MAT_UNDERWATER:
3293  {
3294  Ogre::Pass *M_Technique0_Pass0 = Mat->getTechnique(0)->getPass(0);
3295 
3296  switch (mOptions.NM)
3297  {
3298  case NM_TEXTURE: case NM_RTT:
3299  {
3300  M_Technique0_Pass0->getTextureUnitState(0)->setTextureName("HydraxNormalMap");
3301  int Index = 1;
3302  if (cUReflections)
3303  {
3304  M_Technique0_Pass0->getTextureUnitState(Index)->setTextureName("HydraxReflectionMap");
3305  Index++;
3306  }
3307  M_Technique0_Pass0->getTextureUnitState(Index)->setTextureName("HydraxRefractionMap");
3308  Index++;
3309  if (cDepth && cUReflections)
3310  {
3311  M_Technique0_Pass0->getTextureUnitState(Index)->setTextureName("HydraxDepthReflectionMap");
3312  }
3313  }
3314  break;
3315 
3316  case NM_VERTEX:
3317  {
3318  int Index = 0;
3319  if (cUReflections)
3320  {
3321  M_Technique0_Pass0->getTextureUnitState(Index)->setTextureName("HydraxReflectionMap");
3322  Index++;
3323  }
3324  M_Technique0_Pass0->getTextureUnitState(Index)->setTextureName("HydraxRefractionMap");
3325  Index++;
3326  if (cDepth && cUReflections)
3327  {
3328  M_Technique0_Pass0->getTextureUnitState(Index)->setTextureName("HydraxDepthReflectionMap");
3329  }
3330  }
3331  break;
3332  }
3333 
3334  Ogre::GpuProgramParametersSharedPtr VP_Parameters = M_Technique0_Pass0->getVertexProgramParameters();
3335  Ogre::GpuProgramParametersSharedPtr FP_Parameters = M_Technique0_Pass0->getFragmentProgramParameters();
3336 
3337  if(mOptions.SM != SM_GLSL)
3338  {
3339  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
3340  VP_Parameters->setNamedAutoConstant("uWorldView", Ogre::GpuProgramParameters::ACT_WORLDVIEW_MATRIX);
3341  VP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
3342  }
3343  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
3344  FP_Parameters->setNamedAutoConstant("uEyePosition", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
3345 
3346  FP_Parameters->setNamedConstant("uFullReflectionDistance", mHydrax->getFullReflectionDistance());
3347  FP_Parameters->setNamedConstant("uGlobalTransparency", mHydrax->getGlobalTransparency());
3348  FP_Parameters->setNamedConstant("uNormalDistortion", mHydrax->getNormalDistortion());
3349  FP_Parameters->setNamedConstant("uDistLimit", 1.f/mHydrax->getDistLimit());
3350 
3351  if ((cDepth && cUReflections) || (!cUReflections))
3352  {
3353  FP_Parameters->setNamedConstant("uWaterColor", mHydrax->getWaterColor());
3354  }
3355 
3356  if (cSun)
3357  {
3358  FP_Parameters->setNamedConstant("uSunPosition", mHydrax->getMesh()->getObjectSpacePosition(mHydrax->getSunPosition()));
3359  FP_Parameters->setNamedConstant("uSunStrength", mHydrax->getSunStrength());
3360  FP_Parameters->setNamedConstant("uSunArea", mHydrax->getSunArea());
3361  FP_Parameters->setNamedConstant("uSunColor", mHydrax->getSunColor());
3362  FP_Parameters->setNamedConstant("uDepthLimit", 1.f/mHydrax->getDistLimit());
3363  }
3364  /* Foam is not visible underwater
3365  if (cFoam)
3366  {
3367  FP_Parameters->setNamedConstant("uFoamRange", mHydrax->getMesh()->getOptions().MeshStrength);
3368  FP_Parameters->setNamedConstant("uFoamMaxDistance", mHydrax->getFoamMaxDistance());
3369  FP_Parameters->setNamedConstant("uFoamScale", mHydrax->getFoamScale());
3370  FP_Parameters->setNamedConstant("uFoamStart", mHydrax->getFoamStart());
3371  FP_Parameters->setNamedConstant("uFoamTransparency", mHydrax->getFoamTransparency());
3372  }
3373  */
3374  if (cCaustics && cDepth && cUReflections)
3375  {
3376  FP_Parameters->setNamedConstant("uCausticsPower", mHydrax->getCausticsPower());
3377  }
3378  }
3379  break;
3380 
3382  {
3384  }
3385  break;
3386 
3387  case MAT_SIMPLE_RED:
3388  {
3389  }
3390  break;
3391  case MAT_SIMPLE_BLACK:
3392  {
3393  }
3394  break;
3395  }
3396  }
3397 
3398  void MaterialManager::addDepthTechnique(Ogre::Technique *Technique, const bool& AutoUpdate)
3399  {
3400  if (!Ogre::MaterialManager::getSingleton().resourceExists(_def_Depth_Material_Name))
3401  {
3403  }
3404 
3405  Technique->removeAllPasses();
3406  Technique->createPass();
3407  Technique->setName("_Hydrax_Depth_Technique");
3408  Technique->setSchemeName("HydraxDepth");
3409 
3410  Ogre::Pass *DM_Technique_Pass0 = Technique->getPass(0);
3411 
3412  DM_Technique_Pass0->setVertexProgram(_def_Depth_Shader_VP_Name);
3413  DM_Technique_Pass0->setFragmentProgram(_def_Depth_Shader_FP_Name);
3414 
3415  Ogre::GpuProgramParametersSharedPtr VP_Parameters = DM_Technique_Pass0->getVertexProgramParameters();
3416  Ogre::GpuProgramParametersSharedPtr FP_Parameters = DM_Technique_Pass0->getFragmentProgramParameters();
3417 
3418  if(mOptions.SM != SM_GLSL)
3419  {
3420  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
3421  VP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION);
3422  }
3423  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
3424  VP_Parameters->setNamedConstant("uPlaneYPos", mHydrax->getPosition().y);
3425  VP_Parameters->setNamedConstant("uPlanesError", (float) mHydrax->getPlanesError());
3426 
3427  FP_Parameters->setNamedConstant("uDepthLimit", 1/mHydrax->getDepthLimit());
3428  FP_Parameters->setNamedConstant("uDistLimit", 1/mHydrax->getDistLimit());
3429 
3431  {
3432  FP_Parameters->setNamedConstant("uCausticsScale", mHydrax->getCausticsScale());
3433  FP_Parameters->setNamedConstant("uCausticsEnd", mHydrax->getCausticsEnd());
3434 
3435  if(mOptions.SM == SM_GLSL)
3436  {
3437  FP_Parameters->setNamedConstant("uCaustics", 0);
3438  }
3439  Ogre::TextureUnitState* TUS_Caustics = DM_Technique_Pass0->createTextureUnitState("Caustics.bmp");
3440  TUS_Caustics->setName("Caustics");
3441  TUS_Caustics->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
3442  // To account for variable sim. time, we must update animation manually.
3443  TUS_Caustics->setAnimatedTextureName("Caustics.bmp", 32);
3444  mCausticsAnimTexVec.push_back(TUS_Caustics);
3445  }
3446 
3447  if (AutoUpdate)
3448  {
3449  mDepthTechniques.push_back(Technique);
3450  }
3451  }
3452 
3453  void MaterialManager::addDepthTextureTechnique(Ogre::Technique *Technique, const Ogre::String& TextureName, const Ogre::String& AlphaChannel, const bool& AutoUpdate)
3454  {
3455  if (!Ogre::HighLevelGpuProgramManager::getSingleton().resourceExists(_def_DepthTexture_Shader_VP_Name+AlphaChannel))
3456  {
3458  }
3459 
3460  Technique->removeAllPasses();
3461  Technique->createPass();
3462  Technique->setName("_Hydrax_DepthTexture_Technique");
3463  Technique->setSchemeName("HydraxDepth");
3464 
3465  Ogre::Pass *DM_Technique_Pass0 = Technique->getPass(0);
3466 
3467  // Alpha channel will be stored in pass 0 name:
3468  DM_Technique_Pass0->setName(AlphaChannel);
3469 
3470  DM_Technique_Pass0->setVertexProgram(_def_DepthTexture_Shader_VP_Name+AlphaChannel);
3471  DM_Technique_Pass0->setFragmentProgram(_def_DepthTexture_Shader_FP_Name+AlphaChannel);
3472 
3473  DM_Technique_Pass0->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
3474  DM_Technique_Pass0->setDepthCheckEnabled(true);
3475  DM_Technique_Pass0->setDepthWriteEnabled(false);
3476 
3477  Ogre::GpuProgramParametersSharedPtr VP_Parameters = DM_Technique_Pass0->getVertexProgramParameters();
3478  Ogre::GpuProgramParametersSharedPtr FP_Parameters = DM_Technique_Pass0->getFragmentProgramParameters();
3479 
3480  if(mOptions.SM != SM_GLSL)
3481  {
3482  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
3483  VP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION);
3484  }
3485  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
3486  VP_Parameters->setNamedConstant("uPlaneYPos", mHydrax->getPosition().y);
3487  VP_Parameters->setNamedConstant("uPlanesError", (float) mHydrax->getPlanesError());
3488 
3489  FP_Parameters->setNamedConstant("uDepthLimit", 1/mHydrax->getDepthLimit());
3490  FP_Parameters->setNamedConstant("uDistLimit", 1/mHydrax->getDistLimit());
3491 
3493  {
3494  FP_Parameters->setNamedConstant("uCausticsScale", mHydrax->getCausticsScale());
3495  FP_Parameters->setNamedConstant("uCausticsEnd", mHydrax->getCausticsEnd());
3496 
3497  if(mOptions.SM == SM_GLSL)
3498  {
3499  FP_Parameters->setNamedConstant("uCaustics", 0);
3500  }
3501  Ogre::TextureUnitState *TUS_Caustics = DM_Technique_Pass0->createTextureUnitState("Caustics.bmp");
3502  TUS_Caustics->setName("Caustics");
3503  TUS_Caustics->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
3504  // To account for variable sim. time, we must update animation manually.
3505  TUS_Caustics->setAnimatedTextureName("Caustics.bmp", 32);
3506  mCausticsAnimTexVec.push_back(TUS_Caustics);
3507  }
3508 
3509  if(mOptions.SM == SM_GLSL)
3510  {
3511  FP_Parameters->setNamedConstant("uAlphaTex", 0);
3512  }
3513  Ogre::TextureUnitState *TUS_AlphaTex = DM_Technique_Pass0->createTextureUnitState(TextureName);
3514  TUS_AlphaTex->setName("_DetphTexture_Hydrax");
3515  TUS_AlphaTex->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
3516 
3517  if (AutoUpdate)
3518  {
3519  mDepthTechniques.push_back(Technique);
3520  }
3521  }
3522 
3523  void MaterialManager::setCompositorEnable(const CompositorType &Compositor, const bool &Enable)
3524  {
3525  Ogre::CompositorPtr &Comp = mCompositors[static_cast<int>(Compositor)];
3526 
3527  if (!Comp)
3528  {
3529  return;
3530  }
3531 
3532  Ogre::CompositorManager::getSingleton().
3533  setCompositorEnabled(mHydrax->getViewport(), Comp->getName(), Enable);
3534 
3535  mCompositorsEnable[static_cast<int>(Compositor)] = Enable;
3536  }
3537 
3538  bool MaterialManager::_isComponent(const HydraxComponent &List, const HydraxComponent &ToCheck) const
3539  {
3540  if (List & ToCheck)
3541  {
3542  return true;
3543  }
3544 
3545  if (ToCheck == HYDRAX_COMPONENTS_NONE && List == HYDRAX_COMPONENTS_NONE)
3546  {
3547  return true;
3548  }
3549 
3550  if (ToCheck == HYDRAX_COMPONENTS_ALL && List == HYDRAX_COMPONENTS_ALL)
3551  {
3552  return true;
3553  }
3554 
3555  return false;
3556  }
3557 
3558  void MaterialManager::setGpuProgramParameter(const GpuProgram &GpuP, const MaterialType &MType, const Ogre::String &Name, const Ogre::Real &Value)
3559  {
3560  if (!mCreated)
3561  {
3562  return;
3563  }
3564 
3565  Ogre::GpuProgramParametersSharedPtr Parameters;
3566 
3567  switch (GpuP)
3568  {
3569  case GPUP_VERTEX:
3570  {
3571  Parameters = getMaterial(MType)->getTechnique(0)->getPass(0)->getVertexProgramParameters();
3572  }
3573  break;
3574 
3575  case GPUP_FRAGMENT:
3576  {
3577  Parameters = getMaterial(MType)->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
3578  }
3579  break;
3580  }
3581 
3582  Parameters->setNamedConstant(Name, Value);
3583 
3584  if (MType == MAT_DEPTH)
3585  {
3586  std::vector<Ogre::Technique*>::iterator TechIt;
3587 
3588  for(TechIt = mDepthTechniques.begin(); TechIt != mDepthTechniques.end(); TechIt++)
3589  {
3590  if (!(*TechIt))
3591  {
3592  mDepthTechniques.erase(TechIt);
3593  continue;
3594  }
3595 
3596  switch (GpuP)
3597  {
3598  case GPUP_VERTEX:
3599  {
3600  Parameters = (*TechIt)->getPass(0)->getVertexProgramParameters();
3601  }
3602  break;
3603 
3604  case GPUP_FRAGMENT:
3605  {
3606  Parameters = (*TechIt)->getPass(0)->getFragmentProgramParameters();
3607  }
3608  break;
3609  }
3610 
3611  Parameters->setNamedConstant(Name, Value);
3612  }
3613  }
3614  }
3615 
3616  void MaterialManager::setGpuProgramParameter(const GpuProgram &GpuP, const MaterialType &MType, const Ogre::String &Name, const Ogre::Vector2 &Value)
3617  {
3618  if (!mCreated)
3619  {
3620  return;
3621  }
3622 
3623  Ogre::GpuProgramParametersSharedPtr Parameters;
3624 
3625  switch (GpuP)
3626  {
3627  case GPUP_VERTEX:
3628  {
3629  Parameters = getMaterial(MType)->getTechnique(0)->getPass(0)->getVertexProgramParameters();
3630  }
3631  break;
3632 
3633  case GPUP_FRAGMENT:
3634  {
3635  Parameters = getMaterial(MType)->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
3636  }
3637  break;
3638  }
3639 
3640  float Value_[2] = {Value.x, Value.y};
3641 
3642  if (MType == MAT_DEPTH)
3643  {
3644  std::vector<Ogre::Technique*>::iterator TechIt;
3645 
3646  for(TechIt = mDepthTechniques.begin(); TechIt != mDepthTechniques.end(); TechIt++)
3647  {
3648  if (!(*TechIt))
3649  {
3650  mDepthTechniques.erase(TechIt);
3651  continue;
3652  }
3653 
3654  switch (GpuP)
3655  {
3656  case GPUP_VERTEX:
3657  {
3658  Parameters = (*TechIt)->getPass(0)->getVertexProgramParameters();
3659  }
3660  break;
3661 
3662  case GPUP_FRAGMENT:
3663  {
3664  Parameters = (*TechIt)->getPass(0)->getFragmentProgramParameters();
3665  }
3666  break;
3667  }
3668 
3669  Parameters->setNamedConstant(Name, Value_, 1, 2);
3670  }
3671  }
3672  }
3673 
3674  void MaterialManager::setGpuProgramParameter(const GpuProgram &GpuP, const MaterialType &MType, const Ogre::String &Name, const Ogre::Vector3 &Value)
3675  {
3676  if (!mCreated)
3677  {
3678  return;
3679  }
3680 
3681  Ogre::GpuProgramParametersSharedPtr Parameters;
3682 
3683  switch (GpuP)
3684  {
3685  case GPUP_VERTEX:
3686  {
3687  Parameters = getMaterial(MType)->getTechnique(0)->getPass(0)->getVertexProgramParameters();
3688  }
3689  break;
3690 
3691  case GPUP_FRAGMENT:
3692  {
3693  Parameters = getMaterial(MType)->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
3694  }
3695  break;
3696  }
3697 
3698  Parameters->setNamedConstant(Name, Value);
3699 
3700  if (MType == MAT_DEPTH)
3701  {
3702  std::vector<Ogre::Technique*>::iterator TechIt;
3703 
3704  for(TechIt = mDepthTechniques.begin(); TechIt != mDepthTechniques.end(); TechIt++)
3705  {
3706  if (!(*TechIt))
3707  {
3708  mDepthTechniques.erase(TechIt);
3709  continue;
3710  }
3711 
3712  switch (GpuP)
3713  {
3714  case GPUP_VERTEX:
3715  {
3716  Parameters = (*TechIt)->getPass(0)->getVertexProgramParameters();
3717  }
3718  break;
3719 
3720  case GPUP_FRAGMENT:
3721  {
3722  Parameters = (*TechIt)->getPass(0)->getFragmentProgramParameters();
3723  }
3724  break;
3725  }
3726 
3727  Parameters->setNamedConstant(Name, Value);
3728  }
3729  }
3730  }
3731 
3732  void MaterialManager::UnderwaterCompositorListener::notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat)
3733  {
3735  {
3736  Ogre::Pass* DM_Technique0_Pass0 = mat->getTechnique(0)->getPass(0);
3737  DM_Technique0_Pass0->getTextureUnitState(2)->setTextureName("HydraxDepthMap");
3738  }
3739  }
3740 
3741  void MaterialManager::UnderwaterCompositorListener::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat)
3742  {
3743  const Ogre::Vector3& WC = mMaterialManager->mHydrax->getWaterColor();
3744  Ogre::CompositorPtr &UnderwaterCompositor = mMaterialManager->getCompositor(COMP_UNDERWATER);
3745  UnderwaterCompositor->getTechnique(0)->getTargetPass(0)->getPass(0)->setClearColour(Ogre::ColourValue(WC.x, WC.y, WC.z));
3746 
3747  Ogre::GpuProgramParametersSharedPtr FP_Parameters = mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
3748 
3749  if (mMaterialManager->mHydrax->isComponent(HYDRAX_COMPONENT_DEPTH))
3750  {
3751  FP_Parameters->
3752  setNamedConstant("uWaterColor", mMaterialManager->mHydrax->getWaterColor());
3753  }
3754 
3755  if (mMaterialManager->mHydrax->isComponent(HYDRAX_COMPONENT_CAUSTICS))
3756  {
3757  FP_Parameters->
3758  setNamedConstant("uCausticsPower", mMaterialManager->mHydrax->getCausticsPower());
3759  }
3760 
3761  if (mMaterialManager->mHydrax->isComponent(HYDRAX_COMPONENT_UNDERWATER_GODRAYS))
3762  {
3763  FP_Parameters->
3764  setNamedConstant("uSunColor", mMaterialManager->mHydrax->getSunColor());
3765 
3766  FP_Parameters->setNamedConstant("uLightDirection",
3767  (mMaterialManager->mHydrax->getMesh()->getObjectSpacePosition(mMaterialManager->mHydrax->getCamera()->getPosition()) -
3768  mMaterialManager->mHydrax->getMesh()->getObjectSpacePosition(mMaterialManager->mHydrax->getSunPosition()))
3769  .normalisedCopy());
3770 
3771  FP_Parameters->setNamedConstant("uIntensity", mMaterialManager->mHydrax->getGodRaysIntensity());
3772  FP_Parameters->setNamedConstant("uHGg", mMaterialManager->mHydrax->getGodRaysExposure());
3773 
3774  Ogre::GpuProgramParametersSharedPtr VP_Parameters = mat->getTechnique(0)->getPass(0)->getVertexProgramParameters();
3775 
3776  // FAR_LEFT_TOP
3777  VP_Parameters->
3778  setNamedConstant( "uCorner0", mMaterialManager->mHydrax->getCamera()->getWorldSpaceCorners()[5] );
3779  // FAR_RIGHT_TOP - FAR_LEFT_TOP
3780  VP_Parameters->
3781  setNamedConstant( "uCorner01", mMaterialManager->mHydrax->getCamera()->getWorldSpaceCorners()[4] - mMaterialManager->mHydrax->getCamera()->getWorldSpaceCorners()[5]);
3782  // FAR_LEFT_BOTTOM - FAR_LEFT_TOP
3783  VP_Parameters->
3784  setNamedConstant( "uCorner02", mMaterialManager->mHydrax->getCamera()->getWorldSpaceCorners()[6] - mMaterialManager->mHydrax->getCamera()->getWorldSpaceCorners()[5]);
3785  }
3786 
3787  /*
3788  if (mMaterialManager->_isComponent(mMaterialManager->mComponents, HYDRAX_COMPONENT_DEPTH))
3789  {
3790  Ogre::Viewport *Viewport = mMaterialManager->mHydrax->getCamera()->getViewport();
3791  }
3792  */
3793 
3794  if (mMaterialManager->mCompositorsNeedToBeReloaded[COMP_UNDERWATER])
3795  {
3796  if (mMaterialManager->_isComponent(mMaterialManager->mComponents, HYDRAX_COMPONENT_DEPTH))
3797  {
3798  Ogre::Pass* DM_Technique0_Pass0 = mat->getTechnique(0)->getPass(0);
3799  DM_Technique0_Pass0->getTextureUnitState(2)->setTextureName("HydraxDepthMap");
3800  }
3801 
3802  mMaterialManager->mCompositorsNeedToBeReloaded[COMP_UNDERWATER] = false;
3803  }
3804  }
3805 }
Hydrax::MaterialManager::removeCompositor
void removeCompositor()
Remove compositor.
Definition: MaterialManager.cpp:147
Hydrax::Mesh::getOptions
const Options & getOptions() const
Get options.
Definition: Mesh.h:229
Hydrax::MaterialManager::MAT_UNDERWATER
@ MAT_UNDERWATER
Definition: MaterialManager.h:57
_def_Water_Material_Name
#define _def_Water_Material_Name
Definition: MaterialManager.cpp:36
Hydrax::MaterialManager::NM_TEXTURE
@ NM_TEXTURE
Definition: MaterialManager.h:103
Hydrax::Hydrax::getSunStrength
const Ogre::Real & getSunStrength() const
Get water strength.
Definition: Hydrax.h:492
Hydrax::MaterialManager::mOptions
Options mOptions
Actual material options.
Definition: MaterialManager.h:375
Hydrax::Hydrax::getWaterColor
const Ogre::Vector3 & getWaterColor() const
Get water color.
Definition: Hydrax.h:476
Hydrax::MaterialManager::mCausticsAnimCurrentFrameElapsedTime
float mCausticsAnimCurrentFrameElapsedTime
Time spent on current animation frame, cumulative.
Definition: MaterialManager.h:384
Hydrax::MaterialManager::mMaterials
Ogre::MaterialPtr mMaterials[6]
Hydrax materials vector.
Definition: MaterialManager.h:363
Hydrax::MaterialManager::mCompositors
Ogre::CompositorPtr mCompositors[1]
Hydrax compositors vector.
Definition: MaterialManager.h:365
Hydrax::HYDRAX_COMPONENT_FOAM
@ HYDRAX_COMPONENT_FOAM
Definition: Enums.h:60
Hydrax::HYDRAX_COMPONENT_UNDERWATER_REFLECTIONS
@ HYDRAX_COMPONENT_UNDERWATER_REFLECTIONS
Underwater reflections and god rays need underwater component.
Definition: Enums.h:67
_def_DepthTexture_Shader_FP_Name
#define _def_DepthTexture_Shader_FP_Name
Definition: MaterialManager.cpp:45
Hydrax::MaterialManager::SM_GLSL
@ SM_GLSL
Definition: MaterialManager.h:95
Hydrax::HYDRAX_COMPONENTS_ALL
@ HYDRAX_COMPONENTS_ALL
Definition: Enums.h:71
Hydrax::Hydrax::getPosition
const Ogre::Vector3 & getPosition() const
Get water position.
Definition: Hydrax.h:413
Hydrax::MaterialManager::getMaterial
Ogre::MaterialPtr & getMaterial(const MaterialType &Material)
Get material.
Definition: MaterialManager.h:221
Hydrax::Hydrax::getPlanesError
const Ogre::Real & getPlanesError() const
Get current clip planes error.
Definition: Hydrax.h:421
Hydrax::Hydrax::getMesh
Mesh * getMesh()
Get Hydrax::Mesh.
Definition: Hydrax.h:317
Hydrax::Hydrax::getFoamTransparency
const Ogre::Real & getFoamTransparency() const
Get foam transparency.
Definition: Hydrax.h:540
Hydrax::MaterialManager::_createDepthMaterial
bool _createDepthMaterial(const HydraxComponent &Components, const Options &Options)
Create depth material.
Definition: MaterialManager.cpp:1202
Hydrax
Definition: CfgFileManager.cpp:28
Hydrax::MaterialManager::_createUnderwaterCompositor
bool _createUnderwaterCompositor(const HydraxComponent &Components, const Options &Options)
Create underwater compositor.
Definition: MaterialManager.cpp:2767
Hydrax::MaterialManager::MaterialType
MaterialType
Material type enum.
Definition: MaterialManager.h:50
Hydrax::HYDRAX_COMPONENT_SUN
@ HYDRAX_COMPONENT_SUN
Definition: Enums.h:59
_def_Depth_Shader_VP_Name
#define _def_Depth_Shader_VP_Name
Definition: MaterialManager.cpp:41
Hydrax::Hydrax::getSunColor
const Ogre::Vector3 & getSunColor() const
Get sun color.
Definition: Hydrax.h:508
Hydrax::MaterialManager::mCompositorsNeedToBeReloaded
bool mCompositorsNeedToBeReloaded[1]
Hydrax compositors boolean: Need to be reloaded?
Definition: MaterialManager.h:367
Hydrax::Hydrax::getGlobalTransparency
const Ogre::Real & getGlobalTransparency() const
Get global transparency.
Definition: Hydrax.h:460
Hydrax.h
_def_Water_Shader_FP_Name
#define _def_Water_Shader_FP_Name
Definition: MaterialManager.cpp:38
Hydrax::Hydrax::getFoamScale
const Ogre::Real & getFoamScale() const
Get foam scale.
Definition: Hydrax.h:524
Hydrax::MaterialManager::_createDepthTextureGPUPrograms
bool _createDepthTextureGPUPrograms(const HydraxComponent &Components, const Options &Options, const Ogre::String &AlphaChannel)
Create depth texture gpu programs.
Definition: MaterialManager.cpp:1569
MaterialManager.h
Hydrax::MaterialManager::mHydrax
Hydrax * mHydrax
Hydrax main pointer.
Definition: MaterialManager.h:379
Hydrax::MaterialManager::MAT_DEPTH
@ MAT_DEPTH
Definition: MaterialManager.h:55
Hydrax::MaterialManager::COMP_UNDERWATER
@ COMP_UNDERWATER
Definition: MaterialManager.h:72
Hydrax::Hydrax::getCausticsEnd
const Ogre::Real & getCausticsEnd() const
Get caustics end.
Definition: Hydrax.h:588
Hydrax::MaterialManager::mCausticsAnimCurrentFrame
unsigned int mCausticsAnimCurrentFrame
Definition: MaterialManager.h:382
_def_Underwater_Material_Name
#define _def_Underwater_Material_Name
Definition: MaterialManager.cpp:47
_def_Water_Shader_VP_Name
#define _def_Water_Shader_VP_Name
Definition: MaterialManager.cpp:37
_def_Depth_Shader_FP_Name
#define _def_Depth_Shader_FP_Name
Definition: MaterialManager.cpp:42
Hydrax::MaterialManager::Options
Material options.
Definition: MaterialManager.h:112
Hydrax::MaterialManager::createMaterials
bool createMaterials(const HydraxComponent &Components, const Options &Options)
Create materials.
Definition: MaterialManager.cpp:163
Hydrax::MaterialManager::MAT_SIMPLE_BLACK
@ MAT_SIMPLE_BLACK
Definition: MaterialManager.h:63
Hydrax::CAUSTICS_FRAME_DURATION
const float CAUSTICS_FRAME_DURATION
Definition: MaterialManager.cpp:1544
Hydrax::MaterialManager::_createUnderwaterMaterial
bool _createUnderwaterMaterial(const HydraxComponent &Components, const Options &Options)
Create underwater material.
Definition: MaterialManager.cpp:1808
Hydrax::CAUSTICS_NUM_FRAMES
const unsigned int CAUSTICS_NUM_FRAMES
Definition: MaterialManager.cpp:1545
_def_Depth_Material_Name
#define _def_Depth_Material_Name
Definition: MaterialManager.cpp:40
Hydrax::MaterialManager::UnderwaterCompositorListener::notifyMaterialRender
void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat)
On material render.
Definition: MaterialManager.cpp:3741
Hydrax::Hydrax::getDepthLimit
const Ogre::Real & getDepthLimit() const
Get depth limit.
Definition: Hydrax.h:548
Hydrax::HYDRAX_COMPONENT_DEPTH
@ HYDRAX_COMPONENT_DEPTH
Definition: Enums.h:61
Hydrax::Hydrax::getNormalDistortion
const Ogre::Real & getNormalDistortion() const
Get normal distortion.
Definition: Hydrax.h:484
_def_Underwater_Compositor_Material_Name
#define _def_Underwater_Compositor_Material_Name
Definition: MaterialManager.cpp:51
Hydrax::MaterialManager::mCreated
bool mCreated
Is createMaterials() already called?
Definition: MaterialManager.h:361
Hydrax::MaterialManager::fillGpuProgramsToPass
bool fillGpuProgramsToPass(Ogre::Pass *Pass, const Ogre::String GpuProgramNames[2], const ShaderMode &SM, const Ogre::String EntryPoints[2], const Ogre::String Data[2])
Fill GPU vertex and fragment program to a pass.
Definition: MaterialManager.cpp:239
Hydrax::MaterialManager::SM_HLSL
@ SM_HLSL
Definition: MaterialManager.h:91
Hydrax::MaterialManager::setCompositorEnable
void setCompositorEnable(const CompositorType &Compositor, const bool &Enable)
Set a compositor enable/disable.
Definition: MaterialManager.cpp:3523
Hydrax::MaterialManager::addDepthTextureTechnique
void addDepthTextureTechnique(Ogre::Technique *Technique, const Ogre::String &TextureName, const Ogre::String &AlphaChannel="w", const bool &AutoUpdate=true)
Add depth texture technique to an especified material.
Definition: MaterialManager.cpp:3453
Hydrax::MaterialManager::UnderwaterCompositorListener::mMaterialManager
MaterialManager * mMaterialManager
Material manager parent pointer.
Definition: MaterialManager.h:151
Hydrax::MaterialManager::removeMaterials
void removeMaterials()
Remove materials.
Definition: MaterialManager.cpp:86
Hydrax::Hydrax::getGodRaysIntensity
const Ogre::Real & getGodRaysIntensity() const
Get God rays intensity.
Definition: Hydrax.h:604
Hydrax::Mesh::getObjectSpacePosition
const Ogre::Vector3 getObjectSpacePosition(const Ogre::Vector3 &WorldSpacePosition) const
Get the object-space position from world-space position.
Definition: Mesh.cpp:409
Hydrax::Hydrax::getCamera
Ogre::Camera * getCamera()
Get rendering camera.
Definition: Hydrax.h:293
_def_Simple_Red_Material_Name
#define _def_Simple_Red_Material_Name
Definition: MaterialManager.cpp:57
HydraxLOG
#define HydraxLOG(msg)
Definition: Application.h:59
Hydrax::Hydrax::getFoamStart
const Ogre::Real & getFoamStart() const
Get foam start.
Definition: Hydrax.h:532
Hydrax::MaterialManager::mUnderwaterCompositorListener
UnderwaterCompositorListener mUnderwaterCompositorListener
Underwater compositor listener.
Definition: MaterialManager.h:377
Hydrax::MaterialManager::GPUP_FRAGMENT
@ GPUP_FRAGMENT
Definition: MaterialManager.h:83
_def_Underwater_Compositor_Shader_VP_Name
#define _def_Underwater_Compositor_Shader_VP_Name
Definition: MaterialManager.cpp:52
_def_Simple_Black_Material_Name
#define _def_Simple_Black_Material_Name
Definition: MaterialManager.cpp:58
Hydrax::MaterialManager::setGpuProgramParameter
void setGpuProgramParameter(const GpuProgram &GpuP, const MaterialType &MType, const Ogre::String &Name, const Ogre::Real &Value)
Set gpu program Ogre::Real parameter.
Definition: MaterialManager.cpp:3558
Hydrax::Hydrax::getViewport
Ogre::Viewport * getViewport()
Get main window viewport.
Definition: Hydrax.h:301
Hydrax::MaterialManager::MAT_SIMPLE_RED
@ MAT_SIMPLE_RED
Definition: MaterialManager.h:61
Hydrax::MaterialManager::reload
void reload(const MaterialType &Material)
Reload material.
Definition: MaterialManager.cpp:3170
Hydrax::MaterialManager::NM_RTT
@ NM_RTT
Definition: MaterialManager.h:107
Hydrax::Hydrax::getSunArea
const Ogre::Real & getSunArea() const
Get sun area.
Definition: Hydrax.h:500
Hydrax::MaterialManager::addDepthTechnique
void addDepthTechnique(Ogre::Technique *Technique, const bool &AutoUpdate=true)
Add depth technique to an especified material.
Definition: MaterialManager.cpp:3398
Hydrax::Hydrax::getFoamMaxDistance
const Ogre::Real & getFoamMaxDistance() const
Get foam max distance.
Definition: Hydrax.h:516
Hydrax::MaterialManager::mCausticsAnimTexVec
std::vector< Ogre::TextureUnitState * > mCausticsAnimTexVec
Caustics animated texture, for manual updating.
Definition: MaterialManager.h:381
Hydrax::MaterialManager::_createSimpleColorMaterial
bool _createSimpleColorMaterial(const Ogre::ColourValue &MaterialColor, const MaterialType &MT, const Ogre::String &MaterialName, const bool &DepthCheck=true, const bool &DepthWrite=true)
Definition: MaterialManager.cpp:3150
_def_Underwater_Shader_VP_Name
#define _def_Underwater_Shader_VP_Name
Definition: MaterialManager.cpp:48
_def_Underwater_Compositor_Shader_FP_Name
#define _def_Underwater_Compositor_Shader_FP_Name
Definition: MaterialManager.cpp:53
Hydrax::Hydrax::getSunPosition
const Ogre::Vector3 & getSunPosition() const
Get sun position.
Definition: Hydrax.h:468
Hydrax::HYDRAX_COMPONENT_SMOOTH
@ HYDRAX_COMPONENT_SMOOTH
Smooth transitions and caustics components need depth component.
Definition: Enums.h:63
Hydrax::MaterialManager::mComponents
HydraxComponent mComponents
Actual material components.
Definition: MaterialManager.h:373
Hydrax::MaterialManager::createGpuProgram
bool createGpuProgram(const Ogre::String &Name, const ShaderMode &SM, const GpuProgram &GPUP, const Ogre::String &EntryPoint, const Ogre::String &Data)
Create GPU program.
Definition: MaterialManager.cpp:261
Hydrax::MaterialManager::MAT_WATER
@ MAT_WATER
Definition: MaterialManager.h:53
Hydrax::Hydrax::getCausticsPower
const Ogre::Real & getCausticsPower() const
Get caustics power.
Definition: Hydrax.h:580
Hydrax::Hydrax::getGodRaysExposure
const Ogre::Vector3 & getGodRaysExposure() const
Get God rays exposure factors.
Definition: Hydrax.h:596
Hydrax::HydraxComponent
HydraxComponent
Hydrax flags to select components wich we want to use.
Definition: Enums.h:57
Hydrax::HYDRAX_COMPONENTS_NONE
@ HYDRAX_COMPONENTS_NONE
Definition: Enums.h:70
Hydrax::HYDRAX_COMPONENT_UNDERWATER
@ HYDRAX_COMPONENT_UNDERWATER
Definition: Enums.h:65
_def_Underwater_Compositor_Name
#define _def_Underwater_Compositor_Name
Definition: MaterialManager.cpp:55
Hydrax::HYDRAX_COMPONENT_CAUSTICS
@ HYDRAX_COMPONENT_CAUSTICS
Definition: Enums.h:64
Hydrax::HYDRAX_COMPONENT_UNDERWATER_GODRAYS
@ HYDRAX_COMPONENT_UNDERWATER_GODRAYS
Definition: Enums.h:68
Hydrax::MaterialManager::MAT_UNDERWATER_COMPOSITOR
@ MAT_UNDERWATER_COMPOSITOR
Definition: MaterialManager.h:59
Hydrax::MaterialManager::Options::NM
NormalMode NM
Normal map generation mode.
Definition: MaterialManager.h:136
Hydrax::DecalsManager::registerAll
void registerAll()
Register all decals.
Definition: DecalsManager.cpp:305
Hydrax::Hydrax::getFullReflectionDistance
const Ogre::Real & getFullReflectionDistance() const
Get full reflection distance.
Definition: Hydrax.h:452
Hydrax::Hydrax::getSmoothPower
const Ogre::Real & getSmoothPower() const
Get smooth power.
Definition: Hydrax.h:564
Hydrax::MaterialManager::~MaterialManager
~MaterialManager()
Destructor.
Definition: MaterialManager.cpp:81
Hydrax::MaterialManager::SM_CG
@ SM_CG
Definition: MaterialManager.h:93
Hydrax::MaterialManager::_isComponent
bool _isComponent(const HydraxComponent &List, const HydraxComponent &ToCheck) const
Is component in the given list?
Definition: MaterialManager.cpp:3538
Hydrax::MaterialManager::Options::SM
ShaderMode SM
Shader mode.
Definition: MaterialManager.h:134
Hydrax::MaterialManager::mDepthTechniques
std::vector< Ogre::Technique * > mDepthTechniques
Technique vector for addDepthTechnique(...)
Definition: MaterialManager.h:371
Hydrax::Hydrax::getDistLimit
const Ogre::Real & getDistLimit() const
Get distance limit (viewable underwater)
Definition: Hydrax.h:556
Hydrax::MaterialManager::ShaderMode
ShaderMode
Shader mode.
Definition: MaterialManager.h:88
Hydrax::Hydrax::getCausticsScale
const Ogre::Real & getCausticsScale() const
Get caustics scale.
Definition: Hydrax.h:572
Hydrax::MaterialManager::GpuProgram
GpuProgram
Gpu program enum.
Definition: MaterialManager.h:78
Hydrax::MaterialManager::getCompositor
Ogre::CompositorPtr & getCompositor(const CompositorType &Compositor)
Get compositor.
Definition: MaterialManager.h:230
Hydrax::MaterialManager::_createWaterMaterial
bool _createWaterMaterial(const HydraxComponent &Components, const Options &Options)
Create water material.
Definition: MaterialManager.cpp:349
_def_Underwater_Shader_FP_Name
#define _def_Underwater_Shader_FP_Name
Definition: MaterialManager.cpp:49
_def_DepthTexture_Shader_VP_Name
#define _def_DepthTexture_Shader_VP_Name
Definition: MaterialManager.cpp:44
Hydrax::MaterialManager::updateAnimatedTextures
void updateAnimatedTextures(float dt)
Animated textures must be updated manually to account for variable simulation time.
Definition: MaterialManager.cpp:1547
Hydrax::MaterialManager::UnderwaterCompositorListener::notifyMaterialSetup
void notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat)
On material setup.
Definition: MaterialManager.cpp:3732
Hydrax::MaterialManager::GPUP_VERTEX
@ GPUP_VERTEX
Definition: MaterialManager.h:81
Hydrax::Hydrax::getDecalsManager
DecalsManager * getDecalsManager()
Get Hydrax::DecalsManager.
Definition: Hydrax.h:357
Hydrax::MaterialManager::CompositorType
CompositorType
Compositor type enum.
Definition: MaterialManager.h:69
Hydrax::MaterialManager::mCompositorsEnable
bool mCompositorsEnable[1]
Hydrax compostor enable vector.
Definition: MaterialManager.h:369
Hydrax::MaterialManager::MaterialManager
MaterialManager(Hydrax *h)
Constructor.
Definition: MaterialManager.cpp:62
Hydrax::MaterialManager::NM_VERTEX
@ NM_VERTEX
Definition: MaterialManager.h:105