This repository has no description
1const Framebuffer = @This();
2
3const std = @import("std");
4const c = @import("c.zig").c;
5const errors = @import("errors.zig");
6const glad = @import("glad.zig");
7const Texture = @import("Texture.zig");
8const Renderbuffer = @import("Renderbuffer.zig");
9
10id: c.GLuint,
11
12/// Create a single buffer.
13pub fn create() !Framebuffer {
14 var fbo: c.GLuint = undefined;
15 glad.context.GenFramebuffers.?(1, &fbo);
16 return .{ .id = fbo };
17}
18
19pub fn destroy(v: Framebuffer) void {
20 glad.context.DeleteFramebuffers.?(1, &v.id);
21}
22
23pub fn bind(v: Framebuffer, target: Target) !Binding {
24 // The default framebuffer is documented as being zero but
25 // on multiple OpenGL drivers its not zero, so we grab it
26 // at runtime.
27 var current: c.GLint = undefined;
28 glad.context.GetIntegerv.?(c.GL_FRAMEBUFFER_BINDING, ¤t);
29 glad.context.BindFramebuffer.?(@intFromEnum(target), v.id);
30 return .{ .target = target, .previous = @intCast(current) };
31}
32
33/// Enum for possible binding targets.
34pub const Target = enum(c_uint) {
35 framebuffer = c.GL_FRAMEBUFFER,
36 draw = c.GL_DRAW_FRAMEBUFFER,
37 read = c.GL_READ_FRAMEBUFFER,
38 _,
39};
40
41pub const Attachment = enum(c_uint) {
42 color0 = c.GL_COLOR_ATTACHMENT0,
43 depth = c.GL_DEPTH_ATTACHMENT,
44 stencil = c.GL_STENCIL_ATTACHMENT,
45 depth_stencil = c.GL_DEPTH_STENCIL_ATTACHMENT,
46 _,
47};
48
49pub const Status = enum(c_uint) {
50 complete = c.GL_FRAMEBUFFER_COMPLETE,
51 undefined = c.GL_FRAMEBUFFER_UNDEFINED,
52 incomplete_attachment = c.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
53 incomplete_missing_attachment = c.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
54 incomplete_draw_buffer = c.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER,
55 incomplete_read_buffer = c.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER,
56 unsupported = c.GL_FRAMEBUFFER_UNSUPPORTED,
57 incomplete_multisample = c.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
58 incomplete_layer_targets = c.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS,
59 _,
60};
61
62pub const Binding = struct {
63 target: Target,
64 previous: c.GLuint,
65
66 pub fn unbind(self: Binding) void {
67 glad.context.BindFramebuffer.?(
68 @intFromEnum(self.target),
69 self.previous,
70 );
71 }
72
73 pub fn texture2D(
74 self: Binding,
75 attachment: Attachment,
76 textarget: Texture.Target,
77 texture: Texture,
78 level: c.GLint,
79 ) !void {
80 glad.context.FramebufferTexture2D.?(
81 @intFromEnum(self.target),
82 @intFromEnum(attachment),
83 @intFromEnum(textarget),
84 texture.id,
85 level,
86 );
87 try errors.getError();
88 }
89
90 pub fn renderbuffer(
91 self: Binding,
92 attachment: Attachment,
93 buffer: Renderbuffer,
94 ) !void {
95 glad.context.FramebufferRenderbuffer.?(
96 @intFromEnum(self.target),
97 @intFromEnum(attachment),
98 c.GL_RENDERBUFFER,
99 buffer.id,
100 );
101 try errors.getError();
102 }
103
104 pub fn drawBuffers(
105 self: Binding,
106 bufs: []Attachment,
107 ) !void {
108 _ = self;
109 glad.context.DrawBuffers.?(@intCast(bufs.len), bufs.ptr);
110 try errors.getError();
111 }
112
113 pub fn checkStatus(self: Binding) Status {
114 return @enumFromInt(glad.context.CheckFramebufferStatus.?(@intFromEnum(self.target)));
115 }
116};