Unite nodes shaders.

Pass drawtype and material type to shaders.
Move shaders generation to startup only.
Allow assign shaders per tile.
Initial code to support water surface shader.
master
RealBadAngel 2014-05-14 23:19:31 +02:00
parent 9ffa88b558
commit 6c98fd6658
22 changed files with 315 additions and 793 deletions

View File

@ -1 +0,0 @@
trans_alphach

View File

@ -1,98 +0,0 @@
uniform mat4 mWorldViewProj;
uniform mat4 mInvWorld;
uniform mat4 mTransWorld;
uniform mat4 mWorld;
uniform float dayNightRatio;
uniform vec3 eyePosition;
varying vec3 vPosition;
varying vec3 worldPosition;
varying vec3 eyeVec;
varying vec3 lightVec;
varying vec3 tsEyeVec;
varying vec3 tsLightVec;
const float BS = 10.0;
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = mWorldViewProj * gl_Vertex;
vPosition = gl_Position.xyz;
worldPosition = (mWorld * gl_Vertex).xyz;
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
vec3 normal, tangent, binormal;
normal = normalize(gl_NormalMatrix * gl_Normal);
if (gl_Normal.x > 0.5) {
// 1.0, 0.0, 0.0
tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, -1.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
} else if (gl_Normal.x < -0.5) {
// -1.0, 0.0, 0.0
tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
} else if (gl_Normal.y > 0.5) {
// 0.0, 1.0, 0.0
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
} else if (gl_Normal.y < -0.5) {
// 0.0, -1.0, 0.0
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
} else if (gl_Normal.z > 0.5) {
// 0.0, 0.0, 1.0
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
} else if (gl_Normal.z < -0.5) {
// 0.0, 0.0, -1.0
tangent = normalize(gl_NormalMatrix * vec3(-1.0, 0.0, 0.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
}
mat3 tbnMatrix = mat3( tangent.x, binormal.x, normal.x,
tangent.y, binormal.y, normal.y,
tangent.z, binormal.z, normal.z);
lightVec = sunPosition - worldPosition;
tsLightVec = lightVec * tbnMatrix;
eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz;
tsEyeVec = eyeVec * tbnMatrix;
vec4 color;
float day = gl_Color.r;
float night = gl_Color.g;
float light_source = gl_Color.b;
float rg = mix(night, day, dayNightRatio);
rg += light_source * 2.5; // Make light sources brighter
float b = rg;
// Moonlight is blue
b += (day - night) / 13.0;
rg -= (day - night) / 13.0;
// Emphase blue a bit in darker places
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);
// Artificial light is yellow-ish
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);
color.r = clamp(rg,0.0,1.0);
color.g = clamp(rg,0.0,1.0);
color.b = clamp(b,0.0,1.0);
// Make sides and bottom darker than the top
color = color * color; // SRGB -> Linear
if(gl_Normal.y <= 0.5)
color *= 0.6;
color = sqrt(color); // Linear -> SRGB
color.a = gl_Color.a;
gl_FrontColor = gl_BackColor = color;
}

View File

@ -1 +0,0 @@
trans_alphach_ref

View File

@ -1,100 +0,0 @@
uniform sampler2D baseTexture;
uniform sampler2D normalTexture;
uniform sampler2D useNormalmap;
uniform vec4 skyBgColor;
uniform float fogDistance;
uniform vec3 eyePosition;
varying vec3 vPosition;
varying vec3 worldPosition;
varying vec3 eyeVec;
varying vec3 lightVec;
bool normalTexturePresent = false;
const float e = 2.718281828459;
float intensity (vec3 color){
return (color.r + color.g + color.b) / 3.0;
}
float get_rgb_height (vec2 uv){
return intensity(texture2D(baseTexture,uv).rgb);
}
vec4 get_normal_map(vec2 uv){
vec4 bump = texture2D(normalTexture, uv).rgba;
bump.xyz = normalize(bump.xyz * 2.0 -1.0);
bump.y = -bump.y;
return bump;
}
void main (void)
{
vec3 color;
vec4 bump;
vec2 uv = gl_TexCoord[0].st;
bool use_normalmap = false;
#ifdef USE_NORMALMAPS
if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0){
normalTexturePresent = true;
}
#endif
#ifdef USE_NORMALMAPS
if (normalTexturePresent){
bump = get_normal_map(uv);
use_normalmap = true;
}
#endif
#ifdef GENERATE_NORMALMAPS
if (use_normalmap == false){
float tl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y+SAMPLE_STEP));
float t = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP));
float tr = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y+SAMPLE_STEP));
float r = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y));
float br = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y-SAMPLE_STEP));
float b = get_rgb_height (vec2(uv.x,uv.y-SAMPLE_STEP));
float bl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP));
float l = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y));
float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
bump = vec4 (normalize(vec3 (dX, -dY, NORMALMAPS_STRENGTH)),1.0);
use_normalmap = true;
}
#endif
vec4 base = texture2D(baseTexture, uv).rgba;
#ifdef ENABLE_BUMPMAPPING
if (use_normalmap){
vec3 L = normalize(lightVec);
vec3 E = normalize(eyeVec);
float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0),0.5);
float diffuse = dot(E,bump.xyz);
color = 0.05*base.rgb + diffuse*base.rgb + 0.2*specular*base.rgb;
} else {
color = base.rgb;
}
#else
color = base.rgb;
#endif
vec4 col = vec4(color.rgb, base.a);
col = col * col; // SRGB -> Linear
col *= 1.8;
col.r = 1.0 - exp(1.0 - col.r) / e;
col.g = 1.0 - exp(1.0 - col.g) / e;
col.b = 1.0 - exp(1.0 - col.b) / e;
col = sqrt(col); // Linear -> SRGB
col *= gl_Color;
if(fogDistance != 0.0){
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
col = mix(col, skyBgColor, d);
}
gl_FragColor = vec4(col.rgb, base.a);
}

View File

