From f0fb3fdec1f1d98f176ee45a5417f1c927f1e467 Mon Sep 17 00:00:00 2001 From: Joey Pollack Date: Mon, 22 Aug 2022 19:48:21 -0400 Subject: [PATCH] Line shaders written Renderer2D prepared for Lines and Ellipses --- docs/tasks/refactoring.todo | 2 +- src/renderer/renderer2D.cpp | 359 +++++++++--------- src/renderer/renderer2D.h | 68 +++- src/renderer/shaders/line.frag | 9 + src/renderer/shaders/line.vert | 12 + .../testbed/scenes/simple_render_scene.cpp | 49 +-- 6 files changed, 257 insertions(+), 242 deletions(-) create mode 100644 src/renderer/shaders/line.frag create mode 100644 src/renderer/shaders/line.vert diff --git a/docs/tasks/refactoring.todo b/docs/tasks/refactoring.todo index a7d4bff..5cd3939 100644 --- a/docs/tasks/refactoring.todo +++ b/docs/tasks/refactoring.todo @@ -25,6 +25,6 @@ Renderer rewrite: ☐ Elipse Batch data ☐ DrawLine @low - ☐ Line Shader + ✔ Line Shader @done(22-08-22 19:46) ☐ Line Batch data \ No newline at end of file diff --git a/src/renderer/renderer2D.cpp b/src/renderer/renderer2D.cpp index aa1d883..5cd9f18 100644 --- a/src/renderer/renderer2D.cpp +++ b/src/renderer/renderer2D.cpp @@ -28,17 +28,10 @@ namespace lunarium } - struct QuadTestData - { - Color color; - BufferLayout mBufferLayout; - VertexBuffer* mVertexBuffer; - IndexBuffer* mIndexBuffer; - Shader* mQuadShader; - } mTestData; OpRes Renderer2D::Initialize() { + // Configure OpenGL glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Disable byte-alignment restriction for texture loading glPixelStorei(GL_PACK_ALIGNMENT, 1); // Disable byte-alignment restriction for texture storing @@ -48,108 +41,29 @@ namespace lunarium mpCamera = nullptr; - u32* indices = new u32[mQuadData.MaxIndices]; - // Need to adjust the set of indices because they reference verts deeper into the buffer - // See Hazel for example of this - int offset = 0; - for (int i = 0; i < mQuadData.MaxIndices; i+=6) - { - for ( int j = 0; j < 6; j++) - { - indices[i + j] = mQuadData.indices[(i + j) % 6] + offset; - } - offset += 4; - } - // INIT QUAD DATA - mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // Position - mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 2 }); // Tex_coords - mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 4 }); // Color - mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // Texture Sampler Index - mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // translation - mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // angle - mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // Scale - mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // tex_is_grey_scale - mQuadData.mVertexBuffer = VertexBuffer::Create(mQuadData.mBufferLayout, mQuadData.MaxVertices, nullptr, mQuadData.MaxIndices, indices); - - // RAW VERTEX BUFFER - mQuadData.mRawVertexBuffer = new QuadData::Vertex[mQuadData.MaxVertices]; - mQuadData.mRawBufferIndex = 0; - - int layout_size = mQuadData.mBufferLayout.GetLayoutSizeInBytes(); - int struct_size = sizeof(QuadData::Vertex); - if (struct_size != layout_size) - { - Logger::Error(LogCategory::GRAPHICS, - "Quad::Vertex struct size does not match the vertex layout size! struct: %d, layout: %d", struct_size, layout_size); - } - - //mQuadData.mIndexBuffer = new IndexBuffer(mQuadData.MaxIndices * sizeof(u32)); - - std::string vert_source = File::ReadTextFile("quad.vert"); - std::string frag_source = File::ReadTextFile("quad.frag"); - mQuadData.mQuadShader = new Shader(vert_source.c_str(), nullptr, frag_source.c_str()); - if (!mQuadData.mQuadShader->IsValid()) - { - return OpRes::Fail("Failed to create the quad shader"); - } + OpRes result = InitQuadData(); + if (Failed(result)) { return OpRes::Fail("Could not initialize the 2D Renderer: %s", result.Description.c_str()); } - // TODO: INIT SPRITE DATA - + // INIT LINE DATA + result = InitLineData(); + if (Failed(result)) { return OpRes::Fail("Could not initialize the 2D Renderer: %s", result.Description.c_str()); } - // TODO: INIT WHITE TEXTURE - u8 data[4] = {255, 255, 255, 255}; - mpWhiteTexture = Texture::Create(data, 1, 1); - mLoadedTextures.push_back(mpWhiteTexture); + // INIT ELLIPSE DATA + result = InitEllipseData(); + if (Failed(result)) { return OpRes::Fail("Could not initialize the 2D Renderer: %s", result.Description.c_str()); } - // TODO: INIT TEXT SYSTEM + // INIT TEXT SYSTEM mTextAPI.Initialize().LogIfFailed(LogCategory::GRAPHICS); - mDefaultFont = mTextAPI.LoadFont(lunarium::OpenFontData, lunarium::OpenDataSize, "Open Font"); //mDefaultFont = mTextAPI.LoadFont(lunarium::RobotoFontData, lunarium::RobotoDataSize, "Roboto Font"); - // DEBUG: INIT TEST DATA - // mTestData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 2}); // Position - - // GLfloat vertices[6][2] = { - // { -0.5f, 0.5f, }, - // { 0.5f, -0.5f, }, - // { -0.5f, -0.5f, }, - - // { -0.5f, 0.5f, }, - // { 0.5f, 0.5f, }, - // { 0.5f, -0.5f, } - // }; - // u32 indices[6] = { 0, 1, 2, 3, 4, 5 }; - - // // mTestData.mIndexBuffer = new IndexBuffer(6, indices); - // mTestData.mVertexBuffer = VertexBuffer::Create(mTestData.mBufferLayout, 6, nullptr, 6, indices); - // std::string vert_source = File::ReadTextFile("test.vert"); - // std::string frag_source = File::ReadTextFile("test.frag"); - // mTestData.mQuadShader = new Shader(vert_source.c_str(), nullptr, frag_source.c_str()); - // if (!mTestData.mQuadShader->IsValid()) - // { - // return OpRes::Fail("Failed to create the test shader"); - // } - - // glGenVertexArrays(1, &mTVAO); - // glGenBuffers(1, &mTVBO); - - // glBindBuffer(GL_ARRAY_BUFFER, mTVBO); - // glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 12, vertices, GL_STATIC_DRAW); - - // glBindVertexArray(mTVAO); - // glEnableVertexAttribArray(0); - // glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0); - // glBindBuffer(GL_ARRAY_BUFFER, 0); - // glBindVertexArray(0); - return OpRes::OK(); } void Renderer2D::Shutdown() { - VertexBuffer::Destroy(&mQuadData.mVertexBuffer); + VertexBuffer::Destroy(&mQuadData.VertexBuffer); //delete[] mQuadData.mIndexBuffer; } @@ -207,9 +121,9 @@ namespace lunarium int texture_slot = -1; if (texture) { - for (int i = 0; i < mLoadedTextures.size(); i++) + for (int i = 0; i < mQuadData.LoadedTextures.size(); i++) { - if (texture == mLoadedTextures[i]) + if (texture == mQuadData.LoadedTextures[i]) { texture_slot = i; break; @@ -218,8 +132,8 @@ namespace lunarium if (-1 == texture_slot) { - mLoadedTextures.push_back(texture); - texture_slot = mLoadedTextures.size() - 1; + mQuadData.LoadedTextures.push_back(texture); + texture_slot = mQuadData.LoadedTextures.size() - 1; } } else @@ -227,19 +141,7 @@ namespace lunarium texture_slot = 0; } - - //unsigned char* vertices_wl = (unsigned char*)vertices; // vertices write location pointer - - // glm::mat4 model(1.0f); - // model = glm::translate(model, glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f)); - // model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f)); - - // glm::mat4 model = glm::mat4(1.0f); - // model = glm::translate(model, glm::vec3(quad.X, quad.Y, 0.0f)); - // model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f)); - // model = glm::scale(model, glm::vec3(quad.HalfWidth * 2, quad.HalfHeight * 2, 1.0f)); - - if (mQuadData.mRawBufferIndex + 4 > mQuadData.MaxVertices) + if (mQuadData.RawBufferIndex + 4 > mQuadData.MaxVertices) { Flush(); } @@ -248,92 +150,73 @@ namespace lunarium float left = sub_texture_area.X; if (left < 0) { - sub_texture_area = Rectangle::MakeFromTopLeft(0, 0, mLoadedTextures[texture_slot]->GetWidth(), mLoadedTextures[texture_slot]->GetHeight()); + sub_texture_area = Rectangle::MakeFromTopLeft(0, 0, mQuadData.LoadedTextures[texture_slot]->GetWidth(), + mQuadData.LoadedTextures[texture_slot]->GetHeight()); } - float xScale = (sub_texture_area.HalfWidth * 2) / mLoadedTextures[texture_slot]->GetWidth(); - float xOffset = sub_texture_area.left() / mLoadedTextures[texture_slot]->GetWidth(); - float yScale = (sub_texture_area.HalfHeight * 2) / mLoadedTextures[texture_slot]->GetHeight(); - float yOffset = sub_texture_area.top() / mLoadedTextures[texture_slot]->GetHeight(); + float scale_x = (sub_texture_area.HalfWidth * 2) / mQuadData.LoadedTextures[texture_slot]->GetWidth(); + float offset_x = sub_texture_area.left() / mQuadData.LoadedTextures[texture_slot]->GetWidth(); + float scale_y = (sub_texture_area.HalfHeight * 2) / mQuadData.LoadedTextures[texture_slot]->GetHeight(); + float offset_y = sub_texture_area.top() / mQuadData.LoadedTextures[texture_slot]->GetHeight(); - yOffset *= -1.0f; - - // mImageShader.SetUniformf("uvManip", { xScale, xOffset, yScale * -1.0f, yOffset}); - // vec2(vertex.z * uvManip.x + uvManip.y, vertex.w * uvManip.z - uvManip.w); + // Need to invert the offset_y because OpenGL likes being weird + offset_y *= -1.0f; // FIRST QuadData::Vertex v1; int vert_size = sizeof(QuadData::Vertex); v1.pos = mQuadData.vert_pos[0]; - v1.tex_coord = glm::vec2(mQuadData.vert_tex[0].x * xScale + xOffset, mQuadData.vert_tex[0].y * yScale - yOffset); + 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.mRawVertexBuffer[mQuadData.mRawBufferIndex], &v1, vert_size); - mQuadData.mRawBufferIndex += 1; + memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v1, vert_size); + mQuadData.RawBufferIndex += 1; // SECOND QuadData::Vertex v2; v2.pos = mQuadData.vert_pos[1]; - v2.tex_coord = glm::vec2(mQuadData.vert_tex[1].x * xScale + xOffset, mQuadData.vert_tex[1].y * yScale - yOffset); + 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.mRawVertexBuffer[mQuadData.mRawBufferIndex], &v2, vert_size); - mQuadData.mRawBufferIndex += 1; + memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v2, vert_size); + mQuadData.RawBufferIndex += 1; // THIRD QuadData::Vertex v3; v3.pos = mQuadData.vert_pos[2]; - v3.tex_coord = glm::vec2(mQuadData.vert_tex[2].x * xScale + xOffset, mQuadData.vert_tex[2].y * yScale - yOffset); + 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.mRawVertexBuffer[mQuadData.mRawBufferIndex], &v3, vert_size); - mQuadData.mRawBufferIndex += 1; + memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v3, vert_size); + mQuadData.RawBufferIndex += 1; // FOURTH QuadData::Vertex v4; v4.pos = mQuadData.vert_pos[3]; - v4.tex_coord = glm::vec2(mQuadData.vert_tex[3].x * xScale + xOffset, mQuadData.vert_tex[3].y * yScale - yOffset); + 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.mRawVertexBuffer[mQuadData.mRawBufferIndex], &v4, vert_size); - mQuadData.mRawBufferIndex += 1; - - + memcpy(&mQuadData.RawVertexBuffer[mQuadData.RawBufferIndex], &v4, vert_size); + mQuadData.RawBufferIndex += 1; + mQuadData.NumQuads++; - // memcpy(mQuadData.mRawVertexBuffer + mQuadData.mRawBufferIndex, vertices, sizeof(QuadData::Vertex) * 4); - // mQuadData.mRawBufferIndex += 4; - - // if (!mQuadData.mVertexBuffer->PushVertices(vertices, 4)) - // { - // //Logger::Info(LogCategory::GRAPHICS, "Quad VertexBuffer is full, flushing and retrying"); - // Flush(); - // DrawQuad(quad, color, texture); - // } - - // INDICES - // if (!mQuadData.mVertexBuffer->PushIndices(mQuadData.indices, 6)) - // { - // Logger::Error(LogCategory::GRAPHICS, "Quad IndexBuffer is full - This shouldn't happen because the VertexBuffer should fill up first!"); - // return; - // } - - mQuadData.mNumQuads++; + // Update render stats mFrameStats.NumTris += 2; mFrameStats.NumVerts += 4; @@ -341,9 +224,6 @@ namespace lunarium void Renderer2D::DrawString(const char* string, Rectangle bounding_box, Color color, float scale, int font) { - //Logger::Warn(LogCategory::GRAPHICS, "Renderer2D::DrawString is not yet implemented"); - // mText.DrawString(font, string, glm::vec2(boundingArea.left(), boundingArea.top()), - // glm::vec2(boundingArea.right(), boundingArea.bottom()), color, scale, mProjection); u32 f = font < 0 ? mDefaultFont : font; mTextAPI.DrawString(*this, f, string, bounding_box, color, scale); } @@ -352,65 +232,164 @@ namespace lunarium ///////////////////////////////////////////////////////////////////// // HELPERS ///////////////////////////////////////////////////////////////////// - void Renderer2D::Flush() + void Renderer2D::Flush(int flush_mode) { - if (mQuadData.mNumQuads > 0) + // Draw quads + if (mQuadData.NumQuads > 0 && flush_mode & (1 << FlushMode::Quads) > 0) { - if (!mQuadData.mVertexBuffer->PushVertices(mQuadData.mRawVertexBuffer, mQuadData.mNumQuads * 4)) + 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; } - //mQuadData.mIndexBuffer->Bind(); - mQuadData.mQuadShader->Use(); - for (int i = 0; i < mLoadedTextures.size(); i++) + mQuadData.QuadShader->Use(); + for (int i = 0; i < mQuadData.LoadedTextures.size(); i++) { - mLoadedTextures[i]->Bind(i); + mQuadData.LoadedTextures[i]->Bind(i); } - // Uniform umodel; - // umodel.Type = UniformType::FMAT4; - // umodel.Location = -1; - // umodel.Name = "model"; - Uniform uprojview; uprojview.Type = UniformType::FMAT4; uprojview.Location = -1; uprojview.Name = "projview"; - //mQuadData.mQuadShader->SetUniform(umodel, (void*)glm::value_ptr(glm::mat4(1.0f))).LogIfFailed(LogCategory::GRAPHICS); - mQuadData.mQuadShader->SetUniform(uprojview, (void*)glm::value_ptr(mpCamera->GetViewProjection())).LogIfFailed(LogCategory::GRAPHICS); + mQuadData.QuadShader->SetUniform(uprojview, (void*)glm::value_ptr(mpCamera->GetViewProjection())).LogIfFailed(LogCategory::GRAPHICS); - //Uniform uni { "spriteColor", UniformType::F3, -1 }; - //Color c = ; - //mQuadData.mQuadShader->SetUniform(uni, Color::Red().arr).LogIfFailed(LogCategory::GRAPHICS, "Failed to set uniform for the test shader!"); + mQuadData.VertexBuffer->Bind(); - mQuadData.mVertexBuffer->Bind(); + glDrawElements(GL_TRIANGLES, mQuadData.NumQuads * 6, GL_UNSIGNED_INT, nullptr); - glDrawElements(GL_TRIANGLES, mQuadData.mNumQuads * 6, GL_UNSIGNED_INT, nullptr); - // glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - // glLineWidth(20.0f); - // glDrawElements(GL_TRIANGLES, mQuadData.mNumQuads * 6, GL_UNSIGNED_INT, nullptr); - - // glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); mFrameStats.DrawCalls++; } + + // Draw Lines + if (mLineData.NumLines > 0 && flush_mode & (1 << FlushMode::Lines) > 0) + { + mLineData.MarkedForReset = true; + } + + // Draw Ellipses + if (mEllipseData.NumEllipses > 0 && flush_mode & (1 << FlushMode::Ellipses) > 0) + { + mEllipseData.MarkedForReset = true; + } + // Reset drawing data - for (int i = 0; i < mLoadedTextures.size(); i++) + ResetDrawingData(); + } + + ///////////////////////////////////////////////////////////////////// + // HELPERS HELPERS + ///////////////////////////////////////////////////////////////////// + + OpRes Renderer2D::InitQuadData() + { + u32* indices = new u32[mQuadData.MaxIndices]; + // Need to adjust the set of indices because they reference verts deeper into the buffer + // See Hazel for example of this + int offset = 0; + for (int i = 0; i < mQuadData.MaxIndices; i+=6) + { + for ( int j = 0; j < 6; j++) + { + indices[i + j] = mQuadData.indices[(i + j) % 6] + offset; + } + offset += 4; + } + + // INIT QUAD DATA + mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // Position + mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 2 }); // Tex_coords + mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 4 }); // Color + mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // Texture Sampler Index + mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // translation + mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // angle + mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // Scale + mQuadData.BufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 1 }); // tex_is_grey_scale + 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; + + int layout_size = mQuadData.BufferLayout.GetLayoutSizeInBytes(); + int struct_size = sizeof(QuadData::Vertex); + if (struct_size != layout_size) { - mLoadedTextures[i]->Unbind(); + Logger::Error(LogCategory::GRAPHICS, + "Quad::Vertex struct size does not match the vertex layout size! struct: %d, layout: %d", struct_size, layout_size); } - mLoadedTextures.clear(); - mQuadData.mVertexBuffer->Clear(); - mQuadData.mNumQuads = 0; - mQuadData.mRawBufferIndex = 0; + //mQuadData.mIndexBuffer = new IndexBuffer(mQuadData.MaxIndices * sizeof(u32)); - // TODO: Add the debug texture back to the map - mLoadedTextures.push_back(mpWhiteTexture); + std::string vert_source = File::ReadTextFile("quad.vert"); + std::string frag_source = File::ReadTextFile("quad.frag"); + mQuadData.QuadShader = new Shader(vert_source.c_str(), nullptr, frag_source.c_str()); + if (!mQuadData.QuadShader->IsValid()) + { + return OpRes::Fail("Failed to create the quad shader"); + } + + // INIT WHITE TEXTURE + u8 data[4] = {255, 255, 255, 255}; + mQuadData.WhiteTexture = Texture::Create(data, 1, 1); + mQuadData.LoadedTextures.push_back(mQuadData.WhiteTexture); + + return OpRes::OK(); + } + + OpRes Renderer2D::InitLineData() + { + + return OpRes::OK(); } + + OpRes Renderer2D::InitEllipseData() + { + + return OpRes::OK(); + } + + void Renderer2D::ResetDrawingData() + { + // Reset Quad Data + if (mQuadData.MarkedForReset) + { + // Clear loaded textures + for (int i = 0; i < mQuadData.LoadedTextures.size(); i++) + { + mQuadData.LoadedTextures[i]->Unbind(); + } + mQuadData.LoadedTextures.clear(); + + // Except for the white texture + mQuadData.LoadedTextures.push_back(mQuadData.WhiteTexture); + + mQuadData.VertexBuffer->Clear(); + mQuadData.NumQuads = 0; + mQuadData.RawBufferIndex = 0; + + mQuadData.MarkedForReset = false; + } + + // Reset Line Data + if (mLineData.MarkedForReset) + { + + mLineData.MarkedForReset = false; + } + + // Reset Ellipse Data + if (mEllipseData.MarkedForReset) + { + + mEllipseData.MarkedForReset = false; + } + } Texture* Renderer2D::GetTextDebugTexture() { diff --git a/src/renderer/renderer2D.h b/src/renderer/renderer2D.h index defa043..d22a64e 100644 --- a/src/renderer/renderer2D.h +++ b/src/renderer/renderer2D.h @@ -63,7 +63,17 @@ namespace lunarium friend class RenderContext; OpRes Initialize(); void Shutdown(); - void Flush(); + + enum FlushMode + { + Quads = 0x01, + Lines = 0x02, + Ellipses = 0x04, + + All = 0xFF + }; + + void Flush(int flush_mode = FlushMode::All); private: Renderer2D(); @@ -71,15 +81,34 @@ namespace lunarium Renderer2D(const Renderer2D&&) = delete; Renderer2D operator=(const Renderer2D&) = delete; + private: // Helpers + OpRes InitQuadData(); + OpRes InitLineData(); + OpRes InitEllipseData(); + void ResetDrawingData(); + private: // data + TextRenderer mTextAPI; + int mDefaultFont; + + Color mClearColor; + OrthographicCamera* mpCamera; + FrameStats mFrameStats; + + ///////////////////////////////////////////////////////////////////// + // QUAD DATA QUAD DATA + ///////////////////////////////////////////////////////////////////// struct QuadData { - int mNumQuads = 0; + bool MarkedForReset = false; + int NumQuads = 0; const int MaxQuads = 10000; const int MaxVertices = MaxQuads * 4; const int MaxIndices = MaxQuads * 6; const int TextureSlots = 32; + std::vector LoadedTextures; + Texture* WhiteTexture; const glm::vec4 vert_pos[4] = { { -0.5f, -0.5f, 0.0f, 1.0f }, @@ -109,22 +138,35 @@ namespace lunarium const u32 indices[6] = { 0, 1, 2, 2, 3, 0 }; - Vertex* mRawVertexBuffer; - int mRawBufferIndex; + Vertex* RawVertexBuffer; + int RawBufferIndex; - BufferLayout mBufferLayout; - VertexBuffer* mVertexBuffer; - Shader* mQuadShader; + BufferLayout BufferLayout; + VertexBuffer* VertexBuffer; + Shader* QuadShader; } mQuadData; + ///////////////////////////////////////////////////////////////////// + // ELLIPSE DATA ELLIPSE DATA + ///////////////////////////////////////////////////////////////////// struct EllipseData { - + bool MarkedForReset = false; + int NumEllipses = 0; } mEllipseData; + + ///////////////////////////////////////////////////////////////////// + // LINE DATA LINE DATA + ///////////////////////////////////////////////////////////////////// struct LineData { + bool MarkedForReset = false; + int NumLines = 0; + const int MaxLines = 30000; + const int MaxVertices = MaxLines * 2; + float Thickness = 1.0f; struct Vertex { @@ -140,19 +182,11 @@ namespace lunarium Shader* mShader; } mLineData; - TextRenderer mTextAPI; - int mDefaultFont; - - FrameStats mFrameStats; - OrthographicCamera* mpCamera; - std::vector mLoadedTextures; - Texture* mpWhiteTexture; - Color mClearColor; - /// DEBUG STUFF u32 mTVAO; u32 mTVBO; + }; } diff --git a/src/renderer/shaders/line.frag b/src/renderer/shaders/line.frag new file mode 100644 index 0000000..cbbd6b4 --- /dev/null +++ b/src/renderer/shaders/line.frag @@ -0,0 +1,9 @@ + +#version 450 core +in vec4 o_Color; +out vec4 color; + +void main() +{ + color = o_Color; +} \ No newline at end of file diff --git a/src/renderer/shaders/line.vert b/src/renderer/shaders/line.vert new file mode 100644 index 0000000..c260f68 --- /dev/null +++ b/src/renderer/shaders/line.vert @@ -0,0 +1,12 @@ + +#version 450 core +layout (location = 0) in vec2 position; // +layout (location = 1) in vec4 color; // + +out vec4 o_Color; + +void main() +{ + o_Color = color; + gl_Position = vec4(vertex, 0.0, 1.0); +} \ No newline at end of file diff --git a/src/run_modes/testbed/scenes/simple_render_scene.cpp b/src/run_modes/testbed/scenes/simple_render_scene.cpp index 900b9f0..c922556 100644 --- a/src/run_modes/testbed/scenes/simple_render_scene.cpp +++ b/src/run_modes/testbed/scenes/simple_render_scene.cpp @@ -258,27 +258,19 @@ namespace lunarium mImageSize.Height = Math::ClampI(mImageSize.Height, 180, 720); // Render to texture testing - // mFrameBufferOne->Bind(); - // OrthographicCamera cam(Vec2f{0.0f, 0.0f}, Sizef{(float)mFrameBufferOne->GetTexture()->GetWidth(), (float)mFrameBufferOne->GetTexture()->GetHeight()}); - // Renderer2D& g = Core::Graphics(); - // g.BeginDraw(&cam); - // // OpRes result = Core::GetInstance().BeginRenderToTexture(mFrameBufferOne); - // // if (Failed(result)) - // // { - // // Logger::Error(mLogCat, "Unable to render to texture: %s", result.Description.c_str()); - // // return; - // // } - - - // g.DrawQuad(Rectangle(300, 300, 150, 150), Color::Red()); - // g.DrawQuad(Rectangle(200, 300, 100, 100), Color(0.2f, 0.5f, 0.4f, 1.0f), nullptr, 45.0f); - // //g.DrawFilledEllipse(glm::vec2(600, 300), glm::vec2(100, 150), Color(1.0f, 0.0f, 1.0f, 1.0f), 100); - // // g.DrawString("This is a test of the text renderer!", Rectangle::MakeFromTopLeft(100, 200, mTextBoxWidth, 300), - // // Color(0.0f, 1.0f, 1.0f, 1.0f), 0.5f, g.DefaultFont()); - - // //mpRenderedImage = Core::GetInstance().EndRenderToTexture(); - // g.EndDraw(); - // mpRenderedImage = mFrameBufferOne->GetTexture(); + mFrameBufferOne->Bind(); + OrthographicCamera cam(Vec2f{0.0f, 0.0f}, Sizef{(float)mFrameBufferOne->GetTexture()->GetWidth(), (float)mFrameBufferOne->GetTexture()->GetHeight()}); + Renderer2D& g = Core::Graphics(); + g.BeginDraw(&cam); + + g.DrawQuad(Rectangle(300, 300, 150, 150), Color::Red()); + g.DrawQuad(Rectangle(200, 300, 100, 100), Color(0.2f, 0.5f, 0.4f, 1.0f), nullptr, 45.0f); + //g.DrawFilledEllipse(glm::vec2(600, 300), glm::vec2(100, 150), Color(1.0f, 0.0f, 1.0f, 1.0f), 100); + g.DrawString("This is a test of the text renderer!", Rectangle::MakeFromTopLeft(100, 200, mTextBoxWidth, 300), + Color(0.0f, 1.0f, 1.0f, 1.0f), 0.5f); + g.EndDraw(); + mpRenderedImage = mFrameBufferOne->GetTexture(); + mFrameBufferOne->Unbind(); box_angle += 0.01f; int w, h; @@ -311,25 +303,14 @@ namespace lunarium void SimpleRenderScene::RenderScene(Renderer2D& g) { - - // g.DrawImage(*mpRenderedImage, Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mpRenderedImage->GetWidth(), (float)mpRenderedImage->GetHeight()), - // Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(1.0f, 1.0f, 1.0f, 1.0f), angle); + Rectangle image_rect = Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mpRenderedImage->GetWidth(), (float)mpRenderedImage->GetHeight()); + g.DrawQuad(image_rect, Color::White(), mpRenderedImage, angle); //g.DrawQuad(Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(1.0f, 1.0f, 0.0f, 1.0f), nullptr, angle); g.DrawQuad(Rectangle(100, 100, 16, 16), Color::White(), mpTestImageLoad2, 0.0f, mSubTex); g.DrawSprite(mpTestImageLoad2, glm::vec2(600, 200), Rectangle::MakeFromTopLeft(255, 255, 255, 255)); - // g.DrawQuad(Rectangle(200, 200, 128.0f, 128.0f), Color(0.0f, 1.0f, 0.0f, 1.0f));//, nullptr, box_angle); - // g.DrawQuad(Rectangle(400, 300, 64.0f, 64.0f), Color(0.0f, 1.0f, 1.0f, 1.0f), nullptr, box_angle); - // g.DrawQuad(Rectangle(600, 300, 100.0f, 100.0f), Color::Blue(), nullptr, 45.0f); - // g.DrawQuad(Rectangle(500, 600, 100.0f, 100.0f), Color(0.25f, 0.75f, 0.8f), nullptr, 65.0f); - // g.DrawQuad(Rectangle(800, 500, 100.0f, 100.0f), Color(0.75f, 0.5f, 0.425f), nullptr, 90.0f); - // g.DrawQuad(Rectangle(300, 400, 64.0f, 64.0f), Color(0.25f, 0.5f, 1.0f, 1.0f), nullptr, box_angle * -1); - - - //g.DrawQuads(mQuads, NUM_QUADS, mQuadColors); - //g->DrawImage(*mpTestImageLoad, glm::vec2(0.0f, 0.0f), Color::White()); //Rectangle src = Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mpTestImageLoad->GetWidth(), (float)mpTestImageLoad->GetHeight()); //Rectangle src = Rectangle::MakeFromTopLeft(0.0f, 0.0f, mSrcWidth, mSrcHeight);