~vladh/peony

16fbc3418a672a6e1d9a45bd018a52d0b78b165b — Vlad-Stefan Harbuz 1 year, 7 months ago 16350c8
change settings from macros to struct
6 files changed, 254 insertions(+), 240 deletions(-)

M src/constants.hpp
M src/engine.cpp
M src/internals.cpp
M src/mats.cpp
M src/memory.cpp
M src/renderer.cpp
M src/constants.hpp => src/constants.hpp +29 -20
@@ 33,31 33,40 @@ constexpr f64 PI = 3.14159265358979323846;
#error "Unknown platform"
#endif

// General options
#define USE_PRINT_FPS false
#define USE_TIMERS true
#define USE_MEMORY_DEBUG_LOGS false
#define USE_MEMORYPOOL_ITEM_DEBUG false

// Graphics options
#define TARGET_MONITOR 0
#define USE_FULLSCREEN true
#define USE_WINDOWED_FULLSCREEN true
enum class GraphicsQuality { low, high };

#define USE_ANIMATION_DEBUG false
#define USE_SHADER_DEBUG false
#define USE_OPENGL_DEBUG false
struct Settings {
    GraphicsQuality graphics_quality;
    bool opengl_debug_on;
    bool vsync_on;
    bool shader_debug_on;
    bool shadows_on;
    bool bloom_on;
    bool fog_on;
    bool windowed_fullscreen_on;
    bool fullscreen_on;
    u32 target_monitor;
    bool print_fps_on;
    bool memory_debug_logs_on;
};

#define USE_SHADOW_RENDERING true
#define USE_BLOOM true
#define USE_FOG false
#define USE_VSYNC false

#if defined(PLATFORM_WINDOWS)
  #define GRAPHICS_HIGH
#else
  #define GRAPHICS_LOW
#endif
constexpr Settings SETTINGS = {
    .graphics_quality = GraphicsQuality::high,
    .opengl_debug_on = false,
    .vsync_on = false,
    .shader_debug_on = false,
    .shadows_on = true,
    .bloom_on = true,
    .fog_on = false,
    .windowed_fullscreen_on = true,
    .fullscreen_on = true,
    .target_monitor = 0,
    .print_fps_on = false,
    .memory_debug_logs_on = false,
};

// Constants
constexpr char WINDOW_TITLE[] = "peony";

M src/engine.cpp => src/engine.cpp +3 -3
@@ 95,9 95,9 @@ engine::run_main_loop(GLFWwindow *window)
                    engine::state->timing_info.time_frame_should_end);
            }

            #if USE_PRINT_FPS
            logs::info("%u fps", engine::state->perf_counters.last_fps);
            #endif
            if (SETTINGS.print_fps_on) {
                logs::info("%u fps", engine::state->perf_counters.last_fps);
            }
        }



M src/internals.cpp => src/internals.cpp +93 -93
@@ 43,41 43,41 @@ internals::create_internal_materials()
            material, *builtin_textures->shadowmaps_2d_texture, "shadowmaps_2d");
    }

