From 9d72ed2d5801b1506158082f08bd0b47e58db17f Mon Sep 17 00:00:00 2001 From: fschildt Date: Mon, 29 Sep 2025 13:20:43 +0200 Subject: renderer: major refactor; vectors: now aggregates --- src/renderer/RSoftwareBackend.cpp | 210 +++++++++++++++++++++++++ src/renderer/RSoftwareBackend.hpp | 41 +++++ src/renderer/RenderGroup.cpp | 106 ------------- src/renderer/RenderGroup.hpp | 84 ---------- src/renderer/Renderer.cpp | 311 +++++++++++++++----------------------- src/renderer/Renderer.hpp | 110 +++++++++++--- 6 files changed, 459 insertions(+), 403 deletions(-) create mode 100644 src/renderer/RSoftwareBackend.cpp create mode 100644 src/renderer/RSoftwareBackend.hpp delete mode 100644 src/renderer/RenderGroup.cpp delete mode 100644 src/renderer/RenderGroup.hpp (limited to 'src/renderer') diff --git a/src/renderer/RSoftwareBackend.cpp b/src/renderer/RSoftwareBackend.cpp new file mode 100644 index 0000000..f0e2e5f --- /dev/null +++ b/src/renderer/RSoftwareBackend.cpp @@ -0,0 +1,210 @@ +#include + +#include +#include + +#include +#include +#include + + +RSoftwareBackend::RSoftwareBackend(SDL_Window* window, Renderer& renderer) + : m_window {window} + , m_renderer {renderer} +{ + m_canvas.rshift = 0; + m_canvas.gshift = 8; + m_canvas.bshift = 16; + m_canvas.ashift = 24; + m_canvas.pixels = nullptr; + + + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + + glGenTextures(1, &m_gltexture_id); + glBindTexture(GL_TEXTURE_2D, m_gltexture_id); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +} + +void +RSoftwareBackend::ResizeCanvas(int32_t w, int32_t h) +{ + size_t realloc_size = (size_t)(w * h) * sizeof(m_canvas.pixels[0]); + void *realloc_data = realloc(m_canvas.pixels, realloc_size); + if (!realloc_data) { + printf("could not resize offscreen buffer\n"); + return; + } + + m_canvas.w = w; + m_canvas.h = h; + m_canvas.pixels = (uint32_t*)realloc_data; +} + +void +RSoftwareBackend::Draw() +{ + ResizeCanvas(m_renderer.m_screen_w, m_renderer.m_screen_h); + 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: { + DrawRectangle(entity.rect); + } break; + + case REntityType_MonoBitmap: { + Color color = {0.0f, 0.0f, 0.0f, 1.0f}; + DrawMonoBitmap(entity.bitmap, color); + } break; + + default:; + } + } + + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_gltexture_id); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_canvas.w, m_canvas.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_canvas.pixels); + + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f); + glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f); + glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, 1.0f); + glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, 0); +} + +void +RSoftwareBackend::SortRenderEntities() +{ + auto& sort_entries = m_renderer.m_sort_entries; + std::sort(sort_entries.begin(), sort_entries.end(), + [](const RSortEntry& e1, const RSortEntry& e2) { + return e1.z < e2.z; + }); +} + +void +RSoftwareBackend::DrawRectangle(REntity_Rectangle& rect) +{ + int32_t xmin = m_renderer.WorldXToScreenX(rect.x0); + int32_t ymin = m_renderer.WorldYToScreenY(rect.y0); + int32_t xmax = m_renderer.WorldXToScreenX(rect.x1); + int32_t ymax = m_renderer.WorldYToScreenY(rect.y1); + + if (xmin < 0) { + xmin = 0; + } + if (ymin < 0) { + ymin = 0; + } + if (xmax >= m_canvas.w) { + xmax = m_canvas.w - 1; + } + if (ymax >= m_canvas.h) { + ymax = m_canvas.h - 1; + } + + uint32_t rshift = m_canvas.rshift; + uint32_t gshift = m_canvas.gshift; + uint32_t bshift = m_canvas.bshift; + for (int32_t y = ymin; y <= ymax; ++y) { + uint32_t *pixel = m_canvas.pixels + y * m_canvas.w + xmin; + for (int32_t x = xmin; x <= xmax; ++x) { + uint32_t r = (uint32_t)(rect.color.r * 255.0f); + uint32_t g = (uint32_t)(rect.color.g * 255.0f); + uint32_t b = (uint32_t)(rect.color.b * 255.0f); + uint32_t val = r << rshift | g << gshift | b << bshift; + *pixel++ = val; + } + } +} + + +void +RSoftwareBackend::DrawMonoBitmap(REntity_MonoBitmap& mono_bitmap, Color color) +{ + int32_t x0 = (int32_t)mono_bitmap.x; + int32_t y0 = (int32_t)mono_bitmap.y; + int32_t x1 = (int32_t)mono_bitmap.x + mono_bitmap.w - 1; + int32_t y1 = (int32_t)mono_bitmap.y + mono_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; + } + + + uint32_t rshift = m_canvas.rshift; + uint32_t gshift = m_canvas.gshift; + uint32_t bshift = m_canvas.bshift; + + uint8_t* grayscale = (uint8_t*)mono_bitmap.data + (-cut_bot * mono_bitmap.w) + (-cut_left); + uint32_t* rgba = m_canvas.pixels + y0 * m_canvas.w + x0; + for (int32_t y = y0; y <= y1; y++) { + uint8_t *grayscale_pixels = grayscale; + uint32_t *rgba_pixels = rgba; + for (int32_t x = x0; x <= x1; x++) { + float alpha = *grayscale_pixels / 255.0f; + + // Todo: we do not want to blend with existing color! + + uint32_t rgba_result = *rgba_pixels; + float r0 = (rgba_result >> rshift) & 0xff; + float g0 = (rgba_result >> gshift) & 0xff; + float b0 = (rgba_result >> bshift) & 0xff; + + float r1 = r0 + (color.r - r0)*alpha; + float g1 = g0 + (color.g - g0)*alpha; + float b1 = b0 + (color.b - b0)*alpha; + + rgba_result = (uint32_t)r1 << rshift | (uint32_t)g1 << gshift | (uint32_t)b1 << bshift; + *rgba_pixels = rgba_result; + + grayscale_pixels++; + rgba_pixels++; + } + + grayscale += mono_bitmap.w; + rgba += m_canvas.w; + } +} + diff --git a/src/renderer/RSoftwareBackend.hpp b/src/renderer/RSoftwareBackend.hpp new file mode 100644 index 0000000..5457c7e --- /dev/null +++ b/src/renderer/RSoftwareBackend.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + + +class RSoftwareBackend { +public: + struct Canvas { + uint32_t rshift; + uint32_t gshift; + uint32_t bshift; + uint32_t ashift; + int32_t w; + int32_t h; + uint32_t *pixels; + }; + + +public: + RSoftwareBackend(SDL_Window* window, Renderer& renderer); + + void Draw(); + + +private: + void ResizeCanvas(int32_t w, int32_t h); + void SortRenderEntities(); + + void DrawRectangle(REntity_Rectangle& rect); + void DrawMonoBitmap(REntity_MonoBitmap& mono_bitmap, Color color); + + +private: + SDL_Window* m_window{}; + Renderer& m_renderer; + + uint32_t m_gltexture_id{}; + Canvas m_canvas; +}; + diff --git a/src/renderer/RenderGroup.cpp b/src/renderer/RenderGroup.cpp deleted file mode 100644 index e393393..0000000 --- a/src/renderer/RenderGroup.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include - -RSortEntry::RSortEntry(float z, size_t entity_index) - : z(z), entity_index(entity_index) { -} - -RenderGroup::RenderGroup() { - m_REntities.reserve(1024); - m_RSortEntries.reserve(1024); -} - -void RenderGroup::Reset() { - m_CameraWidth = 0; - m_CameraHeight = 0; - m_REntities.clear(); - m_RSortEntries.clear(); - m_REntities.reserve(1024); - m_RSortEntries.reserve(1024); -} - -void RenderGroup::SetCameraSize(float width, float height) { - m_CameraWidth = width; - m_CameraHeight = height; -} - -float RenderGroup::GetScale() { - float screen_width = static_cast(m_ScreenWidth); - float screen_height = static_cast(m_ScreenHeight); - float xunits = screen_width / m_CameraWidth; - float yunits = screen_height / m_CameraHeight; - float scale = std::min(xunits, yunits); - return scale; -} - -V2F32 RenderGroup::ViewPosToScreenPos(V2F32 view_pos) { - float scale = GetScale(); - float screen_width = static_cast(m_ScreenWidth); - float screen_height = static_cast(m_ScreenHeight); - float viewport_width = m_CameraWidth * scale; - float viewport_height = m_CameraHeight * scale; - float viewport_x0 = (screen_width - viewport_width) / 2; - float viewport_y0 = (screen_height - viewport_height) / 2; - - V2F32 result; - result.x = viewport_x0 + view_pos.x * scale; - result.y = screen_height - (viewport_y0 + view_pos.y * scale); - - return result; -} - -V2F32 RenderGroup::ViewSizeToScreenSize(V2F32 view_size) { - float scale = GetScale(); - - V2F32 result; - result.x = view_size.x * scale; - result.y = view_size.y * scale; - - return result; -} - -ImVec2 RenderGroup::ViewPosToScreenPosImGui(V2F32 view_pos) { - V2F32 screen_pos = ViewPosToScreenPos(view_pos); - ImVec2 result = {screen_pos.x, screen_pos.y}; - return result; -} - -ImVec2 RenderGroup::ViewSizeToScreenSizeImGui(V2F32 view_size) { - V2F32 screen_size = ViewSizeToScreenSize(view_size); - ImVec2 result = {screen_size.x, screen_size.y}; - return result; -} - -void RenderGroup::Clear(Color color) { - m_ClearColor = color; -} - -void RenderGroup::PushRectangle(RectF32 rect, float z, Color color) { - m_REntities.emplace_back(REntity{.rect{ - REntityType_Rectangle, - rect.x0, rect.y0, - rect.x1, rect.y1, - z, - color} - }); - m_RSortEntries.emplace_back(z, m_REntities.size()-1); -} - -void RenderGroup::PushBitmap(V3F32 pos, int w, int h, void *data) { - m_REntities.emplace_back(REntity{.bitmap{ - REntityType_Bitmap, - pos.x, pos.y, - w, h, - pos.z, - data - }}); - m_RSortEntries.emplace_back(pos.z, m_REntities.size()-1); -} - -void RenderGroup::Sort() { - std::sort(m_RSortEntries.begin(), m_RSortEntries.end(), - [](const RSortEntry& e1, const RSortEntry& e2) { - return e1.z < e2.z; - }); -} - diff --git a/src/renderer/RenderGroup.hpp b/src/renderer/RenderGroup.hpp deleted file mode 100644 index ddaa9ff..0000000 --- a/src/renderer/RenderGroup.hpp +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -enum REntityType : int32_t { - REntityType_Rectangle, - REntityType_Bitmap, -}; - -struct REntity_Rectangle { - REntityType type; - float x0; - float y0; - float x1; - float y1; - float z; - Color color; -}; - -struct REntity_Bitmap { - REntityType type; - float x; - float y; - int32_t w; - int32_t h; - float z; - void *data; -}; - -union REntity { - REntityType type; - REntity_Rectangle rect; - REntity_Bitmap bitmap; -}; - -struct RSortEntry { - RSortEntry(float z, size_t entity_index); - float z; - size_t entity_index; -}; - - -class RenderGroup { -public: - RenderGroup(); - void Clear(Color color); - void Reset(); - - void SetCameraSize(float width, float height); - V2F32 ViewPosToScreenPos(V2F32 view_pos); - V2F32 ViewSizeToScreenSize(V2F32 view_size); - ImVec2 ViewPosToScreenPosImGui(V2F32 view_pos); - ImVec2 ViewSizeToScreenSizeImGui(V2F32 view_size); - float GetScale(); - - -public: - void PushRectangle(RectF32 rect, float z, Color color); - void PushBitmap(V3F32 pos, int w, int h, void *bitmap); - void Sort(); - - -public: - int32_t m_ScreenWidth; - int32_t m_ScreenHeight; - - -private: - friend class Renderer; - - float m_CameraWidth; - float m_CameraHeight; - - - Color m_ClearColor; - - std::vector m_REntities; - std::vector m_RSortEntries; -}; - - diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp index 9217f5c..413b3cb 100644 --- a/src/renderer/Renderer.cpp +++ b/src/renderer/Renderer.cpp @@ -1,233 +1,158 @@ #include +#include + #include +#include -#include -#include +#include -Renderer::Renderer(SDL_Window *window) : m_Window(window), m_Canvas{} -{ -} +Renderer g_renderer; -bool -Renderer::Init() +void +Renderer::Init(SDL_Window* window) { - GLenum err = glewInit(); - if (err) { - printf("glewInit() error\n"); - return false; - } - - int32_t window_width; - int32_t window_height; - if (!SDL_GetWindowSize(m_Window, &window_width, &window_height)) { - printf("Error: SDL_GetWindowSize: %s\n", SDL_GetError()); - return false; - } - - - m_Canvas.rshift = 0; - m_Canvas.gshift = 8; - m_Canvas.bshift = 16; - m_Canvas.ashift = 24; - ResizeCanvas(window_width, window_height); + m_render_entities.reserve(1024); + m_sort_entries.reserve(1024); + m_backend = std::make_unique(window, *this); +} - glEnable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); +void +Renderer::Draw() +{ + m_backend->Draw(); +} - glGenTextures(1, &m_GlTexId); - glBindTexture(GL_TEXTURE_2D, m_GlTexId); +void +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); +} - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +void +Renderer::SetScreenSize(int32_t w, int32_t h) +{ + m_screen_w = w; + m_screen_h = h; +} +void +Renderer::SetCameraSize(float w, float h) +{ + m_camera_w = w; + m_camera_h = h; +} - return true; +int32_t +Renderer::WorldXToScreenX(float world_x) +{ + float screen_x = (world_x / m_camera_w) * (float)m_screen_w; + return (int32_t)screen_x; } +int32_t +Renderer::WorldYToScreenY(float world_y) +{ + float screen_y = (world_y / m_camera_h) * (float)m_screen_h; + return (int32_t)screen_y; +} void -Renderer::ResizeCanvas(int32_t w, int32_t h) +Renderer::Clear(Color color) { - size_t realloc_size = (size_t)(w * h) * sizeof(m_Canvas.pixels[0]); - void *realloc_data = realloc(m_Canvas.pixels, realloc_size); - if (!realloc_data) { - printf("could not resize offscreen buffer\n"); - return; - } - - m_Canvas.w = w; - m_Canvas.h = h; - m_Canvas.pixels = (uint32_t*)realloc_data; + m_clear_color = color; } - void -Renderer::Draw(RenderGroup& rgroup) +Renderer::PushRectangle(RectF32 rect, float z, Color color) { - rgroup.Sort(); - REntity_Rectangle clear_rect = { - REntityType_Rectangle, - 0, 0, - (float)(m_Canvas.w-1), (float)(m_Canvas.h-1), - 0.0f, - rgroup.m_ClearColor - }; - DrawRectangle(rgroup, clear_rect); - - - float z = -1; - for (RSortEntry sort_entry : rgroup.m_RSortEntries) { - if (sort_entry.z >= z) { - z = sort_entry.z; - } - - REntity& entity = rgroup.m_REntities[sort_entry.entity_index]; - switch (entity.type) { - case REntityType_Rectangle: { - DrawRectangle(rgroup, entity.rect); - } break; - - case REntityType_Bitmap: { - Color color = {0.0f, 0.0f, 0.0f, 1.0f}; - DrawMonoBitmap(entity.bitmap, color); - } break; - - default:; - } - } - - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_GlTexId); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_Canvas.w, m_Canvas.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_Canvas.pixels); - - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f); - glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f); - glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, 1.0f); - glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f); - glEnd(); - - glBindTexture(GL_TEXTURE_2D, 0); + m_render_entities.emplace_back(REntity{.rect{ + REntityType_Rectangle, + rect.x0, rect.y0, + rect.x1, rect.y1, + z, + color} + }); + m_sort_entries.emplace_back(z, m_render_entities.size()-1); } - void -Renderer::DrawRectangle(RenderGroup& rgroup, REntity_Rectangle& rect) +Renderer::PushMonoBitmap(V3F32 pos, int w, int h, void *data) { - int32_t xmin = WorldXToScreenX(rgroup, rect.x0); - int32_t ymin = WorldYToScreenY(rgroup, rect.y0); - int32_t xmax = WorldXToScreenX(rgroup, rect.x1); - int32_t ymax = WorldYToScreenY(rgroup, rect.y1); - - if (xmin < 0) { - xmin = 0; - } - if (ymin < 0) { - ymin = 0; - } - if (xmax >= m_Canvas.w) { - xmax = m_Canvas.w - 1; - } - if (ymax >= m_Canvas.h) { - ymax = m_Canvas.h - 1; - } - - uint32_t rshift = m_Canvas.rshift; - uint32_t gshift = m_Canvas.gshift; - uint32_t bshift = m_Canvas.bshift; - for (int32_t y = ymin; y <= ymax; ++y) { - uint32_t *pixel = m_Canvas.pixels + y * m_Canvas.w + xmin; - for (int32_t x = xmin; x <= xmax; ++x) { - uint32_t r = (uint32_t)(rect.color.r * 255.0f); - uint32_t g = (uint32_t)(rect.color.g * 255.0f); - uint32_t b = (uint32_t)(rect.color.b * 255.0f); - uint32_t val = r << rshift | g << gshift | b << bshift; - *pixel++ = val; - } - } + m_render_entities.emplace_back(REntity{.bitmap{ + REntityType_MonoBitmap, + pos.x, pos.y, + w, h, + pos.z, + data + }}); + m_sort_entries.emplace_back(pos.z, m_render_entities.size()-1); } -void -Renderer::DrawMonoBitmap(REntity_Bitmap& bitmap, Color color) + +/* temporary helper functions (from old RGroup api) */ + +float +Renderer::GetScale() { - int32_t x0 = (int32_t)bitmap.x; - int32_t y0 = (int32_t)bitmap.y; - int32_t x1 = (int32_t)bitmap.x + bitmap.w - 1; - int32_t y1 = (int32_t)bitmap.y + 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; - } - - - uint32_t rshift = m_Canvas.rshift; - uint32_t gshift = m_Canvas.gshift; - uint32_t bshift = m_Canvas.bshift; - - uint8_t* grayscale = (uint8_t*)bitmap.data + (-cut_bot * bitmap.w) + (-cut_left); - uint32_t* rgba = m_Canvas.pixels + y0 * m_Canvas.w + x0; - for (int32_t y = y0; y <= y1; y++) { - uint8_t *grayscale_pixels = grayscale; - uint32_t *rgba_pixels = rgba; - for (int32_t x = x0; x <= x1; x++) { - float alpha = *grayscale_pixels / 255.0f; - - // Todo: we do not want to blend with existing color! - - uint32_t rgba_result = *rgba_pixels; - float r0 = (rgba_result >> rshift) & 0xff; - float g0 = (rgba_result >> gshift) & 0xff; - float b0 = (rgba_result >> bshift) & 0xff; - - float r1 = r0 + (color.r - r0)*alpha; - float g1 = g0 + (color.g - g0)*alpha; - float b1 = b0 + (color.b - b0)*alpha; - - rgba_result = (uint32_t)r1 << rshift | (uint32_t)g1 << gshift | (uint32_t)b1 << bshift; - *rgba_pixels = rgba_result; - - grayscale_pixels++; - rgba_pixels++; - } - - grayscale += bitmap.w; - rgba += m_Canvas.w; - } + float screen_width = static_cast(m_screen_w); + float screen_height = static_cast(m_screen_h); + float xunits = screen_width / m_camera_w; + float yunits = screen_height / m_camera_h; + float scale = std::min(xunits, yunits); + return scale; } +V2F32 +Renderer::ViewPosToScreenPos(V2F32 view_pos) +{ + float scale = GetScale(); + float screen_width = static_cast(m_screen_w); + float screen_height = static_cast(m_screen_h); + float viewport_width = m_camera_w * scale; + float viewport_height = m_camera_h * scale; + float viewport_x0 = (screen_width - viewport_width) / 2; + float viewport_y0 = (screen_height - viewport_height) / 2; + + V2F32 result; + result.x = viewport_x0 + view_pos.x * scale; + result.y = screen_height - (viewport_y0 + view_pos.y * scale); + + return result; +} -int32_t -Renderer::WorldXToScreenX(RenderGroup& rgroup, float x) +V2F32 +Renderer::ViewSizeToScreenSize(V2F32 view_size) { - float xscreen = (x / rgroup.m_CameraWidth) * (float)rgroup.m_ScreenWidth; - return (int32_t)xscreen; + float scale = GetScale(); + + V2F32 result; + result.x = view_size.x * scale; + result.y = view_size.y * scale; + + return result; } -int32_t -Renderer::WorldYToScreenY(RenderGroup& rgroup, float y) +ImVec2 +Renderer::ViewPosToScreenPosImGui(V2F32 view_pos) +{ + V2F32 screen_pos = ViewPosToScreenPos(view_pos); + ImVec2 result = {screen_pos.x, screen_pos.y}; + return result; +} + +ImVec2 +Renderer::ViewSizeToScreenSizeImGui(V2F32 view_size) { - float yscreen = (y / rgroup.m_CameraHeight) * (float)rgroup.m_ScreenHeight; - return (int32_t)yscreen; + V2F32 screen_size = ViewSizeToScreenSize(view_size); + ImVec2 result = {screen_size.x, screen_size.y}; + return result; } diff --git a/src/renderer/Renderer.hpp b/src/renderer/Renderer.hpp index 24d4b71..4fdf524 100644 --- a/src/renderer/Renderer.hpp +++ b/src/renderer/Renderer.hpp @@ -1,41 +1,111 @@ #pragma once #include -#include + #include #include +#include + +#include +#include + + +class RSoftwareBackend; +class Renderer; + +extern Renderer g_renderer; + + +enum REntityType : int32_t { + REntityType_Rectangle, + REntityType_MonoBitmap, +}; -struct RCanvas { - uint32_t rshift; - uint32_t gshift; - uint32_t bshift; - uint32_t ashift; +struct REntity_Rectangle { + REntityType type; + float x0; + float y0; + float x1; + float y1; + float z; + Color color; +}; + +struct REntity_MonoBitmap { + REntityType type; + float x; + float y; int32_t w; int32_t h; - uint32_t *pixels; + float z; + void *data; +}; + +union REntity { + REntityType type; + REntity_Rectangle rect; + REntity_MonoBitmap bitmap; +}; + +struct RSortEntry { + float z; + size_t entity_index; }; class Renderer { public: - Renderer(SDL_Window *window); + void Init(SDL_Window* window); + + + /* core functions */ + + void Draw(); + void Reset(); + + void Clear(Color color); + void PushRectangle(RectF32 rect, float z, Color color); + void PushMonoBitmap(V3F32 pos, int w, int h, void* bitmap); + + + /* helper functions */ + + void SetScreenSize(int32_t w, int32_t h); + void SetCameraSize(float w, float h); + + + int32_t WorldXToScreenX(float x); + int32_t WorldYToScreenY(float y); + + int32_t WorldWidthToScreenWidth(float w); + int32_t WorldHeightToScreenHeight(float h); + + + /* temporary helper functions (from old RGroup api) */ + float GetScale(); + V2F32 ViewPosToScreenPos(V2F32 view_pos); + V2F32 ViewSizeToScreenSize(V2F32 view_size); + ImVec2 ViewPosToScreenPosImGui(V2F32 view_pos); + ImVec2 ViewSizeToScreenSizeImGui(V2F32 view_size); + + + + // Todo: make this private +public: + int32_t m_screen_w; + int32_t m_screen_h; - bool Init(); - void ResizeCanvas(int32_t w, int32_t h); - void Draw(RenderGroup &render_group); + float m_camera_w; + float m_camera_h; + Color m_clear_color {}; + std::vector m_render_entities; + std::vector m_sort_entries; -private: - void DrawRectangle(RenderGroup& rgroup, REntity_Rectangle& rect); - void DrawMonoBitmap(REntity_Bitmap& bitmap, Color color); - int32_t WorldXToScreenX(RenderGroup& rgroup, float x); - int32_t WorldYToScreenY(RenderGroup& rgroup, float y); + std::unique_ptr m_backend; -private: - SDL_Window *m_Window; - uint32_t m_GlTexId; - RCanvas m_Canvas; + friend class RSoftwareBackend; }; -- cgit v1.2.3