renderer/opengl: create ubos

This commit is contained in:
Mitchell Hashimoto
2023-11-17 09:32:52 -08:00
parent 3502db0f5f
commit 1fedc912f0
4 changed files with 85 additions and 44 deletions

View File

@ -7,26 +7,22 @@ const glad = @import("glad.zig");
id: c.GLuint, id: c.GLuint,
/// Enum for possible binding targets. /// Create a single buffer.
pub const Target = enum(c_uint) { pub fn create() !Buffer {
ArrayBuffer = c.GL_ARRAY_BUFFER, var vbo: c.GLuint = undefined;
ElementArrayBuffer = c.GL_ELEMENT_ARRAY_BUFFER, glad.context.GenBuffers.?(1, &vbo);
_, return Buffer{ .id = vbo };
}; }
/// Enum for possible buffer usages. /// glBindBuffer
pub const Usage = enum(c_uint) { pub fn bind(v: Buffer, target: Target) !Binding {
StreamDraw = c.GL_STREAM_DRAW, glad.context.BindBuffer.?(@intFromEnum(target), v.id);
StreamRead = c.GL_STREAM_READ, return Binding{ .target = target };
StreamCopy = c.GL_STREAM_COPY, }
StaticDraw = c.GL_STATIC_DRAW,
StaticRead = c.GL_STATIC_READ, pub fn destroy(v: Buffer) void {
StaticCopy = c.GL_STATIC_COPY, glad.context.DeleteBuffers.?(1, &v.id);
DynamicDraw = c.GL_DYNAMIC_DRAW, }
DynamicRead = c.GL_DYNAMIC_READ,
DynamicCopy = c.GL_DYNAMIC_COPY,
_,
};
/// Binding is a bound buffer. By using this for functions that operate /// Binding is a bound buffer. By using this for functions that operate
/// on bound buffers, you can easily defer unbinding and in safety-enabled /// on bound buffers, you can easily defer unbinding and in safety-enabled
@ -42,7 +38,12 @@ pub const Binding = struct {
usage: Usage, usage: Usage,
) !void { ) !void {
const info = dataInfo(&data); const info = dataInfo(&data);
glad.context.BufferData.?(@intFromEnum(b.target), info.size, info.ptr, @intFromEnum(usage)); glad.context.BufferData.?(
@intFromEnum(b.target),
info.size,
info.ptr,
@intFromEnum(usage),
);
try errors.getError(); try errors.getError();
} }
@ -54,7 +55,12 @@ pub const Binding = struct {
data: anytype, data: anytype,
) !void { ) !void {
const info = dataInfo(data); const info = dataInfo(data);
glad.context.BufferSubData.?(@intFromEnum(b.target), @intCast(offset), info.size, info.ptr); glad.context.BufferSubData.?(
@intFromEnum(b.target),
@intCast(offset),
info.size,
info.ptr,
);
try errors.getError(); try errors.getError();
} }
@ -66,7 +72,12 @@ pub const Binding = struct {
comptime T: type, comptime T: type,
usage: Usage, usage: Usage,
) !void { ) !void {
glad.context.BufferData.?(@intFromEnum(b.target), @sizeOf(T), null, @intFromEnum(usage)); glad.context.BufferData.?(
@intFromEnum(b.target),
@sizeOf(T),
null,
@intFromEnum(usage),
);
try errors.getError(); try errors.getError();
} }
@ -76,7 +87,12 @@ pub const Binding = struct {
size: usize, size: usize,
usage: Usage, usage: Usage,
) !void { ) !void {
glad.context.BufferData.?(@intFromEnum(b.target), @intCast(size), null, @intFromEnum(usage)); glad.context.BufferData.?(
@intFromEnum(b.target),
@intCast(size),
null,
@intFromEnum(usage),
);
try errors.getError(); try errors.getError();
} }
@ -199,19 +215,24 @@ pub const Binding = struct {
} }
}; };
/// Create a single buffer. /// Enum for possible binding targets.
pub fn create() !Buffer { pub const Target = enum(c_uint) {
var vbo: c.GLuint = undefined; array = c.GL_ARRAY_BUFFER,
glad.context.GenBuffers.?(1, &vbo); element_array = c.GL_ELEMENT_ARRAY_BUFFER,
return Buffer{ .id = vbo }; uniform = c.GL_UNIFORM_BUFFER,
} _,
};
/// glBindBuffer /// Enum for possible buffer usages.
pub fn bind(v: Buffer, target: Target) !Binding { pub const Usage = enum(c_uint) {
glad.context.BindBuffer.?(@intFromEnum(target), v.id); stream_draw = c.GL_STREAM_DRAW,
return Binding{ .target = target }; stream_read = c.GL_STREAM_READ,
} stream_copy = c.GL_STREAM_COPY,
static_draw = c.GL_STATIC_DRAW,
pub fn destroy(v: Buffer) void { static_read = c.GL_STATIC_READ,
glad.context.DeleteBuffers.?(1, &v.id); static_copy = c.GL_STATIC_COPY,
} dynamic_draw = c.GL_DYNAMIC_DRAW,
dynamic_read = c.GL_DYNAMIC_READ,
dynamic_copy = c.GL_DYNAMIC_COPY,
_,
};