@ -1,92 +0,0 @@
uniform mat4 mWorldViewProj;
uniform mat4 mInvWorld;
uniform mat4 mTransWorld;
uniform mat4 mWorld;
uniform float dayNightRatio;
uniform float animationTimer;
uniform vec3 eyePosition;
varying vec3 vPosition;
varying vec3 worldPosition;
varying vec3 eyeVec;
varying vec3 lightVec;
const float BS = 10.0;
#ifdef ENABLE_WAVING_LEAVES
float smoothCurve( float x ) {
return x * x *( 3.0 - 2.0 * x );
}
float triangleWave( float x ) {
return abs( fract( x + 0.5 ) * 2.0 - 1.0 );
}
float smoothTriangleWave( float x ) {
return smoothCurve( triangleWave( x ) ) * 2.0 - 1.0;
}
#endif
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
#ifdef ENABLE_WAVING_LEAVES
vec4 pos = gl_Vertex;
vec4 pos2 = mWorld*gl_Vertex;
pos.x += (smoothTriangleWave(animationTimer*10.0 + pos2.x * 0.01 + pos2.z * 0.01) * 2.0 - 1.0) * 0.4;
pos.y += (smoothTriangleWave(animationTimer*15.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.2;
pos.z += (smoothTriangleWave(animationTimer*10.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.4;
gl_Position = mWorldViewProj * pos;
#else
gl_Position = mWorldViewProj * gl_Vertex;
#endif
vPosition = gl_Position.xyz;
worldPosition = (mWorld * gl_Vertex).xyz;
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
lightVec = sunPosition - worldPosition;
eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz;
vec4 color;
//color = vec4(1.0, 1.0, 1.0, 1.0);
float day = gl_Color.r;
float night = gl_Color.g;
float light_source = gl_Color.b;
/*color.r = mix(night, day, dayNightRatio);
color.g = color.r;
color.b = color.r;*/
float rg = mix(night, day, dayNightRatio);
rg += light_source * 2.5; // Make light sources brighter
float b = rg;
// Moonlight is blue
b += (day - night) / 13.0;
rg -= (day - night) / 13.0;
// Emphase blue a bit in darker places
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);
// Artificial light is yellow-ish
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);
color.r = clamp(rg,0.0,1.0);
color.g = clamp(rg,0.0,1.0);
color.b = clamp(b,0.0,1.0);
// Make sides and bottom darker than the top
color = color * color; // SRGB -> Linear
if(gl_Normal.y <= 0.5)
color *= 0.6;
color = sqrt(color); // Linear -> SRGB
color.a = gl_Color.a;
gl_FrontColor = gl_BackColor = color;
}

View File

@ -1 +0,0 @@
trans_alphach

View File

@ -1,95 +0,0 @@
uniform sampler2D baseTexture;
uniform sampler2D normalTexture;
uniform sampler2D useNormalmap;
uniform vec4 skyBgColor;
uniform float fogDistance;
uniform vec3 eyePosition;
varying vec3 vPosition;
varying vec3 worldPosition;
varying vec3 eyeVec;
varying vec3 tsEyeVec;
varying vec3 lightVec;
varying vec3 tsLightVec;
const float e = 2.718281828459;
float intensity (vec3 color){
return (color.r + color.g + color.b) / 3.0;
}
float get_rgb_height (vec2 uv){
return intensity(texture2D(baseTexture,uv).rgb);
}
vec4 get_normal_map(vec2 uv){
vec4 bump = texture2D(normalTexture, uv).rgba;
bump.xyz = normalize(bump.xyz * 2.0 -1.0);
bump.y = -bump.y;
return bump;
}
void main (void)
{
vec3 color;
vec4 bump;
vec2 uv = gl_TexCoord[0].st;
bool use_normalmap = false;
#ifdef USE_NORMALMAPS
if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0){
bump = get_normal_map(uv);
use_normalmap = true;
}
#endif
#ifdef GENERATE_NORMALMAPS
if (use_normalmap == false){
float tl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y+SAMPLE_STEP));
float t = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP));
float tr = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y+SAMPLE_STEP));
float r = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y));
float br = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y-SAMPLE_STEP));
float b = get_rgb_height (vec2(uv.x,uv.y-SAMPLE_STEP));
float bl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP));
float l = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y));
float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
bump = vec4 (normalize(vec3 (dX, -dY, NORMALMAPS_STRENGTH)),1.0);
use_normalmap = true;
}
#endif
vec4 base = texture2D(baseTexture, uv).rgba;
#ifdef ENABLE_BUMPMAPPING
if (use_normalmap){
vec3 L = normalize(lightVec);
vec3 E = normalize(eyeVec);
float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0),0.5);
float diffuse = dot(E,bump.xyz);
color = 0.05*base.rgb + diffuse*base.rgb + 0.2*specular*base.rgb;
} else {
color = base.rgb;
}
#else
color = base.rgb;
#endif
float alpha = gl_Color.a;
vec4 col = vec4(color.rgb, alpha);
col = col * col; // SRGB -> Linear
col *= 1.8;
col.r = 1.0 - exp(1.0 - col.r) / e;
col.g = 1.0 - exp(1.0 - col.g) / e;
col.b = 1.0 - exp(1.0 - col.b) / e;
col = sqrt(col); // Linear -> SRGB
col *= gl_Color;
if(fogDistance != 0.0){
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
alpha = mix(alpha, 0.0, d);
}
gl_FragColor = vec4(col.rgb, alpha);
}

View File

@ -17,6 +17,7 @@ varying vec3 tsLightVec;
bool normalTexturePresent = false; bool normalTexturePresent = false;
const float e = 2.718281828459; const float e = 2.718281828459;
const float BS = 10.0;
float intensity (vec3 color){ float intensity (vec3 color){
return (color.r + color.g + color.b) / 3.0; return (color.r + color.g + color.b) / 3.0;
@ -94,17 +95,34 @@ vec4 base = texture2D(baseTexture, uv).rgba;
color = base.rgb; color = base.rgb;
#endif #endif
vec4 col = vec4(color.rgb, base.a); #if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE
float alpha = gl_Color.a;
vec4 col = vec4(color.rgb, alpha);
col *= gl_Color;
col = col * col; // SRGB -> Linear col = col * col; // SRGB -> Linear
col *= 1.8; col *= 1.8;
col.r = 1.0 - exp(1.0 - col.r) / e; col.r = 1.0 - exp(1.0 - col.r) / e;
col.g = 1.0 - exp(1.0 - col.g) / e; col.g = 1.0 - exp(1.0 - col.g) / e;
col.b = 1.0 - exp(1.0 - col.b) / e; col.b = 1.0 - exp(1.0 - col.b) / e;
col = sqrt(col); // Linear -> SRGB col = sqrt(col); // Linear -> SRGB
if(fogDistance != 0.0){
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
alpha = mix(alpha, 0.0, d);
}
gl_FragColor = vec4(col.rgb, alpha);
#else
vec4 col = vec4(color.rgb, base.a);
col *= gl_Color; col *= gl_Color;
col = col * col; // SRGB -> Linear
col *= 1.8;
col.r = 1.0 - exp(1.0 - col.r) / e;
col.g = 1.0 - exp(1.0 - col.g) / e;
col.b = 1.0 - exp(1.0 - col.b) / e;
col = sqrt(col); // Linear -> SRGB
if(fogDistance != 0.0){ if(fogDistance != 0.0){
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
col = mix(col, skyBgColor, d); col = mix(col, skyBgColor, d);
} }
gl_FragColor = vec4(col.rgb, base.a); gl_FragColor = vec4(col.rgb, base.a);
#endif
} }

View File

