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.
This commit is contained in:
Jonas Kulla 2014-12-23 18:33:33 +01:00
parent a501e4f22f
commit a53163660f
14 changed files with 67 additions and 42 deletions

View File

@ -210,6 +210,7 @@ source_group("MKXP Source" FILES ${MAIN_SOURCE} ${MAIN_HEADERS})
## Setup embedded source ## ## Setup embedded source ##
set(EMBEDDED_INPUT set(EMBEDDED_INPUT
shader/common.h
shader/transSimple.frag shader/transSimple.frag
shader/trans.frag shader/trans.frag
shader/hue.frag shader/hue.frag

View File

@ -183,6 +183,7 @@ SOURCES += \
src/fluid-fun.cpp src/fluid-fun.cpp
EMBED = \ EMBED = \
shader/common.h \
shader/transSimple.frag \ shader/transSimple.frag \
shader/trans.frag \ shader/trans.frag \
shader/hue.frag \ shader/hue.frag \

View File

@ -6,7 +6,7 @@ uniform sampler2D destination;
uniform vec4 subRect; uniform vec4 subRect;
uniform float opacity; uniform lowp float opacity;
varying vec2 v_texCoord; varying vec2 v_texCoord;

View File

@ -6,7 +6,7 @@ varying vec2 v_blurCoord[2];
void main() 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_texCoord);
frag += texture2D(texture, v_blurCoord[0]); frag += texture2D(texture, v_blurCoord[0]);

15
shader/common.h Normal file
View File

@ -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

View File

@ -1,7 +1,7 @@
uniform float alpha; uniform lowp float alpha;
varying vec4 v_color; varying lowp vec4 v_color;
void main() void main()
{ {

View File

@ -1,11 +1,11 @@
uniform sampler2D texture; uniform sampler2D texture;
uniform vec4 tone; uniform lowp vec4 tone;
uniform float opacity; uniform lowp float opacity;
uniform vec4 color; uniform lowp vec4 color;
uniform vec4 flash; uniform lowp vec4 flash;
varying vec2 v_texCoord; varying vec2 v_texCoord;

View File

@ -2,7 +2,7 @@
uniform sampler2D texture; uniform sampler2D texture;
varying vec2 v_texCoord; varying vec2 v_texCoord;
varying vec4 v_color; varying lowp vec4 v_color;
void main() void main()
{ {

View File

@ -1,5 +1,5 @@
varying vec4 v_color; varying lowp vec4 v_color;
void main() void main()
{ {

View File

@ -6,10 +6,10 @@ uniform vec2 translation;
attribute vec2 position; attribute vec2 position;
attribute vec2 texCoord; attribute vec2 texCoord;
attribute vec4 color; attribute lowp vec4 color;
varying vec2 v_texCoord; varying vec2 v_texCoord;
varying vec4 v_color; varying lowp vec4 v_color;
void main() void main()
{ {

View File

@ -6,10 +6,10 @@ uniform vec2 texSizeInv;
attribute vec2 position; attribute vec2 position;
attribute vec2 texCoord; attribute vec2 texCoord;
attribute vec4 color; attribute lowp vec4 color;
varying vec2 v_texCoord; varying vec2 v_texCoord;
varying vec4 v_color; varying lowp vec4 v_color;
void main() void main()
{ {

View File

@ -1,13 +1,13 @@
uniform sampler2D texture; uniform sampler2D texture;
uniform vec4 tone; uniform lowp vec4 tone;
uniform float opacity; uniform lowp float opacity;
uniform vec4 color; uniform lowp vec4 color;
uniform float bushDepth; uniform float bushDepth;
uniform float bushOpacity; uniform lowp float bushOpacity;
varying vec2 v_texCoord; varying vec2 v_texCoord;
@ -32,7 +32,7 @@ void main()
frag.rgb = mix(frag.rgb, color.rgb, color.a); frag.rgb = mix(frag.rgb, color.rgb, color.a);
/* Apply bush alpha by mathematical if */ /* 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); frag.a *= clamp(bushOpacity + underBush, 0.0, 1.0);
gl_FragColor = frag; gl_FragColor = frag;

View File

@ -14,7 +14,7 @@ void main()
{ {
float transV = texture2D(transMap, v_texCoord).r; float transV = texture2D(transMap, v_texCoord).r;
float cTransV = clamp(transV, prog, prog+vague); 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 newFrag = texture2D(currentScene, v_texCoord);
vec4 oldFrag = texture2D(frozenScene, v_texCoord); vec4 oldFrag = texture2D(frozenScene, v_texCoord);

View File

@ -28,6 +28,7 @@
#include <string.h> #include <string.h>
#include <iostream> #include <iostream>
#include "common.h.xxd"
#include "sprite.frag.xxd" #include "sprite.frag.xxd"
#include "hue.frag.xxd" #include "hue.frag.xxd"
#include "trans.frag.xxd" #include "trans.frag.xxd"
@ -106,32 +107,39 @@ void Shader::unbind()
glState.program.set(0); glState.program.set(0);
} }
static const char *glesHeader = "precision mediump float;\n"; static void setupShaderSource(GLuint shader, GLenum type,
static const size_t glesHeaderSize = strlen(glesHeader); const unsigned char *body, int bodySize)
static void setupShaderSource(GLuint shader,
const unsigned char *src, int srcSize)
{ {
GLuint shaderSrcN; static const char glesDefine[] = "#define GLSLES\n";
const GLchar *shaderSrc[2]; static const char fragDefine[] = "#define FRAGMENT_SHADER\n";
GLint shaderSrcSize[2];
const GLchar *shaderSrc[4];
GLint shaderSrcSize[4];
size_t i = 0;
if (gl.glsles) if (gl.glsles)
{ {
shaderSrcN = 2; shaderSrc[i] = glesDefine;
shaderSrc[0] = glesHeader; shaderSrcSize[i] = sizeof(glesDefine)-1;
shaderSrc[1] = (const GLchar*) src; ++i;
shaderSrcSize[0] = glesHeaderSize;
shaderSrcSize[1] = srcSize;
}
else
{
shaderSrcN = 1;
shaderSrc[0] = (const GLchar*) src;
shaderSrcSize[0] = srcSize;
} }
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, void Shader::init(const unsigned char *vert, int vertSize,
@ -142,7 +150,7 @@ void Shader::init(const unsigned char *vert, int vertSize,
GLint success; GLint success;
/* Compile vertex shader */ /* Compile vertex shader */
setupShaderSource(vertShader, vert, vertSize); setupShaderSource(vertShader, GL_VERTEX_SHADER, vert, vertSize);
gl.CompileShader(vertShader); gl.CompileShader(vertShader);
gl.GetShaderiv(vertShader, GL_COMPILE_STATUS, &success); gl.GetShaderiv(vertShader, GL_COMPILE_STATUS, &success);
@ -156,7 +164,7 @@ void Shader::init(const unsigned char *vert, int vertSize,
} }
/* Compile fragment shader */ /* Compile fragment shader */
setupShaderSource(fragShader, frag, fragSize); setupShaderSource(fragShader, GL_FRAGMENT_SHADER, frag, fragSize);
gl.CompileShader(fragShader); gl.CompileShader(fragShader);
gl.GetShaderiv(fragShader, GL_COMPILE_STATUS, &success); gl.GetShaderiv(fragShader, GL_COMPILE_STATUS, &success);