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,
/// Enum for possible binding targets.
pub const Target = enum(c_uint) {
ArrayBuffer = c.GL_ARRAY_BUFFER,
ElementArrayBuffer = c.GL_ELEMENT_ARRAY_BUFFER,
_,
};
/// Create a single buffer.
pub fn create() !Buffer {
var vbo: c.GLuint = undefined;
glad.context.GenBuffers.?(1, &vbo);
return Buffer{ .id = vbo };
}
/// Enum for possible buffer usages.
pub const Usage = enum(c_uint) {
StreamDraw = c.GL_STREAM_DRAW,
StreamRead = c.GL_STREAM_READ,
StreamCopy = c.GL_STREAM_COPY,
StaticDraw = c.GL_STATIC_DRAW,
StaticRead = c.GL_STATIC_READ,
StaticCopy = c.GL_STATIC_COPY,
DynamicDraw = c.GL_DYNAMIC_DRAW,
DynamicRead = c.GL_DYNAMIC_READ,
DynamicCopy = c.GL_DYNAMIC_COPY,
_,
};
/// glBindBuffer
pub fn bind(v: Buffer, target: Target) !Binding {
glad.context.BindBuffer.?(@intFromEnum(target), v.id);
return Binding{ .target = target };
}
pub fn destroy(v: Buffer) void {
glad.context.DeleteBuffers.?(1, &v.id);
}
/// Binding is a bound buffer. By using this for functions that operate
/// on bound buffers, you can easily defer unbinding and in safety-enabled
@ -42,7 +38,12 @@ pub const Binding = struct {
usage: Usage,
) !void {
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();
}
@ -54,7 +55,12 @@ pub const Binding = struct {
data: anytype,
) !void {
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();
}
@ -66,7 +72,12 @@ pub const Binding = struct {
comptime T: type,
usage: Usage,
) !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();
}
@ -76,7 +87,12 @@ pub const Binding = struct {
size: usize,
usage: Usage,
) !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();
}
@ -199,19 +215,24 @@ pub const Binding = struct {
}
};
/// Create a single buffer.
pub fn create() !Buffer {
var vbo: c.GLuint = undefined;
glad.context.GenBuffers.?(1, &vbo);
return Buffer{ .id = vbo };
}
/// Enum for possible binding targets.
pub const Target = enum(c_uint) {
array = c.GL_ARRAY_BUFFER,
element_array = c.GL_ELEMENT_ARRAY_BUFFER,
uniform = c.GL_UNIFORM_BUFFER,
_,
};
/// glBindBuffer
pub fn bind(v: Buffer, target: Target) !Binding {
glad.context.BindBuffer.?(@intFromEnum(target), v.id);
return Binding{ .target = target };
}
pub fn destroy(v: Buffer) void {
glad.context.DeleteBuffers.?(1, &v.id);
}
/// Enum for possible buffer usages.
pub const Usage = enum(c_uint) {
stream_draw = c.GL_STREAM_DRAW,
stream_read = c.GL_STREAM_READ,
stream_copy = c.GL_STREAM_COPY,
static_draw = c.GL_STATIC_DRAW,
static_read = c.GL_STATIC_READ,
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(
@sizeOf(CellProgram.Cell) * cells.capacity,
.StaticDraw,
.static_draw,
);
self.gl_cells_size = cells.capacity;

View File

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

View File

@ -7,6 +7,19 @@ const gl = @import("opengl");
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 {
var programs = std.ArrayList(CustomProgram).init(alloc);
defer programs.deinit();
@ -26,6 +39,13 @@ pub fn init(src: [:0]const u8) !CustomProgram {
);
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 .{
.program = program,
};