From 08adeb6b9d01671b043aecda06ce56403f08224a Mon Sep 17 00:00:00 2001 From: Joeyrp Date: Fri, 29 Oct 2021 20:44:17 -0400 Subject: [PATCH] Renderer code refactored to implement rotation in a cleaner way. Rectangle type refactored to only store the center point and the half width and half height. Test code refactored to reflect these changes. --- docs/core.todo | 6 ++- src/graphics/igraphics.h | 2 +- src/graphics/opengl/glGraphics.cpp | 52 ++++++------------- src/graphics/opengl/glGraphics.h | 6 +-- src/internal_libs/utils/types.cpp | 43 +++++++++------ src/internal_libs/utils/types.h | 23 ++++---- src/run_modes/tester/scenes/physicsScene.cpp | 50 +++++++++--------- .../tester/scenes/simpleRenderScene.cpp | 8 +-- src/run_modes/tester/tester.cpp | 2 +- 9 files changed, 96 insertions(+), 96 deletions(-) diff --git a/docs/core.todo b/docs/core.todo index 94ce7ab..b4ee6d7 100644 --- a/docs/core.todo +++ b/docs/core.todo @@ -17,9 +17,11 @@ Core: ✔ Implement the Image creation methods @done (9/9/2021, 2:50:20 PM) ✔ Implement Render to Texture @done (9/15/2021, 7:00:33 PM) ✔ Adjust the font loading code to use the binary file buffer instead of ifstream @done (9/17/2021, 6:11:06 PM) - ☐ Find a way to add rotation to shapes and images + ✔ Find a way to add rotation to shapes and images @done (10/29/2021, 7:35:14 PM) ✔ Add a DrawPolygon method that takes vertices and draws arbirary shapes @done (10/29/2021, 6:24:14 PM) - ☐ Allow DrawPolygon to add a texture to the polygon + ☐ Allow DrawPolygon to add a texture to the polygon @low + ✔ Refactor the drawing code to allow for rotation with cleaner code @high @done (10/29/2021, 8:36:24 PM) + ☐ Test rotation of images GUI: diff --git a/src/graphics/igraphics.h b/src/graphics/igraphics.h index 1a8ba79..c5cfdd4 100644 --- a/src/graphics/igraphics.h +++ b/src/graphics/igraphics.h @@ -53,7 +53,7 @@ namespace lunarium virtual void DrawEllipse(glm::vec2 center, glm::vec2 radii, Color color, float thickness, int resolution) = 0; virtual void DrawFilledEllipse(glm::vec2 center, glm::vec2 radii, Color color, int resolution) = 0; virtual void DrawBox(Rectangle dimensions, Color color, float thickness, float angle = 0.0f) = 0; - virtual void DrawFilledBox(glm::vec2 topLeft, glm::vec2 botRight, Color color, float angle = 0.0f) = 0; + virtual void DrawFilledBox(Rectangle box, Color color, float angle = 0.0f) = 0; virtual void DrawImage(Image& image, glm::vec2 topLeft, Color color, float angle = 0.0f) = 0; virtual void DrawImage(Image& image, Rectangle source, Rectangle destination, Color color, float angle = 0.0f) = 0; virtual void DrawString(const char* string, Rectangle boundingArea, Color color, float scale = 1.0f, int font = 0) = 0; diff --git a/src/graphics/opengl/glGraphics.cpp b/src/graphics/opengl/glGraphics.cpp index 9cb998b..47f9227 100644 --- a/src/graphics/opengl/glGraphics.cpp +++ b/src/graphics/opengl/glGraphics.cpp @@ -290,39 +290,18 @@ namespace lunarium glBindVertexArray(0); } - void OglGraphics::DrawFilledBox(glm::vec2 topLeft, glm::vec2 botRight, Color color, float angle) + void OglGraphics::DrawFilledBox(Rectangle box, Color color, float angle) { mShapeShader.MakeActive(); mShapeShader.SetUniformMatrix("projection", 1, glm::value_ptr(mProjection)); glm::mat4 model = glm::mat4(1.0f); - float width = botRight.x - topLeft.x; - float height = botRight.y - topLeft.y; - model = glm::translate(model, glm::vec3(topLeft.x + width / 2, topLeft.y + height / 2 , 0.0f)); + model = glm::translate(model, glm::vec3(box.X, box.Y, 0.0f)); model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f)); - model = glm::scale(model, glm::vec3(width, height, 1.0f)); + model = glm::scale(model, glm::vec3(box.HalfWidth * 2, box.HalfHeight * 2, 1.0f)); mShapeShader.SetUniformMatrix("model", 1, glm::value_ptr(model)); mShapeShader.SetUniformf("shapeColor", { color.Red, color.Green, color.Blue, color.Alpha }); glBindVertexArray(mRectVAO); - // GLfloat vertices[6][4] = { - // { topLeft.x, botRight.y, }, - // { botRight.x, topLeft.y, }, - // { topLeft.x, topLeft.y, }, - - // { topLeft.x, botRight.y, }, - // { botRight.x, botRight.y, }, - // { botRight.x, topLeft.y, } - // }; - - // Pos - // 0.0f, 1.0f, - // 1.0f, 0.0f, - // 0.0f, 0.0f, - - // 0.0f, 1.0f, - // 1.0f, 1.0f, - // 1.0f, 0.0f, - GLfloat vertices[6][4] = { { -0.5f, 0.5f, }, { 0.5f, -0.5f, }, @@ -342,7 +321,7 @@ namespace lunarium void OglGraphics::DrawBox(Rectangle dimensions, Color color, float thickness, float angle) { - glm::vec2 topLeft(dimensions.Left, dimensions.Top); + glm::vec2 topLeft(dimensions.left(), dimensions.top()); glm::vec2 botRight(dimensions.right(), dimensions.bottom()); // left side top to bottom @@ -358,18 +337,21 @@ namespace lunarium DrawLine(glm::vec2(botRight.x, topLeft.y), glm::vec2(topLeft.x, topLeft.y), color, thickness); } - void OglGraphics::DrawImage(Image& image, glm::vec2 topLeft, Color color, float angle) + void OglGraphics::DrawImage(Image& image, glm::vec2 position, Color color, float angle) { - DrawImage(image, Rectangle(0.0f, 0.0f, (float)image.GetWidth(), (float)image.GetHeight()), - Rectangle(topLeft.x, topLeft.y, (float)image.GetWidth(), (float)image.GetHeight()), color, angle); + float half_width = image.GetWidth() / 2; + float half_height = image.GetHeight() / 2; + DrawImage(image, Rectangle(half_width, half_height, half_width, half_height), + Rectangle(position.x, position.y, half_width, half_height), color, angle); } void OglGraphics::DrawImage(Image& image, Rectangle source, Rectangle destination, Color color, float angle) { glm::mat4 id = glm::mat4(1.0f); - glm::vec3 pos = glm::vec3(destination.Left, destination.Top, 0.0f); + glm::vec3 pos = glm::vec3(destination.left(), destination.top(), 0.0f); glm::mat4 trans = glm::translate(id, pos); - trans = glm::scale(trans, glm::vec3(destination.Width, destination.Height, 1.0f)); + trans = glm::rotate(trans, angle, glm::vec3(0.0f, 0.0f, 1.0f)); + trans = glm::scale(trans, glm::vec3(destination.HalfWidth * 2, destination.HalfHeight * 2, 1.0f)); mImageShader.MakeActive(); @@ -387,10 +369,10 @@ namespace lunarium // { // NOTE: Pretty sure these values will work out to be correct with out the if check - float xScale = source.Width / image.GetWidth(); - float xOffset = source.Left / image.GetWidth(); - float yScale = source.Height / image.GetHeight(); - float yOffset = source.Top / image.GetHeight(); + float xScale = (source.HalfWidth * 2) / image.GetWidth(); + float xOffset = source.left() / image.GetWidth(); + float yScale = (source.HalfHeight * 2) / image.GetHeight(); + float yOffset = source.top() / image.GetHeight(); // Logger::Log(LogCategory::GRAPHICS, LogLevel::INFO_VERBOSE, "uvManip Values: %f, %f, %f, %f", xScale, xOffset, yScale, yOffset); @@ -412,7 +394,7 @@ namespace lunarium void OglGraphics::DrawString(const char* string, Rectangle boundingArea, Color color, float scale, int font) { - mText.DrawString(font, string, glm::vec2(boundingArea.Left, boundingArea.Top), + mText.DrawString(font, string, glm::vec2(boundingArea.left(), boundingArea.top()), glm::vec2(boundingArea.right(), boundingArea.bottom()), color, scale, mProjection); } diff --git a/src/graphics/opengl/glGraphics.h b/src/graphics/opengl/glGraphics.h index b824a98..5283329 100644 --- a/src/graphics/opengl/glGraphics.h +++ b/src/graphics/opengl/glGraphics.h @@ -47,9 +47,9 @@ namespace lunarium virtual void DrawLine(glm::vec2 point1, glm::vec2 point2, Color color, float lineWidth); virtual void DrawEllipse(glm::vec2 center, glm::vec2 radii, Color color, float thickness, int resolution); virtual void DrawFilledEllipse(glm::vec2 center, glm::vec2 radii, Color color, int resolution); - virtual void DrawBox(Rectangle dimensions, Color color, float thickness, float angle = 0.0f); - virtual void DrawFilledBox(glm::vec2 topLeft, glm::vec2 botRight, Color color, float angle = 0.0f); - virtual void DrawImage(Image& image, glm::vec2 topLeft, Color color, float angle = 0.0f); + virtual void DrawBox(Rectangle box, Color color, float thickness, float angle = 0.0f); + virtual void DrawFilledBox(Rectangle box, Color color, float angle = 0.0f); + virtual void DrawImage(Image& image, glm::vec2 position, Color color, float angle = 0.0f); virtual void DrawImage(Image& image, Rectangle source, Rectangle destination, Color color, float angle = 0.0f); virtual void DrawString(const char* string, Rectangle boundingArea, Color color, float scale = 1.0f, int font = 0); diff --git a/src/internal_libs/utils/types.cpp b/src/internal_libs/utils/types.cpp index 2614d26..62dfea2 100644 --- a/src/internal_libs/utils/types.cpp +++ b/src/internal_libs/utils/types.cpp @@ -30,37 +30,48 @@ namespace lunarium // RECTANGLE //////////////////////////////////////////////////////////// Rectangle::Rectangle() - : Left(0.0f), Top(0.0f), Width(0.0f), Height(0.0f) + : X(0.0f), Y(0.0f), HalfWidth(1.0f), HalfHeight(1.0f) { } Rectangle::Rectangle(b2AABB& box) { - float hwidth = box.GetExtents().x; - float hheight = box.GetExtents().y; - Left = (box.GetCenter().x - hwidth); - Top = (box.GetCenter().y - hheight); - Width = hwidth * 2; - Height = hheight * 2; + X = box.GetCenter().x; + Y = box.GetCenter().y; + HalfWidth = box.GetExtents().x; + HalfHeight = box.GetExtents().y; } - Rectangle::Rectangle(float _left, float _top, float _width, float _height) - : Left(_left), Top(_top), Width(_width), Height(_height) + Rectangle::Rectangle(float x, float y, float half_width, float half_height) + : X(x), Y(y), HalfWidth(half_width), HalfHeight(half_height) { + } + + Rectangle Rectangle::MakeFromTopLeft(float left, float top, float width, float height) + { + float halfw = width / 2; + float halfh = height / 2; + return Rectangle(left + halfw, top + halfh, halfw, halfh); + } + void Rectangle::Scale(float x, float y) + { + HalfWidth *= x; + HalfHeight *= y; } + float Rectangle::Area() const { - return Width * Height; + return HalfWidth * 2 * HalfHeight * 2; } bool Rectangle::ContainsPoint(glm::vec2 point) const { - if (point.x < this->Left || point.x > this->right()) + if (point.x < this->left() || point.x > this->right()) return false; - if (point.y < this->Top || point.y > this->bottom()) + if (point.y < this->top() || point.y > this->bottom()) return false; return true; @@ -68,14 +79,14 @@ namespace lunarium bool Rectangle::Intersects(const Rectangle& other, glm::vec2& centers) const { - glm::vec2 myCenter = glm::vec2(this->Left + (this->Width / 2.0f), this->Top + (this->Height / 2.0f)); - glm::vec2 otherCenter = glm::vec2(other.Left + (other.Width / 2.0f), other.Top + (other.Height / 2.0f)); + glm::vec2 myCenter = glm::vec2(X, Y); + glm::vec2 otherCenter = glm::vec2(other.X, other.Y); centers = myCenter - otherCenter; - if (this->Left > other.right() || other.Left > this->right()) + if (this->left() > other.right() || other.left() > this->right()) return false; - if (this->Top > other.bottom() || other.Top > this->bottom()) + if (this->top() > other.bottom() || other.top() > this->bottom()) return false; return true; diff --git a/src/internal_libs/utils/types.h b/src/internal_libs/utils/types.h index 812c589..9367c0f 100644 --- a/src/internal_libs/utils/types.h +++ b/src/internal_libs/utils/types.h @@ -59,21 +59,24 @@ namespace lunarium ///////////////////////////////////////////////// struct Rectangle { - float Left; - float Top; - float Width; - float Height; + float X; + float Y; + float HalfWidth; + float HalfHeight; - float right() const { return Left + Width; } - float bottom() const { return Top + Height; } + float left() const { return X - HalfWidth; } + float top() const { return Y - HalfHeight; } + float right() const { return X + HalfWidth; } + float bottom() const { return Y + HalfHeight; } - glm::vec2 LeftTop() const { return glm::vec2(Left, Top); } - glm::vec2 RightBottom() const { return glm::vec2(right(), bottom()); } + glm::vec2 CenterPoint() const; + Sizef FullSize() const; Rectangle(); Rectangle(b2AABB& box); - Rectangle(float _left, float _top, float _width, float _height); + Rectangle(float x, float y, float half_width, float half_height); + void Scale(float x, float y); float Area() const; bool ContainsPoint(glm::vec2 point) const; @@ -81,6 +84,8 @@ namespace lunarium // Rectangle's center to the invoking object's center. // This could be used for determining the angle of the intersection. bool Intersects(const Rectangle& other, glm::vec2& centers) const; + + static Rectangle MakeFromTopLeft(float left, float top, float width, float height); }; ///////////////////////////////////////////////// } diff --git a/src/run_modes/tester/scenes/physicsScene.cpp b/src/run_modes/tester/scenes/physicsScene.cpp index 8b13727..2c4998c 100644 --- a/src/run_modes/tester/scenes/physicsScene.cpp +++ b/src/run_modes/tester/scenes/physicsScene.cpp @@ -127,17 +127,18 @@ namespace lunarium mpGroundBox->ComputeAABB(&groundbox, mpGroundBody->GetTransform(), 0); Rectangle groundRect(groundbox); - g->DrawFilledBox(groundRect.LeftTop() * scaleFactor, - groundRect.RightBottom() * scaleFactor, - Color(0.0f, 1.0f, 0.0f, 1.0f)); + groundRect.Scale(scaleFactor, scaleFactor); + groundRect.X *= scaleFactor; + groundRect.Y *= scaleFactor; + g->DrawFilledBox(groundRect, Color(0.0f, 1.0f, 0.0f, 1.0f)); b2AABB groundbox2; - mpGroundBox2->ComputeAABB(&groundbox2, mpGroundBody2->GetTransform(), 0); - + mpGroundBox2->ComputeAABB(&groundbox2, mpGroundBody2->GetTransform(), 0); Rectangle groundRect2(groundbox2); - g->DrawFilledBox(groundRect2.LeftTop() * scaleFactor, - groundRect2.RightBottom() * scaleFactor, - Color(0.0f, 1.0f, 0.0f, 1.0f)); + groundRect2.Scale(scaleFactor, scaleFactor); + groundRect2.X *= scaleFactor; + groundRect2.Y *= scaleFactor; + g->DrawFilledBox(groundRect2, Color(0.0f, 1.0f, 0.0f, 1.0f)); b2AABB dynbox; b2Transform transform; @@ -146,39 +147,38 @@ namespace lunarium mpDynamicBox->ComputeAABB(&dynbox, transform, 0); Rectangle dynRect(dynbox); float angle = mpDynamicBody->GetAngle(); - g->DrawFilledBox(dynRect.LeftTop() * scaleFactor, - dynRect.RightBottom() * scaleFactor, - Color(0.0f, 0.0f, 1.0f, 1.0f), angle); + dynRect.Scale(scaleFactor, scaleFactor); + dynRect.X *= scaleFactor; + dynRect.Y *= scaleFactor; + g->DrawFilledBox(dynRect, Color(0.0f, 0.0f, 1.0f, 1.0f), angle); // Debug info char str[256] = { 0 }; - sprintf(str, "GroundBox: (%f, %f) (%f, %f)", - groundRect.LeftTop().x * scaleFactor, groundRect.LeftTop().y * scaleFactor, - groundRect.RightBottom().x * scaleFactor, groundRect.RightBottom().y * scaleFactor); - g->DrawString(str, Rectangle(10.0f, 10.0f, 800.0f, 30.0f), Color(0.75f, 0.85f, 0.5f, 1.0f), 0.4f); + sprintf(str, "GroundBox: pos: (%f, %f) size: (%f, %f)", groundRect.X, groundRect.Y, groundRect.HalfWidth, groundRect.HalfHeight); + g->DrawString(str, Rectangle::MakeFromTopLeft(10.0f, 10.0f, 800.0f, 30.0f), Color(0.75f, 0.85f, 0.5f, 1.0f), 0.4f); - sprintf(str, "GroundBox Half Size: (%f, %f)", groundRect.Width, groundRect.Height); - g->DrawString(str, Rectangle(10.0f, 35.0f, 800.0f, 30.0f), Color(0.75f, 0.85f, 0.5f, 1.0f), 0.4f); + // sprintf(str, "GroundBox Half Size: (%f, %f)", groundRect.Width, groundRect.Height); + // g->DrawString(str, Rectangle(10.0f, 35.0f, 800.0f, 30.0f), Color(0.75f, 0.85f, 0.5f, 1.0f), 0.4f); - sprintf(str, "DynBox: (%f, %f) (%f, %f), Angle: %f", - dynRect.LeftTop().x * scaleFactor, dynRect.LeftTop().y * scaleFactor, - dynRect.RightBottom().x * scaleFactor, dynRect.RightBottom().y * scaleFactor, angle); - g->DrawString(str, Rectangle(10.0f, 60.0f, 1000.0f, 100.0f), Color(0.75f, 0.85f, 0.5f, 1.0f), 0.4); + // sprintf(str, "DynBox: (%f, %f) (%f, %f), Angle: %f", + // dynRect.LeftTop().x * scaleFactor, dynRect.LeftTop().y * scaleFactor, + // dynRect.RightBottom().x * scaleFactor, dynRect.RightBottom().y * scaleFactor, angle); + // g->DrawString(str, Rectangle(10.0f, 60.0f, 1000.0f, 100.0f), Color(0.75f, 0.85f, 0.5f, 1.0f), 0.4); int ww, wh; Core::MainWindow().GetFramebufferSize(&ww, &wh); for (int i = 0; i < wh; i += 10) { sprintf(str, "%d", i); - g->DrawString(str, Rectangle(ww - 35.0f, i, 4.0f, 5.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 0.25f); - g->DrawBox(Rectangle(ww - 10.0f, i, 10.0f, 2.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 1.0f); + g->DrawString(str, Rectangle::MakeFromTopLeft(ww - 35.0f, i, 4.0f, 5.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 0.25f); + g->DrawBox(Rectangle::MakeFromTopLeft(ww - 10.0f, i, 10.0f, 2.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 1.0f); } for (int i = 0; i < ww; i += 25) { sprintf(str, "%d", i); - g->DrawString(str, Rectangle(i, wh - 20.0f, 4.0f, 5.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 0.25f); - g->DrawBox(Rectangle(i, wh - 5.0f, 2.0f, 5.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 1.0f); + g->DrawString(str, Rectangle::MakeFromTopLeft(i, wh - 20.0f, 4.0f, 5.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 0.25f); + g->DrawBox(Rectangle::MakeFromTopLeft(i, wh - 5.0f, 2.0f, 5.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 1.0f); } } diff --git a/src/run_modes/tester/scenes/simpleRenderScene.cpp b/src/run_modes/tester/scenes/simpleRenderScene.cpp index 6893da9..8d1893e 100644 --- a/src/run_modes/tester/scenes/simpleRenderScene.cpp +++ b/src/run_modes/tester/scenes/simpleRenderScene.cpp @@ -78,7 +78,7 @@ namespace lunarium IGraphics& g = Core::Graphics(); 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(100, 200, mTextBoxWidth, 300), + 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(); @@ -86,9 +86,9 @@ namespace lunarium void SimpleRenderScene::OnRender(IGraphics* g) { - g->DrawImage(*mpRenderedImage, Rectangle(0.0f, 0.0f, (float)mpRenderedImage->GetWidth(), (float)mpRenderedImage->GetHeight()), - Rectangle(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(1.0f, 1.0f, 1.0f, 1.0f)); + 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)); - g->DrawBox(Rectangle(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(0.0f, 0.0f, 0.0f, 1.0f), 1.0f); + g->DrawBox(Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(0.0f, 0.0f, 0.0f, 1.0f), 1.0f); } } \ No newline at end of file diff --git a/src/run_modes/tester/tester.cpp b/src/run_modes/tester/tester.cpp index 37e0db1..c4c0566 100644 --- a/src/run_modes/tester/tester.cpp +++ b/src/run_modes/tester/tester.cpp @@ -34,7 +34,7 @@ namespace lunarium Logger::Log(mLogCat, LogLevel::INFO, "BUILDING WITH THE EDITOR!"); #endif - // mpScene = new SimpleRenderScene(mLogCat); + // mpScene = new SimpleRenderScene(mLogCat); mpScene = new PhysicsScene(mLogCat); mpScene->OnLoad();