[colobot] 255/377: Optimizations in graphics engines

Didier Raboud odyx at moszumanska.debian.org
Wed Mar 30 13:34:23 UTC 2016


This is an automated email from the git hooks/post-receive script.

odyx pushed a commit to branch debian/master
in repository colobot.

commit 447b466d6e2fbef50bac3d7557dee90768386953
Author: Tomasz Kapuściński <tomaszkax86 at gmail.com>
Date:   Wed Feb 10 21:40:41 2016 +0100

    Optimizations in graphics engines
---
 src/graphics/opengl/gl21device.cpp |  57 ++---
 src/graphics/opengl/gl21device.h   |   4 +-
 src/graphics/opengl/gl33device.cpp | 418 ++++++++++++++++++-------------------
 src/graphics/opengl/gl33device.h   |  25 ++-
 4 files changed, 242 insertions(+), 262 deletions(-)

diff --git a/src/graphics/opengl/gl21device.cpp b/src/graphics/opengl/gl21device.cpp
index 5f49eca..cf10607 100644
--- a/src/graphics/opengl/gl21device.cpp
+++ b/src/graphics/opengl/gl21device.cpp
@@ -440,6 +440,9 @@ void CGL21Device::SetTransform(TransformType type, const Math::Matrix &matrix)
 
         glUniformMatrix4fv(uni_ModelMatrix, 1, GL_FALSE, m_worldMat.Array());
 
+        m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
+        m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
+
         // normal transform
         Math::Matrix normalMat = matrix;
 
@@ -450,17 +453,21 @@ void CGL21Device::SetTransform(TransformType type, const Math::Matrix &matrix)
     }
     else if (type == TRANSFORM_VIEW)
     {
-        m_viewMat = matrix;
         Math::Matrix scale;
-        Math::LoadScaleMatrix(scale, Math::Vector(1.0f, 1.0f, -1.0f));
-        Math::Matrix temp = Math::MultiplyMatrices(scale, matrix);
+        scale.Set(3, 3, -1.0f);
+        m_viewMat = Math::MultiplyMatrices(scale, matrix);
+
+        m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
+        m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
 
-        glUniformMatrix4fv(uni_ViewMatrix, 1, GL_FALSE, temp.Array());
+        glUniformMatrix4fv(uni_ViewMatrix, 1, GL_FALSE, m_viewMat.Array());
     }
     else if (type == TRANSFORM_PROJECTION)
     {
         m_projectionMat = matrix;
 
+        m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
+
         glUniformMatrix4fv(uni_ProjectionMatrix, 1, GL_FALSE, m_projectionMat.Array());
     }
     else if (type == TRANSFORM_SHADOW)
@@ -514,39 +521,21 @@ void CGL21Device::SetLight(int index, const Light &light)
         glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, 180.0f);
     }
 
-    UpdateLightPosition(index);
-}
-
-void CGL21Device::UpdateLightPosition(int index)
-{
-    assert(index >= 0);
-    assert(index < static_cast<int>( m_lights.size() ));
-
-    glMatrixMode(GL_MODELVIEW);
-
-    glPushMatrix();
-
-    glLoadIdentity();
-    //glScalef(1.0f, 1.0f, -1.0f);
-
-    if (m_lights[index].type == LIGHT_SPOT)
+    if (light.type == LIGHT_SPOT)
     {
-        GLfloat direction[4] = { -m_lights[index].direction.x, -m_lights[index].direction.y, -m_lights[index].direction.z, 1.0f };
+        GLfloat direction[4] = { -light.direction.x, -light.direction.y, -light.direction.z, 1.0f };
         glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction);
     }
-
-    if (m_lights[index].type == LIGHT_DIRECTIONAL)
+    else if (light.type == LIGHT_DIRECTIONAL)
     {
-        GLfloat position[4] = { -m_lights[index].direction.x, -m_lights[index].direction.y, -m_lights[index].direction.z, 0.0f };
+        GLfloat position[4] = { -light.direction.x, -light.direction.y, -light.direction.z, 0.0f };
         glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
     }
     else
     {
-        GLfloat position[4] = { m_lights[index].position.x, m_lights[index].position.y, m_lights[index].position.z, 1.0f };
+        GLfloat position[4] = { light.position.x, light.position.y, light.position.z, 1.0f };
         glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
     }
