diff --git a/Content/OgreInternal/FFPLib_AlphaTest.glsl b/Content/OgreInternal/FFPLib_AlphaTest.glsl
new file mode 100644
index 0000000..c28f059
--- /dev/null
+++ b/Content/OgreInternal/FFPLib_AlphaTest.glsl
@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------------
+// Program Name: FFPLib_AlphaTest
+// Program Desc: Alpha test function.
+// Program Type: Vertex/Pixel shader
+// Language: GLSL
+//-----------------------------------------------------------------------------
+
+#define CMPF_ALWAYS_FAIL 0
+#define CMPF_ALWAYS_PASS 1
+#define CMPF_LESS 2
+#define CMPF_LESS_EQUAL 3
+#define CMPF_EQUAL 4
+#define CMPF_NOT_EQUAL 5
+#define CMPF_GREATER_EQUAL 6
+#define CMPF_GREATER 7
+
+bool Alpha_Func(in int func, in float alphaRef, in float alphaValue)
+{
+ // ES2 does not have switch
+ if(func == CMPF_ALWAYS_PASS)
+ return true;
+ else if(func == CMPF_LESS)
+ return alphaValue < alphaRef;
+ else if(func == CMPF_LESS_EQUAL)
+ return alphaValue <= alphaRef;
+ else if(func == CMPF_EQUAL)
+ return alphaValue == alphaRef;
+ else if(func == CMPF_NOT_EQUAL)
+ return alphaValue != alphaRef;
+ else if(func == CMPF_GREATER_EQUAL)
+ return alphaValue >= alphaRef;
+ else if(func == CMPF_GREATER)
+ return alphaValue > alphaRef;
+
+ // CMPF_ALWAYS_FAIL and default
+ return false;
+}
+
+
+void FFP_Alpha_Test(in float func, in float alphaRef, in vec4 texel)
+{
+ bool pass_ = Alpha_Func(int(func), alphaRef, texel.a);
+ if (!pass_)
+ discard;
+}
diff --git a/Content/OgreInternal/FFPLib_Common.glsl b/Content/OgreInternal/FFPLib_Common.glsl
new file mode 100644
index 0000000..7961c71
--- /dev/null
+++ b/Content/OgreInternal/FFPLib_Common.glsl
@@ -0,0 +1 @@
+// this file is going to dissapear with Ogre 14
\ No newline at end of file
diff --git a/Content/OgreInternal/FFPLib_Fog.glsl b/Content/OgreInternal/FFPLib_Fog.glsl
new file mode 100644
index 0000000..3741d40
--- /dev/null
+++ b/Content/OgreInternal/FFPLib_Fog.glsl
@@ -0,0 +1,134 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+(Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org
+
+Copyright (c) 2000-2014 Torus Knot Software Ltd
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+-----------------------------------------------------------------------------
+*/
+
+//-----------------------------------------------------------------------------
+// Program Name: FFPLib_Fog
+// Program Desc: Fog functions of the FFP.
+// Program Type: Vertex/Pixel shader
+// Language: GLSL
+// Notes: Implements core functions needed by FFPFog class.
+// Based on fog engine.
+// See http://msdn.microsoft.com/en-us/library/bb173398.aspx
+// Vertex based fog: the w component of the out position is used
+// as the distance parameter to fog formulas. This is basically the z coordinate
+// in world space. See pixel fog under D3D docs. The fog factor is computed according
+// to each formula, then clamped and output to the pixel shader.
+// Pixel based fog: the w component of the out position is passed to pixel shader
+// that computes the fog factor based on it.
+// Both techniques use the fog factor in the end of the pixel shader to blend
+// the output color with the fog color.
+//-----------------------------------------------------------------------------
+
+
+
+//-----------------------------------------------------------------------------
+void FFP_VertexFog_Linear(in vec4 vOutPos,
+ in vec4 fogParams,
+ out float oFogFactor)
+{
+ float distance = abs(vOutPos.w);
+ float fogFactor = (fogParams.z - distance) * fogParams.w;
+
+ oFogFactor = clamp(fogFactor, 0.0, 1.0);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_VertexFog_Exp(in vec4 vOutPos,
+ in vec4 fogParams,
+ out float oFogFactor)
+{
+ float distance = abs(vOutPos.w);
+ float x = distance*fogParams.x;
+ float fogFactor = 1.0 / exp(x);
+
+ oFogFactor = clamp(fogFactor, 0.0, 1.0);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_VertexFog_Exp2(in vec4 vOutPos,
+ in vec4 fogParams,
+ out float oFogFactor)
+{
+ float distance = abs(vOutPos.w);
+ float x = (distance*fogParams.x*distance*fogParams.x);
+ float fogFactor = 1.0 / exp(x);
+
+ oFogFactor = clamp(fogFactor, 0.0, 1.0);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_PixelFog_PositionDepth(in mat4 mWorld,
+ in vec3 cameraPos,
+ in vec4 pos,
+ out vec3 oPosView,
+ out float oDepth)
+{
+ vec4 vOutPos = mul(mWorld, pos);
+ oPosView = vOutPos.xyz - cameraPos;
+ oDepth = length(oPosView);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_PixelFog_Linear(in float depth,
+ in vec4 fogParams,
+ in vec4 fogColor,
+ in vec4 baseColor,
+ out vec4 oColor)
+{
+ float distance = abs(depth);
+ float fogFactor = clamp((fogParams.z - distance) * fogParams.w, 0.0, 1.0);
+
+ oColor = mix(fogColor, baseColor, fogFactor);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_PixelFog_Exp(in float depth,
+ in vec4 fogParams,
+ in vec4 fogColor,
+ in vec4 baseColor,
+ out vec4 oColor)
+{
+ float distance = abs(depth);
+ float x = (distance*fogParams.x);
+ float fogFactor = clamp(1.0 / exp(x), 0.0, 1.0);
+
+ oColor = mix(fogColor, baseColor, fogFactor);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_PixelFog_Exp2(in float depth,
+ in vec4 fogParams,
+ in vec4 fogColor,
+ in vec4 baseColor,
+ out vec4 oColor)
+{
+ float distance = abs(depth);
+ float x = (distance*fogParams.x*distance*fogParams.x);
+ float fogFactor = clamp(1.0 / exp(x), 0.0, 1.0);
+
+ oColor = mix(fogColor, baseColor, fogFactor);
+}
diff --git a/Content/OgreInternal/FFPLib_Texturing.glsl b/Content/OgreInternal/FFPLib_Texturing.glsl
new file mode 100644
index 0000000..a77a270
--- /dev/null
+++ b/Content/OgreInternal/FFPLib_Texturing.glsl
@@ -0,0 +1,144 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+(Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org
+
+Copyright (c) 2000-2014 Torus Knot Software Ltd
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+-----------------------------------------------------------------------------
+*/
+
+//-----------------------------------------------------------------------------
+// Program Name: FFPLib_Texturing
+// Program Desc: Texture functions of the FFP.
+// Program Type: Vertex/Pixel shader
+// Language: GLSL
+// Notes: Implements core functions for FFPTexturing class.
+// based on texturing operations needed by render system.
+// Implements texture coordinate processing:
+// see http://msdn.microsoft.com/en-us/library/bb206247.aspx
+// Implements texture blending operation:
+// see http://msdn.microsoft.com/en-us/library/bb206241.aspx
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+void FFP_TransformTexCoord(in mat4 m, in vec2 v, out vec2 vOut)
+{
+ vOut = mul(m, vec4(v, 0.0, 1.0)).xy;
+}
+//-----------------------------------------------------------------------------
+void FFP_TransformTexCoord(in mat4 m, in vec4 v, out vec2 vOut)
+{
+ vOut = mul(m, v).xy;
+}
+
+//-----------------------------------------------------------------------------
+void FFP_TransformTexCoord(in mat4 m, in vec3 v, out vec3 vOut)
+{
+ vOut = mul(m, vec4(v, 1.0)).xyz;
+}
+
+//-----------------------------------------------------------------------------
+void FFP_GenerateTexCoord_EnvMap_Normal(in mat3 mWorldIT,
+ in vec3 vNormal,
+ out vec3 vOut)
+{
+ vOut = normalize(mul(mWorldIT, vNormal));
+}
+
+//-----------------------------------------------------------------------------
+void FFP_GenerateTexCoord_EnvMap_Sphere(in mat4 mWorldView,
+ in mat3 mWorldIT,
+ in vec4 vPos,
+ in vec3 vNormal,
+ out vec2 vOut)
+{
+ vec3 normal = normalize( mul(mWorldIT, vNormal));
+ vec3 eyedir = normalize(mul(mWorldView, vPos)).xyz;
+ vec3 r = reflect(eyedir, normal);
+ r.z += 1.0;
+ float two_p = 2.0 * length(r);
+ vOut = vec2(0.5 + r.x / two_p, 0.5 - r.y / two_p);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_GenerateTexCoord_EnvMap_Reflect(in mat4 mWorld,
+ in mat4 mWorldIT,
+ in vec3 vCamPos,
+ in vec3 vNormal,
+ in vec4 vPos,
+ out vec3 vOut)
+{
+ vec3 vWorldNormal = normalize(mul(mWorldIT, vec4(vNormal, 0.0)).xyz);
+ vec3 vWorldPos = mul(mWorld, vPos).xyz;
+ vec3 vEyeDir = normalize(vWorldPos - vCamPos);
+
+ vec3 vReflect = reflect(vEyeDir, vWorldNormal);
+ vReflect.z *= -1.0;
+
+ vOut = vReflect;
+}
+
+//-----------------------------------------------------------------------------
+void FFP_AddSmooth(in float vIn0, in float vIn1, out float vOut)
+{
+ vOut = vIn0 + vIn1 - (vIn0 * vIn1);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_AddSmooth(in vec2 vIn0, in vec2 vIn1, out vec2 vOut)
+{
+ vOut = vIn0 + vIn1 - (vIn0 * vIn1);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_AddSmooth(in vec3 vIn0, in vec3 vIn1, out vec3 vOut)
+{
+ vOut = vIn0 + vIn1 - (vIn0 * vIn1);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_AddSmooth(in vec4 vIn0, in vec4 vIn1, out vec4 vOut)
+{
+ vOut = vIn0 + vIn1 - (vIn0 * vIn1);
+}
+//-----------------------------------------------------------------------------
+void FFP_DotProduct(in float vIn0, in float vIn1, out float vOut)
+{
+ vOut = dot(vIn0, vIn1);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_DotProduct(in vec2 vIn0, in vec2 vIn1, out vec2 vOut)
+{
+ vOut = vec2_splat(dot(vIn0, vIn1));
+}
+
+//-----------------------------------------------------------------------------
+void FFP_DotProduct(in vec3 vIn0, in vec3 vIn1, out vec3 vOut)
+{
+ vOut = vec3_splat(dot(vIn0, vIn1));
+}
+
+//-----------------------------------------------------------------------------
+void FFP_DotProduct(in vec4 vIn0, in vec4 vIn1, out vec4 vOut)
+{
+ vOut = vec4_splat(dot(vIn0, vIn1));
+}
\ No newline at end of file
diff --git a/Content/OgreInternal/FFPLib_Transform.glsl b/Content/OgreInternal/FFPLib_Transform.glsl
new file mode 100644
index 0000000..4102ff2
--- /dev/null
+++ b/Content/OgreInternal/FFPLib_Transform.glsl
@@ -0,0 +1,117 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+(Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org
+
+Copyright (c) 2000-2014 Torus Knot Software Ltd
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+-----------------------------------------------------------------------------
+*/
+
+//-----------------------------------------------------------------------------
+// Program Name: FFPLib_Transform
+// Program Desc: Transform functions of the FFP.
+// Program Type: Vertex shader
+// Language: GLSL
+// Notes: Implements core functions for FFPTransform class.
+// based on transform engine.
+// See http://msdn.microsoft.com/en-us/library/bb206269.aspx
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+void FFP_Transform(in mat3 m,
+ in vec3 v,
+ out vec3 vOut)
+{
+ vOut = mul(m, v);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_Transform(in mat4 m,
+ in vec4 v,
+ out vec4 vOut)
+{
+ vOut = mul(m, v);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_Transform(in mat4 m,
+ in vec4 v,
+ out vec3 vOut)
+{
+ vOut = mul(m, v).xyz;
+}
+
+#ifdef OGRE_HLSL
+void FFP_Transform(in float3x4 m,
+ in float4 v,
+ out float3 vOut)
+{
+ vOut = mul(m, v);
+}
+
+//-----------------------------------------------------------------------------
+void FFP_Transform(in float3x4 m,
+ in float3 v,
+ out float3 vOut)
+{
+ vOut = mul((float3x3)m, v);
+}
+#elif !defined(OGRE_GLSLES) || OGRE_GLSLES > 100
+//-----------------------------------------------------------------------------
+void FFP_Transform(in mat3x4 m,
+ in vec4 v,
+ out vec3 vOut)
+{
+/* transpose non-square uniform matrix for correct row-major > column-major mapping
+ * to keep the indexing inside the shader so mat[0] returns the same data in both GLSL and HLSL
+ * although it will be the first row in HLSL and the first column in GLSL
+ */
+ vOut = v * m;
+}
+
+void FFP_Transform(in mat3x4 m,
+ in vec3 v,
+ out vec3 vOut)
+{
+ vOut = v * mat3(m);
+}
+#endif
+
+//-----------------------------------------------------------------------------
+void FFP_Transform(in mat4 m,
+ in vec3 v,
+ out vec3 vOut)
+{
+#ifdef OGRE_HLSL
+ vOut = mul((float3x3)m, v);
+#else
+ vOut = mat3(m) * v;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void FFP_DerivePointSize(in vec4 params,
+ in float d,
+ out float sz)
+{
+ sz = params.x/sqrt(params.y + params.z*d + params.w*d*d);
+}
diff --git a/Content/OgreInternal/GLSL_GL3Support.glsl b/Content/OgreInternal/GLSL_GL3Support.glsl
new file mode 100644
index 0000000..754e1d7
--- /dev/null
+++ b/Content/OgreInternal/GLSL_GL3Support.glsl
@@ -0,0 +1,86 @@
+// This file is part of the OGRE project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at https://www.ogre3d.org/licensing.
+
+// @public-api
+
+#if __VERSION__ == 100
+mat2 transpose(mat2 m)
+{
+ return mat2(m[0][0], m[1][0],
+ m[0][1], m[1][1]);
+}
+
+mat3 transpose(mat3 m)
+{
+ return mat3(m[0][0], m[1][0], m[2][0],
+ m[0][1], m[1][1], m[2][1],
+ m[0][2], m[1][2], m[2][2]);
+}
+
+mat4 transpose(mat4 m)
+{
+ return mat4(m[0][0], m[1][0], m[2][0], m[3][0],
+ m[0][1], m[1][1], m[2][1], m[3][1],
+ m[0][2], m[1][2], m[2][2], m[3][2],
+ m[0][3], m[1][3], m[2][3], m[3][3]);
+}
+#endif
+
+#if __VERSION__ > 120 || defined(OGRE_GLSLANG)
+#define texture1D texture
+#define texture2D texture
+#define texture3D texture
+#define texture2DArray texture
+#define textureCube texture
+#define shadow2D texture
+#define shadow2DProj textureProj
+#define texture2DProj textureProj
+#define texture2DLod textureLod
+#define textureCubeLod textureLod
+
+#if defined(OGRE_GLSLANG) || (__VERSION__ > 150 && defined(OGRE_VERTEX_SHADER)) || __VERSION__ >= 410
+#define IN(decl, loc) layout(location = loc) in decl;
+#else
+#define IN(decl, loc) in decl;
+#endif
+
+#if defined(OGRE_GLSLANG) || (__VERSION__ > 150 && defined(OGRE_FRAGMENT_SHADER)) || __VERSION__ >= 410
+#define OUT(decl, loc) layout(location = loc) out decl;
+#else
+#define OUT(decl, loc) out decl;
+#endif
+
+#else
+
+#ifdef OGRE_VERTEX_SHADER
+#define IN(decl, loc) attribute decl;
+#define OUT(decl, loc) varying decl;
+#else
+#define IN(decl, loc) varying decl;
+#define OUT(decl, loc) out decl;
+#endif
+
+#endif
+
+#if defined(OGRE_FRAGMENT_SHADER) && (defined(OGRE_GLSLANG) || (__VERSION__ > 130))
+#define gl_FragColor FragColor
+OUT(vec4 FragColor, 0)
+#endif
+
+#ifdef VULKAN
+
+#ifdef OGRE_VERTEX_SHADER
+#define OGRE_UNIFORMS_BEGIN layout(binding = 0, row_major) uniform OgreUniforms {
+#else
+#define OGRE_UNIFORMS_BEGIN layout(binding = 1, row_major) uniform OgreUniforms {
+#endif
+
+#define OGRE_UNIFORMS_END };
+
+#else
+
+#define OGRE_UNIFORMS_BEGIN
+#define OGRE_UNIFORMS_END
+
+#endif
\ No newline at end of file
diff --git a/Content/OgreInternal/HLSL_SM4Support.hlsl b/Content/OgreInternal/HLSL_SM4Support.hlsl
new file mode 100644
index 0000000..2d2e3ea
--- /dev/null
+++ b/Content/OgreInternal/HLSL_SM4Support.hlsl
@@ -0,0 +1,98 @@
+// This file is part of the OGRE project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at https://www.ogre3d.org/licensing.
+
+// @public-api
+
+#if OGRE_HLSL >= 4
+
+// SM4 separates sampler into Texture and SamplerState
+
+#define sampler1D Sampler1D
+#define sampler2D Sampler2D
+#define sampler3D Sampler3D
+#define samplerCUBE SamplerCube
+
+struct Sampler1D
+{
+ Texture1D t;
+ SamplerState s;
+};
+struct Sampler2D
+{
+ Texture2D t;
+ SamplerState s;
+};
+struct Sampler3D
+{
+ Texture3D t;
+ SamplerState s;
+};
+struct SamplerCube
+{
+ TextureCube t;
+ SamplerState s;
+};
+
+float4 tex1D(Sampler1D s, float v) { return s.t.Sample(s.s, v); }
+float4 tex2D(Sampler2D s, float2 v) { return s.t.Sample(s.s, v); }
+float4 tex3D(Sampler3D s, float3 v) { return s.t.Sample(s.s, v); }
+float4 texCUBE(SamplerCube s, float3 v) { return s.t.Sample(s.s, v); }
+float4 texCUBElod(SamplerCube s, float4 v) { return s.t.SampleLevel(s.s, v.xyz, v.w); }
+
+float4 tex2D(Sampler2D s, float2 v, float2 ddx, float2 ddy) { return s.t.SampleGrad(s.s, v, ddx, ddy); }
+float4 tex2Dproj(Sampler2D s, float4 v) { return s.t.Sample(s.s, v.xy/v.w); }
+float4 tex2Dlod(Sampler2D s, float4 v) { return s.t.SampleLevel(s.s, v.xy, v.w); }
+
+#define SAMPLER1D(name, reg) \
+ Texture1D name ## Tex : register(t ## reg);\
+ SamplerState name ## State : register(s ## reg);\
+ static Sampler1D name = {name ## Tex, name ## State}
+
+#define SAMPLER2D(name, reg) \
+ Texture2D name ## Tex : register(t ## reg);\
+ SamplerState name ## State : register(s ## reg);\
+ static Sampler2D name = {name ## Tex, name ## State}
+
+#define SAMPLER3D(name, reg) \
+ Texture3D name ## Tex : register(t ## reg);\
+ SamplerState name ## State : register(s ## reg);\
+ static Sampler3D name = {name ## Tex, name ## State}
+
+#define SAMPLERCUBE(name, reg) \
+ TextureCube name ## Tex : register(t ## reg);\
+ SamplerState name ## State : register(s ## reg);\
+ static SamplerCube name = {name ## Tex, name ## State}
+
+// the following are not available in D3D9, but provided for convenience
+struct Sampler2DShadow
+{
+ Texture2D t;
+ SamplerComparisonState s;
+};
+struct Sampler2DArray
+{
+ Texture2DArray t;
+ SamplerState s;
+};
+
+#define SAMPLER2DSHADOW(name, reg) \
+ Texture2D name ## Tex : register(t ## reg);\
+ SamplerComparisonState name ## State : register(s ## reg);\
+ static Sampler2DShadow name = {name ## Tex, name ## State}
+
+#define SAMPLER2DARRAY(name, reg) \
+ Texture2DArray name ## Tex : register(t ## reg);\
+ SamplerState name ## State : register(s ## reg);\
+ static Sampler2DArray name = {name ## Tex, name ## State}
+
+float tex2Dcmp(Sampler2DShadow s, float3 v) { return s.t.SampleCmpLevelZero(s.s, v.xy, v.z); }
+float4 tex2DARRAY(Sampler2DArray s, float3 v) { return s.t.Sample(s.s, v); }
+#else
+
+#define SAMPLER1D(name, reg) sampler1D name : register(s ## reg)
+#define SAMPLER2D(name, reg) sampler2D name : register(s ## reg)
+#define SAMPLER3D(name, reg) sampler3D name : register(s ## reg)
+#define SAMPLERCUBE(name, reg) samplerCUBE name : register(s ## reg)
+
+#endif
\ No newline at end of file
diff --git a/Content/OgreInternal/OgreUnifiedShader.h b/Content/OgreInternal/OgreUnifiedShader.h
new file mode 100644
index 0000000..370b671
--- /dev/null
+++ b/Content/OgreInternal/OgreUnifiedShader.h
@@ -0,0 +1,184 @@
+// This file is part of the OGRE project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at https://www.ogre3d.org/licensing.
+
+// greatly inspired by
+// - shiny: https://ogrecave.github.io/shiny/defining-materials-shaders.html
+// - bgfx: https://github.com/bkaradzic/bgfx/blob/master/src/bgfx_shader.sh
+
+/// general usage:
+// MAIN_PARAMETERS
+// IN(vec4 vertex, POSITION)
+// MAIN_DECLARATION
+// {
+// GLSL code here
+// }
+
+/// configuration
+// use macros that will be default with Ogre 14
+// #define USE_OGRE_FROM_FUTURE
+
+// @public-api
+
+#if defined(OGRE_HLSL) || defined(OGRE_CG)
+// HLSL
+#include "HLSL_SM4Support.hlsl"
+#define vec2 float2
+#define vec3 float3
+#define vec4 float4
+#define mat3 float3x3
+#define mat4 float4x4
+
+#define ivec2 int2
+#define ivec3 int3
+#define ivec4 int4
+
+#define texture1D tex1D
+#define texture2D tex2D
+#define texture3D tex3D
+#define texture2DArray tex2DARRAY
+#define textureCube texCUBE
+#define shadow2D tex2Dcmp
+#define texture2DProj tex2Dproj
+vec4 texture2DLod(sampler2D s, vec2 v, float lod) { return tex2Dlod(s, vec4(v.x, v.y, 0, lod)); }
+
+#define samplerCube samplerCUBE
+vec4 textureCubeLod(samplerCube s, vec3 v, float lod) { return texCUBElod(s, vec4(v.x, v.y, v.z, lod)); }
+
+#define sampler2DShadow Sampler2DShadow
+
+#define mix lerp
+#define fract frac
+
+float mod(float _a, float _b) { return _a - _b * floor(_a / _b); }
+vec2 mod(vec2 _a, vec2 _b) { return _a - _b * floor(_a / _b); }
+vec3 mod(vec3 _a, vec3 _b) { return _a - _b * floor(_a / _b); }
+vec4 mod(vec4 _a, vec4 _b) { return _a - _b * floor(_a / _b); }
+
+vec2 vec2_splat(float x) { return vec2(x, x); }
+vec3 vec3_splat(float x) { return vec3(x, x, x); }
+vec4 vec4_splat(float x) { return vec4(x, x, x, x); }
+
+mat4 mtxFromRows(vec4 a, vec4 b, vec4 c, vec4 d)
+{
+ return mat4(a, b, c, d);
+}
+
+mat3 mtxFromRows(vec3 a, vec3 b, vec3 c)
+{
+ return mat3(a, b, c);
+}
+
+mat3 mtxFromCols(vec3 a, vec3 b, vec3 c)
+{
+ return transpose(mat3(a, b, c));
+}
+
+#define STATIC static
+
+#define OGRE_UNIFORMS_BEGIN
+#define OGRE_UNIFORMS_END
+
+#define MAIN_PARAMETERS void main(
+
+#ifdef OGRE_VERTEX_SHADER
+#define MAIN_DECLARATION out float4 gl_Position : POSITION)
+#else
+#define MAIN_DECLARATION in float4 gl_FragCoord : POSITION, out float4 gl_FragColor : COLOR)
+#endif
+
+#define IN(decl, sem) in decl : sem,
+#define OUT(decl, sem) out decl : sem,
+#elif defined(OGRE_METAL)
+#define vec2 float2
+#define vec3 float3
+#define vec4 float4
+#define mat3 metal::float3x3
+#define mat4 metal::float4x4
+
+#define IN(decl, sem) decl [[ attribute(sem) ]];
+#else
+// GLSL
+#include "GLSL_GL3Support.glsl"
+
+#ifndef USE_OGRE_FROM_FUTURE
+#define _UNIFORM_BINDING(b)
+#elif defined(VULKAN)
+#define _UNIFORM_BINDING(b) layout(binding = b + 2) uniform
+#elif __VERSION__ >= 420
+#define _UNIFORM_BINDING(b) layout(binding = b) uniform
+#else
+#define _UNIFORM_BINDING(b) uniform
+#endif
+
+#define SAMPLER1D(name, reg) _UNIFORM_BINDING(reg) sampler1D name
+#define SAMPLER2D(name, reg) _UNIFORM_BINDING(reg) sampler2D name
+#define SAMPLER3D(name, reg) _UNIFORM_BINDING(reg) sampler3D name
+#define SAMPLER2DARRAY(name, reg) _UNIFORM_BINDING(reg) sampler2DArray name
+#define SAMPLERCUBE(name, reg) _UNIFORM_BINDING(reg) samplerCube name
+#define SAMPLER2DSHADOW(name, reg) _UNIFORM_BINDING(reg) sampler2DShadow name
+
+#define saturate(x) clamp(x, 0.0, 1.0)
+#define mul(a, b) ((a) * (b))
+
+#define vec2_splat vec2
+#define vec3_splat vec3
+#define vec4_splat vec4
+
+mat4 mtxFromRows(vec4 a, vec4 b, vec4 c, vec4 d)
+{
+ return transpose(mat4(a, b, c, d));
+}
+
+mat3 mtxFromRows(vec3 a, vec3 b, vec3 c)
+{
+ return transpose(mat3(a, b, c));
+}
+
+mat3 mtxFromCols(vec3 a, vec3 b, vec3 c)
+{
+ return mat3(a, b, c);
+}
+
+#define STATIC
+
+#define MAIN_PARAMETERS
+#define MAIN_DECLARATION void main()
+
+#endif
+
+#if !defined(OGRE_HLSL) && !defined(OGRE_CG)
+// semantics as aliases for attribute locations
+#define POSITION 0
+#define BLENDWEIGHT 1
+#define NORMAL 2
+#define COLOR0 3
+#define COLOR1 4
+#define COLOR COLOR0
+#define FOG 5
+#define BLENDINDICES 7
+#define TEXCOORD0 8
+#define TEXCOORD1 9
+#define TEXCOORD2 10
+#define TEXCOORD3 11
+#define TEXCOORD4 12
+#define TEXCOORD5 13
+#define TEXCOORD6 14
+#define TEXCOORD7 15
+#define TANGENT 14
+#endif
+
+#define OGRE_UNIFORMS(params) OGRE_UNIFORMS_BEGIN params OGRE_UNIFORMS_END
+
+// GL_EXT_shader_explicit_arithmetic_types polyfill
+#ifdef OGRE_GLSLES
+#define float32_t highp float
+#define f32vec2 highp vec2
+#define f32vec3 highp vec3
+#define f32vec4 highp vec4
+#else
+#define float32_t float
+#define f32vec2 vec2
+#define f32vec3 vec3
+#define f32vec4 vec4
+#endif
diff --git a/Content/OgreInternal/RTSLib_IBL.glsl b/Content/OgreInternal/RTSLib_IBL.glsl
new file mode 100644
index 0000000..f55372d
--- /dev/null
+++ b/Content/OgreInternal/RTSLib_IBL.glsl
@@ -0,0 +1,88 @@
+// This file is part of the OGRE project.
+// code adapted from Google Filament
+// SPDX-License-Identifier: Apache-2.0
+
+vec3 specularDFG(const PixelParams pixel) {
+ return mix(pixel.dfg.xxx, pixel.dfg.yyy, pixel.f0);
+}
+
+vec3 decodeDataForIBL(const vec4 data) {
+ return data.rgb;
+}
+
+vec3 Irradiance_RoughnessOne(samplerCube light_iblSpecular, const vec3 n, float iblRoughnessOneLevel) {
+ // note: lod used is always integer, hopefully the hardware skips tri-linear filtering
+ return decodeDataForIBL(textureCubeLod(light_iblSpecular, n, iblRoughnessOneLevel));
+}
+
+vec3 PrefilteredDFG_LUT(sampler2D light_iblDFG, float lod, float NoV) {
+ // coord = sqrt(linear_roughness), which is the mapping used by cmgen.
+ // OGRE Specific: y is flipped compared to Filament code
+ return texture2DLod(light_iblDFG, vec2(NoV, 1.0 - lod), 0.0).rgb;
+}
+
+float perceptualRoughnessToLod(float iblRoughnessOneLevel, float perceptualRoughness) {
+ // The mapping below is a quadratic fit for log2(perceptualRoughness)+iblRoughnessOneLevel when
+ // iblRoughnessOneLevel is 4. We found empirically that this mapping works very well for
+ // a 256 cubemap with 5 levels used. But also scales well for other iblRoughnessOneLevel values.
+ return iblRoughnessOneLevel * perceptualRoughness * (2.0 - perceptualRoughness);
+}
+
+vec3 prefilteredRadiance(samplerCube light_iblSpecular, const vec3 r, float perceptualRoughness, float iblRoughnessOneLevel) {
+ float lod = perceptualRoughnessToLod(iblRoughnessOneLevel, perceptualRoughness);
+ return decodeDataForIBL(textureCubeLod(light_iblSpecular, r, lod));
+}
+
+vec3 getSpecularDominantDirection(const vec3 n, const vec3 r, float roughness) {
+ return mix(r, n, roughness * roughness);
+}
+
+void evaluateIBL(inout PixelParams pixel,
+ in vec3 vNormal,
+ in vec3 viewPos,
+ in mat4 invViewMat,
+ in sampler2D dfgTex,
+ in samplerCube iblEnvTex,
+ in float iblRoughnessOneLevel,
+ in float iblLuminance,
+ inout vec3 color)
+{
+ vec3 shading_normal = normalize(vNormal);
+ vec3 shading_view = -normalize(viewPos);
+ float shading_NoV = clampNoV(abs(dot(shading_normal, shading_view)));
+
+ // the above is currently duplicated with CookTorrance
+
+ vec3 shading_reflected = reflect(-shading_view, shading_normal);
+
+ // Pre-filtered DFG term used for image-based lighting
+ pixel.dfg = PrefilteredDFG_LUT(dfgTex, pixel.perceptualRoughness, shading_NoV);
+
+ vec3 E = specularDFG(pixel);
+ vec3 r = getSpecularDominantDirection(shading_normal, shading_reflected, pixel.roughness);
+
+ // OGRE specific: convert r and n back to world space for texture sampling
+ r = normalize(mul(invViewMat, vec4(r, 0.0)).xyz);
+ r.z *= -1.0;
+ shading_normal = normalize(mul(invViewMat, vec4(shading_normal, 0.0)).xyz);
+
+ // specular layer
+ vec3 Fr = E * prefilteredRadiance(iblEnvTex, r, pixel.perceptualRoughness, iblRoughnessOneLevel);
+
+ vec3 diffuseIrradiance = Irradiance_RoughnessOne(iblEnvTex, shading_normal, iblRoughnessOneLevel);
+ vec3 Fd = pixel.diffuseColor * diffuseIrradiance * (1.0 - E);
+
+ Fr *= iblLuminance;
+ Fd *= iblLuminance;
+
+ // Combine all terms
+ // Note: iblLuminance is already premultiplied by the exposure
+
+ color = pow(color, vec3_splat(2.2)); // gamma to linear
+
+ color += Fr + Fd;
+
+ // linear to gamma
+ color = pow(color, vec3_splat(1.0/2.2));
+ color = saturate(color);
+}
\ No newline at end of file
diff --git a/Content/OgreInternal/SGXLib_CookTorrance.glsl b/Content/OgreInternal/SGXLib_CookTorrance.glsl
new file mode 100644
index 0000000..214c72c
--- /dev/null
+++ b/Content/OgreInternal/SGXLib_CookTorrance.glsl
@@ -0,0 +1,241 @@
+// This file is part of the OGRE project.
+// code adapted from Google Filament
+// SPDX-License-Identifier: Apache-2.0
+
+#define PI 3.14159265359
+
+#ifdef OGRE_GLSLES
+ // min roughness such that (MIN_PERCEPTUAL_ROUGHNESS^4) > 0 in fp16 (i.e. 2^(-14/4), rounded up)
+ #define MIN_PERCEPTUAL_ROUGHNESS 0.089
+#else
+ #define MIN_PERCEPTUAL_ROUGHNESS 0.045
+#endif
+
+#define MEDIUMP_FLT_MAX 65504.0
+#define saturateMediump(x) min(x, MEDIUMP_FLT_MAX)
+
+#define MIN_N_DOT_V 1e-4
+
+struct PixelParams
+{
+ vec3 baseColor;
+ vec3 diffuseColor;
+ float perceptualRoughness;
+ float roughness;
+ vec3 f0;
+ vec3 dfg;
+ vec3 energyCompensation;
+};
+
+float clampNoV(float NoV) {
+ // Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
+ return max(NoV, MIN_N_DOT_V);
+}
+
+// Computes x^5 using only multiply operations.
+float pow5(float x) {
+ float x2 = x * x;
+ return x2 * x2 * x;
+}
+
+// https://google.github.io/filament/Filament.md.html#materialsystem/diffusebrdf
+float Fd_Lambert() {
+ return 1.0 / PI;
+}
+
+// https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/fresnel(specularf)
+vec3 F_Schlick(const vec3 f0, float f90, float VoH) {
+ // Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"
+ return f0 + (f90 - f0) * pow5(1.0 - VoH);
+}
+
+vec3 computeDiffuseColor(const vec3 baseColor, float metallic) {
+ return baseColor.rgb * (1.0 - metallic);
+}
+
+vec3 computeF0(const vec3 baseColor, float metallic, float reflectance) {
+ return baseColor.rgb * metallic + (reflectance * (1.0 - metallic));
+}
+
+float perceptualRoughnessToRoughness(float perceptualRoughness) {
+ return perceptualRoughness * perceptualRoughness;
+}
+
+// https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/geometricshadowing(specularg)
+float V_SmithGGXCorrelated(float roughness, float NoV, float NoL) {
+ // Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
+ float a2 = roughness * roughness;
+ // TODO: lambdaV can be pre-computed for all the lights, it should be moved out of this function
+ float lambdaV = NoL * sqrt((NoV - a2 * NoV) * NoV + a2);
+ float lambdaL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2);
+ float v = 0.5 / (lambdaV + lambdaL);
+ // a2=0 => v = 1 / 4*NoL*NoV => min=1/4, max=+inf
+ // a2=1 => v = 1 / 2*(NoL+NoV) => min=1/4, max=+inf
+ // clamp to the maximum value representable in mediump
+ return saturateMediump(v);
+}
+
+// https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/normaldistributionfunction(speculard)
+float D_GGX(float roughness, float NoH, const vec3 h, const vec3 n) {
+ // Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces"
+
+ // In mediump, there are two problems computing 1.0 - NoH^2
+ // 1) 1.0 - NoH^2 suffers floating point cancellation when NoH^2 is close to 1 (highlights)
+ // 2) NoH doesn't have enough precision around 1.0
+ // Both problem can be fixed by computing 1-NoH^2 in highp and providing NoH in highp as well
+
+ // However, we can do better using Lagrange's identity:
+ // ||a x b||^2 = ||a||^2 ||b||^2 - (a . b)^2
+ // since N and H are unit vectors: ||N x H||^2 = 1.0 - NoH^2
+ // This computes 1.0 - NoH^2 directly (which is close to zero in the highlights and has
+ // enough precision).
+ // Overall this yields better performance, keeping all computations in mediump
+#ifdef OGRE_GLSLES
+ vec3 NxH = cross(n, h);
+ float oneMinusNoHSquared = dot(NxH, NxH);
+#else
+ float oneMinusNoHSquared = 1.0 - NoH * NoH;
+#endif
+
+ float a = NoH * roughness;
+ float k = roughness / (oneMinusNoHSquared + a * a);
+ float d = k * k * (1.0 / PI);
+ return saturateMediump(d);
+}
+
+float getDistanceAttenuation(const vec3 params, float distance)
+{
+ return 1.0 / (params.x + params.y * distance + params.z * distance * distance);
+}
+
+float getAngleAttenuation(const vec3 params, const vec3 lightDir, const vec3 toLight)
+{
+ float rho = dot(-lightDir, toLight);
+ float fSpotE = saturate((rho - params.y) / (params.x - params.y));
+ return pow(fSpotE, params.z);
+}
+
+void evaluateLight(
+ in vec3 vNormal,
+ in vec3 viewPos,
+ in vec4 lightPos,
+ in vec3 lightColor,
+ in vec4 pointParams,
+ in vec4 vLightDirView,
+ in vec4 spotParams,
+ in PixelParams pixel,
+ inout vec3 vOutColour)
+{
+ vec3 vLightView = lightPos.xyz;
+ float fLightD = 0.0;
+
+ if (lightPos.w != 0.0)
+ {
+ vLightView -= viewPos; // to light
+ fLightD = length(vLightView);
+
+ if(fLightD > pointParams.x)
+ return;
+ }
+
+ vLightView = normalize(vLightView);
+
+ vec3 vNormalView = normalize(vNormal);
+ float NoL = saturate(dot(vNormalView, vLightView));
+
+ if(NoL <= 0.0)
+ return; // not lit by this light
+
+ // https://google.github.io/filament/Filament.md.html#toc5.6.2
+ float f90 = saturate(dot(pixel.f0, vec3_splat(50.0 * 0.33)));
+
+ vec3 vView = -normalize(viewPos);
+
+ // https://google.github.io/filament/Filament.md.html#materialsystem/standardmodelsummary
+ vec3 h = normalize(vView + vLightView);
+ float NoH = saturate(dot(vNormalView, h));
+ float NoV = clampNoV(abs(dot(vNormalView, vView)));
+
+ float V = V_SmithGGXCorrelated(pixel.roughness, NoV, NoL);
+ vec3 F = F_Schlick(pixel.f0, f90, NoH);
+ float D = D_GGX(pixel.roughness, NoH, h, vNormalView);
+
+ vec3 Fr = (D * V) * F;
+ vec3 Fd = pixel.diffuseColor * Fd_Lambert();
+
+ // https://google.github.io/filament/Filament.md.html#materialsystem/improvingthebrdfs/energylossinspecularreflectance
+ vec3 color = NoL * lightColor * (Fr * pixel.energyCompensation + Fd);
+
+ color *= getDistanceAttenuation(pointParams.yzw, fLightD);
+
+ if(spotParams.w != 0.0)
+ {
+ color *= getAngleAttenuation(spotParams.xyz, vLightDirView.xyz, vLightView);
+ }
+
+ vOutColour += color;
+}
+
+void PBR_MakeParams(in vec3 baseColor, in vec2 mrParam, inout PixelParams pixel)
+{
+#ifdef DEBUG_PSSM
+ baseColor += pssm_lod_info;
+#endif
+ baseColor = pow(baseColor, vec3_splat(2.2));
+ pixel.baseColor = baseColor;
+
+ float perceptualRoughness = mrParam.x;
+ // Clamp the roughness to a minimum value to avoid divisions by 0 during lighting
+ pixel.perceptualRoughness = clamp(perceptualRoughness, MIN_PERCEPTUAL_ROUGHNESS, 1.0);
+ // Remaps the roughness to a perceptually linear roughness (roughness^2)
+ pixel.roughness = perceptualRoughnessToRoughness(pixel.perceptualRoughness);
+
+ float metallic = saturate(mrParam.y);
+ pixel.f0 = computeF0(baseColor, metallic, 0.04);
+ pixel.diffuseColor = computeDiffuseColor(baseColor, metallic);
+
+ pixel.dfg = vec3_splat(0.5); // use full f0 for energy compensation
+ pixel.energyCompensation = vec3_splat(0.0); // will be set later
+}
+
+#if LIGHT_COUNT > 0
+void PBR_Lights(
+#ifdef HAVE_SHADOW_FACTOR
+ in float shadowFactor,
+#endif
+ in vec3 vNormal,
+ in vec3 viewPos,
+ in vec4 ambient,
+ in vec4 lightPos[LIGHT_COUNT],
+ in vec4 lightColor[LIGHT_COUNT],
+ in vec4 pointParams[LIGHT_COUNT],
+ in vec4 vLightDirView[LIGHT_COUNT],
+ in vec4 spotParams[LIGHT_COUNT],
+ in PixelParams pixel,
+ inout vec3 vOutColour)
+{
+ vOutColour = pow(vOutColour, vec3_splat(2.2)); // gamma to linear
+
+ // Energy compensation for multiple scattering in a microfacet model
+ // See "Multiple-Scattering Microfacet BSDFs with the Smith Model"
+ pixel.energyCompensation = 1.0 + pixel.f0 * (1.0 / pixel.dfg.y - 1.0);
+
+ for(int i = 0; i < LIGHT_COUNT; i++)
+ {
+ evaluateLight(vNormal, viewPos, lightPos[i], lightColor[i].xyz, pointParams[i], vLightDirView[i], spotParams[i],
+ pixel, vOutColour);
+
+#ifdef HAVE_SHADOW_FACTOR
+ if(i == 0) // directional lights always come first
+ vOutColour *= shadowFactor;
+#endif
+ }
+
+ vOutColour += pixel.baseColor * pow(ambient.rgb, vec3_splat(2.2));
+
+ // linear to gamma
+ vOutColour = pow(vOutColour, vec3_splat(1.0/2.2));
+
+ vOutColour = saturate(vOutColour);
+}
+#endif
\ No newline at end of file
diff --git a/Content/OgreInternal/SGXLib_DualQuaternion.glsl b/Content/OgreInternal/SGXLib_DualQuaternion.glsl
new file mode 100644
index 0000000..e9a64a3
--- /dev/null
+++ b/Content/OgreInternal/SGXLib_DualQuaternion.glsl
@@ -0,0 +1,172 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+(Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org
+
+Copyright (c) 2000-2014 Torus Knot Software Ltd
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+-----------------------------------------------------------------------------
+*/
+
+//These functions are based on dqs.cg from http://isg.cs.tcd.ie/kavanl/dq/
+/* dqs.cg
+
+ Dual quaternion skinning vertex shaders (no shading computations)
+
+ Version 1.0.3, November 1st, 2007
+
+ Copyright (C) 2006-2007 University of Dublin, Trinity College, All Rights
+ Reserved
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the author(s) be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Author: Ladislav Kavan, kavanl@cs.tcd.ie
+
+*/
+
+//-----------------------------------------------------------------------------
+// Program Name: SGXLib_DualQuaternion
+// Program Desc: Dual quaternion skinning functions.
+// Program Type: Vertex shader
+// Language: GLSL
+//-----------------------------------------------------------------------------
+
+#if defined(OGRE_HLSL) || defined(OGRE_CG)
+// this is technically wrong, thats why we dont put it into OgreUnifiedShader.h
+#define mat2x4 float2x4
+#define mat3x4 float3x4
+#endif
+
+//-----------------------------------------------------------------------------
+void SGX_BlendWeight(in float blendWgt, in mat2x4 dualQuaternion, out mat2x4 vOut)
+{
+ vOut = blendWgt*dualQuaternion;
+}
+
+//-----------------------------------------------------------------------------
+void SGX_BlendWeight(in float blendWgt, in mat3x4 scaleShearMatrix, out mat3x4 vOut)
+{
+ vOut = blendWgt*scaleShearMatrix;
+}
+
+//-----------------------------------------------------------------------------
+// Adjusts the sign of a dual quaternion depending on its orientation to the root dual quaternion
+void SGX_AntipodalityAdjustment(in mat2x4 dq0, in mat2x4 dq1,out mat2x4 dq2)
+{
+ //Accurate antipodality handling. For speed increase, remove the following line,
+ //though, the results will only be valid for rotations less than 180 degrees.
+ dq2 = (dot(dq0[0], dq1[0]) < 0.0) ? dq1 * -1.0 : dq1;
+}
+
+//-----------------------------------------------------------------------------
+void SGX_CalculateBlendPosition(in vec3 position, in mat2x4 blendDQ, out vec4 vOut)
+{
+ vec3 blendPosition = position + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, position) + blendDQ[0].x*position);
+ vec3 trans = 2.0*(blendDQ[0].x*blendDQ[1].yzw - blendDQ[1].x*blendDQ[0].yzw + cross(blendDQ[0].yzw, blendDQ[1].yzw));
+ blendPosition += trans;
+
+ vOut = vec4(blendPosition, 1.0);
+}
+
+//-----------------------------------------------------------------------------
+void SGX_CalculateBlendNormal(in vec3 normal, in mat2x4 blendDQ, out vec3 vOut)
+{
+ vOut = normal + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, normal) + blendDQ[0].x*normal);
+}
+
+//-----------------------------------------------------------------------------
+void SGX_AdjointTransposeMatrix(in mat3x4 M, out mat3 vOut)
+{
+ mat3 atM;
+ atM[0][0] = M[2][2] * M[1][1] - M[1][2] * M[2][1];
+ atM[0][1] = M[1][2] * M[2][0] - M[1][0] * M[2][2];
+ atM[0][2] = M[1][0] * M[2][1] - M[2][0] * M[1][1];
+
+ atM[1][0] = M[0][2] * M[2][1] - M[2][2] * M[0][1];
+ atM[1][1] = M[2][2] * M[0][0] - M[0][2] * M[2][0];
+ atM[1][2] = M[2][0] * M[0][1] - M[0][0] * M[2][1];
+
+ atM[2][0] = M[1][2] * M[0][1] - M[0][2] * M[1][1];
+ atM[2][1] = M[1][0] * M[0][2] - M[1][2] * M[0][0];
+ atM[2][2] = M[0][0] * M[1][1] - M[1][0] * M[0][1];
+
+ vOut = atM;
+}
+
+//-----------------------------------------------------------------------------
+void blendBonesDQ(mat2x4 bones_dq[BONE_COUNT], vec4 indices, vec4 weights, out mat2x4 blendDQ)
+{
+ blendDQ = bones_dq[int(indices.x)] * weights.x;
+ mat2x4 dqi;
+#ifdef CORRECT_ANTIPODALITY
+ mat2x4 dq0 = blendDQ;
+#endif
+#if WEIGHT_COUNT > 1
+ dqi = bones_dq[int(indices.y)] * weights.y;
+# ifdef CORRECT_ANTIPODALITY
+ SGX_AntipodalityAdjustment(dq0, dqi, dqi);
+# endif
+ blendDQ += dqi;
+#endif
+#if WEIGHT_COUNT > 2
+ dqi = bones_dq[int(indices.z)] * weights.z;
+# ifdef CORRECT_ANTIPODALITY
+ SGX_AntipodalityAdjustment(dq0, dqi, dqi);
+# endif
+ blendDQ += dqi;
+#endif
+#if WEIGHT_COUNT > 3
+ dqi = bones_dq[int(indices.w)] * weights.w;
+# ifdef CORRECT_ANTIPODALITY
+ SGX_AntipodalityAdjustment(dq0, dqi, dqi);
+# endif
+ blendDQ += dqi;
+#endif
+
+ blendDQ /= length(blendDQ[0]); // normalise dual quaternion
+}
+
+void blendBonesMat3x4(mat3x4 bones_mat[BONE_COUNT], vec4 indices, vec4 weights, out mat3x4 blendMat)
+{
+ blendMat = bones_mat[int(indices.x)] * weights.x;
+#if WEIGHT_COUNT > 1
+ blendMat += bones_mat[int(indices.y)] * weights.y;
+#endif
+#if WEIGHT_COUNT > 2
+ blendMat += bones_mat[int(indices.z)] * weights.z;
+#endif
+#if WEIGHT_COUNT > 3
+ blendMat += bones_mat[int(indices.w)] * weights.w;
+#endif
+}
\ No newline at end of file
diff --git a/Content/OgreInternal/SGXLib_IntegratedPSSM.glsl b/Content/OgreInternal/SGXLib_IntegratedPSSM.glsl
new file mode 100644
index 0000000..a5ad1bc
--- /dev/null
+++ b/Content/OgreInternal/SGXLib_IntegratedPSSM.glsl
@@ -0,0 +1,182 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+(Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org
+
+Copyright (c) 2000-2014 Torus Knot Software Ltd
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+-----------------------------------------------------------------------------
+*/
+//-----------------------------------------------------------------------------
+// Program Name: SGXLib_IntegratedPSSM
+// Program Desc: Integrated PSSM functions.
+// Program Type: Vertex/Pixel shader
+// Language: GLSL
+//-----------------------------------------------------------------------------
+
+#ifdef PSSM_SAMPLE_CMP
+#define SAMPLER_TYPE sampler2DShadow
+#else
+#define SAMPLER_TYPE sampler2D
+#endif
+
+#ifdef DEBUG_PSSM
+STATIC vec3 pssm_lod_info = vec3(0.0, 0.0, 0.0);
+#endif
+
+// default to 2x2 PCF
+#ifndef PCF_XSAMPLES
+#define PCF_XSAMPLES 2.0
+#endif
+
+//-----------------------------------------------------------------------------
+void SGX_ApplyShadowFactor_Diffuse(in vec4 ambient,
+ in float fShadowFactor,
+ inout vec4 oLight)
+{
+ oLight.rgb = mix(ambient.rgb, oLight.rgb, fShadowFactor);
+
+#ifdef DEBUG_PSSM
+ oLight.rgb += pssm_lod_info;
+#endif
+}
+
+float sampleDepth(in SAMPLER_TYPE shadowMap, vec2 uv, float depth)
+{
+#ifdef PSSM_SAMPLE_CMP
+# if defined(OGRE_GLSL) && OGRE_GLSL < 130
+ return shadow2D(shadowMap, vec3(uv, depth)).r;
+# else
+ return shadow2D(shadowMap, vec3(uv, depth));
+# endif
+#else
+ return (depth <= texture2D(shadowMap, uv).r) ? 1.0 : 0.0;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void SGX_ShadowPCF4(in SAMPLER_TYPE shadowMap, in vec4 shadowMapPos, in vec2 invTexSize, out float c)
+{
+ shadowMapPos = shadowMapPos / shadowMapPos.w;
+#if !defined(OGRE_REVERSED_Z) && !defined(OGRE_HLSL) && !defined(VULKAN)
+ shadowMapPos.z = shadowMapPos.z * 0.5 + 0.5; // convert -1..1 to 0..1
+#endif
+ vec2 uv = shadowMapPos.xy;
+
+ // depth must be clamped to support floating-point depth formats. This is to avoid comparing a
+ // value from the depth texture (which is never greater than 1.0) with a greater-than-one
+ // comparison value (which is possible with floating-point formats).
+ float depth = clamp(shadowMapPos.z, 0.0, 1.0);
+
+ c = 0.0;
+ float scale = 1.0;
+ float offset = (PCF_XSAMPLES / 2.0 - 0.5) * scale;
+ for (float y = -offset; y <= offset; y += scale)
+ for (float x = -offset; x <= offset; x += scale)
+ c += sampleDepth(shadowMap, uv + invTexSize * vec2(x, y), depth);
+
+ c /= PCF_XSAMPLES * PCF_XSAMPLES;
+}
+
+//-----------------------------------------------------------------------------
+void SGX_ComputeShadowFactor_PSSM3(in float fDepth,
+ in vec4 vSplitPoints,
+ in vec4 lightPosition0,
+ in SAMPLER_TYPE shadowMap0,
+ in vec2 invShadowMapSize0,
+ #if PSSM_NUM_SPLITS > 2
+ in vec4 lightPosition1,
+ in SAMPLER_TYPE shadowMap1,
+ in vec2 invShadowMapSize1,
+ #endif
+ #if PSSM_NUM_SPLITS > 3
+ in vec4 lightPosition2,
+ in SAMPLER_TYPE shadowMap2,
+ in vec2 invShadowMapSize2,
+ #endif
+ in vec4 lightPosition3,
+ in SAMPLER_TYPE shadowMap3,
+ in vec2 invShadowMapSize3,
+ out float oShadowFactor)
+{
+#if defined(PROJ_SPACE_SPLITS) && !defined(OGRE_REVERSED_Z) && !defined(OGRE_HLSL) && !defined(VULKAN)
+ vSplitPoints = vSplitPoints * 0.5 + 0.5; // convert -1..1 to 0..1
+#endif
+
+#ifdef OGRE_REVERSED_Z
+ vSplitPoints = vec4_splat(1.0) - vSplitPoints;
+ fDepth = 1.0 - fDepth;
+#endif
+
+ if (fDepth <= vSplitPoints.x)
+ {
+#ifdef PSSM_SAMPLE_COLOUR
+ oShadowFactor = texture2DProj(shadowMap0, lightPosition0).x;
+#else
+ SGX_ShadowPCF4(shadowMap0, lightPosition0, invShadowMapSize0, oShadowFactor);
+#endif
+#ifdef DEBUG_PSSM
+ pssm_lod_info.r = 1.0;
+#endif
+ }
+#if PSSM_NUM_SPLITS > 2
+ else if (fDepth <= vSplitPoints.y)
+ {
+#ifdef PSSM_SAMPLE_COLOUR
+ oShadowFactor = texture2DProj(shadowMap1, lightPosition1).x;
+#else
+ SGX_ShadowPCF4(shadowMap1, lightPosition1, invShadowMapSize1, oShadowFactor);
+#endif
+#ifdef DEBUG_PSSM
+ pssm_lod_info.g = 1.0;
+#endif
+ }
+#endif
+#if PSSM_NUM_SPLITS > 3
+ else if (fDepth <= vSplitPoints.z)
+ {
+#ifdef PSSM_SAMPLE_COLOUR
+ oShadowFactor = texture2DProj(shadowMap2, lightPosition2).x;
+#else
+ SGX_ShadowPCF4(shadowMap2, lightPosition2, invShadowMapSize2, oShadowFactor);
+#endif
+#ifdef DEBUG_PSSM
+ pssm_lod_info.r = 1.0;
+ pssm_lod_info.g = 1.0;
+#endif
+ }
+#endif
+ else if (fDepth <= vSplitPoints.w)
+ {
+#ifdef PSSM_SAMPLE_COLOUR
+ oShadowFactor = texture2DProj(shadowMap3, lightPosition3).x;
+#else
+ SGX_ShadowPCF4(shadowMap3, lightPosition3, invShadowMapSize3, oShadowFactor);
+#endif
+#ifdef DEBUG_PSSM
+ pssm_lod_info.b = 1.0;
+#endif
+ }
+ else
+ {
+ // behind far distance
+ oShadowFactor = 1.0;
+ }
+}
diff --git a/Content/OgreInternal/SGXLib_LayeredBlending.glsl b/Content/OgreInternal/SGXLib_LayeredBlending.glsl
new file mode 100644
index 0000000..8af709a
--- /dev/null
+++ b/Content/OgreInternal/SGXLib_LayeredBlending.glsl
@@ -0,0 +1,825 @@
+/*
+** layered blending & misc math
+** Blending modes, RGB/HSL/Contrast/Desaturate, levels control
+**
+** The shaders below are base on the shaders created by:
+** Romain Dura | Romz
+** Blog: http://blog.mouaif.org
+** Post: http://blog.mouaif.org/?p=94
+*/
+
+
+/*
+** Desaturation
+*/
+
+vec4 Desaturate(in vec3 color, in float Desaturation)
+{
+ vec3 grayXfer = vec3(0.3, 0.59, 0.11);
+ float grayf = dot(grayXfer, color);
+ vec3 gray = vec3(grayf, grayf, grayf);
+ return vec4(mix(color, gray, Desaturation), 1.0);
+}
+
+
+/*
+** Hue, saturation, luminance
+*/
+
+vec3 RGBToHSL(in vec3 color)
+{
+ vec3 hsl; // init to 0 to avoid warnings ? (and reverse if + remove first part)
+
+ float fmin = min(min(color.r, color.g), color.b); //Min. value of RGB
+ float fmax = max(max(color.r, color.g), color.b); //Max. value of RGB
+ float delta = fmax - fmin; //Delta RGB value
+
+ hsl.z = (fmax + fmin) / 2.0; // Luminance
+
+ if (delta == 0.0) //This is a gray, no chroma...
+ {
+ hsl.x = 0.0; // Hue
+ hsl.y = 0.0; // Saturation
+ }
+ else //Chromatic data...
+ {
+ if (hsl.z < 0.5)
+ hsl.y = delta / (fmax + fmin); // Saturation
+ else
+ hsl.y = delta / (2.0 - fmax - fmin); // Saturation
+
+ float deltaR = (((fmax - color.r) / 6.0) + (delta / 2.0)) / delta;
+ float deltaG = (((fmax - color.g) / 6.0) + (delta / 2.0)) / delta;
+ float deltaB = (((fmax - color.b) / 6.0) + (delta / 2.0)) / delta;
+
+ if (color.r == fmax )
+ hsl.x = deltaB - deltaG; // Hue
+ else if (color.g == fmax)
+ hsl.x = (1.0 / 3.0) + deltaR - deltaB; // Hue
+ else if (color.b == fmax)
+ hsl.x = (2.0 / 3.0) + deltaG - deltaR; // Hue
+
+ if (hsl.x < 0.0)
+ hsl.x += 1.0; // Hue
+ else if (hsl.x > 1.0)
+ hsl.x -= 1.0; // Hue
+ }
+
+ return hsl;
+}
+
+float HueToRGB(in float f1, in float f2, in float hue)
+{
+ if (hue < 0.0)
+ hue += 1.0;
+ else if (hue > 1.0)
+ hue -= 1.0;
+ float res;
+ if ((6.0 * hue) < 1.0)
+ res = f1 + (f2 - f1) * 6.0 * hue;
+ else if ((2.0 * hue) < 1.0)
+ res = f2;
+ else if ((3.0 * hue) < 2.0)
+ res = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0;
+ else
+ res = f1;
+ return res;
+}
+
+vec3 HSLToRGB(in vec3 hsl)
+{
+ vec3 rgb;
+
+ if (hsl.y == 0.0)
+ rgb = hsl.zzz; // Luminance
+ else
+ {
+ float f2;
+
+ if (hsl.z < 0.5)
+ f2 = hsl.z * (1.0 + hsl.y);
+ else
+ f2 = (hsl.z + hsl.y) - (hsl.y * hsl.z);
+
+ float f1 = 2.0 * hsl.z - f2;
+
+ rgb.r = HueToRGB(f1, f2, hsl.x + (1.0/3.0));
+ rgb.g = HueToRGB(f1, f2, hsl.x);
+ rgb.b = HueToRGB(f1, f2, hsl.x - (1.0/3.0));
+ }
+
+ return rgb;
+}
+
+
+/*
+** Contrast, saturation, brightness
+** Code of this function is from TGM's shader pack
+** http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=21057
+*/
+
+// For all settings: 1.0 = 100% 0.5=50% 1.5 = 150%
+vec3 ContrastSaturationBrightness(in vec3 color, in float brt, in float sat, in float con)
+{
+ // Increase or decrease these values to adjust r, g and b color channels separately
+ const float AvgLumR = 0.5;
+ const float AvgLumG = 0.5;
+ const float AvgLumB = 0.5;
+
+ const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
+
+ vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
+ vec3 brtColor = color * brt;
+ float intensityf = dot(brtColor, LumCoeff);
+ vec3 intensity = vec3(intensityf, intensityf, intensityf);
+ vec3 satColor = mix(intensity, brtColor, sat);
+ vec3 conColor = mix(AvgLumin, satColor, con);
+ return conColor;
+}
+
+/*
+** Float blending modes
+** Adapted from here: http://www.nathanm.com/photoshop-blending-math/
+** But I modified the HardMix (wrong condition), Overlay, SoftLight, ColorDodge, ColorBurn, VividLight, PinLight (inverted layers) ones to have correct results
+*/
+
+#define BlendLinearDodgef BlendAddf
+#define BlendLinearBurnf BlendSubtractf
+#define BlendAddf(base, blend) min(base + blend, 1.0)
+#define BlendSubtractf(base, blend) max(base + blend - 1.0, 0.0)
+#define BlendLightenf(base, blend) max(blend, base)
+#define BlendDarkenf(base, blend) min(blend, base)
+#define BlendScreenf(base, blend) (1.0 - ((1.0 - base) * (1.0 - blend)))
+#define BlendOverlayf(base, blend) (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)))
+#define BlendSoftLightf(base, blend) ((blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend)))
+#define BlendColorDodgef(base, blend) ((blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0))
+#define BlendColorBurnf(base, blend) ((blend == 0.0) ? blend : max((1.0 - ((1.0 - base) / blend)), 0.0))
+#define BlendHardMixf(base, blend) ((BlendVividLightf(base, blend) < 0.5) ? 0.0 : 1.0)
+
+
+
+/*
+** Vector3 blending modes
+*/
+
+// Component wise blending
+#define Blend1(base, blend, funcf) funcf(base, blend)
+#define Blend3(base, blend, funcf) vec3(funcf(base.r, blend.r), funcf(base.g, blend.g), funcf(base.b, blend.b))
+#define Blend4(base, blend, funcf) vec4(funcf(base.r, blend.r), funcf(base.g, blend.g), funcf(base.b, blend.b), funcf(base.a, blend.a))
+
+#define BlendNormal(base, blend) (base)
+#define BlendMultiply(base, blend) (base * blend)
+#define BlendAverage(base, blend) ((base + blend) / 2.0)
+#define BlendAdd(base, blend) min(base + blend, 1.0)
+#define BlendSubtract(base, blend) max(base + blend - 1.0, 0.0)
+#define BlendDifference(base, blend) abs(base - blend)
+#define BlendNegation(base, blend) (1.0 - abs(1.0 - base - blend))
+#define BlendExclusion(base, blend) (base + blend - 2.0 * base * blend)
+#define BlendPhoenix(base, blend) (min(base, blend) - max(base, blend) + 1.0)
+#define BlendOpacity(base, blend, F, O) (F(base, blend) * O + blend * (1.0 - O))
+
+// Hue Blend mode creates the result color by combining the luminance and saturation of the base color with the hue of the blend color.
+float BlendHue1(in float base, in float blend)
+{
+ return base;
+}
+
+vec3 BlendHue3(in vec3 base, in vec3 blend)
+{
+ vec3 baseHSL = RGBToHSL(base);
+ return HSLToRGB(vec3(RGBToHSL(blend).r, baseHSL.g, baseHSL.b));
+}
+
+vec4 BlendHue4(in vec4 base, in vec4 blend)
+{
+ vec3 hue = BlendHue3(base.xyz, blend.xyz);
+ return vec4(hue.x, hue.y, hue.z, BlendHue1(base.w, blend.w));
+}
+
+// Saturation Blend mode creates the result color by combining the luminance and hue of the base color with the saturation of the blend color.
+float BlendSaturation1(in float base, in float blend)
+{
+ return base;
+}
+
+vec3 BlendSaturation3(in vec3 base, in vec3 blend)
+{
+ vec3 baseHSL = RGBToHSL(base);
+ return HSLToRGB(vec3(baseHSL.r, RGBToHSL(blend).g, baseHSL.b));
+}
+
+vec4 BlendSaturation4(in vec4 base, in vec4 blend)
+{
+ vec3 hue = BlendSaturation3(base.xyz, blend.xyz);
+ return vec4(hue.x, hue.y, hue.z, BlendSaturation1(base.w, blend.w));
+}
+
+// Color Mode keeps the brightness of the base color and applies both the hue and saturation of the blend color.
+float BlendColor1(in float base, in float blend)
+{
+ return base;
+}
+
+vec3 BlendColor3(in vec3 base, in vec3 blend)
+{
+ vec3 blendHSL = RGBToHSL(blend);
+ return HSLToRGB(vec3(blendHSL.r, blendHSL.g, RGBToHSL(base).b));
+}
+
+vec4 BlendColor4(in vec4 base, in vec4 blend)
+{
+ vec3 hue = BlendColor3(base.xyz, blend.xyz);
+ return vec4(hue.x, hue.y, hue.z, BlendColor1(base.w, blend.w));
+}
+
+
+// Luminosity Blend mode creates the result color by combining the hue and saturation of the base color with the luminance of the blend color.
+float BlendLuminosity1(in float base, in float blend)
+{
+ return base;
+}
+
+vec3 BlendLuminosity3(in vec3 base, in vec3 blend)
+{
+ vec3 baseHSL = RGBToHSL(base);
+ return HSLToRGB(vec3(baseHSL.r, baseHSL.g, RGBToHSL(blend).b));
+}
+
+vec4 BlendLuminosity4(in vec4 base, in vec4 blend)
+{
+ vec3 hue = BlendLuminosity3(base.xyz, blend.xyz);
+ return vec4(hue.x, hue.y, hue.z, BlendLuminosity1(base.w, blend.w));
+}
+
+float BlendLinearLightf(in float s1, in float s2)
+{
+ float oColor;
+
+ if (s2 < 0.5)
+ {
+ float s2x = (2.0 * s2);
+ oColor = BlendSubtractf(s1, s2x);
+ }
+ else
+ {
+ float s2x = (2.0 * (s2 - 0.5));
+ oColor = BlendAddf(s1, s2x);
+ }
+
+ return oColor;
+}
+
+float BlendVividLightf(in float s1, in float s2)
+{
+ float oColor;
+
+ if (s2 < 0.5)
+ {
+ float s2x = (2.0 * s2);
+ oColor = BlendColorBurnf(s1, s2x);
+ }
+ else
+ {
+ float s2x = (2.0 * (s2 - 0.5));
+ oColor = BlendColorDodgef(s1, s2x);
+ }
+
+ return oColor;
+}
+
+float BlendPinLightf(in float s1, in float s2)
+{
+ float oColor;
+
+ if (s2 < 0.5)
+ {
+ float s2x = (2.0 * s2);
+ oColor = BlendDarkenf(s1, s2x);
+ }
+ else
+ {
+ float s2x = (2.0 * (s2 - 0.5));
+ oColor = BlendLightenf(s1, s2x);
+ }
+
+ return oColor;
+}
+
+float BlendReflectf(in float s1, in float s2)
+{
+ float oColor;
+
+ if (s2 == 1.0)
+ {
+ oColor = s2;
+ }
+ else
+ {
+ float s1x = (s1 * s1) / (1.0 - s2);
+
+ oColor = min(s1x, 1.0);
+ }
+
+ return oColor;
+}
+
+//------------------------------------
+// Interface for RTShader
+//------------------------------------
+
+
+void SGX_blend_normal(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendNormal(basePixel, blendPixel);
+}
+
+void SGX_blend_normal(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendNormal(basePixel, blendPixel);
+}
+
+void SGX_blend_normal(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendNormal(basePixel, blendPixel);
+}
+
+
+void SGX_blend_lighten(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendLightenf(basePixel, blendPixel);
+}
+
+void SGX_blend_lighten(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendLightenf(basePixel, blendPixel);
+}
+
+void SGX_blend_lighten(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendLightenf(basePixel, blendPixel);
+}
+
+
+void SGX_blend_darken(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendDarkenf(basePixel, blendPixel);
+}
+
+void SGX_blend_darken(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendDarkenf(basePixel, blendPixel);
+}
+
+void SGX_blend_darken(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendDarkenf(basePixel, blendPixel);
+}
+
+
+void SGX_blend_multiply(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendMultiply(basePixel, blendPixel);
+}
+
+void SGX_blend_multiply(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendMultiply(basePixel, blendPixel);
+}
+
+void SGX_blend_multiply(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendMultiply(basePixel, blendPixel);
+}
+
+
+void SGX_blend_average(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendAverage(basePixel, blendPixel);
+}
+
+void SGX_blend_average(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendAverage(basePixel, blendPixel);
+}
+
+void SGX_blend_average(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendAverage(basePixel, blendPixel);
+}
+
+
+void SGX_blend_add(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendAdd(basePixel, blendPixel);
+}
+
+void SGX_blend_add(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendAdd(basePixel, blendPixel);
+}
+
+void SGX_blend_add(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendAdd(basePixel, blendPixel);
+}
+
+
+void SGX_blend_subtract(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendSubtract(basePixel, blendPixel);
+}
+
+void SGX_blend_subtract(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendSubtract(basePixel, blendPixel);
+}
+
+void SGX_blend_subtract(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendSubtract(basePixel, blendPixel);
+}
+
+
+void SGX_blend_difference(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendDifference(basePixel, blendPixel);
+}
+void SGX_blend_difference(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendDifference(basePixel, blendPixel);
+}
+void SGX_blend_difference(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendDifference(basePixel, blendPixel);
+}
+
+
+void SGX_blend_negation(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendNegation(basePixel, blendPixel);
+}
+void SGX_blend_negation(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendNegation(basePixel, blendPixel);
+}
+void SGX_blend_negation(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendNegation(basePixel, blendPixel);
+}
+
+
+void SGX_blend_exclusion(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendExclusion(basePixel, blendPixel);
+}
+void SGX_blend_exclusion(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendExclusion(basePixel, blendPixel);
+}
+void SGX_blend_exclusion(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendExclusion(basePixel, blendPixel);
+}
+
+
+void SGX_blend_screen(in vec4 s1, in vec4 s2, out vec4 oColor)
+{
+ oColor = vec4(BlendScreenf(s1.r, s2.r),
+ BlendScreenf(s1.g, s2.g),
+ BlendScreenf(s1.b, s2.b),
+ BlendScreenf(s1.a, s2.a));
+}
+void SGX_blend_screen(in vec3 s1, in vec3 s2, out vec3 oColor)
+{
+ oColor = vec3(BlendScreenf(s1.r, s2.r),
+ BlendScreenf(s1.g, s2.g),
+ BlendScreenf(s1.b, s2.b));
+}
+void SGX_blend_screen(in float s1, in float s2, out float oColor)
+{
+ oColor = BlendScreenf(s1, s2);
+}
+
+
+void SGX_blend_overlay(in vec4 s1, in vec4 s2, out vec4 oColor)
+{
+ oColor = vec4(BlendOverlayf(s1.r, s2.r),
+ BlendOverlayf(s1.g, s2.g),
+ BlendOverlayf(s1.b, s2.b),
+ BlendOverlayf(s1.a, s2.a));
+}
+void SGX_blend_overlay(in vec3 s1, in vec3 s2, out vec3 oColor)
+{
+ oColor = vec3(BlendOverlayf(s1.r, s2.r),
+ BlendOverlayf(s1.g, s2.g),
+ BlendOverlayf(s1.b, s2.b));
+}
+void SGX_blend_overlay(in float s1, in float s2, out float oColor)
+{
+ oColor = BlendOverlayf(s1, s2);
+}
+
+
+void SGX_blend_softLight(in vec4 s1, in vec4 s2, out vec4 oColor)
+{
+ oColor = vec4(BlendSoftLightf(s1.r, s2.r),
+ BlendSoftLightf(s1.g, s2.g),
+ BlendSoftLightf(s1.b, s2.b),
+ BlendSoftLightf(s1.a, s2.a));
+}
+void SGX_blend_softLight(in vec3 s1, in vec3 s2, out vec3 oColor)
+{
+ oColor = vec3(BlendSoftLightf(s1.r, s2.r),
+ BlendSoftLightf(s1.g, s2.g),
+ BlendSoftLightf(s1.b, s2.b));
+}
+void SGX_blend_softLight(in float s1, in float s2, out float oColor)
+{
+ oColor = BlendSoftLightf(s1, s2);
+}
+
+
+void SGX_blend_hardLight(in vec4 s1, in vec4 s2, out vec4 oColor)
+{
+ oColor = vec4(BlendOverlayf(s1.r, s2.r),
+ BlendOverlayf(s1.g, s2.g),
+ BlendOverlayf(s1.b, s2.b),
+ BlendOverlayf(s1.a, s2.a));
+}
+void SGX_blend_hardLight(in vec3 s1, in vec3 s2, out vec3 oColor)
+{
+ oColor = vec3(BlendOverlayf(s1.r, s2.r),
+ BlendOverlayf(s1.g, s2.g),
+ BlendOverlayf(s1.b, s2.b));
+}
+void SGX_blend_hardLight(in float s1, in float s2, out float oColor)
+{
+ oColor = BlendOverlayf(s1, s2);
+}
+
+
+void SGX_blend_colorDodge(in vec4 s1, in vec4 s2, out vec4 oColor)
+{
+ oColor = vec4(BlendColorDodgef(s1.r, s2.r),
+ BlendColorDodgef(s1.g, s2.g),
+ BlendColorDodgef(s1.b, s2.b),
+ BlendColorDodgef(s1.a, s2.a));
+}
+void SGX_blend_colorDodge(in vec3 s1, in vec3 s2, out vec3 oColor)
+{
+ oColor = vec3(BlendColorDodgef(s1.r, s2.r),
+ BlendColorDodgef(s1.g, s2.g),
+ BlendColorDodgef(s1.b, s2.b));
+}
+void SGX_blend_colorDodge(in float s1, in float s2, out float oColor)
+{
+ oColor = BlendColorDodgef(s1, s2);
+}
+
+
+void SGX_blend_colorBurn(in vec4 s1, in vec4 s2, out vec4 oColor)
+{
+ oColor = vec4(BlendColorBurnf(s1.r, s2.r),
+ BlendColorBurnf(s1.g, s2.g),
+ BlendColorBurnf(s1.b, s2.b),
+ BlendColorBurnf(s1.a, s2.a));
+}
+void SGX_blend_colorBurn(in vec3 s1, in vec3 s2, out vec3 oColor)
+{
+ oColor = vec3(BlendColorBurnf(s1.r, s2.r),
+ BlendColorBurnf(s1.g, s2.g),
+ BlendColorBurnf(s1.b, s2.b));
+}
+void SGX_blend_colorBurn(in float s1, in float s2, out float oColor)
+{
+ oColor = BlendColorBurnf(s1, s2);
+}
+
+
+void SGX_blend_linearDodge(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendAddf(basePixel, blendPixel);
+}
+void SGX_blend_linearDodge(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendAddf(basePixel, blendPixel);
+}
+void SGX_blend_linearDodge(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendAddf(basePixel, blendPixel);
+}
+
+
+void SGX_blend_linearBurn(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendSubtractf(basePixel, blendPixel);
+}
+void SGX_blend_linearBurn(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendSubtractf(basePixel, blendPixel);
+}
+void SGX_blend_linearBurn(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendSubtractf(basePixel, blendPixel);
+}
+
+
+void SGX_blend_linearLight(in vec4 s1, in vec4 s2, out vec4 oColor)
+{
+ oColor = vec4(BlendLinearLightf(s1.r, s2.r),
+ BlendLinearLightf(s1.g, s2.g),
+ BlendLinearLightf(s1.b, s2.b),
+ BlendLinearLightf(s1.a, s2.a));
+}
+void SGX_blend_linearLight(in vec3 s1, in vec3 s2, out vec3 oColor)
+{
+ oColor = vec3(BlendLinearLightf(s1.r, s2.r),
+ BlendLinearLightf(s1.g, s2.g),
+ BlendLinearLightf(s1.b, s2.b));
+}
+void SGX_blend_linearLight(in float s1, in float s2, out float oColor)
+{
+ oColor = BlendLinearLightf(s1, s2);
+}
+
+
+void SGX_blend_vividLight(in vec4 s1, in vec4 s2, out vec4 oColor)
+{
+ oColor = vec4(BlendVividLightf(s1.r, s2.r),
+ BlendVividLightf(s1.g, s2.g),
+ BlendVividLightf(s1.b, s2.b),
+ BlendVividLightf(s1.a, s2.a));
+}
+void SGX_blend_vividLight(in vec3 s1, in vec3 s2, out vec3 oColor)
+{
+ oColor = vec3(BlendVividLightf(s1.r, s2.r),
+ BlendVividLightf(s1.g, s2.g),
+ BlendVividLightf(s1.b, s2.b));
+}
+void SGX_blend_vividLight(in float s1, in float s2, out float oColor)
+{
+ oColor = BlendVividLightf(s1, s2);
+}
+
+
+void SGX_blend_pinLight(in vec4 s1, in vec4 s2, out vec4 oColor)
+{
+ oColor = vec4(BlendPinLightf(s1.r, s2.r),
+ BlendPinLightf(s1.g, s2.g),
+ BlendPinLightf(s1.b, s2.b),
+ BlendPinLightf(s1.a, s2.a));
+}
+void SGX_blend_pinLight(in vec3 s1, in vec3 s2, out vec3 oColor)
+{
+ oColor = vec3(BlendPinLightf(s1.r, s2.r),
+ BlendPinLightf(s1.g, s2.g),
+ BlendPinLightf(s1.b, s2.b));
+}
+void SGX_blend_pinLight(in float s1, in float s2, out float oColor)
+{
+ oColor = BlendPinLightf(s1, s2);
+}
+
+
+void SGX_blend_hardMix(in vec4 s1, in vec4 s2, out vec4 oColor)
+{
+ oColor = vec4(BlendHardMixf(s1.r, s2.r),
+ BlendHardMixf(s1.g, s2.g),
+ BlendHardMixf(s1.b, s2.b),
+ BlendHardMixf(s1.a, s2.a));
+}
+void SGX_blend_hardMix(in vec3 s1, in vec3 s2, out vec3 oColor)
+{
+ oColor = vec3(BlendHardMixf(s1.r, s2.r),
+ BlendHardMixf(s1.g, s2.g),
+ BlendHardMixf(s1.b, s2.b));
+}
+void SGX_blend_hardMix(in float s1, in float s2, out float oColor)
+{
+ oColor = BlendHardMixf(s1, s2);
+}
+
+void SGX_blend_reflect(in vec4 s1, in vec4 s2, out vec4 oColor)
+{
+ oColor = vec4(BlendReflectf(s1.r, s2.r),
+ BlendReflectf(s1.g, s2.g),
+ BlendReflectf(s1.b, s2.b),
+ BlendReflectf(s1.a, s2.a));
+}
+void SGX_blend_reflect(in vec3 s1, in vec3 s2, out vec3 oColor)
+{
+ oColor = vec3(BlendReflectf(s1.r, s2.r),
+ BlendReflectf(s1.g, s2.g),
+ BlendReflectf(s1.b, s2.b));
+}
+void SGX_blend_reflect(in float s1, in float s2, out float oColor)
+{
+ oColor = BlendReflectf(s1, s2);
+}
+
+
+void SGX_blend_glow(in vec4 s1, in vec4 s2, out vec4 oColor)
+{
+ oColor = vec4(BlendReflectf(s1.r, s2.r),
+ BlendReflectf(s1.g, s2.g),
+ BlendReflectf(s1.b, s2.b),
+ BlendReflectf(s1.a, s2.a));
+}
+void SGX_blend_glow(in vec3 s1, in vec3 s2, out vec3 oColor)
+{
+ oColor = vec3(BlendReflectf(s1.r, s2.r),
+ BlendReflectf(s1.g, s2.g),
+ BlendReflectf(s1.b, s2.b));
+}
+void SGX_blend_glow(in float s1, in float s2, out float oColor)
+{
+ oColor = BlendReflectf(s1, s2);
+}
+
+
+void SGX_blend_phoenix(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendPhoenix(basePixel, blendPixel);
+}
+void SGX_blend_phoenix(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendPhoenix(basePixel, blendPixel);
+}
+void SGX_blend_phoenix(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendPhoenix(basePixel, blendPixel);
+}
+
+
+void SGX_blend_saturation(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendSaturation4(basePixel, blendPixel);
+}
+void SGX_blend_saturation(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendSaturation3(basePixel, blendPixel);
+}
+void SGX_blend_saturation(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendSaturation1(basePixel, blendPixel);
+}
+
+
+void SGX_blend_color(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendColor4(basePixel, blendPixel);
+}
+void SGX_blend_color(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendColor3(basePixel, blendPixel);
+}
+void SGX_blend_color(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendColor1(basePixel, blendPixel);
+}
+
+
+void SGX_blend_luminosity(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor)
+{
+ oColor = BlendLuminosity4(basePixel, blendPixel);
+}
+void SGX_blend_luminosity(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor)
+{
+ oColor = BlendLuminosity3(basePixel, blendPixel);
+}
+void SGX_blend_luminosity(in float basePixel, in float blendPixel, out float oColor)
+{
+ oColor = BlendLuminosity1(basePixel, blendPixel);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+/// Source modification functions
+////////////////////////////////////////////////////////////////////////////////////
+
+
+void SGX_src_mod_modulate(in vec4 iColor, in vec4 controlVal, out vec4 oColor)
+{
+ oColor = iColor * controlVal;
+}
+void SGX_src_mod_modulate(in vec3 iColor, in vec3 controlVal, out vec3 oColor)
+{
+ oColor = iColor * controlVal;
+}
+void SGX_src_mod_modulate(in float iColor, in float controlVal, out float oColor)
+{
+ oColor = iColor * controlVal;
+}
+
+void SGX_src_mod_inv_modulate(in vec4 iColor, in vec4 controlVal, out vec4 oColor)
+{
+ oColor = mix(iColor, vec4(1.0,1.0,1.0,1.0), controlVal);
+}
+void SGX_src_mod_inv_modulate(in vec3 iColor, in vec3 controlVal, out vec3 oColor)
+{
+ oColor = mix(iColor, vec3(1.0,1.0,1.0), controlVal);
+}
+void SGX_src_mod_inv_modulate(in float iColor, in float controlVal, out float oColor)
+{
+ oColor = mix(iColor, 1.0, controlVal);
+}
diff --git a/Content/OgreInternal/SGXLib_NormalMap.glsl b/Content/OgreInternal/SGXLib_NormalMap.glsl
new file mode 100644
index 0000000..9863d2e
--- /dev/null
+++ b/Content/OgreInternal/SGXLib_NormalMap.glsl
@@ -0,0 +1,68 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+(Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org
+
+Copyright (c) 2000-2014 Torus Knot Software Ltd
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+-----------------------------------------------------------------------------
+*/
+
+//-----------------------------------------------------------------------------
+// Program Name: SGXLib_NormalMapLighting
+// Program Desc: Normal map lighting functions.
+// Program Type: Vertex/Pixel shader
+// Language: GLSL
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+void SGX_FetchNormal(in sampler2D s,
+ in vec2 uv,
+ out vec3 vOut)
+{
+ vOut = 2.0 * texture2D(s, uv).xyz - 1.0;
+}
+
+//-----------------------------------------------------------------------------
+void SGX_TransformNormal(in vec3 vNormal,
+ in vec4 vTangent,
+ inout vec3 vNormalTS)
+{
+ // use non-normalised post-interpolation values as in mikktspace
+ // resulting normal will be normalised by lighting
+ vec3 vBinormal = cross(vNormal, vTangent.xyz) * sign(vTangent.w);
+ // direction: from tangent space to world
+ mat3 TBN = mtxFromCols(vTangent.xyz, vBinormal, vNormal);
+ vNormalTS = mul(TBN, vNormalTS);
+}
+
+//-----------------------------------------------------------------------------
+void SGX_Generate_Parallax_Texcoord(in sampler2D normalHeightMap,
+ in vec2 texCoord,
+ in vec3 viewPos,
+ in vec2 scaleBias,
+ out vec2 newTexCoord)
+{
+ vec3 eyeVec = -normalize(viewPos);
+ float height = texture2D(normalHeightMap, texCoord).a;
+ float displacement = (height * scaleBias.x) + scaleBias.y;
+ vec2 scaledEyeDir = eyeVec.xy * displacement;
+ newTexCoord = scaledEyeDir + texCoord;
+}
\ No newline at end of file
diff --git a/Content/OgreInternal/SGXLib_PerPixelLighting.glsl b/Content/OgreInternal/SGXLib_PerPixelLighting.glsl
new file mode 100644
index 0000000..ab85048
--- /dev/null
+++ b/Content/OgreInternal/SGXLib_PerPixelLighting.glsl
@@ -0,0 +1,236 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+(Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org
+
+Copyright (c) 2000-2014 Torus Knot Software Ltd
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+-----------------------------------------------------------------------------
+*/
+
+//-----------------------------------------------------------------------------
+// Program Name: SGXLib_Lighting
+// Program Desc: Per pixel lighting functions.
+// Program Type: Vertex/Pixel shader
+// Language: GLSL
+// Notes: Implements core functions for FFPLighting class.
+// based on lighting engine.
+// See http://msdn.microsoft.com/en-us/library/bb147178.aspx
+//-----------------------------------------------------------------------------
+
+#define M_PI 3.141592654
+
+#ifdef OGRE_HLSL
+void SGX_Flip_Backface_Normal(in float triArea, in float targetFlipped, inout vec3 normal)
+{
+#if OGRE_HLSL == 3
+ triArea *= -1.0;
+#endif
+ triArea *= targetFlipped;
+ if(triArea < 0.0)
+ normal *= -1.0;
+}
+#else
+void SGX_Flip_Backface_Normal(in bool frontFacing, in float targetFlipped, inout vec3 normal)
+{
+#ifdef VULKAN
+ targetFlipped *= -1.0;
+#endif
+ if(targetFlipped < 0.0)
+ frontFacing = !frontFacing;
+ if(!frontFacing)
+ normal *= -1.0;
+}
+#endif
+
+//-----------------------------------------------------------------------------
+void SGX_Light_Directional_Diffuse(
+ in vec3 vNormal,
+ in vec3 vLightDirView,
+ in vec3 vDiffuseColour,
+ inout vec3 vOut)
+{
+ vec3 vNormalView = normalize(vNormal);
+ float nDotL = dot(vNormalView, -vLightDirView);
+
+ vOut += vDiffuseColour * clamp(nDotL, 0.0, 1.0);
+ vOut = clamp(vOut, 0.0, 1.0);
+}
+
+//-----------------------------------------------------------------------------
+void SGX_Light_Directional_DiffuseSpecular(
+ in vec3 vNormal,
+ in vec3 vViewPos,
+ in vec3 vLightDirView,
+ in vec3 vDiffuseColour,
+ in vec3 vSpecularColour,
+ in float fSpecularPower,
+ inout vec3 vOutDiffuse,
+ inout vec3 vOutSpecular)
+{
+ vec3 vNormalView = normalize(vNormal);
+ float nDotL = dot(vNormalView, -vLightDirView);
+ vec3 vView = -normalize(vViewPos);
+ vec3 vHalfWay = normalize(vView + -vLightDirView);
+ float nDotH = dot(vNormalView, vHalfWay);
+
+ if (nDotL > 0.0)
+ {
+ vOutDiffuse += vDiffuseColour * nDotL;
+#ifdef NORMALISED
+ vSpecularColour *= (fSpecularPower + 8.0)/(8.0 * M_PI);
+#endif
+ vOutSpecular += vSpecularColour * pow(clamp(nDotH, 0.0, 1.0), fSpecularPower);
+ vOutDiffuse = clamp(vOutDiffuse, 0.0, 1.0);
+ vOutSpecular = clamp(vOutSpecular, 0.0, 1.0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SGX_Light_Point_Diffuse(
+ in vec3 vNormal,
+ in vec3 vViewPos,
+ in vec3 vLightPos,
+ in vec4 vAttParams,
+ in vec3 vDiffuseColour,
+ inout vec3 vOut)
+{
+ vec3 vLightView = vLightPos - vViewPos;
+ float fLightD = length(vLightView);
+ vec3 vNormalView = normalize(vNormal);
+ float nDotL = dot(vNormalView, normalize(vLightView));
+
+ if (nDotL > 0.0 && fLightD <= vAttParams.x)
+ {
+ float fAtten = 1.0 / (vAttParams.y + vAttParams.z*fLightD + vAttParams.w*fLightD*fLightD);
+
+ vOut += vDiffuseColour * nDotL * fAtten;
+ vOut = clamp(vOut, 0.0, 1.0);
+ }
+}
+
+
+
+//-----------------------------------------------------------------------------
+void SGX_Light_Point_DiffuseSpecular(
+ in vec3 vNormal,
+ in vec3 vViewPos,
+ in vec3 vLightPos,
+ in vec4 vAttParams,
+ in vec3 vDiffuseColour,
+ in vec3 vSpecularColour,
+ in float fSpecularPower,
+ inout vec3 vOutDiffuse,
+ inout vec3 vOutSpecular)
+{
+ vec3 vLightView = vLightPos - vViewPos;
+ float fLightD = length(vLightView);
+ vLightView = normalize(vLightView);
+ vec3 vNormalView = normalize(vNormal);
+ float nDotL = dot(vNormalView, vLightView);
+
+ if (nDotL > 0.0 && fLightD <= vAttParams.x)
+ {
+ vec3 vView = -normalize(vViewPos);
+ vec3 vHalfWay = normalize(vView + vLightView);
+ float nDotH = dot(vNormalView, vHalfWay);
+ float fAtten = 1.0 / (vAttParams.y + vAttParams.z*fLightD + vAttParams.w*fLightD*fLightD);
+
+ vOutDiffuse += vDiffuseColour * nDotL * fAtten;
+#ifdef NORMALISED
+ vSpecularColour *= (fSpecularPower + 8.0)/(8.0 * M_PI);
+#endif
+ vOutSpecular += vSpecularColour * pow(clamp(nDotH, 0.0, 1.0), fSpecularPower) * fAtten;
+
+ vOutDiffuse = clamp(vOutDiffuse, 0.0, 1.0);
+ vOutSpecular = clamp(vOutSpecular, 0.0, 1.0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SGX_Light_Spot_Diffuse(
+ in vec3 vNormal,
+ in vec3 vViewPos,
+ in vec3 vLightPos,
+ in vec3 vLightDirView,
+ in vec4 vAttParams,
+ in vec3 vSpotParams,
+ in vec3 vDiffuseColour,
+ inout vec3 vOut)
+{
+ vec3 vLightView = vLightPos - vViewPos;
+ float fLightD = length(vLightView);
+ vLightView = normalize(vLightView);
+ vec3 vNormalView = normalize(vNormal);
+ float nDotL = dot(vNormalView, vLightView);
+
+ if (nDotL > 0.0 && fLightD <= vAttParams.x)
+ {
+ float fAtten = 1.0 / (vAttParams.y + vAttParams.z*fLightD + vAttParams.w*fLightD*fLightD);
+ float rho = dot(-vLightDirView, vLightView);
+ float fSpotE = clamp((rho - vSpotParams.y) / (vSpotParams.x - vSpotParams.y), 0.0, 1.0);
+ float fSpotT = pow(fSpotE, vSpotParams.z);
+
+ vOut += vDiffuseColour * nDotL * fAtten * fSpotT;
+ vOut = clamp(vOut, 0.0, 1.0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SGX_Light_Spot_DiffuseSpecular(
+ in vec3 vNormal,
+ in vec3 vViewPos,
+ in vec3 vLightPos,
+ in vec3 vLightDirView,
+ in vec4 vAttParams,
+ in vec3 vSpotParams,
+ in vec3 vDiffuseColour,
+ in vec3 vSpecularColour,
+ in float fSpecularPower,
+ inout vec3 vOutDiffuse,
+ inout vec3 vOutSpecular)
+{
+ vec3 vLightView = vLightPos - vViewPos;
+ float fLightD = length(vLightView);
+ vLightView = normalize(vLightView);
+ vec3 vNormalView = normalize(vNormal);
+ float nDotL = dot(vNormalView, vLightView);
+
+
+ if (nDotL > 0.0 && fLightD <= vAttParams.x)
+ {
+ vec3 vView = -normalize(vViewPos);
+ vec3 vHalfWay = normalize(vView + vLightView);
+ float nDotH = dot(vNormalView, vHalfWay);
+ float fAtten = 1.0 / (vAttParams.y + vAttParams.z*fLightD + vAttParams.w*fLightD*fLightD);
+ float rho = dot(-vLightDirView, vLightView);
+ float fSpotE = clamp((rho - vSpotParams.y) / (vSpotParams.x - vSpotParams.y), 0.0, 1.0);
+ float fSpotT = pow(fSpotE, vSpotParams.z);
+
+ vOutDiffuse += vDiffuseColour * nDotL * fAtten * fSpotT;
+#ifdef NORMALISED
+ vSpecularColour *= (fSpecularPower + 8.0)/(8.0 * M_PI);
+#endif
+ vOutSpecular += vSpecularColour * pow(clamp(nDotH, 0.0, 1.0), fSpecularPower) * fAtten * fSpotT;
+ vOutDiffuse = clamp(vOutDiffuse, 0.0, 1.0);
+ vOutSpecular = clamp(vOutSpecular, 0.0, 1.0);
+ }
+}
+
diff --git a/Content/OgreInternal/SGXLib_TriplanarTexturing.glsl b/Content/OgreInternal/SGXLib_TriplanarTexturing.glsl
new file mode 100644
index 0000000..179c4d7
--- /dev/null
+++ b/Content/OgreInternal/SGXLib_TriplanarTexturing.glsl
@@ -0,0 +1,47 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+(Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org
+
+Copyright (c) 2000-2014 Torus Knot Software Ltd
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+-----------------------------------------------------------------------------
+*/
+
+void SGX_TriplanarTexturing(in vec4 diffuse, in vec3 normal, in vec4 position, in sampler2D texFromX, in sampler2D texFromY, in sampler2D texFromZ, in vec3 parameters, out vec4 cOut)
+{
+ vec3 blendWeights = abs(normalize(normal));
+ blendWeights = blendWeights - parameters.y;
+ blendWeights = pow(max(blendWeights, vec3(0.0, 0.0, 0.0)), parameters.zzz);
+ float tot = (blendWeights.x + blendWeights.y + blendWeights.z);
+ blendWeights /= vec3(tot, tot, tot);
+ // Move the planar mapping a bit according to the normal length to avoid bad looking skirts.
+ float nLength = length(normal - 1.0);
+ vec2 coord1 = (position.yz + nLength) * parameters.x;
+ vec2 coord2 = (position.zx + nLength) * parameters.x;
+ vec2 coord3 = (position.xy + nLength) * parameters.x;
+
+ vec4 col1 = texture2D(texFromX, coord1);
+ vec4 col2 = texture2D(texFromY, coord2);
+ vec4 col3 = texture2D(texFromZ, coord3);
+ cOut = diffuse * vec4(col1.xyz * blendWeights.x +
+ col2.xyz * blendWeights.y +
+ col3.xyz * blendWeights.z, 1);
+}
diff --git a/Content/OgreInternal/SGXLib_WBOIT.glsl b/Content/OgreInternal/SGXLib_WBOIT.glsl
new file mode 100644
index 0000000..961cc3d
--- /dev/null
+++ b/Content/OgreInternal/SGXLib_WBOIT.glsl
@@ -0,0 +1,19 @@
+// This file is part of the OGRE project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at https://www.ogre3d.org/licensing.
+// SPDX-License-Identifier: MIT
+
+float weight(float z, float a)
+{
+ // from https://casual-effects.blogspot.com/2015/03/implemented-weighted-blended-order.html
+ return clamp(pow(min(1.0, a * 10.0) + 0.01, 3.0) * 1e8 * pow(1.0 - z * 0.9, 3.0), 1e-2, 3e3);
+}
+
+void SGX_WBOIT(float depth, inout vec4 accum, out vec4 revealage)
+{
+ vec4 colour = accum;
+ // Weighted Blended Order-Independent Transparency, Listing 4
+ float w = weight(depth, colour.a);
+ accum = vec4(colour.rgb * w * colour.a, colour.a);
+ revealage = vec4_splat(colour.a * w);
+}
\ No newline at end of file
diff --git a/Content/OgreInternal/dfgLUTmultiscatter.dds b/Content/OgreInternal/dfgLUTmultiscatter.dds
new file mode 100644
index 0000000..51e397b
Binary files /dev/null and b/Content/OgreInternal/dfgLUTmultiscatter.dds differ
diff --git a/Content/fonts/Cube.mesh b/Content/fonts/Cube.mesh
new file mode 100644
index 0000000..7ca09ae
Binary files /dev/null and b/Content/fonts/Cube.mesh differ
diff --git a/Content/fonts/Material.material b/Content/fonts/Material.material
new file mode 100644
index 0000000..5a4c9c8
--- /dev/null
+++ b/Content/fonts/Material.material
@@ -0,0 +1,11 @@
+// generated by blender2ogre 0.8.3 on 2023-07-10 17:26:00
+material Material {
+ receive_shadows on
+ technique {
+ pass {
+ diffuse 0.8 0.8 0.8 1.0
+ specular 0.512 0.512 0.512 1.0 64.0
+
+ }
+ }
+}
diff --git a/Content/fonts/OgreXMLConverter.log b/Content/fonts/OgreXMLConverter.log
new file mode 100644
index 0000000..07d3641
--- /dev/null
+++ b/Content/fonts/OgreXMLConverter.log
@@ -0,0 +1,21 @@
+17:26:00: XMLMeshSerializer reading mesh data from /home/caesium/projects/rbxnu/Content/fonts/Cube.mesh.xml...
+17:26:00: Reading geometry...
+17:26:00: Geometry done...
+17:26:00: Reading submeshes...
+17:26:00: Submeshes done.
+17:26:00: Reading mesh names...
+17:26:00: Mesh names done.
+17:26:00: XMLMeshSerializer import successful.
+17:26:00: MeshSerializer writing mesh data to stream /home/caesium/projects/rbxnu/Content/fonts/Cube.mesh...
+17:26:00: File header written.
+17:26:00: Writing mesh data...
+17:26:00: Writing submesh...
+17:26:00: Exporting submesh texture aliases...
+17:26:00: Submesh texture aliases exported.
+17:26:00: Submesh exported.
+17:26:00: Exporting bounds information....
+17:26:00: Bounds information exported.
+17:26:00: Exporting submesh name table...
+17:26:00: Submesh name table exported.
+17:26:00: Mesh data exported.
+17:26:00: MeshSerializer export successful.
diff --git a/Content/fonts/part_mesh.mtl b/Content/fonts/part_mesh.mtl
new file mode 100644
index 0000000..2c63179
--- /dev/null
+++ b/Content/fonts/part_mesh.mtl
@@ -0,0 +1,12 @@
+# Blender 3.5.1 MTL File: 'None'
+# www.blender.org
+
+newmtl Material
+Ns 250.000000
+Ka 1.000000 1.000000 1.000000
+Kd 0.800000 0.800000 0.800000
+Ks 0.500000 0.500000 0.500000
+Ke 0.000000 0.000000 0.000000
+Ni 1.450000
+d 1.000000
+illum 2
diff --git a/Content/fonts/part_mesh.obj b/Content/fonts/part_mesh.obj
new file mode 100644
index 0000000..7ef1677
--- /dev/null
+++ b/Content/fonts/part_mesh.obj
@@ -0,0 +1,40 @@
+# Blender 3.5.1
+# www.blender.org
+mtllib part_mesh.mtl
+o FormFactor_Brick
+v 1.000000 1.000000 -1.000000
+v 1.000000 -1.000000 -1.000000
+v 1.000000 1.000000 1.000000
+v 1.000000 -1.000000 1.000000
+v -1.000000 1.000000 -1.000000
+v -1.000000 -1.000000 -1.000000
+v -1.000000 1.000000 1.000000
+v -1.000000 -1.000000 1.000000
+vn -0.0000 1.0000 -0.0000
+vn -0.0000 -0.0000 1.0000
+vn -1.0000 -0.0000 -0.0000
+vn -0.0000 -1.0000 -0.0000
+vn 1.0000 -0.0000 -0.0000
+vn -0.0000 -0.0000 -1.0000
+vt 0.625000 0.500000
+vt 0.375000 0.500000
+vt 0.625000 0.750000
+vt 0.375000 0.750000
+vt 0.875000 0.500000
+vt 0.625000 0.250000
+vt 0.125000 0.500000
+vt 0.375000 0.250000
+vt 0.875000 0.750000
+vt 0.625000 1.000000
+vt 0.625000 0.000000
+vt 0.375000 1.000000
+vt 0.375000 0.000000
+vt 0.125000 0.750000
+s 0
+usemtl Material
+f 1/1/1 5/5/1 7/9/1 3/3/1
+f 4/4/2 3/3/2 7/10/2 8/12/2
+f 8/13/3 7/11/3 5/6/3 6/8/3
+f 6/7/4 2/2/4 4/4/4 8/14/4
+f 2/2/5 1/1/5 3/3/5 4/4/5
+f 6/8/6 5/6/6 1/1/6 2/2/6
diff --git a/Content/fonts/part_mesh.scene b/Content/fonts/part_mesh.scene
new file mode 100644
index 0000000..62b1ab7
--- /dev/null
+++ b/Content/fonts/part_mesh.scene
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Projects/Client/Common/CMakeLists.txt b/Projects/Client/Common/CMakeLists.txt
index 00de331..b6cea5a 100644
--- a/Projects/Client/Common/CMakeLists.txt
+++ b/Projects/Client/Common/CMakeLists.txt
@@ -12,11 +12,13 @@ qt_add_library(Common STATIC
Source/OgreWidget.cpp
)
-add_custom_command(TARGET Common POST_BUILD
- COMMAND ${TOOL_WINDEPLOYQT}
- $
- COMMENT "Running windeployqt..."
-)
+if(WIN32)
+ add_custom_command(TARGET Common POST_BUILD
+ COMMAND ${TOOL_WINDEPLOYQT}
+ $
+ COMMENT "Running windeployqt..."
+ )
+endif()
target_include_directories(Common PUBLIC Header)
target_link_libraries(Common PUBLIC ${QT6_LIBRARIES_INCL} Engine)
\ No newline at end of file
diff --git a/Projects/Client/Common/Header/OgreWidget.hpp b/Projects/Client/Common/Header/OgreWidget.hpp
index e0b32ca..437e980 100644
--- a/Projects/Client/Common/Header/OgreWidget.hpp
+++ b/Projects/Client/Common/Header/OgreWidget.hpp
@@ -8,6 +8,7 @@
#include
#include
#include
+#include
#include
@@ -29,6 +30,7 @@ namespace RNR
Ogre::RenderWindow* ogreWindow;
Ogre::SceneManager* ogreSceneManager;
Ogre::Camera* ogreCamera;
+ Ogre::RTShader::ShaderGenerator* ogreShaderGen;
void render();
void initializeOgre();
diff --git a/Projects/Client/Common/Source/OgreWidget.cpp b/Projects/Client/Common/Source/OgreWidget.cpp
index 6d1f596..8a8d6e3 100644
--- a/Projects/Client/Common/Source/OgreWidget.cpp
+++ b/Projects/Client/Common/Source/OgreWidget.cpp
@@ -1,6 +1,9 @@
#include
#include
+#include
+#include
+
#ifdef __unix__
#include
#include
@@ -26,7 +29,7 @@ namespace RNR
{
Ogre::NameValuePairList options = this->getRenderOptions();
- printf("Widget::initializeOgre: initializing render window\n");
+ printf("OgreWidget::initializeOgre: initializing render window\n");
ogreWindow = ogreRoot->createRenderWindow("GLWidget-RenderWindow", width(), height(), false, &options);
ogreWindow->setActive(true);
ogreWindow->setVisible(true);
@@ -34,16 +37,26 @@ namespace RNR
Ogre::ResourceGroupManager::getSingletonPtr()->addResourceLocation("content", "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true);
Ogre::ResourceGroupManager::getSingletonPtr()->addResourceLocation("../Content", "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true);
+ Ogre::ResourceGroupManager::getSingletonPtr()->addResourceLocation("content/OgreInternal", "FileSystem", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, true);
+ Ogre::ResourceGroupManager::getSingletonPtr()->addResourceLocation("../Content/OgreInternal", "FileSystem", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, true);
Ogre::ResourceGroupManager::getSingletonPtr()->initialiseAllResourceGroups();
Ogre::MaterialManager::getSingletonPtr()->load("sky", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
+ Ogre::MaterialManager::getSingletonPtr()->load("materials", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
ogreSceneManager = ogreRoot->createSceneManager();
ogreSceneManager->setSkyBox(true, "sky/null_plainsky512", 5.f);
ogreSceneManager->setAmbientLight(Ogre::ColourValue::White);
- //Ogre::RTShader::ShaderGenerator* shadergen = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
- //shadergen->addSceneManager(ogreSceneManager);
+ if(Ogre::RTShader::ShaderGenerator::initialize())
+ {
+ ogreShaderGen = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
+ ogreShaderGen->addSceneManager(ogreSceneManager);
+ OgreBites::SGTechniqueResolverListener* schemeNotFoundHandler = new OgreBites::SGTechniqueResolverListener(ogreShaderGen);
+ Ogre::MaterialManager::getSingleton().addListener(schemeNotFoundHandler);
+ }
+ else
+ printf("OgreWidget::initializeOgre: unable to initialize ShaderGenerator\n");
Ogre::Light* light = ogreSceneManager->createLight("MainLight");
Ogre::SceneNode* lightNode = ogreSceneManager->getRootSceneNode()->createChildSceneNode();
@@ -70,8 +83,8 @@ namespace RNR
this->render_time += ogreRoot->getTimer()->getMilliseconds() / 1000.0;
ogreRoot->getTimer()->reset();
- ogreCamera->getParentSceneNode()->lookAt(Ogre::Vector3(sinf(render_time)*5.f, cosf(render_time)*5.f, 0.f), Ogre::Node::TS_PARENT);
-
+ ogreCamera->getParentSceneNode()->lookAt(Ogre::Vector3(sinf(this->render_time)*10.f,0,cosf(this->render_time)*10.f), Ogre::Node::TS_PARENT);
+
ogreRoot->renderOneFrame(this->delta);
}
@@ -92,7 +105,7 @@ namespace RNR
{
Ogre::String windowHandle;
windowHandle = Ogre::StringConverter::toString((unsigned long)winId());
- printf("Widget::getWindowHandle(): %s\n", windowHandle.c_str());
+ printf("OgreWidget::getWindowHandle(): %s\n", windowHandle.c_str());
return windowHandle;
}
diff --git a/Projects/Client/Studio/Source/MainWindow.cpp b/Projects/Client/Studio/Source/MainWindow.cpp
index 83073a3..a5cadd6 100644
--- a/Projects/Client/Studio/Source/MainWindow.cpp
+++ b/Projects/Client/Studio/Source/MainWindow.cpp
@@ -2,6 +2,8 @@
#include
#include
#include
+#include
+
#include "Resources/StudioResources.hpp"
@@ -14,7 +16,8 @@ MainWindow::MainWindow()
QGridLayout* grid = new QGridLayout();
ogreRoot = new Ogre::Root();
- ogreRoot->showConfigDialog(NULL);
+ Ogre::ConfigDialog* config = OgreBites::getNativeConfigDialog();
+ ogreRoot->showConfigDialog(config);
ogreRoot->initialise(false);
menubar = new QMenuBar();
diff --git a/Projects/Client/Studio/Source/main.cpp b/Projects/Client/Studio/Source/main.cpp
index 8bd7785..20092b2 100644
--- a/Projects/Client/Studio/Source/main.cpp
+++ b/Projects/Client/Studio/Source/main.cpp
@@ -21,6 +21,10 @@ int main(int argc, char** argv)
window.ogreWidget->initializeOgre();
RNR::World* world = new RNR::World();
+ Ogre::SceneNode* workspace_node = window.ogreWidget->ogreSceneManager->createSceneNode("Workspace");
+ workspace_node->attachObject(world->getWorkspace());
+ workspace_node->setVisible(true);
+ printf("main: workspace = %p (%p)\n",workspace_node, world->getWorkspace());
window.updateTree(world->getDatamodel());
while (window.isVisible())
diff --git a/Projects/Engine/CMakeLists.txt b/Projects/Engine/CMakeLists.txt
index e06c3b0..c2a9a08 100644
--- a/Projects/Engine/CMakeLists.txt
+++ b/Projects/Engine/CMakeLists.txt
@@ -6,8 +6,12 @@ add_library(Engine STATIC
Header/Helpers/Strings.hpp
Header/App/Humanoid/Humanoid.hpp
Header/App/V8/DataModel/ForceField.hpp
+ Header/App/V8/DataModel/BasePart.hpp
Header/App/V8/Tree/Instance.hpp
+ Header/App/V8/Tree/PVInstance.hpp
Header/App/V8/World/World.hpp
+ Header/App/V8/World/Workspace.hpp
+ Header/App/CoordinateFrame.hpp
Header/Network/GUID.hpp
Header/Rendering/Adorn.hpp
@@ -15,8 +19,12 @@ add_library(Engine STATIC
Source/Helpers/Strings.cpp
Source/App/Humanoid/Humanoid.cpp
Source/App/V8/DataModel/ForceField.cpp
+ Source/App/V8/DataModel/BasePart.cpp
Source/App/V8/Tree/Instance.cpp
+ Source/App/V8/Tree/PVInstance.cpp
+ Source/App/CoordinateFrame.cpp
Source/App/V8/World/World.cpp
+ Source/App/V8/World/Workspace.cpp
Source/Network/GUID.cpp
Source/Rendering/Adorn.cpp
)
diff --git a/Projects/Engine/Header/App/CoordinateFrame.hpp b/Projects/Engine/Header/App/CoordinateFrame.hpp
new file mode 100644
index 0000000..3ec459a
--- /dev/null
+++ b/Projects/Engine/Header/App/CoordinateFrame.hpp
@@ -0,0 +1,21 @@
+#pragma once
+#include
+
+namespace RNR
+{
+ class CoordinateFrame
+ {
+ Ogre::Vector3 m_position;
+ Ogre::Matrix3 m_rotation;
+public:
+ CoordinateFrame();
+
+ Ogre::Matrix3 getRotation() { return m_rotation; }
+ Ogre::Vector3 getPosition() { return m_position; }
+
+ Ogre::Matrix4 getMatrix();
+
+ CoordinateFrame operator+(Ogre::Vector3 vector);
+ CoordinateFrame operator*(CoordinateFrame frame);
+ };
+}
\ No newline at end of file
diff --git a/Projects/Engine/Header/App/V8/DataModel/BasePart.hpp b/Projects/Engine/Header/App/V8/DataModel/BasePart.hpp
new file mode 100644
index 0000000..1f4494f
--- /dev/null
+++ b/Projects/Engine/Header/App/V8/DataModel/BasePart.hpp
@@ -0,0 +1,25 @@
+#pragma once
+#include
+#include
+
+namespace RNR
+{
+ class BasePart : public PVInstance, public Ogre::Renderable
+ {
+ Ogre::MaterialPtr m_material;
+ Ogre::Matrix4 m_matrix;
+ Ogre::Vector3 m_position;
+ Ogre::LightList m_nearbyLights;
+ static Ogre::MeshPtr m_partMesh;
+ public:
+ BasePart();
+
+ void updateMatrix();
+
+ virtual const Ogre::MaterialPtr& getMaterial() const;
+ virtual void getRenderOperation(Ogre::RenderOperation& op);
+ virtual Ogre::Real getSquaredViewDepth(const Ogre::Camera* cam) const;
+ virtual const Ogre::LightList& getLights() const;
+ virtual void getWorldTransforms(Ogre::Matrix4* xform) const;
+ };
+}
\ No newline at end of file
diff --git a/Projects/Engine/Header/App/V8/Tree/Instance.hpp b/Projects/Engine/Header/App/V8/Tree/Instance.hpp
index 87b35ad..79716f7 100644
--- a/Projects/Engine/Header/App/V8/Tree/Instance.hpp
+++ b/Projects/Engine/Header/App/V8/Tree/Instance.hpp
@@ -19,7 +19,6 @@ namespace RNR
public:
Instance();
- Instance(std::string name);
~Instance();
bool contains(RNR::Instance* child);
diff --git a/Projects/Engine/Header/App/V8/Tree/PVInstance.hpp b/Projects/Engine/Header/App/V8/Tree/PVInstance.hpp
new file mode 100644
index 0000000..870ce09
--- /dev/null
+++ b/Projects/Engine/Header/App/V8/Tree/PVInstance.hpp
@@ -0,0 +1,20 @@
+#pragma once
+#include
+#include
+
+namespace RNR
+{
+ class PVInstance : public Instance
+ {
+ protected:
+ CoordinateFrame m_cframe;
+ public:
+ PVInstance();
+
+ CoordinateFrame getCFrame() { return m_cframe; };
+ void setCFrame(CoordinateFrame cframe) { m_cframe = cframe; };
+
+ Ogre::Vector3 getPosition() { return m_cframe.getPosition(); }
+ Ogre::Matrix3 getRotation() { return m_cframe.getRotation(); }
+ };
+}
diff --git a/Projects/Engine/Header/App/V8/World/Workspace.hpp b/Projects/Engine/Header/App/V8/World/Workspace.hpp
new file mode 100644
index 0000000..33df1ff
--- /dev/null
+++ b/Projects/Engine/Header/App/V8/World/Workspace.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include
+#include
+
+namespace RNR
+{
+ // this acts as both an Instance to fit in the RNR graph, and as an Ogre MovableObject to fit in the Ogre graph
+ // all instances that are Renderable are stored in the children of this
+ class Workspace : public Instance, public Ogre::MovableObject
+ {
+ public:
+ Workspace();
+
+ virtual void _updateRenderQueue(Ogre::RenderQueue* queue);
+ virtual const Ogre::String& getMovableType(void) const;
+ virtual const Ogre::AxisAlignedBox& getBoundingBox(void) const;
+ virtual Ogre::Real getBoundingRadius(void) const;
+ virtual void visitRenderables(Ogre::Renderable::Visitor* visitor, bool debugRenderables);
+ private:
+ void renderQueueAddInstance(Ogre::RenderQueue* queue, Instance* instance);
+ };
+}
diff --git a/Projects/Engine/Header/App/V8/World/World.hpp b/Projects/Engine/Header/App/V8/World/World.hpp
index ee38d52..1dd9f62 100644
--- a/Projects/Engine/Header/App/V8/World/World.hpp
+++ b/Projects/Engine/Header/App/V8/World/World.hpp
@@ -1,6 +1,7 @@
#pragma once
#include
+#include
namespace RNR
{
@@ -8,6 +9,7 @@ namespace RNR
{
private:
Instance* m_datamodel;
+ Workspace* m_workspace;
public:
World();
@@ -19,5 +21,7 @@ namespace RNR
Instance* getDatamodel() { return m_datamodel; }
void setDatamodel(Instance* instance) { m_datamodel = instance; }
+ Workspace* getWorkspace() { return m_workspace; }
+ void setWorkspace(Workspace* workspace) { m_workspace = workspace; }
};
}
\ No newline at end of file
diff --git a/Projects/Engine/Header/Rendering/PartMeshFactory.hpp b/Projects/Engine/Header/Rendering/PartMeshFactory.hpp
new file mode 100644
index 0000000..e69de29
diff --git a/Projects/Engine/Source/App/CoordinateFrame.cpp b/Projects/Engine/Source/App/CoordinateFrame.cpp
new file mode 100644
index 0000000..852d7ca
--- /dev/null
+++ b/Projects/Engine/Source/App/CoordinateFrame.cpp
@@ -0,0 +1,31 @@
+#include
+
+namespace RNR
+{
+ CoordinateFrame::CoordinateFrame() : m_position(0.f,0.f,0.f), m_rotation()
+ {
+ m_rotation.FromEulerAnglesXYZ(Ogre::Radian(0.f), Ogre::Radian(0.f), Ogre::Radian(0.f));
+ }
+
+ Ogre::Matrix4 CoordinateFrame::getMatrix()
+ {
+ Ogre::Matrix4 res = Ogre::Matrix4();
+ res.makeTransform(m_position, Ogre::Vector3(1.f,1.f,1.f), Ogre::Quaternion(m_rotation));
+ return res;
+ }
+
+ CoordinateFrame CoordinateFrame::operator+(Ogre::Vector3 vector)
+ {
+ CoordinateFrame res;
+ res.m_position = m_position + vector;
+ return res;
+ }
+
+ CoordinateFrame CoordinateFrame::operator*(CoordinateFrame frame)
+ {
+ CoordinateFrame res;
+ res.m_position = m_position * frame.m_position;
+ res.m_rotation = m_rotation * frame.m_rotation;
+ return res;
+ }
+}
\ No newline at end of file
diff --git a/Projects/Engine/Source/App/V8/DataModel/BasePart.cpp b/Projects/Engine/Source/App/V8/DataModel/BasePart.cpp
new file mode 100644
index 0000000..d51de13
--- /dev/null
+++ b/Projects/Engine/Source/App/V8/DataModel/BasePart.cpp
@@ -0,0 +1,58 @@
+#include
+
+namespace RNR
+{
+ Ogre::MeshPtr BasePart::m_partMesh = 0;
+
+ BasePart::BasePart() : m_matrix(), PVInstance()
+ {
+ setName("Part");
+
+ updateMatrix();
+
+ m_material = Ogre::MaterialManager::getSingletonPtr()->create("part", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
+
+ if(m_partMesh == 0)
+ m_partMesh = Ogre::Root::getSingletonPtr()->getMeshManager()->load("fonts/Cube.mesh", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
+ }
+
+ void BasePart::updateMatrix()
+ {
+ m_matrix = m_cframe.getMatrix();
+ m_position = m_cframe.getPosition();
+ m_nearbyLights = Ogre::LightList();
+
+ }
+
+ const Ogre::MaterialPtr& BasePart::getMaterial() const
+ {
+ return m_material;
+ }
+
+ void BasePart::getRenderOperation(Ogre::RenderOperation& op)
+ {
+ Ogre::SubMesh* submesh = m_partMesh->getSubMesh(0);
+ op.operationType = op.OT_TRIANGLE_LIST;
+ op.vertexData = submesh->vertexData;
+ op.indexData = submesh->indexData;
+ op.numberOfInstances = 1;
+ op.srcRenderable = this;
+ op.useIndexes = true;
+ }
+
+ Ogre::Real BasePart::getSquaredViewDepth(const Ogre::Camera* cam) const
+ {
+ Ogre::Vector3 diff = m_position - cam->getDerivedPosition();
+ return diff.squaredLength();
+ }
+
+ const Ogre::LightList& BasePart::getLights() const
+ {
+ return m_nearbyLights;
+ }
+
+ void BasePart::getWorldTransforms(Ogre::Matrix4* xform) const
+ {
+ xform[0] = m_matrix;
+ }
+}
\ No newline at end of file
diff --git a/Projects/Engine/Source/App/V8/Tree/Instance.cpp b/Projects/Engine/Source/App/V8/Tree/Instance.cpp
index cb70281..827e2f3 100644
--- a/Projects/Engine/Source/App/V8/Tree/Instance.cpp
+++ b/Projects/Engine/Source/App/V8/Tree/Instance.cpp
@@ -8,22 +8,21 @@ namespace RNR
setName("Instance");
}
- Instance::Instance(std::string name)
+ Instance::~Instance()
{
- m_parent = 0;
- setName(name);
+ setParent(NULL);
}
- bool Instance::contains(RNR::Instance* child)
+ bool Instance::contains(Instance* child)
{
auto child_it = std::find(m_children.begin(), m_children.end(), child);
return child_it != m_children.end();
}
- bool RNR::Instance::isAncestorOf(RNR::Instance* instance)
+ bool Instance::isAncestorOf(Instance* instance)
{
- RNR::Instance* instance_parent = instance->m_parent;
+ Instance* instance_parent = instance->m_parent;
while (instance_parent != 0)
{
instance_parent = instance_parent->m_parent;
@@ -35,22 +34,22 @@ namespace RNR
return false;
}
- bool RNR::Instance::askSetParent(RNR::Instance* instance)
+ bool Instance::askSetParent(Instance* instance)
{
return true;
}
- bool RNR::Instance::canSetParent(RNR::Instance* instance)
+ bool Instance::canSetParent(Instance* instance)
{
return !instance || instance->canAddChild(this);
}
- bool RNR::Instance::askAddChild(RNR::Instance* instance)
+ bool Instance::askAddChild(Instance* instance)
{
return true;
}
- bool RNR::Instance::canAddChild(RNR::Instance* instance)
+ bool Instance::canAddChild(Instance* instance)
{
if (instance->contains(this) || instance->m_parent == this)
return false;
@@ -61,7 +60,7 @@ namespace RNR
return instance->askSetParent(this);
}
- void RNR::Instance::setName(std::string name)
+ void Instance::setName(std::string name)
{
if (name != this->m_name)
{
@@ -70,7 +69,7 @@ namespace RNR
}
}
- void RNR::Instance::setParent(RNR::Instance* newParent)
+ void Instance::setParent(Instance* newParent)
{
if (newParent != m_parent)
{
@@ -88,7 +87,7 @@ namespace RNR
if (m_parent)
{
- std::vector* children = m_parent->getChildren();
+ std::vector* children = m_parent->getChildren();
auto child_it = std::find(children->begin(), children->end(), this);
if (child_it != children->end())
@@ -101,12 +100,15 @@ namespace RNR
}
m_parent = newParent;
- m_parent->m_children.push_back(this);
- newParent->onChildAdded(this);
+ if(m_parent)
+ {
+ m_parent->m_children.push_back(this);
+ newParent->onChildAdded(this);
+ }
}
}
- void RNR::Instance::onChildAdded(RNR::Instance* childAdded)
+ void Instance::onChildAdded(Instance* childAdded)
{
//
}
diff --git a/Projects/Engine/Source/App/V8/Tree/PVInstance.cpp b/Projects/Engine/Source/App/V8/Tree/PVInstance.cpp
new file mode 100644
index 0000000..f4cac8e
--- /dev/null
+++ b/Projects/Engine/Source/App/V8/Tree/PVInstance.cpp
@@ -0,0 +1,9 @@
+#include
+
+namespace RNR
+{
+ PVInstance::PVInstance() : m_cframe(), Instance()
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Projects/Engine/Source/App/V8/World/Workspace.cpp b/Projects/Engine/Source/App/V8/World/Workspace.cpp
new file mode 100644
index 0000000..aad767a
--- /dev/null
+++ b/Projects/Engine/Source/App/V8/World/Workspace.cpp
@@ -0,0 +1,51 @@
+#include
+#include
+
+namespace RNR
+{
+ Workspace::Workspace() : Instance(), Ogre::MovableObject()
+ {
+ setName("Workspace");
+ }
+
+ void Workspace::_updateRenderQueue(Ogre::RenderQueue* queue)
+ {
+ printf("!!!!!!!!!!!!!!!!!!!!1 _updateRenderQueue\n");
+ std::vector* children = getChildren();
+ for(auto& child : *children)
+ {
+ renderQueueAddInstance(queue, child);
+ }
+ }
+
+ void Workspace::renderQueueAddInstance(Ogre::RenderQueue* queue, Instance* instance)
+ {
+ std::vector* children = instance->getChildren();
+ for(auto& child : *children)
+ {
+ renderQueueAddInstance(queue, child);
+ }
+ BasePart* rend = dynamic_cast(instance);
+ queue->addRenderable(rend);
+ }
+
+ const Ogre::String& Workspace::getMovableType(void) const
+ {
+ return Ogre::String("Entity");
+ }
+
+ const Ogre::AxisAlignedBox& Workspace::getBoundingBox(void) const
+ {
+ return Ogre::AxisAlignedBox(Ogre::Vector3(-1000,-1000,-1000),Ogre::Vector3(1000,1000,1000));
+ }
+
+ Ogre::Real Workspace::getBoundingRadius(void) const
+ {
+ return 100;
+ }
+
+ void Workspace::visitRenderables(Ogre::Renderable::Visitor* visitor, bool debugRenderables)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Projects/Engine/Source/App/V8/World/World.cpp b/Projects/Engine/Source/App/V8/World/World.cpp
index 8f56d7b..7b6a69d 100644
--- a/Projects/Engine/Source/App/V8/World/World.cpp
+++ b/Projects/Engine/Source/App/V8/World/World.cpp
@@ -1,4 +1,5 @@
#include
+#include
namespace RNR
{
@@ -6,15 +7,13 @@ namespace RNR
{
m_datamodel = new Instance();
m_datamodel->setName("DataModel");
+ m_workspace = new Workspace();
+ m_workspace->setParent(m_datamodel);
Instance* test = new Instance();
- Instance* test2 = new Instance();
- test->setParent(m_datamodel);
- test2->setParent(test);
- test = new Instance();
- test->setParent(m_datamodel);
- test = new Instance();
+ BasePart* test2 = new BasePart();
test->setParent(m_datamodel);
+ test2->setParent(m_workspace);
}
World::~World()
diff --git a/Projects/Engine/Source/Rendering/PartMeshFactory.cpp b/Projects/Engine/Source/Rendering/PartMeshFactory.cpp
new file mode 100644
index 0000000..e69de29