Data double buffer moved into the VertexBuffer class

Draw method added to VertexBuffer class
master
Joey Pollack 3 years ago
parent b7ffc48525
commit 0aa09c280e

@ -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) ✔ @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: Medium Importance:
☐ Lines do not rotate correctly
☐ Map Editor can be docked into the main window. The window IDs should prevent this. ☐ 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 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) ✔ 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)

@ -5,7 +5,8 @@
☐ Binary serializeable ☐ Binary serializeable
Renderer rewrite: 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) ✔ 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) ✔ 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) ✔ Textures in batch renderer @high @done(22-08-18 16:09)

@ -118,6 +118,11 @@ namespace lunarium
void Renderer2D::DrawQuad(Rectangle quad, Color color, Texture* texture, float angle, Rectangle sub_texture_area) 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; int texture_slot = -1;
if (texture) if (texture)
{ {
@ -141,10 +146,6 @@ namespace lunarium
texture_slot = 0; 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 tex_is_grey_scale = (texture && texture->GetFormat() == TextureFormat::RED) ? 1.0f : 0.0f;
float left = sub_texture_area.X; float left = sub_texture_area.X;
@ -163,58 +164,60 @@ namespace lunarium
offset_y *= -1.0f; offset_y *= -1.0f;
// FIRST // FIRST
QuadData::Vertex v1; QuadData::Vertex verts[4];
int vert_size = sizeof(QuadData::Vertex); int vert_size = sizeof(QuadData::Vertex);
v1.pos = mQuadData.vert_pos[0]; verts[0].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); verts[0].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; verts[0].color = color;
v1.tex_slot = texture_slot; verts[0].tex_slot = texture_slot;
v1.translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f); verts[0].translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f);
v1.angle = angle; verts[0].angle = angle;
v1.scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f); verts[0].scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f);
v1.tex_is_grey_scale = tex_is_grey_scale; verts[0].tex_is_grey_scale = tex_is_grey_scale;
memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v1, vert_size); //memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v1, vert_size);
mQuadData.RawBufferIndex += 1; //mQuadData.RawBufferIndex += 1;
//mQuadData.VertexBuffer->PushVertices((void*)&v1, 1);
// SECOND // SECOND
QuadData::Vertex v2; verts[1].pos = mQuadData.vert_pos[1];
v2.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);
v2.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;
v2.color = color; verts[1].tex_slot = texture_slot;
v2.tex_slot = texture_slot; verts[1].translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f);
v2.translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f); verts[1].angle = angle;
v2.angle = angle; verts[1].scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f);
v2.scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f); verts[1].tex_is_grey_scale = tex_is_grey_scale;
v2.tex_is_grey_scale = tex_is_grey_scale; //memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v2, vert_size);
memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v2, vert_size); //mQuadData.RawBufferIndex += 1;
mQuadData.RawBufferIndex += 1; // mQuadData.VertexBuffer->PushVertices((void*)&v2, 1);
// THIRD // THIRD
QuadData::Vertex v3; verts[2].pos = mQuadData.vert_pos[2];
v3.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);
v3.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;
v3.color = color; verts[2].tex_slot = texture_slot;
v3.tex_slot = texture_slot; verts[2].translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f);
v3.translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f); verts[2].angle = angle;
v3.angle = angle; verts[2].scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f);
v3.scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f); verts[2].tex_is_grey_scale = tex_is_grey_scale;
v3.tex_is_grey_scale = tex_is_grey_scale; //memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v3, vert_size);
memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v3, vert_size); //mQuadData.RawBufferIndex += 1;
mQuadData.RawBufferIndex += 1; //mQuadData.VertexBuffer->PushVertices((void*)&v3, 1);
// FOURTH // FOURTH
QuadData::Vertex v4; verts[3].pos = mQuadData.vert_pos[3];
v4.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);
v4.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;
v4.color = color; verts[3].tex_slot = texture_slot;
v4.tex_slot = texture_slot; verts[3].translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f);
v4.translation = glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f); verts[3].angle = angle;
v4.angle = angle; verts[3].scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f);
v4.scale = glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f); verts[3].tex_is_grey_scale = tex_is_grey_scale;
v4.tex_is_grey_scale = tex_is_grey_scale; //memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v4, vert_size);
memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v4, vert_size); //mQuadData.RawBufferIndex += 1;
mQuadData.RawBufferIndex += 1;
mQuadData.NumQuads++; mQuadData.NumQuads++;
mQuadData.VertexBuffer->PushVertices((void*)verts, 4);
// Update render stats // Update render stats
mFrameStats.NumTris += 2; 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) 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); Flush(FlushMode::Lines);
mLineData.Thickness = thickness; mLineData.Thickness = thickness;
@ -235,29 +238,30 @@ namespace lunarium
//model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f)); //model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f));
// V1 // V1
LineData::Vertex v1; LineData::Vertex verts[2];
int vert_size = sizeof(LineData::Vertex); int vert_size = sizeof(LineData::Vertex);
glm::vec4 long_pos = model * glm::vec4(-0.5f, 0.0f, 0.0f, 1.0f); 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.translate = glm::vec3(point_a.x, point_a.y, 0.0f);
v1.color = color; verts[0].color = color;
//v1.angle = angle; //v1.angle = angle;
memcpy(&mLineData.RawVertexBuffer[mLineData.RawBufferIndex], &v1, vert_size); // memcpy(&mLineData.RawVertexBuffer[mLineData.RawBufferIndex], &v1, vert_size);
mLineData.RawBufferIndex += 1; // mLineData.RawBufferIndex += 1;
model = glm::mat4(1.0f); model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(point_b.x, point_b.y, 0.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)); // model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f));
// V2 // V2
LineData::Vertex v2;
long_pos = model * glm::vec4(0.5f, 0.0f, 0.0f, 1.0f); 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.translate = glm::vec3(point_b.x, point_b.y, 0.0f);
v2.color = color; verts[1].color = color;
//v2.angle = angle; //v2.angle = angle;
memcpy(&mLineData.RawVertexBuffer[mLineData.RawBufferIndex], &v2, vert_size); // memcpy(&mLineData.RawVertexBuffer[mLineData.RawBufferIndex], &v2, vert_size);
mLineData.RawBufferIndex += 1; // mLineData.RawBufferIndex += 1;
mLineData.VertexBuffer->PushVertices((void*)verts, 2);
mLineData.NumLines++; mLineData.NumLines++;
mFrameStats.NumVerts += 2; mFrameStats.NumVerts += 2;
@ -265,12 +269,17 @@ namespace lunarium
void Renderer2D::DrawBox(Rectangle box, Color color, float thickness, float angle) 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) 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) if (mQuadData.NumQuads > 0 && flush_mode & FlushMode::Quads > 0)
{ {
mQuadData.MarkedForReset = true; mQuadData.MarkedForReset = true;
if (!mQuadData.VertexBuffer->PushVertices(mQuadData.RawVertexBuffer, mQuadData.NumQuads * 4)) // if (!mQuadData.VertexBuffer->PushVertices(mQuadData.RawVertexBuffer, mQuadData.NumQuads * 4))
{ // {
Logger::Error(LogCategory::GRAPHICS, "Could not push verts into the quad buffer!"); // Logger::Error(LogCategory::GRAPHICS, "Could not push verts into the quad buffer!");
ResetDrawingData(); // ResetDrawingData();
return; // return;
} // }
mQuadData.QuadShader->Use(); mQuadData.QuadShader->Use();
for (int i = 0; i < mQuadData.LoadedTextures.size(); i++) for (int i = 0; i < mQuadData.LoadedTextures.size(); i++)
@ -311,10 +320,12 @@ namespace lunarium
mQuadData.VertexBuffer->Bind(); 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 // 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(); // mQuadData.WireFrameShader->Use();
// uprojview.Location = -1; // uprojview.Location = -1;
@ -339,12 +350,12 @@ namespace lunarium
if (mLineData.NumLines > 0 && draw > 0) if (mLineData.NumLines > 0 && draw > 0)
{ {
mLineData.MarkedForReset = true; mLineData.MarkedForReset = true;
if (!mLineData.VertexBuffer->PushVertices(mLineData.RawVertexBuffer, mLineData.NumLines * 2)) // if (!mLineData.VertexBuffer->PushVertices(mLineData.RawVertexBuffer, mLineData.NumLines * 2))
{ // {
Logger::Error(LogCategory::GRAPHICS, "Could not push verts into the line buffer!"); // Logger::Error(LogCategory::GRAPHICS, "Could not push verts into the line buffer!");
ResetDrawingData(); // ResetDrawingData();
return; // return;
} // }
mLineData.Shader->Use(); mLineData.Shader->Use();
Uniform uprojview; Uniform uprojview;
@ -358,7 +369,8 @@ namespace lunarium
//glDrawElements(GL_LINES, mLineData.NumLines * 2, GL_UNSIGNED_INT, nullptr); //glDrawElements(GL_LINES, mLineData.NumLines * 2, GL_UNSIGNED_INT, nullptr);
glLineWidth(mLineData.Thickness); 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++; mFrameStats.DrawCalls++;
} }
@ -404,9 +416,10 @@ namespace lunarium
mQuadData.VertexBuffer = VertexBuffer::Create(mQuadData.BufferLayout, mQuadData.MaxVertices, nullptr, mQuadData.MaxIndices, indices); mQuadData.VertexBuffer = VertexBuffer::Create(mQuadData.BufferLayout, mQuadData.MaxVertices, nullptr, mQuadData.MaxIndices, indices);
// RAW VERTEX BUFFER // RAW VERTEX BUFFER
mQuadData.RawVertexBuffer = new QuadData::Vertex[mQuadData.MaxVertices]; // mQuadData.RawVertexBuffer = new QuadData::Vertex[mQuadData.MaxVertices];
mQuadData.RawBufferIndex = 0; // mQuadData.RawBufferIndex = 0;
// Safety check vertex struct size
int layout_size = mQuadData.BufferLayout.GetLayoutSizeInBytes(); int layout_size = mQuadData.BufferLayout.GetLayoutSizeInBytes();
int struct_size = sizeof(QuadData::Vertex); int struct_size = sizeof(QuadData::Vertex);
if (struct_size != layout_size) 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, 4 }); // Color
// mLineData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // angle // mLineData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // angle
mLineData.VertexBuffer = VertexBuffer::Create(mLineData.BufferLayout, mLineData.MaxVertices); mLineData.VertexBuffer = VertexBuffer::Create(mLineData.BufferLayout, mLineData.MaxVertices);
mLineData.VertexBuffer->SetType(VertexBuffer::LayoutType::LINE);
mLineData.RawVertexBuffer = new LineData::Vertex[mLineData.MaxVertices]; // mLineData.RawVertexBuffer = new LineData::Vertex[mLineData.MaxVertices];
mLineData.RawBufferIndex = 0; // mLineData.RawBufferIndex = 0;
// Safety check vertex struct size
int layout_size = mLineData.BufferLayout.GetLayoutSizeInBytes(); int layout_size = mLineData.BufferLayout.GetLayoutSizeInBytes();
int struct_size = sizeof(LineData::Vertex); int struct_size = sizeof(LineData::Vertex);
if (struct_size != layout_size) if (struct_size != layout_size)
@ -475,6 +490,20 @@ namespace lunarium
OpRes Renderer2D::InitEllipseData() 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(); return OpRes::OK();
} }
@ -496,7 +525,7 @@ namespace lunarium
mQuadData.VertexBuffer->Clear(); mQuadData.VertexBuffer->Clear();
mQuadData.NumQuads = 0; mQuadData.NumQuads = 0;
mQuadData.RawBufferIndex = 0; //mQuadData.RawBufferIndex = 0;
mQuadData.MarkedForReset = false; mQuadData.MarkedForReset = false;
} }
@ -506,7 +535,7 @@ namespace lunarium
{ {
mLineData.VertexBuffer->Clear(); mLineData.VertexBuffer->Clear();
mLineData.NumLines = 0; mLineData.NumLines = 0;
mLineData.RawBufferIndex = 0; // mLineData.RawBufferIndex = 0;
mLineData.Thickness = 1.0f; mLineData.Thickness = 1.0f;
mLineData.MarkedForReset = false; mLineData.MarkedForReset = false;

@ -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 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 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 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); 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: // DEBUG:
@ -138,8 +139,8 @@ namespace lunarium
const u32 indices[6] = { 0, 1, 2, 2, 3, 0 }; const u32 indices[6] = { 0, 1, 2, 2, 3, 0 };
Vertex* RawVertexBuffer; // Vertex* RawVertexBuffer;
int RawBufferIndex; // int RawBufferIndex;
BufferLayout BufferLayout; BufferLayout BufferLayout;
VertexBuffer* VertexBuffer; VertexBuffer* VertexBuffer;
@ -155,6 +156,7 @@ namespace lunarium
bool MarkedForReset = false; bool MarkedForReset = false;
int NumEllipses = 0; int NumEllipses = 0;
const int MaxVertices = 60000; const int MaxVertices = 60000;
const int MaxIndices = 60000;
struct Vertex struct Vertex
{ {
@ -162,8 +164,10 @@ namespace lunarium
glm::vec4 color; glm::vec4 color;
}; };
Vertex* RawVertexBuffer; // Vertex* RawVertexBuffer;
int RawBufferIndex; // int RawBufferIndex;
// u32* RawIndexBuffer;
// int RawIndexBufferIndex;
BufferLayout BufferLayout; BufferLayout BufferLayout;
VertexBuffer* VertexBuffer; VertexBuffer* VertexBuffer;
@ -189,8 +193,8 @@ namespace lunarium
glm::vec4 color; glm::vec4 color;
}; };
Vertex* RawVertexBuffer; // Vertex* RawVertexBuffer;
int RawBufferIndex; // int RawBufferIndex;
BufferLayout BufferLayout; BufferLayout BufferLayout;
VertexBuffer* VertexBuffer; VertexBuffer* VertexBuffer;

