diff --git a/binaries/data/mods/public/art/materials/basic_spec.xml b/binaries/data/mods/public/art/materials/basic_spec.xml
new file mode 100644
index 0000000000..7a74779522
--- /dev/null
+++ b/binaries/data/mods/public/art/materials/basic_spec.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/art/materials/blend_spec.xml b/binaries/data/mods/public/art/materials/blend_spec.xml
new file mode 100644
index 0000000000..6e455fc48e
--- /dev/null
+++ b/binaries/data/mods/public/art/materials/blend_spec.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/art/materials/objectcolor_spec.xml b/binaries/data/mods/public/art/materials/objectcolor_spec.xml
new file mode 100644
index 0000000000..9e4f90ab37
--- /dev/null
+++ b/binaries/data/mods/public/art/materials/objectcolor_spec.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/art/materials/playercolor_spec.xml b/binaries/data/mods/public/art/materials/playercolor_spec.xml
new file mode 100644
index 0000000000..2cb7f77736
--- /dev/null
+++ b/binaries/data/mods/public/art/materials/playercolor_spec.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/shaders/arb/model_common.fp b/binaries/data/mods/public/shaders/arb/model_common.fp
index d7cdc4a6ba..911b4db560 100644
--- a/binaries/data/mods/public/shaders/arb/model_common.fp
+++ b/binaries/data/mods/public/shaders/arb/model_common.fp
@@ -1,22 +1,16 @@
!!ARBfp1.0
-#ifdef USE_FP_SHADOW
+#if USE_FP_SHADOW
OPTION ARB_fragment_program_shadow;
#endif
-#ifdef LIGHTING_MODEL_old
- #define CLAMP_LIGHTING
-#endif
+ATTRIB v_tex = fragment.texcoord[0];
+ATTRIB v_shadow = fragment.texcoord[1];
+ATTRIB v_los = fragment.texcoord[2];
-#ifdef CLAMP_LIGHTING // for compat with old scenarios that expect clamped lighting
- #define MAD_MAYBE_SAT MAD_SAT
-#else
- #define MAD_MAYBE_SAT MAD
-#endif
-
-#ifdef USE_OBJECTCOLOR
+#if USE_OBJECTCOLOR
PARAM objectColor = program.local[0];
#else
-#ifdef USE_PLAYERCOLOR
+#if USE_PLAYERCOLOR
PARAM playerColor = program.local[0];
#endif
#endif
@@ -24,73 +18,106 @@
PARAM shadingColor = program.local[1];
PARAM ambient = program.local[2];
-#ifdef USE_SHADOW_PCF
+#if USE_SHADOW_PCF
PARAM shadowOffsets1 = program.local[3];
PARAM shadowOffsets2 = program.local[4];
TEMP offset;
#endif
-TEMP tex;
-TEMP temp;
-TEMP diffuse;
-TEMP color;
+#if USE_SPECULAR
+ ATTRIB v_normal = fragment.texcoord[3];
+ ATTRIB v_half = fragment.texcoord[4];
+ PARAM specularPower = program.local[5];
+ PARAM specularColor = program.local[6];
+#endif
-TEX tex, fragment.texcoord[0], texture[0], 2D;
-#ifdef USE_TRANSPARENT
+TEMP tex;
+TEMP texdiffuse;
+TEMP sundiffuse;
+TEMP temp;
+TEMP color;
+TEMP shadow;
+
+TEX tex, v_tex, texture[0], 2D;
+#if USE_TRANSPARENT
MOV result.color.a, tex;
#endif
// Apply coloring based on texture alpha
-#ifdef USE_OBJECTCOLOR
+#if USE_OBJECTCOLOR
LRP temp.rgb, objectColor, 1.0, tex.a;
- MUL color.rgb, tex, temp;
+ MUL texdiffuse.rgb, tex, temp;
#else
-#ifdef USE_PLAYERCOLOR
+#if USE_PLAYERCOLOR
LRP temp.rgb, playerColor, 1.0, tex.a;
- MUL color.rgb, tex, temp;
+ MUL texdiffuse.rgb, tex, temp;
#else
- MOV color.rgb, tex;
+ MOV texdiffuse.rgb, tex;
#endif
#endif
-// Compute color = texture * (ambient + diffuse*shadow)
-// (diffuse is 2*fragment.color due to clamp-avoidance in the vertex program)
-#ifdef USE_SHADOW
- #ifdef USE_FP_SHADOW
- #ifdef USE_SHADOW_PCF
- MOV offset.zw, fragment.texcoord[1];
- ADD offset.xy, fragment.texcoord[1], shadowOffsets1;
+#if USE_SPECULAR
+ // specular = specularColor * pow(max(0.0, dot(normalize(v_normal), v_half)), specularPower);
+ TEMP specular;
+ TEMP normal;
+ DP3 normal.w, v_normal, v_normal;
+ RSQ normal.w, normal.w;
+ MUL normal.xyz, v_normal, normal.w;
+ DP3_SAT temp.y, normal, v_half;
+ // temp^p = (2^lg2(temp))^p = 2^(lg2(temp)*p)
+ LG2 temp.y, temp.y;
+ MUL temp.y, temp.y, specularPower.x;
+ EX2 temp.y, temp.y;
+ MUL specular.rgb, specularColor, temp.y;
+#endif
+
+// color = (texdiffuse * sundiffuse + specular) * get_shadow() + texdiffuse * ambient;
+// (sundiffuse is 2*fragment.color due to clamp-avoidance in the vertex program)
+#if USE_SHADOW
+ #if USE_FP_SHADOW
+ #if USE_SHADOW_PCF
+ MOV offset.zw, v_shadow;
+ ADD offset.xy, v_shadow, shadowOffsets1;
TEX temp.x, offset, texture[1], SHADOW2D;
- ADD offset.xy, fragment.texcoord[1], shadowOffsets1.zwzw;
+ ADD offset.xy, v_shadow, shadowOffsets1.zwzw;
TEX temp.y, offset, texture[1], SHADOW2D;
- ADD offset.xy, fragment.texcoord[1], shadowOffsets2;
+ ADD offset.xy, v_shadow, shadowOffsets2;
TEX temp.z, offset, texture[1], SHADOW2D;
- ADD offset.xy, fragment.texcoord[1], shadowOffsets2.zwzw;
+ ADD offset.xy, v_shadow, shadowOffsets2.zwzw;
TEX temp.w, offset, texture[1], SHADOW2D;
- DP4 temp, temp, 0.25;
+ DP4 shadow, temp, 0.25;
#else
- TEX temp, fragment.texcoord[1], texture[1], SHADOW2D;
+ TEX shadow, v_shadow, texture[1], SHADOW2D;
#endif
#else
- TEX tex, fragment.texcoord[1], texture[1], 2D;
- MOV_SAT temp.z, fragment.texcoord[1].z;
- SGE temp, tex.x, temp.z;
+ TEX tex, v_shadow, texture[1], 2D;
+ MOV_SAT temp.z, v_shadow.z;
+ SGE shadow, tex.x, temp.z;
#endif
- #ifdef CLAMP_LIGHTING
- MAD_SAT diffuse.rgb, fragment.color, 2.0, ambient;
- LRP temp.rgb, temp, diffuse, ambient;
+
+ MUL sundiffuse.rgb, fragment.color, 2.0;
+
+ #if USE_SPECULAR
+ MAD color.rgb, texdiffuse, sundiffuse, specular;
+ MUL temp.rgb, texdiffuse, ambient;
+ MAD color.rgb, color, shadow, temp;
#else
- MUL diffuse.rgb, fragment.color, 2.0;
- MAD temp.rgb, diffuse, temp, ambient;
+ MAD temp.rgb, sundiffuse, shadow, ambient;
+ MUL color.rgb, texdiffuse, temp;
#endif
- MUL color.rgb, color, temp;
+
#else
- MAD_MAYBE_SAT temp.rgb, fragment.color, 2.0, ambient;
- MUL color.rgb, color, temp;
+ #if USE_SPECULAR
+ MAD temp.rgb, fragment.color, 2.0, ambient;
+ MAD color.rgb, texdiffuse, temp, specular;
+ #else
+ MAD temp.rgb, fragment.color, 2.0, ambient;
+ MUL color.rgb, texdiffuse, temp;
+ #endif
#endif
// Multiply everything by the LOS texture
-TEX tex.a, fragment.texcoord[2], texture[2], 2D;
+TEX tex.a, v_los, texture[2], 2D;
MUL color.rgb, color, tex.a;
MUL result.color.rgb, color, shadingColor;
diff --git a/binaries/data/mods/public/shaders/arb/model_common.vp b/binaries/data/mods/public/shaders/arb/model_common.vp
index 797f5d1286..a348b031de 100644
--- a/binaries/data/mods/public/shaders/arb/model_common.vp
+++ b/binaries/data/mods/public/shaders/arb/model_common.vp
@@ -1,14 +1,28 @@
!!ARBvp1.0
-PARAM sunDir = program.local[0];
-PARAM sunColor = program.local[1];
-PARAM losTransform = program.local[2];
-PARAM shadowTransform[4] = { program.local[3..6] };
+
+PARAM cameraPos = program.local[0];
+PARAM sunDir = program.local[1];
+PARAM sunColor = program.local[2];
+PARAM losTransform = program.local[3];
+PARAM shadowTransform[4] = { program.local[4..7] };
+#if USE_INSTANCING
+ PARAM instancingTransform[4] = { program.local[8..11] };
+#endif
+
+TEMP temp;
TEMP lighting;
+OUTPUT v_tex = result.texcoord[0];
+OUTPUT v_shadow = result.texcoord[1];
+OUTPUT v_los = result.texcoord[2];
+#if USE_SPECULAR
+ OUTPUT v_normal = result.texcoord[3];
+ OUTPUT v_half = result.texcoord[4];
+#endif
+
//// Compute position and normal:
-#ifdef USE_INSTANCING
- PARAM instancingTransform[4] = { program.local[7..10] };
+#if USE_INSTANCING
TEMP position;
TEMP normal;
DP4 position.x, instancingTransform[0], vertex.position;
@@ -38,17 +52,35 @@ MUL lighting, lighting, 0.5;
// Apply light colour
MUL result.color, lighting, sunColor;
-//// Texture coordinates:
+#if USE_SPECULAR
+ // eyeVec = normalize(cameraPos - position);
+ TEMP eyeVec;
+ SUB eyeVec.xyz, cameraPos, position;
+ DP3 eyeVec.w, eyeVec, eyeVec;
+ RSQ eyeVec.w, eyeVec.w;
+ MUL eyeVec.xyz, eyeVec, eyeVec.w;
-MOV result.texcoord[0], vertex.texcoord[0];
+ // v_half = normalize(-sunDir + eyeVec);
+ TEMP half;
+ SUB half.xyz, eyeVec, sunDir;
+ DP3 half.w, half, half;
+ RSQ half.w, half.w;
+ MUL v_half.xyz, half, half.w;
-#ifdef USE_SHADOW
- DP4 result.texcoord[1].x, shadowTransform[0], position;
- DP4 result.texcoord[1].y, shadowTransform[1], position;
- DP4 result.texcoord[1].z, shadowTransform[2], position;
- DP4 result.texcoord[1].w, shadowTransform[3], position;
+ MOV v_normal, normal;
#endif
-MAD result.texcoord[2], position.xzzz, losTransform.x, losTransform.y;
+//// Texture coordinates:
+
+MOV v_tex, vertex.texcoord[0];
+
+#if USE_SHADOW
+ DP4 v_shadow.x, shadowTransform[0], position;
+ DP4 v_shadow.y, shadowTransform[1], position;
+ DP4 v_shadow.z, shadowTransform[2], position;
+ DP4 v_shadow.w, shadowTransform[3], position;
+#endif
+
+MAD v_los, position.xzzz, losTransform.x, losTransform.y;
END
diff --git a/binaries/data/mods/public/shaders/arb/model_common.xml b/binaries/data/mods/public/shaders/arb/model_common.xml
index cafaf0c769..5a49f878c8 100644
--- a/binaries/data/mods/public/shaders/arb/model_common.xml
+++ b/binaries/data/mods/public/shaders/arb/model_common.xml
@@ -2,11 +2,12 @@
-
-
-
-
-
+
+
+
+
+
+
@@ -23,6 +24,8 @@
+
+
diff --git a/binaries/data/mods/public/shaders/glsl/model_common.fs b/binaries/data/mods/public/shaders/glsl/model_common.fs
index 1003d0f3f8..498a84311f 100644
--- a/binaries/data/mods/public/shaders/glsl/model_common.fs
+++ b/binaries/data/mods/public/shaders/glsl/model_common.fs
@@ -1,20 +1,20 @@
-#version 110
+#version 120
uniform sampler2D baseTex;
uniform sampler2D losTex;
-#ifdef USE_SHADOW
- #ifdef USE_SHADOW_SAMPLER
+#if USE_SHADOW
+ #if USE_SHADOW_SAMPLER
uniform sampler2DShadow shadowTex;
#else
uniform sampler2D shadowTex;
#endif
#endif
-#ifdef USE_OBJECTCOLOR
+#if USE_OBJECTCOLOR
uniform vec3 objectColor;
#else
-#ifdef USE_PLAYERCOLOR
+#if USE_PLAYERCOLOR
uniform vec3 playerColor;
#endif
#endif
@@ -29,11 +29,18 @@ varying vec2 v_tex;
varying vec4 v_shadow;
varying vec2 v_los;
+#if USE_SPECULAR
+ uniform float specularPower;
+ uniform vec3 specularColor;
+ varying vec3 v_normal;
+ varying vec3 v_half;
+#endif
+
float get_shadow()
{
- #ifdef USE_SHADOW
- #ifdef USE_SHADOW_SAMPLER
- #ifdef USE_SHADOW_PCF
+ #if USE_SHADOW
+ #if USE_SHADOW_SAMPLER
+ #if USE_SHADOW_PCF
return 0.25 * (
shadow2D(shadowTex, vec3(v_shadow.xy + shadowOffsets1.xy, v_shadow.z)).a +
shadow2D(shadowTex, vec3(v_shadow.xy + shadowOffsets1.zw, v_shadow.z)).a +
@@ -46,7 +53,7 @@ float get_shadow()
#else
if (v_shadow.z >= 1.0)
return 1.0;
- #ifdef USE_SHADOW_PCF
+ #if USE_SHADOW_PCF
return (
(v_shadow.z <= texture2D(shadowTex, v_shadow.xy + shadowOffsets1.xy).x ? 0.25 : 0.0) +
(v_shadow.z <= texture2D(shadowTex, v_shadow.xy + shadowOffsets1.zw).x ? 0.25 : 0.0) +
@@ -66,7 +73,7 @@ void main()
{
vec4 tex = texture2D(baseTex, v_tex);
- #ifdef USE_TRANSPARENT
+ #if USE_TRANSPARENT
gl_FragColor.a = tex.a;
#else
gl_FragColor.a = 1.0;
@@ -77,22 +84,34 @@ void main()
discard;
#endif
- vec3 color = tex.rgb;
+ vec3 texdiffuse = tex.rgb;
// Apply-coloring based on texture alpha
- #ifdef USE_OBJECTCOLOR
- color *= mix(objectColor, vec3(1.0, 1.0, 1.0), tex.a);
+ #if USE_OBJECTCOLOR
+ texdiffuse *= mix(objectColor, vec3(1.0, 1.0, 1.0), tex.a);
#else
- #ifdef USE_PLAYERCOLOR
- color *= mix(playerColor, vec3(1.0, 1.0, 1.0), tex.a);
+ #if USE_PLAYERCOLOR
+ texdiffuse *= mix(playerColor, vec3(1.0, 1.0, 1.0), tex.a);
#endif
#endif
- color *= v_lighting * get_shadow() + ambient;
-
- color *= texture2D(losTex, v_los).a;
+ vec3 sundiffuse = v_lighting;
+
+ #if USE_SPECULAR
+ // Interpolated v_normal needs to be re-normalized since it varies
+ // significantly between adjacent vertexes;
+ // v_half changes very gradually so don't bother normalizing that
+ vec3 specular = specularColor * pow(max(0.0, dot(normalize(v_normal), v_half)), specularPower);
+ #else
+ vec3 specular = vec3(0.0);
+ #endif
+
+ vec3 color = (texdiffuse * sundiffuse + specular) * get_shadow() + texdiffuse * ambient;
+
+ float los = texture2D(losTex, v_los).a;
+ color *= los;
color *= shadingColor;
-
+
gl_FragColor.rgb = color;
}
diff --git a/binaries/data/mods/public/shaders/glsl/model_common.vs b/binaries/data/mods/public/shaders/glsl/model_common.vs
index f13ba6ca50..d8c87c2ec5 100644
--- a/binaries/data/mods/public/shaders/glsl/model_common.vs
+++ b/binaries/data/mods/public/shaders/glsl/model_common.vs
@@ -1,6 +1,7 @@
-#version 110
+#version 120
uniform mat4 transform;
+uniform vec3 cameraPos;
uniform vec3 sunDir;
uniform vec3 sunColor;
uniform vec2 losTransform;
@@ -12,15 +13,20 @@ varying vec2 v_tex;
varying vec4 v_shadow;
varying vec2 v_los;
+#if USE_SPECULAR
+ varying vec3 v_normal;
+ varying vec3 v_half;
+#endif
+
attribute vec3 a_vertex;
attribute vec3 a_normal;
attribute vec2 a_uv0;
void main()
{
- #ifdef USE_INSTANCING
+ #if USE_INSTANCING
vec4 position = instancingTransform * vec4(a_vertex, 1.0);
- vec3 normal = (instancingTransform * vec4(a_normal, 0.0)).xyz;
+ vec3 normal = mat3(instancingTransform) * a_normal;
#else
vec4 position = vec4(a_vertex, 1.0);
vec3 normal = a_normal;
@@ -28,6 +34,13 @@ void main()
gl_Position = transform * position;
+ #if USE_SPECULAR
+ vec3 eyeVec = normalize(cameraPos.xyz - position.xyz);
+ vec3 sunVec = -sunDir;
+ v_half = normalize(sunVec + eyeVec);
+ v_normal = normal;
+ #endif
+
v_lighting = max(0.0, dot(normal, -sunDir)) * sunColor;
v_tex = a_uv0;
v_shadow = shadowTransform * position;
diff --git a/binaries/data/mods/public/shaders/glsl/terrain_common.fs b/binaries/data/mods/public/shaders/glsl/terrain_common.fs
index 0ace856c14..54e1a90646 100644
--- a/binaries/data/mods/public/shaders/glsl/terrain_common.fs
+++ b/binaries/data/mods/public/shaders/glsl/terrain_common.fs
@@ -1,11 +1,11 @@
-#version 110
+#version 120
uniform sampler2D baseTex;
uniform sampler2D blendTex;
uniform sampler2D losTex;
-#ifdef USE_SHADOW
- #ifdef USE_SHADOW_SAMPLER
+#if USE_SHADOW
+ #if USE_SHADOW_SAMPLER
uniform sampler2DShadow shadowTex;
#else
uniform sampler2D shadowTex;
@@ -23,11 +23,18 @@ varying vec4 v_shadow;
varying vec2 v_los;
varying vec2 v_blend;
+#if USE_SPECULAR
+ uniform float specularPower;
+ uniform vec3 specularColor;
+ varying vec3 v_normal;
+ varying vec3 v_half;
+#endif
+
float get_shadow()
{
- #ifdef USE_SHADOW
- #ifdef USE_SHADOW_SAMPLER
- #ifdef USE_SHADOW_PCF
+ #if USE_SHADOW
+ #if USE_SHADOW_SAMPLER
+ #if USE_SHADOW_PCF
return 0.25 * (
shadow2D(shadowTex, vec3(v_shadow.xy + shadowOffsets1.xy, v_shadow.z)).a +
shadow2D(shadowTex, vec3(v_shadow.xy + shadowOffsets1.zw, v_shadow.z)).a +
@@ -40,7 +47,7 @@ float get_shadow()
#else
if (v_shadow.z >= 1.0)
return 1.0;
- #ifdef USE_SHADOW_PCF
+ #if USE_SHADOW_PCF
return (
(v_shadow.z <= texture2D(shadowTex, v_shadow.xy + shadowOffsets1.xy).x ? 0.25 : 0.0) +
(v_shadow.z <= texture2D(shadowTex, v_shadow.xy + shadowOffsets1.zw).x ? 0.25 : 0.0) +
@@ -58,26 +65,38 @@ float get_shadow()
void main()
{
- #ifdef BLEND
+ #if BLEND
// Use alpha from blend texture
gl_FragColor.a = 1.0 - texture2D(blendTex, v_blend).a;
#endif
- // Load diffuse colour
- vec4 color = texture2D(baseTex, v_tex);
+ vec4 tex = texture2D(baseTex, v_tex);
- #ifdef DECAL
+ #if DECAL
// Use alpha from main texture
- gl_FragColor.a = color.a;
+ gl_FragColor.a = tex.a;
#endif
- color.rgb *= v_lighting * get_shadow() + ambient;
-
- color *= texture2D(losTex, v_los).a;
+ vec3 texdiffuse = tex.rgb;
+ vec3 sundiffuse = v_lighting;
- #ifdef DECAL
- color.rgb *= shadingColor;
+ #if USE_SPECULAR
+ // Interpolated v_normal needs to be re-normalized since it varies
+ // significantly between adjacenent vertexes;
+ // v_half changes very gradually so don't bother normalizing that
+ vec3 specular = specularColor * pow(max(0.0, dot(normalize(v_normal), v_half)), specularPower);
+ #else
+ vec3 specular = vec3(0.0);
#endif
- gl_FragColor.rgb = color.rgb;
+ vec3 color = (texdiffuse * sundiffuse + specular) * get_shadow() + texdiffuse * ambient;
+
+ float los = texture2D(losTex, v_los).a;
+ color *= los;
+
+ #if DECAL
+ color *= shadingColor;
+ #endif
+
+ gl_FragColor.rgb = color;
}
diff --git a/binaries/data/mods/public/shaders/glsl/terrain_common.vs b/binaries/data/mods/public/shaders/glsl/terrain_common.vs
index 8a0a570ebc..a24d62d73f 100644
--- a/binaries/data/mods/public/shaders/glsl/terrain_common.vs
+++ b/binaries/data/mods/public/shaders/glsl/terrain_common.vs
@@ -1,6 +1,8 @@
-#version 110
+#version 120
uniform mat4 transform;
+uniform vec3 cameraPos;
+uniform vec3 sunDir;
uniform vec3 sunColor;
uniform vec2 textureTransform;
uniform vec2 losTransform;
@@ -12,6 +14,11 @@ varying vec4 v_shadow;
varying vec2 v_los;
varying vec2 v_blend;
+#if USE_SPECULAR
+ varying vec3 v_normal;
+ varying vec3 v_half;
+#endif
+
attribute vec3 a_vertex;
attribute vec3 a_color;
attribute vec2 a_uv0;
@@ -19,31 +26,44 @@ attribute vec2 a_uv1;
void main()
{
- gl_Position = transform * vec4(a_vertex, 1.0);
+ vec4 position = vec4(a_vertex, 1.0);
+
+ gl_Position = transform * position;
v_lighting = a_color * sunColor;
-#ifdef DECAL
- v_tex = a_uv0;
-#else
- // Compute texcoords from position and terrain-texture-dependent transform
- float c = textureTransform.x;
- float s = -textureTransform.y;
- v_tex = vec2(a_vertex.x * c + a_vertex.z * -s, a_vertex.x * -s + a_vertex.z * -c);
+ #if DECAL
+ v_tex = a_uv0;
+ #else
+ // Compute texcoords from position and terrain-texture-dependent transform
+ float c = textureTransform.x;
+ float s = -textureTransform.y;
+ v_tex = vec2(a_vertex.x * c + a_vertex.z * -s, a_vertex.x * -s + a_vertex.z * -c);
-#ifdef GL_ES
- // XXX: Ugly hack to hide some precision issues in GLES
- v_tex = mod(v_tex, vec2(9.0, 9.0));
-#endif
-#endif
+ #if GL_ES
+ // XXX: Ugly hack to hide some precision issues in GLES
+ v_tex = mod(v_tex, vec2(9.0, 9.0));
+ #endif
+ #endif
-#ifdef BLEND
- v_blend = a_uv1;
-#endif
+ #if BLEND
+ v_blend = a_uv1;
+ #endif
-#ifdef USE_SHADOW
- v_shadow = shadowTransform * vec4(a_vertex, 1.0);
-#endif
+ #if USE_SHADOW
+ v_shadow = shadowTransform * vec4(a_vertex, 1.0);
+ #endif
+
+ #if USE_SPECULAR
+ // TODO: for proper specular terrain, we need to provide vertex normals.
+ // But we don't have that yet, so do something wrong instead.
+ vec3 normal = vec3(0, 1, 0);
+
+ vec3 eyeVec = normalize(cameraPos.xyz - position.xyz);
+ vec3 sunVec = -sunDir;
+ v_half = normalize(sunVec + eyeVec);
+ v_normal = normal;
+ #endif
v_los = a_vertex.xz * losTransform.x + losTransform.yy;
}
diff --git a/source/graphics/Camera.cpp b/source/graphics/Camera.cpp
index a330b613fd..ea96ffc003 100644
--- a/source/graphics/Camera.cpp
+++ b/source/graphics/Camera.cpp
@@ -195,8 +195,8 @@ void CCamera::GetScreenCoordinates(const CVector3D& world, float& x, float& y) c
CVector4D screenspace = transform.Transform(CVector4D(world.X, world.Y, world.Z, 1.0f));
- x = screenspace.m_X / screenspace.m_W;
- y = screenspace.m_Y / screenspace.m_W;
+ x = screenspace.X / screenspace.W;
+ y = screenspace.Y / screenspace.W;
x = (x + 1) * 0.5f * g_Renderer.GetWidth();
y = (1 - y) * 0.5f * g_Renderer.GetHeight();
}
diff --git a/source/graphics/CinemaTrack.cpp b/source/graphics/CinemaTrack.cpp
index 8885903db8..ed79f283b8 100644
--- a/source/graphics/CinemaTrack.cpp
+++ b/source/graphics/CinemaTrack.cpp
@@ -95,7 +95,7 @@ void CCinemaPath::DrawSpline(const CVector4D& RGBA, int smoothness, bool lines)
#warning TODO: do something about CCinemaPath on GLES
#else
- glColor4f( RGBA.m_X, RGBA.m_Y, RGBA.m_Z, RGBA.m_W );
+ glColor4f( RGBA.X, RGBA.Y, RGBA.Z, RGBA.W );
if ( lines )
{
glLineWidth(1.8f);
diff --git a/source/graphics/Material.cpp b/source/graphics/Material.cpp
index c8e87dfd44..fbf5cc6371 100644
--- a/source/graphics/Material.cpp
+++ b/source/graphics/Material.cpp
@@ -23,16 +23,10 @@ static CColor BrokenColor(0.3f, 0.3f, 0.3f, 1.0f);
CMaterial::CMaterial() :
m_AlphaBlending(false),
- m_PlayerID(INVALID_PLAYER),
- m_ObjectColor(BrokenColor)
+ m_PlayerID(INVALID_PLAYER)
{
}
-void CMaterial::SetObjectColor(const CColor& colour)
-{
- m_ObjectColor = colour;
-}
-
void CMaterial::SetDiffuseTexture(const CTexturePtr& texture)
{
m_DiffuseTexture = texture;
@@ -47,3 +41,8 @@ void CMaterial::AddShaderDefine(const char* key, const char* value)
{
m_ShaderDefines.Add(key, value);
}
+
+void CMaterial::AddStaticUniform(const char* key, const CVector4D& value)
+{
+ m_StaticUniforms.Add(key, value);
+}
diff --git a/source/graphics/Material.h b/source/graphics/Material.h
index 85a7c14325..01e1c5fdee 100644
--- a/source/graphics/Material.h
+++ b/source/graphics/Material.h
@@ -36,11 +36,6 @@ public:
void SetUsesAlphaBlending(bool flag) { m_AlphaBlending = flag; }
bool UsesAlphaBlending() { return m_AlphaBlending; }
- // Color used for "objectColor" in shaders when USE_OBJECTCOLOR is set,
- // to allow e.g. variations in horse colorings
- void SetObjectColor(const CColor &colour);
- CColor GetObjectColor() { return m_ObjectColor; }
-
void SetDiffuseTexture(const CTexturePtr& texture);
const CTexturePtr& GetDiffuseTexture() const { return m_DiffuseTexture; }
@@ -50,15 +45,18 @@ public:
void AddShaderDefine(const char* key, const char* value);
const CShaderDefines& GetShaderDefines() const { return m_ShaderDefines; }
+ void AddStaticUniform(const char* key, const CVector4D& value);
+ const CShaderUniforms& GetStaticUniforms() const { return m_StaticUniforms; }
+
private:
CTexturePtr m_DiffuseTexture;
CStrIntern m_ShaderEffect;
CShaderDefines m_ShaderDefines;
+ CShaderUniforms m_StaticUniforms;
bool m_AlphaBlending;
player_id_t m_PlayerID;
- CColor m_ObjectColor;
};
#endif
diff --git a/source/graphics/MaterialManager.cpp b/source/graphics/MaterialManager.cpp
index a78614c774..2bc095985a 100644
--- a/source/graphics/MaterialManager.cpp
+++ b/source/graphics/MaterialManager.cpp
@@ -16,10 +16,13 @@
*/
#include "precompiled.h"
+
+#include "MaterialManager.h"
+
#include "lib/ogl.h"
+#include "maths/Vector4D.h"
#include "ps/Filesystem.h"
#include "ps/XML/Xeromyces.h"
-#include "MaterialManager.h"
CMaterial CMaterialManager::LoadMaterial(const VfsPath& pathname)
{
@@ -39,6 +42,7 @@ CMaterial CMaterialManager::LoadMaterial(const VfsPath& pathname)
EL(alpha_blending);
EL(define);
EL(shader);
+ EL(uniform);
AT(effect);
AT(name);
AT(value);
@@ -66,6 +70,13 @@ CMaterial CMaterialManager::LoadMaterial(const VfsPath& pathname)
{
material.AddShaderDefine(attrs.GetNamedItem(at_name).c_str(), attrs.GetNamedItem(at_value).c_str());
}
+ else if (token == el_uniform)
+ {
+ std::stringstream str(attrs.GetNamedItem(at_value));
+ CVector4D vec;
+ str >> vec.X >> vec.Y >> vec.Z >> vec.W;
+ material.AddStaticUniform(attrs.GetNamedItem(at_name).c_str(), vec);
+ }
}
m_Materials[pathname] = material;
diff --git a/source/graphics/MaterialManager.h b/source/graphics/MaterialManager.h
index 14fbfeb783..e2fe2b73b6 100644
--- a/source/graphics/MaterialManager.h
+++ b/source/graphics/MaterialManager.h
@@ -20,6 +20,7 @@
#include