package opengl_backend import "core:log" import gl "vendor:OpenGL" import bk ".." begin_frame_opengl :: proc(clear_color: [4]f32) -> (bk.Frame_Context, bool) { if g_gl == nil { log.error("gpu/opengl: begin_frame before backend init") return {}, false } make_gl_context_current(&g_gl.gl_ctx) g_gl.frame_active = true return {frame_index = g_gl.current_frame}, true } end_frame_opengl :: proc(ctx: bk.Frame_Context) -> bool { if g_gl == nil do return false if !swap_gl_context(&g_gl.gl_ctx) { log.error("gpu/opengl: swap buffers failed") } g_gl.frame_active = false g_gl.current_frame = (g_gl.current_frame + 1) % bk.MAX_FRAMES_IN_FLIGHT return false } begin_default_pass_opengl :: proc(ctx: bk.Frame_Context, clear_color: [4]f32) { if g_gl == nil do return gl.BindFramebuffer(gl.FRAMEBUFFER, 0) gl.Viewport(0, 0, i32(g_gl.width), i32(g_gl.height)) gl.ClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]) gl.ClearDepth(1.0) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) g_gl.render_pass_active = true } begin_render_pass_opengl :: proc(ctx: bk.Frame_Context, desc: bk.Render_Pass_Begin_Desc) { if desc.framebuffer == bk.NULL_FRAMEBUFFER { begin_default_pass_opengl(ctx, desc.clear_color) return } fb, fb_ok := framebuffer_entry(desc.framebuffer) if !fb_ok { log.error("gpu/opengl: invalid framebuffer") return } gl.BindFramebuffer(gl.FRAMEBUFFER, fb.id) gl.Viewport(0, 0, i32(desc.width), i32(desc.height)) gl.ClearDepth(f64(desc.clear_depth)) gl.ClearStencil(i32(desc.clear_stencil)) mask := u32(0) pass, pass_ok := render_pass_entry(desc.pass) if pass_ok { if pass.desc.has_depth do mask |= gl.DEPTH_BUFFER_BIT if pass.desc.has_stencil do mask |= gl.STENCIL_BUFFER_BIT } else { mask = gl.DEPTH_BUFFER_BIT } if fb.color_count > 0 { for i in 0.. 0 else desc.clear_color gl.ClearBufferfv(gl.COLOR, i32(i), &clear[0]) } } if mask & gl.STENCIL_BUFFER_BIT != 0 do gl.StencilMask(0xFF) if mask != 0 do gl.Clear(mask) g_gl.render_pass_active = true } end_render_pass_opengl :: proc(ctx: bk.Frame_Context) { if g_gl == nil do return g_gl.render_pass_active = false } set_viewport_opengl :: proc(ctx: bk.Frame_Context, x, y, w, h: f32) { gl.Viewport(i32(x), i32(y), i32(w), i32(h)) } set_scissor_opengl :: proc(ctx: bk.Frame_Context, x, y: i32, w, h: u32) { gl.Enable(gl.SCISSOR_TEST) gl.Scissor(x, y, i32(w), i32(h)) } set_depth_bias_opengl :: proc(ctx: bk.Frame_Context, constant, slope: f32) { gl.PolygonOffset(slope, constant) }