RigsofRods
Soft-body Physics Simulation
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].setNull();
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  TUS_Caustics->setAnimatedTextureName("Caustics.bmp", 32, 1.5);
1534  }
1535 
1536  DepthMaterial->setReceiveShadows(false);
1537  DepthMaterial->load();
1538 
1539  return true;
1540  }
1541 
1542  bool MaterialManager::_createDepthTextureGPUPrograms(const HydraxComponent &Components, const Options &Options, const Ogre::String& AlphaChannel)
1543  {
1544  const bool cCaustics = _isComponent(Components, HYDRAX_COMPONENT_CAUSTICS);
1545 
1546  Ogre::String VertexProgramData, FragmentProgramData;
1547 
1548  // Vertex program
1549 
1550  switch (Options.SM)
1551  {
1552  case SM_HLSL: case SM_CG:
1553  {
1554  // No caustics
1555  if (!cCaustics)
1556  {
1557  VertexProgramData +=
1558  Ogre::String(
1559  "void main_vp(\n") +
1560  // IN
1561  "float4 iPosition : POSITION,\n" +
1562  "float2 iUV : TEXCOORD0,\n" +
1563  // OUT
1564  "out float4 oPosition : POSITION,\n" +
1565  "out float3 oPosition_UV : TEXCOORD0,\n" +
1566  // UNIFORM
1567  "uniform float uPlaneYPos,\n" +
1568  "uniform float4x4 uWorld,\n" +
1569  "uniform float4x4 uWorldViewProj)\n" +
1570  "{\n" +
1571  "oPosition = mul(uWorldViewProj, iPosition);\n" +
1572  "oPosition_UV.x = mul(uWorld, iPosition).y;\n" +
1573  "oPosition_UV.x-=uPlaneYPos;\n" +
1574  "oPosition_UV.yz = iUV;\n" +
1575  "}\n";
1576  }
1577  else // Caustics
1578  {
1579  VertexProgramData +=
1580  Ogre::String(
1581  "void main_vp(\n") +
1582  // IN
1583  "float4 iPosition : POSITION,\n" +
1584  "float2 iUV : TEXCOORD0,\n" +
1585  // OUT
1586  "out float4 oPosition : POSITION,\n" +
1587  "out float3 oPosition_UV : TEXCOORD0,\n" +
1588  "out float2 oUvWorld : TEXCOORD1,\n" +
1589  // UNIFORM
1590  "uniform float uPlaneYPos,\n" +
1591  "uniform float4x4 uWorld,\n" +
1592  "uniform float4x4 uWorldViewProj)\n" +
1593  "{\n" +
1594  "oPosition = mul(uWorldViewProj, iPosition);\n" +
1595  "float3 wPos = mul(uWorld, iPosition);\n" +
1596  "oPosition_UV.x = wPos.y;\n" +
1597  "oPosition_UV.x-=uPlaneYPos;\n" +
1598  "oPosition_UV.yz = iUV;\n" +
1599  "oUvWorld = wPos.xz;\n" +
1600  "}\n";
1601  }
1602  }
1603  break;
1604 
1605  case SM_GLSL:
1606  // No caustics
1607  if (!cCaustics)
1608  {
1609  VertexProgramData += Ogre::String( "\n" ) +
1610  // UNIFORMS
1611  "uniform float uPlaneYPos;\n" +
1612  "uniform mat4 uWorld;\n" +
1613  // IN
1614  // OUT
1615  "varying vec3 Position_UV;\n" +
1616  // main function
1617  "void main()\n" +
1618  "{\n" +
1619  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" +
1620  "Position_UV.x = (uWorld * gl_Vertex).y;\n" +
1621  "Position_UV.x -= uPlaneYPos;\n" +
1622  "Position_UV.yz = gl_MultiTexCoord0;\n" +
1623  "}\n";
1624  }
1625  else // Caustics
1626  {
1627  VertexProgramData += Ogre::String( "\n" ) +
1628  // UNIFORMS
1629  "uniform float uPlaneYPos;\n" +
1630  "uniform mat4 uWorld;\n" +
1631  // IN
1632  // OUT
1633  "varying vec3 Position_UV;\n" +
1634  "varying vec2 UVWorld;\n" +
1635  // main function
1636  "void main()\n" +
1637  "{\n" +
1638  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" +
1639  "vec3 wPos = uWorld * iPosition;\n" +
1640  "Position_UV.x = wPos.y;\n" +
1641  "Position_UV.x -= uPlaneYPos;\n" +
1642  "Position_UV.yz = gl_MultiTexCoord0;\n" +
1643  "UVWorld = wPos.xz;\n" +
1644  "}\n";
1645  }
1646  break;
1647  }
1648 
1649  // Fragment program
1650 
1651  switch (Options.SM)
1652  {
1653  case SM_HLSL: case SM_CG:
1654  {
1655  // No caustics
1656  if (!cCaustics)
1657  {
1658  FragmentProgramData +=
1659  Ogre::String(
1660  "void main_fp(\n") +
1661  // IN
1662  "float3 iPosition_UV : TEXCOORD0,\n" +
1663  // OUT
1664  "out float4 oColor : COLOR,\n" +
1665  // UNIFORM
1666  "uniform float uDepthLimit,\n" +
1667  "uniform sampler2D uAlphaTex : register(s0))\n" +
1668  "{\n" +
1669  "float pixelYDepth = (iPosition_UV.x*uDepthLimit+1);\n" +
1670  "pixelYDepth = saturate(pixelYDepth);\n" +
1671  "oColor = float4(pixelYDepth,0,0,0);\n" +
1672  "oColor.a = tex2D(uAlphaTex, iPosition_UV.yz)."+AlphaChannel+";" +
1673  "}\n";
1674  }
1675  else // Caustics
1676  {
1677  FragmentProgramData +=
1678  Ogre::String(
1679  "void main_fp(\n") +
1680  // IN
1681  "float3 iPosition_UV : TEXCOORD0,\n" +
1682  "float2 iUvWorld : TEXCOORD1,\n" +
1683  // OUT
1684  "out float4 oColor : COLOR,\n" +
1685  // UNIFORM
1686  "uniform float uDepthLimit,\n" +
1687  "uniform float uCausticsScale,\n" +
1688  "uniform float uCausticsEnd,\n" +
1689  "uniform sampler2D uCaustics : register(s0),\n" +
1690  "uniform sampler2D uAlphaTex : register(s1))\n" +
1691  "{\n" +
1692  "float pixelYDepth = (iPosition_UV.x*uDepthLimit+1);\n" +
1693  "pixelYDepth = saturate(pixelYDepth);\n" +
1694  "oColor = float4(pixelYDepth,0,0,0);\n" +
1695  "oColor.g = saturate(uCausticsEnd-pixelYDepth)*tex2D(uCaustics, iUvWorld/uCausticsScale).r;\n" +
1696  "oColor.a = tex2D(uAlphaTex, iPosition_UV.yz)."+AlphaChannel+";" +
1697  "}\n";
1698  }
1699  }
1700  break;
1701 
1702  case SM_GLSL:
1703  {
1704  Ogre::String AlphaChannelGLSL = AlphaChannel;
1705  std::replace( AlphaChannelGLSL.begin(), AlphaChannelGLSL.end(), 'r', 'x' );
1706  std::replace( AlphaChannelGLSL.begin(), AlphaChannelGLSL.end(), 'g', 'y' );
1707  std::replace( AlphaChannelGLSL.begin(), AlphaChannelGLSL.end(), 'b', 'z' );
1708  std::replace( AlphaChannelGLSL.begin(), AlphaChannelGLSL.end(), 'a', 'w' );
1709  // No caustics
1710  if (!cCaustics)
1711  {
1712  FragmentProgramData += Ogre::String( "\n" ) +
1713  // UNIFORMS
1714  "uniform float uDepthLimit;\n" +
1715  "uniform float uDistLimit;\n" +
1716  "uniform sampler2D uAlphaTex;\n" +
1717  // IN
1718  "variying vec3 Position_UV;\n" +
1719  // OUT
1720  // main function
1721  "void main()\n" +
1722  "{\n" +
1723  "float pixelYDepth = clamp(Position_UV.x*uDepthLimit + 1.0, 0.0, 1.0);\n" +
1724  "gl_FragColor = vec4(pixelYDepth,0.0,0.0,0.0);\n" +
1725  "gl_FragColor.w = texture2D(uAlphaTex, iPosition_UV.yz)."+AlphaChannelGLSL+";" +
1726  "}\n";
1727  }
1728  else // Caustics
1729  {
1730  FragmentProgramData += Ogre::String( "\n" ) +
1731  // UNIFORMS
1732  "uniform float uDistLimit;\n" +
1733  "uniform float uCausticsScale;\n" +
1734  "uniform float uCausticsEnd;\n" +
1735  "uniform sampler2D uCaustics;\n" +
1736  "uniform sampler2D uAlphaTex;\n" +
1737  // IN
1738  "variying vec3 Position_UV;\n" +
1739  "variying vec2 UVWorld;\n" +
1740  // OUT
1741  // main function
1742  "void main()\n" +
1743  "{\n" +
1744  "float pixelYDepth = clamp(Position_UV.x*uDepthLimit + 1.0, 0.0, 1.0);\n" +
1745  "gl_FragColor = vec4(pixelYDepth,0.0,0.0,0.0);\n" +
1746  "gl_FragColor.y = clamp(uCausticsEnd-pixelYDepth, 0.0, 1.0)*texture2D(uCaustics, UVWorld/uCausticsScale).x;\n" +
1747  "gl_FragColor.w = texture2D(uAlphaTex, iPosition_UV.yz)."+AlphaChannelGLSL+";" +
1748  "}\n";
1749  }
1750  }
1751  break;
1752  }
1753 
1754  Ogre::String GpuProgramsData[2] = {VertexProgramData, FragmentProgramData};
1755  Ogre::String GpuProgramNames[2] = {_def_DepthTexture_Shader_VP_Name+AlphaChannel, _def_DepthTexture_Shader_FP_Name+AlphaChannel};
1756  Ogre::String EntryPoints[2];
1757  if(Options.SM == SM_GLSL)
1758  {
1759  EntryPoints[0] = Ogre::String("main");
1760  EntryPoints[1] = Ogre::String("main");
1761  }
1762  else
1763  {
1764  EntryPoints[0] = Ogre::String("main_vp");
1765  EntryPoints[1] = Ogre::String("main_fp");
1766  }
1767 
1768  GpuProgram GpuPrograms[2] = {GPUP_VERTEX, GPUP_FRAGMENT};
1769 
1770  for (int k = 0; k < 2; k++)
1771  {
1772  if (!createGpuProgram(GpuProgramNames[k], Options.SM, GpuPrograms[k], EntryPoints[k], GpuProgramsData[k]))
1773  {
1774  return false;
1775  }
1776  }
1777 
1778  return true;
1779  }
1780 
1782  {
1783  const bool cDepth = _isComponent(Components, HYDRAX_COMPONENT_DEPTH );
1784  //const bool cSmooth = _isComponent(Components, HYDRAX_COMPONENT_SMOOTH ); // cSmooth uneeded underwater
1785  const bool cSun = _isComponent(Components, HYDRAX_COMPONENT_SUN );
1786  //const bool cFoam = _isComponent(Components, HYDRAX_COMPONENT_FOAM );
1787  const bool cCaustics = _isComponent(Components, HYDRAX_COMPONENT_CAUSTICS);
1788  const bool cUReflections = _isComponent(Components, HYDRAX_COMPONENT_UNDERWATER_REFLECTIONS);
1789 
1790  Ogre::String VertexProgramData, FragmentProgramData;
1791 
1792  // Vertex program
1793 
1794  switch (Options.NM)
1795  {
1796  case NM_TEXTURE:
1797  {
1798  switch (Options.SM)
1799  {
1800  case SM_HLSL: case SM_CG:
1801  {
1802  VertexProgramData +=
1803  Ogre::String(
1804  "void main_vp(\n") +
1805  // IN
1806  "float4 iPosition : POSITION,\n" +
1807  "float2 iUv : TEXCOORD0,\n" +
1808  // OUT
1809  "out float4 oPosition : POSITION,\n" +
1810  "out float4 oPosition_ : TEXCOORD0,\n" +
1811  "out float2 oUvNoise : TEXCOORD1,\n" +
1812  "out float4 oUvProjection : TEXCOORD2,\n" +
1813  "out float2 oDistance : TEXCOORD3,\n";
1814  /* Foam is not visible underwater
1815  if (cFoam)
1816  {
1817  VertexProgramData +=
1818  "out float4 oWorldPosition : TEXCOORD4,\n";
1819  }
1820  */
1821  VertexProgramData += Ogre::String(
1822  // UNIFORM
1823  "uniform float4x4 uWorldViewProj,\n") +
1824  "uniform float4x4 uWorldView,\n" +
1825  "uniform float4x4 uWorld,\n" +
1826  "uniform float3 uCameraPos)\n" +
1827  "{\n" +
1828  "oPosition_ = iPosition;\n";
1829  /* Foam is not visible underwater
1830  if (cFoam)
1831  {
1832  VertexProgramData +=
1833  "oWorldPosition = mul(uWorld, iPosition);\n";
1834  }
1835  */
1836  VertexProgramData += Ogre::String(
1837  "oPosition = mul(uWorldViewProj, iPosition);\n") +
1838  // Projective texture coordinates, adjust for mapping
1839  "float4x4 scalemat = float4x4(0.5, 0, 0, 0.5,"+
1840  "0,-0.5, 0, 0.5,"+
1841  "0, 0, 0.5, 0.5,"+
1842  "0, 0, 0, 1);\n" +
1843  "oUvProjection = mul(scalemat, oPosition);\n" +
1844  "oUvNoise = iUv;\n" +
1845  // Distance
1846  "float4 mwPos = mul(uWorldView, iPosition);\n" +
1847  "oDistance.x = abs(mwPos.z);\n" +
1848  "oDistance.y = -mul( uWorld, float4(uCameraPos, 1.0) ).y;\n" +
1849  "}\n";
1850  }
1851  break;
1852 
1853  case SM_GLSL:
1854  {
1855  VertexProgramData += Ogre::String( "\n" );
1856  // UNIFORMS
1857  VertexProgramData += "uniform mat4 uWorld;\n";
1858  // IN
1859  // OUT
1860  VertexProgramData += Ogre::String(
1861  "varying vec4 Position_;\n") +
1862  "varying vec4 UVProjection;\n" +
1863  "varying vec2 Distance_;\n";
1864  /* Foam is not visible underwater
1865  if (cFoam)
1866  {
1867  VertexProgramData += "varying vec4 WorldPosition;\n";
1868  }
1869  */
1870  // main function
1871  VertexProgramData += Ogre::String(
1872  "void main()\n") +
1873  "{\n" +
1874  "Position_ = gl_Vertex;\n";
1875  /* Foam is not visible underwater
1876  if (cFoam)
1877  {
1878  VertexProgramData += "WorldPosition = uWorld * gl_Vertex;\n";
1879  }
1880  */
1881  VertexProgramData += Ogre::String(
1882  // Projective texture coordinates, adjust for mapping
1883  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n") +
1884  "mat4 scalemat = mat4( 1.0, 0.0, 0.0, 0.0,\n" +
1885  " 0.0, -1.0, 0.0, 0.0,\n" +
1886  " 0.0, 0.0, 1.0, 0.0,\n" +
1887  " 0.0, 0.0, 0.0, 1.0);\n" +
1888  "UVProjection = scalemat * gl_Position;\n" +
1889  "gl_TexCoord[0] = gl_MultiTexCoord0;\n" +
1890  // Distance
1891  "vec4 mwPos = gl_ModelViewMatrix * gl_Vertex;\n" +
1892  "Distance_.x = abs(mwPos.z);\n" +
1893  "Distance_.y = -( uWorld * gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0) ).y;\n" +
1894  "}\n";
1895  }
1896  break;
1897  }
1898  }
1899  break;
1900 
1901  case NM_VERTEX:
1902  {
1903  switch (Options.SM)
1904  {
1905  case SM_HLSL: case SM_CG:
1906  {
1907  VertexProgramData +=
1908  Ogre::String(
1909  "void main_vp(\n") +
1910  // IN
1911  "float4 iPosition : POSITION,\n" +
1912  "float3 iNormal : NORMAL,\n"+
1913  // OUT
1914  "out float4 oPosition : POSITION,\n" +
1915  "out float4 oPosition_ : TEXCOORD0,\n" +
1916  "out float4 oUvProjection : TEXCOORD1,\n" +
1917  "out float3 oNormal : TEXCOORD2,\n" +
1918  "out float2 oDistance : TEXCOORD3,\n";
1919  /* Foam is not visible underwater
1920  if (cFoam)
1921  {
1922  VertexProgramData +=
1923  "out float4 oWorldPosition : TEXCOORD4,\n";
1924  }
1925  */
1926  VertexProgramData += Ogre::String(
1927  // UNIFORM
1928  "uniform float4x4 uWorldViewProj,\n") +
1929  "uniform float4x4 uWorldView,\n" +
1930  "uniform float4x4 uWorld,\n" +
1931  "uniform float3 uCameraPos)\n" +
1932  "{\n" +
1933  "oPosition_ = iPosition;\n";
1934  /* Foam is not visible underwater
1935  if (cFoam)
1936  {
1937  VertexProgramData += "oWorldPosition = mul(uWorld, iPosition);\n";
1938  }
1939  */
1940  VertexProgramData += Ogre::String(
1941  "oPosition = mul(uWorldViewProj, iPosition);\n") +
1942  // Projective texture coordinates, adjust for mapping
1943  "float4x4 scalemat = float4x4(0.5, 0, 0, 0.5,"+
1944  "0,-0.5, 0, 0.5,"+
1945  "0, 0, 0.5, 0.5,"+
1946  "0, 0, 0, 1);\n" +
1947  "oUvProjection = mul(scalemat, oPosition);\n" +
1948  "oNormal = normalize(iNormal);\n"+
1949  // Distance
1950  "float4 mwPos = mul(uWorldView, iPosition);\n" +
1951  "oDistance.x = abs(mwPos.z);\n" +
1952  "oDistance.y = -mul( uWorld, float4(uCameraPos, 1.0) ).y;\n" +
1953  "}\n";
1954  }
1955  break;
1956 
1957  case SM_GLSL:
1958  {
1959  VertexProgramData += Ogre::String( "\n");
1960  // UNIFORMS
1961  VertexProgramData += "uniform mat4 uWorld;\n";
1962  // IN
1963  // OUT
1964  VertexProgramData += Ogre::String(
1965  "varying vec4 Position_;\n") +
1966  "varying vec4 UVProjection;\n" +
1967  "varying vec3 Normal;\n" +
1968  "varying vec2 Distance_;\n";
1969  /* Foam is not visible underwater
1970  if(cFoam)
1971  {
1972  VertexProgramData += "varying vec4 WorldPosition;\n";
1973  }
1974  */
1975  // PROGRAM
1976  VertexProgramData += Ogre::String(
1977  "void main()\n") +
1978  "{\n" +
1979  "Position_ = gl_Vertex;\n";
1980  /* Foam is not visible underwater
1981  if(cFoam)
1982  {
1983  VertexProgramData += "WorldPosition = uWorld * gl_Vertex;\n";
1984  }
1985  */
1986  VertexProgramData += Ogre::String(
1987  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n") +
1988  "mat4 scalemat = mat4( 1.0, 0.0, 0.0, 0.0,\n" +
1989  " 0.0, -1.0, 0.0, 0.0,\n" +
1990  " 0.0, 0.0, 1.0, 0.0,\n" +
1991  " 0.0, 0.0, 0.0, 1.0);\n" +
1992  "UVProjection = scalemat * gl_Position;\n" +
1993  "Normal = normalize(gl_Normal);\n" +
1994  // Distance
1995  "vec4 mwPos = gl_ModelViewMatrix * gl_Vertex;\n" +
1996  "Distance_.x = abs(mwPos.z);\n" +
1997  "Distance_.y = -( uWorld * gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0) ).y;\n" +
1998  "}\n";
1999  }
2000  break;
2001  }
2002  }
2003  break;
2004 
2005  case NM_RTT:
2006  {
2007  switch (Options.SM)
2008  {
2009  case SM_HLSL: case SM_CG:
2010  {
2011  VertexProgramData +=
2012  Ogre::String(
2013  "void main_vp(\n") +
2014  // IN
2015  "float4 iPosition : POSITION,\n" +
2016  // OUT
2017  "out float4 oPosition : POSITION,\n" +
2018  "out float4 oPosition_ : TEXCOORD0,\n" +
2019  "out float4 oUvProjection : TEXCOORD1,\n" +
2020  "out float2 oDistance : TEXCOORD2,\n";
2021  /* Foam is not visible underwater
2022  if (cFoam)
2023  {
2024  VertexProgramData +=
2025  "out float4 oWorldPosition : TEXCOORD3,\n";
2026  }
2027  */
2028  VertexProgramData += Ogre::String(
2029  // UNIFORM
2030  "uniform float4x4 uWorldViewProj,\n") +
2031  "uniform float4x4 uWorldView,\n" +
2032  "uniform float4x4 uWorld,\n" +
2033  "uniform float3 uCameraPos)\n" +
2034  "{\n" +
2035  "oPosition_ = iPosition;\n";
2036  /* Foam is not visible underwater
2037  if (cFoam)
2038  {
2039  VertexProgramData += "oWorldPosition = mul(uWorld, iPosition);\n";
2040  }
2041  */
2042  VertexProgramData += Ogre::String(
2043  "oPosition = mul(uWorldViewProj, iPosition);\n") +
2044  // Projective texture coordinates, adjust for mapping
2045  "float4x4 scalemat = float4x4(0.5, 0, 0, 0.5,"+
2046  "0,-0.5, 0, 0.5,"+
2047  "0, 0, 0.5, 0.5,"+
2048  "0, 0, 0, 1);\n" +
2049  "oUvProjection = mul(scalemat, oPosition);\n" +
2050  // Distance
2051  "float4 mwPos = mul(uWorldView, iPosition);\n" +
2052  "oDistance.x = abs(mwPos.z);\n" +
2053  "oDistance.y = -mul( uWorld, float4(uCameraPos, 1.0) ).y;\n" +
2054  "}\n";
2055  }
2056  break;
2057 
2058  case SM_GLSL:
2059  {
2060  VertexProgramData += Ogre::String( "\n");
2061  // UNIFORMS
2062  VertexProgramData += "uniform mat4 uWorld;\n";
2063  // IN
2064  // OUT
2065  VertexProgramData += Ogre::String(
2066  "varying vec4 Position_;\n") +
2067  "varying vec4 UVProjection;\n" +
2068  "varying vec2 Distance_;\n";
2069  /* Foam is not visible underwater
2070  if(cFoam)
2071  {
2072  VertexProgramData += "varying vec4 WorldPosition;\n";
2073  }
2074  */
2075  // PROGRAM
2076  VertexProgramData +=Ogre::String(
2077  "void main()\n") +
2078  "{\n" +
2079  "Position_ = gl_Vertex;\n";
2080  /* Foam is not visible underwater
2081  if(cFoam)
2082  {
2083  VertexProgramData += "WorldPosition = uWorld * gl_Vertex;\n";
2084  }
2085  */
2086  VertexProgramData += Ogre::String(
2087  "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n") +
2088  "mat4 scalemat = mat4( 1.0, 0.0, 0.0, 0.0,\n" +
2089  " 0.0, -1.0, 0.0, 0.0,\n" +
2090  " 0.0, 0.0, 1.0, 0.0,\n" +
2091  " 0.0, 0.0, 0.0, 1.0);\n" +
2092  "UVProjection = scalemat * gl_Position;\n" +
2093  // Distance
2094  "vec4 mwPos = gl_ModelViewMatrix * gl_Vertex;\n" +
2095  "Distance_.x = abs(mwPos.z);\n" +
2096  "Distance_.y = -( uWorld * gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0) ).y;\n" +
2097  "}\n";
2098  }
2099  break;
2100  }
2101  }
2102  break;
2103  }
2104 
2105  // Fragment program
2106 
2107  switch (Options.NM)
2108  {
2109  case NM_TEXTURE: case NM_VERTEX: case NM_RTT:
2110  {
2111  switch (Options.SM)
2112  {
2113  case SM_HLSL: case SM_CG:
2114  {
2115  FragmentProgramData +=
2116  Ogre::String("float3 expand(float3 v)\n") +
2117  "{\n" +
2118  "return (v - 0.5) * 2;\n" +
2119  "}\n\n" +
2120 
2121  "void main_fp(" +
2122  // IN
2123  "float4 iPosition : TEXCOORD0,\n";
2124  int TEXCOORDNUM = 1;
2125  if (Options.NM == NM_TEXTURE)
2126  {
2127  FragmentProgramData +=
2128  "float2 iUvNoise : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
2129  TEXCOORDNUM++;
2130  }
2131  FragmentProgramData +=
2132  "float4 iUvProjection : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
2133  TEXCOORDNUM++;
2134  if (Options.NM == NM_VERTEX)
2135  {
2136  FragmentProgramData +=
2137  "float3 iNormal : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
2138  TEXCOORDNUM++;
2139  }
2140  FragmentProgramData +=
2141  "float2 iDistance : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
2142  TEXCOORDNUM++;
2143  /* Foam is not visible underwater
2144  if (cFoam)
2145  {
2146  FragmentProgramData +=
2147  "float4 iWorldPosition : TEXCOORD" + Ogre::StringConverter::toString(TEXCOORDNUM) + ",\n";
2148  }
2149  */
2150 
2151  FragmentProgramData += Ogre::String(
2152  // OUT
2153  "out float4 oColor : COLOR,\n") +
2154  // UNIFORM
2155  "uniform float3 uEyePosition,\n" +
2156  "uniform float uFullReflectionDistance,\n" +
2157  "uniform float uGlobalTransparency,\n" +
2158  "uniform float uNormalDistortion,\n" +
2159  "uniform float uDistLimit,\n" +
2160  "uniform float3 uWaterColor,\n";
2161  if (cSun)
2162  {
2163  FragmentProgramData += Ogre::String(
2164  "uniform float3 uSunPosition,\n") +
2165  "uniform float uSunStrength,\n" +
2166  "uniform float uSunArea,\n" +
2167  "uniform float3 uSunColor,\n" +
2168  "uniform float uDepthLimit,\n";
2169  }
2170  /* Foam is not visible underwater
2171  if (cFoam)
2172  {
2173  FragmentProgramData += Ogre::String(
2174  "uniform float uFoamRange,\n") +
2175  "uniform float uFoamMaxDistance,\n" +
2176  "uniform float uFoamScale,\n" +
2177  "uniform float uFoamStart,\n" +
2178  "uniform float uFoamTransparency,\n";
2179  }
2180  */
2181  if (cCaustics && cUReflections)
2182  {
2183  FragmentProgramData +=
2184  "uniform float uCausticsPower,\n";
2185  }
2186 
2187  int TexNum = 0;
2188 
2189  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
2190  {
2191  FragmentProgramData +=
2192  "uniform sampler2D uNormalMap : register(s" + Ogre::StringConverter::toString(TexNum) + "),\n";
2193  TexNum++;
2194  }
2195  if (cUReflections)
2196  {
2197  FragmentProgramData +=
2198  "uniform sampler2D uReflectionMap : register(s" + Ogre::StringConverter::toString(TexNum) + "),\n";
2199  TexNum++;
2200  }
2201 
2202  FragmentProgramData +=
2203  "uniform sampler2D uRefractionMap : register(s" + Ogre::StringConverter::toString(TexNum) + "),\n";
2204  TexNum++;
2205 
2206  if (cDepth && cUReflections)
2207  {
2208  FragmentProgramData +=
2209  "uniform sampler2D uDepthReflectionMap : register(s" + Ogre::StringConverter::toString(TexNum) + "),\n";
2210  TexNum++;
2211  }
2212 
2213  FragmentProgramData +=
2214  #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
2215  "uniform sampler1D uFresnelMap : register(s" + Ogre::StringConverter::toString(TexNum) + ")";
2216  #else
2217  "uniform sampler2D uFresnelMap : register(s" + Ogre::StringConverter::toString(TexNum) + ")";
2218  #endif
2219  TexNum++;
2220 
2221  /* Foam is not visible underwater
2222  if (cFoam)
2223  {
2224  FragmentProgramData += Ogre::String(
2225  ",\nuniform sampler2D uFoamMap : register(s" + Ogre::StringConverter::toString(TexNum) + ")\n");
2226  }
2227  */
2228  FragmentProgramData += Ogre::String(
2229  ")\n") +
2230  "{\n" +
2231  "float2 ProjectionCoord = iUvProjection.xy / iUvProjection.w;\n" +
2232  "float3 camToSurface = iPosition.xyz - uEyePosition;\n" +
2233  "float additionalReflection=camToSurface.x*camToSurface.x+camToSurface.z*camToSurface.z;\n";
2234 
2235  /* Foam is not visible underwater
2236  if (cFoam)
2237  {
2238  // Calculate the foam visibility as a function fo distance specified by user
2239  FragmentProgramData +=
2240  "float foamVisibility=1.0f-saturate(additionalReflection/uFoamMaxDistance);\n";
2241  }
2242  */
2243 
2244  FragmentProgramData += Ogre::String(
2245  "additionalReflection/=uFullReflectionDistance;\n") +
2246  "camToSurface=normalize(-camToSurface);\n";
2247  if (Options.NM == NM_TEXTURE)
2248  {
2249  FragmentProgramData += Ogre::String(
2250  "float3 pixelNormal = tex2D(uNormalMap,iUvNoise).xyz;\n") +
2251  // Inverte y with z, because at creation our local normal to the plane was z
2252  "pixelNormal.yz=pixelNormal.zy;\n" +
2253  // Remap from [0,1] to [-1,1]
2254  "pixelNormal.xyz=-expand(pixelNormal.xyz);\n";
2255  }
2256  else if (Options.NM == NM_VERTEX)
2257  {
2258  FragmentProgramData +=
2259  "float3 pixelNormal = -iNormal;\n";
2260  }
2261  else // NM_RTT
2262  {
2263  FragmentProgramData +=
2264  "float3 pixelNormal = -(2.0*tex2D(uNormalMap, ProjectionCoord.xy).xyz - 1.0);\n";
2265  }
2266  FragmentProgramData +=
2267  "float2 pixelNormalModified = uNormalDistortion*pixelNormal.zx;\n";
2268 
2269  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
2270  {
2271  FragmentProgramData +=
2272  "float dotProduct=dot(camToSurface,pixelNormal);\n";
2273  }
2274  else
2275  {
2276  FragmentProgramData +=
2277  "float dotProduct=dot(-camToSurface,pixelNormal);\n";
2278  }
2279  FragmentProgramData += Ogre::String(
2280  "dotProduct=saturate(dotProduct);\n") +
2281  #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
2282  "float fresnel = tex1D(uFresnelMap,dotProduct);\n" +
2283  #else
2284  "float fresnel = tex2D(uFresnelMap,float2(dotProduct,dotProduct));\n" +
2285  #endif
2286  // Add additional reflection and saturate
2287  "fresnel+=additionalReflection;\n" +
2288  "fresnel=saturate(fresnel);\n" +
2289  // Decrease the transparency and saturate
2290  "fresnel-=uGlobalTransparency;\n" +
2291  "fresnel=saturate(fresnel);\n" +
2292  "float3 reflection;\n" +
2293  #if OGRE_PLATFORM != OGRE_PLATFORM_WIN32
2294  // Reversing projection if underwater
2295  "if(uEyePosition.y < 0.0)\n" +
2296  "{\n" +
2297  "ProjectionCoord.y = 1.0 - ProjectionCoord.y;\n" +
2298  "}\n" +
2299  #endif
2300  // Get the reflection/refraction pixels. Make sure to disturb the texcoords by pixelnormal
2301  "float3 refraction=tex2D(uRefractionMap,ProjectionCoord.xy-pixelNormalModified).xyz;\n";
2302  if (cUReflections)
2303  {
2304  FragmentProgramData +=
2305  "reflection=tex2D(uReflectionMap,ProjectionCoord.xy+pixelNormalModified).xyz;\n";
2306  }
2307  else
2308  {
2309  FragmentProgramData +=
2310  "reflection=uWaterColor;\n";
2311  }
2312 
2313  if (cDepth && cUReflections)
2314  {
2315  if (cCaustics)
2316  {
2317  FragmentProgramData += Ogre::String(
2318  "float2 depth = tex2D(uDepthReflectionMap,ProjectionCoord.xy+pixelNormalModified).rg;\n") +
2319  "reflection *= 1+depth.y*uCausticsPower;\n" +
2320  "reflection = lerp(uWaterColor,reflection,depth.x);\n";
2321  }
2322  else
2323  {
2324  FragmentProgramData += Ogre::String(
2325  "float depth = tex2D(uDepthReflectionMap,ProjectionCoord.xy-pixelNormalModified).r;\n") +
2326  "reflection = lerp(uWaterColor,reflection,depth);\n";
2327  }
2328  }
2329  FragmentProgramData += Ogre::String(
2330  "float4 Color = float4(lerp(refraction,reflection,fresnel),1);\n" ) +
2331  "float Distance = saturate(1.0 - iDistance.x*uDistLimit);\n" +
2332  "Color.xyz = lerp(uWaterColor, Color.xyz, Distance);\n" +
2333  "Color.xyz = lerp(Color.xyz, uWaterColor, uGlobalTransparency);\n";
2334 
2335  if (cSun)
2336  {
2337  FragmentProgramData += Ogre::String(
2338  "float3 refractedVector = normalize(reflect(camToSurface, pixelNormal.xyz));\n") +
2339  "float3 surfaceToSun=normalize(uSunPosition-iPosition.xyz);\n" +
2340  // Temporally solution, fix this
2341  "surfaceToSun.xz = -surfaceToSun.xz;" +
2342  "float3 sunlight = uSunStrength*pow(saturate(dot(refractedVector,surfaceToSun)),uSunArea)*uSunColor;\n" +
2343  "Distance = saturate(1.0 - iDistance.y*uDepthLimit);\n" +
2344  "Color.xyz+=Distance*sunlight*saturate(1.0-additionalReflection);\n";
2345  }
2346 
2347  /* Foam is not visible underwater
2348  if (cFoam)
2349  {
2350  FragmentProgramData += Ogre::String(
2351  "float hmap = iPosition.y/uFoamRange*foamVisibility;\n") +
2352  "float2 foamTex=iWorldPosition.xz*uFoamScale+pixelNormalModified;\n" +
2353  "float foam=tex2D(uFoamMap,foamTex).r;\n" +
2354  "float foamTransparency=saturate(hmap-uFoamStart)*uFoamTransparency;\n" +
2355  "Color.xyz=lerp(Color.xyz,1,foamTransparency*foam);\n";
2356  }
2357  */
2358  FragmentProgramData += Ogre::String(
2359  "oColor = Color;\n") +
2360  "}\n";
2361  }
2362  break;
2363 
2364  case SM_GLSL:
2365  FragmentProgramData += Ogre::String("\n") +
2366  // UNIFORMS
2367  "uniform vec3 uEyePosition;\n" +
2368  "uniform float uFullReflectionDistance;\n" +
2369  "uniform float uGlobalTransparency;\n" +
2370  "uniform float uNormalDistortion;\n" +
2371  "uniform float uDistLimit;\n" +
2372  "uniform vec3 uWaterColor;\n";
2373 
2374  if (cSun)
2375  {
2376  FragmentProgramData += Ogre::String(
2377  "uniform vec3 uSunPosition;\n") +
2378  "uniform float uSunStrength;\n" +
2379  "uniform float uSunArea;\n" +
2380  "uniform vec3 uSunColor;\n" +
2381  "uniform float uDepthLimit;\n";
2382  }
2383  /* Foam is not visible underwater
2384  if (cFoam)
2385  {
2386  FragmentProgramData += Ogre::String(
2387  "uniform float uFoamRange;\n") +
2388  "uniform float uFoamMaxDistance;\n" +
2389  "uniform float uFoamScale;\n" +
2390  "uniform float uFoamStart;\n" +
2391  "uniform float uFoamTransparency;\n";
2392  }
2393  */
2394  if (cCaustics && cUReflections)
2395  {
2396  FragmentProgramData +=
2397  "uniform float uCausticsPower;\n";
2398  }
2399 
2400  int TexNum = 0;
2401  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
2402  {
2403  FragmentProgramData +=
2404  "uniform sampler2D uNormalMap;\n";
2405  TexNum++;
2406  }
2407 
2408  if (cUReflections)
2409  {
2410  FragmentProgramData += Ogre::String(
2411  "uniform sampler2D uReflectionMap;\n");
2412  TexNum++;
2413  }
2414  FragmentProgramData += Ogre::String(
2415  "uniform sampler2D uRefractionMap;\n");
2416  TexNum++;
2417 
2418  if (cDepth && cUReflections)
2419  {
2420  FragmentProgramData +=
2421  "uniform sampler2D uDepthReflectionMap;\n";
2422  TexNum++;
2423  }
2424 
2425  FragmentProgramData +=
2426  #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
2427  "uniform sampler1D uFresnelMap;\n";
2428  #else
2429  "uniform sampler2D uFresnelMap;\n";
2430  #endif
2431  TexNum++;
2432 
2433  /* Foam is not visible underwater
2434  if (cFoam)
2435  {
2436  FragmentProgramData +=
2437  "uniform sampler2D uFoamMap;\n";
2438  }
2439  */
2440  // IN
2441  FragmentProgramData +=
2442  "varying vec4 Position_;\n";
2443  int TEXCOORDNUM = 1;
2444  if (Options.NM == NM_TEXTURE)
2445  {
2446  TEXCOORDNUM++;
2447  }
2448  FragmentProgramData +=
2449  "varying vec4 UVProjection;\n";
2450  TEXCOORDNUM++;
2451  if (Options.NM == NM_VERTEX)
2452  {
2453  FragmentProgramData +=
2454  "varying vec3 Normal;\n";
2455  TEXCOORDNUM++;
2456  }
2457  /* Foam is not visible underwater
2458  if (cFoam)
2459  {
2460  FragmentProgramData +=
2461  "varying vec4 WorldPosition;\n";
2462  }
2463  */
2464  FragmentProgramData +=
2465  "varying vec2 Distance_;\n";
2466  // Expand function
2467  FragmentProgramData += Ogre::String(
2468  "vec3 expand(vec3 v)\n") +
2469  "{\n" +
2470  "return (v - 0.5) * 2.0;\n" +
2471  "}\n\n" +
2472  // main function
2473  "void main()\n" +
2474  "{\n" +
2475  "vec2 ProjectionCoord = UVProjection.xy / UVProjection.w;\n" +
2476  "ProjectionCoord += 1.0;\n" +
2477  "ProjectionCoord *= 0.5;\n" +
2478  "vec3 camToSurface = Position_.xyz - uEyePosition;\n" +
2479  "float additionalReflection=camToSurface.x*camToSurface.x+camToSurface.z*camToSurface.z;\n";
2480  /* Must not view foam underwater
2481  if (cFoam)
2482  {
2483  // Calculate the foam visibility as a function fo distance specified by user
2484  FragmentProgramData +=
2485  "float foamVisibility=1.0-clamp(additionalReflection/uFoamMaxDistance, 0.0, 1.0);\n";
2486  }
2487  */
2488  FragmentProgramData += Ogre::String(
2489  "additionalReflection/=uFullReflectionDistance;\n") +
2490  "camToSurface=normalize(-camToSurface);\n";
2491  if (Options.NM == NM_TEXTURE)
2492  {
2493  FragmentProgramData += Ogre::String(
2494  "vec3 pixelNormal = texture2D(uNormalMap,gl_TexCoord[0].xy).xyz;\n") +
2495  // Inverte y with z, because at creation our local normal to the plane was z
2496  "pixelNormal.yz=pixelNormal.zy;\n" +
2497  // Remap from [0,1] to [-1,1]
2498  "pixelNormal.xyz=-expand(pixelNormal.xyz);\n";
2499  }
2500  else if (Options.NM == NM_VERTEX)
2501  {
2502  FragmentProgramData +=
2503  "vec3 pixelNormal = -Normal;\n";
2504  }
2505  else // NM_RTT
2506  {
2507  FragmentProgramData +=
2508  "vec3 pixelNormal = -2.0*texture2D(uNormalMap, ProjectionCoord.xy).xyz - 1.0;\n";
2509  }
2510  FragmentProgramData +=
2511  "vec2 pixelNormalModified = uNormalDistortion*pixelNormal.zx;\n";
2512  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
2513  {
2514  FragmentProgramData +=
2515  "float dotProduct=dot(camToSurface,pixelNormal);\n";
2516  }
2517  else
2518  {
2519  FragmentProgramData +=
2520  "float dotProduct=dot(-camToSurface,pixelNormal);\n";
2521  }
2522  FragmentProgramData += Ogre::String(
2523  "dotProduct=clamp(dotProduct, 0.0, 1.0);\n") +
2524  #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
2525  "float fresnel = texture1D(uFresnelMap,dotProduct).x;\n" +
2526  #else
2527  "float fresnel = texture2D(uFresnelMap,vec2(dotProduct,dotProduct)).x;\n" +
2528  #endif
2529  // Add additional reflection and saturate
2530  "fresnel +=additionalReflection;\n" +
2531  "fresnel = clamp(fresnel, 0.0, 1.0);\n" +
2532  // Decrease the transparency and saturate
2533  "fresnel -= uGlobalTransparency;\n" +
2534  "fresnel = clamp(fresnel, 0.0, 1.0);\n" +
2535  // Get the reflection/refraction pixels. Make sure to disturb the texcoords by pixelnormal
2536  "vec3 reflection;\n" +
2537  #if OGRE_PLATFORM != OGRE_PLATFORM_WIN32
2538  // Reversing projection if underwater
2539  "if(uEyePosition.y < 0.0)\n" +
2540  "{\n" +
2541  "ProjectionCoord.y = 1.0 - ProjectionCoord.y;\n" +
2542  "}\n" +
2543  #endif
2544  "vec3 refraction=texture2D(uRefractionMap,ProjectionCoord.xy-pixelNormalModified).xyz;\n";
2545  if (cUReflections)
2546  {
2547  FragmentProgramData +=
2548  "reflection=texture2D(uReflectionMap,ProjectionCoord.xy+pixelNormalModified).xyz;\n";
2549  }
2550  else
2551  {
2552  FragmentProgramData +=
2553  "reflection=uWaterColor;\n";
2554  }
2555  if (cDepth && cUReflections)
2556  {
2557  if (cCaustics)
2558  {
2559  FragmentProgramData += Ogre::String(
2560  "vec2 depth = texture2D(uDepthReflectionMap,ProjectionCoord.xy+pixelNormalModified).xy;\n") +
2561  "reflection *= 1.0 + depth.y*uCausticsPower;\n" +
2562  "reflection = mix(uWaterColor,reflection,depth.x);\n";
2563  }
2564  else
2565  {
2566  FragmentProgramData += Ogre::String(
2567  "float depth = texture2D(uDepthReflectionMap,ProjectionCoord.xy+pixelNormalModified).x;\n") +
2568  "reflection = mix(uWaterColor,reflection,depth);\n";
2569  }
2570  }
2571  FragmentProgramData += Ogre::String(
2572  "gl_FragColor = vec4(mix(refraction,reflection,fresnel),1.0);\n") +
2573  "float Distance = clamp(1.0 - Distance_.x*uDistLimit, 0.0, 1.0);\n" +
2574  "gl_FragColor.xyz = mix(uWaterColor, gl_FragColor.xyz, Distance);\n" +
2575  "gl_FragColor.xyz = mix(gl_FragColor.xyz, uWaterColor, uGlobalTransparency);\n";
2576  if (cSun)
2577  {
2578  FragmentProgramData += Ogre::String(
2579  "vec3 refractedVector = normalize(reflect(-camToSurface,pixelNormal.xyz));\n") +
2580  "vec3 surfaceToSun=normalize(uSunPosition-Position_.xyz);\n" +
2581  // Temporally solution, fix this
2582  "surfaceToSun.xz = -surfaceToSun.xz;" +
2583  "vec3 sunlight = uSunStrength*pow(clamp(dot(refractedVector,surfaceToSun),0.0,1.0),uSunArea)*uSunColor;\n" +
2584  "Distance = clamp(1.0 - Distance_.y*uDepthLimit, 0.0, 1.0);\n";
2585  "gl_FragColor.xyz+=Distance*sunlight*clamp(1.0 - additionalReflection, 0.0, 1.0);\n";
2586  }
2587  /* Must not view foam underwater
2588  if (cFoam)
2589  {
2590  FragmentProgramData += Ogre::String(
2591  "float hmap = Position_.y/uFoamRange*foamVisibility;\n") +
2592  "vec2 foamTex=WorldPosition.xz*uFoamScale+pixelNormalModified;\n" +
2593  "float foam=texture2D(uFoamMap,foamTex).x;\n" +
2594  "float foamTransparency=clamp(hmap-uFoamStart, 0.0, 1.0)*uFoamTransparency;\n" +
2595  "gl_FragColor.xyz=mix(gl_FragColor.xyz,vec3(1.0,1.0,1.0),foamTransparency*foam);\n";
2596  }
2597  */
2598  FragmentProgramData +=
2599  "}\n";
2600  break;
2601  }
2602  }
2603  break;
2604  }
2605 
2606  // Second: build our material
2607  Ogre::MaterialPtr &UnderwaterMaterial = getMaterial(MAT_UNDERWATER);
2608  UnderwaterMaterial = Ogre::MaterialManager::getSingleton().
2610  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
2611 
2612  Ogre::Pass *UM_Technique0_Pass0 = UnderwaterMaterial->getTechnique(0)->getPass(0);
2613 
2614  UM_Technique0_Pass0->setDepthWriteEnabled(true);
2615  UM_Technique0_Pass0->setCullingMode(Ogre::CULL_NONE);
2616 
2617  Ogre::String GpuProgramsData[2] = {VertexProgramData, FragmentProgramData};
2618  Ogre::String GpuProgramNames[2] = {_def_Underwater_Shader_VP_Name, _def_Underwater_Shader_FP_Name};
2619  Ogre::String EntryPoints[2];
2620  if(Options.SM == SM_GLSL)
2621  {
2622  EntryPoints[0] = Ogre::String("main");
2623  EntryPoints[1] = Ogre::String("main");
2624  }
2625  else
2626  {
2627  EntryPoints[0] = Ogre::String("main_vp");
2628  EntryPoints[1] = Ogre::String("main_fp");
2629  }
2630 
2631  fillGpuProgramsToPass(UM_Technique0_Pass0, GpuProgramNames, Options.SM, EntryPoints, GpuProgramsData);
2632 
2633  Ogre::GpuProgramParametersSharedPtr VP_Parameters = UM_Technique0_Pass0->getVertexProgramParameters();
2634  Ogre::GpuProgramParametersSharedPtr FP_Parameters = UM_Technique0_Pass0->getFragmentProgramParameters();
2635 
2636  if(Options.SM != SM_GLSL)
2637  {
2638  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
2639  VP_Parameters->setNamedAutoConstant("uWorldView", Ogre::GpuProgramParameters::ACT_WORLDVIEW_MATRIX);
2640  VP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
2641  }
2642  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
2643  FP_Parameters->setNamedAutoConstant("uEyePosition", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
2644 
2645  FP_Parameters->setNamedConstant("uFullReflectionDistance", mHydrax->getFullReflectionDistance());
2646  FP_Parameters->setNamedConstant("uGlobalTransparency", mHydrax->getGlobalTransparency());
2647  FP_Parameters->setNamedConstant("uNormalDistortion", mHydrax->getNormalDistortion());
2648  FP_Parameters->setNamedConstant("uDistLimit", 1.f/mHydrax->getDistLimit());
2649  if (cSun)
2650  {
2651  }
2652  FP_Parameters->setNamedConstant("uWaterColor", mHydrax->getWaterColor());
2653 
2654  if (cSun)
2655  {
2656  FP_Parameters->setNamedConstant("uSunPosition", mHydrax->getMesh()->getObjectSpacePosition(mHydrax->getSunPosition()));
2657  FP_Parameters->setNamedConstant("uSunStrength", mHydrax->getSunStrength());
2658  FP_Parameters->setNamedConstant("uSunArea", mHydrax->getSunArea());
2659  FP_Parameters->setNamedConstant("uSunColor", mHydrax->getSunColor());
2660  FP_Parameters->setNamedConstant("uDepthLimit", 1.f/mHydrax->getDepthLimit());
2661  }
2662  /* Foam is not visible underwater
2663  if (cFoam)
2664  {
2665  FP_Parameters->setNamedConstant("uFoamRange", mHydrax->getMesh()->getOptions().MeshStrength);
2666  FP_Parameters->setNamedConstant("uFoamMaxDistance", mHydrax->getFoamMaxDistance());
2667  FP_Parameters->setNamedConstant("uFoamScale", mHydrax->getFoamScale());
2668  FP_Parameters->setNamedConstant("uFoamStart", mHydrax->getFoamStart());
2669  FP_Parameters->setNamedConstant("uFoamTransparency", mHydrax->getFoamTransparency());
2670  }
2671  */
2672  if (cCaustics && cDepth && cUReflections)
2673  {
2674  FP_Parameters->setNamedConstant("uCausticsPower", mHydrax->getCausticsPower());
2675  }
2676 
2677  int GLSLTextUnit = 0;
2678 
2679  if (Options.NM == NM_TEXTURE || Options.NM == NM_RTT)
2680  {
2681  if(Options.SM == SM_GLSL)
2682  {
2683  FP_Parameters->setNamedConstant("uNormalMap", GLSLTextUnit);
2684  GLSLTextUnit++;
2685  }
2686  UM_Technique0_Pass0->createTextureUnitState("HydraxNormalMap")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
2687  }
2688 
2689  if (cUReflections)
2690  {
2691  if(Options.SM == SM_GLSL)
2692  {
2693  FP_Parameters->setNamedConstant("uReflectionMap", GLSLTextUnit);
2694  GLSLTextUnit++;
2695  }
2696  UM_Technique0_Pass0->createTextureUnitState("HydraxReflectionMap")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
2697  }
2698  if(Options.SM == SM_GLSL)
2699  {
2700  FP_Parameters->setNamedConstant("uRefractionMap", GLSLTextUnit);
2701  GLSLTextUnit++;
2702  }
2703  UM_Technique0_Pass0->createTextureUnitState("HydraxRefractionMap")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
2704 
2705  if (cDepth && cUReflections)
2706  {
2707  if(Options.SM == SM_GLSL)
2708  {
2709  FP_Parameters->setNamedConstant("uDepthReflectionMap", GLSLTextUnit);
2710  GLSLTextUnit++;
2711  }
2712  UM_Technique0_Pass0->createTextureUnitState()->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
2713  }
2714 
2715  if(Options.SM == SM_GLSL)
2716  {
2717  FP_Parameters->setNamedConstant("uFresnelMap", GLSLTextUnit);
2718  GLSLTextUnit++;
2719  }
2720  UM_Technique0_Pass0->createTextureUnitState("Fresnel.bmp")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
2721 
2722  /* Foam is not visible underwater
2723  if (cFoam)
2724  {
2725  if(Options.SM == SM_GLSL)
2726  {
2727  FP_Parameters->setNamedConstant("uFoamMap", GLSLTextUnit);
2728  GLSLTextUnit++;
2729  }
2730  UM_Technique0_Pass0->createTextureUnitState("Foam.png")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
2731  }
2732  */
2733 
2734  UnderwaterMaterial->setReceiveShadows(false);
2735  UnderwaterMaterial->load();
2736 
2737  return true;
2738  }
2739 
2741  {
2742  const bool cCaustics = _isComponent(Components, HYDRAX_COMPONENT_CAUSTICS);
2743  const bool cDepth = _isComponent(Components, HYDRAX_COMPONENT_DEPTH);
2744  const bool cGodRays = _isComponent(Components, HYDRAX_COMPONENT_UNDERWATER_GODRAYS);
2745 
2746  Ogre::String VertexProgramData, FragmentProgramData;
2747 
2748  // Vertex program
2749  switch (Options.SM)
2750  {
2751  case SM_HLSL: case SM_CG:
2752  {
2753  VertexProgramData +=
2754  Ogre::String(
2755  "void main_vp(\n") +
2756  // IN
2757  "float4 iPosition : POSITION,\n" +
2758  // OUT
2759  "out float4 oPosition : POSITION,\n" +
2760  "out float3 oPosition_ : TEXCOORD0,\n" +
2761  "out float2 oUV : TEXCOORD1,\n";
2762  // UNIFORM
2763  if (cGodRays)
2764  {
2765  VertexProgramData +=
2766  Ogre::String(
2767  "uniform float3 uCorner0,\n") +
2768  "uniform float3 uCorner01,\n" +
2769  "uniform float3 uCorner02,\n";
2770  }
2771  VertexProgramData +=
2772  Ogre::String(
2773  "uniform float4x4 uWorldViewProj)\n") +
2774  "{\n" +
2775  "oPosition = mul(uWorldViewProj, iPosition);\n"+
2776  "iPosition.xy = sign(iPosition.xy);\n"+
2777  "oUV = (float2(iPosition.x, -iPosition.y) + 1.0f) * 0.5f;";
2778  if (cGodRays)
2779  {
2780  VertexProgramData += Ogre::String(
2781  "uCorner01 *= oUV.x;\n")+
2782  "uCorner02 *= oUV.y;\n"+
2783  "oPosition_ = uCorner0+uCorner01+uCorner02;";
2784  }
2785  VertexProgramData +=
2786  "}\n";
2787  }
2788  break;
2789 
2790  case SM_GLSL:
2791  {
2792  VertexProgramData += Ogre::String( "\n" );
2793  // UNIFORMS
2794  if (cGodRays)
2795  {
2796  VertexProgramData += Ogre::String(
2797  "uniform vec3 uCorner0;\n") +
2798  "uniform vec3 uCorner01;\n" +
2799  "uniform vec3 uCorner02;\n";
2800  }
2801  // IN
2802  // OUT
2803  VertexProgramData += Ogre::String(
2804  "varying vec3 Position_;\n") +
2805  "varying vec2 UV;\n" +
2806  // main function
2807  "void main()\n" +
2808  "{\n" +
2809  "gl_Position = ftransform();\n" +
2810  "vec2 iPosition = sign(gl_Vertex.xy);\n"+
2811  "UV = (vec2(iPosition.x, -iPosition.y) + 1.0) * 0.5;\n";
2812  if (cGodRays)
2813  {
2814  VertexProgramData += Ogre::String(
2815  "vec3 vCorner01 = uCorner01 * UV.x;\n")+
2816  "vec3 vCorner02 = uCorner02 * UV.y;\n"+
2817  "Position_ = uCorner0+vCorner01+vCorner02;\n";
2818  }
2819  VertexProgramData +=
2820  "}\n";
2821  }
2822  break;
2823  }
2824 
2825  // Fragment program
2826  switch (Options.SM)
2827  {
2828  case SM_HLSL: case SM_CG:
2829  {
2830  FragmentProgramData +=
2831  Ogre::String(
2832  "void main_fp(\n") +
2833  // IN
2834  "float3 iPosition : TEXCOORD0,\n" +
2835  "float2 iUV : TEXCOORD1,\n" +
2836  // OUT
2837  "out float4 oColor : COLOR,\n";
2838  // UNIFORM
2839  if (cCaustics)
2840  {
2841  FragmentProgramData +=
2842  "uniform float uCausticsPower,\n";
2843  }
2844  if (cGodRays)
2845  {
2846  FragmentProgramData += Ogre::String(
2847  "uniform float3 uSunColor,\n") +
2848  "uniform float3 uLightDirection,\n"+
2849  "uniform float uIntensity,\n"+
2850  "uniform float3 uHGg,\n"+
2851  "uniform float3 uCameraPos,\n";
2852  }
2853  FragmentProgramData += Ogre::String(
2854  "uniform float uTime,\n") +
2855  "uniform float3 uWaterColor,\n" +
2856  "uniform sampler2D uOriginalMap : register(s0),\n" +
2857  "uniform sampler2D uDistortMap : register(s1)\n";
2858  if (cDepth)
2859  {
2860  FragmentProgramData +=
2861  ",\nuniform sampler2D uDepthMap : register(s2)";
2862  }
2863  FragmentProgramData += Ogre::String(
2864  ")\n" ) +
2865  "{\n" +
2866  "float2 distortUV = (tex2D(uDistortMap, float2(iUV.x + uTime, iUV.y + uTime)).xy - 0.5)/50.0;\n";
2867  if (cCaustics) // Depth, caustics
2868  {
2869  FragmentProgramData += Ogre::String(
2870  "float2 depth = tex2D(uDepthMap, iUV+distortUV).xy;\n") +
2871  "float4 Color = float4(lerp(uWaterColor,tex2D(uOriginalMap, iUV+distortUV)*(1.0+depth.y*uCausticsPower), depth.x),1.0);\n";
2872  if (cGodRays)
2873  {
2874  FragmentProgramData += Ogre::String(
2875  "float3 view_vector = normalize(iPosition-uCameraPos);\n") +
2876  "float dot_product = dot(view_vector, -uLightDirection);\n"+
2877  "float num = uHGg.x;\n"+
2878  "float den = (uHGg.y - uHGg.z*dot_product);\n"+
2879  "den = rsqrt(den);\n"+
2880  "float phase = num * (den*den*den);\n" +
2881  "Color.xyz += (0.15 + uIntensity*tex2D(uDepthMap, iUV).z)*phase*uSunColor;\n";
2882  }
2883  }
2884  else if (cDepth) // Depth, no caustics
2885  {
2886  FragmentProgramData +=
2887  "float4 Color = float4(lerp(uWaterColor,tex2D(uOriginalMap, iUV+distortUV).xyz,tex2D(uDepthMap, iUV+distortUV).r),1.0);\n";
2888  if (cGodRays)
2889  {
2890  FragmentProgramData += Ogre::String(
2891  "float3 view_vector = normalize(iPosition-uCameraPos);") +
2892  "float dot_product = dot(view_vector, -uLightDirection);"+
2893  "float num = uHGg.x;"+
2894  "float den = (uHGg.y - uHGg.z*dot_product); "+
2895  "den = rsqrt(den); "+
2896  "float phase = num * (den*den*den);"+
2897  "Color.xyz += (0.15 + uIntensity*tex2D(uDepthMap, iUV).y)*phase*uSunColor;";
2898  }
2899  }
2900  else // No depth, no caustics
2901  {
2902  FragmentProgramData +=
2903  "float4 Color = tex2D(uOriginalMap, iUV+distortUV);";
2904  }
2905  FragmentProgramData += Ogre::String(
2906  "oColor = Color;\n") +
2907  "}\n";
2908  }
2909  break;
2910 
2911  case SM_GLSL:
2912  {
2913  FragmentProgramData += Ogre::String( "\n" );
2914  // UNIFORM
2915  if (cCaustics)
2916  {
2917  FragmentProgramData +=
2918  "uniform float uCausticsPower;\n";
2919  }
2920  if (cGodRays)
2921  {
2922  FragmentProgramData += Ogre::String(
2923  "uniform vec3 uSunColor;\n") +
2924  "uniform vec3 uLightDirection;\n"+
2925  "uniform float uIntensity;\n"+
2926  "uniform vec3 uHGg;\n"+
2927  "uniform vec3 uCameraPos;\n";
2928  }
2929  FragmentProgramData += Ogre::String(
2930  "uniform float uTime;\n") +
2931  "uniform float uGlobalTransparency;\n" +
2932  "uniform vec3 uWaterColor;\n" +
2933  "uniform sampler2D uOriginalMap;\n" +
2934  "uniform sampler2D uDistortMap;\n";
2935  if (cDepth)
2936  {
2937  FragmentProgramData +=
2938  "uniform sampler2D uDepthMap;\n";
2939  }
2940  // IN
2941  FragmentProgramData += Ogre::String(
2942  "varying vec3 Position_;\n") +
2943  "varying vec2 UV;\n" +
2944  // OUT
2945  // main function
2946  "void main()\n" +
2947  "{\n" +
2948  "vec2 distortUV = (texture2D(uDistortMap, vec2(UV.x + uTime, UV.y + uTime)).xy - 0.5)*0.02;\n";
2949  // "vec2 distortUV = vec2(0.0,0.0);\n";
2950  if (cCaustics) // Depth, caustics
2951  {
2952  FragmentProgramData += Ogre::String(
2953  "vec2 depth = texture2D(uDepthMap, UV+distortUV).xy;\n") +
2954  "gl_FragColor = vec4(mix(uWaterColor,texture2D(uOriginalMap, UV+distortUV).xyz*(1.0+depth.y*uCausticsPower), depth.x),1.0);\n";
2955  if (cGodRays)
2956  {
2957  FragmentProgramData += Ogre::String(
2958  "vec3 view_vector = normalize(Position_-uCameraPos);\n") +
2959  "float dot_product = dot(view_vector, -uLightDirection);\n"+
2960  "float num = uHGg.x;\n"+
2961  "float den = (uHGg.y - uHGg.z*dot_product);\n"+
2962  "den = inversesqrt(den);\n"+
2963  "float phase = num * pow(den, 3.0);\n"+
2964  "gl_FragColor.xyz += (0.15 + uIntensity*texture2D(uDepthMap, UV).z)*phase*uSunColor;";
2965  }
2966  }
2967  else if (cDepth) // Depth, no caustics
2968  {
2969  FragmentProgramData +=
2970  "gl_FragColor = vec4(mix(uWaterColor,texture2D(uOriginalMap, UV+distortUV).xyz,texture2D(uDepthMap, UV+distortUV).r),1.0);\n";
2971  if (cGodRays)
2972  {
2973  FragmentProgramData += Ogre::String(
2974  "vec3 view_vector = normalize(Position_-uCameraPos);\n") +
2975  "float dot_product = dot(view_vector, -uLightDirection);\n"+
2976  "float num = uHGg.x;\n"+
2977  "float den = (uHGg.y - uHGg.z*dot_product);\n"+
2978  "den = inversesqrt(den);\n"+
2979  "float phase = num * pow(den, 3.0);\n"+
2980  "gl_FragColor.xyz += (0.15 + uIntensity*texture2D(uDepthMap, UV).z)*phase*uSunColor;\n";
2981  }
2982  }
2983  else // No depth, no caustics
2984  {
2985  FragmentProgramData +=
2986  "gl_FragColor = texture2D(uOriginalMap, UV+distortUV);\n";
2987  }
2988  FragmentProgramData +=
2989  "}\n";
2990  }
2991  break;
2992  }
2993 
2994  // Build our material
2995  Ogre::MaterialPtr &UnderwaterCompositorMaterial = getMaterial(MAT_UNDERWATER_COMPOSITOR);
2996  UnderwaterCompositorMaterial = Ogre::MaterialManager::getSingleton().
2998  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
2999 
3000  Ogre::Pass *DM_Technique0_Pass0 = UnderwaterCompositorMaterial->getTechnique(0)->getPass(0);
3001 
3002  DM_Technique0_Pass0->setCullingMode(Ogre::CULL_NONE);
3003  DM_Technique0_Pass0->setDepthFunction(Ogre::CMPF_ALWAYS_PASS);
3004 
3005  Ogre::String GpuProgramsData[2] = {VertexProgramData, FragmentProgramData};
3007  Ogre::String EntryPoints[2];
3008  if(Options.SM == SM_GLSL)
3009  {
3010  EntryPoints[0] = Ogre::String("main");
3011  EntryPoints[1] = Ogre::String("main");
3012  }
3013  else
3014  {
3015  EntryPoints[0] = Ogre::String("main_vp");
3016  EntryPoints[1] = Ogre::String("main_fp");
3017  }
3018 
3019  fillGpuProgramsToPass(DM_Technique0_Pass0, GpuProgramNames, Options.SM, EntryPoints, GpuProgramsData);
3020 
3021  Ogre::GpuProgramParametersSharedPtr VP_Parameters = DM_Technique0_Pass0->getVertexProgramParameters();
3022  Ogre::GpuProgramParametersSharedPtr FP_Parameters = DM_Technique0_Pass0->getFragmentProgramParameters();
3023 
3024  if(Options.SM != SM_GLSL)
3025  {
3026  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
3027  }
3028 
3029  FP_Parameters->setNamedConstantFromTime("uTime", 0.1f);
3030  FP_Parameters->setNamedConstant("uWaterColor", mHydrax->getWaterColor());
3031 
3032  if (cCaustics)
3033  {
3034  FP_Parameters->setNamedConstant("uCausticsPower", mHydrax->getCausticsPower());
3035  }
3036 
3037  if (cGodRays)
3038  {
3039  FP_Parameters->setNamedConstant("uSunColor", mHydrax->getSunColor());
3040  FP_Parameters->setNamedConstant("uLightDirection",
3041  (mHydrax->getMesh()->getObjectSpacePosition(mHydrax->getCamera()->getPosition()) -
3043  .normalisedCopy());
3044  FP_Parameters->setNamedConstant("uIntensity", mHydrax->getGodRaysIntensity());
3045  FP_Parameters->setNamedConstant("uHGg", mHydrax->getGodRaysExposure());
3046  FP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION);
3047  }
3048 
3049  // From compositor, original scene
3050  int GLSLTextUnit = 0;
3051  if(Options.SM == SM_GLSL)
3052  {
3053  FP_Parameters->setNamedConstant("uOriginalMap", GLSLTextUnit);
3054  GLSLTextUnit++;
3055  }
3056  DM_Technique0_Pass0->createTextureUnitState()->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
3057  if(Options.SM == SM_GLSL)
3058  {
3059  FP_Parameters->setNamedConstant("uDistortMap", GLSLTextUnit);
3060  GLSLTextUnit++;
3061  }
3062  DM_Technique0_Pass0->createTextureUnitState("UnderwaterDistortion.jpg")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
3063  if (cDepth)
3064  {
3065  if(Options.SM == SM_GLSL)
3066  {
3067  FP_Parameters->setNamedConstant("uDepthMap", GLSLTextUnit);
3068  GLSLTextUnit++;
3069  }
3070  DM_Technique0_Pass0->createTextureUnitState("HydraxDepthMap")->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
3071  //Ogre::Viewport *Viewport = mHydrax->getCamera()->getViewport();
3072  }
3073 
3074  UnderwaterCompositorMaterial->setReceiveShadows(false);
3075  UnderwaterCompositorMaterial->load();
3076 
3077  Ogre::CompositorPtr &UnderwaterCompositor = getCompositor(COMP_UNDERWATER);
3078  UnderwaterCompositor = Ogre::CompositorManager::getSingleton().
3079  create(_def_Underwater_Compositor_Name, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
3080 
3081  Ogre::CompositionTechnique* UnderWaterComp_Technique = UnderwaterCompositor->createTechnique();
3082 
3083  // Create the texture definition to render the original scene
3084  Ogre::CompositionTechnique::TextureDefinition* TDef = UnderWaterComp_Technique->createTextureDefinition("OriginalScene");
3085  TDef->width = 0;
3086  TDef->height = 0;
3087  Ogre::PixelFormatList l;
3088  l.push_back(Ogre::PF_A8R8G8B8);
3089  TDef->formatList = l;
3090 
3091  // Render the original scene
3092  Ogre::CompositionTargetPass* CTPass = UnderWaterComp_Technique->createTargetPass();
3093  CTPass->setInputMode(Ogre::CompositionTargetPass::IM_NONE);
3094  CTPass->setOutputName("OriginalScene");
3095  Ogre::CompositionPass* CPassClear = CTPass->createPass();
3096  CPassClear->setType(Ogre::CompositionPass::PT_CLEAR);
3097 
3098  const Ogre::Vector3& WC = mHydrax->getWaterColor();
3099  CPassClear->setClearColour(Ogre::ColourValue(WC.x, WC.y, WC.z));
3100 
3101  Ogre::CompositionPass* CPass = CTPass->createPass();
3102  CPass->setType(Ogre::CompositionPass::PT_RENDERSCENE);
3103  CPass->setFirstRenderQueue(Ogre::RENDER_QUEUE_SKIES_EARLY+1);
3104 
3105  // Build the output target pass
3106  Ogre::CompositionTargetPass* CTOutputPass = UnderWaterComp_Technique->getOutputTargetPass();
3107  CTOutputPass->setInputMode(Ogre::CompositionTargetPass::IM_NONE);
3108 
3109  // Final composition pass
3110  Ogre::CompositionPass* COutputPass = CTOutputPass->createPass();
3111  COutputPass->setType(Ogre::CompositionPass::PT_RENDERQUAD);
3112  COutputPass->setMaterial(getMaterial(MAT_UNDERWATER_COMPOSITOR));
3113  COutputPass->setInput(0, "OriginalScene");
3114  COutputPass->setLastRenderQueue(0);
3115 
3116  Ogre::CompositorManager::getSingleton().
3118  addListener(&mUnderwaterCompositorListener);
3119 
3120  return true;
3121  }
3122 
3123  bool MaterialManager::_createSimpleColorMaterial(const Ogre::ColourValue& Color, const MaterialType& MT, const Ogre::String& Name, const bool& DepthCheck, const bool& DepthWrite)
3124  {
3125  Ogre::MaterialPtr &SimpleColorMaterial = getMaterial(MT);
3126  SimpleColorMaterial = Ogre::MaterialManager::getSingleton().
3127  create(Name,
3128  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
3129 
3130  Ogre::Pass *SCM_T0_Pass0 = SimpleColorMaterial->getTechnique(0)->getPass(0);
3131  SCM_T0_Pass0->setLightingEnabled(false);
3132  SCM_T0_Pass0->setDepthCheckEnabled(DepthCheck);
3133  SCM_T0_Pass0->setDepthWriteEnabled(DepthWrite);
3134  SCM_T0_Pass0->setCullingMode(Ogre::CULL_NONE);
3135  SCM_T0_Pass0->createTextureUnitState()->setColourOperationEx(Ogre::LBX_MODULATE,Ogre::LBS_MANUAL,Ogre::LBS_CURRENT, Color);
3136 
3137  SimpleColorMaterial->setReceiveShadows(false);
3138  SimpleColorMaterial->load();
3139 
3140  return true;
3141  }
3142 
3144  {
3145  Ogre::MaterialPtr &Mat = getMaterial(Material);
3146 
3147  if (Mat.isNull())
3148  {
3149  return;
3150  }
3151 
3152  Mat->reload();
3153 
3154  const bool cDepth = _isComponent(mComponents, HYDRAX_COMPONENT_DEPTH );
3155  const bool cSmooth = _isComponent(mComponents, HYDRAX_COMPONENT_SMOOTH );
3156  const bool cSun = _isComponent(mComponents, HYDRAX_COMPONENT_SUN );
3157  const bool cFoam = _isComponent(mComponents, HYDRAX_COMPONENT_FOAM );
3158  const bool cCaustics = _isComponent(mComponents, HYDRAX_COMPONENT_CAUSTICS);
3160 
3161  switch (Material)
3162  {
3163  case MAT_WATER:
3164  {
3165  Ogre::Pass *M_Technique0_Pass0 = Mat->getTechnique(0)->getPass(0);
3166 
3167  switch (mOptions.NM)
3168  {
3169  case NM_TEXTURE: case NM_RTT:
3170  {
3171  M_Technique0_Pass0->getTextureUnitState(0)->setTextureName("HydraxNormalMap");
3172  M_Technique0_Pass0->getTextureUnitState(1)->setTextureName("HydraxReflectionMap");
3173  M_Technique0_Pass0->getTextureUnitState(2)->setTextureName("HydraxRefractionMap");
3174  if (cDepth)
3175  {
3176  M_Technique0_Pass0->getTextureUnitState(3)->setTextureName("HydraxDepthMap");
3177  }
3178  }
3179  break;
3180 
3181  case NM_VERTEX:
3182  {
3183  M_Technique0_Pass0->getTextureUnitState(0)->setTextureName("HydraxReflectionMap");
3184  M_Technique0_Pass0->getTextureUnitState(1)->setTextureName("HydraxRefractionMap");
3185  if (cDepth)
3186  {
3187  M_Technique0_Pass0->getTextureUnitState(2)->setTextureName("HydraxDepthMap");
3188  }
3189  }
3190  break;
3191  }
3192 
3193  Ogre::GpuProgramParametersSharedPtr VP_Parameters = M_Technique0_Pass0->getVertexProgramParameters();
3194  Ogre::GpuProgramParametersSharedPtr FP_Parameters = M_Technique0_Pass0->getFragmentProgramParameters();
3195 
3196  if(mOptions.SM != SM_GLSL)
3197  {
3198  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
3199  }
3200  if (cFoam)
3201  {
3202  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
3203  }
3204  FP_Parameters->setNamedAutoConstant("uEyePosition", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
3205 
3206  FP_Parameters->setNamedConstant("uFullReflectionDistance", mHydrax->getFullReflectionDistance());
3207  FP_Parameters->setNamedConstant("uGlobalTransparency", mHydrax->getGlobalTransparency());
3208  FP_Parameters->setNamedConstant("uNormalDistortion", mHydrax->getNormalDistortion());
3209 
3210  FP_Parameters->setNamedConstant("uWaterColor", mHydrax->getWaterColor());
3211  if (cSmooth)
3212  {
3213  FP_Parameters->setNamedConstant("uSmoothPower", mHydrax->getSmoothPower());
3214  }
3215  if (cSun)
3216  {
3217  FP_Parameters->setNamedConstant("uSunPosition", mHydrax->getMesh()->getObjectSpacePosition(mHydrax->getSunPosition()));
3218  FP_Parameters->setNamedConstant("uSunStrength", mHydrax->getSunStrength());
3219  FP_Parameters->setNamedConstant("uSunArea", mHydrax->getSunArea());
3220  FP_Parameters->setNamedConstant("uSunColor", mHydrax->getSunColor());
3221  }
3222  if (cFoam)
3223  {
3224  FP_Parameters->setNamedConstant("uFoamRange", mHydrax->getMesh()->getOptions().MeshStrength);
3225  FP_Parameters->setNamedConstant("uFoamMaxDistance", mHydrax->getFoamMaxDistance());
3226  FP_Parameters->setNamedConstant("uFoamScale", mHydrax->getFoamScale());
3227  FP_Parameters->setNamedConstant("uFoamStart", mHydrax->getFoamStart());
3228  FP_Parameters->setNamedConstant("uFoamTransparency", mHydrax->getFoamTransparency());
3229  }
3230  if (cCaustics)
3231  {
3232  FP_Parameters->setNamedConstant("uCausticsPower", mHydrax->getCausticsPower());
3233  }
3234  }
3235  break;
3236 
3237  case MAT_DEPTH:
3238  {
3239  Ogre::Pass *M_Technique0_Pass0 = Mat->getTechnique(0)->getPass(0);
3240 
3241  Ogre::GpuProgramParametersSharedPtr VP_Parameters = M_Technique0_Pass0->getVertexProgramParameters();
3242  Ogre::GpuProgramParametersSharedPtr FP_Parameters = M_Technique0_Pass0->getFragmentProgramParameters();
3243 
3244  if(mOptions.SM != SM_GLSL)
3245  {
3246  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
3247  // VP_Parameters->setNamedAutoConstant("uWorldView", Ogre::GpuProgramParameters::ACT_WORLDVIEW_MATRIX);
3248  VP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION);
3249  }
3250  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
3251  VP_Parameters->setNamedConstant("uPlaneYPos", mHydrax->getPosition().y);
3252  VP_Parameters->setNamedConstant("uPlanesError", (float) mHydrax->getPlanesError());
3253 
3254  FP_Parameters->setNamedConstant("uDepthLimit", 1.f/mHydrax->getDepthLimit());
3255  FP_Parameters->setNamedConstant("uDistLimit", 1.f/mHydrax->getDistLimit());
3256 
3257  if (cCaustics)
3258  {
3259  FP_Parameters->setNamedConstant("uCausticsScale", mHydrax->getCausticsScale());
3260  FP_Parameters->setNamedConstant("uCausticsEnd", mHydrax->getCausticsEnd());
3261  }
3262  }
3263  break;
3264 
3265  case MAT_UNDERWATER:
3266  {
3267  Ogre::Pass *M_Technique0_Pass0 = Mat->getTechnique(0)->getPass(0);
3268 
3269  switch (mOptions.NM)
3270  {
3271  case NM_TEXTURE: case NM_RTT:
3272  {
3273  M_Technique0_Pass0->getTextureUnitState(0)->setTextureName("HydraxNormalMap");
3274  int Index = 1;
3275  if (cUReflections)
3276  {
3277  M_Technique0_Pass0->getTextureUnitState(Index)->setTextureName("HydraxReflectionMap");
3278  Index++;
3279  }
3280  M_Technique0_Pass0->getTextureUnitState(Index)->setTextureName("HydraxRefractionMap");
3281  Index++;
3282  if (cDepth && cUReflections)
3283  {
3284  M_Technique0_Pass0->getTextureUnitState(Index)->setTextureName("HydraxDepthReflectionMap");
3285  }
3286  }
3287  break;
3288 
3289  case NM_VERTEX:
3290  {
3291  int Index = 0;
3292  if (cUReflections)
3293  {
3294  M_Technique0_Pass0->getTextureUnitState(Index)->setTextureName("HydraxReflectionMap");
3295  Index++;
3296  }
3297  M_Technique0_Pass0->getTextureUnitState(Index)->setTextureName("HydraxRefractionMap");
3298  Index++;
3299  if (cDepth && cUReflections)
3300  {
3301  M_Technique0_Pass0->getTextureUnitState(Index)->setTextureName("HydraxDepthReflectionMap");
3302  }
3303  }
3304  break;
3305  }
3306 
3307  Ogre::GpuProgramParametersSharedPtr VP_Parameters = M_Technique0_Pass0->getVertexProgramParameters();
3308  Ogre::GpuProgramParametersSharedPtr FP_Parameters = M_Technique0_Pass0->getFragmentProgramParameters();
3309 
3310  if(mOptions.SM != SM_GLSL)
3311  {
3312  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
3313  VP_Parameters->setNamedAutoConstant("uWorldView", Ogre::GpuProgramParameters::ACT_WORLDVIEW_MATRIX);
3314  VP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
3315  }
3316  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
3317  FP_Parameters->setNamedAutoConstant("uEyePosition", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
3318 
3319  FP_Parameters->setNamedConstant("uFullReflectionDistance", mHydrax->getFullReflectionDistance());
3320  FP_Parameters->setNamedConstant("uGlobalTransparency", mHydrax->getGlobalTransparency());
3321  FP_Parameters->setNamedConstant("uNormalDistortion", mHydrax->getNormalDistortion());
3322  FP_Parameters->setNamedConstant("uDistLimit", 1.f/mHydrax->getDistLimit());
3323 
3324  if ((cDepth && cUReflections) || (!cUReflections))
3325  {
3326  FP_Parameters->setNamedConstant("uWaterColor", mHydrax->getWaterColor());
3327  }
3328 
3329  if (cSun)
3330  {
3331  FP_Parameters->setNamedConstant("uSunPosition", mHydrax->getMesh()->getObjectSpacePosition(mHydrax->getSunPosition()));
3332  FP_Parameters->setNamedConstant("uSunStrength", mHydrax->getSunStrength());
3333  FP_Parameters->setNamedConstant("uSunArea", mHydrax->getSunArea());
3334  FP_Parameters->setNamedConstant("uSunColor", mHydrax->getSunColor());
3335  FP_Parameters->setNamedConstant("uDepthLimit", 1.f/mHydrax->getDistLimit());
3336  }
3337  /* Foam is not visible underwater
3338  if (cFoam)
3339  {
3340  FP_Parameters->setNamedConstant("uFoamRange", mHydrax->getMesh()->getOptions().MeshStrength);
3341  FP_Parameters->setNamedConstant("uFoamMaxDistance", mHydrax->getFoamMaxDistance());
3342  FP_Parameters->setNamedConstant("uFoamScale", mHydrax->getFoamScale());
3343  FP_Parameters->setNamedConstant("uFoamStart", mHydrax->getFoamStart());
3344  FP_Parameters->setNamedConstant("uFoamTransparency", mHydrax->getFoamTransparency());
3345  }
3346  */
3347  if (cCaustics && cDepth && cUReflections)
3348  {
3349  FP_Parameters->setNamedConstant("uCausticsPower", mHydrax->getCausticsPower());
3350  }
3351  }
3352  break;
3353 
3355  {
3357  }
3358  break;
3359 
3360  case MAT_SIMPLE_RED:
3361  {
3362  }
3363  break;
3364  case MAT_SIMPLE_BLACK:
3365  {
3366  }
3367  break;
3368  }
3369  }
3370 
3371  void MaterialManager::addDepthTechnique(Ogre::Technique *Technique, const bool& AutoUpdate)
3372  {
3373  if (!Ogre::MaterialManager::getSingleton().resourceExists(_def_Depth_Material_Name))
3374  {
3376  }
3377 
3378  Technique->removeAllPasses();
3379  Technique->createPass();
3380  Technique->setName("_Hydrax_Depth_Technique");
3381  Technique->setSchemeName("HydraxDepth");
3382 
3383  Ogre::Pass *DM_Technique_Pass0 = Technique->getPass(0);
3384 
3385  DM_Technique_Pass0->setVertexProgram(_def_Depth_Shader_VP_Name);
3386  DM_Technique_Pass0->setFragmentProgram(_def_Depth_Shader_FP_Name);
3387 
3388  Ogre::GpuProgramParametersSharedPtr VP_Parameters = DM_Technique_Pass0->getVertexProgramParameters();
3389  Ogre::GpuProgramParametersSharedPtr FP_Parameters = DM_Technique_Pass0->getFragmentProgramParameters();
3390 
3391  if(mOptions.SM != SM_GLSL)
3392  {
3393  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
3394  VP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION);
3395  }
3396  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
3397  VP_Parameters->setNamedConstant("uPlaneYPos", mHydrax->getPosition().y);
3398  VP_Parameters->setNamedConstant("uPlanesError", (float) mHydrax->getPlanesError());
3399 
3400  FP_Parameters->setNamedConstant("uDepthLimit", 1/mHydrax->getDepthLimit());
3401  FP_Parameters->setNamedConstant("uDistLimit", 1/mHydrax->getDistLimit());
3402 
3404  {
3405  FP_Parameters->setNamedConstant("uCausticsScale", mHydrax->getCausticsScale());
3406  FP_Parameters->setNamedConstant("uCausticsEnd", mHydrax->getCausticsEnd());
3407 
3408  if(mOptions.SM == SM_GLSL)
3409  {
3410  FP_Parameters->setNamedConstant("uCaustics", 0);
3411  }
3412  Ogre::TextureUnitState *TUS_Caustics = DM_Technique_Pass0->createTextureUnitState("Caustics.bmp");
3413  TUS_Caustics->setName("Caustics");
3414  TUS_Caustics->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
3415  TUS_Caustics->setAnimatedTextureName("Caustics.bmp", 32, 1.5);
3416  }
3417 
3418  if (AutoUpdate)
3419  {
3420  mDepthTechniques.push_back(Technique);
3421  }
3422  }
3423 
3424  void MaterialManager::addDepthTextureTechnique(Ogre::Technique *Technique, const Ogre::String& TextureName, const Ogre::String& AlphaChannel, const bool& AutoUpdate)
3425  {
3426  if (!Ogre::HighLevelGpuProgramManager::getSingleton().resourceExists(_def_DepthTexture_Shader_VP_Name+AlphaChannel))
3427  {
3429  }
3430 
3431  Technique->removeAllPasses();
3432  Technique->createPass();
3433  Technique->setName("_Hydrax_DepthTexture_Technique");
3434  Technique->setSchemeName("HydraxDepth");
3435 
3436  Ogre::Pass *DM_Technique_Pass0 = Technique->getPass(0);
3437 
3438  // Alpha channel will be stored in pass 0 name:
3439  DM_Technique_Pass0->setName(AlphaChannel);
3440 
3441  DM_Technique_Pass0->setVertexProgram(_def_DepthTexture_Shader_VP_Name+AlphaChannel);
3442  DM_Technique_Pass0->setFragmentProgram(_def_DepthTexture_Shader_FP_Name+AlphaChannel);
3443 
3444  DM_Technique_Pass0->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
3445  DM_Technique_Pass0->setDepthCheckEnabled(true);
3446  DM_Technique_Pass0->setDepthWriteEnabled(false);
3447 
3448  Ogre::GpuProgramParametersSharedPtr VP_Parameters = DM_Technique_Pass0->getVertexProgramParameters();
3449  Ogre::GpuProgramParametersSharedPtr FP_Parameters = DM_Technique_Pass0->getFragmentProgramParameters();
3450 
3451  if(mOptions.SM != SM_GLSL)
3452  {
3453  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
3454  VP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION);
3455  }
3456  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
3457  VP_Parameters->setNamedConstant("uPlaneYPos", mHydrax->getPosition().y);
3458  VP_Parameters->setNamedConstant("uPlanesError", (float) mHydrax->getPlanesError());
3459 
3460  FP_Parameters->setNamedConstant("uDepthLimit", 1/mHydrax->getDepthLimit());
3461  FP_Parameters->setNamedConstant("uDistLimit", 1/mHydrax->getDistLimit());
3462 
3464  {
3465  FP_Parameters->setNamedConstant("uCausticsScale", mHydrax->getCausticsScale());
3466  FP_Parameters->setNamedConstant("uCausticsEnd", mHydrax->getCausticsEnd());
3467 
3468  if(mOptions.SM == SM_GLSL)
3469  {
3470  FP_Parameters->setNamedConstant("uCaustics", 0);
3471  }
3472  Ogre::TextureUnitState *TUS_Caustics = DM_Technique_Pass0->createTextureUnitState("Caustics.bmp");
3473  TUS_Caustics->setName("Caustics");
3474  TUS_Caustics->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
3475  TUS_Caustics->setAnimatedTextureName("Caustics.bmp", 32, 1.5);
3476  }
3477 
3478  if(mOptions.SM == SM_GLSL)
3479  {
3480  FP_Parameters->setNamedConstant("uAlphaTex", 0);
3481  }
3482  Ogre::TextureUnitState *TUS_AlphaTex = DM_Technique_Pass0->createTextureUnitState(TextureName);
3483  TUS_AlphaTex->setName("_DetphTexture_Hydrax");
3484  TUS_AlphaTex->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
3485 
3486  if (AutoUpdate)
3487  {
3488  mDepthTechniques.push_back(Technique);
3489  }
3490  }
3491 
3492  void MaterialManager::setCompositorEnable(const CompositorType &Compositor, const bool &Enable)
3493  {
3494  Ogre::CompositorPtr &Comp = mCompositors[static_cast<int>(Compositor)];
3495 
3496  if (Comp.isNull())
3497  {
3498  return;
3499  }
3500 
3501  Ogre::CompositorManager::getSingleton().
3502  setCompositorEnabled(mHydrax->getViewport(), Comp->getName(), Enable);
3503 
3504  mCompositorsEnable[static_cast<int>(Compositor)] = Enable;
3505  }
3506 
3507  bool MaterialManager::_isComponent(const HydraxComponent &List, const HydraxComponent &ToCheck) const
3508  {
3509  if (List & ToCheck)
3510  {
3511  return true;
3512  }
3513 
3514  if (ToCheck == HYDRAX_COMPONENTS_NONE && List == HYDRAX_COMPONENTS_NONE)
3515  {
3516  return true;
3517  }
3518 
3519  if (ToCheck == HYDRAX_COMPONENTS_ALL && List == HYDRAX_COMPONENTS_ALL)
3520  {
3521  return true;
3522  }
3523 
3524  return false;
3525  }
3526 
3527  void MaterialManager::setGpuProgramParameter(const GpuProgram &GpuP, const MaterialType &MType, const Ogre::String &Name, const Ogre::Real &Value)
3528  {
3529  if (!mCreated)
3530  {
3531  return;
3532  }
3533 
3534  Ogre::GpuProgramParametersSharedPtr Parameters;
3535 
3536  switch (GpuP)
3537  {
3538  case GPUP_VERTEX:
3539  {
3540  Parameters = getMaterial(MType)->getTechnique(0)->getPass(0)->getVertexProgramParameters();
3541  }
3542  break;
3543 
3544  case GPUP_FRAGMENT:
3545  {
3546  Parameters = getMaterial(MType)->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
3547  }
3548  break;
3549  }
3550 
3551  Parameters->setNamedConstant(Name, Value);
3552 
3553  if (MType == MAT_DEPTH)
3554  {
3555  std::vector<Ogre::Technique*>::iterator TechIt;
3556 
3557  for(TechIt = mDepthTechniques.begin(); TechIt != mDepthTechniques.end(); TechIt++)
3558  {
3559  if (!(*TechIt))
3560  {
3561  mDepthTechniques.erase(TechIt);
3562  continue;
3563  }
3564 
3565  switch (GpuP)
3566  {
3567  case GPUP_VERTEX:
3568  {
3569  Parameters = (*TechIt)->getPass(0)->getVertexProgramParameters();
3570  }
3571  break;
3572 
3573  case GPUP_FRAGMENT:
3574  {
3575  Parameters = (*TechIt)->getPass(0)->getFragmentProgramParameters();
3576  }
3577  break;
3578  }
3579 
3580  Parameters->setNamedConstant(Name, Value);
3581  }
3582  }
3583  }
3584 
3585  void MaterialManager::setGpuProgramParameter(const GpuProgram &GpuP, const MaterialType &MType, const Ogre::String &Name, const Ogre::Vector2 &Value)
3586  {
3587  if (!mCreated)
3588  {
3589  return;
3590  }
3591 
3592  Ogre::GpuProgramParametersSharedPtr Parameters;
3593 
3594  switch (GpuP)
3595  {
3596  case GPUP_VERTEX:
3597  {
3598  Parameters = getMaterial(MType)->getTechnique(0)->getPass(0)->getVertexProgramParameters();
3599  }
3600  break;
3601 
3602  case GPUP_FRAGMENT:
3603  {
3604  Parameters = getMaterial(MType)->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
3605  }
3606  break;
3607  }
3608 
3609  float Value_[2] = {Value.x, Value.y};
3610 
3611  if (MType == MAT_DEPTH)
3612  {
3613  std::vector<Ogre::Technique*>::iterator TechIt;
3614 
3615  for(TechIt = mDepthTechniques.begin(); TechIt != mDepthTechniques.end(); TechIt++)
3616  {
3617  if (!(*TechIt))
3618  {
3619  mDepthTechniques.erase(TechIt);
3620  continue;
3621  }
3622 
3623  switch (GpuP)
3624  {
3625  case GPUP_VERTEX:
3626  {
3627  Parameters = (*TechIt)->getPass(0)->getVertexProgramParameters();
3628  }
3629  break;
3630 
3631  case GPUP_FRAGMENT:
3632  {
3633  Parameters = (*TechIt)->getPass(0)->getFragmentProgramParameters();
3634  }
3635  break;
3636  }
3637 
3638  Parameters->setNamedConstant(Name, Value_, 1, 2);
3639  }
3640  }
3641  }
3642 
3643  void MaterialManager::setGpuProgramParameter(const GpuProgram &GpuP, const MaterialType &MType, const Ogre::String &Name, const Ogre::Vector3 &Value)
3644  {
3645  if (!mCreated)
3646  {
3647  return;
3648  }
3649 
3650  Ogre::GpuProgramParametersSharedPtr Parameters;
3651 
3652  switch (GpuP)
3653  {
3654  case GPUP_VERTEX:
3655  {
3656  Parameters = getMaterial(MType)->getTechnique(0)->getPass(0)->getVertexProgramParameters();
3657  }
3658  break;
3659 
3660  case GPUP_FRAGMENT:
3661  {
3662  Parameters = getMaterial(MType)->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
3663  }
3664  break;
3665  }
3666 
3667  Parameters->setNamedConstant(Name, Value);
3668 
3669  if (MType == MAT_DEPTH)
3670  {
3671  std::vector<Ogre::Technique*>::iterator TechIt;
3672 
3673  for(TechIt = mDepthTechniques.begin(); TechIt != mDepthTechniques.end(); TechIt++)
3674  {
3675  if (!(*TechIt))
3676  {
3677  mDepthTechniques.erase(TechIt);
3678  continue;
3679  }
3680 
3681  switch (GpuP)
3682  {
3683  case GPUP_VERTEX:
3684  {
3685  Parameters = (*TechIt)->getPass(0)->getVertexProgramParameters();
3686  }
3687  break;
3688 
3689  case GPUP_FRAGMENT:
3690  {
3691  Parameters = (*TechIt)->getPass(0)->getFragmentProgramParameters();
3692  }
3693  break;
3694  }
3695 
3696  Parameters->setNamedConstant(Name, Value);
3697  }
3698  }
3699  }
3700 
3701  void MaterialManager::UnderwaterCompositorListener::notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat)
3702  {
3704  {
3705  Ogre::Pass* DM_Technique0_Pass0 = mat->getTechnique(0)->getPass(0);
3706  DM_Technique0_Pass0->getTextureUnitState(2)->setTextureName("HydraxDepthMap");
3707  }
3708  }
3709 
3710  void MaterialManager::UnderwaterCompositorListener::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat)
3711  {
3712  const Ogre::Vector3& WC = mMaterialManager->mHydrax->getWaterColor();
3713  Ogre::CompositorPtr &UnderwaterCompositor = mMaterialManager->getCompositor(COMP_UNDERWATER);
3714  UnderwaterCompositor->getTechnique(0)->getTargetPass(0)->getPass(0)->setClearColour(Ogre::ColourValue(WC.x, WC.y, WC.z));
3715 
3716  Ogre::GpuProgramParametersSharedPtr FP_Parameters = mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
3717 
3718  if (mMaterialManager->mHydrax->isComponent(HYDRAX_COMPONENT_DEPTH))
3719  {
3720  FP_Parameters->
3721  setNamedConstant("uWaterColor", mMaterialManager->mHydrax->getWaterColor());
3722  }
3723 
3724  if (mMaterialManager->mHydrax->isComponent(HYDRAX_COMPONENT_CAUSTICS))
3725  {
3726  FP_Parameters->
3727  setNamedConstant("uCausticsPower", mMaterialManager->mHydrax->getCausticsPower());
3728  }
3729 
3730  if (mMaterialManager->mHydrax->isComponent(HYDRAX_COMPONENT_UNDERWATER_GODRAYS))
3731  {
3732  FP_Parameters->
3733  setNamedConstant("uSunColor", mMaterialManager->mHydrax->getSunColor());
3734 
3735  FP_Parameters->setNamedConstant("uLightDirection",
3736  (mMaterialManager->mHydrax->getMesh()->getObjectSpacePosition(mMaterialManager->mHydrax->getCamera()->getPosition()) -
3737  mMaterialManager->mHydrax->getMesh()->getObjectSpacePosition(mMaterialManager->mHydrax->getSunPosition()))
3738  .normalisedCopy());
3739 
3740  FP_Parameters->setNamedConstant("uIntensity", mMaterialManager->mHydrax->getGodRaysIntensity());
3741  FP_Parameters->setNamedConstant("uHGg", mMaterialManager->mHydrax->getGodRaysExposure());
3742 
3743  Ogre::GpuProgramParametersSharedPtr VP_Parameters = mat->getTechnique(0)->getPass(0)->getVertexProgramParameters();
3744 
3745  // FAR_LEFT_TOP
3746  VP_Parameters->
3747  setNamedConstant( "uCorner0", mMaterialManager->mHydrax->getCamera()->getWorldSpaceCorners()[5] );
3748  // FAR_RIGHT_TOP - FAR_LEFT_TOP
3749  VP_Parameters->
3750  setNamedConstant( "uCorner01", mMaterialManager->mHydrax->getCamera()->getWorldSpaceCorners()[4] - mMaterialManager->mHydrax->getCamera()->getWorldSpaceCorners()[5]);
3751  // FAR_LEFT_BOTTOM - FAR_LEFT_TOP
3752  VP_Parameters->
3753  setNamedConstant( "uCorner02", mMaterialManager->mHydrax->getCamera()->getWorldSpaceCorners()[6] - mMaterialManager->mHydrax->getCamera()->getWorldSpaceCorners()[5]);
3754  }
3755 
3756  /*
3757  if (mMaterialManager->_isComponent(mMaterialManager->mComponents, HYDRAX_COMPONENT_DEPTH))
3758  {
3759  Ogre::Viewport *Viewport = mMaterialManager->mHydrax->getCamera()->getViewport();
3760  }
3761  */
3762 
3763  if (mMaterialManager->mCompositorsNeedToBeReloaded[COMP_UNDERWATER])
3764  {
3765  if (mMaterialManager->_isComponent(mMaterialManager->mComponents, HYDRAX_COMPONENT_DEPTH))
3766  {
3767  Ogre::Pass* DM_Technique0_Pass0 = mat->getTechnique(0)->getPass(0);
3768  DM_Technique0_Pass0->getTextureUnitState(2)->setTextureName("HydraxDepthMap");
3769  }
3770 
3771  mMaterialManager->mCompositorsNeedToBeReloaded[COMP_UNDERWATER] = false;
3772  }
3773  }
3774 }
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:371
Hydrax::Hydrax::getWaterColor
const Ogre::Vector3 & getWaterColor() const
Get water color.
Definition: Hydrax.h:476
Hydrax::MaterialManager::mMaterials
Ogre::MaterialPtr mMaterials[6]
Hydrax materials vector.
Definition: MaterialManager.h:359
Hydrax::MaterialManager::mCompositors
Ogre::CompositorPtr mCompositors[1]
Hydrax compositors vector.
Definition: MaterialManager.h:361
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:2740
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:363
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:1542
MaterialManager.h
Hydrax::MaterialManager::mHydrax
Hydrax * mHydrax
Hydrax main pointer.
Definition: MaterialManager.h:375
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
_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::MaterialManager::_createUnderwaterMaterial
bool _createUnderwaterMaterial(const HydraxComponent &Components, const Options &Options)
Create underwater material.
Definition: MaterialManager.cpp:1781
_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:3710
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:357
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:3492
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:3424
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:373
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:3527
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:3143
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:3371
Hydrax::Hydrax::getFoamMaxDistance
const Ogre::Real & getFoamMaxDistance() const
Get foam max distance.
Definition: Hydrax.h:516
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:3123
_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:369
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:3507
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:367
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::UnderwaterCompositorListener::notifyMaterialSetup
void notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat)
On material setup.
Definition: MaterialManager.cpp:3701
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:365
Hydrax::MaterialManager::MaterialManager
MaterialManager(Hydrax *h)
Constructor.
Definition: MaterialManager.cpp:62
Hydrax::MaterialManager::NM_VERTEX
@ NM_VERTEX
Definition: MaterialManager.h:105