Restructured passes
This commit is contained in:
138
pass.odin
138
pass.odin
@@ -3,32 +3,36 @@ package renderer
|
||||
import "core:fmt"
|
||||
|
||||
MAX_DRAW_COMMANDS_CAPACITY :: 4096
|
||||
MAX_POST_PROCESS_NODES_PER_PASS :: 8
|
||||
|
||||
PASS_MAX_INPUT_TEXTURES :: 8
|
||||
Pass :: struct {
|
||||
name: string,
|
||||
type: Pass_Type,
|
||||
}
|
||||
|
||||
Pass_Type :: union {
|
||||
Scene_Pass,
|
||||
Post_Processing_Pass,
|
||||
}
|
||||
|
||||
Scene_Pass :: struct {
|
||||
name: string,
|
||||
|
||||
input_textures: [PASS_MAX_INPUT_TEXTURES]^Texture, // TODO: SS - Make this a map?
|
||||
input_texture_count: u8,
|
||||
|
||||
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,
|
||||
|
||||
draw_commands: [dynamic]Draw_Command, // Capacity is 'MAX_DRAW_COMMANDS_CAPACITY'.
|
||||
|
||||
output_rt: ^Render_Target, // Commands draw to this render-target.
|
||||
}
|
||||
|
||||
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,
|
||||
post_processing_nodes: [dynamic]Post_Processing_Node, // These nodes are executed after all commands have been drawn onto the render-target.
|
||||
}
|
||||
|
||||
shader_program: Shader_Program,
|
||||
Post_Processing_Node :: struct {
|
||||
input: []^Texture,
|
||||
output: ^Render_Target,
|
||||
|
||||
program: ^Shader_Program,
|
||||
}
|
||||
|
||||
Draw_Command :: struct {
|
||||
@@ -81,76 +85,82 @@ Sort_Mode :: enum {
|
||||
|
||||
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
|
||||
output_rt: ^Render_Target,
|
||||
) -> Pass
|
||||
{
|
||||
// if input_depth_texture == nil {
|
||||
// if test_depth || clear_depth || write_depth {
|
||||
// assert(false)
|
||||
// }
|
||||
// }
|
||||
assert(len(name) > 0)
|
||||
|
||||
p := Scene_Pass {
|
||||
name = name,
|
||||
|
||||
output_rt = output_rt,
|
||||
|
||||
draw_commands = make([dynamic]Draw_Command, 0, MAX_DRAW_COMMANDS_CAPACITY),
|
||||
|
||||
clear_color = clear_color,
|
||||
p: Pass
|
||||
p.name = name
|
||||
p.type = Scene_Pass {
|
||||
blend_mode = blend_mode,
|
||||
sort_mode = sort_mode,
|
||||
|
||||
draw_commands = make([dynamic]Draw_Command, 0, MAX_DRAW_COMMANDS_CAPACITY),
|
||||
|
||||
output_rt = output_rt,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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,
|
||||
create_post_processing_pass :: proc(name: string, post_processing_nodes: []Post_Processing_Node) -> Pass {
|
||||
assert(len(name) > 0)
|
||||
|
||||
p: Pass
|
||||
p.name = name
|
||||
|
||||
ppp := Post_Processing_Pass {
|
||||
post_processing_nodes = make([dynamic]Post_Processing_Node, 0, MAX_POST_PROCESS_NODES_PER_PASS)
|
||||
}
|
||||
|
||||
append(&ppp.post_processing_nodes, ..post_processing_nodes)
|
||||
|
||||
p.type = ppp
|
||||
return p
|
||||
}
|
||||
|
||||
delete_pass :: proc {
|
||||
delete_scene_pass,
|
||||
delete_pass :: proc(pass: ^Pass) {
|
||||
assert(pass != nil)
|
||||
|
||||
switch &t in &pass.type {
|
||||
case Scene_Pass: delete_scene_pass(&t)
|
||||
case Post_Processing_Pass: delete_post_processing_pass(&t)
|
||||
}
|
||||
}
|
||||
|
||||
@(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 {
|
||||
@(private) delete_post_processing_pass :: proc(pass: ^Post_Processing_Pass) {
|
||||
delete(pass.post_processing_nodes)
|
||||
}
|
||||
|
||||
add_command_to_pass :: proc(renderer: ^Renderer, pass: ^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)
|
||||
switch &t in &pass.type {
|
||||
case Post_Processing_Pass: {
|
||||
fmt.printfln("Can't add commands to a post-processing pass.")
|
||||
return false
|
||||
}
|
||||
case Scene_Pass: {
|
||||
if t.output_rt == nil {
|
||||
fmt.printfln("Pass '%v' does not have a output render-target so you're not allowed to add commands to it.", pass.name)
|
||||
return false
|
||||
}
|
||||
|
||||
cmd := command
|
||||
cmd.renderer = renderer
|
||||
n, err := append(&t.draw_commands, cmd)
|
||||
assert(err == .None)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user