Work on passes/pipeline, render targets

This commit is contained in:
2026-01-26 20:45:29 +01:00
parent 6b2d76bd8a
commit bd4b81d434
7 changed files with 764 additions and 160 deletions

146
pass.odin
View File

@@ -2,35 +2,155 @@ package renderer
import "core:fmt"
MAX_DRAW_COMMANDS_PER_PASS :: 1024
MAX_DRAW_COMMANDS_CAPACITY :: 4096
Pass :: struct {
PASS_MAX_INPUT_TEXTURES :: 8
Scene_Pass :: struct {
name: string,
clear_color: RGB_Color,
should_test_depth: bool,
should_clear_depth: bool,
input_textures: [PASS_MAX_INPUT_TEXTURES]^Texture, // TODO: SS - Make this a map?
input_texture_count: u8,
draw_commands: [MAX_DRAW_COMMANDS_PER_PASS]Draw_Command,
draw_command_count: u32,
output_rt: ^Render_Target,
draw_commands: [dynamic]Draw_Command, // Capacity is 'MAX_DRAW_COMMANDS_CAPACITY'.
clear_color: Maybe(RGB_Color),
blend_mode: Blend_Mode,
sort_mode: Sort_Mode,
}
Post_Processing_Pass :: struct {
name: string,
input_texture: ^Texture, // TODO: SS - Make this an array of texture-pointers, or maybe a map.
input_depth_texture: ^Texture,
output_rt: ^Render_Target,
shader_program: Shader_Program,
}
Draw_Command :: struct {
renderer: ^Renderer, // Needed for sorting.
mesh: Mesh,
material: Material,
position: [3]f32,
rotation: [3]f32,
scale: [3]f32,
// TODO: SS - Add rotation.
}
add_command_to_pass :: proc(pass: ^Pass, command: Draw_Command) -> bool {
if pass.draw_command_count >= len(pass.draw_commands) {
return false
Blend_Mode :: enum {
None,
Alpha,
Additive,
Multiply,
}
Blend_Factor :: enum {
Zero,
One,
Src_Color,
One_Minus_Src_Color,
Dst_Color,
One_Minus_Dst_Color,
Src_Alpha,
One_Minus_Src_Alpha,
Dst_Alpha,
One_Minus_Dst_Alpha,
// ..
}
Blend_Factors :: struct {
source, destination: Blend_Factor
}
@(private) BLEND_FACTOR_TABLE :: [Blend_Mode]Blend_Factors {
.None = { .One, .Zero },
.Alpha = { .Src_Alpha, .One_Minus_Src_Alpha },
.Additive = { .Src_Alpha, .One },
.Multiply = { .Dst_Color, .Zero },
}
Sort_Mode :: enum {
None, // Draws the commands in the order they're placed in the 'draw_commmands' array.
Back_To_Front, // Sorts the commands in the 'draw_commmands' array (from back to front) before drawing them.
Front_To_Back, // Sorts the commands in the 'draw_commmands' array (from front to back) before drawing them.
}
create_scene_pass :: proc(
name: string,
input_textures: []^Texture,
output_rt: ^Render_Target,
clear_color: Maybe(RGB_Color),
blend_mode: Blend_Mode,
sort_mode: Sort_Mode,
) -> Scene_Pass
{
// if input_depth_texture == nil {
// if test_depth || clear_depth || write_depth {
// assert(false)
// }
// }
p := Scene_Pass {
name = name,
output_rt = output_rt,
draw_commands = make([dynamic]Draw_Command, 0, MAX_DRAW_COMMANDS_CAPACITY),
clear_color = clear_color,
blend_mode = blend_mode,
sort_mode = sort_mode,
}
for texture, i in input_textures {
if p.input_texture_count >= PASS_MAX_INPUT_TEXTURES {
fmt.printfln("Hit max capacity of textures per pass.")
break
}
p.input_textures[p.input_texture_count] = texture
p.input_texture_count += 1
}
pass.draw_commands[pass.draw_command_count] = command
pass.draw_command_count += 1
return p
}
create_post_processing_pass :: proc(
name: string,
input_texture, input_depth_texture: ^Texture,
output_rt: ^Render_Target,
shader_program: Shader_Program,
) -> Post_Processing_Pass
{
return {
name = name,
input_texture = input_texture,
input_depth_texture = input_depth_texture,
output_rt = output_rt,
shader_program = shader_program,
}
}
delete_pass :: proc {
delete_scene_pass,
}
@(private) delete_scene_pass :: proc(pass: ^Scene_Pass) {
delete(pass.draw_commands)
}
add_command_to_pass :: proc(renderer: ^Renderer, pass: ^Scene_Pass, command: Draw_Command) -> bool {
assert(renderer != nil)
assert(pass != nil)
cmd := command
cmd.renderer = renderer
n, err := append(&pass.draw_commands, cmd)
assert(err == .None)
return true
}