aboutsummaryrefslogtreecommitdiff
path: root/src/renderer
diff options
context:
space:
mode:
authorfschildt <florian.schildt@protonmail.com>2025-10-16 15:33:06 +0200
committerfschildt <florian.schildt@protonmail.com>2025-10-16 15:33:06 +0200
commita873df7a66dc1831cee4eae2d998abed88246268 (patch)
treec19cd079ce106e1431d64c34babf4ef59cf71723 /src/renderer
parent9f2845b12135c32dde91e58afc1193d54333ec9f (diff)
renderer: introduce text rendering
Diffstat (limited to 'src/renderer')
-rw-r--r--src/renderer/RSoftwareBackend.cpp123
-rw-r--r--src/renderer/RSoftwareBackend.hpp13
-rw-r--r--src/renderer/Renderer.cpp47
-rw-r--r--src/renderer/Renderer.hpp23
4 files changed, 155 insertions, 51 deletions
diff --git a/src/renderer/RSoftwareBackend.cpp b/src/renderer/RSoftwareBackend.cpp
index 4d78ec7..d05cee7 100644
--- a/src/renderer/RSoftwareBackend.cpp
+++ b/src/renderer/RSoftwareBackend.cpp
@@ -1,3 +1,4 @@
+#include "imgui.h"
#include <renderer/RSoftwareBackend.hpp>
#include <SDL3/SDL_video.h>
@@ -8,9 +9,8 @@
#include <cstdio>
-RSoftwareBackend::RSoftwareBackend(SDL_Window* window, Renderer& renderer)
- : m_window {window}
- , m_renderer {renderer}
+RSoftwareBackend::RSoftwareBackend(Renderer& renderer)
+ : m_renderer {renderer}
{
m_canvas.rshift = 0;
m_canvas.gshift = 8;
@@ -53,21 +53,7 @@ RSoftwareBackend::Draw()
SortRenderEntities();
- REntity_Rectangle clear_rect = {
- REntityType_Rectangle,
- {0, 0, (float)(m_canvas.w-1), (float)(m_canvas.h-1)},
- 0.0f,
- m_renderer.m_clear_color
- };
- DrawRectangle(clear_rect);
-
-
- float z = -1;
for (RSortEntry sort_entry : m_renderer.m_sort_entries) {
- if (sort_entry.z >= z) {
- z = sort_entry.z;
- }
-
REntity& entity = m_renderer.m_render_entities[sort_entry.entity_index];
switch (entity.type) {
case REntityType_Rectangle: {
@@ -78,6 +64,13 @@ RSoftwareBackend::Draw()
DrawAlphaBitmap(entity.bitmap);
} break;
+ case REntityType_Text: {
+ DrawText(entity.text);
+ }; break;
+
+ case REntityType_Circle: {
+ }; break;
+
default:;
}
}
@@ -147,10 +140,10 @@ RSoftwareBackend::DrawRectangle(REntity_Rectangle& entity)
void
RSoftwareBackend::DrawAlphaBitmap(REntity_AlphaBitmap& entity)
{
- int32_t x0 = (int32_t)entity.pos.x;
- int32_t y0 = (int32_t)entity.pos.y;
- int32_t x1 = (int32_t)entity.pos.x + entity.bitmap.w - 1;
- int32_t y1 = (int32_t)entity.pos.y + entity.bitmap.h - 1;
+ int32_t x0 = m_renderer.WorldXToScreenX(entity.pos.x);
+ int32_t y0 = m_renderer.WorldYToScreenY(entity.pos.y);
+ int32_t x1 = x0 + entity.bitmap.w - 1;
+ int32_t y1 = y0 + entity.bitmap.h - 1;
int32_t cut_left = 0;
int32_t cut_bot = 0;
@@ -171,10 +164,6 @@ RSoftwareBackend::DrawAlphaBitmap(REntity_AlphaBitmap& entity)
}
- uint32_t rshift = m_canvas.rshift;
- uint32_t gshift = m_canvas.gshift;
- uint32_t bshift = m_canvas.bshift;
-
uint8_t* alpha_row = (uint8_t*)entity.bitmap.pixels.get() + (-cut_bot * entity.bitmap.w) + (-cut_left);
uint32_t* rgba_row = m_canvas.pixels + y0 * m_canvas.w + x0;
for (int32_t y = y0; y <= y1; y++) {
@@ -193,9 +182,9 @@ RSoftwareBackend::DrawAlphaBitmap(REntity_AlphaBitmap& entity)
float g1 = entity.color.g * alphaf;
float b1 = entity.color.b * alphaf;
- uint32_t r2 = uint32_t(r1 * 255.0f) << rshift;
- uint32_t g2 = uint32_t(g1 * 255.0f) << gshift;
- uint32_t b2 = uint32_t(b1 * 255.0f) << bshift;
+ uint32_t r2 = uint32_t(r1 * 255.0f) << m_canvas.rshift;
+ uint32_t g2 = uint32_t(g1 * 255.0f) << m_canvas.gshift;
+ uint32_t b2 = uint32_t(b1 * 255.0f) << m_canvas.bshift;
uint32_t rgba_result = r2 | g2 | b2;
*rgba = rgba_result;
@@ -209,3 +198,81 @@ RSoftwareBackend::DrawAlphaBitmap(REntity_AlphaBitmap& entity)
}
}
+void
+RSoftwareBackend::DrawText(REntity_Text& entity)
+{
+ int32_t xscreen = m_renderer.WorldXToScreenX(entity.pos.x);
+ int32_t yscreen = m_renderer.WorldYToScreenY(entity.pos.y);
+ for (char32_t ch : entity.text) {
+ Glyph& glyph = entity.font.GetGlyph(ch);
+
+ int32_t x = xscreen + glyph.xoff;
+ int32_t y = yscreen + glyph.yoff;
+ DrawTextGlyph(glyph, entity.color, x, y);
+
+ xscreen += glyph.xadvance;
+ }
+}
+
+void
+RSoftwareBackend::DrawTextGlyph(Glyph& glyph, Color color, int32_t xscreen, int32_t yscreen)
+{
+ int32_t x0 = xscreen;
+ int32_t y0 = yscreen;
+ int32_t x1 = x0 + glyph.bitmap.w - 1;
+ int32_t y1 = y0 + glyph.bitmap.h - 1;
+
+ int32_t cut_left = 0;
+ int32_t cut_bot = 0;
+
+ if (x0 < 0) {
+ cut_left = x0;
+ x0 = 0;
+ }
+ if (y0 < 0) {
+ cut_bot = y0;
+ y0 = 0;
+ }
+ if (x1 >= m_canvas.w) {
+ x1 = m_canvas.w - 1;
+ }
+ if (y1 >= m_canvas.h) {
+ y1 = m_canvas.h - 1;
+ }
+
+
+ uint8_t* alpha_row = (uint8_t*)glyph.bitmap.pixels.get() + (-cut_bot * glyph.bitmap.w) + (-cut_left);
+ uint32_t* rgba_row = m_canvas.pixels + y0 * m_canvas.w + x0;
+
+ for (int32_t y = y0; y <= y1; y++) {
+ uint8_t* alpha = alpha_row;
+ uint32_t* rgba = rgba_row;
+ for (int32_t x = x0; x <= x1; x++) {
+ if (*alpha == 0) {
+ alpha++;
+ rgba++;
+ continue;
+ }
+
+ float alphaf = *alpha / 255.0f;
+
+ float r1 = color.r * alphaf;
+ float g1 = color.g * alphaf;
+ float b1 = color.b * alphaf;
+
+ uint32_t r2 = uint32_t(r1 * 255.0f) << m_canvas.rshift;
+ uint32_t g2 = uint32_t(g1 * 255.0f) << m_canvas.gshift;
+ uint32_t b2 = uint32_t(b1 * 255.0f) << m_canvas.bshift;
+
+ uint32_t rgba_result = r2 | g2 | b2;
+ *rgba = rgba_result;
+
+ alpha++;
+ rgba++;
+ }
+
+ alpha_row += glyph.bitmap.w;
+ rgba_row += m_canvas.w;
+ }
+}
+
diff --git a/src/renderer/RSoftwareBackend.hpp b/src/renderer/RSoftwareBackend.hpp
index 89d6a52..3e5e17d 100644
--- a/src/renderer/RSoftwareBackend.hpp
+++ b/src/renderer/RSoftwareBackend.hpp
@@ -16,11 +16,19 @@ public:
uint32_t* pixels;
};
+ struct DestRect {
+ int32_t x0;
+ int32_t y0;
+ int32_t x1;
+ int32_t y1;
+ };
+
public:
- RSoftwareBackend(SDL_Window* window, Renderer& renderer);
+ RSoftwareBackend(Renderer& renderer);
void Draw();
+ void Clear(Color color);
private:
@@ -29,10 +37,11 @@ private:
void DrawRectangle(REntity_Rectangle& entity);
void DrawAlphaBitmap(REntity_AlphaBitmap& entity);
+ void DrawText(REntity_Text& entity);
+ void DrawTextGlyph(Glyph& glyph, Color color, int32_t xscreen, int32_t yscreen);
private:
- SDL_Window* m_window{};
Renderer& m_renderer;
uint32_t m_gltexture_id{};
diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp
index 4e449ba..956c488 100644
--- a/src/renderer/Renderer.cpp
+++ b/src/renderer/Renderer.cpp
@@ -13,16 +13,10 @@ Renderer g_renderer;
void
Renderer::Init(SDL_Window* window)
{
+ m_window = window;
m_render_entities.reserve(1024);
m_sort_entries.reserve(1024);
-
- m_backend = std::make_unique<RSoftwareBackend>(window, *this);
-}
-
-void
-Renderer::Draw()
-{
- m_backend->Draw();
+ m_backend = std::make_unique<RSoftwareBackend>(*this);
}
void
@@ -30,12 +24,16 @@ Renderer::Reset()
{
m_render_entities.clear();
m_sort_entries.clear();
- m_render_entities.reserve(1024);
- m_sort_entries.reserve(1024);
SetCameraSize(0.0f, 0.0f);
}
void
+Renderer::Draw()
+{
+ m_backend->Draw();
+}
+
+void
Renderer::SetScreenSize(int32_t w, int32_t h)
{
m_screen_w = w;
@@ -66,7 +64,13 @@ Renderer::WorldYToScreenY(float world_y)
void
Renderer::Clear(Color color)
{
- m_clear_color = color;
+ Rectangle rect = {
+ 0.0f,
+ 0.0f,
+ m_camera_w,
+ m_camera_h
+ };
+ PushRectangle(rect, color, -1.0f);
}
void
@@ -74,37 +78,48 @@ Renderer::PushAlphaBitmap(AlphaBitmap& bitmap, V3F32 pos, Color color)
{
m_render_entities.emplace_back(REntity{.bitmap{
REntityType_AlphaBitmap,
- pos,
bitmap,
+ pos,
color
}});
m_sort_entries.emplace_back(pos.z, m_render_entities.size()-1);
}
void
-Renderer::PushRectangle(Rectangle rect, float z, Color color)
+Renderer::PushRectangle(Rectangle rect, Color color, float z)
{
m_render_entities.emplace_back(REntity{.rect{
REntityType_Rectangle,
rect,
- z,
color
}});
m_sort_entries.emplace_back(z, m_render_entities.size()-1);
}
void
-Renderer::PushCircle(Circle circle, float z, Color color)
+Renderer::PushCircle(Circle circle, Color color, float z)
{
m_render_entities.emplace_back(REntity{.circle{
REntityType_Circle,
circle,
- z,
color
}});
m_sort_entries.emplace_back(z, m_render_entities.size()-1);
}
+void
+Renderer::PushText(std::u32string& text, Font& font, V3F32 pos, Color color)
+{
+ m_render_entities.emplace_back(REntity{.text{
+ REntityType_Text,
+ text,
+ font,
+ pos,
+ color
+ }});
+ m_sort_entries.emplace_back(pos.z, m_render_entities.size()-1);
+}
+
/* temporary helper functions (from old RGroup api) */
diff --git a/src/renderer/Renderer.hpp b/src/renderer/Renderer.hpp
index b825681..515e1da 100644
--- a/src/renderer/Renderer.hpp
+++ b/src/renderer/Renderer.hpp
@@ -22,34 +22,44 @@ enum REntityType : int32_t {
REntityType_Rectangle,
REntityType_AlphaBitmap,
REntityType_Circle,
+ REntityType_Text,
};
+
struct REntity_AlphaBitmap {
REntityType type;
- V3F32 pos;
AlphaBitmap& bitmap;
+ V3F32 pos;
Color color;
};
struct REntity_Rectangle {
REntityType type;
Rectangle rect;
- float z;
Color color;
};
struct REntity_Circle {
REntityType type;
Circle circle;
- float z;
Color color;
};
+struct REntity_Text {
+ REntityType type;
+ std::u32string& text;
+ Font& font;
+ V3F32 pos;
+ Color color;
+};
+
+
union REntity {
REntityType type;
REntity_AlphaBitmap bitmap;
REntity_Rectangle rect;
REntity_Circle circle;
+ REntity_Text text;
};
struct RSortEntry {
@@ -69,9 +79,10 @@ public:
void Reset();
void Clear(Color color);
- void PushRectangle(Rectangle rect, float z, Color color);
void PushAlphaBitmap(AlphaBitmap& bitmap, V3F32 pos, Color color);
- void PushCircle(Circle circle, float z, Color color);
+ void PushRectangle(Rectangle rect, Color color, float z);
+ void PushCircle(Circle circle, Color color, float z);
+ void PushText(std::u32string& text, Font& font, V3F32 pos, Color color);
/* helper functions */
@@ -98,6 +109,8 @@ public:
public:
+ SDL_Window* m_window;
+
int32_t m_screen_w;
int32_t m_screen_h;