From 2d6ca321022793fcc5a294ae700b904e5495aca0 Mon Sep 17 00:00:00 2001 From: aap Date: Thu, 14 May 2020 11:54:20 +0200 Subject: [PATCH] made gl3 UBOs optional; also tried other snake oil --- src/gl/gl2_shaders/Makefile | 7 +- src/gl/gl2_shaders/header.frag | 13 ++ src/gl/gl2_shaders/header_fs.inc | 15 ++ src/gl/gl2_shaders/matfx_env.frag | 25 +--- src/gl/gl2_shaders/matfx_gl2.inc | 25 +--- src/gl/gl2_shaders/simple.frag | 26 +--- src/gl/gl2_shaders/simple_fs_gl2.inc | 26 +--- src/gl/gl3device.cpp | 208 +++++++++++---------------- src/gl/gl3immed.cpp | 38 +++-- src/gl/gl3matfx.cpp | 2 +- src/gl/gl3shader.cpp | 4 +- src/gl/gl3skin.cpp | 2 +- src/gl/rwgl3.h | 1 + src/gl/shaders/Makefile | 7 +- src/gl/shaders/default.vert | 24 +--- src/gl/shaders/default_vs_gl3.inc | 24 +--- src/gl/shaders/header.frag | 28 ++++ src/gl/shaders/header.vert | 124 +++++++++------- src/gl/shaders/header_fs.inc | 30 ++++ src/gl/shaders/header_vs.inc | 124 +++++++++------- src/gl/shaders/matfx_env.frag | 25 +--- src/gl/shaders/matfx_env.vert | 24 +--- src/gl/shaders/matfx_gl3.inc | 49 +------ src/gl/shaders/simple.frag | 25 +--- src/gl/shaders/simple_fs_gl3.inc | 25 +--- src/gl/shaders/skin.vert | 28 +--- src/gl/shaders/skin_gl3.inc | 28 +--- 27 files changed, 374 insertions(+), 583 deletions(-) create mode 100644 src/gl/gl2_shaders/header.frag create mode 100644 src/gl/gl2_shaders/header_fs.inc create mode 100644 src/gl/shaders/header.frag create mode 100644 src/gl/shaders/header_fs.inc diff --git a/src/gl/gl2_shaders/Makefile b/src/gl/gl2_shaders/Makefile index e41d382..76d83a5 100644 --- a/src/gl/gl2_shaders/Makefile +++ b/src/gl/gl2_shaders/Makefile @@ -1,10 +1,15 @@ -all: header_vs.inc im2d_gl2.inc im3d_gl2.inc default_vs_gl2.inc simple_fs_gl2.inc matfx_gl2.inc skin_gl2.inc +all: header_vs.inc header_fs.inc im2d_gl2.inc im3d_gl2.inc default_vs_gl2.inc simple_fs_gl2.inc matfx_gl2.inc skin_gl2.inc header_vs.inc: header.vert (echo 'const char *header_vert_src =';\ sed 's/..*/"&\\n"/' header.vert;\ echo ';') >header_vs.inc +header_fs.inc: header.frag + (echo 'const char *header_frag_src =';\ + sed 's/..*/"&\\n"/' header.frag;\ + echo ';') >header_fs.inc + im2d_gl2.inc: im2d.vert (echo 'const char *im2d_vert_src =';\ sed 's/..*/"&\\n"/' im2d.vert;\ diff --git a/src/gl/gl2_shaders/header.frag b/src/gl/gl2_shaders/header.frag new file mode 100644 index 0000000..fa2ef02 --- /dev/null +++ b/src/gl/gl2_shaders/header.frag @@ -0,0 +1,13 @@ +uniform vec2 u_alphaRef; + +uniform float u_fogStart; +uniform float u_fogEnd; +uniform float u_fogRange; +uniform float u_fogDisable; +uniform vec4 u_fogColor; + +void DoAlphaTest(float a) +{ + if(a < u_alphaRef.x || a >= u_alphaRef.y) + discard; +} diff --git a/src/gl/gl2_shaders/header_fs.inc b/src/gl/gl2_shaders/header_fs.inc new file mode 100644 index 0000000..05b7604 --- /dev/null +++ b/src/gl/gl2_shaders/header_fs.inc @@ -0,0 +1,15 @@ +const char *header_frag_src = +"uniform vec2 u_alphaRef;\n" + +"uniform float u_fogStart;\n" +"uniform float u_fogEnd;\n" +"uniform float u_fogRange;\n" +"uniform float u_fogDisable;\n" +"uniform vec4 u_fogColor;\n" + +"void DoAlphaTest(float a)\n" +"{\n" +" if(a < u_alphaRef.x || a >= u_alphaRef.y)\n" +" discard;\n" +"}\n" +; diff --git a/src/gl/gl2_shaders/matfx_env.frag b/src/gl/gl2_shaders/matfx_env.frag index ae6de8e..ecba24f 100644 --- a/src/gl/gl2_shaders/matfx_env.frag +++ b/src/gl/gl2_shaders/matfx_env.frag @@ -1,11 +1,3 @@ -uniform vec2 u_alphaRef; - -uniform float u_fogStart; -uniform float u_fogEnd; -uniform float u_fogRange; -uniform float u_fogDisable; -uniform vec4 u_fogColor; - uniform sampler2D tex0; uniform sampler2D tex1; @@ -34,22 +26,7 @@ main(void) color.rgb = pass1.rgb*pass1.a + pass2.rgb; color.a = pass1.a; - if(color.a < u_alphaRef.x || color.a >= u_alphaRef.y) - discard; -/* - switch(u_alphaTest){ - default: - case 0: break; - case 1: - if(color.a < u_alphaRef) - discard; - break; - case 2: - if(color.a >= u_alphaRef) - discard; - break; - } -*/ + DoAlphaTest(color.a); gl_FragColor = color; } diff --git a/src/gl/gl2_shaders/matfx_gl2.inc b/src/gl/gl2_shaders/matfx_gl2.inc index 8915392..5e18644 100644 --- a/src/gl/gl2_shaders/matfx_gl2.inc +++ b/src/gl/gl2_shaders/matfx_gl2.inc @@ -31,14 +31,6 @@ const char *matfx_env_vert_src = "}\n" ; const char *matfx_env_frag_src = -"uniform vec2 u_alphaRef;\n" - -"uniform float u_fogStart;\n" -"uniform float u_fogEnd;\n" -"uniform float u_fogRange;\n" -"uniform float u_fogDisable;\n" -"uniform vec4 u_fogColor;\n" - "uniform sampler2D tex0;\n" "uniform sampler2D tex1;\n" @@ -67,22 +59,7 @@ const char *matfx_env_frag_src = " color.rgb = pass1.rgb*pass1.a + pass2.rgb;\n" " color.a = pass1.a;\n" -" if(color.a < u_alphaRef.x || color.a >= u_alphaRef.y)\n" -" discard;\n" -"/*\n" -" switch(u_alphaTest){\n" -" default:\n" -" case 0: break;\n" -" case 1:\n" -" if(color.a < u_alphaRef)\n" -" discard;\n" -" break;\n" -" case 2:\n" -" if(color.a >= u_alphaRef)\n" -" discard;\n" -" break;\n" -" }\n" -"*/\n" +" DoAlphaTest(color.a);\n" " gl_FragColor = color;\n" "}\n" diff --git a/src/gl/gl2_shaders/simple.frag b/src/gl/gl2_shaders/simple.frag index 2c5a359..becbbf7 100644 --- a/src/gl/gl2_shaders/simple.frag +++ b/src/gl/gl2_shaders/simple.frag @@ -1,11 +1,3 @@ -uniform vec2 u_alphaRef; - -uniform float u_fogStart; -uniform float u_fogEnd; -uniform float u_fogRange; -uniform float u_fogDisable; -uniform vec4 u_fogColor; - uniform sampler2D tex0; varying vec4 v_color; @@ -18,23 +10,7 @@ main(void) vec4 color; color = v_color*texture2D(tex0, vec2(v_tex0.x, 1.0-v_tex0.y)); color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog); - if(color.a < u_alphaRef.x || color.a >= u_alphaRef.y) - discard; -/* - switch(u_alphaTest){ - default: - case 0: break; - case 1: - if(color.a < u_alphaRef) - discard; - break; - case 2: - if(color.a >= u_alphaRef) - discard; - break; - } -*/ - + DoAlphaTest(color.a); gl_FragColor = color; } diff --git a/src/gl/gl2_shaders/simple_fs_gl2.inc b/src/gl/gl2_shaders/simple_fs_gl2.inc index 413a2c9..3e95645 100644 --- a/src/gl/gl2_shaders/simple_fs_gl2.inc +++ b/src/gl/gl2_shaders/simple_fs_gl2.inc @@ -1,12 +1,4 @@ const char *simple_frag_src = -"uniform vec2 u_alphaRef;\n" - -"uniform float u_fogStart;\n" -"uniform float u_fogEnd;\n" -"uniform float u_fogRange;\n" -"uniform float u_fogDisable;\n" -"uniform vec4 u_fogColor;\n" - "uniform sampler2D tex0;\n" "varying vec4 v_color;\n" @@ -19,23 +11,7 @@ const char *simple_frag_src = " vec4 color;\n" " color = v_color*texture2D(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n" " color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n" -" if(color.a < u_alphaRef.x || color.a >= u_alphaRef.y)\n" -" discard;\n" -"/*\n" -" switch(u_alphaTest){\n" -" default:\n" -" case 0: break;\n" -" case 1:\n" -" if(color.a < u_alphaRef)\n" -" discard;\n" -" break;\n" -" case 2:\n" -" if(color.a >= u_alphaRef)\n" -" discard;\n" -" break;\n" -" }\n" -"*/\n" - +" DoAlphaTest(color.a);\n" " gl_FragColor = color;\n" "}\n" diff --git a/src/gl/gl3device.cpp b/src/gl/gl3device.cpp index 228c5a7..3c78366 100644 --- a/src/gl/gl3device.cpp +++ b/src/gl/gl3device.cpp @@ -58,10 +58,13 @@ struct GlGlobals const char *winTitle; } glGlobals; +int32 alphaFunc; +float32 alphaRef; + struct UniformState { - int32 alphaFunc; - float32 alphaRef; + float32 alphaRefLow; + float32 alphaRefHigh; float32 fogStart; float32 fogEnd; @@ -78,35 +81,23 @@ struct UniformScene float32 view[16]; }; -struct UniformLight -{ - float32 enabled, radius, minusCosAngle, hardSpot; - V3d position; int32 pad0; - V3d direction; int32 pad1; - RGBAf color; -}; - #define MAX_LIGHTS 8 struct UniformObject { RawMatrix world; RGBAf ambLight; - UniformLight directLights[MAX_LIGHTS]; - UniformLight pointLights[MAX_LIGHTS]; - UniformLight spotLights[MAX_LIGHTS]; + struct { + float type; + float radius; + float minusCosAngle; + float hardSpot; + } lightParams[MAX_LIGHTS]; + V4d lightPosition[MAX_LIGHTS]; + V4d lightDirection[MAX_LIGHTS]; + RGBAf lightColor[MAX_LIGHTS]; }; -struct { - float type; - float radius; - float minusCosAngle; - float hardSpot; -} lightParams[MAX_LIGHTS]; -V4d lightPosition[MAX_LIGHTS]; -V4d lightDirection[MAX_LIGHTS]; -RGBAf lightColor[MAX_LIGHTS]; - const char *shaderDecl330 = "#version 330\n"; const char *shaderDecl100es = "#version 100\n"\ @@ -125,8 +116,13 @@ const char *shaderDecl = shaderDecl100es; const char *shaderDecl = shaderDecl330; #endif +// this needs a define in the shaders as well! +//#define RW_GL_USE_UBOS + #ifndef RW_GLES2 static GLuint vao; +#endif +#ifdef RW_GL_USE_UBOS static GLuint ubo_state, ubo_scene, ubo_object; #endif static GLuint whitetex; @@ -134,7 +130,7 @@ static UniformState uniformState; static UniformScene uniformScene; static UniformObject uniformObject; -#ifdef RW_GLES2 +#ifndef RW_GL_USE_UBOS // State int32 u_alphaRef; int32 u_fogStart; @@ -271,8 +267,8 @@ setAlphaTest(bool32 enable) if(rwStateCache.alphaTestEnable != enable){ rwStateCache.alphaTestEnable = enable; shaderfunc = rwStateCache.alphaTestEnable ? rwStateCache.alphaFunc : ALPHAALWAYS; - if(uniformState.alphaFunc != shaderfunc){ - uniformState.alphaFunc = shaderfunc; + if(alphaFunc != shaderfunc){ + alphaFunc = shaderfunc; stateDirty = 1; } } @@ -285,8 +281,8 @@ setAlphaTestFunction(uint32 function) if(rwStateCache.alphaFunc != function){ rwStateCache.alphaFunc = function; shaderfunc = rwStateCache.alphaTestEnable ? rwStateCache.alphaFunc : ALPHAALWAYS; - if(uniformState.alphaFunc != shaderfunc){ - uniformState.alphaFunc = shaderfunc; + if(alphaFunc != shaderfunc){ + alphaFunc = shaderfunc; stateDirty = 1; } } @@ -560,8 +556,8 @@ setRenderState(int32 state, void *pvalue) setAlphaTestFunction(value); break; case ALPHATESTREF: - if(uniformState.alphaRef != value/255.0f){ - uniformState.alphaRef = value/255.0f; + if(alphaRef != value/255.0f){ + alphaRef = value/255.0f; stateDirty = 1; } break; @@ -627,7 +623,7 @@ getRenderState(int32 state) val = rwStateCache.alphaFunc; break; case ALPHATESTREF: - val = (uint32)(uniformState.alphaRef*255.0f); + val = (uint32)(alphaRef*255.0f); break; case GSALPHATEST: val = rwStateCache.gsalpha; @@ -645,8 +641,8 @@ static void resetRenderState(void) { rwStateCache.alphaFunc = ALPHAGREATEREQUAL; - uniformState.alphaFunc = 0; - uniformState.alphaRef = 10.0f/255.0f; + alphaFunc = 0; + alphaRef = 10.0f/255.0f; uniformState.fogDisable = 1.0f; uniformState.fogStart = 0.0f; uniformState.fogEnd = 0.0f; @@ -694,62 +690,6 @@ setWorldMatrix(Matrix *mat) int32 setLights(WorldLights *lightData) { -#ifndef RW_GLES2 - int i, np, ns; - Light *l; - int32 bits; - - uniformObject.ambLight = lightData->ambient; - memset(uniformObject.directLights, 0, sizeof(uniformObject.directLights)); - memset(uniformObject.pointLights, 0, sizeof(uniformObject.pointLights)); - memset(uniformObject.spotLights, 0, sizeof(uniformObject.spotLights)); - - bits = 0; - - for(i = 0; i < lightData->numDirectionals && i < 8; i++){ - l = lightData->directionals[i]; - uniformObject.directLights[i].enabled = 1.0f; - uniformObject.directLights[i].color = l->color; - uniformObject.directLights[i].direction = l->getFrame()->getLTM()->at; - bits |= VSLIGHT_POINT; - } - - np = 0; - ns = 0; - for(i = 0; i < lightData->numLocals; i++){ - l = lightData->locals[i]; - switch(l->getType()){ - case Light::POINT: - if(np >= 8) - continue; - uniformObject.pointLights[np].enabled = 1.0f; - uniformObject.pointLights[np].color = l->color; - uniformObject.pointLights[np].position = l->getFrame()->getLTM()->pos; - uniformObject.pointLights[np].radius = l->radius; - np++; - bits |= VSLIGHT_POINT; - break; - - case Light::SPOT: - case Light::SOFTSPOT: - if(np >= 8) - continue; - uniformObject.spotLights[ns].enabled = 1.0f; - uniformObject.spotLights[ns].color = l->color; - uniformObject.spotLights[ns].position = l->getFrame()->getLTM()->pos; - uniformObject.spotLights[ns].direction = l->getFrame()->getLTM()->at; - uniformObject.spotLights[ns].radius = l->radius; - uniformObject.spotLights[ns].minusCosAngle = l->minusCosAngle; - if(l->getType() == Light::SOFTSPOT) - uniformObject.spotLights[ns].hardSpot = 0.0f; - else - uniformObject.spotLights[ns].hardSpot = 1.0f; - ns++; - bits |= VSLIGHT_SPOT; - break; - } - } -#else int i, n; Light *l; int32 bits; @@ -764,9 +704,9 @@ setLights(WorldLights *lightData) n = 0; for(i = 0; i < lightData->numDirectionals && i < 8; i++){ l = lightData->directionals[i]; - lightParams[n].type = 1.0f; - lightColor[n] = l->color; - memcpy(&lightDirection[n], &l->getFrame()->getLTM()->at, sizeof(V3d)); + uniformObject.lightParams[n].type = 1.0f; + uniformObject.lightColor[n] = l->color; + memcpy(&uniformObject.lightDirection[n], &l->getFrame()->getLTM()->at, sizeof(V3d)); bits |= VSLIGHT_POINT; n++; if(n >= MAX_LIGHTS) @@ -778,10 +718,10 @@ setLights(WorldLights *lightData) switch(l->getType()){ case Light::POINT: - lightParams[n].type = 2.0f; - lightParams[n].radius = l->radius; - lightColor[n] = l->color; - memcpy(&lightPosition[n], &l->getFrame()->getLTM()->pos, sizeof(V3d)); + uniformObject.lightParams[n].type = 2.0f; + uniformObject.lightParams[n].radius = l->radius; + uniformObject.lightColor[n] = l->color; + memcpy(&uniformObject.lightPosition[n], &l->getFrame()->getLTM()->pos, sizeof(V3d)); bits |= VSLIGHT_POINT; n++; if(n >= MAX_LIGHTS) @@ -789,17 +729,17 @@ setLights(WorldLights *lightData) break; case Light::SPOT: case Light::SOFTSPOT: - lightParams[n].type = 3.0f; - lightParams[n].minusCosAngle = l->minusCosAngle; - lightParams[n].radius = l->radius; - lightColor[n] = l->color; - memcpy(&lightPosition[n], &l->getFrame()->getLTM()->pos, sizeof(V3d)); - memcpy(&lightDirection[n], &l->getFrame()->getLTM()->at, sizeof(V3d)); + uniformObject.lightParams[n].type = 3.0f; + uniformObject.lightParams[n].minusCosAngle = l->minusCosAngle; + uniformObject.lightParams[n].radius = l->radius; + uniformObject.lightColor[n] = l->color; + memcpy(&uniformObject.lightPosition[n], &l->getFrame()->getLTM()->pos, sizeof(V3d)); + memcpy(&uniformObject.lightDirection[n], &l->getFrame()->getLTM()->at, sizeof(V3d)); // lower bound of falloff if(l->getType() == Light::SOFTSPOT) - lightParams[n].hardSpot = 0.0f; + uniformObject.lightParams[n].hardSpot = 0.0f; else - lightParams[n].hardSpot = 1.0f; + uniformObject.lightParams[n].hardSpot = 1.0f; bits |= VSLIGHT_SPOT; n++; if(n >= MAX_LIGHTS) @@ -808,9 +748,8 @@ setLights(WorldLights *lightData) } } - lightParams[n].type = 0.0f; + uniformObject.lightParams[n].type = 0.0f; out: -#endif objectDirty = 1; return bits; } @@ -834,10 +773,10 @@ Shader *lastShaderUploaded; void flushCache(void) { -#ifdef RW_GLES2 +#ifndef RW_GL_USE_UBOS #define U(i) currentShader->uniformLocations[i] - // TODO: this is probably a stupid way to do it with gl2 + // TODO: this is probably a stupid way to do it without UBOs if(lastShaderUploaded != currentShader){ lastShaderUploaded = currentShader; objectDirty = 1; @@ -848,10 +787,10 @@ flushCache(void) if(objectDirty){ glUniformMatrix4fv(U(u_world), 1, 0, (float*)&uniformObject.world); glUniform4fv(U(u_ambLight), 1, (float*)&uniformObject.ambLight); - glUniform4fv(U(u_lightParams), MAX_LIGHTS, (float*)lightParams); - glUniform4fv(U(u_lightPosition), MAX_LIGHTS, (float*)lightPosition); - glUniform4fv(U(u_lightDirection), MAX_LIGHTS, (float*)lightDirection); - glUniform4fv(U(u_lightColor), MAX_LIGHTS, (float*)lightColor); + glUniform4fv(U(u_lightParams), MAX_LIGHTS, (float*)uniformObject.lightParams); + glUniform4fv(U(u_lightPosition), MAX_LIGHTS, (float*)uniformObject.lightPosition); + glUniform4fv(U(u_lightDirection), MAX_LIGHTS, (float*)uniformObject.lightDirection); + glUniform4fv(U(u_lightColor), MAX_LIGHTS, (float*)uniformObject.lightColor); objectDirty = 0; } @@ -867,16 +806,16 @@ flushCache(void) uniformState.fogEnd = rwStateCache.fogEnd; uniformState.fogRange = 1.0f/(rwStateCache.fogStart - rwStateCache.fogEnd); - switch(uniformState.alphaFunc){ + switch(alphaFunc){ case ALPHAALWAYS: default: glUniform2f(U(u_alphaRef), -1000.0f, 1000.0f); break; case ALPHAGREATEREQUAL: - glUniform2f(U(u_alphaRef), uniformState.alphaRef, 1000.0f); + glUniform2f(U(u_alphaRef), alphaRef, 1000.0f); break; case ALPHALESS: - glUniform2f(U(u_alphaRef), -1000.0f, uniformState.alphaRef); + glUniform2f(U(u_alphaRef), -1000.0f, alphaRef); break; } @@ -890,24 +829,39 @@ flushCache(void) #else if(objectDirty){ glBindBuffer(GL_UNIFORM_BUFFER, ubo_object); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformObject), - &uniformObject); + glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformObject), nil, GL_STREAM_DRAW); + glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformObject), &uniformObject, GL_STREAM_DRAW); objectDirty = 0; } if(sceneDirty){ glBindBuffer(GL_UNIFORM_BUFFER, ubo_scene); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformScene), - &uniformScene); + glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformScene), nil, GL_STREAM_DRAW); + glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformScene), &uniformScene, GL_STREAM_DRAW); sceneDirty = 0; } if(stateDirty){ + switch(alphaFunc){ + case ALPHAALWAYS: + default: + uniformState.alphaRefLow = -1000.0f; + uniformState.alphaRefHigh = 1000.0f; + break; + case ALPHAGREATEREQUAL: + uniformState.alphaRefLow = alphaRef; + uniformState.alphaRefHigh = 1000.0f; + break; + case ALPHALESS: + uniformState.alphaRefLow = -1000.0f; + uniformState.alphaRefHigh = alphaRef; + break; + } uniformState.fogDisable = rwStateCache.fogEnable ? 0.0f : 1.0f; uniformState.fogStart = rwStateCache.fogStart; uniformState.fogEnd = rwStateCache.fogEnd; uniformState.fogRange = 1.0f/(rwStateCache.fogStart - rwStateCache.fogEnd); glBindBuffer(GL_UNIFORM_BUFFER, ubo_state); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformState), - &uniformState); + glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformState), nil, GL_STREAM_DRAW); + glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformState), &uniformState, GL_STREAM_DRAW); stateDirty = 0; } #endif @@ -1283,7 +1237,7 @@ stopGLFW(void) static int initOpenGL(void) { -#ifdef RW_GLES2 +#ifndef RW_GL_USE_UBOS u_alphaRef = registerUniform("u_alphaRef"); u_fogStart = registerUniform("u_fogStart"); u_fogEnd = registerUniform("u_fogEnd"); @@ -1322,26 +1276,28 @@ initOpenGL(void) #ifndef RW_GLES2 glGenVertexArrays(1, &vao); glBindVertexArray(vao); +#endif +#ifdef RW_GL_USE_UBOS glGenBuffers(1, &ubo_state); glBindBuffer(GL_UNIFORM_BUFFER, ubo_state); glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("State"), ubo_state); glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformState), &uniformState, - GL_DYNAMIC_DRAW); + GL_STREAM_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); glGenBuffers(1, &ubo_scene); glBindBuffer(GL_UNIFORM_BUFFER, ubo_scene); glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("Scene"), ubo_scene); glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformScene), &uniformScene, - GL_DYNAMIC_DRAW); + GL_STREAM_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); glGenBuffers(1, &ubo_object); glBindBuffer(GL_UNIFORM_BUFFER, ubo_object); glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("Object"), ubo_object); glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformObject), &uniformObject, - GL_DYNAMIC_DRAW); + GL_STREAM_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); #endif @@ -1353,7 +1309,7 @@ initOpenGL(void) #include "shaders/simple_fs_gl3.inc" #endif const char *vs[] = { shaderDecl, header_vert_src, default_vert_src, nil }; - const char *fs[] = { shaderDecl, simple_frag_src, nil }; + const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil }; defaultShader = Shader::create(vs, fs); assert(defaultShader); diff --git a/src/gl/gl3immed.cpp b/src/gl/gl3immed.cpp index 68d0c65..1abaa0a 100644 --- a/src/gl/gl3immed.cpp +++ b/src/gl/gl3immed.cpp @@ -58,20 +58,18 @@ openIm2D(void) #include "shaders/simple_fs_gl3.inc" #endif const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil }; - const char *fs[] = { shaderDecl, simple_frag_src, nil }; + const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil }; im2dShader = Shader::create(vs, fs); assert(im2dShader); glGenBuffers(1, &im2DIbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2DIbo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, - nil, GL_DYNAMIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, nil, GL_STREAM_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glGenBuffers(1, &im2DVbo); glBindBuffer(GL_ARRAY_BUFFER, im2DVbo); - glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im2DVertex), - nil, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im2DVertex), nil, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -113,8 +111,8 @@ im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32 numVertices) cam = (Camera*)engine->currentCamera; glBindBuffer(GL_ARRAY_BUFFER, im2DVbo); - glBufferData(GL_ARRAY_BUFFER, numVertices*sizeof(Im2DVertex), - vertices, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im2DVertex), nil, GL_STREAM_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices*sizeof(Im2DVertex), vertices); xform[0] = 2.0f/cam->frameBuffer->width; xform[1] = -2.0f/cam->frameBuffer->height; @@ -142,12 +140,12 @@ im2DRenderIndexedPrimitive(PrimitiveType primType, // TODO: fixed size glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2DIbo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*2, - indices, GL_DYNAMIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, nil, GL_STREAM_DRAW); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, numIndices*2, indices); glBindBuffer(GL_ARRAY_BUFFER, im2DVbo); - glBufferData(GL_ARRAY_BUFFER, numVertices*sizeof(Im2DVertex), - vertices, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im2DVertex), nil, GL_STREAM_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices*sizeof(Im2DVertex), vertices); xform[0] = 2.0f/cam->frameBuffer->width; xform[1] = -2.0f/cam->frameBuffer->height; @@ -192,20 +190,18 @@ openIm3D(void) #include "shaders/simple_fs_gl3.inc" #endif const char *vs[] = { shaderDecl, header_vert_src, im3d_vert_src, nil }; - const char *fs[] = { shaderDecl, simple_frag_src, nil }; + const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil }; im3dShader = Shader::create(vs, fs); assert(im3dShader); glGenBuffers(1, &im3DIbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im3DIbo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, - nil, GL_DYNAMIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, nil, GL_STREAM_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glGenBuffers(1, &im3DVbo); glBindBuffer(GL_ARRAY_BUFFER, im3DVbo); - glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im3DVertex), - nil, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im3DVertex), nil, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -234,8 +230,8 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags) // TODO: fixed size glBindBuffer(GL_ARRAY_BUFFER, im3DVbo); - glBufferData(GL_ARRAY_BUFFER, numVertices*sizeof(Im3DVertex), - vertices, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im3DVertex), nil, GL_STREAM_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices*sizeof(Im3DVertex), vertices); setAttribPointers(im3dattribDesc, 3); num3DVertices = numVertices; } @@ -248,21 +244,19 @@ im3DRenderPrimitive(PrimitiveType primType) flushCache(); glDrawArrays(primTypeMap[primType], 0, num3DVertices); disableAttribPointers(im3dattribDesc, 3); - } void im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im3DIbo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*2, - indices, GL_DYNAMIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, nil, GL_STREAM_DRAW); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, numIndices*2, indices); flushCache(); glDrawElements(primTypeMap[primType], numIndices, GL_UNSIGNED_SHORT, nil); disableAttribPointers(im3dattribDesc, 3); - } void diff --git a/src/gl/gl3matfx.cpp b/src/gl/gl3matfx.cpp index 5502b71..0d44a5d 100644 --- a/src/gl/gl3matfx.cpp +++ b/src/gl/gl3matfx.cpp @@ -47,7 +47,7 @@ matfxOpen(void *o, int32, int32) #include "shaders/matfx_gl3.inc" #endif const char *vs[] = { shaderDecl, header_vert_src, matfx_env_vert_src, nil }; - const char *fs[] = { shaderDecl, matfx_env_frag_src, nil }; + const char *fs[] = { shaderDecl, header_frag_src, matfx_env_frag_src, nil }; envShader = Shader::create(vs, fs); assert(envShader); diff --git a/src/gl/gl3shader.cpp b/src/gl/gl3shader.cpp index a2b3b5c..b3751d3 100644 --- a/src/gl/gl3shader.cpp +++ b/src/gl/gl3shader.cpp @@ -19,8 +19,10 @@ namespace gl3 { #ifdef RW_GLES2 #include "gl2_shaders/header_vs.inc" +#include "gl2_shaders/header_fs.inc" #else #include "shaders/header_vs.inc" +#include "shaders/header_fs.inc" #endif UniformRegistry uniformRegistry; @@ -202,7 +204,7 @@ Shader::create(const char **vsrc, const char **fsrc) printf("\n"); #endif -#ifdef RW_GLES2 +#ifdef xxxRW_GLES2 int numAttribs; glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numAttribs); for(i = 0; i < numAttribs; i++){ diff --git a/src/gl/gl3skin.cpp b/src/gl/gl3skin.cpp index acc0241..9601a20 100644 --- a/src/gl/gl3skin.cpp +++ b/src/gl/gl3skin.cpp @@ -45,7 +45,7 @@ skinOpen(void *o, int32, int32) #include "shaders/skin_gl3.inc" #endif const char *vs[] = { shaderDecl, header_vert_src, skin_vert_src, nil }; - const char *fs[] = { shaderDecl, simple_frag_src, nil }; + const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil }; skinShader = Shader::create(vs, fs); assert(skinShader); diff --git a/src/gl/rwgl3.h b/src/gl/rwgl3.h index c397b8f..c0eeb45 100644 --- a/src/gl/rwgl3.h +++ b/src/gl/rwgl3.h @@ -164,6 +164,7 @@ enum extern const char *shaderDecl; // #version stuff extern const char *header_vert_src; +extern const char *header_frag_src; // per Scene void setProjectionMatrix(float32*); diff --git a/src/gl/shaders/Makefile b/src/gl/shaders/Makefile index cec56d3..2301a95 100644 --- a/src/gl/shaders/Makefile +++ b/src/gl/shaders/Makefile @@ -1,10 +1,15 @@ -all: header_vs.inc im2d_gl3.inc im3d_gl3.inc default_vs_gl3.inc simple_fs_gl3.inc matfx_gl3.inc skin_gl3.inc +all: header_vs.inc header_fs.inc im2d_gl3.inc im3d_gl3.inc default_vs_gl3.inc simple_fs_gl3.inc matfx_gl3.inc skin_gl3.inc header_vs.inc: header.vert (echo 'const char *header_vert_src =';\ sed 's/..*/"&\\n"/' header.vert;\ echo ';') >header_vs.inc +header_fs.inc: header.frag + (echo 'const char *header_frag_src =';\ + sed 's/..*/"&\\n"/' header.frag;\ + echo ';') >header_fs.inc + im2d_gl3.inc: im2d.vert (echo 'const char *im2d_vert_src =';\ sed 's/..*/"&\\n"/' im2d.vert;\ diff --git a/src/gl/shaders/default.vert b/src/gl/shaders/default.vert index cebf153..66499a3 100644 --- a/src/gl/shaders/default.vert +++ b/src/gl/shaders/default.vert @@ -18,29 +18,7 @@ main(void) v_color = in_color; v_color.rgb += u_ambLight.rgb*surfAmbient; - -#ifdef DIRECTIONALS - for(int i = 0; i < MAX_LIGHTS; i++){ - if(u_directLights[i].enabled == 0.0) - break; - v_color.rgb += DoDirLight(u_directLights[i], N)*surfDiffuse; - } -#endif -#ifdef POINTLIGHTS - for(int i = 0; i < MAX_LIGHTS; i++){ - if(u_pointLights[i].enabled == 0.0) - break; - v_color.rgb += DoPointLight(u_pointLights[i], V.xyz, N)*surfDiffuse; - } -#endif -#ifdef SPOTLIGHTS - for(int i = 0; i < MAX_LIGHTS; i++){ - if(u_spotLights[i].enabled == 0.0) - break; - v_color.rgb += DoSpotLight(u_spotLights[i], V.xyz, N)*surfDiffuse; - } -#endif - + v_color.rgb += DoDynamicLight(V.xyz, N)*surfDiffuse; v_color = clamp(v_color, 0.0f, 1.0); v_color *= u_matColor; diff --git a/src/gl/shaders/default_vs_gl3.inc b/src/gl/shaders/default_vs_gl3.inc index cc3965a..6422cab 100644 --- a/src/gl/shaders/default_vs_gl3.inc +++ b/src/gl/shaders/default_vs_gl3.inc @@ -19,29 +19,7 @@ const char *default_vert_src = " v_color = in_color;\n" " v_color.rgb += u_ambLight.rgb*surfAmbient;\n" - -"#ifdef DIRECTIONALS\n" -" for(int i = 0; i < MAX_LIGHTS; i++){\n" -" if(u_directLights[i].enabled == 0.0)\n" -" break;\n" -" v_color.rgb += DoDirLight(u_directLights[i], N)*surfDiffuse;\n" -" }\n" -"#endif\n" -"#ifdef POINTLIGHTS\n" -" for(int i = 0; i < MAX_LIGHTS; i++){\n" -" if(u_pointLights[i].enabled == 0.0)\n" -" break;\n" -" v_color.rgb += DoPointLight(u_pointLights[i], V.xyz, N)*surfDiffuse;\n" -" }\n" -"#endif\n" -"#ifdef SPOTLIGHTS\n" -" for(int i = 0; i < MAX_LIGHTS; i++){\n" -" if(u_spotLights[i].enabled == 0.0)\n" -" break;\n" -" v_color.rgb += DoSpotLight(u_spotLights[i], V.xyz, N)*surfDiffuse;\n" -" }\n" -"#endif\n" - +" v_color.rgb += DoDynamicLight(V.xyz, N)*surfDiffuse;\n" " v_color = clamp(v_color, 0.0f, 1.0);\n" " v_color *= u_matColor;\n" diff --git a/src/gl/shaders/header.frag b/src/gl/shaders/header.frag new file mode 100644 index 0000000..d340a78 --- /dev/null +++ b/src/gl/shaders/header.frag @@ -0,0 +1,28 @@ +#ifdef USE_UBOS +layout(std140) uniform State +{ + vec2 u_alphaRef; + + float u_fogStart; + float u_fogEnd; + float u_fogRange; + float u_fogDisable; + vec4 u_fogColor; +}; +#else +//uniform int u_alphaTest; +//uniform float u_alphaRef; +uniform vec2 u_alphaRef; + +uniform float u_fogStart; +uniform float u_fogEnd; +uniform float u_fogRange; +uniform float u_fogDisable; +uniform vec4 u_fogColor; +#endif + +void DoAlphaTest(float a) +{ + if(a < u_alphaRef.x || a >= u_alphaRef.y) + discard; +} diff --git a/src/gl/shaders/header.vert b/src/gl/shaders/header.vert index 1adc854..43a797d 100644 --- a/src/gl/shaders/header.vert +++ b/src/gl/shaders/header.vert @@ -1,7 +1,12 @@ + +#define DIRECTIONALS +//#define POINTLIGHTS +//#define SPOTLIGHTS + +#ifdef USE_UBOS layout(std140) uniform State { - int u_alphaTest; - float u_alphaRef; + vec2 u_alphaRef; float u_fogStart; float u_fogEnd; @@ -9,32 +14,47 @@ layout(std140) uniform State float u_fogDisable; vec4 u_fogColor; }; +#else +uniform vec2 u_alphaRef; +uniform float u_fogStart; +uniform float u_fogEnd; +uniform float u_fogRange; +uniform float u_fogDisable; +uniform vec4 u_fogColor; +#endif + +#ifdef USE_UBOS layout(std140) uniform Scene { mat4 u_proj; mat4 u_view; }; +#else +uniform mat4 u_proj; +uniform mat4 u_view; +#endif #define MAX_LIGHTS 8 -struct Light { - float enabled; - float radius; - float minusCosAngle; - float hardSpot; - vec4 position; - vec4 direction; - vec4 color; -}; +#ifdef USE_UBOS layout(std140) uniform Object { mat4 u_world; vec4 u_ambLight; - Light u_directLights[MAX_LIGHTS]; - Light u_pointLights[MAX_LIGHTS]; - Light u_spotLights[MAX_LIGHTS]; + vec4 u_lightParams[MAX_LIGHTS]; // type, radius, minusCosAngle, hardSpot + vec4 u_lightPosition[MAX_LIGHTS]; + vec4 u_lightDirection[MAX_LIGHTS]; + vec4 u_lightColor[MAX_LIGHTS]; }; +#else +uniform mat4 u_world; +uniform vec4 u_ambLight; +uniform vec4 u_lightParams[MAX_LIGHTS]; // type, radius, minusCosAngle, hardSpot +uniform vec4 u_lightPosition[MAX_LIGHTS]; +uniform vec4 u_lightDirection[MAX_LIGHTS]; +uniform vec4 u_lightColor[MAX_LIGHTS]; +#endif uniform vec4 u_matColor; uniform vec4 u_surfProps; // amb, spec, diff, extra @@ -43,44 +63,52 @@ uniform vec4 u_surfProps; // amb, spec, diff, extra #define surfSpecular (u_surfProps.y) #define surfDiffuse (u_surfProps.z) -vec3 DoDirLight(Light L, vec3 N) +vec3 DoDynamicLight(vec3 V, vec3 N) { - float l = max(0.0, dot(N, -L.direction.xyz)); - return l*L.color.rgb; -} - -vec3 DoPointLight(Light L, vec3 V, vec3 N) -{ - // As on PS2 - vec3 dir = V - L.position.xyz; - float dist = length(dir); - float atten = max(0.0, (1.0 - dist/L.radius)); - float l = max(0.0, dot(N, -normalize(dir))); - return l*L.color.rgb*atten; -} - -vec3 DoSpotLight(Light L, vec3 V, vec3 N) -{ - // As on PS2 - vec3 dir = V - L.position.xyz; - float dist = length(dir); - float atten = max(0.0, (1.0 - dist/L.radius)); - dir /= dist; - float l = max(0.0, dot(N, -dir)); - float pcos = dot(dir, L.direction.xyz); // cos to point - float ccos = -L.minusCosAngle; - float falloff = (pcos-ccos)/(1.0-ccos); - if(falloff < 0.0) // outside of cone - l = 0.0; - l *= max(falloff, L.hardSpot); - return l*L.color.xyz*atten; + vec3 color = vec3(0.0, 0.0, 0.0); + for(int i = 0; i < MAX_LIGHTS; i++){ + if(u_lightParams[i].x == 0.0) + break; +#ifdef DIRECTIONALS + if(u_lightParams[i].x == 1.0){ + // direct + float l = max(0.0, dot(N, -u_lightDirection[i].xyz)); + color += l*u_lightColor[i].rgb; + }else +#endif +#ifdef POINTLIGHTS + if(u_lightParams[i].x == 2.0){ + // point + vec3 dir = V - u_lightPosition[i].xyz; + float dist = length(dir); + float atten = max(0.0, (1.0 - dist/u_lightParams[i].y)); + float l = max(0.0, dot(N, -normalize(dir))); + color += l*u_lightColor[i].rgb*atten; + }else +#endif +#ifdef SPOTLIGHTS + if(u_lightParams[i].x == 3.0){ + // spot + vec3 dir = V - u_lightPosition[i].xyz; + float dist = length(dir); + float atten = max(0.0, (1.0 - dist/u_lightParams[i].y)); + dir /= dist; + float l = max(0.0, dot(N, -dir)); + float pcos = dot(dir, u_lightDirection[i].xyz); // cos to point + float ccos = -u_lightParams[i].z; + float falloff = (pcos-ccos)/(1.0-ccos); + if(falloff < 0.0) // outside of cone + l = 0.0; + l *= max(falloff, u_lightParams[i].w); + return l*u_lightColor[i].rgb*atten; + }else +#endif + ; + } + return color; } float DoFog(float w) { return clamp((w - u_fogEnd)*u_fogRange, u_fogDisable, 1.0); } - -#define DIRECTIONALS -//#define POINTLIGHTS -//#define SPOTLIGHTS diff --git a/src/gl/shaders/header_fs.inc b/src/gl/shaders/header_fs.inc new file mode 100644 index 0000000..0b9741d --- /dev/null +++ b/src/gl/shaders/header_fs.inc @@ -0,0 +1,30 @@ +const char *header_frag_src = +"#ifdef USE_UBOS\n" +"layout(std140) uniform State\n" +"{\n" +" vec2 u_alphaRef;\n" + +" float u_fogStart;\n" +" float u_fogEnd;\n" +" float u_fogRange;\n" +" float u_fogDisable;\n" +" vec4 u_fogColor;\n" +"};\n" +"#else\n" +"//uniform int u_alphaTest;\n" +"//uniform float u_alphaRef;\n" +"uniform vec2 u_alphaRef;\n" + +"uniform float u_fogStart;\n" +"uniform float u_fogEnd;\n" +"uniform float u_fogRange;\n" +"uniform float u_fogDisable;\n" +"uniform vec4 u_fogColor;\n" +"#endif\n" + +"void DoAlphaTest(float a)\n" +"{\n" +" if(a < u_alphaRef.x || a >= u_alphaRef.y)\n" +" discard;\n" +"}\n" +; diff --git a/src/gl/shaders/header_vs.inc b/src/gl/shaders/header_vs.inc index 695c7b5..2e54d07 100644 --- a/src/gl/shaders/header_vs.inc +++ b/src/gl/shaders/header_vs.inc @@ -1,8 +1,13 @@ const char *header_vert_src = + +"#define DIRECTIONALS\n" +"//#define POINTLIGHTS\n" +"//#define SPOTLIGHTS\n" + +"#ifdef USE_UBOS\n" "layout(std140) uniform State\n" "{\n" -" int u_alphaTest;\n" -" float u_alphaRef;\n" +" vec2 u_alphaRef;\n" " float u_fogStart;\n" " float u_fogEnd;\n" @@ -10,32 +15,47 @@ const char *header_vert_src = " float u_fogDisable;\n" " vec4 u_fogColor;\n" "};\n" +"#else\n" +"uniform vec2 u_alphaRef;\n" +"uniform float u_fogStart;\n" +"uniform float u_fogEnd;\n" +"uniform float u_fogRange;\n" +"uniform float u_fogDisable;\n" +"uniform vec4 u_fogColor;\n" +"#endif\n" + +"#ifdef USE_UBOS\n" "layout(std140) uniform Scene\n" "{\n" " mat4 u_proj;\n" " mat4 u_view;\n" "};\n" +"#else\n" +"uniform mat4 u_proj;\n" +"uniform mat4 u_view;\n" +"#endif\n" "#define MAX_LIGHTS 8\n" -"struct Light {\n" -" float enabled;\n" -" float radius;\n" -" float minusCosAngle;\n" -" float hardSpot;\n" -" vec4 position;\n" -" vec4 direction;\n" -" vec4 color;\n" -"};\n" +"#ifdef USE_UBOS\n" "layout(std140) uniform Object\n" "{\n" " mat4 u_world;\n" " vec4 u_ambLight;\n" -" Light u_directLights[MAX_LIGHTS];\n" -" Light u_pointLights[MAX_LIGHTS];\n" -" Light u_spotLights[MAX_LIGHTS];\n" +" vec4 u_lightParams[MAX_LIGHTS]; // type, radius, minusCosAngle, hardSpot\n" +" vec4 u_lightPosition[MAX_LIGHTS];\n" +" vec4 u_lightDirection[MAX_LIGHTS];\n" +" vec4 u_lightColor[MAX_LIGHTS];\n" "};\n" +"#else\n" +"uniform mat4 u_world;\n" +"uniform vec4 u_ambLight;\n" +"uniform vec4 u_lightParams[MAX_LIGHTS]; // type, radius, minusCosAngle, hardSpot\n" +"uniform vec4 u_lightPosition[MAX_LIGHTS];\n" +"uniform vec4 u_lightDirection[MAX_LIGHTS];\n" +"uniform vec4 u_lightColor[MAX_LIGHTS];\n" +"#endif\n" "uniform vec4 u_matColor;\n" "uniform vec4 u_surfProps; // amb, spec, diff, extra\n" @@ -44,45 +64,53 @@ const char *header_vert_src = "#define surfSpecular (u_surfProps.y)\n" "#define surfDiffuse (u_surfProps.z)\n" -"vec3 DoDirLight(Light L, vec3 N)\n" +"vec3 DoDynamicLight(vec3 V, vec3 N)\n" "{\n" -" float l = max(0.0, dot(N, -L.direction.xyz));\n" -" return l*L.color.rgb;\n" -"}\n" - -"vec3 DoPointLight(Light L, vec3 V, vec3 N)\n" -"{\n" -" // As on PS2\n" -" vec3 dir = V - L.position.xyz;\n" -" float dist = length(dir);\n" -" float atten = max(0.0, (1.0 - dist/L.radius));\n" -" float l = max(0.0, dot(N, -normalize(dir)));\n" -" return l*L.color.rgb*atten;\n" -"}\n" - -"vec3 DoSpotLight(Light L, vec3 V, vec3 N)\n" -"{\n" -" // As on PS2\n" -" vec3 dir = V - L.position.xyz;\n" -" float dist = length(dir);\n" -" float atten = max(0.0, (1.0 - dist/L.radius));\n" -" dir /= dist;\n" -" float l = max(0.0, dot(N, -dir));\n" -" float pcos = dot(dir, L.direction.xyz); // cos to point\n" -" float ccos = -L.minusCosAngle;\n" -" float falloff = (pcos-ccos)/(1.0-ccos);\n" -" if(falloff < 0.0) // outside of cone\n" -" l = 0.0;\n" -" l *= max(falloff, L.hardSpot);\n" -" return l*L.color.xyz*atten;\n" +" vec3 color = vec3(0.0, 0.0, 0.0);\n" +" for(int i = 0; i < MAX_LIGHTS; i++){\n" +" if(u_lightParams[i].x == 0.0)\n" +" break;\n" +"#ifdef DIRECTIONALS\n" +" if(u_lightParams[i].x == 1.0){\n" +" // direct\n" +" float l = max(0.0, dot(N, -u_lightDirection[i].xyz));\n" +" color += l*u_lightColor[i].rgb;\n" +" }else\n" +"#endif\n" +"#ifdef POINTLIGHTS\n" +" if(u_lightParams[i].x == 2.0){\n" +" // point\n" +" vec3 dir = V - u_lightPosition[i].xyz;\n" +" float dist = length(dir);\n" +" float atten = max(0.0, (1.0 - dist/u_lightParams[i].y));\n" +" float l = max(0.0, dot(N, -normalize(dir)));\n" +" color += l*u_lightColor[i].rgb*atten;\n" +" }else\n" +"#endif\n" +"#ifdef SPOTLIGHTS\n" +" if(u_lightParams[i].x == 3.0){\n" +" // spot\n" +" vec3 dir = V - u_lightPosition[i].xyz;\n" +" float dist = length(dir);\n" +" float atten = max(0.0, (1.0 - dist/u_lightParams[i].y));\n" +" dir /= dist;\n" +" float l = max(0.0, dot(N, -dir));\n" +" float pcos = dot(dir, u_lightDirection[i].xyz); // cos to point\n" +" float ccos = -u_lightParams[i].z;\n" +" float falloff = (pcos-ccos)/(1.0-ccos);\n" +" if(falloff < 0.0) // outside of cone\n" +" l = 0.0;\n" +" l *= max(falloff, u_lightParams[i].w);\n" +" return l*u_lightColor[i].rgb*atten;\n" +" }else\n" +"#endif\n" +" ;\n" +" }\n" +" return color;\n" "}\n" "float DoFog(float w)\n" "{\n" " return clamp((w - u_fogEnd)*u_fogRange, u_fogDisable, 1.0);\n" "}\n" - -"#define DIRECTIONALS\n" -"//#define POINTLIGHTS\n" -"//#define SPOTLIGHTS\n" ; diff --git a/src/gl/shaders/matfx_env.frag b/src/gl/shaders/matfx_env.frag index aa831d2..43c60ef 100644 --- a/src/gl/shaders/matfx_env.frag +++ b/src/gl/shaders/matfx_env.frag @@ -1,15 +1,3 @@ -layout(std140) uniform State -{ - int u_alphaTest; - float u_alphaRef; - - float u_fogStart; - float u_fogEnd; - float u_fogRange; - float u_fogDisable; - vec4 u_fogColor; -}; - uniform sampler2D tex0; uniform sampler2D tex1; @@ -38,16 +26,5 @@ main(void) color.rgb = pass1.rgb*pass1.a + pass2.rgb; color.a = pass1.a; - switch(u_alphaTest){ - default: - case 0: break; - case 1: - if(color.a < u_alphaRef) - discard; - break; - case 2: - if(color.a >= u_alphaRef) - discard; - break; - } + DoAlphaTest(color.a); } diff --git a/src/gl/shaders/matfx_env.vert b/src/gl/shaders/matfx_env.vert index 40cf146..73d4b44 100644 --- a/src/gl/shaders/matfx_env.vert +++ b/src/gl/shaders/matfx_env.vert @@ -22,29 +22,7 @@ main(void) v_color = in_color; v_color.rgb += u_ambLight.rgb*surfAmbient; - -#ifdef DIRECTIONALS - for(int i = 0; i < MAX_LIGHTS; i++){ - if(u_directLights[i].enabled == 0.0) - break; - v_color.rgb += DoDirLight(u_directLights[i], N)*surfDiffuse; - } -#endif -#ifdef POINTLIGHTS - for(int i = 0; i < MAX_LIGHTS; i++){ - if(u_pointLights[i].enabled == 0.0) - break; - v_color.rgb += DoPointLight(u_pointLights[i], V.xyz, N)*surfDiffuse; - } -#endif -#ifdef SPOTLIGHTS - for(int i = 0; i < MAX_LIGHTS; i++){ - if(u_spotLights[i].enabled == 0.0) - break; - v_color.rgb += DoSpotLight(u_spotLights[i], V.xyz, N)*surfDiffuse; - } -#endif - + v_color.rgb += DoDynamicLight(V.xyz, N)*surfDiffuse; v_color = clamp(v_color, 0.0f, 1.0); v_color *= u_matColor; diff --git a/src/gl/shaders/matfx_gl3.inc b/src/gl/shaders/matfx_gl3.inc index fa41ec5..7562b33 100644 --- a/src/gl/shaders/matfx_gl3.inc +++ b/src/gl/shaders/matfx_gl3.inc @@ -23,29 +23,7 @@ const char *matfx_env_vert_src = " v_color = in_color;\n" " v_color.rgb += u_ambLight.rgb*surfAmbient;\n" - -"#ifdef DIRECTIONALS\n" -" for(int i = 0; i < MAX_LIGHTS; i++){\n" -" if(u_directLights[i].enabled == 0.0)\n" -" break;\n" -" v_color.rgb += DoDirLight(u_directLights[i], N)*surfDiffuse;\n" -" }\n" -"#endif\n" -"#ifdef POINTLIGHTS\n" -" for(int i = 0; i < MAX_LIGHTS; i++){\n" -" if(u_pointLights[i].enabled == 0.0)\n" -" break;\n" -" v_color.rgb += DoPointLight(u_pointLights[i], V.xyz, N)*surfDiffuse;\n" -" }\n" -"#endif\n" -"#ifdef SPOTLIGHTS\n" -" for(int i = 0; i < MAX_LIGHTS; i++){\n" -" if(u_spotLights[i].enabled == 0.0)\n" -" break;\n" -" v_color.rgb += DoSpotLight(u_spotLights[i], V.xyz, N)*surfDiffuse;\n" -" }\n" -"#endif\n" - +" v_color.rgb += DoDynamicLight(V.xyz, N)*surfDiffuse;\n" " v_color = clamp(v_color, 0.0f, 1.0);\n" " v_color *= u_matColor;\n" @@ -53,18 +31,6 @@ const char *matfx_env_vert_src = "}\n" ; const char *matfx_env_frag_src = -"layout(std140) uniform State\n" -"{\n" -" int u_alphaTest;\n" -" float u_alphaRef;\n" - -" float u_fogStart;\n" -" float u_fogEnd;\n" -" float u_fogRange;\n" -" float u_fogDisable;\n" -" vec4 u_fogColor;\n" -"};\n" - "uniform sampler2D tex0;\n" "uniform sampler2D tex1;\n" @@ -93,17 +59,6 @@ const char *matfx_env_frag_src = " color.rgb = pass1.rgb*pass1.a + pass2.rgb;\n" " color.a = pass1.a;\n" -" switch(u_alphaTest){\n" -" default:\n" -" case 0: break;\n" -" case 1:\n" -" if(color.a < u_alphaRef)\n" -" discard;\n" -" break;\n" -" case 2:\n" -" if(color.a >= u_alphaRef)\n" -" discard;\n" -" break;\n" -" }\n" +" DoAlphaTest(color.a);\n" "}\n" ; diff --git a/src/gl/shaders/simple.frag b/src/gl/shaders/simple.frag index eef08cc..87157be 100644 --- a/src/gl/shaders/simple.frag +++ b/src/gl/shaders/simple.frag @@ -1,15 +1,3 @@ -layout(std140) uniform State -{ - int u_alphaTest; - float u_alphaRef; - - float u_fogStart; - float u_fogEnd; - float u_fogRange; - float u_fogDisable; - vec4 u_fogColor; -}; - uniform sampler2D tex0; in vec4 v_color; @@ -23,17 +11,6 @@ main(void) { color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y)); color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog); - switch(u_alphaTest){ - default: - case 0: break; - case 1: - if(color.a < u_alphaRef) - discard; - break; - case 2: - if(color.a >= u_alphaRef) - discard; - break; - } + DoAlphaTest(color.a); } diff --git a/src/gl/shaders/simple_fs_gl3.inc b/src/gl/shaders/simple_fs_gl3.inc index a8e691e..47d8997 100644 --- a/src/gl/shaders/simple_fs_gl3.inc +++ b/src/gl/shaders/simple_fs_gl3.inc @@ -1,16 +1,4 @@ const char *simple_frag_src = -"layout(std140) uniform State\n" -"{\n" -" int u_alphaTest;\n" -" float u_alphaRef;\n" - -" float u_fogStart;\n" -" float u_fogEnd;\n" -" float u_fogRange;\n" -" float u_fogDisable;\n" -" vec4 u_fogColor;\n" -"};\n" - "uniform sampler2D tex0;\n" "in vec4 v_color;\n" @@ -24,18 +12,7 @@ const char *simple_frag_src = "{\n" " color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n" " color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n" -" switch(u_alphaTest){\n" -" default:\n" -" case 0: break;\n" -" case 1:\n" -" if(color.a < u_alphaRef)\n" -" discard;\n" -" break;\n" -" case 2:\n" -" if(color.a >= u_alphaRef)\n" -" discard;\n" -" break;\n" -" }\n" +" DoAlphaTest(color.a);\n" "}\n" ; diff --git a/src/gl/shaders/skin.vert b/src/gl/shaders/skin.vert index 1a90898..1933497 100644 --- a/src/gl/shaders/skin.vert +++ b/src/gl/shaders/skin.vert @@ -25,33 +25,13 @@ main(void) gl_Position = u_proj * u_view * V; vec3 N = mat3(u_world) * SkinNormal; + v_tex0 = in_tex0; + v_color = in_color; v_color.rgb += u_ambLight.rgb*surfAmbient; - -#ifdef DIRECTIONALS - for(int i = 0; i < MAX_LIGHTS; i++){ - if(u_directLights[i].enabled == 0.0) - break; - v_color.rgb += DoDirLight(u_directLights[i], N)*surfDiffuse; - } -#endif -#ifdef POINTLIGHTS - for(int i = 0; i < MAX_LIGHTS; i++){ - if(u_pointLights[i].enabled == 0.0) - break; - v_color.rgb += DoPointLight(u_pointLights[i], V.xyz, N)*surfDiffuse; - } -#endif -#ifdef SPOTLIGHTS - for(int i = 0; i < MAX_LIGHTS; i++){ - if(u_spotLights[i].enabled == 0.0) - break; - v_color.rgb += DoSpotLight(u_spotLights[i], V.xyz, N)*surfDiffuse; - } -#endif + v_color.rgb += DoDynamicLight(V.xyz, N)*surfDiffuse; + v_color = clamp(v_color, 0.0f, 1.0); v_color *= u_matColor; - v_tex0 = in_tex0; - v_fog = DoFog(gl_Position.z); } diff --git a/src/gl/shaders/skin_gl3.inc b/src/gl/shaders/skin_gl3.inc index 0880a54..980099b 100644 --- a/src/gl/shaders/skin_gl3.inc +++ b/src/gl/shaders/skin_gl3.inc @@ -26,34 +26,14 @@ const char *skin_vert_src = " gl_Position = u_proj * u_view * V;\n" " vec3 N = mat3(u_world) * SkinNormal;\n" +" v_tex0 = in_tex0;\n" + " v_color = in_color;\n" " v_color.rgb += u_ambLight.rgb*surfAmbient;\n" - -"#ifdef DIRECTIONALS\n" -" for(int i = 0; i < MAX_LIGHTS; i++){\n" -" if(u_directLights[i].enabled == 0.0)\n" -" break;\n" -" v_color.rgb += DoDirLight(u_directLights[i], N)*surfDiffuse;\n" -" }\n" -"#endif\n" -"#ifdef POINTLIGHTS\n" -" for(int i = 0; i < MAX_LIGHTS; i++){\n" -" if(u_pointLights[i].enabled == 0.0)\n" -" break;\n" -" v_color.rgb += DoPointLight(u_pointLights[i], V.xyz, N)*surfDiffuse;\n" -" }\n" -"#endif\n" -"#ifdef SPOTLIGHTS\n" -" for(int i = 0; i < MAX_LIGHTS; i++){\n" -" if(u_spotLights[i].enabled == 0.0)\n" -" break;\n" -" v_color.rgb += DoSpotLight(u_spotLights[i], V.xyz, N)*surfDiffuse;\n" -" }\n" -"#endif\n" +" v_color.rgb += DoDynamicLight(V.xyz, N)*surfDiffuse;\n" +" v_color = clamp(v_color, 0.0f, 1.0);\n" " v_color *= u_matColor;\n" -" v_tex0 = in_tex0;\n" - " v_fog = DoFog(gl_Position.z);\n" "}\n" ;