aboutsummaryrefslogtreecommitdiff
path: root/src/renderer/Renderer.cpp
diff options
context:
space:
mode:
authorfschildt <florian.schildt@protonmail.com>2025-09-29 13:20:43 +0200
committerfschildt <florian.schildt@protonmail.com>2025-09-29 13:20:43 +0200
commit9d72ed2d5801b1506158082f08bd0b47e58db17f (patch)
tree1fe30ab6dae55db5a3faaac6b8d54f67a31255d3 /src/renderer/Renderer.cpp
parentd793b79dea7d5e19982128528276cf05d6c23b5d (diff)
renderer: major refactor; vectors: now aggregates
Diffstat (limited to 'src/renderer/Renderer.cpp')
-rw-r--r--src/renderer/Renderer.cpp311
1 files changed, 118 insertions, 193 deletions
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 <renderer/Renderer.hpp>
+#include <renderer/RSoftwareBackend.hpp>
+
#include <GL/glew.h>
+#include <imgui.h>
-#include <cstdio>
-#include <cstdlib>
+#include <memory>
-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<RSoftwareBackend>(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<float>(m_screen_w);
+ float screen_height = static_cast<float>(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<float>(m_screen_w);
+ float screen_height = static_cast<float>(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;
}