From 71d132b4700993ef27dea02508d963c65bbbc7e3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 6 Oct 2019 10:19:51 +0200 Subject: [PATCH] - use explicitly declared matrix uniforms. The builtin matrices are no longer available in modern GLSL, preventing an upgrade of the shader. Also perform better reporting of shader compilation errors. --- source/build/src/animvpx.cpp | 4 -- source/build/src/mdsprite.cpp | 4 +- source/build/src/polymost.cpp | 4 +- source/glbackend/gl_hwtexture.h | 7 ++- source/glbackend/gl_shader.cpp | 9 +++- source/glbackend/gl_shader.h | 6 ++- source/glbackend/glbackend.cpp | 52 +++++++++---------- source/glbackend/glbackend.h | 4 +- .../demolition/shaders/glsl/polymost.vp | 12 +++-- 9 files changed, 56 insertions(+), 46 deletions(-) diff --git a/source/build/src/animvpx.cpp b/source/build/src/animvpx.cpp index 7c72bb178..c8a7b8260 100644 --- a/source/build/src/animvpx.cpp +++ b/source/build/src/animvpx.cpp @@ -355,10 +355,6 @@ void animvpx_setup_glstate(int32_t animvpx_flags) //Force fullscreen (glox1=-1 forces it to restore afterwards) GLInterface.SetViewport(0,0,xdim,ydim); glox1 = -1; - VSMatrix identity(0); - GLInterface.SetMatrix(Matrix_ModelView, &identity); - GLInterface.SetMatrix(Matrix_Projection, &identity); - GLInterface.EnableAlphaTest(false); GLInterface.EnableDepthTest(false); GLInterface.EnableBlend(false); diff --git a/source/build/src/mdsprite.cpp b/source/build/src/mdsprite.cpp index 6c4134e99..baffe2f42 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -1930,7 +1930,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) texmat.loadIdentity(); texmat.translate(xpanning, ypanning, 1.0f); texmat.scale(f, f, 1.0f); - GLInterface.SetMatrix(Matrix_Texture3, &texmat); + GLInterface.SetMatrix(Matrix_Detail, &texmat); } tex = r_glowmapping ? mdloadskin((md2model_t *) m, tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum, GLOWPAL, surfi) : 0; @@ -1942,7 +1942,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) texmat.loadIdentity(); texmat.translate(xpanning, ypanning, 1.0f); - GLInterface.SetMatrix(Matrix_Texture4, &texmat); + GLInterface.SetMatrix(Matrix_Glow, &texmat); } indexhandle = m->vindexes; diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index c525156e9..fee91d25f 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -1400,7 +1400,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32 if ((detailpth->hicr->scale.x != 1.0f) || (detailpth->hicr->scale.y != 1.0f)) texmat.scale(detailpth->hicr->scale.x, detailpth->hicr->scale.y, 1.0f); - GLInterface.SetMatrix(Matrix_Texture3, &texmat); + GLInterface.SetMatrix(Matrix_Detail, &texmat); } } @@ -1664,7 +1664,7 @@ do if (pth->hicr) { VSMatrix identity(0); - GLInterface.SetMatrix(Matrix_Texture3, &identity); + GLInterface.SetMatrix(Matrix_Detail, &identity); } if (videoGetRenderMode() != REND_POLYMOST) diff --git a/source/glbackend/gl_hwtexture.h b/source/glbackend/gl_hwtexture.h index 56edb6ea6..9493eb2cf 100644 --- a/source/glbackend/gl_hwtexture.h +++ b/source/glbackend/gl_hwtexture.h @@ -5,6 +5,8 @@ class FBitmap; class FTexture; +#include "tarray.h" + class FHardwareTexture //: public IHardwareTexture { public: @@ -34,13 +36,16 @@ public: friend class FGameTexture; }; +// This class identifies a single source image to the game. +// Since hightile palette variations are identified by file name, they will create separate game textures. class FGameTexture { int Width, Height; bool isHightile; + // Source image for this texture. FTexture* sourceData = nullptr; - // either indexed or the sole image for hightiles. + // indexed or the sole image for hightiles. FHardwareTexture* hwBase = nullptr; // If the number was large a TMap would be better - // but in most cases the maximum number of palettes for a single tile is less than 10 where a linear search is much faster than a TMap. diff --git a/source/glbackend/gl_shader.cpp b/source/glbackend/gl_shader.cpp index 95f9cdf60..b805cb2e4 100644 --- a/source/glbackend/gl_shader.cpp +++ b/source/glbackend/gl_shader.cpp @@ -99,8 +99,8 @@ bool FShader::Load(const char * name, const char * vert_prog, const char * frag_ if (linked == 0) { // only print message if there's an error. - initprintf("Init Shader '%s':\n%s\n", name, error.GetChars()); - return false; + FStringf err("Init Shader '%s':\n%s\n", name, error.GetChars()); + throw std::runtime_error(err); // Failing to compile a shader is fatal. } return true; } @@ -158,6 +158,11 @@ bool PolymostShader::Load(const char * name, const char * vert_prog, const char NPOTEmulationXOffset.Init(hShader, "u_npotEmulationXOffset"); Brightness.Init(hShader, "u_brightness"); RotMatrix.Init(hShader, "u_rotMatrix"); + ModelMatrix.Init(hShader, "u_modelMatrix"); + ProjectionMatrix.Init(hShader, "u_projectionMatrix"); + DetailMatrix.Init(hShader, "u_detailMatrix"); + GlowMatrix.Init(hShader, "u_glowMatrix"); + ShadeInterpolate.Init(hShader, "u_shadeInterpolate"); glUseProgram(hShader); diff --git a/source/glbackend/gl_shader.h b/source/glbackend/gl_shader.h index a895961da..b6ce44692 100644 --- a/source/glbackend/gl_shader.h +++ b/source/glbackend/gl_shader.h @@ -51,7 +51,11 @@ public: FBufferedUniform1f NPOTEmulationXOffset; FBufferedUniform1f Brightness; FUniformMatrix4f RotMatrix; - FBufferedUniform1f ShadeInterpolate; + FUniformMatrix4f ModelMatrix; + FUniformMatrix4f ProjectionMatrix; + FUniformMatrix4f DetailMatrix; + FUniformMatrix4f GlowMatrix; + FBufferedUniform1f ShadeInterpolate; public: diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index 6c3728916..28ff9d72b 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -62,9 +62,18 @@ void GLInstance::Init() glinfo.dumped = 1; } new(&renderState) PolymostRenderState; // reset to defaults. - LoadSurfaceShader(); - LoadVPXShader(); - LoadPolymostShader(); + try + { + LoadSurfaceShader(); + LoadVPXShader(); + LoadPolymostShader(); + } + catch (const std::runtime_error& err) + { + // This is far from an optimal solution but at this point the only way to get the error out. + wm_msgbox("Shader compilation failed", err.what()); + exit(1); + } } @@ -78,11 +87,7 @@ void GLInstance::LoadPolymostShader() Vert.Push(0); Frag.Push(0); polymostShader = new PolymostShader(); - if (!polymostShader->Load("PolymostShader", (const char*)Vert.Data(), (const char*)Frag.Data())) - { - wm_msgbox("Fatal Error", "Shader compilation failed"); - exit(1); - } + polymostShader->Load("PolymostShader", (const char*)Vert.Data(), (const char*)Frag.Data()); SetPolymostShader(); } @@ -96,11 +101,7 @@ void GLInstance::LoadVPXShader() Vert.Push(0); Frag.Push(0); vpxShader = new FShader(); - if (!vpxShader->Load("VPXShader", (const char*)Vert.Data(), (const char*)Frag.Data())) - { - wm_msgbox("Fatal Error", "Shader compilation failed"); - exit(1); - } + vpxShader->Load("VPXShader", (const char*)Vert.Data(), (const char*)Frag.Data()); } void GLInstance::LoadSurfaceShader() @@ -113,11 +114,7 @@ void GLInstance::LoadSurfaceShader() Vert.Push(0); Frag.Push(0); surfaceShader = new SurfaceShader(); - if (!surfaceShader->Load("SurfaceShader", (const char*)Vert.Data(), (const char*)Frag.Data())) - { - wm_msgbox("Fatal Error", "Shader compilation failed"); - exit(1); - } + surfaceShader->Load("SurfaceShader", (const char*)Vert.Data(), (const char*)Frag.Data()); } @@ -253,26 +250,25 @@ void GLInstance::SetMatrix(int num, const VSMatrix *mat) { default: return; + case Matrix_View: polymostShader->RotMatrix.Set(mat->get()); break; case Matrix_Projection: - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(mat->get()); + polymostShader->ProjectionMatrix.Set(mat->get()); break; case Matrix_ModelView: - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(mat->get()); + polymostShader->ModelMatrix.Set(mat->get()); break; - case Matrix_Texture3: - case Matrix_Texture4: - glActiveTexture(GL_TEXTURE3 + num - Matrix_Texture3); - glMatrixMode(GL_TEXTURE); - glLoadMatrixf(mat->get()); - glActiveTexture(GL_TEXTURE0); + case Matrix_Detail: + polymostShader->DetailMatrix.Set(mat->get()); + break; + + case Matrix_Glow: + polymostShader->GlowMatrix.Set(mat->get()); break; } } diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index 41b38bdb8..ecd98c76d 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -67,8 +67,8 @@ enum EMatrixType Matrix_View, Matrix_Projection, Matrix_ModelView, - Matrix_Texture3, - Matrix_Texture4, + Matrix_Detail, + Matrix_Glow, // These are the only ones being used. NUMMATRICES }; diff --git a/wadsrc/static/demolition/shaders/glsl/polymost.vp b/wadsrc/static/demolition/shaders/glsl/polymost.vp index df5a9fcc3..dd311db61 100644 --- a/wadsrc/static/demolition/shaders/glsl/polymost.vp +++ b/wadsrc/static/demolition/shaders/glsl/polymost.vp @@ -5,6 +5,10 @@ varying float v_distance; uniform float u_usePalette; uniform mat4 u_rotMatrix; +uniform mat4 u_modelMatrix; +uniform mat4 u_projectionMatrix; +uniform mat4 u_detailMatrix; +uniform mat4 u_glowMatrix; const float c_zero = 0.0; const float c_one = 1.0; @@ -12,16 +16,16 @@ const float c_one = 1.0; void main() { vec4 vertex = u_rotMatrix * gl_Vertex; - vec4 eyeCoordPosition = gl_ModelViewMatrix * vertex; - gl_Position = gl_ModelViewProjectionMatrix * vertex; + vec4 eyeCoordPosition = u_modelMatrix * vertex; + gl_Position = u_projectionMatrix * eyeCoordPosition; eyeCoordPosition.xyz /= eyeCoordPosition.w; gl_TexCoord[0] = gl_MultiTexCoord0; //gl_TexCoord[0] = mix(gl_TexCoord[0].xyzw, gl_TexCoord[0].yxzw, u_usePalette); WTF is this??? - gl_TexCoord[3] = gl_TextureMatrix[3] * gl_MultiTexCoord0; - gl_TexCoord[4] = gl_TextureMatrix[4] * gl_MultiTexCoord0; + gl_TexCoord[3] = u_detailMatrix * gl_MultiTexCoord0; + gl_TexCoord[4] = u_glowMatrix * gl_MultiTexCoord0; gl_FogFragCoord = abs(eyeCoordPosition.z);