diff options
| author | fschildt <florian.schildt@protonmail.com> | 2025-10-16 15:33:06 +0200 |
|---|---|---|
| committer | fschildt <florian.schildt@protonmail.com> | 2025-10-16 15:33:06 +0200 |
| commit | a873df7a66dc1831cee4eae2d998abed88246268 (patch) | |
| tree | c19cd079ce106e1431d64c34babf4ef59cf71723 /src/renderer | |
| parent | 9f2845b12135c32dde91e58afc1193d54333ec9f (diff) | |
renderer: introduce text rendering
Diffstat (limited to 'src/renderer')
| -rw-r--r-- | src/renderer/RSoftwareBackend.cpp | 123 | ||||
| -rw-r--r-- | src/renderer/RSoftwareBackend.hpp | 13 | ||||
| -rw-r--r-- | src/renderer/Renderer.cpp | 47 | ||||
| -rw-r--r-- | src/renderer/Renderer.hpp | 23 |
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; |
