diff --git a/mesh.odin b/mesh.odin index e9d3d6a..9a76d44 100644 --- a/mesh.odin +++ b/mesh.odin @@ -50,7 +50,7 @@ create_mesh_layout_vertices_indices :: proc(renderer: ^Renderer, layout: []Mesh_ Primitive_Mesh_Type :: enum { Cube, - Quad, + UI_Quad, World_Quad, // NOTE: SS - Not sure I like two quads but it's probably alright. Sphere, } @@ -132,7 +132,7 @@ create_mesh_from_primitive :: proc(renderer: ^Renderer, primitive_mesh_type: Pri return m, ok } - case .Quad: { + case .World_Quad: { m, ok := create_mesh( renderer = renderer, layout = { @@ -142,7 +142,7 @@ create_mesh_from_primitive :: proc(renderer: ^Renderer, primitive_mesh_type: Pri { "tangent", 3, size_of(f32), }, }, vertices = []f32 { - // Positions. // Normals // Texture Coordinates. // Tangent. + // 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. @@ -155,6 +155,27 @@ create_mesh_from_primitive :: proc(renderer: ^Renderer, primitive_mesh_type: Pri ) return m, ok } + case .UI_Quad: { + m, ok := create_mesh( + renderer = renderer, + layout = { + { "position", 3, size_of(f32), }, + { "texture_coords", 2, size_of(f32), }, + }, + vertices = []f32 { + // Positions. // UV. + 0.0, 0.0, 0.0, 0.0, 1.0, + 1.0, 0.0, 0.0, 1.0, 1.0, + 1.0, 1.0, 0.0, 1.0, 0.0, + 0.0, 1.0, 0.0, 0.0, 0.0, + }, + indices = []u32 { + 0, 1, 2, + 0, 2, 3, + } + ) + return m, ok + } case .Sphere: { X_SEGMENTS :: 64 Y_SEGMENTS :: 32 diff --git a/pass.odin b/pass.odin index 9b5d997..1b749e2 100644 --- a/pass.odin +++ b/pass.odin @@ -40,9 +40,10 @@ Uniform :: union { Uniform_Matrix4f32, Uniform_Matrix4f32_Pointer, + Uniform_Vector2, + Uniform_Vector2_Pointer, Uniform_Vector3, Uniform_Vector3_Pointer, - Uniform_Vector4, Uniform_Vector4_Pointer, @@ -73,6 +74,15 @@ Uniform_Matrix4f32_Pointer :: struct { value: ^linalg.Matrix4f32, } +Uniform_Vector2 :: struct { + name: string, + value: [2]f32, +} +Uniform_Vector2_Pointer :: struct { + name: string, + value: ^[2]f32, +} + Uniform_Vector3 :: struct { name: string, value: [3]f32, @@ -278,13 +288,15 @@ add_command_to_pass :: proc(renderer: ^Renderer, pass: ^Pass, command: Draw_Comm } 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) + // log.infof("Executing pass '%v'.", pass.name) assert(renderer != nil) assert(pass != nil) switch &t in &pass.type { case Scene_Pass: { + // temp_draw_count := 0 + apply_polygon_mode(renderer, renderer.polygon_mode) assert(t.output_rt != nil) @@ -310,6 +322,8 @@ execute_pass :: proc(renderer: ^Renderer, pass: ^Pass, view_matrix, projection_m sort_draw_commands(renderer, &t) + // TODO: SS - Frustum-culling. + 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) @@ -335,6 +349,8 @@ execute_pass :: proc(renderer: ^Renderer, pass: ^Pass, view_matrix, projection_m // Draw the mesh. draw_mesh(&dc.mesh) + + // temp_draw_count += 1 } // Clear the pass' draw-commands. @@ -343,6 +359,8 @@ execute_pass :: proc(renderer: ^Renderer, pass: ^Pass, view_matrix, projection_m // TODO: SS - "Deactivate" the pass? apply_polygon_mode(renderer, .Fill) + + // log.infof(" Done! Drew %v meshes.", temp_draw_count) } case Post_Processing_Pass: { // Execute the post-processing nodes. diff --git a/renderer.odin b/renderer.odin index 61f702e..f632d4c 100644 --- a/renderer.odin +++ b/renderer.odin @@ -27,7 +27,7 @@ Renderer :: struct { 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, + default_cube_mesh, default_quad_world_mesh, default_quad_ui_mesh, default_sphere_mesh: Mesh, fullscreen_vertex_shader, fullscreen_fragment_shader: Shader, fullscreen_shader_program: Shader_Program, @@ -97,13 +97,16 @@ create :: proc(render_resolution: Resolution, surface_ptr: rawptr) -> (^Renderer set_vsync(renderer, true) { // Create the default mesh-primitives. - // default_cube_mesh, default_quad_mesh, default_sphere_mesh: Mesh, + // default_cube_mesh, default_quad_world_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, .World_Quad); ok { + renderer.default_quad_world_mesh = m + } + if m, ok := create_mesh(renderer, .UI_Quad); ok { + renderer.default_quad_ui_mesh = m } if m, ok := create_mesh(renderer, .Sphere); ok { renderer.default_sphere_mesh = m @@ -321,7 +324,7 @@ execute_post_processing_node :: proc(renderer: ^Renderer, node: ^Post_Processing destroy :: proc(renderer: ^Renderer) { delete_mesh(renderer, &renderer.default_cube_mesh) - delete_mesh(renderer, &renderer.default_quad_mesh) + delete_mesh(renderer, &renderer.default_quad_world_mesh) delete_mesh(renderer, &renderer.default_sphere_mesh) when RENDER_BACKEND_OPENGL { diff --git a/renderer_backend_opengl_windows.odin b/renderer_backend_opengl_windows.odin index 5476f68..e991319 100644 --- a/renderer_backend_opengl_windows.odin +++ b/renderer_backend_opengl_windows.odin @@ -696,6 +696,21 @@ when RENDER_BACKEND_OPENGL { return true } + opengl_set_shader_uniform_vector2 :: proc(program: ^Shader_Program, uniform: Uniform_Vector2) -> bool { + opengl_activate_shader_program(program) + + loc := gl.GetUniformLocation(program.backend.handle, fmt.ctprintf("%v", uniform.name)) + if loc < 0 { + fmt.printfln("vector2 Loc: %v", loc) + return false + } + + v := transmute([2]f32)uniform.value + gl.Uniform2fv(loc, 1, &v[0]) + + return true + } + opengl_set_shader_uniform_vector3 :: proc(program: ^Shader_Program, uniform: Uniform_Vector3) -> bool { opengl_activate_shader_program(program) diff --git a/shader.odin b/shader.odin index c608a4a..ee0683f 100644 --- a/shader.odin +++ b/shader.odin @@ -134,6 +134,8 @@ set_shader_uniforms :: proc(program: ^Shader_Program, uniforms: []Uniform) { 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_Vector2: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (vector2) '%v' in program (vs: '%s', fs: '%s').", t.name, vs_path, fs_path) }} + case Uniform_Vector2_Pointer: { if !set_shader_uniform(program, t) { fmt.printfln("Failed to set uniform (vector2 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) }} @@ -150,6 +152,8 @@ set_shader_uniform :: proc { // TODO: SS - Improve setting shader uniforms. A bi set_shader_uniform_float_pointer, set_shader_uniform_matrix4f32, set_shader_uniform_matrix4f32_pointer, + set_shader_uniform_vector2, + set_shader_uniform_vector2_pointer, set_shader_uniform_vector3, set_shader_uniform_vector3_pointer, set_shader_uniform_vector4, @@ -208,13 +212,31 @@ set_shader_uniform_matrix4f32 :: proc(program: ^Shader_Program, uniform: Uniform return false } +set_shader_uniform_vector2_pointer :: proc(program: ^Shader_Program, uniform: Uniform_Vector2_Pointer) -> bool { + if uniform.value == nil { + return false + } + return set_shader_uniform(program, Uniform_Vector2 { uniform.name, uniform.value^ }) +} +set_shader_uniform_vector2 :: proc(program: ^Shader_Program, uniform: Uniform_Vector2) -> 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_vector2(program, uniform) + } + + return false +} + set_shader_uniform_vector3_pointer :: proc(program: ^Shader_Program, uniform: Uniform_Vector3_Pointer) -> bool { if uniform.value == nil { 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) @@ -234,7 +256,6 @@ set_shader_uniform_vector4_pointer :: proc(program: ^Shader_Program, uniform: Un } 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)