diff --git a/src/common/rendering/gles/gles_postprocess.cpp b/src/common/rendering/gles/gles_postprocess.cpp index deac9739b..a618c3b2e 100644 --- a/src/common/rendering/gles/gles_postprocess.cpp +++ b/src/common/rendering/gles/gles_postprocess.cpp @@ -163,16 +163,17 @@ void FGLRenderer::DrawPresentTexture(const IntRect &box, bool applyGamma) { int index = -1; UniformFieldDesc desc = mPresentShader->Uniforms.mFields[n]; + int loc = mPresentShader->Uniforms.UniformLocation[n]; switch (desc.Type) { case UniformType::Int: - glUniform1i(desc.UniformLocation, *((GLint*)(((char*)(&mPresentShader->Uniforms)) + desc.Offset))); + glUniform1i(loc, *((GLint*)(((char*)(&mPresentShader->Uniforms)) + desc.Offset))); break; case UniformType::Float: - glUniform1f(desc.UniformLocation, *((GLfloat*)(((char*)(&mPresentShader->Uniforms)) + desc.Offset))); + glUniform1f(loc, *((GLfloat*)(((char*)(&mPresentShader->Uniforms)) + desc.Offset))); break; case UniformType::Vec2: - glUniform2fv(desc.UniformLocation,1, ((GLfloat*)(((char*)(&mPresentShader->Uniforms)) + desc.Offset))); + glUniform2fv(loc,1 , ((GLfloat*)(((char*)(&mPresentShader->Uniforms)) + desc.Offset))); break; } } diff --git a/src/common/rendering/gles/gles_renderstate.cpp b/src/common/rendering/gles/gles_renderstate.cpp index bd1a79c5e..5c603c5fa 100644 --- a/src/common/rendering/gles/gles_renderstate.cpp +++ b/src/common/rendering/gles/gles_renderstate.cpp @@ -37,7 +37,6 @@ #include "gles_buffers.h" #include "hw_clock.h" #include "printf.h" -#include "colormaps.h" #include "hwrenderer/data/hw_viewpointbuffer.h" diff --git a/src/common/rendering/gles/gles_shaderprogram.cpp b/src/common/rendering/gles/gles_shaderprogram.cpp index c82fb772c..26906f57a 100644 --- a/src/common/rendering/gles/gles_shaderprogram.cpp +++ b/src/common/rendering/gles/gles_shaderprogram.cpp @@ -261,7 +261,7 @@ FString FShaderProgram::PatchShader(ShaderType type, const FString &code, const void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program_name) { - FString prolog = Uniforms.CreateDeclaration("Uniforms", PresentUniforms::Desc(), true); + FString prolog = Uniforms.CreateDeclaration("Uniforms", PresentUniforms::Desc()); mShader.reset(new FShaderProgram()); mShader->Compile(FShaderProgram::Vertex, "shaders_gles/pp/screenquad.vp", prolog, 330); @@ -270,12 +270,14 @@ void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program mShader->Bind(); Uniforms.Init(); + Uniforms.UniformLocation.resize(Uniforms.mFields.size()); + for (int n = 0; n < Uniforms.mFields.size(); n++) { int index = -1; UniformFieldDesc desc = Uniforms.mFields[n]; index = glGetUniformLocation(mShader->mProgram, desc.Name); - Uniforms.mFields[n].UniformLocation = index; + Uniforms.UniformLocation[n] = index; } } @@ -288,7 +290,4 @@ void FPresentShader::Bind() mShader->Bind(); } - - - } \ No newline at end of file diff --git a/src/common/rendering/gles/gles_shaderprogram.h b/src/common/rendering/gles/gles_shaderprogram.h index 59c3fe7e5..a8dc97428 100644 --- a/src/common/rendering/gles/gles_shaderprogram.h +++ b/src/common/rendering/gles/gles_shaderprogram.h @@ -51,13 +51,97 @@ private: TArray> samplerstobind; }; +template +class ShaderUniformsGles +{ +public: + ShaderUniformsGles() + { + memset(&Values, 0, sizeof(Values)); + } + + ~ShaderUniformsGles() + { + if (mBuffer != nullptr) + delete mBuffer; + } + + FString CreateDeclaration(const char* name, const std::vector& fields) + { + mFields = fields; + FString decl; + decl += "\n"; + for (size_t i = 0; i < fields.size(); i++) + { + decl.AppendFormat("\tuniform %s %s;\n", GetTypeStr(fields[i].Type), fields[i].Name); + } + decl += "\n"; + return decl; + } + + void Init() + { + if (mBuffer == nullptr) + mBuffer = screen->CreateDataBuffer(-1, false, false); + } + + void SetData() + { + if (mBuffer != nullptr) + mBuffer->SetData(sizeof(T), &Values); + } + + IDataBuffer* GetBuffer() const + { + // OpenGL needs to mess around with this in ways that should not be part of the interface. + return mBuffer; + } + + T* operator->() { return &Values; } + const T* operator->() const { return &Values; } + + T Values; + + std::vector mFields; + std::vector UniformLocation; + +private: + ShaderUniformsGles(const ShaderUniformsGles&) = delete; + ShaderUniformsGles& operator=(const ShaderUniformsGles&) = delete; + + IDataBuffer* mBuffer = nullptr; + +private: + static const char* GetTypeStr(UniformType type) + { + switch (type) + { + default: + case UniformType::Int: return "int"; + case UniformType::UInt: return "uint"; + case UniformType::Float: return "float"; + case UniformType::Vec2: return "vec2"; + case UniformType::Vec3: return "vec3"; + case UniformType::Vec4: return "vec4"; + case UniformType::IVec2: return "ivec2"; + case UniformType::IVec3: return "ivec3"; + case UniformType::IVec4: return "ivec4"; + case UniformType::UVec2: return "uvec2"; + case UniformType::UVec3: return "uvec3"; + case UniformType::UVec4: return "uvec4"; + case UniformType::Mat4: return "mat4"; + } + } +}; + + class FPresentShaderBase { public: virtual ~FPresentShaderBase() {} virtual void Bind() = 0; - ShaderUniforms Uniforms; + ShaderUniformsGles Uniforms; protected: virtual void Init(const char * vtx_shader_name, const char * program_name); diff --git a/src/common/rendering/hwrenderer/data/shaderuniforms.h b/src/common/rendering/hwrenderer/data/shaderuniforms.h index 47a5f9449..2543b52b1 100644 --- a/src/common/rendering/hwrenderer/data/shaderuniforms.h +++ b/src/common/rendering/hwrenderer/data/shaderuniforms.h @@ -40,47 +40,33 @@ public: const char *Name; UniformType Type; std::size_t Offset; - int UniformLocation = -1; // Only used when uniform buffers aren't used }; class UniformBlockDecl { public: - static FString Create(const char *name, const std::vector &fields, int bindingpoint, bool noUniformBuffer = false) + static FString Create(const char *name, const std::vector &fields, int bindingpoint) { FString decl; - - if (noUniformBuffer == false) + FString layout; + if (bindingpoint == -1) { - FString layout; - if (bindingpoint == -1) - { - layout = "push_constant"; - } - else if (screen->glslversion < 4.20) - { - layout = "std140"; - } - else - { - layout.Format("std140, binding = %d", bindingpoint); - } - decl.Format("layout(%s) uniform %s\n{\n", layout.GetChars(), name); - for (size_t i = 0; i < fields.size(); i++) - { - decl.AppendFormat("\t%s %s;\n", GetTypeStr(fields[i].Type), fields[i].Name); - } - decl += "};\n"; + layout = "push_constant"; } - else // Not using buffer + else if (screen->glslversion < 4.20) { - decl += "\n"; - for (size_t i = 0; i < fields.size(); i++) - { - decl.AppendFormat("\tuniform %s %s;\n", GetTypeStr(fields[i].Type), fields[i].Name); - } - decl += "\n"; + layout = "std140"; } + else + { + layout.Format("std140, binding = %d", bindingpoint); + } + decl.Format("layout(%s) uniform %s\n{\n", layout.GetChars(), name); + for (size_t i = 0; i < fields.size(); i++) + { + decl.AppendFormat("\t%s %s;\n", GetTypeStr(fields[i].Type), fields[i].Name); + } + decl += "};\n"; return decl; } @@ -128,12 +114,12 @@ public: return bindingpoint; } - FString CreateDeclaration(const char *name, const std::vector &fields, bool noUniformBuffer = false) + FString CreateDeclaration(const char *name, const std::vector &fields) { mFields = fields; - return UniformBlockDecl::Create(name, fields, bindingpoint, noUniformBuffer); + return UniformBlockDecl::Create(name, fields, bindingpoint); } - + void Init() { if (mBuffer == nullptr) @@ -145,25 +131,24 @@ public: if (mBuffer != nullptr) mBuffer->SetData(sizeof(T), &Values); } - + IDataBuffer* GetBuffer() const { // OpenGL needs to mess around with this in ways that should not be part of the interface. return mBuffer; } - + T *operator->() { return &Values; } const T *operator->() const { return &Values; } T Values; - std::vector mFields; - private: ShaderUniforms(const ShaderUniforms &) = delete; ShaderUniforms &operator=(const ShaderUniforms &) = delete; IDataBuffer *mBuffer = nullptr; + std::vector mFields; };