From c7de871865235953ae38fcc253ffbf297774a083 Mon Sep 17 00:00:00 2001 From: samstalhandske Date: Fri, 14 Nov 2025 14:40:05 +0100 Subject: [PATCH] Started on the render-pipeline/pass architecture. --- pass.odin | 9 ++++++ pipeline.odin | 47 ++++++++++++++++++++++++++++ renderer.odin | 22 ++++++++++--- renderer_backend_opengl_windows.odin | 2 +- 4 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 pass.odin create mode 100644 pipeline.odin diff --git a/pass.odin b/pass.odin new file mode 100644 index 0000000..caa6dfe --- /dev/null +++ b/pass.odin @@ -0,0 +1,9 @@ +package renderer + +RGB_Color :: [3]u8 +RGBA_Color :: [4]u8 + +Pass :: struct { + name: string, + clear_color: RGB_Color, +} \ No newline at end of file diff --git a/pipeline.odin b/pipeline.odin new file mode 100644 index 0000000..8501d62 --- /dev/null +++ b/pipeline.odin @@ -0,0 +1,47 @@ +package renderer + +import "core:mem" +import "core:log" + +MAX_PASSES_IN_PIPELINE :: 8 + +Pipeline :: struct { + passes: [MAX_PASSES_IN_PIPELINE]^Pass, + amount_of_passes: u8, +} + +clear_pipeline :: proc(renderer: ^Renderer) { + assert(renderer != nil) + pipeline := &renderer.pipeline + + pipeline.amount_of_passes = 0; + mem.set(&pipeline.passes[0], 0, MAX_PASSES_IN_PIPELINE * size_of(Pass)) +} + +set_pipeline :: proc(renderer: ^Renderer, passes: []^Pass) { + clear_pipeline(renderer) + for p in passes { + if !add_pass_to_pipeline(renderer, p) { + return + } + } +} + +@(private="file") add_pass_to_pipeline :: proc(renderer: ^Renderer, pass: ^Pass) -> bool { + assert(renderer != nil) + assert(pass != nil) + + pipeline := &renderer.pipeline + + if pipeline.amount_of_passes == MAX_PASSES_IN_PIPELINE { + log.warnf("Failed to add pass '%v' to renderer's pipeline; hit max capacity (%v).", pass.name, MAX_PASSES_IN_PIPELINE) + return false + } + + pipeline.passes[pipeline.amount_of_passes] = pass + pipeline.amount_of_passes += 1 + + log.infof("Successfully added pass '%v' to pipeline.", pass.name) + + return true +} \ No newline at end of file diff --git a/renderer.odin b/renderer.odin index 08a016f..0abb012 100644 --- a/renderer.odin +++ b/renderer.odin @@ -1,6 +1,7 @@ package renderer import "core:fmt" +import "core:log" RENDER_BACKEND_OPENGL :: #config(RENDER_BACKEND_OPENGL, false) RENDER_BACKEND_VULKAN :: #config(RENDER_BACKEND_VULKAN, false) @@ -13,6 +14,8 @@ Renderer :: struct { viewport: Viewport, surface_ptr: rawptr, backend: rawptr, + + pipeline: Pipeline, } Viewport :: struct { @@ -26,7 +29,6 @@ Renderer_API :: enum { Metal, } - create :: proc(surface_ptr: rawptr) -> (^Renderer, bool) { renderer := new(Renderer) renderer.surface_ptr = surface_ptr @@ -64,17 +66,29 @@ set_viewport :: proc(renderer: ^Renderer, x, y, width, height: u16) { } } -set_clear_color :: proc(renderer: ^Renderer, color: [3]u8) { +@(private="file") set_clear_color :: proc(renderer: ^Renderer, color: RGB_Color) { when RENDER_BACKEND_OPENGL { opengl_set_clear_color(renderer, color) } } render_frame :: proc(renderer: ^Renderer) { - + pipeline := &renderer.pipeline + for i in 0 ..< pipeline.amount_of_passes { + pass := pipeline.passes[i] + + // TODO: SS - "Activate" the pass. + set_clear_color(renderer, pass.clear_color) + + // TODO: SS - Loop over the pass' render-commands. + + // TODO: SS - "Deactivate" the pass. + } + + swap_buffers(renderer) } -swap_buffers :: proc(renderer: ^Renderer) { +@(private="file") swap_buffers :: proc(renderer: ^Renderer) { when RENDER_BACKEND_OPENGL { opengl_swap_buffers(renderer) } diff --git a/renderer_backend_opengl_windows.odin b/renderer_backend_opengl_windows.odin index 3ec2e15..332c21c 100644 --- a/renderer_backend_opengl_windows.odin +++ b/renderer_backend_opengl_windows.odin @@ -69,7 +69,7 @@ when RENDER_BACKEND_OPENGL { ) } - opengl_set_clear_color :: proc(renderer: ^Renderer, color: [3]u8) { + opengl_set_clear_color :: proc(renderer: ^Renderer, color: RGB_Color) { gl.ClearColor( f32(color.r) / f32(max(u8)), f32(color.g) / f32(max(u8)),