package renderer import "core:math/linalg" import "core:fmt" import "core:log" RENDER_BACKEND_OPENGL :: #config(RENDER_BACKEND_OPENGL, false) RENDER_BACKEND_VULKAN :: #config(RENDER_BACKEND_VULKAN, false) RENDER_BACKEND_DIRECTX11 :: #config(RENDER_BACKEND_DIRECTX11, false) RENDER_BACKEND_METAL :: #config(RENDER_BACKEND_METAL, false) Renderer :: struct { viewport: Viewport, surface_ptr: rawptr, backend: rawptr, pipeline: Pipeline, active_camera: ^Camera, } Viewport :: struct { x, y, width, height: u16, } get_aspect_ratio :: proc(renderer: ^Renderer) -> f32 { assert(renderer != nil) viewport := &renderer.viewport return f32(viewport.width) / f32(viewport.height) } RGB_Color :: [3]u8 RGBA_Color :: [4]u8 create :: proc(surface_ptr: rawptr) -> (^Renderer, bool) { renderer := new(Renderer) renderer.surface_ptr = surface_ptr when RENDER_BACKEND_OPENGL { if !opengl_init(renderer) { fmt.printfln("Failed to initialize OpenGL.") destroy(renderer) return nil, false } } else { destroy(renderer) fmt.printfln("Unhandled backend or no backend selected.") return nil, false } return renderer, true } set_viewport :: proc(renderer: ^Renderer, x, y, width, height: u16) { log.infof("Setting viewport to %v:%v, %vx%v.", x, y, width, height) renderer.viewport = { x = x, y = y, width = width, height = height, } when RENDER_BACKEND_OPENGL { opengl_viewport_changed(renderer) } } @(private="file") set_clear_color :: proc(renderer: ^Renderer, color: RGB_Color) { when RENDER_BACKEND_OPENGL { opengl_set_clear_color(renderer, color) } } @(private="file") clear_screen :: proc(renderer: ^Renderer, clear_depth: bool) { when RENDER_BACKEND_OPENGL { opengl_clear_screen(renderer, clear_depth) } } render_frame :: proc(renderer: ^Renderer) { if renderer.active_camera == nil { fmt.printfln("No active camera!") return } view_matrix, view_matrix_ok := get_camera_view_matrix(renderer.active_camera) assert(view_matrix_ok) projection_matrix, projection_matrix_ok := get_camera_projection_matrix(renderer, renderer.active_camera) assert(projection_matrix_ok) pipeline := &renderer.pipeline for i in 0 ..< pipeline.amount_of_passes { pass := pipeline.passes[i] set_clear_color(renderer, pass.clear_color) clear_screen(renderer, pass.should_clear_depth) enable_depth_testing(renderer, pass.should_test_depth) for i in 0..