Harbor

branch main
showing the latest snapshot on main
gl_frame.odin 2.5 KB · Plain text
backend/opengl/gl_frame.odin 0644 Raw
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..<fb.color_count {
			clear := desc.clear_colors[i] if desc.color_count > 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)
}