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