From f1cffea9448ac65735ccca35e49f5efe703117b6 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 1 Apr 2022 17:44:54 -0700 Subject: [PATCH] opengl: buffers --- src/main.zig | 18 ++++-------- src/opengl.zig | 1 + src/opengl/Buffer.zig | 56 ++++++++++++++++++++++++++++++++++++++ src/opengl/VertexArray.zig | 5 ++++ 4 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 src/opengl/Buffer.zig diff --git a/src/main.zig b/src/main.zig index cc0f1478c..69214a0ab 100644 --- a/src/main.zig +++ b/src/main.zig @@ -52,17 +52,11 @@ pub fn main() !void { }; const vao = try gl.VertexArray.create(); defer vao.destroy(); - var vbo: c_uint = undefined; - c.glGenBuffers(1, &vbo); + const vbo = try gl.Buffer.create(); + defer vbo.destroy(); try vao.bind(); - - c.glBindBuffer(c.GL_ARRAY_BUFFER, vbo); - c.glBufferData( - c.GL_ARRAY_BUFFER, - @as(isize, @sizeOf(@TypeOf(vertices))), - &vertices, - c.GL_STATIC_DRAW, - ); + try vbo.bind(c.GL_ARRAY_BUFFER); + try vbo.setData(c.GL_ARRAY_BUFFER, vertices[0..], c.GL_STATIC_DRAW); c.glVertexAttribPointer( 0, @@ -74,8 +68,8 @@ pub fn main() !void { ); c.glEnableVertexAttribArray(0); - c.glBindBuffer(c.GL_ARRAY_BUFFER, 0); - c.glBindVertexArray(0); + try gl.Buffer.unbind(c.GL_ARRAY_BUFFER); + try gl.VertexArray.unbind(); // Wait for the user to close the window. while (!window.shouldClose()) { diff --git a/src/opengl.zig b/src/opengl.zig index 65dc2284b..dbd5b39ad 100644 --- a/src/opengl.zig +++ b/src/opengl.zig @@ -9,6 +9,7 @@ //! API is exposed via the `c` constant. pub const c = @import("opengl/c.zig"); +pub const Buffer = @import("opengl/Buffer.zig"); pub const Program = @import("opengl/Program.zig"); pub const Shader = @import("opengl/Shader.zig"); pub const VertexArray = @import("opengl/VertexArray.zig"); diff --git a/src/opengl/Buffer.zig b/src/opengl/Buffer.zig new file mode 100644 index 000000000..21b134f58 --- /dev/null +++ b/src/opengl/Buffer.zig @@ -0,0 +1,56 @@ +const Buffer = @This(); + +const c = @import("c.zig"); +const errors = @import("errors.zig"); + +id: c.GLuint, + +/// Create a single buffer. +pub inline fn create() !Buffer { + var vbo: c.GLuint = undefined; + c.glGenBuffers(1, &vbo); + return Buffer{ .id = vbo }; +} + +// Unbind any active vertex array. +pub inline fn unbind(target: c.GLenum) !void { + c.glBindBuffer(target, 0); +} + +/// glBindBuffer +pub inline fn bind(v: Buffer, target: c.GLenum) !void { + c.glBindBuffer(target, v.id); +} + +pub inline fn setData( + v: Buffer, + target: c.GLenum, + data: []const f32, + usage: c.GLenum, +) !void { + // Maybe one day in debug mode we can validate that this buffer + // is currently bound. + _ = v; + + // Determine the per-element size. This is all comptime-computed. + const dataInfo = @typeInfo(@TypeOf(data)); + const size: usize = switch (dataInfo) { + .Pointer => |ptr| switch (ptr.size) { + .Slice => @sizeOf(ptr.child), + else => unreachable, + }, + else => unreachable, + }; + + c.glBufferData( + target, + @intCast(isize, size * data.len), + data.ptr, + usage, + ); + try errors.getError(); +} + +pub inline fn destroy(v: Buffer) void { + c.glDeleteBuffers(1, &v.id); +} diff --git a/src/opengl/VertexArray.zig b/src/opengl/VertexArray.zig index b78212013..718ec9b9f 100644 --- a/src/opengl/VertexArray.zig +++ b/src/opengl/VertexArray.zig @@ -11,6 +11,11 @@ pub inline fn create() !VertexArray { return VertexArray{ .id = vao }; } +// Unbind any active vertex array. +pub inline fn unbind() !void { + c.glBindVertexArray(0); +} + /// glBindVertexArray pub inline fn bind(v: VertexArray) !void { c.glBindVertexArray(v.id);