156 lines
3.7 KiB
Odin
156 lines
3.7 KiB
Odin
package renderer
|
|
|
|
import "core:fmt"
|
|
|
|
MAX_DRAW_COMMANDS_CAPACITY :: 4096
|
|
|
|
PASS_MAX_INPUT_TEXTURES :: 8
|
|
|
|
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,
|
|
}
|
|
|
|
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,
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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
|
|
} |