package renderer import "core:fmt" import os "core:os/os2" Shader :: struct { path: string, type: Shader_Type, backend: Shader_Backend, } Shader_Program :: struct { vertex_shader, fragment_shader: ^Shader, backend: Shader_Program_Backend, } Shader_Type :: enum { Vertex, Fragment, // .. } create_shader :: proc(renderer: ^Renderer, type: Shader_Type, path: string) -> (Shader, bool) { fmt.printfln("Creating shader") bytes, error := os.read_entire_file_from_path(path, context.allocator) if error != nil { return {}, false } defer delete(bytes) s: Shader s.type = type s.path = path when RENDER_BACKEND_OPENGL { shader_opengl, ok := opengl_create_shader(renderer, type, bytes) if !ok { return {}, false } s.backend = shader_opengl fmt.printfln("Backend id: %v", s.backend) } else { #assert(false) } return s, true } delete_shader :: proc(renderer: ^Renderer, shader: ^Shader) { assert(shader != nil) when RENDER_BACKEND_OPENGL { opengl_delete_shader(renderer, shader) } } create_shader_program :: proc(renderer: ^Renderer, vertex_shader, fragment_shader: ^Shader) -> (Shader_Program, bool) { assert(vertex_shader != nil) assert(fragment_shader != nil) p: Shader_Program p.vertex_shader = vertex_shader p.fragment_shader = fragment_shader when RENDER_BACKEND_OPENGL { program_opengl, ok := opengl_create_shader_program(renderer, vertex_shader, fragment_shader) if !ok { return {}, false } p.backend = program_opengl } else { #assert(false) } return p, true } delete_shader_program :: proc(renderer: ^Renderer, shader_program: ^Shader_Program) { assert(shader_program != nil) when RENDER_BACKEND_OPENGL { opengl_delete_shader_program(renderer, shader_program) } } reload_shader_program :: proc(renderer: ^Renderer, p: ^Shader_Program) -> bool { assert(renderer != nil) assert(p != nil) assert(p.vertex_shader != nil) assert(p.fragment_shader != nil) new_vs, vs_ok := create_shader(renderer, p.vertex_shader.type, p.vertex_shader.path) if !vs_ok { fmt.printfln("Failed to reload vertex shader") return false } new_fs, fs_ok := create_shader(renderer, p.fragment_shader.type, p.fragment_shader.path) if !fs_ok { fmt.printfln("Failed to reload fragment shader") delete_shader(renderer, &new_vs) return false } new_program, program_ok := create_shader_program(renderer, &new_vs, &new_fs) if !program_ok { fmt.printfln("Failed to relink shader program") delete_shader(renderer, &new_vs) delete_shader(renderer, &new_fs) return false } delete_shader_program(renderer, p) delete_shader(renderer, p.vertex_shader) delete_shader(renderer, p.fragment_shader) p.backend = new_program.backend p.vertex_shader^ = new_vs p.fragment_shader^ = new_fs return true }