#if USE_BLOOM
    // preblur
    {
        mats::Material *material = mats::init_material(mats::push_material(), "preblur");
        shaders::init_shader_asset(&material->shader_asset,
            &temp_memory_pool,
            "blur", shaders::Type::standard,
            "screenquad.vert", "blur.frag", "");
        mats::add_texture_to_material(
            material, *builtin_textures->l_bright_color_texture, "source_texture");
    }

    // blur1
    {
        mats::Material *material = mats::init_material(mats::push_material(), "blur1");
        shaders::init_shader_asset(&material->shader_asset,
            &temp_memory_pool,
            "blur", shaders::Type::standard,
            "screenquad.vert", "blur.frag", "");
        mats::add_texture_to_material(
            material, *builtin_textures->blur2_texture, "source_texture");
    if (SETTINGS.bloom_on) {
        // preblur
        {
            mats::Material *material = mats::init_material(mats::push_material(), "preblur");
            shaders::init_shader_asset(&material->shader_asset,
                &temp_memory_pool,
                "blur", shaders::Type::standard,
                "screenquad.vert", "blur.frag", "");
            mats::add_texture_to_material(
                material, *builtin_textures->l_bright_color_texture, "source_texture");
        }

        // blur1
        {
            mats::Material *material = mats::init_material(mats::push_material(), "blur1");
            shaders::init_shader_asset(&material->shader_asset,
                &temp_memory_pool,
                "blur", shaders::Type::standard,
                "screenquad.vert", "blur.frag", "");
            mats::add_texture_to_material(
                material, *builtin_textures->blur2_texture, "source_texture");
        }

        // blur2
        {
            mats::Material *material = mats::init_material(mats::push_material(), "blur2");
            shaders::init_shader_asset(&material->shader_asset,
                &temp_memory_pool,
                "blur", shaders::Type::standard,
                "screenquad.vert", "blur.frag", "");
            mats::add_texture_to_material(
                material, *builtin_textures->blur1_texture, "source_texture");
        }
    }

    // blur2
    {
        mats::Material *material = mats::init_material(mats::push_material(), "blur2");
        shaders::init_shader_asset(&material->shader_asset,
            &temp_memory_pool,
            "blur", shaders::Type::standard,
            "screenquad.vert", "blur.frag", "");
        mats::add_texture_to_material(
            material, *builtin_textures->blur1_texture, "source_texture");
    }
#endif

    // postprocessing
    {
        mats::Material *material = mats::init_material(mats::push_material(), "postprocessing");


@@ 88,15 88,15 @@ internals::create_internal_materials()
        mats::add_texture_to_material(
            material, *builtin_textures->l_color_texture, "l_color_texture");

#if USE_BLOOM
        mats::add_texture_to_material(
            material, *builtin_textures->blur2_texture, "bloom_texture");
#endif
        if (SETTINGS.bloom_on) {
            mats::add_texture_to_material(
                material, *builtin_textures->blur2_texture, "bloom_texture");
        }

#if USE_FOG
        mats::add_texture_to_material(
            material, *builtin_textures->l_depth_texture, "l_depth_texture");
#endif
        if (SETTINGS.fog_on) {
            mats::add_texture_to_material(
                material, *builtin_textures->l_depth_texture, "l_depth_texture");
        }
    }

    // renderdebug


@@ 121,17 121,17 @@ internals::create_internal_materials()
        mats::add_texture_to_material(
            material, *builtin_textures->l_bright_color_texture, "l_bright_color_texture");

#if USE_FOG
        mats::add_texture_to_material(
            material, *builtin_textures->l_depth_texture, "l_depth_texture");
#endif
        if (SETTINGS.fog_on) {
            mats::add_texture_to_material(
                material, *builtin_textures->l_depth_texture, "l_depth_texture");
        }

#if USE_BLOOM
        mats::add_texture_to_material(
            material, *builtin_textures->blur1_texture, "blur1_texture");
        mats::add_texture_to_material(
            material, *builtin_textures->blur2_texture, "blur2_texture");
#endif
        if (SETTINGS.bloom_on) {
            mats::add_texture_to_material(
                material, *builtin_textures->blur1_texture, "blur1_texture");
            mats::add_texture_to_material(
                material, *builtin_textures->blur2_texture, "blur2_texture");
        }

        mats::add_texture_to_material(
            material, *builtin_textures->shadowmaps_3d_texture, "shadowmaps_3d");


@@ 179,49 179,49 @@ internals::create_internal_entities()
        models::add_material_to_model_loader(model_loader, "lighting");
    }