@ -4,37 +4,60 @@ uniform mat4 mTransWorld;
uniform mat4 mWorld; uniform mat4 mWorld;
uniform float dayNightRatio; uniform float dayNightRatio;
uniform float animationTimer;
uniform vec3 eyePosition; uniform vec3 eyePosition;
uniform float animationTimer;
varying vec3 vPosition; varying vec3 vPosition;
varying vec3 worldPosition; varying vec3 worldPosition;
varying vec3 eyeVec; varying vec3 eyeVec;
varying vec3 lightVec; varying vec3 lightVec;
varying vec3 tsEyeVec; varying vec3 tsEyeVec;
varying vec3 tsLightVec; varying vec3 tsLightVec;
const float e = 2.718281828459;
const float BS = 10.0; const float BS = 10.0;
float smoothCurve( float x ) {
return x * x *( 3.0 - 2.0 * x );
}
float triangleWave( float x ) {
return abs( fract( x + 0.5 ) * 2.0 - 1.0 );
}
float smoothTriangleWave( float x ) {
return smoothCurve( triangleWave( x ) ) * 2.0 - 1.0;
}
void main(void) void main(void)
{ {
gl_TexCoord[0] = gl_MultiTexCoord0; gl_TexCoord[0] = gl_MultiTexCoord0;
#ifdef ENABLE_WAVING_WATER #if (MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE) && ENABLE_WAVING_WATER
vec4 pos2 = gl_Vertex; vec4 pos = gl_Vertex;
pos2.y -= 2.0; pos.y -= 2.0;
pos2.y -= sin (pos2.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) * WATER_WAVE_HEIGHT pos.y -= sin (pos.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) * WATER_WAVE_HEIGHT
+ sin ((pos2.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) / 7.0) * WATER_WAVE_HEIGHT; + sin ((pos.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) / 7.0) * WATER_WAVE_HEIGHT;
gl_Position = mWorldViewProj * pos2; gl_Position = mWorldViewProj * pos;
vPosition = gl_Position.xyz; #elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES
vec4 pos = gl_Vertex;
vec4 pos2 = mWorld * gl_Vertex;
pos.x += (smoothTriangleWave(animationTimer*10.0 + pos2.x * 0.01 + pos2.z * 0.01) * 2.0 - 1.0) * 0.4;
pos.y += (smoothTriangleWave(animationTimer*15.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.2;
pos.z += (smoothTriangleWave(animationTimer*10.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.4;
gl_Position = mWorldViewProj * pos;
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
vec4 pos = gl_Vertex;
vec4 pos2 = mWorld * gl_Vertex;
if (gl_TexCoord[0].y < 0.05) {
pos.x += (smoothTriangleWave(animationTimer * 20.0 + pos2.x * 0.1 + pos2.z * 0.1) * 2.0 - 1.0) * 0.8;
pos.y -= (smoothTriangleWave(animationTimer * 10.0 + pos2.x * -0.5 + pos2.z * -0.5) * 2.0 - 1.0) * 0.4;
}
gl_Position = mWorldViewProj * pos;
#else #else
gl_Position = mWorldViewProj * gl_Vertex; gl_Position = mWorldViewProj * gl_Vertex;
vPosition = gl_Position.xyz;
#endif #endif
vPosition = gl_Position.xyz;
worldPosition = (mWorld * gl_Vertex).xyz; worldPosition = (mWorld * gl_Vertex).xyz;
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0); vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
@ -85,7 +108,7 @@ void main(void)
// Moonlight is blue // Moonlight is blue
b += (day - night) / 13.0; b += (day - night) / 13.0;
rg -= (day - night) / 13.0; rg -= (day - night) / 23.0;
// Emphase blue a bit in darker places // Emphase blue a bit in darker places
// See C++ implementation in mapblock_mesh.cpp finalColorBlend() // See C++ implementation in mapblock_mesh.cpp finalColorBlend()
@ -99,12 +122,14 @@ void main(void)
color.g = clamp(rg,0.0,1.0); color.g = clamp(rg,0.0,1.0);
color.b = clamp(b,0.0,1.0); color.b = clamp(b,0.0,1.0);
#if !(MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE)
// Make sides and bottom darker than the top // Make sides and bottom darker than the top
color = color * color; // SRGB -> Linear color = color * color; // SRGB -> Linear
if(gl_Normal.y <= 0.5) if(gl_Normal.y <= 0.5)
color *= 0.6; color *= 0.6;
color = sqrt(color); // Linear -> SRGB color = sqrt(color); // Linear -> SRGB
color.a = gl_Color.a; #endif
color.a = gl_Color.a;
gl_FrontColor = gl_BackColor = color; gl_FrontColor = gl_BackColor = color;
} }

View File

@ -1 +0,0 @@
trans_alphach_ref

View File

@ -1,94 +0,0 @@
uniform sampler2D baseTexture;
uniform sampler2D normalTexture;
uniform sampler2D useNormalmap;
uniform vec4 skyBgColor;
uniform float fogDistance;
uniform vec3 eyePosition;
varying vec3 vPosition;
varying vec3 worldPosition;
varying vec3 eyeVec;
varying vec3 lightVec;
bool normalTexturePresent = false;
const float e = 2.718281828459;
float intensity (vec3 color){
return (color.r + color.g + color.b) / 3.0;
}
float get_rgb_height (vec2 uv){
return intensity(texture2D(baseTexture,uv).rgb);
}
vec4 get_normal_map(vec2 uv){
vec4 bump = texture2D(normalTexture, uv).rgba;
bump.xyz = normalize(bump.xyz * 2.0 -1.0);
bump.y = -bump.y;
return bump;
}
void main (void)
{
vec3 color;
vec4 bump;
vec2 uv = gl_TexCoord[0].st;
bool use_normalmap = false;
#ifdef USE_NORMALMAPS
if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0){
bump = get_normal_map(uv);
use_normalmap = true;
}
#endif
#ifdef GENERATE_NORMALMAPS
if (use_normalmap == false){
float tl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y+SAMPLE_STEP));
float t = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP));
float tr = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y+SAMPLE_STEP));
float r = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y));
float br = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y-SAMPLE_STEP));
float b = get_rgb_height (vec2(uv.x,uv.y-SAMPLE_STEP));
float bl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP));
float l = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y));
float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
bump = vec4 (normalize(vec3 (dX, -dY, NORMALMAPS_STRENGTH)),1.0);
use_normalmap = true;
}
#endif
vec4 base = texture2D(baseTexture, uv).rgba;
#ifdef ENABLE_BUMPMAPPING
if (use_normalmap){
vec3 L = normalize(lightVec);
vec3 E = normalize(eyeVec);
float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0),0.5);
float diffuse = dot(E,bump.xyz);
color = 0.05*base.rgb + diffuse*base.rgb + 0.2*specular*base.rgb;
} else {
color = base.rgb;
}
#else
color = base.rgb;
#endif
vec4 col = vec4(color.rgb, base.a);
col = col * col; // SRGB -> Linear
col *= 1.8;
col.r = 1.0 - exp(1.0 - col.r) / e;
col.g = 1.0 - exp(1.0 - col.g) / e;
col.b = 1.0 - exp(1.0 - col.b) / e;
col = sqrt(col); // Linear -> SRGB
col *= gl_Color;
if(fogDistance != 0.0){
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
col = mix(col, skyBgColor, d);
}
gl_FragColor = vec4(col.rgb, base.a);
}

View File

@ -1,93 +0,0 @@
uniform mat4 mWorldViewProj;
uniform mat4 mInvWorld;
uniform mat4 mTransWorld;
uniform mat4 mWorld;
uniform float dayNightRatio;
uniform float animationTimer;
uniform vec3 eyePosition;
varying vec3 vPosition;
varying vec3 worldPosition;
varying vec3 eyeVec;
varying vec3 lightVec;
const float BS = 10.0;
#ifdef ENABLE_WAVING_PLANTS
float smoothCurve( float x ) {
return x * x *( 3.0 - 2.0 * x );
}
float triangleWave( float x ) {
return abs( fract( x + 0.5 ) * 2.0 - 1.0 );
}
float smoothTriangleWave( float x ) {
return smoothCurve( triangleWave( x ) ) * 2.0 - 1.0;
}
#endif
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
#ifdef ENABLE_WAVING_PLANTS
vec4 pos = gl_Vertex;
vec4 pos2 = mWorld * gl_Vertex;
if (gl_TexCoord[0].y < 0.05) {
pos.x += (smoothTriangleWave(animationTimer * 20.0 + pos2.x * 0.1 + pos2.z * 0.1) * 2.0 - 1.0) * 0.8;
pos.y -= (smoothTriangleWave(animationTimer * 10.0 + pos2.x * -0.5 + pos2.z * -0.5) * 2.0 - 1.0) * 0.4;
}
gl_Position = mWorldViewProj * pos;
#else
gl_Position = mWorldViewProj * gl_Vertex;
#endif
vPosition = gl_Position.xyz;
worldPosition = (mWorld * gl_Vertex).xyz;
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
lightVec = sunPosition - worldPosition;
eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz;
vec4 color;
//color = vec4(1.0, 1.0, 1.0, 1.0);
float day = gl_Color.r;
float night = gl_Color.g;
float light_source = gl_Color.b;
/*color.r = mix(night, day, dayNightRatio);
color.g = color.r;
color.b = color.r;*/
float rg = mix(night, day, dayNightRatio);
rg += light_source * 2.5; // Make light sources brighter
float b = rg;
// Moonlight is blue
b += (day - night) / 13.0;
rg -= (day - night) / 13.0;
// Emphase blue a bit in darker places
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);
// Artificial light is yellow-ish
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);
color.r = clamp(rg,0.0,1.0);
color.g = clamp(rg,0.0,1.0);
color.b = clamp(b,0.0,1.0);
// Make sides and bottom darker than the top
color = color * color; // SRGB -> Linear
if(gl_Normal.y <= 0.5)
color *= 0.6;
color = sqrt(color); // Linear -> SRGB
color.a = gl_Color.a;
gl_FrontColor = gl_BackColor = color;
}

View File

@ -1 +0,0 @@
trans_alphach_ref

View File