View File

@ -1480,7 +1480,7 @@ fn drawCells(
try binding.setDataNullManual( try binding.setDataNullManual(
@sizeOf(CellProgram.Cell) * cells.capacity, @sizeOf(CellProgram.Cell) * cells.capacity,
.StaticDraw, .static_draw,
); );
self.gl_cells_size = cells.capacity; self.gl_cells_size = cells.capacity;

View File

@ -88,17 +88,17 @@ pub fn init() !CellProgram {
// Element buffer (EBO) // Element buffer (EBO)
const ebo = try gl.Buffer.create(); const ebo = try gl.Buffer.create();
errdefer ebo.destroy(); errdefer ebo.destroy();
var ebobind = try ebo.bind(.ElementArrayBuffer); var ebobind = try ebo.bind(.element_array);
defer ebobind.unbind(); defer ebobind.unbind();
try ebobind.setData([6]u8{ try ebobind.setData([6]u8{
0, 1, 3, // Top-left triangle 0, 1, 3, // Top-left triangle
1, 2, 3, // Bottom-right triangle 1, 2, 3, // Bottom-right triangle
}, .StaticDraw); }, .static_draw);
// Vertex buffer (VBO) // Vertex buffer (VBO)
const vbo = try gl.Buffer.create(); const vbo = try gl.Buffer.create();
errdefer vbo.destroy(); errdefer vbo.destroy();
var vbobind = try vbo.bind(.ArrayBuffer); var vbobind = try vbo.bind(.array);
defer vbobind.unbind(); defer vbobind.unbind();
var offset: usize = 0; var offset: usize = 0;
try vbobind.attributeAdvanced(0, 2, gl.c.GL_UNSIGNED_SHORT, false, @sizeOf(Cell), offset); try vbobind.attributeAdvanced(0, 2, gl.c.GL_UNSIGNED_SHORT, false, @sizeOf(Cell), offset);
@ -148,10 +148,10 @@ pub fn bind(self: CellProgram) !Binding {
const vao = try self.vao.bind(); const vao = try self.vao.bind();
errdefer vao.unbind(); errdefer vao.unbind();
const ebo = try self.ebo.bind(.ElementArrayBuffer); const ebo = try self.ebo.bind(.element_array);
errdefer ebo.unbind(); errdefer ebo.unbind();
const vbo = try self.vbo.bind(.ArrayBuffer); const vbo = try self.vbo.bind(.array);
errdefer vbo.unbind(); errdefer vbo.unbind();
return .{ return .{

View File

@ -7,6 +7,19 @@ const gl = @import("opengl");
program: gl.Program, program: gl.Program,
pub const Uniforms = extern struct {
resolution: [3]f32 align(16),
time: f32 align(4),
time_delta: f32 align(4),
frame_rate: f32 align(4),
frame: i32 align(4),
channel_time: [4][4]f32 align(16),
channel_resolution: [4][4]f32 align(16),
mouse: [4]f32 align(16),
date: [4]f32 align(16),
sample_rate: f32 align(4),
};
pub fn createList(alloc: Allocator, srcs: []const [:0]const u8) ![]const CustomProgram { pub fn createList(alloc: Allocator, srcs: []const [:0]const u8) ![]const CustomProgram {
var programs = std.ArrayList(CustomProgram).init(alloc); var programs = std.ArrayList(CustomProgram).init(alloc);
defer programs.deinit(); defer programs.deinit();
@ -26,6 +39,13 @@ pub fn init(src: [:0]const u8) !CustomProgram {
); );
errdefer program.destroy(); errdefer program.destroy();
// Create our uniform buffer that is shared across all custom shaders
const ubo = try gl.Buffer.create();
errdefer ubo.destroy();
var ubobind = try ubo.bind(.uniform);
defer ubobind.unbind();
try ubobind.setDataNull(Uniforms, .static_draw);
return .{ return .{
.program = program, .program = program,
}; };