1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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)
}