@ -14,10 +14,11 @@ varying vec3 tsEyeVec;
varying vec3 lightVec; varying vec3 lightVec;
varying vec3 tsLightVec; varying vec3 tsLightVec;
bool normalTexturePresent = false; bool normalTexturePresent = false;
const float e = 2.718281828459; const float e = 2.718281828459;
const float BS = 10.0;
float intensity (vec3 color){ float intensity (vec3 color){
return (color.r + color.g + color.b) / 3.0; return (color.r + color.g + color.b) / 3.0;
} }
@ -39,7 +40,7 @@ void main (void)
vec4 bump; vec4 bump;
vec2 uv = gl_TexCoord[0].st; vec2 uv = gl_TexCoord[0].st;
bool use_normalmap = false; bool use_normalmap = false;
#ifdef USE_NORMALMAPS #ifdef USE_NORMALMAPS
if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0){ if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0){
normalTexturePresent = true; normalTexturePresent = true;
@ -94,17 +95,34 @@ vec4 base = texture2D(baseTexture, uv).rgba;
color = base.rgb; color = base.rgb;
#endif #endif
vec4 col = vec4(color.rgb, base.a); #if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE
float alpha = gl_Color.a;
vec4 col = vec4(color.rgb, alpha);
col *= gl_Color;
col = col * col; // SRGB -> Linear col = col * col; // SRGB -> Linear
col *= 1.8; col *= 1.8;
col.r = 1.0 - exp(1.0 - col.r) / e; col.r = 1.0 - exp(1.0 - col.r) / e;
col.g = 1.0 - exp(1.0 - col.g) / e; col.g = 1.0 - exp(1.0 - col.g) / e;
col.b = 1.0 - exp(1.0 - col.b) / e; col.b = 1.0 - exp(1.0 - col.b) / e;
col = sqrt(col); // Linear -> SRGB col = sqrt(col); // Linear -> SRGB
if(fogDistance != 0.0){
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
alpha = mix(alpha, 0.0, d);
}
gl_FragColor = vec4(col.rgb, alpha);
#else
vec4 col = vec4(color.rgb, base.a);
col *= gl_Color; col *= gl_Color;
col = col * col; // SRGB -> Linear
col *= 1.8;
col.r = 1.0 - exp(1.0 - col.r) / e;
col.g = 1.0 - exp(1.0 - col.g) / e;
col.b = 1.0 - exp(1.0 - col.b) / e;
col = sqrt(col); // Linear -> SRGB
if(fogDistance != 0.0){ if(fogDistance != 0.0){
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
col = mix(col, skyBgColor, d); col = mix(col, skyBgColor, d);
} }
gl_FragColor = vec4(col.rgb, base.a); gl_FragColor = vec4(col.rgb, base.a);
#endif
} }

View File

@ -4,24 +4,59 @@ uniform mat4 mTransWorld;
uniform mat4 mWorld; uniform mat4 mWorld;
uniform float dayNightRatio; uniform float dayNightRatio;
uniform vec3 eyePosition; uniform vec3 eyePosition;
uniform float animationTimer;
varying vec3 vPosition; varying vec3 vPosition;
varying vec3 worldPosition; varying vec3 worldPosition;
varying vec3 eyeVec; varying vec3 eyeVec;
varying vec3 lightVec; varying vec3 lightVec;
varying vec3 tsEyeVec; varying vec3 tsEyeVec;
varying vec3 tsLightVec; varying vec3 tsLightVec;
const float e = 2.718281828459;
const float BS = 10.0; const float BS = 10.0;
float smoothCurve( float x ) {
return x * x *( 3.0 - 2.0 * x );
}
float triangleWave( float x ) {
return abs( fract( x + 0.5 ) * 2.0 - 1.0 );
}
float smoothTriangleWave( float x ) {
return smoothCurve( triangleWave( x ) ) * 2.0 - 1.0;
}
void main(void) void main(void)
{ {
gl_TexCoord[0] = gl_MultiTexCoord0; gl_TexCoord[0] = gl_MultiTexCoord0;
#if (MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE) && ENABLE_WAVING_WATER
vec4 pos = gl_Vertex;
pos.y -= 2.0;
pos.y -= sin (pos.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) * WATER_WAVE_HEIGHT
+ sin ((pos.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) / 7.0) * WATER_WAVE_HEIGHT;
gl_Position = mWorldViewProj * pos;
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES
vec4 pos = gl_Vertex;
vec4 pos2 = mWorld * gl_Vertex;
pos.x += (smoothTriangleWave(animationTimer*10.0 + pos2.x * 0.01 + pos2.z * 0.01) * 2.0 - 1.0) * 0.4;
pos.y += (smoothTriangleWave(animationTimer*15.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.2;
pos.z += (smoothTriangleWave(animationTimer*10.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.4;
gl_Position = mWorldViewProj * pos;
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
vec4 pos = gl_Vertex;
vec4 pos2 = mWorld * gl_Vertex;
if (gl_TexCoord[0].y < 0.05) {
pos.x += (smoothTriangleWave(animationTimer * 20.0 + pos2.x * 0.1 + pos2.z * 0.1) * 2.0 - 1.0) * 0.8;
pos.y -= (smoothTriangleWave(animationTimer * 10.0 + pos2.x * -0.5 + pos2.z * -0.5) * 2.0 - 1.0) * 0.4;
}
gl_Position = mWorldViewProj * pos;
#else
gl_Position = mWorldViewProj * gl_Vertex; gl_Position = mWorldViewProj * gl_Vertex;
#endif
vPosition = gl_Position.xyz; vPosition = gl_Position.xyz;
worldPosition = (mWorld * gl_Vertex).xyz; worldPosition = (mWorld * gl_Vertex).xyz;
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0); vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
@ -73,7 +108,7 @@ void main(void)
// Moonlight is blue // Moonlight is blue
b += (day - night) / 13.0; b += (day - night) / 13.0;
rg -= (day - night) / 13.0; rg -= (day - night) / 23.0;
// Emphase blue a bit in darker places // Emphase blue a bit in darker places
// See C++ implementation in mapblock_mesh.cpp finalColorBlend() // See C++ implementation in mapblock_mesh.cpp finalColorBlend()
@ -87,12 +122,14 @@ void main(void)
color.g = clamp(rg,0.0,1.0); color.g = clamp(rg,0.0,1.0);
color.b = clamp(b,0.0,1.0); color.b = clamp(b,0.0,1.0);
#if !(MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE)
// Make sides and bottom darker than the top // Make sides and bottom darker than the top
color = color * color; // SRGB -> Linear color = color * color; // SRGB -> Linear
if(gl_Normal.y <= 0.5) if(gl_Normal.y <= 0.5)
color *= 0.6; color *= 0.6;
color = sqrt(color); // Linear -> SRGB color = sqrt(color); // Linear -> SRGB
color.a = gl_Color.a; #endif
color.a = gl_Color.a;
gl_FrontColor = gl_BackColor = color; gl_FrontColor = gl_BackColor = color;
} }

View File

@ -2670,9 +2670,9 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
infostream<<"- Updating node aliases"<<std::endl; infostream<<"- Updating node aliases"<<std::endl;
m_nodedef->updateAliases(m_itemdef); m_nodedef->updateAliases(m_itemdef);
// Update node textures // Update node textures and assign shaders to each tile
infostream<<"- Updating node textures"<<std::endl; infostream<<"- Updating node textures"<<std::endl;
m_nodedef->updateTextures(m_tsrc); m_nodedef->updateTextures(m_tsrc, m_shsrc);
// Preload item textures and meshes if configured to // Preload item textures and meshes if configured to
if(g_settings->getBool("preload_item_visuals")) if(g_settings->getBool("preload_item_visuals"))

View File

@ -1106,24 +1106,13 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
/* /*
Convert MeshCollector to SMesh Convert MeshCollector to SMesh
*/ */
ITextureSource *tsrc = m_gamedef->tsrc();
IShaderSource *shdrsrc = m_gamedef->getShaderSource();
bool enable_shaders = g_settings->getBool("enable_shaders"); bool enable_shaders = g_settings->getBool("enable_shaders");
bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping"); bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion"); bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");
video::E_MATERIAL_TYPE shadermat1, shadermat2, shadermat3,
shadermat4, shadermat5;
shadermat1 = shadermat2 = shadermat3 = shadermat4 = shadermat5 =
video::EMT_SOLID;
if (enable_shaders) {
IShaderSource *shdrsrc = m_gamedef->getShaderSource();
shadermat1 = shdrsrc->getShader("solids_shader").material;
shadermat2 = shdrsrc->getShader("liquids_shader").material;
shadermat3 = shdrsrc->getShader("alpha_shader").material;
shadermat4 = shdrsrc->getShader("leaves_shader").material;
shadermat5 = shdrsrc->getShader("plants_shader").material;
}
for(u32 i = 0; i < collector.prebuffers.size(); i++) for(u32 i = 0; i < collector.prebuffers.size(); i++)
{ {
PreMeshBuffer &p = collector.prebuffers[i]; PreMeshBuffer &p = collector.prebuffers[i];
@ -1135,7 +1124,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
// - Cracks // - Cracks
if(p.tile.material_flags & MATERIAL_FLAG_CRACK) if(p.tile.material_flags & MATERIAL_FLAG_CRACK)
{ {
ITextureSource *tsrc = data->m_gamedef->tsrc();
// Find the texture name plus ^[crack:N: // Find the texture name plus ^[crack:N:
std::ostringstream os(std::ios::binary); std::ostringstream os(std::ios::binary);
os<<tsrc->getTextureName(p.tile.texture_id)<<"^[crack"; os<<tsrc->getTextureName(p.tile.texture_id)<<"^[crack";
@ -1151,7 +1139,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
// - Texture animation // - Texture animation
if(p.tile.material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) if(p.tile.material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES)
{ {
ITextureSource *tsrc = data->m_gamedef->tsrc();
// Add to MapBlockMesh in order to animate these tiles // Add to MapBlockMesh in order to animate these tiles
m_animation_tiles[i] = p.tile; m_animation_tiles[i] = p.tile;
m_animation_frames[i] = 0; m_animation_frames[i] = 0;
@ -1206,7 +1193,8 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
material.setTexture(0, p.tile.texture); material.setTexture(0, p.tile.texture);
if (enable_shaders) { if (enable_shaders) {
ITextureSource *tsrc = data->m_gamedef->tsrc(); material.MaterialType = shdrsrc->getShaderInfo(p.tile.shader_id).material;
p.tile.applyMaterialOptionsWithShaders(material);
material.setTexture(2, tsrc->getTexture("disable_img.png")); material.setTexture(2, tsrc->getTexture("disable_img.png"));
if (enable_bumpmapping || enable_parallax_occlusion) { if (enable_bumpmapping || enable_parallax_occlusion) {
if (tsrc->isKnownSourceImage("override_normal.png")){ if (tsrc->isKnownSourceImage("override_normal.png")){
@ -1230,8 +1218,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
} }
} }
} }
p.tile.applyMaterialOptionsWithShaders(material,
shadermat1, shadermat2, shadermat3, shadermat4, shadermat5);
} else { } else {
p.tile.applyMaterialOptions(material); p.tile.applyMaterialOptions(material);
} }
@ -1360,6 +1346,7 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first); scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first);
ITextureSource *tsrc = m_gamedef->getTextureSource(); ITextureSource *tsrc = m_gamedef->getTextureSource();
IShaderSource *shdrsrc = m_gamedef->getShaderSource();
// Create new texture name from original // Create new texture name from original
std::ostringstream os(std::ios::binary); std::ostringstream os(std::ios::binary);
@ -1367,9 +1354,10 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
os<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<<frame; os<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<<frame;
// Set the texture // Set the texture
buf->getMaterial().setTexture(0, tsrc->getTexture(os.str())); buf->getMaterial().setTexture(0, tsrc->getTexture(os.str()));
buf->getMaterial().setTexture(2, tsrc->getTexture("disable_img.png")); if (enable_shaders){
if (enable_shaders && (enable_bumpmapping || enable_parallax_occlusion)) buf->getMaterial().setTexture(2, tsrc->getTexture("disable_img.png"));
{ buf->getMaterial().MaterialType = shdrsrc->getShaderInfo(tile.shader_id).material;
if (enable_bumpmapping || enable_parallax_occlusion){
if (tsrc->isKnownSourceImage("override_normal.png")){ if (tsrc->isKnownSourceImage("override_normal.png")){
buf->getMaterial().setTexture(1, tsrc->getTexture("override_normal.png")); buf->getMaterial().setTexture(1, tsrc->getTexture("override_normal.png"));
buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png")); buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png"));
@ -1388,6 +1376,7 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
} }
} }
} }
}
} }
// Day-night transition // Day-night transition

