From 9960cc47945a66702978e872af80d9472fa241d8 Mon Sep 17 00:00:00 2001 From: RuiwenTang Date: Thu, 10 Aug 2023 18:07:41 +0800 Subject: [PATCH] gl_engine: use vertex array buffer and index buffer when render primitive VAO is new object in modern GL API, which can split and manage vertex buffer and attribute state. This is optional in GLES and is mandatory in GL. Also index buffer is faster then pass cpu data in GL draw call. --- src/lib/gl_engine/tvgGlGeometry.cpp | 27 +++++++++++++++++++++------ src/lib/gl_engine/tvgGlGeometry.h | 6 +++++- src/lib/gl_engine/tvgGlGpuBuffer.h | 2 +- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/lib/gl_engine/tvgGlGeometry.cpp b/src/lib/gl_engine/tvgGlGeometry.cpp index 68dd1fa2..bcce3414 100644 --- a/src/lib/gl_engine/tvgGlGeometry.cpp +++ b/src/lib/gl_engine/tvgGlGeometry.cpp @@ -29,6 +29,13 @@ #define NORMALIZED_LEFT_3D -1.0f #define NORMALIZED_RIGHT_3D 1.0f +GlGeometry::~GlGeometry() +{ + if (mVao) { + glDeleteVertexArrays(1, &mVao); + } +} + uint32_t GlGeometry::getPrimitiveCount() { return mPrimitives.size(); @@ -214,7 +221,8 @@ bool GlGeometry::tesselate(TVG_UNUSED const RenderShape& rshape, float viewWd, f void GlGeometry::disableVertex(uint32_t location) { GL_CHECK(glDisableVertexAttribArray(location)); - mGpuBuffer->unbind(GlGpuBuffer::Target::ARRAY_BUFFER); + mVertexBuffer->unbind(GlGpuBuffer::Target::ARRAY_BUFFER); + mIndexBuffer->unbind(GlGpuBuffer::Target::ELEMENT_ARRAY_BUFFER); } @@ -222,20 +230,27 @@ void GlGeometry::draw(const uint32_t location, const uint32_t primitiveIndex, Re { if (primitiveIndex >= mPrimitives.size()) return; + if (mVao == 0) glGenVertexArrays(1, &mVao); + glBindVertexArray(mVao); + VertexDataArray& geometry = (flag == RenderUpdateFlag::Stroke) ? mPrimitives[primitiveIndex].mStroke : mPrimitives[primitiveIndex].mFill; updateBuffer(location, geometry); - GL_CHECK(glDrawElements(GL_TRIANGLES, geometry.indices.size(), GL_UNSIGNED_INT, geometry.indices.data())); + + GL_CHECK(glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), 0)); + GL_CHECK(glEnableVertexAttribArray(location)); + + GL_CHECK(glDrawElements(GL_TRIANGLES, geometry.indices.size(), GL_UNSIGNED_INT, 0)); } void GlGeometry::updateBuffer(uint32_t location, const VertexDataArray& vertexArray) { - if (mGpuBuffer.get() == nullptr) mGpuBuffer = make_unique(); + if (mVertexBuffer == nullptr) mVertexBuffer = std::make_unique(); + if (mIndexBuffer == nullptr) mIndexBuffer = std::make_unique(); - mGpuBuffer->updateBufferData(GlGpuBuffer::Target::ARRAY_BUFFER, vertexArray.vertices.size() * sizeof(VertexData), vertexArray.vertices.data()); - GL_CHECK(glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), 0)); - GL_CHECK(glEnableVertexAttribArray(location)); + mVertexBuffer->updateBufferData(GlGpuBuffer::Target::ARRAY_BUFFER, vertexArray.vertices.size() * sizeof(VertexData), vertexArray.vertices.data()); + mIndexBuffer->updateBufferData(GlGpuBuffer::Target::ELEMENT_ARRAY_BUFFER, vertexArray.indices.size() * sizeof(uint32_t), vertexArray.indices.data()); } diff --git a/src/lib/gl_engine/tvgGlGeometry.h b/src/lib/gl_engine/tvgGlGeometry.h index 9689daf8..659856f3 100644 --- a/src/lib/gl_engine/tvgGlGeometry.h +++ b/src/lib/gl_engine/tvgGlGeometry.h @@ -266,6 +266,8 @@ class GlGeometry { public: + ~GlGeometry(); + uint32_t getPrimitiveCount(); const GlSize getPrimitiveSize(const uint32_t primitiveIndex) const; bool decomposeOutline(const RenderShape& rshape); @@ -290,7 +292,9 @@ private: void decomposeCubicCurve(GlPrimitive& primitve, const GlPoint &pt1, const GlPoint &cpt1, const GlPoint &cpt2, const GlPoint &pt2, GlPoint &min, GlPoint &max); void updateBuffer(const uint32_t location, const VertexDataArray& vertexArray); - unique_ptr mGpuBuffer; + GLuint mVao = 0; + std::unique_ptr mVertexBuffer; + std::unique_ptr mIndexBuffer; vector mPrimitives; GlTransform mTransform; }; diff --git a/src/lib/gl_engine/tvgGlGpuBuffer.h b/src/lib/gl_engine/tvgGlGpuBuffer.h index 3e9f10f8..0587466f 100644 --- a/src/lib/gl_engine/tvgGlGpuBuffer.h +++ b/src/lib/gl_engine/tvgGlGpuBuffer.h @@ -31,7 +31,7 @@ public: enum class Target { ARRAY_BUFFER = GL_ARRAY_BUFFER, - ELEMENT_ARRAY_BUFFER = GL_ARRAY_BUFFER + ELEMENT_ARRAY_BUFFER = GL_ELEMENT_ARRAY_BUFFER, }; GlGpuBuffer();