-
-    glPopMatrix();
 }
 
 void CGL21Device::SetLightEnabled(int index, bool enabled)
@@ -1560,13 +1549,7 @@ void CGL21Device::DestroyStaticBuffer(unsigned int bufferId)
 
 int CGL21Device::ComputeSphereVisibility(const Math::Vector &center, float radius)
 {
-    Math::Matrix m;
-    m = Math::MultiplyMatrices(m_worldMat, m);
-    m = Math::MultiplyMatrices(m_viewMat, m);
-    Math::Matrix sc;
-    Math::LoadScaleMatrix(sc, Math::Vector(1.0f, 1.0f, -1.0f));
-    m = Math::MultiplyMatrices(sc, m);
-    m = Math::MultiplyMatrices(m_projectionMat, m);
+    Math::Matrix &m = m_combinedMatrix;
 
     Math::Vector vec[6];
     float originPlane[6];
@@ -1655,12 +1638,6 @@ void CGL21Device::SetRenderState(RenderState state, bool enabled)
 
         glUniform1i(uni_LightingEnabled, enabled ? 1 : 0);
 
-        if (enabled)
-        {
-            for (int index = 0; index < static_cast<int>( m_lights.size() ); ++index)
-                UpdateLightPosition(index);
-        }
-
         return;
     }
     else if (state == RENDER_STATE_ALPHA_TEST)
diff --git a/src/graphics/opengl/gl21device.h b/src/graphics/opengl/gl21device.h
index c59137e..5be94a5 100644
--- a/src/graphics/opengl/gl21device.h
+++ b/src/graphics/opengl/gl21device.h
@@ -172,8 +172,6 @@ public:
     bool IsFramebufferSupported() override;
 
 private:
-    //! Updates position for given light based on transformation matrices
-    void UpdateLightPosition(int index);
     //! Updates the texture params for given texture stage
     void UpdateTextureParams(int index);
     //! Updates texture status
@@ -193,6 +191,8 @@ private:
     Math::Matrix m_modelviewMat;
     //! Current projection matrix
     Math::Matrix m_projectionMat;
+    //! Combined world-view-projection matrix
+    Math::Matrix m_combinedMatrix;
 
     //! The current material
     Material m_material;
diff --git a/src/graphics/opengl/gl33device.cpp b/src/graphics/opengl/gl33device.cpp
index b89b90f..b088646 100644
--- a/src/graphics/opengl/gl33device.cpp
+++ b/src/graphics/opengl/gl33device.cpp
@@ -254,11 +254,6 @@ bool CGL33Device::Create()
     m_texturesEnabled    = std::vector<bool>              (maxTextures, false);
     m_textureStageParams = std::vector<TextureStageParams>(maxTextures, TextureStageParams());
 
-    // Create auxilliary vertex buffer
-    m_vertex = CreateStaticBuffer(PRIMITIVE_POINTS, static_cast<Vertex*>(nullptr), 1);
-    m_vertexTex2 = CreateStaticBuffer(PRIMITIVE_POINTS, static_cast<VertexTex2*>(nullptr), 1);
-    m_vertexCol = CreateStaticBuffer(PRIMITIVE_POINTS, static_cast<VertexCol*>(nullptr), 1);
-
     int value;
     if (CConfigFile::GetInstance().GetIntProperty("Setup", "PerPixelLighting", value))
     {
@@ -396,6 +391,23 @@ bool CGL33Device::Create()
 
     m_framebuffers["default"] = MakeUnique<CDefaultFramebuffer>(framebufferParams);
 
+    // create dynamic buffers
+
+    glGenVertexArrays(1, &m_auxiliaryVAO);
+
+    for (int i = 0; i < 64; i++)
+    {
+        DynamicBuffer buffer;
+
+        glGenBuffers(1, &buffer.vbo);
+        BindVBO(buffer.vbo);
+
+        buffer.size = 1024;
+        glBufferData(GL_ARRAY_BUFFER, buffer.size, nullptr, GL_STREAM_DRAW);
+
+        m_buffers.push_back(buffer);
+    }
+
     GetLogger()->Info("CDevice created successfully\n");
 
     return true;
@@ -417,6 +429,14 @@ void CGL33Device::Destroy()
     // Should not be strictly necessary, but just in case
     DestroyAllTextures();
 
+    // delete all dynamic buffers
+    for (auto& buffer : m_buffers)
+    {
+        glDeleteBuffers(1, &buffer.vbo);
+    }
+    glDeleteVertexArrays(1, &m_auxiliaryVAO);
+    m_buffers.clear();
+
     m_lights.clear();
     m_lightsEnabled.clear();
 
@@ -470,6 +490,9 @@ void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix)
         m_worldMat = matrix;
         glUniformMatrix4fv(uni_ModelMatrix, 1, GL_FALSE, m_worldMat.Array());
 
