Nimbin[12]?SDL & Graphics / sdl_runtime_compiler / src/rendering/wall_surfaces.cpp

sdl_runtime_compiler git · main

SDL3 game for running and compiling code at runtime

sdl3 c++ compiler dlopen cmake · first commit 2026-04-19 · last commit 2026-07-03 (3 months ago) · synced 3 days ago · upstream: git.ide3.de/hsnr/sdl-runtime-compiler

C++ 72.3% C 26.2%
git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gz
src/rendering/wall_surfaces.cpp 4.2 KB · 155 lines raw
#include <SDL3/SDL.h>

#include "entities/camera.hpp"
#include "rendering/gl_renderer.hpp"
#include "utils/globals.hpp"
#include "utils/light.hpp"
#include "utils/math.hpp"
#include "wall/wall.hpp"

namespace
Nimbin
{


namespace {

static void
build_Wall(Wall::Surfaces::Quad& out,
           Wall::Position pos,
           float world_scale,
           SDL_FColor col)
{
    const float ws = world_scale;
    const float inset = 0.01f;

    Vec3 corners[4];
    Vec3 normal;

    switch (pos) {
        case Wall::Position::PosX: {
            float x = ws - inset;
            corners[0] = { x, -ws, -ws };  // bottom-back
            corners[1] = { x, -ws,  ws };  // bottom-front
            corners[2] = { x,  ws,  ws };  // top-front
            corners[3] = { x,  ws, -ws };  // top-back
            normal     = { -1.0, 0.0, 0.0 };
            break;
        }
        case Wall::Position::NegX: {
            float x = -ws + inset;
            corners[0] = { x, -ws,  ws };
            corners[1] = { x, -ws, -ws };
            corners[2] = { x,  ws, -ws };
            corners[3] = { x,  ws,  ws };
            normal     = { 1.0, 0.0, 0.0 };
            break;
        }
        case Wall::Position::PosZ: {
            float z = ws - inset;
            corners[0] = {  ws, -ws, z };
            corners[1] = { -ws, -ws, z };
            corners[2] = { -ws,  ws, z };
            corners[3] = {  ws,  ws, z };
            normal     = { 0.0, 0.0, -1.0 };
            break;
        }
        case Wall::Position::NegZ:
        default: {
            float z = -ws + inset;
            corners[0] = { -ws, -ws, z };
            corners[1] = {  ws, -ws, z };
            corners[2] = {  ws,  ws, z };
            corners[3] = { -ws,  ws, z };
            normal     = { 0.0, 0.0, 1.0 };
            break;
        }
    }

    out.verts.clear();
    out.indices.clear();
    out.color = col;

    auto push = [&](const Vec3& p) {
        out.verts.push_back(static_cast<float>(p.x));
        out.verts.push_back(static_cast<float>(p.y));
        out.verts.push_back(static_cast<float>(p.z));
        out.verts.push_back(static_cast<float>(normal.x));
        out.verts.push_back(static_cast<float>(normal.y));
        out.verts.push_back(static_cast<float>(normal.z));
        out.verts.push_back(static_cast<float>(p.y));
        out.verts.push_back(0.0f);
        out.verts.push_back(0.0f);
    };

    for (const Vec3& c : corners) push(c);

    out.indices = { 0, 1, 2, 0, 2, 3 };
}

} // namespace



namespace Wall
{

void
Surfaces::generate(float world_scale)
{
    _walls.clear();
    _walls.resize(4);

    struct Spec {
        Role       role;
        Position   pos;
        SDL_FColor color;
        bool       is_editor;
    };
    const Spec specs[4] = {
        { Role::Editor,   Position::NegX, Config::Color::editor,   false },
        { Role::Program,  Position::PosX, Config::Color::program,  false },
        { Role::Info,     Position::PosZ, Config::Color::info,     false },
        { Role::Compiler, Position::NegZ, Config::Color::compiler, false },
    };

    for (size_t i = 0; i < 4; i++) {
        _walls[i].role      = specs[i].role;
        _walls[i].is_editor = specs[i].is_editor;
        build_Wall(_walls[i], specs[i].pos, world_scale, specs[i].color);
    }
}


void
Surfaces::draw(GlRenderer& gl, const Camera& cam, const Light& light) const
{
    if (_walls.empty()) return;

    Mat4 view  = buildViewMat4    (cam);
    Mat4 proj  = gl.get_Projection();
    Mat4 model = Mat4::identity   ();
    Mat4 mvp   = Mat4::mul        (proj, Mat4::mul(view, model));

    gl.set_Wireframe      (false);
    gl.set_MVP            (model, mvp);
    gl.set_NormalMat      (model);
    gl.set_Light          (light);
    gl.set_TextLineSpacing(Config::Wall::text_line_spacing);

    for (const Quad& w : _walls) {
        gl.set_Color           (w.color.r, w.color.g, w.color.b);
        gl.enable_WallPaperMode(w.is_editor);
        gl.set_ColorUseVertex  (false);
        gl.draw_MeshColored    (w.verts.data(),
                                static_cast<int>(w.verts.size() / 9),
                                w.indices.data(),
                                static_cast<int>(w.indices.size()));
    }
    gl.enable_WallPaperMode(false);
}


} // Wall

} // namespace Nimbin