From a53163660f435860250cd2150d54d1dd6930408e Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Tue, 23 Dec 2014 18:33:33 +0100 Subject: [PATCH] Shader: Refine preprocessing on GLES platform Don't globally set float precision to mediump, only fragment shaders need that and defining it for vertex shaders causes tilemap cracks. Also manually define low precision for variables that hold color / alpha values. --- CMakeLists.txt | 1 + mkxp.pro | 1 + shader/bitmapBlit.frag | 2 +- shader/blur.frag | 2 +- shader/common.h | 15 ++++++++++++ shader/flashMap.frag | 4 ++-- shader/plane.frag | 8 +++---- shader/simpleAlpha.frag | 2 +- shader/simpleColor.frag | 2 +- shader/simpleColor.vert | 4 ++-- shader/simpleMatrix.vert | 4 ++-- shader/sprite.frag | 10 ++++---- shader/trans.frag | 2 +- src/shader.cpp | 52 +++++++++++++++++++++++----------------- 14 files changed, 67 insertions(+), 42 deletions(-) create mode 100644 shader/common.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e5cd77c..9fb0284 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -210,6 +210,7 @@ source_group("MKXP Source" FILES ${MAIN_SOURCE} ${MAIN_HEADERS}) ## Setup embedded source ## set(EMBEDDED_INPUT + shader/common.h shader/transSimple.frag shader/trans.frag shader/hue.frag diff --git a/mkxp.pro b/mkxp.pro index f21f264..0753a8a 100644 --- a/mkxp.pro +++ b/mkxp.pro @@ -183,6 +183,7 @@ SOURCES += \ src/fluid-fun.cpp EMBED = \ + shader/common.h \ shader/transSimple.frag \ shader/trans.frag \ shader/hue.frag \ diff --git a/shader/bitmapBlit.frag b/shader/bitmapBlit.frag index 18be173..850b919 100644 --- a/shader/bitmapBlit.frag +++ b/shader/bitmapBlit.frag @@ -6,7 +6,7 @@ uniform sampler2D destination; uniform vec4 subRect; -uniform float opacity; +uniform lowp float opacity; varying vec2 v_texCoord; diff --git a/shader/blur.frag b/shader/blur.frag index 0fb7c46..3b8fe48 100644 --- a/shader/blur.frag +++ b/shader/blur.frag @@ -6,7 +6,7 @@ varying vec2 v_blurCoord[2]; void main() { - vec4 frag = vec4(0, 0, 0, 0); + lowp vec4 frag = vec4(0, 0, 0, 0); frag += texture2D(texture, v_texCoord); frag += texture2D(texture, v_blurCoord[0]); diff --git a/shader/common.h b/shader/common.h new file mode 100644 index 0000000..a34ef54 --- /dev/null +++ b/shader/common.h @@ -0,0 +1,15 @@ +#ifdef GLSLES + +#ifdef FRAGMENT_SHADER +/* Only the fragment shader has no default float precision */ +precision mediump float; +#endif + +#else + +/* Desktop GLSL doesn't know about these */ +#define highp +#define mediump +#define lowp + +#endif diff --git a/shader/flashMap.frag b/shader/flashMap.frag index c065b77..34ed06b 100644 --- a/shader/flashMap.frag +++ b/shader/flashMap.frag @@ -1,7 +1,7 @@ -uniform float alpha; +uniform lowp float alpha; -varying vec4 v_color; +varying lowp vec4 v_color; void main() { diff --git a/shader/plane.frag b/shader/plane.frag index 7364d10..14b52c5 100644 --- a/shader/plane.frag +++ b/shader/plane.frag @@ -1,11 +1,11 @@ uniform sampler2D texture; -uniform vec4 tone; +uniform lowp vec4 tone; -uniform float opacity; -uniform vec4 color; -uniform vec4 flash; +uniform lowp float opacity; +uniform lowp vec4 color; +uniform lowp vec4 flash; varying vec2 v_texCoord; diff --git a/shader/simpleAlpha.frag b/shader/simpleAlpha.frag index 4214e2b..163bca9 100644 --- a/shader/simpleAlpha.frag +++ b/shader/simpleAlpha.frag @@ -2,7 +2,7 @@ uniform sampler2D texture; varying vec2 v_texCoord; -varying vec4 v_color; +varying lowp vec4 v_color; void main() { diff --git a/shader/simpleColor.frag b/shader/simpleColor.frag index 3e0dcba..da3a77f 100644 --- a/shader/simpleColor.frag +++ b/shader/simpleColor.frag @@ -1,5 +1,5 @@ -varying vec4 v_color; +varying lowp vec4 v_color; void main() { diff --git a/shader/simpleColor.vert b/shader/simpleColor.vert index 837cd1b..aed5cad 100644 --- a/shader/simpleColor.vert +++ b/shader/simpleColor.vert @@ -6,10 +6,10 @@ uniform vec2 translation; attribute vec2 position; attribute vec2 texCoord; -attribute vec4 color; +attribute lowp vec4 color; varying vec2 v_texCoord; -varying vec4 v_color; +varying lowp vec4 v_color; void main() { diff --git a/shader/simpleMatrix.vert b/shader/simpleMatrix.vert index 23287cb..d439dbd 100644 --- a/shader/simpleMatrix.vert +++ b/shader/simpleMatrix.vert @@ -6,10 +6,10 @@ uniform vec2 texSizeInv; attribute vec2 position; attribute vec2 texCoord; -attribute vec4 color; +attribute lowp vec4 color; varying vec2 v_texCoord; -varying vec4 v_color; +varying lowp vec4 v_color; void main() { diff --git a/shader/sprite.frag b/shader/sprite.frag index ab50876..93c35f3 100644 --- a/shader/sprite.frag +++ b/shader/sprite.frag @@ -1,13 +1,13 @@ uniform sampler2D texture; -uniform vec4 tone; +uniform lowp vec4 tone; -uniform float opacity; -uniform vec4 color; +uniform lowp float opacity; +uniform lowp vec4 color; uniform float bushDepth; -uniform float bushOpacity; +uniform lowp float bushOpacity; varying vec2 v_texCoord; @@ -32,7 +32,7 @@ void main() frag.rgb = mix(frag.rgb, color.rgb, color.a); /* Apply bush alpha by mathematical if */ - float underBush = float(v_texCoord.y < bushDepth); + lowp float underBush = float(v_texCoord.y < bushDepth); frag.a *= clamp(bushOpacity + underBush, 0.0, 1.0); gl_FragColor = frag; diff --git a/shader/trans.frag b/shader/trans.frag index 8f2cdd7..9023aed 100644 --- a/shader/trans.frag +++ b/shader/trans.frag @@ -14,7 +14,7 @@ void main() { float transV = texture2D(transMap, v_texCoord).r; float cTransV = clamp(transV, prog, prog+vague); - float alpha = (cTransV - prog) / vague; + lowp float alpha = (cTransV - prog) / vague; vec4 newFrag = texture2D(currentScene, v_texCoord); vec4 oldFrag = texture2D(frozenScene, v_texCoord); diff --git a/src/shader.cpp b/src/shader.cpp index 3cd4261..a31e376 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -28,6 +28,7 @@ #include #include +#include "common.h.xxd" #include "sprite.frag.xxd" #include "hue.frag.xxd" #include "trans.frag.xxd" @@ -106,32 +107,39 @@ void Shader::unbind() glState.program.set(0); } -static const char *glesHeader = "precision mediump float;\n"; -static const size_t glesHeaderSize = strlen(glesHeader); - -static void setupShaderSource(GLuint shader, - const unsigned char *src, int srcSize) +static void setupShaderSource(GLuint shader, GLenum type, + const unsigned char *body, int bodySize) { - GLuint shaderSrcN; - const GLchar *shaderSrc[2]; - GLint shaderSrcSize[2]; + static const char glesDefine[] = "#define GLSLES\n"; + static const char fragDefine[] = "#define FRAGMENT_SHADER\n"; + + const GLchar *shaderSrc[4]; + GLint shaderSrcSize[4]; + size_t i = 0; if (gl.glsles) { - shaderSrcN = 2; - shaderSrc[0] = glesHeader; - shaderSrc[1] = (const GLchar*) src; - shaderSrcSize[0] = glesHeaderSize; - shaderSrcSize[1] = srcSize; - } - else - { - shaderSrcN = 1; - shaderSrc[0] = (const GLchar*) src; - shaderSrcSize[0] = srcSize; + shaderSrc[i] = glesDefine; + shaderSrcSize[i] = sizeof(glesDefine)-1; + ++i; } - gl.ShaderSource(shader, shaderSrcN, shaderSrc, shaderSrcSize); + if (type == GL_FRAGMENT_SHADER) + { + shaderSrc[i] = fragDefine; + shaderSrcSize[i] = sizeof(fragDefine)-1; + ++i; + } + + shaderSrc[i] = (const GLchar*) shader_common_h; + shaderSrcSize[i] = shader_common_h_len; + ++i; + + shaderSrc[i] = (const GLchar*) body; + shaderSrcSize[i] = bodySize; + ++i; + + gl.ShaderSource(shader, i, shaderSrc, shaderSrcSize); } void Shader::init(const unsigned char *vert, int vertSize, @@ -142,7 +150,7 @@ void Shader::init(const unsigned char *vert, int vertSize, GLint success; /* Compile vertex shader */ - setupShaderSource(vertShader, vert, vertSize); + setupShaderSource(vertShader, GL_VERTEX_SHADER, vert, vertSize); gl.CompileShader(vertShader); gl.GetShaderiv(vertShader, GL_COMPILE_STATUS, &success); @@ -156,7 +164,7 @@ void Shader::init(const unsigned char *vert, int vertSize, } /* Compile fragment shader */ - setupShaderSource(fragShader, frag, fragSize); + setupShaderSource(fragShader, GL_FRAGMENT_SHADER, frag, fragSize); gl.CompileShader(fragShader); gl.GetShaderiv(fragShader, GL_COMPILE_STATUS, &success);