From 0aa09c280e53e85a7846d00412699c04e00c5ac2 Mon Sep 17 00:00:00 2001 From: Joey Pollack Date: Mon, 29 Aug 2022 15:07:21 -0400 Subject: [PATCH] Data double buffer moved into the VertexBuffer class Draw method added to VertexBuffer class --- docs/tasks/Bugs.todo | 1 + docs/tasks/refactoring.todo | 3 +- src/renderer/renderer2D.cpp | 195 ++++++++++-------- src/renderer/renderer2D.h | 18 +- src/renderer/shaders/line.vert | 2 +- src/renderer/vertex_buffer.cpp | 97 +++++++-- src/renderer/vertex_buffer.h | 15 +- .../testbed/scenes/simple_render_scene.cpp | 1 + 8 files changed, 225 insertions(+), 107 deletions(-) diff --git a/docs/tasks/Bugs.todo b/docs/tasks/Bugs.todo index 4e58f23..b9792d3 100644 --- a/docs/tasks/Bugs.todo +++ b/docs/tasks/Bugs.todo @@ -8,6 +8,7 @@ High Importance: ✔ @high Editor asset file paths are saved as absolute paths. They need to be relative to the project root. @done(22-03-18 20:41) Medium Importance: + ☐ Lines do not rotate correctly ☐ Map Editor can be docked into the main window. The window IDs should prevent this. ☐ Map Editor does not grab tile sets if the Map Editor is opened before a project is loaded ✔ Map Editor paints the wrong tiles when scrolling with the middle mouse button (this may have to do with the parent window having the scroll bar) @done(22-04-07 13:50) \ No newline at end of file diff --git a/docs/tasks/refactoring.todo b/docs/tasks/refactoring.todo index 94f48cc..2a5fbb5 100644 --- a/docs/tasks/refactoring.todo +++ b/docs/tasks/refactoring.todo @@ -5,7 +5,8 @@ ☐ Binary serializeable Renderer rewrite: - ☐ Add Draw method to the VertexBuffer class @high + ☐ Add double buffer to the VertexBuffer class with a Flush method to send the verts to the gpu @high + ✔ Add Draw method to the VertexBuffer class @high @done(22-08-29 15:06) ✔ Batch rendering minimally working @done(22-08-12 19:19) ✔ See if it's possible/better to move the matrix math into the shaders @high @done(22-08-15 14:23) ✔ Textures in batch renderer @high @done(22-08-18 16:09) diff --git a/src/renderer/renderer2D.cpp b/src/renderer/renderer2D.cpp index aff3def..0673011 100644 --- a/src/renderer/renderer2D.cpp +++ b/src/renderer/renderer2D.cpp @@ -118,6 +118,11 @@ namespace lunarium void Renderer2D::DrawQuad(Rectangle quad, Color color, Texture* texture, float angle, Rectangle sub_texture_area) { + if (!mQuadData.VertexBuffer->WillFit(4)) + { + Flush(FlushMode::Quads); + } + int texture_slot = -1; if (texture) { @@ -141,10 +146,6 @@ namespace lunarium texture_slot = 0; } - if (mQuadData.RawBufferIndex + 4 > mQuadData.MaxVertices) - { - Flush(FlushMode::Quads); - } float tex_is_grey_scale = (texture && texture->GetFormat() == TextureFormat::RED) ? 1.0f : 0.0f; float left = sub_texture_area.X; @@ -163,58 +164,60 @@ namespace lunarium offset_y *= -1.0f; // FIRST - QuadData::Vertex v1; + QuadData::Vertex verts[4]; int vert_size = sizeof(QuadData::Vertex); - v1.pos = mQuadData.vert_pos[0]; - v1.tex_coord = glm::vec2(mQuadData.vert_tex[0].x * scale_x + offset_x, mQuadData.vert_tex[0].y * scale_y - offset_y); - v1.color = color; - v1.tex_slot = texture_slot; - v1.translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f); - v1.angle = angle; - v1.scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f); - v1.tex_is_grey_scale = tex_is_grey_scale; - memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v1, vert_size); - mQuadData.RawBufferIndex += 1; + verts[0].pos = mQuadData.vert_pos[0]; + verts[0].tex_coord = glm::vec2(mQuadData.vert_tex[0].x * scale_x + offset_x, mQuadData.vert_tex[0].y * scale_y - offset_y); + verts[0].color = color; + verts[0].tex_slot = texture_slot; + verts[0].translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f); + verts[0].angle = angle; + verts[0].scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f); + verts[0].tex_is_grey_scale = tex_is_grey_scale; + //memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v1, vert_size); + //mQuadData.RawBufferIndex += 1; + //mQuadData.VertexBuffer->PushVertices((void*)&v1, 1); // SECOND - QuadData::Vertex v2; - v2.pos = mQuadData.vert_pos[1]; - v2.tex_coord = glm::vec2(mQuadData.vert_tex[1].x * scale_x + offset_x, mQuadData.vert_tex[1].y * scale_y - offset_y); - v2.color = color; - v2.tex_slot = texture_slot; - v2.translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f); - v2.angle = angle; - v2.scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f); - v2.tex_is_grey_scale = tex_is_grey_scale; - memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v2, vert_size); - mQuadData.RawBufferIndex += 1; + verts[1].pos = mQuadData.vert_pos[1]; + verts[1].tex_coord = glm::vec2(mQuadData.vert_tex[1].x * scale_x + offset_x, mQuadData.vert_tex[1].y * scale_y - offset_y); + verts[1].color = color; + verts[1].tex_slot = texture_slot; + verts[1].translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f); + verts[1].angle = angle; + verts[1].scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f); + verts[1].tex_is_grey_scale = tex_is_grey_scale; + //memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v2, vert_size); + //mQuadData.RawBufferIndex += 1; + // mQuadData.VertexBuffer->PushVertices((void*)&v2, 1); // THIRD - QuadData::Vertex v3; - v3.pos = mQuadData.vert_pos[2]; - v3.tex_coord = glm::vec2(mQuadData.vert_tex[2].x * scale_x + offset_x, mQuadData.vert_tex[2].y * scale_y - offset_y); - v3.color = color; - v3.tex_slot = texture_slot; - v3.translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f); - v3.angle = angle; - v3.scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f); - v3.tex_is_grey_scale = tex_is_grey_scale; - memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v3, vert_size); - mQuadData.RawBufferIndex += 1; + verts[2].pos = mQuadData.vert_pos[2]; + verts[2].tex_coord = glm::vec2(mQuadData.vert_tex[2].x * scale_x + offset_x, mQuadData.vert_tex[2].y * scale_y - offset_y); + verts[2].color = color; + verts[2].tex_slot = texture_slot; + verts[2].translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f); + verts[2].angle = angle; + verts[2].scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f); + verts[2].tex_is_grey_scale = tex_is_grey_scale; + //memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v3, vert_size); + //mQuadData.RawBufferIndex += 1; + //mQuadData.VertexBuffer->PushVertices((void*)&v3, 1); // FOURTH - QuadData::Vertex v4; - v4.pos = mQuadData.vert_pos[3]; - v4.tex_coord = glm::vec2(mQuadData.vert_tex[3].x * scale_x + offset_x, mQuadData.vert_tex[3].y * scale_y - offset_y); - v4.color = color; - v4.tex_slot = texture_slot; - v4.translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f); - v4.angle = angle; - v4.scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f); - v4.tex_is_grey_scale = tex_is_grey_scale; - memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v4, vert_size); - mQuadData.RawBufferIndex += 1; + verts[3].pos = mQuadData.vert_pos[3]; + verts[3].tex_coord = glm::vec2(mQuadData.vert_tex[3].x * scale_x + offset_x, mQuadData.vert_tex[3].y * scale_y - offset_y); + verts[3].color = color; + verts[3].tex_slot = texture_slot; + verts[3].translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f); + verts[3].angle = angle; + verts[3].scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f); + verts[3].tex_is_grey_scale = tex_is_grey_scale; + //memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v4, vert_size); + //mQuadData.RawBufferIndex += 1; + mQuadData.NumQuads++; + mQuadData.VertexBuffer->PushVertices((void*)verts, 4); // Update render stats mFrameStats.NumTris += 2; @@ -224,7 +227,7 @@ namespace lunarium void Renderer2D::DrawLine(glm::vec2 point_a, glm::vec2 point_b, Color color, float thickness, float angle) { - if (thickness != mLineData.Thickness || mLineData.RawBufferIndex + 2 > mLineData.MaxVertices) + if (thickness != mLineData.Thickness || !mLineData.VertexBuffer->WillFit(2)) { Flush(FlushMode::Lines); mLineData.Thickness = thickness; @@ -235,29 +238,30 @@ namespace lunarium //model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f)); // V1 - LineData::Vertex v1; + LineData::Vertex verts[2]; int vert_size = sizeof(LineData::Vertex); glm::vec4 long_pos = model * glm::vec4(-0.5f, 0.0f, 0.0f, 1.0f); - v1.pos = glm::vec2(long_pos.x, long_pos.y); + verts[0].pos = glm::vec2(long_pos.x, long_pos.y); // v1.translate = glm::vec3(point_a.x, point_a.y, 0.0f); - v1.color = color; + verts[0].color = color; //v1.angle = angle; - memcpy(&mLineData.RawVertexBuffer[mLineData.RawBufferIndex], &v1, vert_size); - mLineData.RawBufferIndex += 1; + // memcpy(&mLineData.RawVertexBuffer[mLineData.RawBufferIndex], &v1, vert_size); + // mLineData.RawBufferIndex += 1; model = glm::mat4(1.0f); model = glm::translate(model, glm::vec3(point_b.x, point_b.y, 0.0f)); // model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f)); // V2 - LineData::Vertex v2; long_pos = model * glm::vec4(0.5f, 0.0f, 0.0f, 1.0f); - v2.pos = glm::vec2(long_pos.x, long_pos.y); + verts[1].pos = glm::vec2(long_pos.x, long_pos.y); // v2.translate = glm::vec3(point_b.x, point_b.y, 0.0f); - v2.color = color; + verts[1].color = color; //v2.angle = angle; - memcpy(&mLineData.RawVertexBuffer[mLineData.RawBufferIndex], &v2, vert_size); - mLineData.RawBufferIndex += 1; + // memcpy(&mLineData.RawVertexBuffer[mLineData.RawBufferIndex], &v2, vert_size); + // mLineData.RawBufferIndex += 1; + + mLineData.VertexBuffer->PushVertices((void*)verts, 2); mLineData.NumLines++; mFrameStats.NumVerts += 2; @@ -265,12 +269,17 @@ namespace lunarium void Renderer2D::DrawBox(Rectangle box, Color color, float thickness, float angle) { - + // TODO: Use DrawLine to make a box + } + + void Renderer2D::DrawEllipse(glm::vec2 center_point, glm::vec2 radii, Color color, int resolution, float thickness, float angle) + { + // TODO: Use DrawLine to make ellipse } - void Renderer2D::DrawEllipse(glm::vec2 center_point, glm::vec2 radii, Color color, bool filled, float thickness, float angle) + void Renderer2D::DrawEllipseFilled(glm::vec2 center_point, glm::vec2 radii, Color color, int resolution, float angle) { - Logger::Warn(LogCategory::GRAPHICS, "Renderer2D::DrawEllipse is not implemented yet"); + } void Renderer2D::DrawString(const char* string, Rectangle bounding_box, Color color, float scale, int font) @@ -289,12 +298,12 @@ namespace lunarium if (mQuadData.NumQuads > 0 && flush_mode & FlushMode::Quads > 0) { mQuadData.MarkedForReset = true; - if (!mQuadData.VertexBuffer->PushVertices(mQuadData.RawVertexBuffer, mQuadData.NumQuads * 4)) - { - Logger::Error(LogCategory::GRAPHICS, "Could not push verts into the quad buffer!"); - ResetDrawingData(); - return; - } + // if (!mQuadData.VertexBuffer->PushVertices(mQuadData.RawVertexBuffer, mQuadData.NumQuads * 4)) + // { + // Logger::Error(LogCategory::GRAPHICS, "Could not push verts into the quad buffer!"); + // ResetDrawingData(); + // return; + // } mQuadData.QuadShader->Use(); for (int i = 0; i < mQuadData.LoadedTextures.size(); i++) @@ -311,10 +320,12 @@ namespace lunarium mQuadData.VertexBuffer->Bind(); - glDrawElements(GL_TRIANGLES, mQuadData.NumQuads * 6, GL_UNSIGNED_INT, nullptr); + mQuadData.VertexBuffer->DrawArray(mQuadData.NumQuads * 6); + + // glDrawElements(GL_TRIANGLES, mQuadData.NumQuads * 6, GL_UNSIGNED_INT, nullptr); // Checking how the rotation looks when lines are drawn instead - //glDrawArrays(GL_LINES, 0, mQuadData.NumQuads * 4); + // glDrawArrays(GL_LINES, 0, mQuadData.NumQuads * 4); // mQuadData.WireFrameShader->Use(); // uprojview.Location = -1; @@ -339,12 +350,12 @@ namespace lunarium if (mLineData.NumLines > 0 && draw > 0) { mLineData.MarkedForReset = true; - if (!mLineData.VertexBuffer->PushVertices(mLineData.RawVertexBuffer, mLineData.NumLines * 2)) - { - Logger::Error(LogCategory::GRAPHICS, "Could not push verts into the line buffer!"); - ResetDrawingData(); - return; - } + // if (!mLineData.VertexBuffer->PushVertices(mLineData.RawVertexBuffer, mLineData.NumLines * 2)) + // { + // Logger::Error(LogCategory::GRAPHICS, "Could not push verts into the line buffer!"); + // ResetDrawingData(); + // return; + // } mLineData.Shader->Use(); Uniform uprojview; @@ -358,7 +369,8 @@ namespace lunarium //glDrawElements(GL_LINES, mLineData.NumLines * 2, GL_UNSIGNED_INT, nullptr); glLineWidth(mLineData.Thickness); - glDrawArrays(GL_LINES, 0, mLineData.NumLines * 2); + //glDrawArrays(GL_LINES, 0, mLineData.NumLines * 2); + mLineData.VertexBuffer->DrawArray(mLineData.NumLines * 2); mFrameStats.DrawCalls++; } @@ -404,9 +416,10 @@ namespace lunarium mQuadData.VertexBuffer = VertexBuffer::Create(mQuadData.BufferLayout, mQuadData.MaxVertices, nullptr, mQuadData.MaxIndices, indices); // RAW VERTEX BUFFER - mQuadData.RawVertexBuffer = new QuadData::Vertex[mQuadData.MaxVertices]; - mQuadData.RawBufferIndex = 0; + // mQuadData.RawVertexBuffer = new QuadData::Vertex[mQuadData.MaxVertices]; + // mQuadData.RawBufferIndex = 0; + // Safety check vertex struct size int layout_size = mQuadData.BufferLayout.GetLayoutSizeInBytes(); int struct_size = sizeof(QuadData::Vertex); if (struct_size != layout_size) @@ -449,10 +462,12 @@ namespace lunarium mLineData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 4 }); // Color // mLineData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // angle mLineData.VertexBuffer = VertexBuffer::Create(mLineData.BufferLayout, mLineData.MaxVertices); + mLineData.VertexBuffer->SetType(VertexBuffer::LayoutType::LINE); - mLineData.RawVertexBuffer = new LineData::Vertex[mLineData.MaxVertices]; - mLineData.RawBufferIndex = 0; + // mLineData.RawVertexBuffer = new LineData::Vertex[mLineData.MaxVertices]; + // mLineData.RawBufferIndex = 0; + // Safety check vertex struct size int layout_size = mLineData.BufferLayout.GetLayoutSizeInBytes(); int struct_size = sizeof(LineData::Vertex); if (struct_size != layout_size) @@ -475,6 +490,20 @@ namespace lunarium OpRes Renderer2D::InitEllipseData() { + mEllipseData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 2}); // Position + mEllipseData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 4}); // Color + mEllipseData.VertexBuffer = VertexBuffer::Create(mEllipseData.BufferLayout, mEllipseData.MaxVertices, nullptr, mEllipseData.MaxIndices, nullptr); + + // Safety check vertex struct size + int layout_size = mEllipseData.BufferLayout.GetLayoutSizeInBytes(); + int struct_size = sizeof(EllipseData::Vertex); + if (struct_size != layout_size) + { + Logger::Error(LogCategory::GRAPHICS, + "EllipseData::Vertex struct size does not match the vertex layout size! struct: %d, layout: %d", struct_size, layout_size); + } + + return OpRes::OK(); } @@ -496,7 +525,7 @@ namespace lunarium mQuadData.VertexBuffer->Clear(); mQuadData.NumQuads = 0; - mQuadData.RawBufferIndex = 0; + //mQuadData.RawBufferIndex = 0; mQuadData.MarkedForReset = false; } @@ -506,7 +535,7 @@ namespace lunarium { mLineData.VertexBuffer->Clear(); mLineData.NumLines = 0; - mLineData.RawBufferIndex = 0; + // mLineData.RawBufferIndex = 0; mLineData.Thickness = 1.0f; mLineData.MarkedForReset = false; diff --git a/src/renderer/renderer2D.h b/src/renderer/renderer2D.h index 60bdd5a..c839961 100644 --- a/src/renderer/renderer2D.h +++ b/src/renderer/renderer2D.h @@ -53,7 +53,8 @@ namespace lunarium void DrawQuad(Rectangle quad, Color color, Texture* texture = nullptr, float angle = 0.0f, Rectangle sub_texture_area = Rectangle(-1, -1, -1, -1)); void DrawLine(glm::vec2 point_a, glm::vec2 point_b, Color color, float thickness = 1.0f, float angle = 0.0f); void DrawBox(Rectangle box, Color color, float thickness = 1.0f, float angle = 0.0f); - void DrawEllipse(glm::vec2 center_point, glm::vec2 radii, Color color, bool filled = false, float thickness = 1.0f, float angle = 0.0f); + void DrawEllipse(glm::vec2 center_point, glm::vec2 radii, Color color, int resolution = 300, float thickness = 1.0f, float angle = 0.0f); + void DrawEllipseFilled(glm::vec2 center_point, glm::vec2 radii, Color color, int resolution = 300, float angle = 0.0f); void DrawString(const char* string, Rectangle bounding_box, Color color = {1.0f, 1.0f, 1.0f, 1.0f}, float scale = 1.0f, int font = -1); // DEBUG: @@ -138,8 +139,8 @@ namespace lunarium const u32 indices[6] = { 0, 1, 2, 2, 3, 0 }; - Vertex* RawVertexBuffer; - int RawBufferIndex; + // Vertex* RawVertexBuffer; + // int RawBufferIndex; BufferLayout BufferLayout; VertexBuffer* VertexBuffer; @@ -155,6 +156,7 @@ namespace lunarium bool MarkedForReset = false; int NumEllipses = 0; const int MaxVertices = 60000; + const int MaxIndices = 60000; struct Vertex { @@ -162,8 +164,10 @@ namespace lunarium glm::vec4 color; }; - Vertex* RawVertexBuffer; - int RawBufferIndex; + // Vertex* RawVertexBuffer; + // int RawBufferIndex; + // u32* RawIndexBuffer; + // int RawIndexBufferIndex; BufferLayout BufferLayout; VertexBuffer* VertexBuffer; @@ -189,8 +193,8 @@ namespace lunarium glm::vec4 color; }; - Vertex* RawVertexBuffer; - int RawBufferIndex; + // Vertex* RawVertexBuffer; + // int RawBufferIndex; BufferLayout BufferLayout; VertexBuffer* VertexBuffer; diff --git a/src/renderer/shaders/line.vert b/src/renderer/shaders/line.vert index 91dc104..29d2505 100644 --- a/src/renderer/shaders/line.vert +++ b/src/renderer/shaders/line.vert @@ -1,7 +1,7 @@ #version 450 core layout (location = 0) in vec2 position; // -layout (location = 1) in vec4 color; // +layout (location = 1) in vec4 color; // out vec4 o_Color; diff --git a/src/renderer/vertex_buffer.cpp b/src/renderer/vertex_buffer.cpp index 390615b..4dd2ff9 100644 --- a/src/renderer/vertex_buffer.cpp +++ b/src/renderer/vertex_buffer.cpp @@ -91,12 +91,14 @@ namespace lunarium } VertexBuffer::VertexBuffer(BufferLayout& VertexLayout, u32 num_vertices, const void* vertices, u32 num_indices, u32* indices) - : mLayout(VertexLayout), mSize(0), mIndex(0), mEBO(0), mEBOSize(num_indices * sizeof(u32)), mEBOIndex(0), mNumIndices(0), mIsStatic(false) + : mLayout(VertexLayout), mSize(0), mIndex(0), mEBO(0), mEBOSize(num_indices * sizeof(u32)), mEBOIndex(0), mNumIndices(0), mNumVertices(0), + mIsStatic(false), mCPUBuffer(nullptr), mCPUIdxBuffer(nullptr), mPrimType(LayoutType::TRIANGLE) { mIsStatic = vertices != nullptr; // Calculate buffer size mSize = VertexLayout.GetLayoutSizeInBytes() * num_vertices; + mCPUBuffer = new u8[mSize]; glGenVertexArrays(1, &mVAO); glGenBuffers(1, &mVBO); @@ -104,6 +106,7 @@ namespace lunarium if (mEBOSize > 0) { glGenBuffers(1, &mEBO); + mCPUIdxBuffer = new u32[mNumIndices]; } @@ -112,6 +115,7 @@ namespace lunarium if (vertices) { glBufferData(GL_ARRAY_BUFFER, mSize, vertices, GL_STATIC_DRAW); + mNumVertices = num_vertices; } else { @@ -147,6 +151,12 @@ namespace lunarium mNumIndices = 0; } + + void VertexBuffer::SetType(LayoutType primitive_type) + { + mPrimType = primitive_type; + } + void VertexBuffer::Bind() { glBindVertexArray(mVAO); @@ -168,6 +178,20 @@ namespace lunarium glBindBuffer(GL_ARRAY_BUFFER, 0); } + + bool VertexBuffer::WillFit(u32 num_vertices) + { + int data_size = mLayout.GetLayoutSizeInBytes() * num_vertices; + return mIndex + data_size <= mSize; + } + + + bool VertexBuffer::IdxWillFit(u32 num_indices) + { + int data_size = sizeof(u32) * num_indices; + return (mEBOIndex + data_size <= mEBOSize); + } + bool VertexBuffer::PushVertices(const void* vertices, u32 num_verts) { if (mIsStatic) @@ -186,11 +210,10 @@ namespace lunarium return false; } - // Add verts to the buffer - BindVBO(); - glBufferSubData(GL_ARRAY_BUFFER, mIndex, data_size, vertices); - UnbindVBO(); + // Add verts to the cpu buffer + memcpy(mCPUBuffer + mIndex, vertices, data_size); + mNumVertices += num_verts; mIndex += data_size; return true; } @@ -212,20 +235,68 @@ namespace lunarium return false; } - Bind(); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, mEBOIndex, data_size, indices); - Unbind(); - int error = glGetError(); - if (error > 0) - { - Logger::Error(LogCategory::GRAPHICS, "OGL ERROR!"); - } + memcpy(mCPUIdxBuffer + mEBOIndex, indices, data_size); + + // Bind(); + // glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, mEBOIndex, data_size, indices); + // Unbind(); + // int error = glGetError(); + // if (error > 0) + // { + // Logger::Error(LogCategory::GRAPHICS, "OGL ERROR!"); + // } mNumIndices += num_indices; mEBOIndex += data_size; return true; } + + void VertexBuffer::DrawArray(u32 num_elements) + { + BindVBO(); + + if (!mIsStatic) + { + glBufferSubData(GL_ARRAY_BUFFER, 0, mIndex, mCPUBuffer); // mIndex also happens to be the size in bytes of the cpu buffer + } + + GLenum primitive = (mPrimType == LayoutType::TRIANGLE) ? GL_TRIANGLES : GL_LINES; + + if (mNumIndices > 0) + { + if (!mEBOIsStatic) + { + Bind(); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mEBOIndex, mCPUIdxBuffer); + } + + num_elements = (num_elements > 0) ? num_elements : mNumIndices; + glDrawElements(primitive, num_elements, GL_UNSIGNED_INT, nullptr); + } + else + { + num_elements = (num_elements > 0) ? num_elements : mNumVertices; + glDrawArrays(primitive, 0, num_elements); + } + + + + UnbindVBO(); + mIndex = 0; + mEBOIndex = 0; + + if (!mIsStatic) + { + mNumVertices = 0; + } + + if (!mEBOIsStatic) + { + mNumIndices = 0; + } + } + ///////////////////////////////////////////////////////////////////// // HELPER METHODS ///////////////////////////////////////////////////////////////////// diff --git a/src/renderer/vertex_buffer.h b/src/renderer/vertex_buffer.h index bc69112..c04d3a1 100644 --- a/src/renderer/vertex_buffer.h +++ b/src/renderer/vertex_buffer.h @@ -55,8 +55,7 @@ namespace lunarium enum LayoutType { LINE, - QUAD, - SPRITE, + TRIANGLE, }; public: @@ -65,6 +64,8 @@ namespace lunarium static VertexBuffer* Create(BufferLayout& VertexLayout, u32 num_vertices, const void* vertices = nullptr, u32 num_indices = 0, u32* indices = nullptr); static void Destroy(VertexBuffer** ppBuf); + void SetType(LayoutType primitive_type); + void Clear(); void Bind(); @@ -73,21 +74,30 @@ namespace lunarium void BindVBO(); void UnbindVBO(); + bool WillFit(u32 num_vertices); + bool IdxWillFit(u32 num_indices); + /// Returns false if the data does not fit in the buffer /// size is the size in bytes bool PushVertices(const void* vertices, u32 num_verts); bool PushIndices(const u32* indices, u32 num_indices); + void DrawArray(u32 num_elements = 0); + private: BufferLayout mLayout; + LayoutType mPrimType; bool mIsStatic; u32 mVAO; u32 mVBO; + u8* mCPUBuffer; u32 mSize; // Size of the buffer in bytes u32 mIndex; // The next spot to push data into for a dynamic buffer + u32 mNumVertices; u32 mEBO; + u32* mCPUIdxBuffer; u32 mEBOSize; u32 mEBOIndex; u32 mEBOIsStatic; @@ -97,6 +107,7 @@ namespace lunarium VertexBuffer(BufferLayout& VertexLayout, u32 num_vertices, const void* vertices = nullptr, u32 num_indices = 0, u32* indices = nullptr); void Free(); + void Flush(); }; } diff --git a/src/run_modes/testbed/scenes/simple_render_scene.cpp b/src/run_modes/testbed/scenes/simple_render_scene.cpp index 98eeb9d..fb16eed 100644 --- a/src/run_modes/testbed/scenes/simple_render_scene.cpp +++ b/src/run_modes/testbed/scenes/simple_render_scene.cpp @@ -267,6 +267,7 @@ namespace lunarium case ShapeMode::Ellipses: { + g.DrawEllipse(glm::vec2(300.0f, 300.0f), glm::vec2(25.0f, 45.0f), Color::Blue(), 300, true); } break; }