Spheres/primitive built-in meshes, cull-modes, vec4 uniforms
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
package renderer
|
package renderer
|
||||||
|
|
||||||
import "core:math/rand"
|
import "core:math/rand"
|
||||||
Color :: union {
|
|
||||||
|
Color :: union #no_nil {
|
||||||
RGB_Color,
|
RGB_Color,
|
||||||
RGBA_Color,
|
RGBA_Color,
|
||||||
}
|
}
|
||||||
|
|||||||
196
mesh.odin
196
mesh.odin
@@ -1,5 +1,7 @@
|
|||||||
package renderer
|
package renderer
|
||||||
|
|
||||||
|
import "core:math"
|
||||||
|
import "core:log"
|
||||||
Mesh :: struct {
|
Mesh :: struct {
|
||||||
amount_of_indices: u32,
|
amount_of_indices: u32,
|
||||||
backend: Mesh_Backend,
|
backend: Mesh_Backend,
|
||||||
@@ -14,7 +16,12 @@ Mesh_Layout :: struct {
|
|||||||
type_size: u32,
|
type_size: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
create_mesh :: proc(renderer: ^Renderer, layout: []Mesh_Layout, vertices: []f32, indices: []u32) -> (Mesh, bool) { // TODO: SS - Should probably return a Mesh_Handle.
|
create_mesh :: proc {
|
||||||
|
create_mesh_layout_vertices_indices,
|
||||||
|
create_mesh_from_primitive,
|
||||||
|
}
|
||||||
|
|
||||||
|
create_mesh_layout_vertices_indices :: proc(renderer: ^Renderer, layout: []Mesh_Layout, vertices: []f32, indices: []u32) -> (Mesh, bool) { // TODO: SS - Should probably return a Mesh_Handle.
|
||||||
mesh: Mesh
|
mesh: Mesh
|
||||||
|
|
||||||
if len(vertices) == 0 {
|
if len(vertices) == 0 {
|
||||||
@@ -40,3 +47,190 @@ create_mesh :: proc(renderer: ^Renderer, layout: []Mesh_Layout, vertices: []f32,
|
|||||||
|
|
||||||
return m, true
|
return m, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Primitive_Mesh_Type :: enum {
|
||||||
|
Cube,
|
||||||
|
Quad,
|
||||||
|
Sphere,
|
||||||
|
}
|
||||||
|
|
||||||
|
create_mesh_from_primitive :: proc(renderer: ^Renderer, primitive_mesh_type: Primitive_Mesh_Type) -> (Mesh, bool) {
|
||||||
|
switch primitive_mesh_type {
|
||||||
|
case .Cube: {
|
||||||
|
m, ok := create_mesh(
|
||||||
|
renderer = renderer,
|
||||||
|
layout = {
|
||||||
|
{ "position", 3, size_of(f32), },
|
||||||
|
{ "normal", 3, size_of(f32), },
|
||||||
|
{ "texture_coords", 2, size_of(f32), },
|
||||||
|
{ "tangent", 3, size_of(f32), },
|
||||||
|
},
|
||||||
|
vertices = []f32{
|
||||||
|
// Positions // Normals // UV // Tangent
|
||||||
|
// Back face
|
||||||
|
-0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||||
|
0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
|
||||||
|
0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
|
||||||
|
-0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0,
|
||||||
|
|
||||||
|
// Front face
|
||||||
|
-0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||||
|
0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
|
||||||
|
0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
|
||||||
|
-0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0,
|
||||||
|
|
||||||
|
// Left face
|
||||||
|
-0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0,
|
||||||
|
-0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0,
|
||||||
|
-0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
|
||||||
|
-0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
|
||||||
|
|
||||||
|
// Right face
|
||||||
|
0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0,
|
||||||
|
0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0,
|
||||||
|
0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -1.0,
|
||||||
|
0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, -1.0,
|
||||||
|
|
||||||
|
// Bottom face
|
||||||
|
-0.5, -0.5, -0.5, 0.0,-1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0,
|
||||||
|
0.5, -0.5, -0.5, 0.0,-1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0,
|
||||||
|
0.5, -0.5, 0.5, 0.0,-1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0,
|
||||||
|
-0.5, -0.5, 0.5, 0.0,-1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||||
|
|
||||||
|
// Top face
|
||||||
|
-0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0,
|
||||||
|
0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0,
|
||||||
|
0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0,
|
||||||
|
-0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||||
|
},
|
||||||
|
indices = []u32 {
|
||||||
|
// Back face
|
||||||
|
0, 3, 1,
|
||||||
|
1, 3, 2,
|
||||||
|
|
||||||
|
// Front face
|
||||||
|
4, 5, 7,
|
||||||
|
5, 6, 7,
|
||||||
|
|
||||||
|
// Left face
|
||||||
|
8, 9, 11,
|
||||||
|
9, 10, 11,
|
||||||
|
|
||||||
|
// Right face
|
||||||
|
12, 13, 15,
|
||||||
|
13, 14, 15,
|
||||||
|
|
||||||
|
// Bottom face
|
||||||
|
16, 17, 18,
|
||||||
|
16, 18, 19,
|
||||||
|
|
||||||
|
// Top face
|
||||||
|
20, 22, 21,
|
||||||
|
20, 23, 22
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return m, ok
|
||||||
|
}
|
||||||
|
case .Quad: {
|
||||||
|
m, ok := create_mesh(
|
||||||
|
renderer = renderer,
|
||||||
|
layout = {
|
||||||
|
{ "position", 3, size_of(f32), },
|
||||||
|
{ "normal", 3, size_of(f32), },
|
||||||
|
{ "texture_coords", 2, size_of(f32), },
|
||||||
|
{ "tangent", 3, size_of(f32), },
|
||||||
|
},
|
||||||
|
vertices = []f32 {
|
||||||
|
// Positions. // Normals // Texture Coordinates. // Tangent.
|
||||||
|
0.5, 0.5, 0.0, 0, 0, 0, 1.0, 1.0, 1, 0, 0, // Top right.
|
||||||
|
0.5, -0.5, 0.0, 0, 0, 0, 1.0, 0.0, 1, 0, 0, // Bottom right.
|
||||||
|
-0.5, -0.5, 0.0, 0, 0, 0, 0.0, 0.0, 1, 0, 0, // Bottom left.
|
||||||
|
-0.5, 0.5, 0.0, 0, 0, 0, 0.0, 1.0, 1, 0, 0, // Top left.
|
||||||
|
},
|
||||||
|
indices = []u32 {
|
||||||
|
0, 1, 3,
|
||||||
|
1, 2, 3,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return m, ok
|
||||||
|
}
|
||||||
|
case .Sphere: {
|
||||||
|
X_SEGMENTS :: 64
|
||||||
|
Y_SEGMENTS :: 32
|
||||||
|
|
||||||
|
vertices := make([dynamic]f32, 0)
|
||||||
|
indices := make([dynamic]u32, 0)
|
||||||
|
|
||||||
|
for y in 0..=Y_SEGMENTS {
|
||||||
|
y_segment := f32(y) / f32(Y_SEGMENTS)
|
||||||
|
phi := y_segment * math.PI
|
||||||
|
|
||||||
|
for x in 0..=X_SEGMENTS {
|
||||||
|
x_segment := f32(x) / f32(X_SEGMENTS)
|
||||||
|
theta := x_segment * math.TAU
|
||||||
|
|
||||||
|
px := math.cos(theta) * math.sin(phi)
|
||||||
|
py := math.cos(phi)
|
||||||
|
pz := math.sin(theta) * math.sin(phi)
|
||||||
|
|
||||||
|
// Position.
|
||||||
|
append(&vertices, px * 0.5)
|
||||||
|
append(&vertices, py * 0.5)
|
||||||
|
append(&vertices, pz * 0.5)
|
||||||
|
|
||||||
|
// Normal.
|
||||||
|
append(&vertices, px)
|
||||||
|
append(&vertices, py)
|
||||||
|
append(&vertices, pz)
|
||||||
|
|
||||||
|
// UV.
|
||||||
|
append(&vertices, x_segment)
|
||||||
|
append(&vertices, 1.0 - y_segment)
|
||||||
|
|
||||||
|
// Tangent.
|
||||||
|
tx := -math.sin(theta)
|
||||||
|
ty := f32(0.0)
|
||||||
|
tz := math.cos(theta)
|
||||||
|
|
||||||
|
append(&vertices, tx)
|
||||||
|
append(&vertices, ty)
|
||||||
|
append(&vertices, tz)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for y in 0..<Y_SEGMENTS {
|
||||||
|
for x in 0..<X_SEGMENTS {
|
||||||
|
i0 := u32(y * (X_SEGMENTS + 1) + x)
|
||||||
|
i1 := u32((y + 1) * (X_SEGMENTS + 1) + x)
|
||||||
|
i2 := u32((y + 1) * (X_SEGMENTS + 1) + x + 1)
|
||||||
|
i3 := u32(y * (X_SEGMENTS + 1) + x + 1)
|
||||||
|
|
||||||
|
append(&indices, i0)
|
||||||
|
append(&indices, i3)
|
||||||
|
append(&indices, i1)
|
||||||
|
|
||||||
|
append(&indices, i1)
|
||||||
|
append(&indices, i3)
|
||||||
|
append(&indices, i2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m, ok := create_mesh(
|
||||||
|
renderer = renderer,
|
||||||
|
layout = {
|
||||||
|
{ "position", 3, size_of(f32), },
|
||||||
|
{ "normal", 3, size_of(f32), },
|
||||||
|
{ "texture_coords", 2, size_of(f32), },
|
||||||
|
{ "tangent", 3, size_of(f32), },
|
||||||
|
},
|
||||||
|
vertices = vertices[:],
|
||||||
|
indices = indices[:],
|
||||||
|
)
|
||||||
|
|
||||||
|
return m, ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {}, false
|
||||||
|
}
|
||||||
155
pass.odin
155
pass.odin
@@ -2,6 +2,7 @@ package renderer
|
|||||||
|
|
||||||
import "core:math/linalg"
|
import "core:math/linalg"
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
|
import "core:log"
|
||||||
|
|
||||||
MAX_DRAW_COMMANDS_CAPACITY :: 4096
|
MAX_DRAW_COMMANDS_CAPACITY :: 4096
|
||||||
MAX_POST_PROCESS_NODES_PER_PASS :: 8
|
MAX_POST_PROCESS_NODES_PER_PASS :: 8
|
||||||
@@ -19,6 +20,7 @@ Pass_Type :: union {
|
|||||||
Scene_Pass :: struct {
|
Scene_Pass :: struct {
|
||||||
blend_mode: Blend_Mode,
|
blend_mode: Blend_Mode,
|
||||||
sort_mode: Sort_Mode,
|
sort_mode: Sort_Mode,
|
||||||
|
cull_mode: Cull_Mode,
|
||||||
|
|
||||||
draw_commands: [dynamic]Draw_Command, // Capacity is 'MAX_DRAW_COMMANDS_CAPACITY'.
|
draw_commands: [dynamic]Draw_Command, // Capacity is 'MAX_DRAW_COMMANDS_CAPACITY'.
|
||||||
|
|
||||||
@@ -31,10 +33,21 @@ Post_Processing_Pass :: struct {
|
|||||||
|
|
||||||
Uniform :: union {
|
Uniform :: union {
|
||||||
Uniform_Texture,
|
Uniform_Texture,
|
||||||
|
|
||||||
Uniform_Float,
|
Uniform_Float,
|
||||||
|
Uniform_Float_Pointer,
|
||||||
|
|
||||||
Uniform_Matrix4f32,
|
Uniform_Matrix4f32,
|
||||||
|
Uniform_Matrix4f32_Pointer,
|
||||||
|
|
||||||
Uniform_Vector3,
|
Uniform_Vector3,
|
||||||
|
Uniform_Vector3_Pointer,
|
||||||
|
|
||||||
|
Uniform_Vector4,
|
||||||
|
Uniform_Vector4_Pointer,
|
||||||
|
|
||||||
Uniform_Color,
|
Uniform_Color,
|
||||||
|
Uniform_Color_Pointer,
|
||||||
}
|
}
|
||||||
|
|
||||||
Uniform_Texture :: struct {
|
Uniform_Texture :: struct {
|
||||||
@@ -43,21 +56,46 @@ Uniform_Texture :: struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Uniform_Float :: struct {
|
Uniform_Float :: struct {
|
||||||
|
name: string,
|
||||||
|
value: f32,
|
||||||
|
}
|
||||||
|
Uniform_Float_Pointer :: struct {
|
||||||
name: string,
|
name: string,
|
||||||
value: ^f32,
|
value: ^f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
Uniform_Matrix4f32 :: struct {
|
Uniform_Matrix4f32 :: struct {
|
||||||
|
name: string,
|
||||||
|
value: linalg.Matrix4f32,
|
||||||
|
}
|
||||||
|
Uniform_Matrix4f32_Pointer :: struct {
|
||||||
name: string,
|
name: string,
|
||||||
value: ^linalg.Matrix4f32,
|
value: ^linalg.Matrix4f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
Uniform_Vector3 :: struct {
|
Uniform_Vector3 :: struct {
|
||||||
|
name: string,
|
||||||
|
value: [3]f32,
|
||||||
|
}
|
||||||
|
Uniform_Vector3_Pointer :: struct {
|
||||||
name: string,
|
name: string,
|
||||||
value: ^[3]f32,
|
value: ^[3]f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Uniform_Vector4 :: struct {
|
||||||
|
name: string,
|
||||||
|
value: [4]f32,
|
||||||
|
}
|
||||||
|
Uniform_Vector4_Pointer :: struct {
|
||||||
|
name: string,
|
||||||
|
value: ^[4]f32,
|
||||||
|
}
|
||||||
|
|
||||||
Uniform_Color :: struct {
|
Uniform_Color :: struct {
|
||||||
|
name: string,
|
||||||
|
value: Color,
|
||||||
|
}
|
||||||
|
Uniform_Color_Pointer :: struct {
|
||||||
name: string,
|
name: string,
|
||||||
value: ^Color,
|
value: ^Color,
|
||||||
}
|
}
|
||||||
@@ -69,16 +107,46 @@ Post_Processing_Node :: struct {
|
|||||||
program: ^Shader_Program,
|
program: ^Shader_Program,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: SS - Create a pool of 'Draw_Command's and reuse them.
|
||||||
|
|
||||||
|
MAX_UNIFORMS_PER_DRAW_COMMAND :: 8
|
||||||
|
|
||||||
Draw_Command :: struct {
|
Draw_Command :: struct {
|
||||||
renderer: ^Renderer, // Needed for sorting.
|
renderer: ^Renderer, // Needed for sorting.
|
||||||
|
|
||||||
mesh: Mesh,
|
mesh: Mesh,
|
||||||
material: Material,
|
material: Material,
|
||||||
|
uniforms: [MAX_UNIFORMS_PER_DRAW_COMMAND]Uniform,
|
||||||
|
uniform_count: u8,
|
||||||
|
|
||||||
position: [3]f32,
|
position: [3]f32,
|
||||||
rotation: [3]f32,
|
rotation: [3]f32,
|
||||||
scale: [3]f32,
|
scale: [3]f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create_draw_command :: proc(renderer: ^Renderer, mesh: Mesh, material: Material, uniforms: []Uniform, position, rotation, scale: [3]f32, loc := #caller_location) -> Draw_Command {
|
||||||
|
dc: Draw_Command
|
||||||
|
|
||||||
|
dc.renderer = renderer
|
||||||
|
dc.mesh = mesh
|
||||||
|
dc.material = material
|
||||||
|
dc.position = position
|
||||||
|
dc.rotation = rotation
|
||||||
|
dc.scale = scale
|
||||||
|
|
||||||
|
for u in uniforms {
|
||||||
|
if dc.uniform_count >= MAX_UNIFORMS_PER_DRAW_COMMAND {
|
||||||
|
log.warnf("Hit max capacity (%v) of uniforms per draw command! %v", MAX_UNIFORMS_PER_DRAW_COMMAND, loc)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
dc.uniforms[dc.uniform_count] = u
|
||||||
|
dc.uniform_count += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return dc
|
||||||
|
}
|
||||||
|
|
||||||
Blend_Mode :: enum {
|
Blend_Mode :: enum {
|
||||||
None,
|
None,
|
||||||
Alpha,
|
Alpha,
|
||||||
@@ -117,10 +185,18 @@ Sort_Mode :: enum {
|
|||||||
Front_To_Back, // Sorts the commands in the 'draw_commmands' array (from front to back) before drawing them.
|
Front_To_Back, // Sorts the commands in the 'draw_commmands' array (from front to back) before drawing them.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cull_Mode :: enum {
|
||||||
|
None,
|
||||||
|
Back,
|
||||||
|
Front,
|
||||||
|
Front_Back,
|
||||||
|
}
|
||||||
|
|
||||||
create_scene_pass :: proc(
|
create_scene_pass :: proc(
|
||||||
name: string,
|
name: string,
|
||||||
blend_mode: Blend_Mode,
|
blend_mode: Blend_Mode,
|
||||||
sort_mode: Sort_Mode,
|
sort_mode: Sort_Mode,
|
||||||
|
cull_mode: Cull_Mode,
|
||||||
output_rt: ^Render_Target,
|
output_rt: ^Render_Target,
|
||||||
) -> Pass
|
) -> Pass
|
||||||
{
|
{
|
||||||
@@ -131,6 +207,7 @@ create_scene_pass :: proc(
|
|||||||
p.type = Scene_Pass {
|
p.type = Scene_Pass {
|
||||||
blend_mode = blend_mode,
|
blend_mode = blend_mode,
|
||||||
sort_mode = sort_mode,
|
sort_mode = sort_mode,
|
||||||
|
cull_mode = cull_mode,
|
||||||
|
|
||||||
draw_commands = make([dynamic]Draw_Command, 0, MAX_DRAW_COMMANDS_CAPACITY),
|
draw_commands = make([dynamic]Draw_Command, 0, MAX_DRAW_COMMANDS_CAPACITY),
|
||||||
|
|
||||||
@@ -195,6 +272,82 @@ add_command_to_pass :: proc(renderer: ^Renderer, pass: ^Pass, command: Draw_Comm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
execute_pass :: proc(renderer: ^Renderer, pass: ^Pass, view_matrix, projection_matrix: linalg.Matrix4x4f32) { // TODO: SS - Move to 'pass.odin'.
|
||||||
|
// fmt.printfln("Executing pass '%v'.", pass.name)
|
||||||
|
|
||||||
|
assert(renderer != nil)
|
||||||
|
assert(pass != nil)
|
||||||
|
|
||||||
|
switch &t in &pass.type {
|
||||||
|
case Scene_Pass: {
|
||||||
|
apply_polygon_mode(renderer, renderer.polygon_mode)
|
||||||
|
|
||||||
|
assert(t.output_rt != nil)
|
||||||
|
bind_render_target(renderer, t.output_rt)
|
||||||
|
defer bind_render_target(renderer, nil)
|
||||||
|
|
||||||
|
should_write_depth := t.output_rt.depth_texture != nil
|
||||||
|
should_test_depth := should_write_depth
|
||||||
|
should_clear_depth := should_write_depth
|
||||||
|
|
||||||
|
should_clear_color := true
|
||||||
|
set_clear_color(renderer, RGBA_Color { 0, 0, 0, 0 })
|
||||||
|
|
||||||
|
clear_screen(renderer, should_clear_color, should_clear_depth)
|
||||||
|
apply_depth(renderer, should_test_depth, should_write_depth)
|
||||||
|
|
||||||
|
apply_blend_mode(renderer, t.blend_mode)
|
||||||
|
defer apply_blend_mode(renderer, .None)
|
||||||
|
|
||||||
|
apply_cull_mode(renderer, t.cull_mode)
|
||||||
|
defer apply_cull_mode(renderer, .None)
|
||||||
|
|
||||||
|
sort_draw_commands(renderer, &t)
|
||||||
|
|
||||||
|
for &dc in &t.draw_commands { // TODO: SS - Don't think we need the address of the draw-commands.
|
||||||
|
model_matrix := linalg.identity(linalg.Matrix4x4f32)
|
||||||
|
|
||||||
|
// Translate.
|
||||||
|
translation := linalg.matrix4_translate(dc.position)
|
||||||
|
|
||||||
|
// Rotate.
|
||||||
|
rot_x := linalg.matrix4_rotate(linalg.to_radians(dc.rotation.x), [3]f32 { 1, 0, 0 })
|
||||||
|
rot_y := linalg.matrix4_rotate(linalg.to_radians(dc.rotation.y), [3]f32 { 0, 1, 0 })
|
||||||
|
rot_z := linalg.matrix4_rotate(linalg.to_radians(dc.rotation.z), [3]f32 { 0, 0, 1 })
|
||||||
|
rotation := rot_z * rot_y * rot_x
|
||||||
|
|
||||||
|
// Scale.
|
||||||
|
scale := linalg.matrix4_scale(dc.scale)
|
||||||
|
|
||||||
|
model_matrix *= translation * rotation * scale
|
||||||
|
|
||||||
|
// Apply uniforms.
|
||||||
|
activate_material(&dc.material, model_matrix, view_matrix, projection_matrix)
|
||||||
|
if dc.uniform_count > 0 {
|
||||||
|
set_shader_uniforms(dc.material.shader_program, dc.uniforms[:dc.uniform_count])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the mesh.
|
||||||
|
draw_mesh(&dc.mesh)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the pass' draw-commands.
|
||||||
|
clear(&t.draw_commands)
|
||||||
|
|
||||||
|
// TODO: SS - "Deactivate" the pass?
|
||||||
|
|
||||||
|
apply_polygon_mode(renderer, .Fill)
|
||||||
|
}
|
||||||
|
case Post_Processing_Pass: {
|
||||||
|
// Execute the post-processing nodes.
|
||||||
|
for &pp in &t.post_processing_nodes {
|
||||||
|
execute_post_processing_node(renderer, &pp, view_matrix, projection_matrix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: SS - "Deactivate" the pass?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
173
renderer.odin
173
renderer.odin
@@ -23,6 +23,9 @@ Renderer :: struct {
|
|||||||
|
|
||||||
active_camera: ^Camera, // NOTE: SS - Hardcoded to 1 active camera. Split-screen is likely not possible due to this. Fix(?).
|
active_camera: ^Camera, // NOTE: SS - Hardcoded to 1 active camera. Split-screen is likely not possible due to this. Fix(?).
|
||||||
|
|
||||||
|
// Primitive meshes.
|
||||||
|
default_cube_mesh, default_quad_mesh, default_sphere_mesh: Mesh,
|
||||||
|
|
||||||
fullscreen_vertex_shader, fullscreen_fragment_shader: Shader,
|
fullscreen_vertex_shader, fullscreen_fragment_shader: Shader,
|
||||||
fullscreen_shader_program: Shader_Program,
|
fullscreen_shader_program: Shader_Program,
|
||||||
fullscreen_mesh: Mesh,
|
fullscreen_mesh: Mesh,
|
||||||
@@ -65,6 +68,20 @@ create :: proc(surface_ptr: rawptr) -> (^Renderer, bool) {
|
|||||||
|
|
||||||
set_vsync(renderer, true)
|
set_vsync(renderer, true)
|
||||||
|
|
||||||
|
{ // Create the default mesh-primitives.
|
||||||
|
// default_cube_mesh, default_quad_mesh, default_sphere_mesh: Mesh,
|
||||||
|
|
||||||
|
if m, ok := create_mesh(renderer, .Cube); ok {
|
||||||
|
renderer.default_cube_mesh = m
|
||||||
|
}
|
||||||
|
if m, ok := create_mesh(renderer, .Quad); ok {
|
||||||
|
renderer.default_quad_mesh = m
|
||||||
|
}
|
||||||
|
if m, ok := create_mesh(renderer, .Sphere); ok {
|
||||||
|
renderer.default_sphere_mesh = m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{ // Create the fullscreen shaders, material and mesh.
|
{ // Create the fullscreen shaders, material and mesh.
|
||||||
fs_vertex_shader, fs_vertex_shader_ok := create_shader(renderer, .Vertex, "fs_vertex.glsl")
|
fs_vertex_shader, fs_vertex_shader_ok := create_shader(renderer, .Vertex, "fs_vertex.glsl")
|
||||||
assert(fs_vertex_shader_ok)
|
assert(fs_vertex_shader_ok)
|
||||||
@@ -135,13 +152,13 @@ set_vsync :: proc(renderer: ^Renderer, on: bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private="file") set_clear_color :: proc(renderer: ^Renderer, color: Color) {
|
@(private) set_clear_color :: proc(renderer: ^Renderer, color: Color) {
|
||||||
when RENDER_BACKEND_OPENGL {
|
when RENDER_BACKEND_OPENGL {
|
||||||
opengl_set_clear_color(renderer, color)
|
opengl_set_clear_color(renderer, color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private="file") clear_screen :: proc(renderer: ^Renderer, clear_color: bool, clear_depth: bool) {
|
@(private) clear_screen :: proc(renderer: ^Renderer, clear_color: bool, clear_depth: bool) {
|
||||||
when RENDER_BACKEND_OPENGL {
|
when RENDER_BACKEND_OPENGL {
|
||||||
opengl_clear_screen(renderer, clear_color, clear_depth)
|
opengl_clear_screen(renderer, clear_color, clear_depth)
|
||||||
}
|
}
|
||||||
@@ -202,75 +219,6 @@ render_frame :: proc(renderer: ^Renderer, texture_to_present: ^Texture, clear_co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
execute_pass :: proc(renderer: ^Renderer, pass: ^Pass, view_matrix, projection_matrix: linalg.Matrix4x4f32) { // TODO: SS - Move to 'pass.odin'.
|
|
||||||
// fmt.printfln("Executing pass '%v'.", pass.name)
|
|
||||||
|
|
||||||
assert(renderer != nil)
|
|
||||||
assert(pass != nil)
|
|
||||||
|
|
||||||
switch &t in &pass.type {
|
|
||||||
case Scene_Pass: {
|
|
||||||
apply_polygon_mode(renderer, renderer.polygon_mode)
|
|
||||||
|
|
||||||
assert(t.output_rt != nil)
|
|
||||||
bind_render_target(renderer, t.output_rt)
|
|
||||||
defer bind_render_target(renderer, nil)
|
|
||||||
|
|
||||||
should_write_depth := t.output_rt.depth_texture != nil
|
|
||||||
should_test_depth := should_write_depth
|
|
||||||
should_clear_depth := should_write_depth
|
|
||||||
|
|
||||||
should_clear_color := true
|
|
||||||
set_clear_color(renderer, RGBA_Color { 0, 0, 0, 0 })
|
|
||||||
|
|
||||||
clear_screen(renderer, should_clear_color, should_clear_depth)
|
|
||||||
apply_depth(renderer, should_test_depth, should_write_depth)
|
|
||||||
|
|
||||||
apply_blend_mode(renderer, t.blend_mode)
|
|
||||||
defer apply_blend_mode(renderer, .None)
|
|
||||||
|
|
||||||
sort_draw_commands(renderer, &t)
|
|
||||||
|
|
||||||
for &dc in &t.draw_commands { // TODO: SS - Don't think we need the address of the draw-commands.
|
|
||||||
model_matrix := linalg.identity(linalg.Matrix4x4f32)
|
|
||||||
|
|
||||||
// Translate.
|
|
||||||
translation := linalg.matrix4_translate(dc.position)
|
|
||||||
|
|
||||||
// Rotate.
|
|
||||||
rot_x := linalg.matrix4_rotate(linalg.to_radians(dc.rotation.x), [3]f32 { 1, 0, 0 })
|
|
||||||
rot_y := linalg.matrix4_rotate(linalg.to_radians(dc.rotation.y), [3]f32 { 0, 1, 0 })
|
|
||||||
rot_z := linalg.matrix4_rotate(linalg.to_radians(dc.rotation.z), [3]f32 { 0, 0, 1 })
|
|
||||||
rotation := rot_z * rot_y * rot_x
|
|
||||||
|
|
||||||
// Scale.
|
|
||||||
scale := linalg.matrix4_scale(dc.scale)
|
|
||||||
|
|
||||||
model_matrix *= translation * rotation * scale
|
|
||||||
|
|
||||||
activate_material(&dc.material, model_matrix, view_matrix, projection_matrix)
|
|
||||||
|
|
||||||
draw_mesh(&dc.mesh)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the pass' draw-commands.
|
|
||||||
clear(&t.draw_commands)
|
|
||||||
|
|
||||||
// TODO: SS - "Deactivate" the pass?
|
|
||||||
|
|
||||||
apply_polygon_mode(renderer, .Fill)
|
|
||||||
}
|
|
||||||
case Post_Processing_Pass: {
|
|
||||||
// Execute the post-processing nodes.
|
|
||||||
for &pp in &t.post_processing_nodes {
|
|
||||||
execute_post_processing_node(renderer, &pp, view_matrix, projection_matrix)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: SS - "Deactivate" the pass?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
execute_post_processing_node :: proc(renderer: ^Renderer, node: ^Post_Processing_Node, view_matrix, projection_matrix: linalg.Matrix4x4f32) {
|
execute_post_processing_node :: proc(renderer: ^Renderer, node: ^Post_Processing_Node, view_matrix, projection_matrix: linalg.Matrix4x4f32) {
|
||||||
assert(renderer != nil)
|
assert(renderer != nil)
|
||||||
assert(node != nil)
|
assert(node != nil)
|
||||||
@@ -287,45 +235,15 @@ execute_post_processing_node :: proc(renderer: ^Renderer, node: ^Post_Processing
|
|||||||
|
|
||||||
// fmt.printfln("TODO: SS - Execute post-processing node '%v' (VS: '%v', FS: '%v').", "NAME", node.program.vertex_shader.path, node.program.fragment_shader.path)
|
// fmt.printfln("TODO: SS - Execute post-processing node '%v' (VS: '%v', FS: '%v').", "NAME", node.program.vertex_shader.path, node.program.fragment_shader.path)
|
||||||
|
|
||||||
|
set_shader_uniforms(node.program, node.uniforms)
|
||||||
|
|
||||||
mat: Material
|
mat: Material
|
||||||
mat.shader_program = node.program
|
mat.shader_program = node.program
|
||||||
|
|
||||||
fs_path := node.program.fragment_shader != nil ? node.program.fragment_shader.path : "nil"
|
for u in node.uniforms {
|
||||||
vs_path := node.program.vertex_shader != nil ? node.program.vertex_shader.path : "nil"
|
if t, is_texture := u.(Uniform_Texture); is_texture {
|
||||||
|
|
||||||
for u, i in node.uniforms {
|
|
||||||
switch &t in u {
|
|
||||||
case Uniform_Texture: {
|
|
||||||
if mat.texture_count > MATERIAL_MAX_TEXTURES {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
mat.textures[mat.texture_count] = t.value
|
mat.textures[mat.texture_count] = t.value
|
||||||
mat.texture_count += 1
|
mat.texture_count += 1
|
||||||
if !set_shader_uniform(node.program, t) {
|
|
||||||
fmt.printfln("Failed to set uniform-texture %v in program (vs: '%s', fs: '%s').", t.index, vs_path, fs_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Uniform_Float: {
|
|
||||||
if !set_shader_uniform(node.program, t) {
|
|
||||||
fmt.printfln("Failed to set uniform-float '%s' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Uniform_Matrix4f32: {
|
|
||||||
if !set_shader_uniform(node.program, t) {
|
|
||||||
fmt.printfln("Failed to set uniform-matrix4f32 '%s' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Uniform_Vector3: {
|
|
||||||
if !set_shader_uniform(node.program, t) {
|
|
||||||
fmt.printfln("Failed to set uniform-vector3 '%s' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Uniform_Color: {
|
|
||||||
if !set_shader_uniform(node.program, t) {
|
|
||||||
fmt.printfln("Failed to set uniform-color '%s' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,6 +256,10 @@ destroy :: proc(renderer: ^Renderer) {
|
|||||||
opengl_destroy(renderer)
|
opengl_destroy(renderer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: SS - Destroy 'default_cube_mesh'
|
||||||
|
// TODO: SS - Destroy 'default_quad_mesh'
|
||||||
|
// TODO: SS - Destroy 'default_sphere_mesh'
|
||||||
|
|
||||||
assert(renderer != nil)
|
assert(renderer != nil)
|
||||||
free(renderer)
|
free(renderer)
|
||||||
}
|
}
|
||||||
@@ -354,39 +276,7 @@ destroy :: proc(renderer: ^Renderer) {
|
|||||||
p := material.shader_program
|
p := material.shader_program
|
||||||
|
|
||||||
activate_shader_program(p)
|
activate_shader_program(p)
|
||||||
|
set_shader_uniforms(material.shader_program, material.uniforms)
|
||||||
fs_path := p.fragment_shader != nil ? p.fragment_shader.path : "nil"
|
|
||||||
vs_path := p.vertex_shader != nil ? p.vertex_shader.path : "nil"
|
|
||||||
|
|
||||||
for u in material.uniforms {
|
|
||||||
switch &t in u {
|
|
||||||
case Uniform_Texture: {
|
|
||||||
if !set_shader_uniform(p, t) {
|
|
||||||
fmt.printfln("Failed to set uniform-texture %v in program (vs: '%s', fs: '%s').", t.index, vs_path, fs_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Uniform_Float: {
|
|
||||||
if !set_shader_uniform(p, t) {
|
|
||||||
fmt.printfln("Failed to set uniform-float '%s' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Uniform_Matrix4f32: {
|
|
||||||
if !set_shader_uniform(p, t) {
|
|
||||||
fmt.printfln("Failed to set uniform-matrix4f32 '%s' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Uniform_Vector3: {
|
|
||||||
if !set_shader_uniform(p, t) {
|
|
||||||
fmt.printfln("Failed to set uniform-vector3 '%s' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Uniform_Color: {
|
|
||||||
if !set_shader_uniform(p, t) {
|
|
||||||
fmt.printfln("Failed to set uniform-color '%s' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
when RENDER_BACKEND_OPENGL {
|
when RENDER_BACKEND_OPENGL {
|
||||||
opengl_activate_material(material, model_matrix, view_matrix, projection_matrix)
|
opengl_activate_material(material, model_matrix, view_matrix, projection_matrix)
|
||||||
@@ -415,7 +305,14 @@ destroy :: proc(renderer: ^Renderer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(private) apply_cull_mode :: proc(renderer: ^Renderer, cull_mode: Cull_Mode) {
|
||||||
|
when RENDER_BACKEND_OPENGL {
|
||||||
|
opengl_set_cull_mode(renderer, cull_mode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@(private) sort_draw_commands :: proc(renderer: ^Renderer, pass: ^Scene_Pass) {
|
@(private) sort_draw_commands :: proc(renderer: ^Renderer, pass: ^Scene_Pass) {
|
||||||
|
// TODO: SS - Set the pass' 'renderer' variable here instead?
|
||||||
switch pass.sort_mode {
|
switch pass.sort_mode {
|
||||||
case .None: {}
|
case .None: {}
|
||||||
case .Back_To_Front: {
|
case .Back_To_Front: {
|
||||||
|
|||||||
@@ -517,6 +517,29 @@ when RENDER_BACKEND_OPENGL {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opengl_set_cull_mode :: proc(renderer: ^Renderer, cull_mode: Cull_Mode) {
|
||||||
|
switch cull_mode {
|
||||||
|
case .None: {
|
||||||
|
gl.Disable(gl.CULL_FACE)
|
||||||
|
}
|
||||||
|
case .Back: {
|
||||||
|
gl.Enable(gl.CULL_FACE)
|
||||||
|
gl.CullFace(gl.BACK)
|
||||||
|
gl.FrontFace(gl.CCW)
|
||||||
|
}
|
||||||
|
case .Front: {
|
||||||
|
gl.Enable(gl.CULL_FACE)
|
||||||
|
gl.CullFace(gl.FRONT)
|
||||||
|
gl.FrontFace(gl.CCW)
|
||||||
|
}
|
||||||
|
case .Front_Back: {
|
||||||
|
gl.Enable(gl.CULL_FACE)
|
||||||
|
gl.CullFace(gl.FRONT_AND_BACK)
|
||||||
|
gl.FrontFace(gl.CCW)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
opengl_bind_render_target :: proc(renderer: ^Renderer, rt: ^Render_Target) {
|
opengl_bind_render_target :: proc(renderer: ^Renderer, rt: ^Render_Target) {
|
||||||
if rt == nil {
|
if rt == nil {
|
||||||
gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
|
gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
|
||||||
@@ -629,7 +652,7 @@ when RENDER_BACKEND_OPENGL {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.Uniform1f(loc, uniform.value^)
|
gl.Uniform1f(loc, uniform.value)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -644,7 +667,7 @@ when RENDER_BACKEND_OPENGL {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
data := transmute([16]f32)(uniform.value^)
|
data := transmute([16]f32)(uniform.value)
|
||||||
gl.UniformMatrix4fv(loc, 1, gl.FALSE, &data[0])
|
gl.UniformMatrix4fv(loc, 1, gl.FALSE, &data[0])
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@@ -659,7 +682,23 @@ when RENDER_BACKEND_OPENGL {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.Uniform3fv(loc, 1, &uniform.value[0])
|
v := transmute([3]f32)uniform.value
|
||||||
|
gl.Uniform3fv(loc, 1, &v[0])
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
opengl_set_shader_uniform_vector4 :: proc(program: ^Shader_Program, uniform: Uniform_Vector4) -> bool {
|
||||||
|
opengl_activate_shader_program(program)
|
||||||
|
|
||||||
|
loc := gl.GetUniformLocation(program.backend.handle, fmt.ctprintf("%v", uniform.name))
|
||||||
|
if loc < 0 {
|
||||||
|
fmt.printfln("vector4 Loc: %v", loc)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
v := transmute([4]f32)uniform.value
|
||||||
|
gl.Uniform4fv(loc, 1, &v[0])
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
106
shader.odin
106
shader.odin
@@ -123,12 +123,39 @@ reload_shader_program :: proc(renderer: ^Renderer, p: ^Shader_Program) -> bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_shader_uniforms :: proc(program: ^Shader_Program, uniforms: []Uniform) {
|
||||||
|
fs_path := program.fragment_shader != nil ? program.fragment_shader.path : "nil"
|
||||||
|
vs_path := program.vertex_shader != nil ? program.vertex_shader.path : "nil"
|
||||||
|
|
||||||
|
for u in uniforms {
|
||||||
|
switch &t in u {
|
||||||
|
case Uniform_Texture: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (texture) %v in program (vs: '%s', fs: '%s').", t.index, vs_path, fs_path) }}
|
||||||
|
case Uniform_Float: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (float) '%v' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path) }}
|
||||||
|
case Uniform_Float_Pointer: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (float pointer) '%v' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path) }}
|
||||||
|
case Uniform_Matrix4f32: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (matrix4f32) '%v' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path) }}
|
||||||
|
case Uniform_Matrix4f32_Pointer: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (matrix4f32 pointer) '%v' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path) }}
|
||||||
|
case Uniform_Vector3: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (vector3) '%v' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path) }}
|
||||||
|
case Uniform_Vector3_Pointer: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (vector3 pointer) '%v' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path) }}
|
||||||
|
case Uniform_Vector4: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (vector4) '%v' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path) }}
|
||||||
|
case Uniform_Vector4_Pointer: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (vector4 pointer) '%v' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path) }}
|
||||||
|
case Uniform_Color: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (color) '%v' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path) }}
|
||||||
|
case Uniform_Color_Pointer: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (color pointer) '%v' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path) }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
set_shader_uniform :: proc { // TODO: SS - Improve setting shader uniforms. A bit bug-prone and annoying to explicitly add code-paths for every 'Uniform' type needed.
|
set_shader_uniform :: proc { // TODO: SS - Improve setting shader uniforms. A bit bug-prone and annoying to explicitly add code-paths for every 'Uniform' type needed.
|
||||||
set_shader_uniform_texture,
|
set_shader_uniform_texture,
|
||||||
set_shader_uniform_float,
|
set_shader_uniform_float,
|
||||||
|
set_shader_uniform_float_pointer,
|
||||||
set_shader_uniform_matrix4f32,
|
set_shader_uniform_matrix4f32,
|
||||||
|
set_shader_uniform_matrix4f32_pointer,
|
||||||
set_shader_uniform_vector3,
|
set_shader_uniform_vector3,
|
||||||
|
set_shader_uniform_vector3_pointer,
|
||||||
|
set_shader_uniform_vector4,
|
||||||
|
set_shader_uniform_vector4_pointer,
|
||||||
set_shader_uniform_color,
|
set_shader_uniform_color,
|
||||||
|
set_shader_uniform_color_pointer,
|
||||||
}
|
}
|
||||||
|
|
||||||
set_shader_uniform_texture :: proc(program: ^Shader_Program, uniform: Uniform_Texture) -> bool {
|
set_shader_uniform_texture :: proc(program: ^Shader_Program, uniform: Uniform_Texture) -> bool {
|
||||||
@@ -143,13 +170,15 @@ set_shader_uniform_texture :: proc(program: ^Shader_Program, uniform: Uniform_Te
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
set_shader_uniform_float :: proc(program: ^Shader_Program, uniform: Uniform_Float) -> bool {
|
set_shader_uniform_float_pointer :: proc(program: ^Shader_Program, uniform: Uniform_Float_Pointer) -> bool {
|
||||||
assert(program != nil)
|
|
||||||
assert(len(uniform.name) > 0)
|
|
||||||
|
|
||||||
if uniform.value == nil {
|
if uniform.value == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
return set_shader_uniform(program, Uniform_Float { uniform.name, uniform.value^ })
|
||||||
|
}
|
||||||
|
set_shader_uniform_float :: proc(program: ^Shader_Program, uniform: Uniform_Float) -> bool {
|
||||||
|
assert(program != nil)
|
||||||
|
assert(len(uniform.name) > 0)
|
||||||
|
|
||||||
// TODO: SS - Somehow verify that 'uniform.name' exists in the shader(s)?
|
// TODO: SS - Somehow verify that 'uniform.name' exists in the shader(s)?
|
||||||
|
|
||||||
@@ -160,13 +189,15 @@ set_shader_uniform_float :: proc(program: ^Shader_Program, uniform: Uniform_Floa
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
set_shader_uniform_matrix4f32 :: proc(program: ^Shader_Program, uniform: Uniform_Matrix4f32) -> bool {
|
set_shader_uniform_matrix4f32_pointer :: proc(program: ^Shader_Program, uniform: Uniform_Matrix4f32_Pointer) -> bool {
|
||||||
assert(program != nil)
|
|
||||||
assert(len(uniform.name) > 0)
|
|
||||||
|
|
||||||
if uniform.value == nil {
|
if uniform.value == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
return set_shader_uniform(program, Uniform_Matrix4f32 { uniform.name, uniform.value^ })
|
||||||
|
}
|
||||||
|
set_shader_uniform_matrix4f32 :: proc(program: ^Shader_Program, uniform: Uniform_Matrix4f32) -> bool {
|
||||||
|
assert(program != nil)
|
||||||
|
assert(len(uniform.name) > 0)
|
||||||
|
|
||||||
// TODO: SS - Somehow verify that 'uniform.name' exists in the shader(s)?
|
// TODO: SS - Somehow verify that 'uniform.name' exists in the shader(s)?
|
||||||
|
|
||||||
@@ -177,13 +208,16 @@ set_shader_uniform_matrix4f32 :: proc(program: ^Shader_Program, uniform: Uniform
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
set_shader_uniform_vector3 :: proc(program: ^Shader_Program, uniform: Uniform_Vector3) -> bool {
|
set_shader_uniform_vector3_pointer :: proc(program: ^Shader_Program, uniform: Uniform_Vector3_Pointer) -> bool {
|
||||||
assert(program != nil)
|
|
||||||
assert(len(uniform.name) > 0)
|
|
||||||
|
|
||||||
if uniform.value == nil {
|
if uniform.value == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
return set_shader_uniform(program, Uniform_Vector3 { uniform.name, uniform.value^ })
|
||||||
|
}
|
||||||
|
|
||||||
|
set_shader_uniform_vector3 :: proc(program: ^Shader_Program, uniform: Uniform_Vector3) -> bool {
|
||||||
|
assert(program != nil)
|
||||||
|
assert(len(uniform.name) > 0)
|
||||||
|
|
||||||
// TODO: SS - Somehow verify that 'uniform.name' exists in the shader(s)?
|
// TODO: SS - Somehow verify that 'uniform.name' exists in the shader(s)?
|
||||||
|
|
||||||
@@ -194,13 +228,35 @@ set_shader_uniform_vector3 :: proc(program: ^Shader_Program, uniform: Uniform_Ve
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
set_shader_uniform_color :: proc(program: ^Shader_Program, uniform: Uniform_Color) -> bool {
|
set_shader_uniform_vector4_pointer :: proc(program: ^Shader_Program, uniform: Uniform_Vector4_Pointer) -> bool {
|
||||||
assert(program != nil)
|
|
||||||
assert(len(uniform.name) > 0)
|
|
||||||
|
|
||||||
if uniform.value == nil {
|
if uniform.value == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
return set_shader_uniform(program, Uniform_Vector4 { uniform.name, uniform.value^ })
|
||||||
|
}
|
||||||
|
|
||||||
|
set_shader_uniform_vector4 :: proc(program: ^Shader_Program, uniform: Uniform_Vector4) -> bool {
|
||||||
|
assert(program != nil)
|
||||||
|
assert(len(uniform.name) > 0)
|
||||||
|
|
||||||
|
// TODO: SS - Somehow verify that 'uniform.name' exists in the shader(s)?
|
||||||
|
|
||||||
|
when RENDER_BACKEND_OPENGL {
|
||||||
|
return opengl_set_shader_uniform_vector4(program, uniform)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
set_shader_uniform_color_pointer :: proc(program: ^Shader_Program, uniform: Uniform_Color_Pointer) -> bool {
|
||||||
|
if uniform.value == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return set_shader_uniform(program, Uniform_Color { uniform.name, uniform.value^ })
|
||||||
|
}
|
||||||
|
set_shader_uniform_color :: proc(program: ^Shader_Program, uniform: Uniform_Color) -> bool {
|
||||||
|
assert(program != nil)
|
||||||
|
assert(len(uniform.name) > 0)
|
||||||
|
|
||||||
// TODO: SS - Somehow verify that 'uniform.name' exists in the shader(s)?
|
// TODO: SS - Somehow verify that 'uniform.name' exists in the shader(s)?
|
||||||
|
|
||||||
@@ -210,7 +266,7 @@ set_shader_uniform_color :: proc(program: ^Shader_Program, uniform: Uniform_Colo
|
|||||||
|
|
||||||
u := Uniform_Vector3 {
|
u := Uniform_Vector3 {
|
||||||
name = uniform.name,
|
name = uniform.name,
|
||||||
value = &rgb,
|
value = rgb,
|
||||||
}
|
}
|
||||||
|
|
||||||
when RENDER_BACKEND_OPENGL {
|
when RENDER_BACKEND_OPENGL {
|
||||||
@@ -220,16 +276,14 @@ set_shader_uniform_color :: proc(program: ^Shader_Program, uniform: Uniform_Colo
|
|||||||
case RGBA_Color: {
|
case RGBA_Color: {
|
||||||
rgba := color_to_f32(c)
|
rgba := color_to_f32(c)
|
||||||
|
|
||||||
// u := Uniform_Vector4 {
|
u := Uniform_Vector4 {
|
||||||
// name = uniform.name,
|
name = uniform.name,
|
||||||
// value = &rgba,
|
value = rgba,
|
||||||
// }
|
}
|
||||||
|
|
||||||
// TODO: SS - Set vector4.
|
when RENDER_BACKEND_OPENGL {
|
||||||
// when RENDER_BACKEND_OPENGL {
|
return opengl_set_shader_uniform_vector4(program, u)
|
||||||
// return opengl_set_shader_uniform_vector4(program, uniform)
|
}
|
||||||
// }
|
|
||||||
assert(false, "TODO: SS - Allow setting rgba in uniform.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user