#if USE_BLOOM
    // Preblur screenquad
    {
        entities::Entity *entity = entities::add_entity_to_set("screenquad_preblur");
        models::ModelLoader *model_loader = engine::push_model_loader();
        models::EntityLoader *entity_loader = engine::get_entity_loader(entity->handle);
        models::init_model_loader(model_loader, "builtin:screenquad_preblur");
        models::init_entity_loader(entity_loader,
            "screenquad_preblur",
            "builtin:screenquad_preblur",
            drawable::Pass::preblur,
            entity->handle);
        models::add_material_to_model_loader(model_loader, "preblur");
    }

    // Blur 1 screenquad
    {
        entities::Entity *entity = entities::add_entity_to_set("screenquad_blur1");
        models::ModelLoader *model_loader = engine::push_model_loader();
        models::EntityLoader *entity_loader = engine::get_entity_loader(entity->handle);
        models::init_model_loader(model_loader, "builtin:screenquad_blur1");
        models::init_entity_loader(entity_loader,
            "screenquad_blur1",
            "builtin:screenquad_blur1",
            drawable::Pass::blur1,
            entity->handle);
        models::add_material_to_model_loader(model_loader, "blur1");
    }

    // Blur 2 screenquad
    {
        entities::Entity *entity = entities::add_entity_to_set("screenquad_blur2");
        models::ModelLoader *model_loader = engine::push_model_loader();
        models::EntityLoader *entity_loader = engine::get_entity_loader(entity->handle);
        models::init_model_loader(model_loader, "builtin:screenquad_blur2");
        models::init_entity_loader(entity_loader,
            "screenquad_blur2",
            "builtin:screenquad_blur2",
            drawable::Pass::blur2,
            entity->handle);
        models::add_material_to_model_loader(model_loader, "blur2");
    if (SETTINGS.bloom_on) {
        // Preblur screenquad
        {
            entities::Entity *entity = entities::add_entity_to_set("screenquad_preblur");
            models::ModelLoader *model_loader = engine::push_model_loader();
            models::EntityLoader *entity_loader = engine::get_entity_loader(entity->handle);
            models::init_model_loader(model_loader, "builtin:screenquad_preblur");
            models::init_entity_loader(entity_loader,
                "screenquad_preblur",
                "builtin:screenquad_preblur",
                drawable::Pass::preblur,
                entity->handle);
            models::add_material_to_model_loader(model_loader, "preblur");
        }

        // Blur 1 screenquad
        {
            entities::Entity *entity = entities::add_entity_to_set("screenquad_blur1");
            models::ModelLoader *model_loader = engine::push_model_loader();
            models::EntityLoader *entity_loader = engine::get_entity_loader(entity->handle);
            models::init_model_loader(model_loader, "builtin:screenquad_blur1");
            models::init_entity_loader(entity_loader,
                "screenquad_blur1",
                "builtin:screenquad_blur1",
                drawable::Pass::blur1,
                entity->handle);
            models::add_material_to_model_loader(model_loader, "blur1");
        }

        // Blur 2 screenquad
        {
            entities::Entity *entity = entities::add_entity_to_set("screenquad_blur2");
            models::ModelLoader *model_loader = engine::push_model_loader();
            models::EntityLoader *entity_loader = engine::get_entity_loader(entity->handle);
            models::init_model_loader(model_loader, "builtin:screenquad_blur2");
            models::init_entity_loader(entity_loader,
                "screenquad_blur2",
                "builtin:screenquad_blur2",
                drawable::Pass::blur2,
                entity->handle);
            models::add_material_to_model_loader(model_loader, "blur2");
        }
    }
#endif

    // Postprocessing screenquad
    {

M src/mats.cpp => src/mats.cpp +4 -4
@@ 358,10 358,10 @@ mats::bind_texture_uniforms(Material *material)
        for (u32 idx = 0; idx < material->n_textures; idx++) {
            Texture *texture = &material->textures[idx];
            const char *uniform_name = material->texture_uniform_names[idx];
#if USE_SHADER_DEBUG
            logs::info("Setting uniforms: (uniform_name %s) (texture->texture_name %d)",
                uniform_name, texture->texture_name);
#endif
            if (SETTINGS.shader_debug_on) {
                logs::info("Setting uniforms: (uniform_name %s) (texture->texture_name %d)",
                    uniform_name, texture->texture_name);
            }
            shaders::set_int(shader_asset, uniform_name,
                shaders::add_texture_unit(shader_asset, texture->texture_name, texture->target)
            );

M src/memory.cpp => src/memory.cpp +17 -17
@@ 20,10 20,10 @@ memory::push(

    // If we haven't allocated anything in the pool, let's allocate something now.
    if (pool->memory == nullptr) {
#if USE_MEMORY_DEBUG_LOGS
        logs::info("Allocating memory pool: %.2fMB (%dB)",
            util::b_to_mb((f64)pool->size), pool->size);
#endif
        if (SETTINGS.memory_debug_logs_on) {
            logs::info("Allocating memory pool: %.2fMB (%dB)",
                util::b_to_mb((f64)pool->size), pool->size);
        }

        pool->memory = (u8*)calloc(1, pool->size);
        if (!pool->memory) {


@@ 45,13 45,13 @@ memory::push(
    pool->used += item_size;
    pool->n_items++;

#if USE_MEMORY_DEBUG_LOGS
    logs::info("Pusing to memory pool: %.2fMB (%dB) for %s, now at %.2fMB (%dB)",
        util::b_to_mb((f64)item_size),
        item_size, item_debug_name,
        util::b_to_mb((f64)pool->used),
        pool->used);
#endif
    if (SETTINGS.memory_debug_logs_on) {
        logs::info("Pusing to memory pool: %.2fMB (%dB) for %s, now at %.2fMB (%dB)",
            util::b_to_mb((f64)item_size),
            item_size, item_debug_name,
            util::b_to_mb((f64)pool->used),
            pool->used);
    }

    return new_memory;
}


@@ 82,9 82,9 @@ memory::print_memory_pool(Pool *pool)
void
memory::destroy_memory_pool(Pool *memory_pool)
{
#if USE_MEMORY_DEBUG_LOGS
    logs::info("destroy_memory_pool");
#endif
    if (SETTINGS.memory_debug_logs_on) {
        logs::info("destroy_memory_pool");
    }
    reset_memory_pool(memory_pool);
    free(memory_pool->memory);
}


@@ 93,9 93,9 @@ memory::destroy_memory_pool(Pool *memory_pool)
void
memory::reset_memory_pool(Pool *pool)
{
    #if USE_MEMORY_DEBUG_LOGS
    logs::info("Resetting memory pool");
    #endif
    if (SETTINGS.memory_debug_logs_on) {
        logs::info("Resetting memory pool");
    }
    pool->used = 0;
    pool->n_items = 0;
}

M src/renderer.cpp => src/renderer.cpp +108 -103
@@ 32,10 32,10 @@ renderer::init_window(WindowSize *window_size)
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

#if USE_OPENGL_DEBUG
    logs::info("Using OpenGL debug context");
    glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
#endif
    if (SETTINGS.opengl_debug_on) {
        logs::info("Using OpenGL debug context");
        glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
    }

    // Remove window decorations (border etc.)
    glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);


@@ 46,37 46,43 @@ renderer::init_window(WindowSize *window_size)
    // Create the window. Right now we're working with screencoord sizes,
    // not pixels!

#if USE_FULLSCREEN
    i32 n_monitors;
    GLFWmonitor **monitors = glfwGetMonitors(&n_monitors);
    GLFWmonitor *target_monitor = monitors[TARGET_MONITOR];
    const GLFWvidmode *video_mode = glfwGetVideoMode(target_monitor);
    glfwWindowHint(GLFW_RED_BITS, video_mode->redBits);
    glfwWindowHint(GLFW_GREEN_BITS, video_mode->greenBits);
    glfwWindowHint(GLFW_BLUE_BITS, video_mode->blueBits);
    glfwWindowHint(GLFW_REFRESH_RATE, video_mode->refreshRate);

    window_size->screencoord_width = video_mode->width;
    window_size->screencoord_height = video_mode->height;

    GLFWwindow *window = glfwCreateWindow(
        window_size->screencoord_width, window_size->screencoord_height,
        WINDOW_TITLE,
#if USE_WINDOWED_FULLSCREEN
        nullptr, nullptr
#else
        target_monitor, nullptr
#endif
    );
#else
    window_size->screencoord_width = 1920;
    window_size->screencoord_height = 1080;
    GLFWwindow *window;

    if (SETTINGS.fullscreen_on) {
        i32 n_monitors;
        GLFWmonitor **monitors = glfwGetMonitors(&n_monitors);
        GLFWmonitor *target_monitor = monitors[SETTINGS.target_monitor];
        const GLFWvidmode *video_mode = glfwGetVideoMode(target_monitor);
        glfwWindowHint(GLFW_RED_BITS, video_mode->redBits);
        glfwWindowHint(GLFW_GREEN_BITS, video_mode->greenBits);
        glfwWindowHint(GLFW_BLUE_BITS, video_mode->blueBits);
        glfwWindowHint(GLFW_REFRESH_RATE, video_mode->refreshRate);

        window_size->screencoord_width = video_mode->width;
        window_size->screencoord_height = video_mode->height;

        if (SETTINGS.windowed_fullscreen_on) {
            window = glfwCreateWindow(
                window_size->screencoord_width, window_size->screencoord_height,
                WINDOW_TITLE,
                nullptr, nullptr);
        } else {
            window = glfwCreateWindow(
                window_size->screencoord_width, window_size->screencoord_height,
                WINDOW_TITLE,
                target_monitor, nullptr);
        }
    } else {
        window_size->screencoord_width = 1920;
        window_size->screencoord_height = 1080;

    GLFWwindow *window = glfwCreateWindow(
        window_size->screencoord_width, window_size->screencoord_height, WINDOW_TITLE, nullptr, nullptr);
        window = glfwCreateWindow(
            window_size->screencoord_width, window_size->screencoord_height,
            WINDOW_TITLE,
            nullptr, nullptr);

    glfwSetWindowPos(window, 200, 200);
#endif
        glfwSetWindowPos(window, 200, 200);
    }

    if (!window) {
        logs::fatal("Failed to create GLFW window");


@@ 84,9 90,10 @@ renderer::init_window(WindowSize *window_size)
    }

    glfwMakeContextCurrent(window);
#if !USE_VSYNC
    glfwSwapInterval(0);
#endif

    if (!SETTINGS.vsync_on) {
        glfwSwapInterval(0);
    }

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        logs::fatal("Failed to initialize GLAD");


@@ 107,26 114,26 @@ renderer::init_window(WindowSize *window_size)
    // TODO: Remove GL_EXT_debug_label from GLAD
    // TODO: Remove GL_ARB_texture_storage_multisample from GLAD

#if USE_OPENGL_DEBUG
    if (GLAD_GL_AMD_debug_output || GLAD_GL_ARB_debug_output || GLAD_GL_KHR_debug) {
        GLint flags;
        glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
    if (SETTINGS.opengl_debug_on) {
        if (GLAD_GL_AMD_debug_output || GLAD_GL_ARB_debug_output || GLAD_GL_KHR_debug) {
            GLint flags;
            glGetIntegerv(GL_CONTEXT_FLAGS, &flags);

        if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) {
            glEnable(GL_DEBUG_OUTPUT);
            glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
            glDebugMessageCallback(util::debug_message_callback, nullptr);
            glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
            if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) {
                glEnable(GL_DEBUG_OUTPUT);
                glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
                glDebugMessageCallback(util::debug_message_callback, nullptr);
                glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
            } else {
                logs::fatal("Tried to initialise OpenGL debug output but couldn't");
            }
        } else {
            logs::fatal("Tried to initialise OpenGL debug output but couldn't");
            logs::warning(
                "Tried to initialise OpenGL debug output but none of "
                "[GL_AMD_debug_output, GL_ARB_debug_output, GL_KHR_debug] "
                "are supported on this system. Skipping.");
        }
    } else {
        logs::warning(
            "Tried to initialise OpenGL debug output but none of "
            "[GL_AMD_debug_output, GL_ARB_debug_output, GL_KHR_debug] "
            "are supported on this system. Skipping.");
    }
#endif

    // Enable multisampling
    glEnable(GL_MULTISAMPLE);


@@ 250,9 257,9 @@ renderer::render(GLFWwindow *window)
    // vsync, but actually a graphics driver has forced it off, in which case we won't be
    // using glFinish(), but we should be...probably not going to be a real problem,
    // though.
#if !USE_VSYNC
    glFinish();
#endif
    if (!SETTINGS.vsync_on) {
        glFinish();
    }

    WindowSize *window_size = core::get_window_size();



@@ 266,17 273,16 @@ renderer::render(GLFWwindow *window)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glBindFramebuffer(GL_FRAMEBUFFER, renderer::state->builtin_textures.l_buffer);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#if USE_BLOOM
        glBindFramebuffer(GL_FRAMEBUFFER, renderer::state->builtin_textures.blur1_buffer);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glBindFramebuffer(GL_FRAMEBUFFER, renderer::state->builtin_textures.blur2_buffer);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#endif
        if (SETTINGS.bloom_on) {
            glBindFramebuffer(GL_FRAMEBUFFER, renderer::state->builtin_textures.blur1_buffer);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glBindFramebuffer(GL_FRAMEBUFFER, renderer::state->builtin_textures.blur2_buffer);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        }
    }

    // Render shadow map
#if USE_SHADOW_RENDERING
    {
    if (SETTINGS.shadows_on) {
        // Point lights
        {
            f32 ratio = (f32)renderer::state->builtin_textures.shadowmap_3d_width /


@@ 381,7 387,6 @@ renderer::render(GLFWwindow *window)
            }
        }
    }
#endif

    glViewport(0, 0, window_size->width, window_size->height);



@@ 456,9 461,8 @@ renderer::render(GLFWwindow *window)

    glDisable(GL_DEPTH_TEST);

#if USE_BLOOM
    // Blur pass
    {
    if (SETTINGS.bloom_on) {
        glBindFramebuffer(GL_FRAMEBUFFER, renderer::state->builtin_textures.blur1_buffer);
        copy_scene_data_to_ubo(0, 0, true);
        render_scene(drawable::Pass::preblur, drawable::Mode::regular);


@@ 477,7 481,6 @@ renderer::render(GLFWwindow *window)
            render_scene(drawable::Pass::blur2, drawable::Mode::regular);
        }
    }
#endif

    glBindFramebuffer(GL_FRAMEBUFFER, 0);



@@ 522,21 525,25 @@ renderer::init(
) {
    renderer::state = renderer_state;
    BuiltinTextures *builtin_textures = &renderer::state->builtin_textures;
    *builtin_textures = {
#if defined(GRAPHICS_LOW)
        .shadowmap_3d_width = 500,
        .shadowmap_3d_height = 500,
        .shadowmap_2d_width = 800,
        .shadowmap_2d_height = 600,
#elif defined(GRAPHICS_HIGH)
        .shadowmap_3d_width = min((u32)width, (u32)2000),
        .shadowmap_3d_height = min((u32)width, (u32)2000),
        .shadowmap_2d_width = 2560 * 2,
        .shadowmap_2d_height = 1440 * 2,
#endif
        .shadowmap_near_clip_dist = 0.05f,
        .shadowmap_far_clip_dist = 200.0f,
    };
    if (SETTINGS.graphics_quality == GraphicsQuality::high) {
        *builtin_textures = {
            .shadowmap_3d_width = min((u32)width, (u32)2000),
            .shadowmap_3d_height = min((u32)width, (u32)2000),
            .shadowmap_2d_width = 2560 * 2,
            .shadowmap_2d_height = 1440 * 2,
            .shadowmap_near_clip_dist = 0.05f,
            .shadowmap_far_clip_dist = 200.0f,
        };
    } else if (SETTINGS.graphics_quality == GraphicsQuality::low) {
        *builtin_textures = {
            .shadowmap_3d_width = 500,
            .shadowmap_3d_height = 500,
            .shadowmap_2d_width = 800,
            .shadowmap_2d_height = 600,
            .shadowmap_near_clip_dist = 0.05f,
            .shadowmap_far_clip_dist = 200.0f,
        };
    }
    init_g_buffer(memory_pool,
        &builtin_textures->g_buffer,
        &builtin_textures->g_position_texture,


@@ 850,18 857,19 @@ renderer::init_l_buffer(
        glDrawBuffers(2, attachments);
    }

#if USE_FOG
    // l_depth_texture
    // NOTE: Either this or the depth buffer should be enabled, not both
    // NOTE: This does not work on macOS. The most likely reason is that in the render()
    // function, we copy the depth framebuffer from the g_buffer to the "depth
    // framebuffer" of the l_buffer (this one). Of course, the l_buffer does not have a
    // depth framebuffer, but it has a depth texture. It looks like some machines are
    // capable of doing the right thing, but we can't rely on being able to do this. The
    // solution would probably be to use a depth texture for the g_buffer as well. That
    // way, we know we can copy the depth from one to the other without issues.  For the
    // moment, we're not using fog, so this is just commented out.
    {
    if (SETTINGS.fog_on) {
        // l_depth_texture
        // NOTE: Either this or the depth buffer should be enabled, not both
        // NOTE: This does not work on macOS. The most likely reason is that in
        // the render() function, we copy the depth framebuffer from the
        // g_buffer to the "depth framebuffer" of the l_buffer (this one). Of
        // course, the l_buffer does not have a depth framebuffer, but it has a
        // depth texture. It looks like some machines are capable of doing the
        // right thing, but we can't rely on being able to do this. The solution
        // would probably be to use a depth texture for the g_buffer as well.
        // That way, we know we can copy the depth from one to the other without
        // issues. For the moment, we're not using fog, so this is just
        // commented out.
        u32 l_depth_texture_name;
        glGenTextures(1, &l_depth_texture_name);



@@ 881,11 889,9 @@ renderer::init_l_buffer(
            0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
            (*l_depth_texture)->texture_name, 0);
    }
#else
    // Depth buffer
    // NOTE: Either this or the l_depth_texure should be enabled, not both
    {
    } else {
        // Depth buffer
        // NOTE: Either this or the l_depth_texure should be enabled, not both
        u32 rbo_depth;
        glGenRenderbuffers(1, &rbo_depth);
        glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);


@@ 893,7 899,6 @@ renderer::init_l_buffer(
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
            rbo_depth);
    }
#endif

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        logs::fatal("Framebuffer not complete!");


@@ 911,9 916,9 @@ renderer::init_blur_buffers(
    u32 width,
    u32 height
) {
#if !USE_BLOOM
    return;
#endif
    if (!SETTINGS.bloom_on) {
        return;
    }
    glGenFramebuffers(1, blur1_buffer);
    glBindFramebuffer(GL_FRAMEBUFFER, *blur1_buffer);
    u32 blur1_texture_name;