Naiive & Slow (But correct) implementation of OutlineRoundedRect. Needs to be performance-improved to a contiguous line loop.
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 7m7s

This commit is contained in:
2024-10-16 13:19:42 -04:00
parent cc504c65ec
commit 7f1794e48f
4 changed files with 151 additions and 1 deletions

View File

@@ -58,6 +58,8 @@ namespace JGL {
void DrawPoint(const Color4& color, const Vector2& coordinates, float radius = 1.f);
void DrawPoint(const Color4& color, float x, float y, float radius = 1.f);
void DrawPoints(const Color4& color, const std::vector<Vector2>& points, float radius = 1.f);
/// Plots a line (segment) on the screen.
/// @param color A 3-or-4 channel color value. @see classes Color3, Color4.
/// @param A The starting point of the line segment.
@@ -82,6 +84,14 @@ namespace JGL {
/// Draws a filled rectangle with rounded corners on the screen.
void FillRoundedRect(const Color4& color, const Vector2& pos, const Vector2& size, float radius = 5, unsigned int subdivisions = 8);
/// Draws a filled rectangle with chamfered (beveled) corners on the screen.
void FillChamferRect(const Color4& color, const Vector2& pos, const Vector2& size, float radius = 5);
/// Draws an outline of a rectangle with rounded corners onto the screen.
void OutlineRoundedRect(const Color4& color, const Vector2& pos, const Vector2& size, float radius = 5, float thickness = 1);
void OutlineChamferRect(const Color4& color, const Vector2& pos, const Vector2& size, float radius = 5, float thickness = 1);
/// Draws a render target to the screen.
void DrawRenderTarget(const RenderTarget& render_target, const Vector2& position, float rad_rotation = 0, const Vector2& origin = Vector2(0 , 0),
const Vector2& scale = Vector2(1, 1), const Color4& color = Colors::White, Direction inversion = Direction::None);
@@ -164,8 +174,11 @@ namespace JGL {
/// TODO Implement the following. These ones are going to be extremely annoying.
void FillPolygon(const Color4& color, const std::vector<Vector2>& points);
void FillTexturedPolygon();
void OutlineRoundedRect(const Color4& color, const Vector2& pos, const Vector2& size, float radius = 5, float thickness = 1);
void FillTexturedTriangle();
void DrawArc(const Color4 &color, const Vector2 &center, float radius, float arc_begin, float arc_end,
unsigned int subdivisions, float thickness);
}
/// Drawing functions for primitive 3D Shapes.

View File

@@ -38,6 +38,8 @@ public:
}
void Draw() {
if (dragging)
J2D::DrawPoint(Colors::White, position, 4.f);
else if (hovered)
@@ -46,6 +48,8 @@ public:
J2D::DrawPoint(Colors::Reds::Salmon, position, 3.f);
J2D::DrawString(Colors::White, std::format("{:.1f},{:.1f}", position.x, position.y), position.x, position.y, 1.f, 10, FreeSans);
}
};
@@ -174,6 +178,9 @@ public:
J2D::FillCircle(Colors::White, {52, 204}, 50, 24);
J2D::OutlineCircle(Colors::White, {153, 204}, 50, 24);
J2D::FillChamferRect(Colors::Reds::LightSalmon, {150, 400}, {64, 64}, 5);
J2D::OutlineRoundedRect(Colors::Reds::LightCoral, {250, 350}, {128, 128}, 10, 2);
J2D::FillGradientTriangle(Color4(Colors::Red), Color4(Colors::Green), Color4(Colors::Blue), {{0, 275}, {0, 375}, {100, 375}});
J2D::OutlineTriangle(Colors::Blue, {{100, 275}, {0, 275}, {100, 375}});
J2D::DrawGradientLine(Colors::Red, Colors::Blue, {105, 375}, {200, 275}, 2);

View File

