diff options
| author | fschildt <florian.schildt@protonmail.com> | 2025-09-29 13:20:43 +0200 | 
|---|---|---|
| committer | fschildt <florian.schildt@protonmail.com> | 2025-09-29 13:20:43 +0200 | 
| commit | 9d72ed2d5801b1506158082f08bd0b47e58db17f (patch) | |
| tree | 1fe30ab6dae55db5a3faaac6b8d54f67a31255d3 /src/renderer/Renderer.cpp | |
| parent | d793b79dea7d5e19982128528276cf05d6c23b5d (diff) | |
renderer: major refactor; vectors: now aggregates
Diffstat (limited to 'src/renderer/Renderer.cpp')
| -rw-r--r-- | src/renderer/Renderer.cpp | 311 | 
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;  }  | 
