diff --git a/build/android/Start.sh b/build/android/Start.sh index 799e2a6e..85ff2ae7 100755 --- a/build/android/Start.sh +++ b/build/android/Start.sh @@ -11,15 +11,14 @@ DEST=$(mktemp -d) echo echo "=> Creating Assets:" -for dir in builtin textures; do - cp -r ../../$dir $DEST/$dir +for dir in builtin textures client; do + cp -r ../../$dir $DEST/ done mkdir -p $DEST/fonts cp ../../fonts/Retron2000.ttf $DEST/fonts/ # no PNG fonts because freetype -#mkdir -p $DEST/media -#cp -r native/deps/Android/Irrlicht/shaders $DEST/media/shaders +cp -r native/deps/Android/Irrlicht/shaders $DEST/client/shaders/Irrlicht echo echo "* Converting locale files:" @@ -36,6 +35,10 @@ for lang in *; do done popd +find $DEST -type d -name '.git' -print0 | xargs -0 -- rm -r +find $DEST -type f -name '.git*' -delete +find $DEST -type f -name '.DS_Store' -delete + # remove broken languages for broken_lang in ja ko he; do find $DEST -type d -name $broken_lang -print0 | xargs -0 -- rm -r diff --git a/build/android/native/jni/Android.mk b/build/android/native/jni/Android.mk index e6fae369..6789442b 100644 --- a/build/android/native/jni/Android.mk +++ b/build/android/native/jni/Android.mk @@ -54,6 +54,7 @@ LOCAL_CFLAGS += \ -DUSE_LEVELDB=1 \ -DUSE_LUAJIT=1 \ -DUSE_GETTEXT=1 \ + -DENABLE_GLES=1 \ $(GPROF_DEF) ifdef NDEBUG diff --git a/build/iOS/assets.sh b/build/iOS/assets.sh index 58cef926..5632332a 100755 --- a/build/iOS/assets.sh +++ b/build/iOS/assets.sh @@ -8,12 +8,11 @@ fi FOLDER=$(pwd) DEST=$(mktemp -d) -for dir in builtin textures; do - cp -r ../../$dir $DEST/$dir +for dir in builtin textures client; do + cp -r ../../$dir $DEST/ done -#mkdir -p $DEST/media -#cp -r deps/irrlicht/shaders $DEST/media/shaders +cp -r deps/irrlicht/shaders $DEST/client/shaders/Irrlicht mkdir -p $DEST/fonts cp ../../fonts/Retron2000.ttf $DEST/fonts/ # no PNG fonts because freetype diff --git a/builtin/mainmenu/tab_settings.lua b/builtin/mainmenu/tab_settings.lua index 851ed798..5656355b 100644 --- a/builtin/mainmenu/tab_settings.lua +++ b/builtin/mainmenu/tab_settings.lua @@ -154,15 +154,18 @@ local function formspec() "box[8,0;3.75,4.5;#999999]" local video_driver = core.settings:get("video_driver") - local shaders_supported = video_driver == "opengl" - local shaders_enabled = false - if shaders_supported then - shaders_enabled = core.settings:get_bool("enable_shaders") + local shaders_enabled = core.settings:get_bool("enable_shaders") + if video_driver == "opengl" then tab_string = tab_string .. "checkbox[8.25,0;cb_shaders;" .. fgettext("Shaders") .. ";" .. tostring(shaders_enabled) .. "]" + elseif video_driver == "ogles2" then + tab_string = tab_string .. + "checkbox[8.25,0;cb_shaders;" .. fgettext("Shaders (experimental)") .. ";" + .. tostring(shaders_enabled) .. "]" else core.settings:set_bool("enable_shaders", false) + shaders_enabled = false tab_string = tab_string .. "label[8.38,0.2;" .. core.colorize("#888888", fgettext("Shaders (unavailable)")) .. "]" diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 5cd2e6ef..10f49943 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -511,7 +511,7 @@ display_gamma (Gamma) float 2.2 1.0 3.0 texture_path (Texture path) path # The rendering back-end for Irrlicht. -video_driver (Video driver) enum opengl null,software,burningsvideo,direct3d8,direct3d9,opengl +video_driver (Video driver) enum opengl null,software,burningsvideo,direct3d8,direct3d9,opengl,ogles1,ogles2 # Height on which clouds are appearing. cloud_height (Cloud height) int 120 diff --git a/client/shaders/default_shader/opengl_fragment.glsl b/client/shaders/default_shader/opengl_fragment.glsl index 925ab6e1..2d34f208 100644 --- a/client/shaders/default_shader/opengl_fragment.glsl +++ b/client/shaders/default_shader/opengl_fragment.glsl @@ -1,4 +1,6 @@ +varying mediump vec4 varColor; + void main(void) { - gl_FragColor = gl_Color; + gl_FragColor = varColor; } diff --git a/client/shaders/default_shader/opengl_vertex.glsl b/client/shaders/default_shader/opengl_vertex.glsl index d0b16c8b..17e98b94 100644 --- a/client/shaders/default_shader/opengl_vertex.glsl +++ b/client/shaders/default_shader/opengl_vertex.glsl @@ -1,9 +1,7 @@ -uniform mat4 mWorldViewProj; +varying mediump vec4 varColor; void main(void) { - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_Position = mWorldViewProj * gl_Vertex; - - gl_FrontColor = gl_BackColor = gl_Color; + gl_Position = mWorldViewProj * inVertexPosition; + varColor = inVertexColor; } diff --git a/client/shaders/minimap_shader/opengl_fragment.glsl b/client/shaders/minimap_shader/opengl_fragment.glsl index fa4f9cb1..21fe7742 100644 --- a/client/shaders/minimap_shader/opengl_fragment.glsl +++ b/client/shaders/minimap_shader/opengl_fragment.glsl @@ -2,9 +2,12 @@ uniform sampler2D baseTexture; uniform sampler2D normalTexture; uniform vec3 yawVec; +varying mediump vec4 varColor; +varying mediump vec2 varTexCoord; + void main (void) { - vec2 uv = gl_TexCoord[0].st; + vec2 uv = varTexCoord.st; //texture sampling rate const float step = 1.0 / 256.0; @@ -27,6 +30,6 @@ void main (void) vec3 color = (1.1 * diffuse + 0.05 * height + 0.5 * specular) * base.rgb; vec4 col = vec4(color.rgb, base.a); - col *= gl_Color; + col *= varColor; gl_FragColor = vec4(col.rgb, base.a); } diff --git a/client/shaders/minimap_shader/opengl_vertex.glsl b/client/shaders/minimap_shader/opengl_vertex.glsl index 88f9356d..e77c7c2b 100644 --- a/client/shaders/minimap_shader/opengl_vertex.glsl +++ b/client/shaders/minimap_shader/opengl_vertex.glsl @@ -1,9 +1,9 @@ -uniform mat4 mWorldViewProj; -uniform mat4 mWorld; +varying mediump vec4 varColor; +varying mediump vec2 varTexCoord; void main(void) { - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_Position = mWorldViewProj * gl_Vertex; - gl_FrontColor = gl_BackColor = gl_Color; + varTexCoord = inTexCoord0.xy; + gl_Position = mWorldViewProj * inVertexPosition; + varColor = inVertexColor; } diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index 7c5b9b61..9484f4b6 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -6,21 +6,14 @@ uniform vec4 skyBgColor; uniform float fogDistance; uniform vec3 eyePosition; -varying vec3 vPosition; -varying vec3 worldPosition; -varying float area_enable_parallax; - -varying vec3 eyeVec; -varying vec3 tsEyeVec; -varying vec3 lightVec; -varying vec3 tsLightVec; - -bool normalTexturePresent = false; +varying mediump vec4 varColor; +varying mediump vec2 varTexCoord; +varying mediump vec3 eyeVec; const float e = 2.718281828459; const float BS = 10.0; const float fogStart = FOG_START; -const float fogShadingParameter = 1 / ( 1 - fogStart); +const float fogShadingParameter = 1.0 / (1.0 - fogStart); #ifdef ENABLE_TONE_MAPPING @@ -54,149 +47,20 @@ vec4 applyToneMapping(vec4 color) } #endif -void get_texture_flags() -{ - vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0)); - if (flags.r > 0.5) { - normalTexturePresent = true; - } -} - -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); - return bump; -} - -float find_intersection(vec2 dp, vec2 ds) -{ - float depth = 1.0; - float best_depth = 0.0; - float size = 0.0625; - for (int i = 0; i < 15; i++) { - depth -= size; - float h = texture2D(normalTexture, dp + ds * depth).a; - if (depth <= h) { - best_depth = depth; - break; - } - } - depth = best_depth; - for (int i = 0; i < 4; i++) { - size *= 0.5; - float h = texture2D(normalTexture,dp + ds * depth).a; - if (depth <= h) { - best_depth = depth; - depth += size; - } else { - depth -= size; - } - } - return best_depth; -} - -float find_intersectionRGB(vec2 dp, vec2 ds) -{ - const float depth_step = 1.0 / 24.0; - float depth = 1.0; - for (int i = 0 ; i < 24 ; i++) { - float h = get_rgb_height(dp + ds * depth); - if (h >= depth) - break; - depth -= depth_step; - } - return depth; -} - void main(void) { vec3 color; vec4 bump; - vec2 uv = gl_TexCoord[0].st; + vec2 uv = varTexCoord.st; bool use_normalmap = false; - get_texture_flags(); -#ifdef ENABLE_PARALLAX_OCCLUSION - vec2 eyeRay = vec2 (tsEyeVec.x, -tsEyeVec.y); - const float scale = PARALLAX_OCCLUSION_SCALE / PARALLAX_OCCLUSION_ITERATIONS; - const float bias = PARALLAX_OCCLUSION_BIAS / PARALLAX_OCCLUSION_ITERATIONS; - -#if PARALLAX_OCCLUSION_MODE == 0 - // Parallax occlusion with slope information - if (normalTexturePresent && area_enable_parallax > 0.0) { - for (int i = 0; i < PARALLAX_OCCLUSION_ITERATIONS; i++) { - vec4 normal = texture2D(normalTexture, uv.xy); - float h = normal.a * scale - bias; - uv += h * normal.z * eyeRay; - } -#endif - -#if PARALLAX_OCCLUSION_MODE == 1 - // Relief mapping - if (normalTexturePresent && area_enable_parallax > 0.0) { - vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE; - float dist = find_intersection(uv, ds); - uv += dist * ds; -#endif - } else if (GENERATE_NORMALMAPS == 1 && area_enable_parallax > 0.0) { - vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE; - float dist = find_intersectionRGB(uv, ds); - uv += dist * ds; - } -#endif - -#if USE_NORMALMAPS == 1 - if (normalTexturePresent) { - bump = get_normal_map(uv); - use_normalmap = true; - } -#endif - -#if GENERATE_NORMALMAPS == 1 - if (normalTexturePresent == 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), 1.0); - float diffuse = dot(-E,bump.xyz); - color = (diffuse + 0.1 * specular) * base.rgb; - } else { - color = base.rgb; - } -#else - color = base.rgb; +#ifdef USE_DISCARD + if (base.a == 0.0) + discard; #endif + vec4 col = vec4(base.rgb * varColor.rgb, 1.0); - vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0); - #ifdef ENABLE_TONE_MAPPING col = applyToneMapping(col); #endif diff --git a/client/shaders/nodes_shader/opengl_vertex.glsl b/client/shaders/nodes_shader/opengl_vertex.glsl index 3ac79c26..826c24c2 100644 --- a/client/shaders/nodes_shader/opengl_vertex.glsl +++ b/client/shaders/nodes_shader/opengl_vertex.glsl @@ -1,19 +1,11 @@ -uniform mat4 mWorldViewProj; -uniform mat4 mWorld; - // Color of the light emitted by the sun. +uniform highp mat4 mWorld; uniform vec3 dayLight; -uniform vec3 eyePosition; uniform float animationTimer; -varying vec3 vPosition; -varying vec3 worldPosition; - -varying vec3 eyeVec; -varying vec3 lightVec; -varying vec3 tsEyeVec; -varying vec3 tsLightVec; -varying float area_enable_parallax; +varying mediump vec4 varColor; +varying mediump vec2 varTexCoord; +varying mediump vec3 eyeVec; // Color of the light emitted by the light sources. const vec3 artificialLight = vec3(1.04, 1.04, 1.04); @@ -41,24 +33,15 @@ float smoothTriangleWave(float x) void main(void) { - gl_TexCoord[0] = gl_MultiTexCoord0; + varTexCoord = inTexCoord0.xy; //TODO: make offset depending on view angle and parallax uv displacement //thats for textures that doesnt align vertically, like dirt with grass - //gl_TexCoord[0].y += 0.008; - - //Allow parallax/relief mapping only for certain kind of nodes - //Variable is also used to control area of the effect -#if (DRAW_TYPE == NDT_NORMAL || DRAW_TYPE == NDT_LIQUID || DRAW_TYPE == NDT_FLOWINGLIQUID) - area_enable_parallax = 1.0; -#else - area_enable_parallax = 0.0; -#endif - + //varTexCoord.y += 0.008; float disp_x; float disp_z; #if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES) || (MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS) - vec4 pos2 = mWorld * gl_Vertex; + vec4 pos2 = mWorld * inVertexPosition; float tOffset = (pos2.x + pos2.y) * 0.001 + pos2.z * 0.002; disp_x = (smoothTriangleWave(animationTimer * 23.0 + tOffset) + smoothTriangleWave(animationTimer * 11.0 + tOffset)) * 0.4; @@ -69,58 +52,29 @@ float disp_z; #if (MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE) && ENABLE_WAVING_WATER - vec4 pos = gl_Vertex; + vec4 pos = inVertexPosition; pos.y -= 2.0; float posYbuf = (pos.z / WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH); pos.y -= sin(posYbuf) * WATER_WAVE_HEIGHT + sin(posYbuf / 7.0) * WATER_WAVE_HEIGHT; gl_Position = mWorldViewProj * pos; #elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES - vec4 pos = gl_Vertex; + vec4 pos = inVertexPosition; pos.x += disp_x; pos.y += disp_z * 0.1; pos.z += disp_z; gl_Position = mWorldViewProj * pos; #elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS - vec4 pos = gl_Vertex; - if (gl_TexCoord[0].y < 0.05) { + vec4 pos = inVertexPosition; + if (varTexCoord.y < 0.05) { pos.x += disp_x; pos.z += disp_z; } gl_Position = mWorldViewProj * pos; #else - gl_Position = mWorldViewProj * gl_Vertex; + gl_Position = mWorldViewProj * inVertexPosition; #endif - - vPosition = gl_Position.xyz; - worldPosition = (mWorld * gl_Vertex).xyz; - - // Don't generate heightmaps when too far from the eye - float dist = distance (vec3(0.0, 0.0, 0.0), vPosition); - if (dist > 150.0) { - area_enable_parallax = 0.0; - } - - vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0); - - vec3 normal, tangent, binormal; - normal = normalize(gl_NormalMatrix * gl_Normal); - tangent = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz); - binormal = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz); - - vec3 v; - - lightVec = sunPosition - worldPosition; - v.x = dot(lightVec, tangent); - v.y = dot(lightVec, binormal); - v.z = dot(lightVec, normal); - tsLightVec = normalize (v); - - eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz; - v.x = dot(eyeVec, tangent); - v.y = dot(eyeVec, binormal); - v.z = dot(eyeVec, normal); - tsEyeVec = normalize (v); + eyeVec = -(mWorldView * inVertexPosition).xyz; // Calculate color. // Red, green and blue components are pre-multiplied with @@ -129,16 +83,16 @@ float disp_z; // The pre-baked colors are halved to prevent overflow. vec4 color; // The alpha gives the ratio of sunlight in the incoming light. - float nightRatio = 1 - gl_Color.a; - color.rgb = gl_Color.rgb * (gl_Color.a * dayLight.rgb + - nightRatio * artificialLight.rgb) * 2; - color.a = 1; + float nightRatio = 1.0 - inVertexColor.a; + color.rgb = inVertexColor.rgb * (inVertexColor.a * dayLight.rgb + + nightRatio * artificialLight.rgb) * 2.0; + color.a = 1.0; // Emphase blue a bit in darker places // See C++ implementation in mapblock_mesh.cpp finalColorBlend() - float brightness = (color.r + color.g + color.b) / 3; + float brightness = (color.r + color.g + color.b) / 3.0; color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) + 0.07 * brightness); - gl_FrontColor = gl_BackColor = clamp(color, 0.0, 1.0); + varColor = clamp(color, 0.0, 1.0); } diff --git a/client/shaders/selection_shader/opengl_fragment.glsl b/client/shaders/selection_shader/opengl_fragment.glsl index c679d0e1..977394aa 100644 --- a/client/shaders/selection_shader/opengl_fragment.glsl +++ b/client/shaders/selection_shader/opengl_fragment.glsl @@ -1,9 +1,12 @@ uniform sampler2D baseTexture; +varying mediump vec4 varColor; +varying mediump vec2 varTexCoord; + void main(void) { - vec2 uv = gl_TexCoord[0].st; + vec2 uv = varTexCoord.st; vec4 color = texture2D(baseTexture, uv); - color.rgb *= gl_Color.rgb; + color.rgb *= varColor.rgb; gl_FragColor = color; } diff --git a/client/shaders/selection_shader/opengl_vertex.glsl b/client/shaders/selection_shader/opengl_vertex.glsl index d0b16c8b..e77c7c2b 100644 --- a/client/shaders/selection_shader/opengl_vertex.glsl +++ b/client/shaders/selection_shader/opengl_vertex.glsl @@ -1,9 +1,9 @@ -uniform mat4 mWorldViewProj; +varying mediump vec4 varColor; +varying mediump vec2 varTexCoord; void main(void) { - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_Position = mWorldViewProj * gl_Vertex; - - gl_FrontColor = gl_BackColor = gl_Color; + varTexCoord = inTexCoord0.xy; + gl_Position = mWorldViewProj * inVertexPosition; + varColor = inVertexColor; } diff --git a/client/shaders/wielded_shader/opengl_fragment.glsl b/client/shaders/wielded_shader/opengl_fragment.glsl index 546aef71..f926dcff 100644 --- a/client/shaders/wielded_shader/opengl_fragment.glsl +++ b/client/shaders/wielded_shader/opengl_fragment.glsl @@ -6,11 +6,9 @@ uniform vec4 skyBgColor; uniform float fogDistance; uniform vec3 eyePosition; -varying vec3 vPosition; -varying vec3 worldPosition; - -varying vec3 eyeVec; -varying vec3 lightVec; +varying mediump vec4 varColor; +varying mediump vec2 varTexCoord; +varying mediump vec3 eyeVec; bool normalTexturePresent = false; bool texTileableHorizontal = false; @@ -20,96 +18,19 @@ bool texSeamless = false; const float e = 2.718281828459; const float BS = 10.0; const float fogStart = FOG_START; -const float fogShadingParameter = 1 / ( 1 - fogStart); - -void get_texture_flags() -{ - vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0)); - if (flags.r > 0.5) { - normalTexturePresent = true; - } - if (flags.g > 0.5) { - texTileableHorizontal = true; - } - if (flags.b > 0.5) { - texTileableVertical = true; - } - if (texTileableHorizontal && texTileableVertical) { - texSeamless = true; - } -} - -float intensity(vec3 color) -{ - return (color.r + color.g + color.b) / 3.0; -} - -float get_rgb_height(vec2 uv) -{ - if (texSeamless) { - return intensity(texture2D(baseTexture, uv).rgb); - } else { - return intensity(texture2D(baseTexture, clamp(uv, 0.0, 0.999)).rgb); - } -} - -vec4 get_normal_map(vec2 uv) -{ - vec4 bump = texture2D(normalTexture, uv).rgba; - bump.xyz = normalize(bump.xyz * 2.0 - 1.0); - return bump; -} +const float fogShadingParameter = 1.0 / (1.0 - fogStart); void main(void) { - vec3 color; - vec4 bump; - vec2 uv = gl_TexCoord[0].st; - bool use_normalmap = false; - get_texture_flags(); - -#if USE_NORMALMAPS == 1 - if (normalTexturePresent) { - bump = get_normal_map(uv); - use_normalmap = true; - } -#endif - -#if GENERATE_NORMALMAPS == 1 - if (normalTexturePresent == 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 + vec2 uv = varTexCoord.st; 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), 1.0); - float diffuse = dot(-E,bump.xyz); - color = (diffuse + 0.1 * specular) * base.rgb; - } else { - color = base.rgb; - } -#else - color = base.rgb; +#ifdef USE_DISCARD + if (base.a == 0.0) + discard; #endif - - vec4 col = vec4(color.rgb, base.a); - col *= gl_Color; + vec4 col = base; + col *= varColor; // Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?), // the fog will only be rendered correctly if the last operation before the // clamp() is an addition. Else, the clamp() seems to be ignored. diff --git a/client/shaders/wielded_shader/opengl_vertex.glsl b/client/shaders/wielded_shader/opengl_vertex.glsl index 9f05b833..d6bd39aa 100644 --- a/client/shaders/wielded_shader/opengl_vertex.glsl +++ b/client/shaders/wielded_shader/opengl_vertex.glsl @@ -1,32 +1,16 @@ -uniform mat4 mWorldViewProj; -uniform mat4 mWorld; +uniform highp mat4 mWorld; -uniform vec3 eyePosition; -uniform float animationTimer; - -varying vec3 vPosition; -varying vec3 worldPosition; - -varying vec3 eyeVec; -varying vec3 lightVec; -varying vec3 tsEyeVec; -varying vec3 tsLightVec; +varying mediump vec4 varColor; +varying mediump vec2 varTexCoord; +varying mediump vec3 eyeVec; const float e = 2.718281828459; 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); - - lightVec = sunPosition - worldPosition; - eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz; - - gl_FrontColor = gl_BackColor = gl_Color; + varTexCoord = inTexCoord0.xy; + gl_Position = mWorldViewProj * inVertexPosition; + eyeVec = -(mWorldView * inVertexPosition).xyz; + varColor = inVertexColor; } diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp index 0c024fcb..aa31d40e 100644 --- a/src/client/clientlauncher.cpp +++ b/src/client/clientlauncher.cpp @@ -591,7 +591,7 @@ bool ClientLauncher::create_engine_device() params.PrivateData = porting::app_global; #endif params.OGLES2ShaderPath = std::string(porting::path_share + DIR_DELIM + - "media" + DIR_DELIM + "shaders" + DIR_DELIM).c_str(); + "client" + DIR_DELIM + "shaders" + DIR_DELIM + "Irrlicht" + DIR_DELIM).c_str(); #endif device = createDeviceEx(params); diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 8b7c96a1..84386302 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -804,11 +804,12 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc else if (waving == 2) special_material = TILE_MATERIAL_WAVING_LEAVES; } + u32 special_shader = shdsrc->getShader("nodes_shader", special_material, drawtype); // Special tiles (fill in f->special_tiles[]) for (u16 j = 0; j < CF_SPECIAL_COUNT; j++) { fillTileAttribs(tsrc, &special_tiles[j].layers[0], &tdef_spec[j], - tile_shader, tsettings.use_normal_texture, + special_shader, tsettings.use_normal_texture, tdef_spec[j].backface_culling, special_material); } diff --git a/src/shader.cpp b/src/shader.cpp index b59063cc..b5af7196 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "gamedef.h" #include "client/tile.h" +#include "config.h" /* A cache from shader name to shader path @@ -208,13 +209,19 @@ public: class MainShaderConstantSetter : public IShaderConstantSetter { - CachedVertexShaderSetting m_world_view_proj; CachedVertexShaderSetting m_world; +#if ENABLE_GLES + CachedVertexShaderSetting m_world_view; + CachedVertexShaderSetting m_world_view_proj; +#endif public: - MainShaderConstantSetter() : - m_world_view_proj("mWorldViewProj"), - m_world("mWorld") + MainShaderConstantSetter() + : m_world("mWorld") +#if ENABLE_GLES + , m_world_view_proj("mWorldViewProj") + , m_world_view("mWorldView") +#endif {} ~MainShaderConstantSetter() {} @@ -224,23 +231,16 @@ public: video::IVideoDriver *driver = services->getVideoDriver(); sanity_check(driver); - // Set clip matrix - core::matrix4 worldViewProj; - worldViewProj = driver->getTransform(video::ETS_PROJECTION); - worldViewProj *= driver->getTransform(video::ETS_VIEW); - worldViewProj *= driver->getTransform(video::ETS_WORLD); - if (is_highlevel) - m_world_view_proj.set(*reinterpret_cast(worldViewProj.pointer()), services); - else - services->setVertexShaderConstant(worldViewProj.pointer(), 0, 4); - // Set world matrix core::matrix4 world = driver->getTransform(video::ETS_WORLD); - if (is_highlevel) - m_world.set(*reinterpret_cast(world.pointer()), services); - else - services->setVertexShaderConstant(world.pointer(), 4, 4); + m_world.set(*reinterpret_cast(world.pointer()), services); +#if ENABLE_GLES + core::matrix4 worldView = driver->getTransform(video::ETS_VIEW) * world; + core::matrix4 worldViewProj = driver->getTransform(video::ETS_PROJECTION) * worldView; + m_world_view_proj.set(*reinterpret_cast(worldViewProj.pointer()), services); + m_world_view.set(*reinterpret_cast(worldView.pointer()), services); +#endif } }; @@ -341,7 +341,7 @@ IWritableShaderSource* createShaderSource(IrrlichtDevice *device) Generate shader given the shader name. */ ShaderInfo generate_shader(const std::string &name, - u8 material_type, u8 drawtype, + int material_type, int drawtype, IrrlichtDevice *device, std::vector &callbacks, const std::vector &setter_factories, SourceShaderCache *sourcecache); @@ -349,10 +349,9 @@ ShaderInfo generate_shader(const std::string &name, /* Load shader programs */ -void load_shaders(std::string name, SourceShaderCache *sourcecache, - video::E_DRIVER_TYPE drivertype, bool enable_shaders, - std::string &vertex_program, std::string &pixel_program, - std::string &geometry_program, bool &is_highlevel); +bool load_shaders(std::string name, SourceShaderCache *sourcecache, + video::E_DRIVER_TYPE drivertype, + std::string &vertex_program, std::string &pixel_program); ShaderSource::ShaderSource(IrrlichtDevice *device): m_device(device) @@ -525,7 +524,7 @@ void ShaderSource::rebuildShaders() } -ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtype, +ShaderInfo generate_shader(const std::string &name, int material_type, int drawtype, IrrlichtDevice *device, std::vector &callbacks, const std::vector &setter_factories, SourceShaderCache *sourcecache) @@ -571,11 +570,9 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp // Then load shaders std::string vertex_program; std::string pixel_program; - std::string geometry_program; - bool is_highlevel; - load_shaders(name, sourcecache, driver->getDriverType(), - enable_shaders, vertex_program, pixel_program, - geometry_program, is_highlevel); + if (!load_shaders(name, sourcecache, driver->getDriverType(), vertex_program, pixel_program)) + return shaderinfo; + // Check hardware/driver support if(vertex_program != "" && !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) && @@ -593,20 +590,46 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp <queryFeature(video::EVDF_GEOMETRY_SHADER)){ - infostream<<"generate_shader(): geometry shaders disabled " - "because of missing driver/hardware support." - <getDriverType() == video::EDT_OGLES2; +#endif + std::string shaders_header, vertex_header, pixel_header; // geometry shaders aren’t supported in GLES<3 + if (use_gles) { + shaders_header = + "#version 100\n" + ; + vertex_header = R"( + uniform highp mat4 mWorldView; + uniform highp mat4 mWorldViewProj; + + attribute highp vec4 inVertexPosition; + attribute lowp vec4 inVertexColor; + attribute mediump vec4 inTexCoord0; + )"; + pixel_header = R"( + precision mediump float; + )"; + if (shaderinfo.base_material != video::EMT_SOLID) + pixel_header += "#define USE_DISCARD\n"; + } else { + shaders_header = R"( + #version 120 + #define lowp + #define mediump + #define highp + )"; + vertex_header = R"( + #define mWorldView gl_ModelViewMatrix + #define mWorldViewProj gl_ModelViewProjectionMatrix + + #define inVertexPosition gl_Vertex + #define inVertexColor gl_Color + #define inTexCoord0 gl_MultiTexCoord0 + )"; + } static const char* drawTypes[] = { "NDT_NORMAL", @@ -632,7 +655,7 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaders_header += "#define "; shaders_header += drawTypes[i]; shaders_header += " "; - shaders_header += itos(i); + shaders_header += std::to_string(i); shaders_header += "\n"; } @@ -650,15 +673,15 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaders_header += "#define "; shaders_header += materialTypes[i]; shaders_header += " "; - shaders_header += itos(i); + shaders_header += std::to_string(i); shaders_header += "\n"; } shaders_header += "#define MATERIAL_TYPE "; - shaders_header += itos(material_type); + shaders_header += std::to_string(material_type); shaders_header += "\n"; shaders_header += "#define DRAW_TYPE "; - shaders_header += itos(drawtype); + shaders_header += std::to_string(drawtype); shaders_header += "\n"; if (g_settings->getBool("generate_normalmaps")) { @@ -667,7 +690,7 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaders_header += "#define GENERATE_NORMALMAPS 0\n"; } shaders_header += "#define NORMALMAPS_STRENGTH "; - shaders_header += ftos(g_settings->getFloat("normalmaps_strength")); + shaders_header += std::to_string(g_settings->getFloat("normalmaps_strength")); shaders_header += "\n"; float sample_step; int smooth = (int)g_settings->getFloat("normalmaps_smooth"); @@ -686,7 +709,7 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp break; } shaders_header += "#define SAMPLE_STEP "; - shaders_header += ftos(sample_step); + shaders_header += std::to_string(sample_step); shaders_header += "\n"; if (g_settings->getBool("enable_bumpmapping")) @@ -699,16 +722,16 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp int iterations = g_settings->getFloat("parallax_occlusion_iterations"); shaders_header += "#define ENABLE_PARALLAX_OCCLUSION\n"; shaders_header += "#define PARALLAX_OCCLUSION_MODE "; - shaders_header += itos(mode); + shaders_header += std::to_string(mode); shaders_header += "\n"; shaders_header += "#define PARALLAX_OCCLUSION_SCALE "; - shaders_header += ftos(scale); + shaders_header += std::to_string(scale); shaders_header += "\n"; shaders_header += "#define PARALLAX_OCCLUSION_BIAS "; - shaders_header += ftos(bias); + shaders_header += std::to_string(bias); shaders_header += "\n"; shaders_header += "#define PARALLAX_OCCLUSION_ITERATIONS "; - shaders_header += itos(iterations); + shaders_header += std::to_string(iterations); shaders_header += "\n"; } @@ -721,13 +744,13 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp if (g_settings->getBool("enable_waving_water")){ shaders_header += "#define ENABLE_WAVING_WATER 1\n"; shaders_header += "#define WATER_WAVE_HEIGHT "; - shaders_header += ftos(g_settings->getFloat("water_wave_height")); + shaders_header += std::to_string(g_settings->getFloat("water_wave_height")); shaders_header += "\n"; shaders_header += "#define WATER_WAVE_LENGTH "; - shaders_header += ftos(g_settings->getFloat("water_wave_length")); + shaders_header += std::to_string(g_settings->getFloat("water_wave_length")); shaders_header += "\n"; shaders_header += "#define WATER_WAVE_SPEED "; - shaders_header += ftos(g_settings->getFloat("water_wave_speed")); + shaders_header += std::to_string(g_settings->getFloat("water_wave_speed")); shaders_header += "\n"; } else{ shaders_header += "#define ENABLE_WAVING_WATER 0\n"; @@ -749,7 +772,7 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaders_header += "#define ENABLE_TONE_MAPPING\n"; shaders_header += "#define FOG_START "; - shaders_header += ftos(rangelim(g_settings->getFloat("fog_start"), 0.0f, 0.99f)); + shaders_header += std::to_string(rangelim(g_settings->getFloat("fog_start"), 0.0f, 0.99f)); shaders_header += "\n"; // Call addHighLevelShaderMaterial() or addShaderMaterial() @@ -757,70 +780,43 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp const c8* pixel_program_ptr = 0; const c8* geometry_program_ptr = 0; if (!vertex_program.empty()) { - vertex_program = shaders_header + vertex_program; + vertex_program = shaders_header + vertex_header + vertex_program; vertex_program_ptr = vertex_program.c_str(); } if (!pixel_program.empty()) { - pixel_program = shaders_header + pixel_program; + pixel_program = shaders_header + pixel_header + pixel_program; pixel_program_ptr = pixel_program.c_str(); } - if (!geometry_program.empty()) { - geometry_program = shaders_header + geometry_program; - geometry_program_ptr = geometry_program.c_str(); - } ShaderCallback *cb = new ShaderCallback(setter_factories); s32 shadermat = -1; - if(is_highlevel){ - infostream<<"Compiling high level shaders for "<addHighLevelShaderMaterial( - vertex_program_ptr, // Vertex shader program - "vertexMain", // Vertex shader entry point - video::EVST_VS_1_1, // Vertex shader version - pixel_program_ptr, // Pixel shader program - "pixelMain", // Pixel shader entry point - video::EPST_PS_1_2, // Pixel shader version - geometry_program_ptr, // Geometry shader program - "geometryMain", // Geometry shader entry point - video::EGST_GS_4_0, // Geometry shader version - scene::EPT_TRIANGLES, // Geometry shader input - scene::EPT_TRIANGLE_STRIP, // Geometry shader output - 0, // Support maximum number of vertices - cb, // Set-constant callback - shaderinfo.base_material, // Base material - 1 // Userdata passed to callback - ); - if(shadermat == -1){ - errorstream<<"generate_shader(): " - "failed to generate \""<addShaderMaterial( - vertex_program_ptr, // Vertex shader program - pixel_program_ptr, // Pixel shader program - cb, // Set-constant callback - shaderinfo.base_material, // Base material - 0 // Userdata passed to callback - ); - if(shadermat == -1){ - errorstream<<"generate_shader(): " - "failed to generate \""<addHighLevelShaderMaterial( + vertex_program_ptr, // Vertex shader program + "vertexMain", // Vertex shader entry point + video::EVST_VS_1_1, // Vertex shader version + pixel_program_ptr, // Pixel shader program + "pixelMain", // Pixel shader entry point + video::EPST_PS_1_2, // Pixel shader version + geometry_program_ptr, // Geometry shader program + "geometryMain", // Geometry shader entry point + video::EGST_GS_4_0, // Geometry shader version + scene::EPT_TRIANGLES, // Geometry shader input + scene::EPT_TRIANGLE_STRIP, // Geometry shader output + 0, // Support maximum number of vertices + cb, // Set-constant callback + shaderinfo.base_material, // Base material + 1 // Userdata passed to callback + ); + if(shadermat == -1){ + errorstream<<"generate_shader(): " + "failed to generate \""<getOrLoad(name, "d3d9.hlsl"); - pixel_program = vertex_program; - geometry_program = vertex_program; - } - else if(drivertype == video::EDT_OPENGL){ - // OpenGL: GLSL - vertex_program = sourcecache->getOrLoad(name, "opengl_vertex.glsl"); - pixel_program = sourcecache->getOrLoad(name, "opengl_fragment.glsl"); - geometry_program = sourcecache->getOrLoad(name, "opengl_geometry.glsl"); - } - if(vertex_program != "" || pixel_program != "" || geometry_program != ""){ - is_highlevel = true; - return; - } + switch (drivertype) { + case video::EDT_OPENGL: +#if ENABLE_GLES + case video::EDT_OGLES2: +#endif + // OpenGL: GLSL + vertex_program = sourcecache->getOrLoad(name, "opengl_vertex.glsl"); + pixel_program = sourcecache->getOrLoad(name, "opengl_fragment.glsl"); + break; + default: + return false; } - + return !vertex_program.empty() && !pixel_program.empty(); } void dumpShaderProgram(std::ostream &output_stream,