@ -1,7 +1,7 @@
#version 450 core #version 450 core
layout (location = 0) in vec2 position; // <vec2 position> layout (location = 0) in vec2 position; // <vec2 position>
layout (location = 1) in vec4 color; // <vec2 position> layout (location = 1) in vec4 color; // <vec4 color>
out vec4 o_Color; out vec4 o_Color;

@ -91,12 +91,14 @@ namespace lunarium
} }
VertexBuffer::VertexBuffer(BufferLayout& VertexLayout, u32 num_vertices, const void* vertices, u32 num_indices, u32* indices) 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; mIsStatic = vertices != nullptr;
// Calculate buffer size // Calculate buffer size
mSize = VertexLayout.GetLayoutSizeInBytes() * num_vertices; mSize = VertexLayout.GetLayoutSizeInBytes() * num_vertices;
mCPUBuffer = new u8[mSize];
glGenVertexArrays(1, &mVAO); glGenVertexArrays(1, &mVAO);
glGenBuffers(1, &mVBO); glGenBuffers(1, &mVBO);
@ -104,6 +106,7 @@ namespace lunarium
if (mEBOSize > 0) if (mEBOSize > 0)
{ {
glGenBuffers(1, &mEBO); glGenBuffers(1, &mEBO);
mCPUIdxBuffer = new u32[mNumIndices];
} }
@ -112,6 +115,7 @@ namespace lunarium
if (vertices) if (vertices)
{ {
glBufferData(GL_ARRAY_BUFFER, mSize, vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, mSize, vertices, GL_STATIC_DRAW);
mNumVertices = num_vertices;
} }
else else
{ {
@ -147,6 +151,12 @@ namespace lunarium
mNumIndices = 0; mNumIndices = 0;
} }
void VertexBuffer::SetType(LayoutType primitive_type)
{
mPrimType = primitive_type;
}
void VertexBuffer::Bind() void VertexBuffer::Bind()
{ {
glBindVertexArray(mVAO); glBindVertexArray(mVAO);
@ -168,6 +178,20 @@ namespace lunarium
glBindBuffer(GL_ARRAY_BUFFER, 0); 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) bool VertexBuffer::PushVertices(const void* vertices, u32 num_verts)
{ {
if (mIsStatic) if (mIsStatic)
@ -186,11 +210,10 @@ namespace lunarium
return false; return false;
} }
// Add verts to the buffer // Add verts to the cpu buffer
BindVBO(); memcpy(mCPUBuffer + mIndex, vertices, data_size);
glBufferSubData(GL_ARRAY_BUFFER, mIndex, data_size, vertices);
UnbindVBO();
mNumVertices += num_verts;
mIndex += data_size; mIndex += data_size;
return true; return true;
} }
@ -212,20 +235,68 @@ namespace lunarium
return false; return false;
} }
Bind(); memcpy(mCPUIdxBuffer + mEBOIndex, indices, data_size);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, mEBOIndex, data_size, indices);
Unbind(); // Bind();
int error = glGetError(); // glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, mEBOIndex, data_size, indices);
if (error > 0) // Unbind();
{ // int error = glGetError();
Logger::Error(LogCategory::GRAPHICS, "OGL ERROR!"); // if (error > 0)
} // {
// Logger::Error(LogCategory::GRAPHICS, "OGL ERROR!");
// }
mNumIndices += num_indices; mNumIndices += num_indices;
mEBOIndex += data_size; mEBOIndex += data_size;
return true; 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 // HELPER METHODS
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////