+        m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
+        m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
+
         // normal transform
         Math::Matrix normalMat = matrix;
 
@@ -480,15 +503,21 @@ void CGL33Device::SetTransform(TransformType type, const Math::Matrix &matrix)
     }
     else if (type == TRANSFORM_VIEW)
     {
-        m_viewMat = matrix;
         Math::Matrix scale;
-        Math::LoadScaleMatrix(scale, Math::Vector(1.0f, 1.0f, -1.0f));
-        Math::Matrix temp = Math::MultiplyMatrices(scale, matrix);
-        glUniformMatrix4fv(uni_ViewMatrix, 1, GL_FALSE, temp.Array());
+        scale.Set(3, 3, -1.0f);
+        m_viewMat = Math::MultiplyMatrices(scale, matrix);
+
+        m_modelviewMat = Math::MultiplyMatrices(m_viewMat, m_worldMat);
+        m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
+
+        glUniformMatrix4fv(uni_ViewMatrix, 1, GL_FALSE, m_viewMat.Array());
     }
     else if (type == TRANSFORM_PROJECTION)
     {
         m_projectionMat = matrix;
+
+        m_combinedMatrix = Math::MultiplyMatrices(m_projectionMat, m_modelviewMat);
+
         glUniformMatrix4fv(uni_ProjectionMatrix, 1, GL_FALSE, m_projectionMat.Array());
     }
     else if (type == TRANSFORM_SHADOW)
@@ -1186,162 +1215,138 @@ void CGL33Device::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode
 void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount, Color color)
 {
     Vertex* vs = const_cast<Vertex*>(vertices);
-    VertexBufferInfo &info = m_vboObjects[m_vertex];
+
+    DynamicBuffer &buffer = m_buffers[m_nextBuffer];
 
     unsigned int size = vertexCount * sizeof(Vertex);
 
-    BindVAO(info.vao);
-    BindVBO(info.vbo);
+    BindVAO(m_auxiliaryVAO);
+    BindVBO(buffer.vbo);
 
-    // If needed vertex data is too large, increase the size of buffer
-    if (info.size >= size)
-    {
-        glBufferSubData(GL_ARRAY_BUFFER, 0, size, vs);
-    }
-    else
-    {
-        CLogger::GetInstance().Debug("Resizing dynamic buffer: %d->%d\n", info.size, size);
-        glBufferData(GL_ARRAY_BUFFER, size, vs, GL_STREAM_DRAW);
-        info.size = size;
+    UpdateDynamicBuffer(buffer, size, vs);
 
-        // Vertex coordinate
-        glEnableVertexAttribArray(0);
-        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
-            reinterpret_cast<void*>(offsetof(Vertex, coord)));
-
-        // Normal
-        glEnableVertexAttribArray(1);
-        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
-            reinterpret_cast<void*>(offsetof(Vertex, normal)));
+    // Vertex coordinate
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
+        reinterpret_cast<void*>(offsetof(Vertex, coord)));
 
-        // Color
-        glDisableVertexAttribArray(2);
-        glVertexAttrib4fv(2, color.Array());
+    // Normal
+    glEnableVertexAttribArray(1);
+    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
+        reinterpret_cast<void*>(offsetof(Vertex, normal)));
 
-        // Texture coordinate 0
-        glEnableVertexAttribArray(3);
-        glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
-            reinterpret_cast<void*>(offsetof(Vertex, texCoord)));
+    // Color
+    glDisableVertexAttribArray(2);
+    glVertexAttrib4fv(2, color.Array());
 
-        // Texture coordinate 1
-        glDisableVertexAttribArray(4);
-        glVertexAttrib2f(4, 0.0f, 0.0f);
-    }
+    // Texture coordinate 0
+    glEnableVertexAttribArray(3);
+    glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
+        reinterpret_cast<void*>(offsetof(Vertex, texCoord)));
 
