Added triangle drawing functions to BasicRenderer2D

This commit is contained in:
OmniaX-Dev 2026-04-15 17:15:34 +02:00
parent 10ecd04747
commit e8d13b931e
4 changed files with 94 additions and 21 deletions

View file

@ -15,6 +15,7 @@
***FIX: WindowOutputHandler text rendering
***Implement wrappers in Renderer2D to take a center and size for rects
***find a way to add fixed update to gui::Window
***Add triangle drawing functions to BasicRenderer2D
Add theme caching
Implement global scale (probably query desktop scale and adjust accordingly)
Implement show/hide functionality for widgets

View file

@ -215,27 +215,27 @@ namespace ogfx
Vec2 BasicRenderer2D::getStringDimensions(const String& message, i32 fontSize, TTF_Font* font)
{
if (!isValid()) return { 0, 0 };
if (fontSize <= 0) fontSize = m_fontSize;
if (!font) font = m_font;
if (fontSize <= 0) fontSize = m_fontSize;
if (!font) font = m_font;
i32 oldFontSize = getFontSize();
setFontSize(fontSize);
setFontSize(fontSize);
auto glyphs = m_fontGlyphAtlas.processString(message, font, fontSize);
if (glyphs.empty()) return { 0, 0 };
auto glyphs = m_fontGlyphAtlas.processString(message, font, fontSize);
if (glyphs.empty()) return { 0, 0 };
f32 totalWidth = 0;
for (size_t i = 0; i < glyphs.size(); i++)
{
totalWidth += glyphs[i]->advance;
if (i > 0)
{
i32 kern = 0;
TTF_GetGlyphKerning(font, glyphs[i - 1]->codepoint, glyphs[i]->codepoint, &kern);
totalWidth += kern;
}
}
f32 totalWidth = 0;
for (size_t i = 0; i < glyphs.size(); i++)
{
totalWidth += glyphs[i]->advance;
if (i > 0)
{
i32 kern = 0;
TTF_GetGlyphKerning(font, glyphs[i - 1]->codepoint, glyphs[i]->codepoint, &kern);
totalWidth += kern;
}
}
setFontSize(oldFontSize);
return { totalWidth, glyphs[0]->size.y };
return { totalWidth, glyphs[0]->size.y };
}
// ===================================================== UTILS =====================================================
@ -361,7 +361,7 @@ namespace ogfx
void BasicRenderer2D::drawCenteredString(const String& str, const Rectangle& bounds, const Color& color, i32 fontSize, f32 scale)
{
drawCenteredString(str, Vec2 { bounds.x + bounds.w * 0.5f, bounds.y + bounds.h * 0.5f }, color, fontSize, scale);
drawCenteredString(str, Vec2 { bounds.x + bounds.w * 0.5f, bounds.y + bounds.h * 0.5f }, color, fontSize, scale);
}
// ===================================================== SPECIALIZED =====================================================
@ -430,7 +430,7 @@ namespace ogfx
void BasicRenderer2D::drawRect(const Vec2& center, const Vec2& size, const Color& color, i32 thickness)
{
drawRect({ center.x - size.x * 0.5f, center.y - size.y * 0.5f, size.x, size.y }, color, thickness);
drawRect({ center.x - size.x * 0.5f, center.y - size.y * 0.5f, size.x, size.y }, color, thickness);
}
void BasicRenderer2D::drawRoundRect(const Rectangle& rect, const Color& color, f32 radius, i32 thickness)
@ -473,7 +473,7 @@ namespace ogfx
void BasicRenderer2D::drawRoundRect(const Vec2& center, const Vec2& size, const Color& color, f32 radius, i32 thickness)
{
drawRoundRect({ center.x - size.x * 0.5f, center.y - size.y * 0.5f, size.x, size.y }, color, radius, thickness);
drawRoundRect({ center.x - size.x * 0.5f, center.y - size.y * 0.5f, size.x, size.y }, color, radius, thickness);
}
void BasicRenderer2D::drawCircle(const Vec2& center, f32 radius, const Color& color, i32 thickness)
@ -511,6 +511,25 @@ namespace ogfx
generate_ellipse_stroke(center, rx, ry, thickness, 0.0f, 2.0f * M_PI, color, segments);
}
void BasicRenderer2D::drawTriangle(const Triangle& tri, const Color& color, i32 thickness)
{
if (!m_initialized)
return;
drawTriangle(tri.vA, tri.vB, tri.vC, color, thickness);
}
void BasicRenderer2D::drawTriangle(const Vec2& A, const Vec2& B, const Vec2& C, const Color& color, i32 thickness)
{
if (!m_initialized)
return;
drawLine({ A, B }, color, thickness, false);
drawLine({ B, C }, color, thickness, false);
drawLine({ C, A }, color, thickness, false);
}
void BasicRenderer2D::fillRect(const Rectangle& rect, const Color& color)
{
if (!m_initialized)
@ -679,6 +698,26 @@ namespace ogfx
generate_filled_ellipse(center, radiusX, radiusY, color, segments);
}
void BasicRenderer2D::fillTriangle(const Triangle& tri, const Color& color)
{
if (!m_initialized)
return;
fillTriangle(tri.vA, tri.vB, tri.vC, color);
}
void BasicRenderer2D::fillTriangle(const Vec2& A, const Vec2& B, const Vec2& C, const Color& color)
{
if (!m_initialized)
return;
Vec2 verts[3] = { A, B, C };
Vec2 texCoords[3] = { {0, 0}, {0, 0}, {0, 0} };
u32 inds[3] = { 0, 1, 2 };
push_polygon(verts, texCoords, 3, inds, 3, color, nullptr);
}
void BasicRenderer2D::outlinedRect(const Rectangle& rect, const Color& fillColor, const Color& outlineColor, i32 outlineThickness)
{
if (!m_initialized) return;
@ -733,6 +772,32 @@ namespace ogfx
fillEllipse(rect + offset, fillColor);
drawEllipse(rect, outlineColor, outlineThickness);
}
void BasicRenderer2D::outlinedTriangle(const Triangle& tri, const Color& fillColor, const Color& outlineColor, i32 outlineThickness)
{
if (!m_initialized) return;
outlinedTriangle(tri.vA, tri.vB, tri.vC, fillColor, outlineColor, outlineThickness);
}
void BasicRenderer2D::outlinedTriangle(const Vec2& A, const Vec2& B, const Vec2& C, const Color& fillColor, const Color& outlineColor, i32 outlineThickness)
{
if (!m_initialized) return;
drawTriangle(A, B, C, outlineColor, outlineThickness);
// Inset the fill triangle so it doesn't bleed past the outline
f32 inset = cast<f32>(outlineThickness);
Vec2 centroid = { (A.x + B.x + C.x) / 3.0f, (A.y + B.y + C.y) / 3.0f };
auto shrink = [&](const Vec2& v) -> Vec2 {
Vec2 dir = { centroid.x - v.x, centroid.y - v.y };
f32 len = std::sqrt(dir.x * dir.x + dir.y * dir.y);
if (len < 0.001f) return v;
dir.x /= len;
dir.y /= len;
return { v.x + dir.x * inset, v.y + dir.y * inset };
};
fillTriangle(shrink(A), shrink(B), shrink(C), fillColor);
}
// ===================================================== PRIMITIVES =====================================================

