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.
This commit is contained in:
RuiwenTang 2023-08-10 18:07:41 +08:00 committed by Hermet Park
parent 7a35ff4d4b
commit 9960cc4794
3 changed files with 27 additions and 8 deletions

View file

@ -29,6 +29,13 @@
#define NORMALIZED_LEFT_3D -1.0f #define NORMALIZED_LEFT_3D -1.0f
#define NORMALIZED_RIGHT_3D 1.0f #define NORMALIZED_RIGHT_3D 1.0f
GlGeometry::~GlGeometry()
{
if (mVao) {
glDeleteVertexArrays(1, &mVao);
}
}
uint32_t GlGeometry::getPrimitiveCount() uint32_t GlGeometry::getPrimitiveCount()
{ {
return mPrimitives.size(); return mPrimitives.size();
@ -214,7 +221,8 @@ bool GlGeometry::tesselate(TVG_UNUSED const RenderShape& rshape, float viewWd, f
void GlGeometry::disableVertex(uint32_t location) void GlGeometry::disableVertex(uint32_t location)
{ {
GL_CHECK(glDisableVertexAttribArray(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 (primitiveIndex >= mPrimitives.size()) return;
if (mVao == 0) glGenVertexArrays(1, &mVao);
glBindVertexArray(mVao);
VertexDataArray& geometry = (flag == RenderUpdateFlag::Stroke) ? mPrimitives[primitiveIndex].mStroke : mPrimitives[primitiveIndex].mFill; VertexDataArray& geometry = (flag == RenderUpdateFlag::Stroke) ? mPrimitives[primitiveIndex].mStroke : mPrimitives[primitiveIndex].mFill;
updateBuffer(location, geometry); 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) void GlGeometry::updateBuffer(uint32_t location, const VertexDataArray& vertexArray)
{ {
if (mGpuBuffer.get() == nullptr) mGpuBuffer = make_unique<GlGpuBuffer>(); if (mVertexBuffer == nullptr) mVertexBuffer = std::make_unique<GlGpuBuffer>();
if (mIndexBuffer == nullptr) mIndexBuffer = std::make_unique<GlGpuBuffer>();
mGpuBuffer->updateBufferData(GlGpuBuffer::Target::ARRAY_BUFFER, vertexArray.vertices.size() * sizeof(VertexData), vertexArray.vertices.data()); mVertexBuffer->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)); mIndexBuffer->updateBufferData(GlGpuBuffer::Target::ELEMENT_ARRAY_BUFFER, vertexArray.indices.size() * sizeof(uint32_t), vertexArray.indices.data());
GL_CHECK(glEnableVertexAttribArray(location));
} }

View file

@ -266,6 +266,8 @@ class GlGeometry
{ {
public: public:
~GlGeometry();
uint32_t getPrimitiveCount(); uint32_t getPrimitiveCount();
const GlSize getPrimitiveSize(const uint32_t primitiveIndex) const; const GlSize getPrimitiveSize(const uint32_t primitiveIndex) const;
bool decomposeOutline(const RenderShape& rshape); 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 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); void updateBuffer(const uint32_t location, const VertexDataArray& vertexArray);
unique_ptr<GlGpuBuffer> mGpuBuffer; GLuint mVao = 0;
std::unique_ptr<GlGpuBuffer> mVertexBuffer;
std::unique_ptr<GlGpuBuffer> mIndexBuffer;
vector<GlPrimitive> mPrimitives; vector<GlPrimitive> mPrimitives;
GlTransform mTransform; GlTransform mTransform;
}; };

View file

@ -31,7 +31,7 @@ public:
enum class Target enum class Target
{ {
ARRAY_BUFFER = GL_ARRAY_BUFFER, ARRAY_BUFFER = GL_ARRAY_BUFFER,
ELEMENT_ARRAY_BUFFER = GL_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER = GL_ELEMENT_ARRAY_BUFFER,
}; };
GlGpuBuffer(); GlGpuBuffer();