-    glVertexAttrib4fv(2, color.Array());
+    // Texture coordinate 1
+    glDisableVertexAttribArray(4);
+    glVertexAttrib2f(4, 0.0f, 0.0f);
 
     UpdateRenderingMode();
 
     glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
+
+    m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
 }
 
 void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, Color color)
 {
     VertexTex2* vs = const_cast<VertexTex2*>(vertices);
-    VertexBufferInfo &info = m_vboObjects[m_vertexTex2];
+
+    DynamicBuffer &buffer = m_buffers[m_nextBuffer];
 
     unsigned int size = vertexCount * sizeof(VertexTex2);
 
-    BindVAO(info.vao);
-    BindVBO(info.vbo);
+    BindVAO(m_auxiliaryVAO);
+    BindVBO(buffer.vbo);
 
-    // If needed vertex data is too large, increase the size of buffer
-    if (info.size >= size)
-    {
-        glBufferSubData(GL_ARRAY_BUFFER, 0, size, vs);
-    }
-    else
-    {
-        CLogger::GetInstance().Debug("Resizing dynamic buffer: %d->%d\n", info.size, size);
-        glBufferData(GL_ARRAY_BUFFER, size, vs, GL_STREAM_DRAW);
-        info.size = size;
-
-        // Vertex coordinate
-        glEnableVertexAttribArray(0);
-        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
-            reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
+    UpdateDynamicBuffer(buffer, size, vs);
 
-        // Normal
-        glEnableVertexAttribArray(1);
-        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
-            reinterpret_cast<void*>(offsetof(VertexTex2, normal)));
+    // Vertex coordinate
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
+        reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
 
-        // Color
-        glDisableVertexAttribArray(2);
-        glVertexAttrib4fv(2, color.Array());
+    // Normal
+    glEnableVertexAttribArray(1);
+    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
+        reinterpret_cast<void*>(offsetof(VertexTex2, normal)));
 
-        // Texture coordinate 0
-        glEnableVertexAttribArray(3);
-        glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
-            reinterpret_cast<void*>(offsetof(VertexTex2, texCoord)));
+    // Color
+    glDisableVertexAttribArray(2);
+    glVertexAttrib4fv(2, color.Array());
 
-        // Texture coordinate 1
-        glEnableVertexAttribArray(4);
-        glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
-            reinterpret_cast<void*>(offsetof(VertexTex2, texCoord2)));
-    }
+    // Texture coordinate 0
+    glEnableVertexAttribArray(3);
+    glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
+        reinterpret_cast<void*>(offsetof(VertexTex2, texCoord)));
 
-    glVertexAttrib4fv(2, color.Array());
+    // Texture coordinate 1
+    glEnableVertexAttribArray(4);
+    glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
+        reinterpret_cast<void*>(offsetof(VertexTex2, texCoord2)));
 
     UpdateRenderingMode();
 
     glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
+
+    m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
 }
 
 void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount)
 {
     VertexCol* vs = const_cast<VertexCol*>(vertices);
-    VertexBufferInfo &info = m_vboObjects[m_vertexCol];
+
+    DynamicBuffer &buffer = m_buffers[m_nextBuffer];
 
     unsigned int size = vertexCount * sizeof(VertexCol);
 
-    BindVAO(info.vao);
-    BindVBO(info.vbo);
+    BindVAO(m_auxiliaryVAO);
+    BindVBO(buffer.vbo);
 
-    // If needed vertex data is too large, increase the size of buffer
-    if (info.size >= size)
-    {
-        glBufferSubData(GL_ARRAY_BUFFER, 0, size, vs);
-    }
-    else
-    {
-        CLogger::GetInstance().Debug("Resizing dynamic buffer: %d->%d\n", info.size, size);
-        glBufferData(GL_ARRAY_BUFFER, size, vs, GL_STREAM_DRAW);
-        info.size = size;
+    UpdateDynamicBuffer(buffer, size, vs);
 
-        // Vertex coordinate
-        glEnableVertexAttribArray(0);
-        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
-            reinterpret_cast<void*>(offsetof(VertexCol, coord)));
+    // Vertex coordinate
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
+        reinterpret_cast<void*>(offsetof(VertexCol, coord)));
 