View File

@ -597,7 +597,8 @@ public:
} }
} }
} }
virtual void updateTextures(ITextureSource *tsrc) virtual void updateTextures(ITextureSource *tsrc,
IShaderSource *shdsrc)
{ {
#ifndef SERVER #ifndef SERVER
infostream<<"CNodeDefManager::updateTextures(): Updating " infostream<<"CNodeDefManager::updateTextures(): Updating "
@ -621,6 +622,8 @@ public:
} }
bool is_liquid = false; bool is_liquid = false;
bool is_water_surface = false;
u8 material_type; u8 material_type;
material_type = (f->alpha == 255) ? TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA; material_type = (f->alpha == 255) ? TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA;
@ -676,13 +679,13 @@ public:
} }
} }
if (f->waving == 1) if (f->waving == 1)
material_type = TILE_MATERIAL_LEAVES; material_type = TILE_MATERIAL_WAVING_LEAVES;
break; break;
case NDT_PLANTLIKE: case NDT_PLANTLIKE:
f->solidness = 0; f->solidness = 0;
f->backface_culling = false; f->backface_culling = false;
if (f->waving == 1) if (f->waving == 1)
material_type = TILE_MATERIAL_PLANTS; material_type = TILE_MATERIAL_WAVING_PLANTS;
break; break;
case NDT_TORCHLIKE: case NDT_TORCHLIKE:
case NDT_SIGNLIKE: case NDT_SIGNLIKE:
@ -693,11 +696,22 @@ public:
break; break;
} }
if (is_liquid) if (is_liquid){
material_type = (f->alpha == 255) ? TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT; material_type = (f->alpha == 255) ? TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT;
if (f->name == "default:water_source")
is_water_surface = true;
}
u32 tile_shader[6];
for(u16 j=0; j<6; j++)
tile_shader[j] = shdsrc->getShader("nodes_shader",material_type, f->drawtype);
if (is_water_surface)
tile_shader[0] = shdsrc->getShader("water_surface_shader",material_type, f->drawtype);
// Tiles (fill in f->tiles[]) // Tiles (fill in f->tiles[])
for(u16 j=0; j<6; j++){ for(u16 j=0; j<6; j++){
// Shader
f->tiles[j].shader_id = tile_shader[j];
// Texture // Texture
f->tiles[j].texture = tsrc->getTexture( f->tiles[j].texture = tsrc->getTexture(
tiledef[j].name, tiledef[j].name,
@ -740,6 +754,8 @@ public:
} }
// Special tiles (fill in f->special_tiles[]) // Special tiles (fill in f->special_tiles[])
for(u16 j=0; j<CF_SPECIAL_COUNT; j++){ for(u16 j=0; j<CF_SPECIAL_COUNT; j++){
// Shader
f->special_tiles[j].shader_id = tile_shader[j];
// Texture // Texture
f->special_tiles[j].texture = tsrc->getTexture( f->special_tiles[j].texture = tsrc->getTexture(
f->tiledef_special[j].name, f->tiledef_special[j].name,

View File

@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapnode.h" #include "mapnode.h"
#ifndef SERVER #ifndef SERVER
#include "tile.h" #include "tile.h"
#include "shader.h"
#endif #endif
#include "itemgroup.h" #include "itemgroup.h"
#include "sound.h" // SimpleSoundSpec #include "sound.h" // SimpleSoundSpec
@ -35,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class IItemDefManager; class IItemDefManager;
class ITextureSource; class ITextureSource;
class IShaderSource;
class IGameDef; class IGameDef;
typedef std::list<std::pair<content_t, int> > GroupItems; typedef std::list<std::pair<content_t, int> > GroupItems;
@ -323,7 +325,8 @@ public:
/* /*
Update tile textures to latest return values of TextueSource. Update tile textures to latest return values of TextueSource.
*/ */
virtual void updateTextures(ITextureSource *tsrc)=0; virtual void updateTextures(ITextureSource *tsrc,
IShaderSource *shdsrc)=0;
virtual void serialize(std::ostream &os, u16 protocol_version)=0; virtual void serialize(std::ostream &os, u16 protocol_version)=0;
virtual void deSerialize(std::istream &is)=0; virtual void deSerialize(std::istream &is)=0;

View File

@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h" #include "log.h"
#include "gamedef.h" #include "gamedef.h"
#include "strfnd.h" // trim() #include "strfnd.h" // trim()
#include "tile.h"
/* /*
A cache from shader name to shader path A cache from shader name to shader path
@ -210,7 +211,8 @@ public:
class MainShaderConstantSetter : public IShaderConstantSetter class MainShaderConstantSetter : public IShaderConstantSetter
{ {
public: public:
MainShaderConstantSetter(IrrlichtDevice *device) MainShaderConstantSetter(IrrlichtDevice *device):
m_device(device)
{} {}
~MainShaderConstantSetter() {} ~MainShaderConstantSetter() {}
@ -254,6 +256,9 @@ public:
services->setVertexShaderConstant(world.pointer(), 8, 4); services->setVertexShaderConstant(world.pointer(), 8, 4);
} }
private:
IrrlichtDevice *m_device;
}; };
/* /*
@ -266,13 +271,6 @@ public:
ShaderSource(IrrlichtDevice *device); ShaderSource(IrrlichtDevice *device);
~ShaderSource(); ~ShaderSource();
/*
Gets a shader material id from cache or
- if main thread, from getShaderIdDirect
- if other thread, adds to request queue and waits for main thread
*/
u32 getShaderId(const std::string &name);
/* /*
- If shader material specified by name is found from cache, - If shader material specified by name is found from cache,
return the cached id. return the cached id.
@ -280,26 +278,23 @@ public:
The id 0 points to a null shader. Its material is EMT_SOLID. The id 0 points to a null shader. Its material is EMT_SOLID.
*/ */
u32 getShaderIdDirect(const std::string &name); u32 getShaderIdDirect(const std::string &name,
const u8 material_type, const u8 drawtype);
// Finds out the name of a cached shader.
std::string getShaderName(u32 id);
/* /*
If shader specified by the name pointed by the id doesn't If shader specified by the name pointed by the id doesn't
exist, create it, then return the cached shader. exist, create it, then return id.
Can be called from any thread. If called from some other thread Can be called from any thread. If called from some other thread
and not found in cache, the call is queued to the main thread and not found in cache, the call is queued to the main thread
for processing. for processing.
*/ */
ShaderInfo getShader(u32 id);
u32 getShader(const std::string &name,
ShaderInfo getShader(const std::string &name) const u8 material_type, const u8 drawtype);
{
return getShader(getShaderId(name)); ShaderInfo getShaderInfo(u32 id);
}
// Processes queued shader requests from other threads. // Processes queued shader requests from other threads.
// Shall be called from the main thread. // Shall be called from the main thread.
void processQueue(); void processQueue();
@ -337,9 +332,7 @@ private:
// A shader id is index in this array. // A shader id is index in this array.
// The first position contains a dummy shader. // The first position contains a dummy shader.
std::vector<ShaderInfo> m_shaderinfo_cache; std::vector<ShaderInfo> m_shaderinfo_cache;
// Maps a shader name to an index in the former. // The former container is behind this mutex
std::map<std::string, u32> m_name_to_id;
// The two former containers are behind this mutex
JMutex m_shaderinfo_cache_mutex; JMutex m_shaderinfo_cache_mutex;
// Queued shader fetches (to be processed by the main thread) // Queued shader fetches (to be processed by the main thread)
@ -358,7 +351,9 @@ IWritableShaderSource* createShaderSource(IrrlichtDevice *device)
/* /*
Generate shader given the shader name. Generate shader given the shader name.
*/ */
ShaderInfo generate_shader(std::string name, IrrlichtDevice *device, ShaderInfo generate_shader(std::string name,
u8 material_type, u8 drawtype,
IrrlichtDevice *device,
video::IShaderConstantSetCallBack *callback, video::IShaderConstantSetCallBack *callback,
SourceShaderCache *sourcecache); SourceShaderCache *sourcecache);
@ -381,7 +376,6 @@ ShaderSource::ShaderSource(IrrlichtDevice *device):
// Add a dummy ShaderInfo as the first index, named "" // Add a dummy ShaderInfo as the first index, named ""
m_shaderinfo_cache.push_back(ShaderInfo()); m_shaderinfo_cache.push_back(ShaderInfo());
m_name_to_id[""] = 0;
// Add main global constant setter // Add main global constant setter
addGlobalConstantSetter(new MainShaderConstantSetter(device)); addGlobalConstantSetter(new MainShaderConstantSetter(device));
@ -398,28 +392,17 @@ ShaderSource::~ShaderSource()
m_global_setters.clear(); m_global_setters.clear();
} }
u32 ShaderSource::getShaderId(const std::string &name) u32 ShaderSource::getShader(const std::string &name,
const u8 material_type, const u8 drawtype)
{ {
//infostream<<"getShaderId(): \""<<name<<"\""<<std::endl;
{
/*
See if shader already exists
*/
JMutexAutoLock lock(m_shaderinfo_cache_mutex);
std::map<std::string, u32>::iterator n;
n = m_name_to_id.find(name);
if(n != m_name_to_id.end())
return n->second;
}
/* /*
Get shader Get shader
*/ */
if(get_current_thread_id() == m_main_thread){ if(get_current_thread_id() == m_main_thread){
return getShaderIdDirect(name); return getShaderIdDirect(name, material_type, drawtype);
} else { } else {
/*errorstream<<"getShaderId(): Queued: name=\""<<name<<"\""<<std::endl;*/ /*errorstream<<"getShader(): Queued: name=\""<<name<<"\""<<std::endl;*/
// We're gonna ask the result to be put into here // We're gonna ask the result to be put into here
@ -445,7 +428,7 @@ u32 ShaderSource::getShaderId(const std::string &name)
} }
infostream<<"getShaderId(): Failed"<<std::endl; infostream<<"getShader(): Failed"<<std::endl;
return 0; return 0;
} }
@ -453,7 +436,8 @@ u32 ShaderSource::getShaderId(const std::string &name)
/* /*
This method generates all the shaders This method generates all the shaders
*/ */
u32 ShaderSource::getShaderIdDirect(const std::string &name) u32 ShaderSource::getShaderIdDirect(const std::string &name,
const u8 material_type, const u8 drawtype)
{ {
//infostream<<"getShaderIdDirect(): name=\""<<name<<"\""<<std::endl; //infostream<<"getShaderIdDirect(): name=\""<<name<<"\""<<std::endl;
@ -463,6 +447,14 @@ u32 ShaderSource::getShaderIdDirect(const std::string &name)
return 0; return 0;
} }
// Check if already have such instance
for(u32 i=0; i<m_shaderinfo_cache.size(); i++){
ShaderInfo *info = &m_shaderinfo_cache[i];
if(info->name == name && info->material_type == material_type &&
info->drawtype == drawtype)
return i;
}
/* /*
Calling only allowed from main thread Calling only allowed from main thread
*/ */
@ -472,25 +464,7 @@ u32 ShaderSource::getShaderIdDirect(const std::string &name)
return 0; return 0;
} }
/* ShaderInfo info = generate_shader(name, material_type, drawtype, m_device,
See if shader already exists
*/
{
JMutexAutoLock lock(m_shaderinfo_cache_mutex);
std::map<std::string, u32>::iterator n;
n = m_name_to_id.find(name);
if(n != m_name_to_id.end()){
/*infostream<<"getShaderIdDirect(): \""<<name
<<"\" found in cache"<<std::endl;*/
return n->second;
}
}
/*infostream<<"getShaderIdDirect(): \""<<name
<<"\" NOT found in cache. Creating it."<<std::endl;*/
ShaderInfo info = generate_shader(name, m_device,
m_shader_callback, &m_sourcecache); m_shader_callback, &m_sourcecache);
/* /*
@ -501,29 +475,15 @@ u32 ShaderSource::getShaderIdDirect(const std::string &name)
u32 id = m_shaderinfo_cache.size(); u32 id = m_shaderinfo_cache.size();
m_shaderinfo_cache.push_back(info); m_shaderinfo_cache.push_back(info);
m_name_to_id[name] = id;
/*infostream<<"getShaderIdDirect(): " infostream<<"getShaderIdDirect(): "
<<"Returning id="<<id<<" for name \""<<name<<"\""<<std::endl;*/ <<"Returning id="<<id<<" for name \""<<name<<"\""<<std::endl;
return id; return id;
} }
std::string ShaderSource::getShaderName(u32 id)
{
JMutexAutoLock lock(m_shaderinfo_cache_mutex);
if(id >= m_shaderinfo_cache.size()){ ShaderInfo ShaderSource::getShaderInfo(u32 id)
errorstream<<"ShaderSource::getShaderName(): id="<<id
<<" >= m_shaderinfo_cache.size()="
<<m_shaderinfo_cache.size()<<std::endl;
return "";
}
return m_shaderinfo_cache[id].name;
}
ShaderInfo ShaderSource::getShader(u32 id)
{ {
JMutexAutoLock lock(m_shaderinfo_cache_mutex); JMutexAutoLock lock(m_shaderinfo_cache_mutex);
@ -535,21 +495,8 @@ ShaderInfo ShaderSource::getShader(u32 id)
void ShaderSource::processQueue() void ShaderSource::processQueue()
{ {
/*
Fetch shaders
*/
//NOTE this is only thread safe for ONE consumer thread!
if(!m_get_shader_queue.empty()){
GetRequest<std::string, u32, u8, u8>
request = m_get_shader_queue.pop();
/**errorstream<<"ShaderSource::processQueue(): "
<<"got shader request with "
<<"name=\""<<request.key<<"\""
<<std::endl;**/
m_get_shader_queue.pushResult(request,getShaderIdDirect(request.key));
}
} }
void ShaderSource::insertSourceShader(const std::string &name_of_shader, void ShaderSource::insertSourceShader(const std::string &name_of_shader,
@ -582,8 +529,8 @@ void ShaderSource::rebuildShaders()
for(u32 i=0; i<m_shaderinfo_cache.size(); i++){ for(u32 i=0; i<m_shaderinfo_cache.size(); i++){
ShaderInfo *info = &m_shaderinfo_cache[i]; ShaderInfo *info = &m_shaderinfo_cache[i];
if(info->name != ""){ if(info->name != ""){
*info = generate_shader(info->name, m_device, *info = generate_shader(info->name, info->material_type,
m_shader_callback, &m_sourcecache); info->drawtype, m_device, m_shader_callback, &m_sourcecache);
} }
} }
} }
@ -597,29 +544,36 @@ void ShaderSource::onSetConstants(video::IMaterialRendererServices *services,
} }
} }
ShaderInfo generate_shader(std::string name, IrrlichtDevice *device, ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype,
video::IShaderConstantSetCallBack *callback, IrrlichtDevice *device, video::IShaderConstantSetCallBack *callback,
SourceShaderCache *sourcecache) SourceShaderCache *sourcecache)
{ {
/*infostream<<"generate_shader(): "
"\""<<name<<"\""<<std::endl;*/
ShaderInfo shaderinfo; ShaderInfo shaderinfo;
shaderinfo.name = name; shaderinfo.name = name;
shaderinfo.material_type = material_type;
shaderinfo.drawtype = drawtype;
shaderinfo.material = video::EMT_SOLID; shaderinfo.material = video::EMT_SOLID;
switch(material_type){
/* case TILE_MATERIAL_BASIC:
Get the base material shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
*/
std::string base_material_name =
trim(sourcecache->getOrLoad(name, "base.txt"));
for(s32 i = 0; video::sBuiltInMaterialTypeNames[i] != 0; i++){
if(video::sBuiltInMaterialTypeNames[i] == base_material_name){
shaderinfo.material = (video::E_MATERIAL_TYPE) i;
break; break;
} case TILE_MATERIAL_ALPHA:
shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
break;
case TILE_MATERIAL_LIQUID_TRANSPARENT:
shaderinfo.base_material = video::EMT_TRANSPARENT_VERTEX_ALPHA;
break;
case TILE_MATERIAL_LIQUID_OPAQUE:
shaderinfo.base_material = video::EMT_SOLID;
break;
case TILE_MATERIAL_WAVING_LEAVES:
shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
break;
case TILE_MATERIAL_WAVING_PLANTS:
shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
break;
} }
bool enable_shaders = g_settings->getBool("enable_shaders"); bool enable_shaders = g_settings->getBool("enable_shaders");
if(!enable_shaders) if(!enable_shaders)
return shaderinfo; return shaderinfo;
@ -645,7 +599,6 @@ ShaderInfo generate_shader(std::string name, IrrlichtDevice *device,
load_shaders(name, sourcecache, driver->getDriverType(), load_shaders(name, sourcecache, driver->getDriverType(),
enable_shaders, vertex_program, pixel_program, enable_shaders, vertex_program, pixel_program,
geometry_program, is_highlevel); geometry_program, is_highlevel);
// Check hardware/driver support // Check hardware/driver support
if(vertex_program != "" && if(vertex_program != "" &&
!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) && !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) &&
@ -678,6 +631,55 @@ ShaderInfo generate_shader(std::string name, IrrlichtDevice *device,
// Create shaders header // Create shaders header
std::string shaders_header = "#version 120\n"; std::string shaders_header = "#version 120\n";
static const char* drawTypes[] = {
"NDT_NORMAL",
"NDT_AIRLIKE",
"NDT_LIQUID",
"NDT_FLOWINGLIQUID",
"NDT_GLASSLIKE",
"NDT_ALLFACES",
"NDT_ALLFACES_OPTIONAL",
"NDT_TORCHLIKE",
"NDT_SIGNLIKE",
"NDT_PLANTLIKE",
"NDT_FENCELIKE",
"NDT_RAILLIKE",
"NDT_NODEBOX",
"NDT_GLASSLIKE_FRAMED"
};
for (int i = 0; i < 14; i++){
shaders_header += "#define ";
shaders_header += drawTypes[i];
shaders_header += " ";
shaders_header += itos(i);
shaders_header += "\n";
}
static const char* materialTypes[] = {
"TILE_MATERIAL_BASIC",
"TILE_MATERIAL_ALPHA",
"TILE_MATERIAL_LIQUID_TRANSPARENT",
"TILE_MATERIAL_LIQUID_OPAQUE",
"TILE_MATERIAL_WAVING_LEAVES",
"TILE_MATERIAL_WAVING_PLANTS"
};
for (int i = 0; i < 6; i++){
shaders_header += "#define ";
shaders_header += materialTypes[i];
shaders_header += " ";
shaders_header += itos(i);
shaders_header += "\n";
}
shaders_header += "#define MATERIAL_TYPE ";
shaders_header += itos(material_type);
shaders_header += "\n";
shaders_header += "#define DRAW_TYPE ";
shaders_header += itos(drawtype);
shaders_header += "\n";
if (g_settings->getBool("generate_normalmaps")){ if (g_settings->getBool("generate_normalmaps")){
shaders_header += "#define GENERATE_NORMALMAPS\n"; shaders_header += "#define GENERATE_NORMALMAPS\n";
shaders_header += "#define NORMALMAPS_STRENGTH "; shaders_header += "#define NORMALMAPS_STRENGTH ";
@ -721,7 +723,7 @@ ShaderInfo generate_shader(std::string name, IrrlichtDevice *device,
shaders_header += "#define USE_NORMALMAPS\n"; shaders_header += "#define USE_NORMALMAPS\n";
if (g_settings->getBool("enable_waving_water")){ if (g_settings->getBool("enable_waving_water")){
shaders_header += "#define ENABLE_WAVING_WATER\n"; shaders_header += "#define ENABLE_WAVING_WATER 1\n";
shaders_header += "#define WATER_WAVE_HEIGHT "; shaders_header += "#define WATER_WAVE_HEIGHT ";
shaders_header += ftos(g_settings->getFloat("water_wave_height")); shaders_header += ftos(g_settings->getFloat("water_wave_height"));
shaders_header += "\n"; shaders_header += "\n";
@ -731,13 +733,21 @@ ShaderInfo generate_shader(std::string name, IrrlichtDevice *device,
shaders_header += "#define WATER_WAVE_SPEED "; shaders_header += "#define WATER_WAVE_SPEED ";
shaders_header += ftos(g_settings->getFloat("water_wave_speed")); shaders_header += ftos(g_settings->getFloat("water_wave_speed"));
shaders_header += "\n"; shaders_header += "\n";
} else{
shaders_header += "#define ENABLE_WAVING_WATER 0\n";
} }
shaders_header += "#define ENABLE_WAVING_LEAVES ";
if (g_settings->getBool("enable_waving_leaves")) if (g_settings->getBool("enable_waving_leaves"))
shaders_header += "#define ENABLE_WAVING_LEAVES\n"; shaders_header += "1\n";
else
shaders_header += "0\n";
shaders_header += "#define ENABLE_WAVING_PLANTS ";
if (g_settings->getBool("enable_waving_plants")) if (g_settings->getBool("enable_waving_plants"))
shaders_header += "#define ENABLE_WAVING_PLANTS\n"; shaders_header += "1\n";
else
shaders_header += "0\n";
if(pixel_program != "") if(pixel_program != "")
pixel_program = shaders_header + pixel_program; pixel_program = shaders_header + pixel_program;
@ -772,11 +782,10 @@ ShaderInfo generate_shader(std::string name, IrrlichtDevice *device,
scene::EPT_TRIANGLES, // Geometry shader input scene::EPT_TRIANGLES, // Geometry shader input
scene::EPT_TRIANGLE_STRIP, // Geometry shader output scene::EPT_TRIANGLE_STRIP, // Geometry shader output
0, // Support maximum number of vertices 0, // Support maximum number of vertices
callback, // Set-constant callback callback, // Set-constant callback
shaderinfo.material, // Base material shaderinfo.base_material, // Base material
1 // Userdata passed to callback 1 // Userdata passed to callback
); );
if(shadermat == -1){ if(shadermat == -1){
errorstream<<"generate_shader(): " errorstream<<"generate_shader(): "
"failed to generate \""<<name<<"\", " "failed to generate \""<<name<<"\", "
@ -791,7 +800,7 @@ ShaderInfo generate_shader(std::string name, IrrlichtDevice *device,
vertex_program_ptr, // Vertex shader program vertex_program_ptr, // Vertex shader program
pixel_program_ptr, // Pixel shader program pixel_program_ptr, // Pixel shader program
callback, // Set-constant callback callback, // Set-constant callback
shaderinfo.material, // Base material shaderinfo.base_material, // Base material
0 // Userdata passed to callback 0 // Userdata passed to callback
); );

View File

@ -46,9 +46,15 @@ std::string getShaderPath(const std::string &name_of_shader,
struct ShaderInfo struct ShaderInfo
{ {
std::string name; std::string name;
video::E_MATERIAL_TYPE base_material;
video::E_MATERIAL_TYPE material; video::E_MATERIAL_TYPE material;
u8 drawtype;
u8 material_type;
s32 user_data;
ShaderInfo(): name(""), material(video::EMT_SOLID) {} ShaderInfo(): name(""), base_material(video::EMT_SOLID),
material(video::EMT_SOLID),
drawtype(0), material_type(0) {}
virtual ~ShaderInfo() {} virtual ~ShaderInfo() {}
}; };
@ -77,11 +83,11 @@ class IShaderSource
public: public:
IShaderSource(){} IShaderSource(){}
virtual ~IShaderSource(){} virtual ~IShaderSource(){}
virtual u32 getShaderId(const std::string &name){return 0;} virtual u32 getShaderIdDirect(const std::string &name,
virtual u32 getShaderIdDirect(const std::string &name){return 0;} const u8 material_type, const u8 drawtype){return 0;}
virtual std::string getShaderName(u32 id){return "";} virtual ShaderInfo getShaderInfo(u32 id){return ShaderInfo();}
virtual ShaderInfo getShader(u32 id){return ShaderInfo();} virtual u32 getShader(const std::string &name,
virtual ShaderInfo getShader(const std::string &name){return ShaderInfo();} const u8 material_type, const u8 drawtype){return 0;}
}; };
class IWritableShaderSource : public IShaderSource class IWritableShaderSource : public IShaderSource
@ -89,11 +95,11 @@ class IWritableShaderSource : public IShaderSource
public: public:
IWritableShaderSource(){} IWritableShaderSource(){}
virtual ~IWritableShaderSource(){} virtual ~IWritableShaderSource(){}
virtual u32 getShaderId(const std::string &name){return 0;} virtual u32 getShaderIdDirect(const std::string &name,
virtual u32 getShaderIdDirect(const std::string &name){return 0;} const u8 material_type, const u8 drawtype){return 0;}
virtual std::string getShaderName(u32 id){return "";} virtual ShaderInfo getShaderInfo(u32 id){return ShaderInfo();}
virtual ShaderInfo getShader(u32 id){return ShaderInfo();} virtual u32 getShader(const std::string &name,
virtual ShaderInfo getShader(const std::string &name){return ShaderInfo();} const u8 material_type, const u8 drawtype){return 0;}
virtual void processQueue()=0; virtual void processQueue()=0;
virtual void insertSourceShader(const std::string &name_of_shader, virtual void insertSourceShader(const std::string &name_of_shader,

View File

@ -136,8 +136,8 @@ enum MaterialType{
TILE_MATERIAL_ALPHA, TILE_MATERIAL_ALPHA,
TILE_MATERIAL_LIQUID_TRANSPARENT, TILE_MATERIAL_LIQUID_TRANSPARENT,
TILE_MATERIAL_LIQUID_OPAQUE, TILE_MATERIAL_LIQUID_OPAQUE,
TILE_MATERIAL_LEAVES, TILE_MATERIAL_WAVING_LEAVES,
TILE_MATERIAL_PLANTS TILE_MATERIAL_WAVING_PLANTS
}; };
// Material flags // Material flags
@ -167,6 +167,7 @@ struct TileSpec
//0 // <- DEBUG, Use the one below //0 // <- DEBUG, Use the one below
MATERIAL_FLAG_BACKFACE_CULLING MATERIAL_FLAG_BACKFACE_CULLING
), ),
shader_id(0),
animation_frame_count(1), animation_frame_count(1),
animation_frame_length_ms(0), animation_frame_length_ms(0),
rotation(0) rotation(0)
@ -206,42 +207,18 @@ struct TileSpec
case TILE_MATERIAL_LIQUID_OPAQUE: case TILE_MATERIAL_LIQUID_OPAQUE:
material.MaterialType = video::EMT_SOLID; material.MaterialType = video::EMT_SOLID;
break; break;
case TILE_MATERIAL_LEAVES: case TILE_MATERIAL_WAVING_LEAVES:
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
break; break;
case TILE_MATERIAL_PLANTS: case TILE_MATERIAL_WAVING_PLANTS:
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
break; break;
} }
material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) ? true : false; material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) ? true : false;
} }
void applyMaterialOptionsWithShaders(video::SMaterial &material,
const video::E_MATERIAL_TYPE &basic, void applyMaterialOptionsWithShaders(video::SMaterial &material) const
const video::E_MATERIAL_TYPE &liquid,
const video::E_MATERIAL_TYPE &alpha,
const video::E_MATERIAL_TYPE &leaves,
const video::E_MATERIAL_TYPE &plants) const
{ {
switch(material_type){
case TILE_MATERIAL_BASIC:
material.MaterialType = basic;
break;
case TILE_MATERIAL_ALPHA:
material.MaterialType = alpha;
break;
case TILE_MATERIAL_LIQUID_TRANSPARENT:
material.MaterialType = liquid;
break;
case TILE_MATERIAL_LIQUID_OPAQUE:
material.MaterialType = liquid;
break;
case TILE_MATERIAL_LEAVES:
material.MaterialType = leaves;
break;
case TILE_MATERIAL_PLANTS:
material.MaterialType = plants;
break;
}
material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) ? true : false; material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) ? true : false;
} }
@ -252,6 +229,7 @@ struct TileSpec
// Material parameters // Material parameters
u8 material_type; u8 material_type;
u8 material_flags; u8 material_flags;
u32 shader_id;
// Animation parameters // Animation parameters
u8 animation_frame_count; u8 animation_frame_count;
u16 animation_frame_length_ms; u16 animation_frame_length_ms;