diff --git a/src/graphics/core/renderers.h b/src/graphics/core/renderers.h index 9e7c8580..63691472 100644 --- a/src/graphics/core/renderers.h +++ b/src/graphics/core/renderers.h @@ -61,6 +61,8 @@ public: virtual void SetProjection(float left, float right, float bottom, float top) = 0; //! Sets texture, setting texture 0 means using white texture virtual void SetTexture(const Texture& texture) = 0; + //! Sets color + virtual void SetColor(const glm::vec4& color) = 0; //! Draws primitive virtual void DrawPrimitive(PrimitiveType type, int count, const Vertex2D* vertices) = 0; diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index ff63a16e..08bf9339 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -1976,6 +1976,7 @@ void CEngine::SetState(int state, const Color& color) return; m_device->GetUIRenderer()->Flush(); + m_device->GetUIRenderer()->SetColor({ color.r, color.g, color.b, color.a }); m_lastState = state; m_lastColor = color; diff --git a/src/graphics/opengl/gl33renderers.cpp b/src/graphics/opengl/gl33renderers.cpp index 7bfc08cb..fefbb6cb 100644 --- a/src/graphics/opengl/gl33renderers.cpp +++ b/src/graphics/opengl/gl33renderers.cpp @@ -36,7 +36,7 @@ CGL33UIRenderer::CGL33UIRenderer(CGL33Device* device) m_program = LinkProgram(2, shaders); if (m_program == 0) { - GetLogger()->Error("Cound not link shader program for normal rendering\n"); + GetLogger()->Error("Cound not link shader program for interface renderer\n"); return; } @@ -45,9 +45,21 @@ CGL33UIRenderer::CGL33UIRenderer(CGL33Device* device) glUseProgram(m_program); - m_projectionMatrix = glGetUniformLocation(m_program, "uni_ProjectionMatrix"); - auto matrix = glm::ortho(0.0f, +1.0f, 0.0f, +1.0f); - glUniformMatrix4fv(m_projectionMatrix, 1, GL_FALSE, glm::value_ptr(matrix)); + // Create uniform buffer + glGenBuffers(1, &m_uniformBuffer); + + m_uniforms.projectionMatrix = glm::ortho(0.0f, +1.0f, 0.0f, +1.0f); + m_uniforms.color = { 1.0f, 1.0f, 1.0f, 1.0f }; + + m_uniformsDirty = true; + + UpdateUniforms(); + + // Bind uniform block to uniform buffer binding + GLuint blockIndex = glGetUniformBlockIndex(m_program, "Uniforms"); + + glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_uniformBuffer); + glUniformBlockBinding(m_program, blockIndex, 0); // Set texture unit to 8th auto texture = glGetUniformLocation(m_program, "uni_Texture"); @@ -91,13 +103,8 @@ void CGL33UIRenderer::SetProjection(float left, float right, float bottom, float { Flush(); - glUseProgram(m_program); - - auto matrix = glm::ortho(left, right, bottom, top); - - glUniformMatrix4fv(m_projectionMatrix, 1, GL_FALSE, glm::value_ptr(matrix)); - - m_device->Restore(); + m_uniforms.projectionMatrix = glm::ortho(left, right, bottom, top); + m_uniformsDirty = true; } void CGL33UIRenderer::SetTexture(const Texture& texture) @@ -116,6 +123,14 @@ void CGL33UIRenderer::SetTexture(const Texture& texture) glBindTexture(GL_TEXTURE_2D, m_currentTexture); } +void CGL33UIRenderer::SetColor(const glm::vec4& color) +{ + Flush(); + + m_uniforms.color = color; + m_uniformsDirty = true; +} + void CGL33UIRenderer::DrawPrimitive(PrimitiveType type, int count, const Vertex2D* vertices) { // If too much data would be buffered, flush @@ -137,8 +152,12 @@ void CGL33UIRenderer::Flush() { if (m_types.empty()) return; + UpdateUniforms(); + glUseProgram(m_program); + glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_uniformBuffer); + // Increase buffer size if necessary size_t size = m_buffer.size() * sizeof(Vertex2D); @@ -190,4 +209,14 @@ void CGL33UIRenderer::Flush() m_device->Restore(); } +void CGL33UIRenderer::UpdateUniforms() +{ + if (!m_uniformsDirty) return; + + glBindBuffer(GL_COPY_WRITE_BUFFER, m_uniformBuffer); + glBufferData(GL_COPY_WRITE_BUFFER, sizeof(Uniforms), nullptr, GL_STREAM_DRAW); + glBufferSubData(GL_COPY_WRITE_BUFFER, 0, sizeof(Uniforms), &m_uniforms); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); +} + } // namespace Gfx diff --git a/src/graphics/opengl/gl33renderers.h b/src/graphics/opengl/gl33renderers.h index bdd26c89..74810abe 100644 --- a/src/graphics/opengl/gl33renderers.h +++ b/src/graphics/opengl/gl33renderers.h @@ -45,16 +45,29 @@ public: virtual void SetProjection(float left, float right, float bottom, float top) override; virtual void SetTexture(const Texture& texture) override; + virtual void SetColor(const glm::vec4& color) override; virtual void DrawPrimitive(PrimitiveType type, int count, const Vertex2D* vertices) override; virtual void Flush() override; private: + void UpdateUniforms(); + CGL33Device* const m_device; - // location of uni_ProjectionMatrix uniform - GLint m_projectionMatrix = -1; + // Uniform data + struct Uniforms + { + glm::mat4 projectionMatrix; + glm::vec4 color; + }; + Uniforms m_uniforms; + // true means uniforms need to be updated + bool m_uniformsDirty = false; + + // Uniform buffer object + GLuint m_uniformBuffer = 0; // Vertex buffer object GLuint m_bufferVBO = 0; diff --git a/src/graphics/opengl/shaders/gl33/ui_vs.glsl b/src/graphics/opengl/shaders/gl33/ui_vs.glsl index 8629eaae..f610b2e5 100644 --- a/src/graphics/opengl/shaders/gl33/ui_vs.glsl +++ b/src/graphics/opengl/shaders/gl33/ui_vs.glsl @@ -20,12 +20,16 @@ // VERTEX SHADER - UI RENDERER #version 330 core -uniform mat4 uni_ProjectionMatrix; - layout(location = 0) in vec4 in_VertexCoord; layout(location = 1) in vec2 in_TexCoord; layout(location = 2) in vec4 in_Color; +uniform Uniforms +{ + mat4 uni_Matrix; + vec4 uni_Color; +}; + out VertexData { vec4 Color; @@ -34,8 +38,8 @@ out VertexData void main() { - gl_Position = uni_ProjectionMatrix * in_VertexCoord; + gl_Position = uni_Matrix * in_VertexCoord; - data.Color = in_Color; + data.Color = uni_Color * in_Color; data.TexCoord = in_TexCoord; }