-        // Normal
-        glDisableVertexAttribArray(1);
-        glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
+    // Normal
+    glDisableVertexAttribArray(1);
+    glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
 
-        // Color
-        glEnableVertexAttribArray(2);
-        glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
-            reinterpret_cast<void*>(offsetof(VertexCol, color)));
+    // Color
+    glEnableVertexAttribArray(2);
+    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
+        reinterpret_cast<void*>(offsetof(VertexCol, color)));
 
-        // Texture coordinate 0
-        glDisableVertexAttribArray(3);
-        glVertexAttrib2f(3, 0.0f, 0.0f);
+    // Texture coordinate 0
+    glDisableVertexAttribArray(3);
+    glVertexAttrib2f(3, 0.0f, 0.0f);
 
-        // Texture coordinate 1
-        glDisableVertexAttribArray(4);
-        glVertexAttrib2f(4, 0.0f, 0.0f);
-    }
+    // Texture coordinate 1
+    glDisableVertexAttribArray(4);
+    glVertexAttrib2f(4, 0.0f, 0.0f);
 
     UpdateRenderingMode();
 
     glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
+
+    m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
 }
 
 void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
     int first[], int count[], int drawCount, Color color)
 {
     Vertex* vs = const_cast<Vertex*>(vertices);
-    VertexBufferInfo &info = m_vboObjects[m_vertex];
+
+    DynamicBuffer &buffer = m_buffers[m_nextBuffer];
 
     int vertexCount = 0;
 
@@ -1355,56 +1360,47 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
 
     unsigned int size = vertexCount * sizeof(Vertex);
 
-    BindVAO(info.vao);
-    BindVBO(info.vbo);
+    BindVAO(m_auxiliaryVAO);
+    BindVBO(buffer.vbo);
 
-    // If needed vertex data is too large, increase the size of buffer
-    if (info.size >= size)
-    {
-        glBufferSubData(GL_ARRAY_BUFFER, 0, size, vs);
-    }
-    else
-    {
-        CLogger::GetInstance().Debug("Resizing dynamic buffer: %d->%d\n", info.size, size);
-        glBufferData(GL_ARRAY_BUFFER, size, vs, GL_STREAM_DRAW);
-        info.size = size;
-
-        // Vertex coordinate
-        glEnableVertexAttribArray(0);
-        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
-            reinterpret_cast<void*>(offsetof(Vertex, coord)));
+    UpdateDynamicBuffer(buffer, size, vs);
 
-        // Normal
-        glEnableVertexAttribArray(1);
-        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
-            reinterpret_cast<void*>(offsetof(Vertex, normal)));
+    // Vertex coordinate
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
+        reinterpret_cast<void*>(offsetof(Vertex, coord)));
 
-        // Color
-        glDisableVertexAttribArray(2);
-        glVertexAttrib4fv(2, color.Array());
+    // Normal
+    glEnableVertexAttribArray(1);
+    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
+        reinterpret_cast<void*>(offsetof(Vertex, normal)));
 
-        // Texture coordinate 0
-        glEnableVertexAttribArray(3);
-        glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
-            reinterpret_cast<void*>(offsetof(Vertex, texCoord)));
+    // Color
+    glDisableVertexAttribArray(2);
+    glVertexAttrib4fv(2, color.Array());
 
-        // Texture coordinate 1
-        glDisableVertexAttribArray(4);
-        glVertexAttrib2f(4, 0.0f, 0.0f);
-    }
+    // Texture coordinate 0
+    glEnableVertexAttribArray(3);
+    glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
+        reinterpret_cast<void*>(offsetof(Vertex, texCoord)));
 
-    glVertexAttrib4fv(2, color.Array());
+    // Texture coordinate 1
+    glDisableVertexAttribArray(4);
+    glVertexAttrib2f(4, 0.0f, 0.0f);
 
     UpdateRenderingMode();
 
     glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
