diff --git a/src/graphics/opengl/gl21device.cpp b/src/graphics/opengl/gl21device.cpp index 5f49eca8..cf10607c 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); - glUniformMatrix4fv(uni_ViewMatrix, 1, GL_FALSE, temp.Array()); + 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) @@ -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( 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 ¢er, 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( 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 c59137e9..5be94a5f 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 b89b90ff..b0886465 100644 --- a/src/graphics/opengl/gl33device.cpp +++ b/src/graphics/opengl/gl33device.cpp @@ -254,11 +254,6 @@ bool CGL33Device::Create() m_texturesEnabled = std::vector (maxTextures, false); m_textureStageParams = std::vector(maxTextures, TextureStageParams()); - // Create auxilliary vertex buffer - m_vertex = CreateStaticBuffer(PRIMITIVE_POINTS, static_cast(nullptr), 1); - m_vertexTex2 = CreateStaticBuffer(PRIMITIVE_POINTS, static_cast(nullptr), 1); - m_vertexCol = CreateStaticBuffer(PRIMITIVE_POINTS, static_cast(nullptr), 1); - int value; if (CConfigFile::GetInstance().GetIntProperty("Setup", "PerPixelLighting", value)) { @@ -396,6 +391,23 @@ bool CGL33Device::Create() m_framebuffers["default"] = MakeUnique(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(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(offsetof(Vertex, coord))); + // Vertex coordinate + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), + reinterpret_cast(offsetof(Vertex, coord))); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(offsetof(Vertex, normal))); - - // Color - glDisableVertexAttribArray(2); - glVertexAttrib4fv(2, color.Array()); - - // Texture coordinate 0 - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(offsetof(Vertex, texCoord))); - - // Texture coordinate 1 - glDisableVertexAttribArray(4); - glVertexAttrib2f(4, 0.0f, 0.0f); - } + // Normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), + reinterpret_cast(offsetof(Vertex, normal))); + // Color + glDisableVertexAttribArray(2); glVertexAttrib4fv(2, color.Array()); + // Texture coordinate 0 + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), + reinterpret_cast(offsetof(Vertex, texCoord))); + + // 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(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; + UpdateDynamicBuffer(buffer, size, vs); - // Vertex coordinate - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), - reinterpret_cast(offsetof(VertexTex2, coord))); + // Vertex coordinate + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), + reinterpret_cast(offsetof(VertexTex2, coord))); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), - reinterpret_cast(offsetof(VertexTex2, normal))); - - // Color - glDisableVertexAttribArray(2); - glVertexAttrib4fv(2, color.Array()); - - // Texture coordinate 0 - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), - reinterpret_cast(offsetof(VertexTex2, texCoord))); - - // Texture coordinate 1 - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), - reinterpret_cast(offsetof(VertexTex2, texCoord2))); - } + // Normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), + reinterpret_cast(offsetof(VertexTex2, normal))); + // Color + glDisableVertexAttribArray(2); glVertexAttrib4fv(2, color.Array()); + // Texture coordinate 0 + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), + reinterpret_cast(offsetof(VertexTex2, texCoord))); + + // Texture coordinate 1 + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), + reinterpret_cast(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(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(offsetof(VertexCol, coord))); + // Vertex coordinate + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol), + reinterpret_cast(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(offsetof(VertexCol, color))); + // Color + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol), + reinterpret_cast(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(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; + UpdateDynamicBuffer(buffer, size, vs); - // Vertex coordinate - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(offsetof(Vertex, coord))); + // Vertex coordinate + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), + reinterpret_cast(offsetof(Vertex, coord))); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(offsetof(Vertex, normal))); - - // Color - glDisableVertexAttribArray(2); - glVertexAttrib4fv(2, color.Array()); - - // Texture coordinate 0 - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(offsetof(Vertex, texCoord))); - - // Texture coordinate 1 - glDisableVertexAttribArray(4); - glVertexAttrib2f(4, 0.0f, 0.0f); - } + // Normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), + reinterpret_cast(offsetof(Vertex, normal))); + // Color + glDisableVertexAttribArray(2); glVertexAttrib4fv(2, color.Array()); + // Texture coordinate 0 + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), + reinterpret_cast(offsetof(Vertex, texCoord))); + + // 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(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(offsetof(VertexTex2, coord))); + // Vertex coordinate + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), + reinterpret_cast(offsetof(VertexTex2, coord))); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), - reinterpret_cast(offsetof(VertexTex2, normal))); - - // Color - glDisableVertexAttribArray(2); - glVertexAttrib4fv(2, color.Array()); - - // Texture coordinate 0 - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), - reinterpret_cast(offsetof(VertexTex2, texCoord))); - - // Texture coordinate 1 - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), - reinterpret_cast(offsetof(VertexTex2, texCoord2))); - } + // Normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), + reinterpret_cast(offsetof(VertexTex2, normal))); + // Color + glDisableVertexAttribArray(2); glVertexAttrib4fv(2, color.Array()); + // Texture coordinate 0 + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), + reinterpret_cast(offsetof(VertexTex2, texCoord))); + + // Texture coordinate 1 + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), + reinterpret_cast(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(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(offsetof(VertexCol, coord))); + // Vertex coordinate + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol), + reinterpret_cast(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(offsetof(VertexCol, color))); + // Color + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol), + reinterpret_cast(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 ¢er, 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 79825dfc..b701276f 100644 --- a/src/graphics/opengl/gl33device.h +++ b/src/graphics/opengl/gl33device.h @@ -44,6 +44,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 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