diff --git a/source/build/include/polymost.h b/source/build/include/polymost.h index 642e8216f..88c433259 100644 --- a/source/build/include/polymost.h +++ b/source/build/include/polymost.h @@ -51,8 +51,6 @@ void polymost_completeMirror(); int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall); int32_t polymost_spriteHasTranslucency(uspritetype const * const tspr); -void useShaderProgram(uint32_t shaderID); - float* multiplyMatrix4f(float m0[4*4], const float m1[4*4]); void polymost_glinit(void); diff --git a/source/build/src/glsurface.cpp b/source/build/src/glsurface.cpp index 73eb88950..a4249f390 100644 --- a/source/build/src/glsurface.cpp +++ b/source/build/src/glsurface.cpp @@ -10,145 +10,42 @@ #include "baselayer.h" #include "build.h" +#include "tarray.h" #include "../../glbackend/glbackend.h" -static void* buffer; +static TArray buffer; static FHardwareTexture* bufferTexture; static vec2_t bufferRes; static FHardwareTexture* paletteTexture; -static GLuint shaderProgramID = 0; -static GLint texSamplerLoc = -1; -static GLint paletteSamplerLoc = -1; - -static GLuint compileShader(GLenum shaderType, const char* const source) -{ - GLuint shaderID = glCreateShader(shaderType); - if (shaderID == 0) - return 0; - - const char* const sources[1] = {source}; - glShaderSource(shaderID, - 1, - sources, - NULL); - glCompileShader(shaderID); - - GLint compileStatus; - glGetShaderiv(shaderID, GL_COMPILE_STATUS, &compileStatus); - if (!compileStatus) - { - GLint logLength; - glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLength); - OSD_Printf("Compile Status: %u\n", compileStatus); - if (logLength > 0) - { - char *infoLog = (char*) Xmalloc(logLength); - glGetShaderInfoLog(shaderID, logLength, &logLength, infoLog); - OSD_Printf("Log:\n%s\n", infoLog); - Xfree(infoLog); - } - } - - return shaderID; -} - bool glsurface_initialize(vec2_t bufferResolution) { - if (buffer) + if (buffer.Size()) glsurface_destroy(); bufferRes = bufferResolution; - buffer = Xaligned_alloc(16, bufferRes.x * bufferRes.y); + buffer.Resize(bufferRes.x * bufferRes.y); bufferTexture = GLInterface.NewTexture(); bufferTexture->CreateTexture(bufferRes.x, bufferRes.y, true, false); glsurface_setPalette(curpalettefaded); - - const char* const VERTEX_SHADER_CODE = - "#version 110\n\ - \n\ - attribute vec4 i_vertPos;\n\ - attribute vec2 i_texCoord;\n\ - \n\ - varying vec2 v_texCoord;\n\ - \n\ - void main()\n\ - {\n\ - gl_Position = i_vertPos;\n\ - v_texCoord = i_texCoord;\n\ - }\n"; - const char* const FRAGMENT_SHADER_CODE = - "#version 110\n\ - \n\ - //s_texture points to an indexed color texture\n\ - uniform sampler2D s_texture;\n\ - //s_palette is the palette texture\n\ - uniform sampler2D s_palette;\n\ - \n\ - varying vec2 v_texCoord;\n\ - \n\ - const float c_paletteScale = 255.0/256.0;\n\ - const float c_paletteOffset = 0.5/256.0;\n\ - \n\ - void main()\n\ - {\n\ - vec4 color = texture2D(s_texture, v_texCoord.xy);\n\ - color.r = c_paletteOffset + c_paletteScale*color.r;\n\ - color.rgb = texture2D(s_palette, color.rg).rgb;\n\ - \n\ - // DEBUG \n\ - //color = texture2D(s_palette, v_texCoord.xy);\n\ - //color = texture2D(s_texture, v_texCoord.xy);\n\ - \n\ - gl_FragColor = color;\n\ - }\n"; - - shaderProgramID = glCreateProgram(); - GLuint vertexShaderID = compileShader(GL_VERTEX_SHADER, VERTEX_SHADER_CODE); - GLuint fragmentShaderID = compileShader(GL_FRAGMENT_SHADER, FRAGMENT_SHADER_CODE); - glAttachShader(shaderProgramID, vertexShaderID); - glAttachShader(shaderProgramID, fragmentShaderID); - glBindAttribLocation(shaderProgramID, 0, "i_vertPos"); - glBindAttribLocation(shaderProgramID, 1, "i_texCoord"); - glLinkProgram(shaderProgramID); - glDetachShader(shaderProgramID, vertexShaderID); - glDeleteShader(vertexShaderID); - glDetachShader(shaderProgramID, fragmentShaderID); - glDeleteShader(fragmentShaderID); - glUseProgram(shaderProgramID); - - texSamplerLoc = glGetUniformLocation(shaderProgramID, "s_texture"); - paletteSamplerLoc = glGetUniformLocation(shaderProgramID, "s_palette"); - - glUniform1i(texSamplerLoc, 0); - glUniform1i(paletteSamplerLoc, 1); - + GLInterface.SetSurfaceShader(); return true; } void glsurface_destroy() { - if (!buffer) - return; - - ALIGNED_FREE_AND_NULL(buffer); - - delete bufferTexture; + if (bufferTexture) delete bufferTexture; bufferTexture = nullptr; - delete paletteTexture; + if (paletteTexture) delete paletteTexture; paletteTexture = nullptr; - - glUseProgram(0); - glDeleteProgram(shaderProgramID); - shaderProgramID = 0; } void glsurface_setPalette(void* pPalette) { - if (!buffer) + if (!buffer.Size()) return; if (!pPalette) return; @@ -164,7 +61,7 @@ void glsurface_setPalette(void* pPalette) void* glsurface_getBuffer() { - return buffer; + return buffer.Data(); } vec2_t glsurface_getBufferResolution() @@ -174,10 +71,10 @@ vec2_t glsurface_getBufferResolution() void glsurface_blitBuffer() { - if (!buffer) - return; + if (!buffer.Size()) + return; - bufferTexture->LoadTexture((uint8_t*)buffer); + bufferTexture->LoadTexture(buffer.Data()); GLInterface.BindTexture(0, bufferTexture, Sampler2DNoFilter); auto data = GLInterface.AllocVertices(4); diff --git a/source/glbackend/gl_shader.cpp b/source/glbackend/gl_shader.cpp index 56a61372c..95f9cdf60 100644 --- a/source/glbackend/gl_shader.cpp +++ b/source/glbackend/gl_shader.cpp @@ -177,3 +177,28 @@ bool PolymostShader::Load(const char * name, const char * vert_prog, const char glUseProgram(0); return true; } + +//========================================================================== +// +// +// +//========================================================================== + +bool SurfaceShader::Load(const char* name, const char* vert_prog, const char* frag_prog) +{ + if (!FShader::Load(name, vert_prog, frag_prog)) return false; + + glUseProgram(hShader); + + int SamplerLoc; + SamplerLoc = glGetUniformLocation(hShader, "s_texture"); + glUniform1i(SamplerLoc, 0); + SamplerLoc = glGetUniformLocation(hShader, "s_palette"); + glUniform1i(SamplerLoc, 1); + + glBindAttribLocation(hShader, 0, "i_vertPos"); + glBindAttribLocation(hShader, 1, "i_texCoord"); + + glUseProgram(0); + return true; +} diff --git a/source/glbackend/gl_shader.h b/source/glbackend/gl_shader.h index 89792e289..ea7de2c1f 100644 --- a/source/glbackend/gl_shader.h +++ b/source/glbackend/gl_shader.h @@ -58,3 +58,11 @@ public: PolymostShader() = default; virtual bool Load(const char * name, const char * vert_prog_lump, const char * fragprog); //, const char * fragprog2, const char *defines); }; + +class SurfaceShader : public FShader +{ +public: + SurfaceShader() = default; + virtual bool Load(const char* name, const char* vert_prog_lump, const char* fragprog); //, const char * fragprog2, const char *defines); + +}; \ No newline at end of file diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index 6a223cfb4..ce02c1926 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -62,6 +62,7 @@ void GLInstance::Init() glinfo.dumped = 1; } new(&renderState) PolymostRenderState; // reset to defaults. + LoadSurfaceShader(); LoadPolymostShader(); } @@ -83,6 +84,22 @@ void GLInstance::LoadPolymostShader() SetPolymostShader(); } +void GLInstance::LoadSurfaceShader() +{ + auto fr1 = GetBaseResource("demolition/shaders/glsl/surface.vp"); + TArray Vert = fr1.Read(); + fr1 = GetBaseResource("demolition/shaders/glsl/surface.fp"); + TArray Frag = fr1.Read(); + // Zero-terminate both strings. + Vert.Push(0); + Frag.Push(0); + surfaceShader = new SurfaceShader(); + if (!surfaceShader->Load("SurfaceShader", (const char*)Vert.Data(), (const char*)Frag.Data())) + { + exit(1); + } +} + void GLInstance::InitGLState(int fogmode, int multisample) { @@ -373,6 +390,16 @@ void GLInstance::SetPolymostShader() } +void GLInstance::SetSurfaceShader() +{ + if (activeShader != surfaceShader) + { + surfaceShader->Bind(); + activeShader = surfaceShader; + } +} + + void PolymostRenderState::Apply(PolymostShader* shader) { diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index 68adf90fd..76405ca8b 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -11,6 +11,7 @@ class FSamplerManager; class FShader; class PolymostShader; +class SurfaceShader; struct glinfo_t { const char* vendor; @@ -130,6 +131,7 @@ class GLInstance PolymostRenderState renderState; FShader* activeShader; PolymostShader* polymostShader; + SurfaceShader* surfaceShader; public: @@ -139,6 +141,8 @@ public: void Init(); void InitGLState(int fogmode, int multisample); void LoadPolymostShader(); + void LoadSurfaceShader(); + void LoadVPXShader(); void Deinit(); @@ -192,6 +196,7 @@ public: void SetAlphaThreshold(float al); void SetWireframe(bool on); void SetPolymostShader(); + void SetSurfaceShader(); void ReadPixels(int w, int h, uint8_t* buffer);