+
+    m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
 }
 
 void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
     int first[], int count[], int drawCount, Color color)
 {
     VertexTex2* vs = const_cast<VertexTex2*>(vertices);
-    VertexBufferInfo &info = m_vboObjects[m_vertexTex2];
+
+    DynamicBuffer &buffer = m_buffers[m_nextBuffer];
 
     int vertexCount = 0;
 
@@ -1418,57 +1414,48 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
 
     unsigned int size = vertexCount * sizeof(VertexTex2);
 
-    BindVAO(info.vao);
-    BindVBO(info.vbo);
+    BindVAO(m_auxiliaryVAO);
+    BindVBO(buffer.vbo);
 
-    // If needed vertex data is too large, increase the size of buffer
-    if (info.size >= size)
-    {
-        glBufferSubData(GL_ARRAY_BUFFER, 0, size, vs);
-    }
-    else
-    {
-        CLogger::GetInstance().Debug("Resizing dynamic buffer: %d->%d\n", info.size, size);
-        glBufferData(GL_ARRAY_BUFFER, size, vs, GL_STREAM_DRAW);
-        info.size = size;
+    UpdateDynamicBuffer(buffer, size, vs);
 
-        // Vertex coordinate
-        glEnableVertexAttribArray(0);
-        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
-            reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
-
-        // Normal
-        glEnableVertexAttribArray(1);
-        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
-            reinterpret_cast<void*>(offsetof(VertexTex2, normal)));
+    // Vertex coordinate
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
+        reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
 
-        // Color
-        glDisableVertexAttribArray(2);
-        glVertexAttrib4fv(2, color.Array());
+    // Normal
+    glEnableVertexAttribArray(1);
+    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
+        reinterpret_cast<void*>(offsetof(VertexTex2, normal)));
 
-        // Texture coordinate 0
-        glEnableVertexAttribArray(3);
-        glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
-            reinterpret_cast<void*>(offsetof(VertexTex2, texCoord)));
+    // Color
+    glDisableVertexAttribArray(2);
+    glVertexAttrib4fv(2, color.Array());
 
-        // Texture coordinate 1
-        glEnableVertexAttribArray(4);
-        glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
-            reinterpret_cast<void*>(offsetof(VertexTex2, texCoord2)));
-    }
+    // Texture coordinate 0
+    glEnableVertexAttribArray(3);
+    glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
+        reinterpret_cast<void*>(offsetof(VertexTex2, texCoord)));
 
-    glVertexAttrib4fv(2, color.Array());
+    // Texture coordinate 1
+    glEnableVertexAttribArray(4);
+    glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
+        reinterpret_cast<void*>(offsetof(VertexTex2, texCoord2)));
 
     UpdateRenderingMode();
 
     glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
+
+    m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
 }
 
 void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
     int first[], int count[], int drawCount)
 {
     VertexCol* vs = const_cast<VertexCol*>(vertices);
-    VertexBufferInfo &info = m_vboObjects[m_vertexCol];
+
+    DynamicBuffer &buffer = m_buffers[m_nextBuffer];
 
     int vertexCount = 0;
 
@@ -1482,46 +1469,38 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
 
     unsigned int size = vertexCount * sizeof(VertexCol);
 
-    BindVAO(info.vao);
-    BindVBO(info.vbo);
+    BindVAO(m_auxiliaryVAO);
+    BindVBO(buffer.vbo);
 
-    // If needed vertex data is too large, increase the size of buffer
-    if (info.size >= size)
-    {
-        glBufferSubData(GL_ARRAY_BUFFER, 0, size, vs);
-    }
-    else
-    {
-        CLogger::GetInstance().Debug("Resizing dynamic buffer: %d->%d\n", info.size, size);
-        glBufferData(GL_ARRAY_BUFFER, size, vs, GL_STREAM_DRAW);
-        info.size = size;
+    UpdateDynamicBuffer(buffer, size, vs);
 
-        // Vertex coordinate
-        glEnableVertexAttribArray(0);
-        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
-            reinterpret_cast<void*>(offsetof(VertexCol, coord)));
+    // Vertex coordinate
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
+        reinterpret_cast<void*>(offsetof(VertexCol, coord)));
 
-        // Normal
-        glDisableVertexAttribArray(1);
-        glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
+    // Normal
+    glDisableVertexAttribArray(1);
+    glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
 
-        // Color
-        glEnableVertexAttribArray(2);
-        glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
-            reinterpret_cast<void*>(offsetof(VertexCol, color)));
+    // Color
+    glEnableVertexAttribArray(2);
+    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
+        reinterpret_cast<void*>(offsetof(VertexCol, color)));
 