@@ -687,6 +687,135 @@ namespace JGL {
glColor4fv(baseColor);
}
void J2D::DrawGradientLine(const Color4 &color_a, const Color4 &color_b, float x, float y, float w, float h,
float thickness) {
DrawGradientLine(color_a, color_b, {x, y}, {w, h}, thickness);
}
void J2D::DrawArc(const Color4& color, const Vector2& center, float radius, float arc_begin, float arc_end, unsigned int subdivisions, float thickness)
{
if (!inJ2D)
Logger::Error("Drawing J2D element before J2D begin.");
float step = Math::Abs(arc_end-arc_begin) / (float) subdivisions;
std::vector<Vector2> vertices(subdivisions);
GLfloat angle, x, y;
int i = 0;
for (angle = arc_begin; angle <= arc_end; angle += step) {
x = center.x + (radius * std::cos(angle));
y = center.y + (radius * std::sin(angle));
if (i < subdivisions)
vertices[i] = {x, y};
else
vertices.emplace_back(x, y);
i++;
}
glLineWidth(thickness);
glColor4ubv(color.ptr());
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices.data());
glDrawArrays(GL_LINE_STRIP, 0, (int) vertices.size());
glColor4fv(baseColor);
}
void J2D::OutlineRoundedRect(const Color4 &color, const Vector2 &pos, const Vector2 &size, float radius, float thickness)
{
// A rounded rectangle of size 2a x 2b with rounding radius r is given by
// f(x; a, r) + f(y; b, r) = 1
// where
// f(x; a, r) = {
// if |x| >= a - r: (|x| - (a-r) / r )^2
// otherwise: 0
// }
//std::vector<Vector2> vertices;
// TODO: Calculate vertices for top-left quarter-circle.
Vector2 tl = pos;
Vector2 tr = pos + Vector2(size.x, 0);
Vector2 br = pos + size;
Vector2 bl = pos + Vector2(0, size.y);
// Center-point around which to calculate each 'quarter-circle'.
Vector2 anchor_tl = pos + Vector2(radius, radius);
Vector2 anchor_tr = pos + Vector2(size.x-radius, radius);
Vector2 anchor_br = pos + size - Vector2(radius, radius);
Vector2 anchor_bl = pos + Vector2(radius, size.y - radius);
//J2D::Begin();
//J2D::DrawPoints(Colors::Red, {tl, tr, br, bl}, 2);
//J2D::DrawPoints(Colors::Blue, {anchor_tl, anchor_tr, anchor_br, anchor_bl}, 2);
//J2D::End();
Vector2 anchor_topleft_top = pos + Vector2(radius, 0);
Vector2 anchor_topright_top = pos + Vector2(size.x - radius, 0);
// TODO: Calculate vertices for top-right quarter-circle.
Vector2 anchor_topright_right = pos + Vector2(size.x, radius);
Vector2 anchor_bottomright_right = pos + Vector2(size.x, size.y - radius);
// TODO: Calculate vertices for bottom-right quarter-circle.
Vector2 anchor_bottomright_bottom = pos + Vector2(size.x - radius, size.y);
Vector2 anchor_bottomleft_bottom = pos + Vector2(radius, size.y);
// TODO: Calculate vertices for bottom-left quarter-circle.
Vector2 anchor_bottomleft_left = pos + Vector2(0, size.y - radius);
Vector2 anchor_topleft_left = pos + Vector2(0, radius);
//J2D::Begin();
// The 3.01f, etc is a tiny-bit of overshoot to compensate for the fact that
// this is not being plotted as a continuous line-loop.
// Once i'm done working this out I expect bill will want to make it such.
unsigned int subdivisions = 9;
J2D::DrawArc(color, anchor_tl, radius, Math::Pi, 3.01f*Math::Pi/2.f, subdivisions, thickness);
J2D::DrawLine(color, anchor_topleft_top, anchor_topright_top, thickness);
J2D::DrawArc(color, anchor_tr, radius, 3.f*Math::Pi/2.f, 2.02*Math::Pi, subdivisions, thickness);
J2D::DrawLine(color, anchor_topright_right, anchor_bottomright_right, thickness);
J2D::DrawArc(color, anchor_br, radius, 0.0f, 1.01f*Math::Pi/2, subdivisions, thickness);
J2D::DrawLine(color, anchor_bottomright_bottom, anchor_bottomleft_bottom, thickness);
J2D::DrawArc(color, anchor_bl, radius, Math::Pi/2, Math::Pi*1.01f, subdivisions, thickness);
J2D::DrawLine(color, anchor_bottomleft_left, anchor_topleft_left, thickness);
//J2D::End();
}
void J2D::FillChamferRect(const Color4 &color, const Vector2 &pos, const Vector2 &size, float radius) {
FillRoundedRect(color, pos, size, radius, 4);
}
void J2D::OutlineChamferRect(const Color4 &color, const Vector2 &pos, const Vector2 &size, float radius,
float thickness) {
Vector2 anchor_topleft_top = pos + Vector2(radius, 0);
Vector2 anchor_topright_top = pos + Vector2(size.x - radius, 0);
Vector2 anchor_topright_right = pos + Vector2(size.x, radius);
Vector2 anchor_bottomright_right = pos + Vector2(size.x, size.y - radius);
Vector2 anchor_bottomright_bottom = pos + Vector2(size.x - radius, size.y);
Vector2 anchor_bottomleft_bottom = pos + Vector2(radius, size.y);
Vector2 anchor_bottomleft_left = pos + Vector2(0, size.y - radius);
Vector2 anchor_topleft_left = pos + Vector2(0, radius);
Vector2 vertices[] = {anchor_topleft_top, anchor_topright_top, anchor_topright_right, anchor_bottomright_right, anchor_bottomright_bottom, anchor_bottomleft_bottom, anchor_bottomleft_left, anchor_topleft_left};
glColor4ubv(color.ptr());
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), vertices);
glDrawArrays(GL_LINE_LOOP, 0, 8);
glColor4fv(baseColor);
}
void J2D::DrawPoints(const Color4 &color, const std::vector<Vector2> &points, float radius) {
glPointSize(radius);
glColor4ubv(color.ptr());
glVertexPointer(2, GL_FLOAT, sizeof(Vector2), points.data());
glDrawArrays(GL_POINTS, 0, points.size());
glColor4fv(baseColor);
}
#pragma endregion
#pragma region J3D

View File

@@ -156,6 +156,7 @@ namespace JGL {
void J3D::DrawString(const Color4& color, const std::string& text, const Vector3& pos, float scale, u32 size, const Font& font, const EulerAngle& angle, bool draw_back_face) {
// TODO: Determine the proper scale factor mathematically
// This number was arrived at holistically.
scale = scale * 0.002f;
scale = -scale;
float x = pos.x;