@ -55,8 +55,7 @@ namespace lunarium
enum LayoutType enum LayoutType
{ {
LINE, LINE,
QUAD, TRIANGLE,
SPRITE,
}; };
public: 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 VertexBuffer* Create(BufferLayout& VertexLayout, u32 num_vertices, const void* vertices = nullptr, u32 num_indices = 0, u32* indices = nullptr);
static void Destroy(VertexBuffer** ppBuf); static void Destroy(VertexBuffer** ppBuf);
void SetType(LayoutType primitive_type);
void Clear(); void Clear();
void Bind(); void Bind();
@ -73,21 +74,30 @@ namespace lunarium
void BindVBO(); void BindVBO();
void UnbindVBO(); void UnbindVBO();
bool WillFit(u32 num_vertices);
bool IdxWillFit(u32 num_indices);
/// Returns false if the data does not fit in the buffer /// Returns false if the data does not fit in the buffer
/// size is the size in bytes /// size is the size in bytes
bool PushVertices(const void* vertices, u32 num_verts); bool PushVertices(const void* vertices, u32 num_verts);
bool PushIndices(const u32* indices, u32 num_indices); bool PushIndices(const u32* indices, u32 num_indices);
void DrawArray(u32 num_elements = 0);
private: private:
BufferLayout mLayout; BufferLayout mLayout;
LayoutType mPrimType;
bool mIsStatic; bool mIsStatic;
u32 mVAO; u32 mVAO;
u32 mVBO; u32 mVBO;
u8* mCPUBuffer;
u32 mSize; // Size of the buffer in bytes u32 mSize; // Size of the buffer in bytes
u32 mIndex; // The next spot to push data into for a dynamic buffer u32 mIndex; // The next spot to push data into for a dynamic buffer
u32 mNumVertices;
u32 mEBO; u32 mEBO;
u32* mCPUIdxBuffer;
u32 mEBOSize; u32 mEBOSize;
u32 mEBOIndex; u32 mEBOIndex;
u32 mEBOIsStatic; 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); VertexBuffer(BufferLayout& VertexLayout, u32 num_vertices, const void* vertices = nullptr, u32 num_indices = 0, u32* indices = nullptr);
void Free(); void Free();
void Flush();
}; };
} }

@ -267,6 +267,7 @@ namespace lunarium
case ShapeMode::Ellipses: case ShapeMode::Ellipses:
{ {
g.DrawEllipse(glm::vec2(300.0f, 300.0f), glm::vec2(25.0f, 45.0f), Color::Blue(), 300, true);
} break; } break;
} }

Loading…
Cancel
Save