-        // Texture coordinate 0
-        glDisableVertexAttribArray(3);
-        glVertexAttrib2f(3, 0.0f, 0.0f);
+    // Texture coordinate 0
+    glDisableVertexAttribArray(3);
+    glVertexAttrib2f(3, 0.0f, 0.0f);
 
-        // Texture coordinate 1
-        glDisableVertexAttribArray(4);
-        glVertexAttrib2f(4, 0.0f, 0.0f);
-    }
+    // Texture coordinate 1
+    glDisableVertexAttribArray(4);
+    glVertexAttrib2f(4, 0.0f, 0.0f);
 
     UpdateRenderingMode();
 
     glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
+
+    m_nextBuffer = (m_nextBuffer + 1) % m_buffers.size();
 }
 
 unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
@@ -1870,13 +1849,7 @@ void CGL33Device::DestroyStaticBuffer(unsigned int bufferId)
 
 int CGL33Device::ComputeSphereVisibility(const Math::Vector &center, float radius)
 {
-    Math::Matrix m;
-    m = Math::MultiplyMatrices(m_worldMat, m);
-    m = Math::MultiplyMatrices(m_viewMat, m);
-    Math::Matrix sc;
-    Math::LoadScaleMatrix(sc, Math::Vector(1.0f, 1.0f, -1.0f));
-    m = Math::MultiplyMatrices(sc, m);
-    m = Math::MultiplyMatrices(m_projectionMat, m);
+    Math::Matrix &m = m_combinedMatrix;
 
     Math::Vector vec[6];
     float originPlane[6];
@@ -2163,6 +2136,19 @@ inline void CGL33Device::BindVAO(GLuint vao)
     m_currentVAO = vao;
 }
 
+inline void CGL33Device::UpdateDynamicBuffer(DynamicBuffer &buffer, unsigned int size, void* data)
+{
+    if (buffer.size < size)
+    {
+        glBufferData(GL_ARRAY_BUFFER, size, data, GL_STREAM_DRAW);
+        buffer.size = size;
+    }
+    else
+    {
+        glBufferSubData(GL_ARRAY_BUFFER, 0, size, data);
+    }
+}
+
 bool CGL33Device::IsAnisotropySupported()
 {
     return m_anisotropyAvailable;
diff --git a/src/graphics/opengl/gl33device.h b/src/graphics/opengl/gl33device.h
index 79825df..b701276 100644
--- a/src/graphics/opengl/gl33device.h
+++ b/src/graphics/opengl/gl33device.h
@@ -45,6 +45,16 @@ namespace Gfx
 {
 
 /**
+  \struct DynamicBuffer
+  \brief Structure for storing dynamic buffer
+*/
+struct DynamicBuffer
+{
+    GLuint vbo;
+    unsigned int size;
+};
+
+/**
   \class CGL33Device
   \brief Implementation of CDevice interface in OpenGL 3.3
 
@@ -186,6 +196,9 @@ private:
     //! Binds VAO
     inline void BindVAO(GLuint vao);
 
+    //! Updates dynamic buffer
+    inline void UpdateDynamicBuffer(DynamicBuffer &buffer, unsigned int size, void* data);
+
 private:
     //! Current config
     DeviceConfig m_config;
@@ -198,6 +211,8 @@ private:
     Math::Matrix m_modelviewMat;
     //! Current projection matrix
     Math::Matrix m_projectionMat;
+    //! Combined world-view-projection matrix
+    Math::Matrix m_combinedMatrix;
 
     //! The current material
     Material m_material;
@@ -264,10 +279,12 @@ private:
     //! true enables per-pixel lighting
     bool m_perPixelLighting = false;
 
-    //! Auxilliary vertex buffers for general rendering
-    unsigned int m_vertex = 0;
-    unsigned int m_vertexTex2 = 0;
-    unsigned int m_vertexCol = 0;
+    //! Auxilliary buffers for rendering primitives with DrawPrimitive*
+    std::vector<DynamicBuffer> m_buffers = {};
+    //! Index to next auxilliary buffer
+    int m_nextBuffer = 0;
+    //! Auxiliary VAO for rendering primitives with DrawPrimitive*
+    GLuint m_auxiliaryVAO = 0;
 
     // Uniforms
     //! Projection matrix

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git



More information about the Pkg-games-commits mailing list