View file

@ -96,6 +96,8 @@ namespace ogfx
void drawCircle(const Vec2& center, f32 radius, const Color& color, i32 thickness = 1);
void drawCircle(const Rectangle& rect, const Color& color, i32 thickness = 1);
void drawEllipse(const Rectangle& rect, const Color& color, i32 thickness = 1);
void drawTriangle(const Triangle& tri, const Color& color, i32 thickness = 1);
void drawTriangle(const Vec2& A, const Vec2& B, const Vec2& C, const Color& color, i32 thickness = 1);
void fillRect(const Rectangle& rect, const Color& color);
void fillRect(const Vec2& center, const Vec2& size, const Color& color);
@ -104,6 +106,8 @@ namespace ogfx
void fillCircle(const Vec2& center, f32 radius, const Color& color);
void fillCircle(const Rectangle& rect, const Color& color);
void fillEllipse(const Rectangle& rect, const Color& color);
void fillTriangle(const Triangle& tri, const Color& color);
void fillTriangle(const Vec2& A, const Vec2& B, const Vec2& C, const Color& color);
void outlinedRect(const Vec2& center, const Vec2& size, const Color& fillColor, const Color& outlineColor, i32 outlineThickness = 1);
void outlinedRect(const Rectangle& rect, const Color& fillColor, const Color& outlineColor, i32 outlineThickness = 1);
@ -112,6 +116,8 @@ namespace ogfx
void outlinedCircle(const Vec2& center, f32 radius, const Color& fillColor, const Color& outlineColor, i32 outlineThickness = 1);
void outlinedCircle(const Rectangle& rect, const Color& fillColor, const Color& outlineColor, i32 outlineThickness = 1);
void outlinedEllipse(const Rectangle& rect, const Color& fillColor, const Color& outlineColor, i32 outlineThickness = 1);
void outlinedTriangle(const Triangle& tri, const Color& fillColor, const Color& outlineColor, i32 outlineThickness = 1);
void outlinedTriangle(const Vec2& A, const Vec2& B, const Vec2& C, const Color& fillColor, const Color& outlineColor, i32 outlineThickness = 1);
private:
void init_arrays(void);

View file

@ -153,7 +153,8 @@ class Window : public ogfx::gui::Window
void onRedraw(ogfx::BasicRenderer2D& gfx) override
{
gfx.drawAnimation(m_anim, { 200, 200 });
wout().xy(100, 100).fg(Colors::Crimson).p("CIAO BELLA").resetColors();
gfx.outlinedTriangle({ 30, 30 }, { 100, 50 }, { 60, 90 }, Colors::Crimson, Colors::DarkBlue, 5);
gfx.endFrame();
}
void onFixedUpdate(void) override