diff --git a/src/main.zig b/src/main.zig index 12454c6e5..cc0f1478c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -50,11 +50,11 @@ pub fn main() !void { 0.5, -0.5, 0.0, // right 0.0, 0.5, 0.0, // top }; - var vao: c_uint = undefined; + const vao = try gl.VertexArray.create(); + defer vao.destroy(); var vbo: c_uint = undefined; - c.glGenVertexArrays(1, &vao); c.glGenBuffers(1, &vbo); - c.glBindVertexArray(vao); + try vao.bind(); c.glBindBuffer(c.GL_ARRAY_BUFFER, vbo); c.glBufferData( @@ -83,8 +83,8 @@ pub fn main() !void { c.glClearColor(0.2, 0.3, 0.3, 1.0); c.glClear(c.GL_COLOR_BUFFER_BIT); - c.glUseProgram(program.id); - c.glBindVertexArray(vao); + try program.use(); + try vao.bind(); c.glDrawArrays(c.GL_TRIANGLES, 0, 3); // const pos = try window.getCursorPos(); diff --git a/src/opengl.zig b/src/opengl.zig index 185d3ce77..65dc2284b 100644 --- a/src/opengl.zig +++ b/src/opengl.zig @@ -1,3 +1,14 @@ +//! OpenGL bindings. +//! +//! These are pupose-built for usage within this program. While they closely +//! align with the OpenGL C APIs, they aren't meant to be general purpose. +//! Certain use cases will CERTAINLY be sub-optimal by using these helpers +//! and should use the C API directly. +//! +//! For performance-intensive or unsupported aspects of OpenGL, the C +//! API is exposed via the `c` constant. + pub const c = @import("opengl/c.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/Program.zig b/src/opengl/Program.zig index d30a5ccbd..44c2e9835 100644 --- a/src/opengl/Program.zig +++ b/src/opengl/Program.zig @@ -10,7 +10,7 @@ const errors = @import("errors.zig"); id: c.GLuint, -pub fn create() !Program { +pub inline fn create() !Program { const id = c.glCreateProgram(); if (id == 0) try errors.mustError(); @@ -18,12 +18,12 @@ pub fn create() !Program { return Program{ .id = id }; } -pub fn attachShader(p: Program, s: Shader) !void { +pub inline fn attachShader(p: Program, s: Shader) !void { c.glAttachShader(p.id, s.id); try errors.getError(); } -pub fn link(p: Program) !void { +pub inline fn link(p: Program) !void { c.glLinkProgram(p.id); // Check if linking succeeded @@ -41,19 +41,23 @@ pub fn link(p: Program) !void { return error.CompileFailed; } +pub inline fn use(p: Program) !void { + c.glUseProgram(p.id); +} + /// getInfoLog returns the info log for this program. This attempts to /// keep the log fully stack allocated and is therefore limited to a max /// amount of elements. // // NOTE(mitchellh): we can add a dynamic version that uses an allocator // if we ever need it. -pub fn getInfoLog(s: Program) [512]u8 { +pub inline fn getInfoLog(s: Program) [512]u8 { var msg: [512]u8 = undefined; c.glGetProgramInfoLog(s.id, msg.len, null, &msg); return msg; } -pub fn destroy(p: Program) void { +pub inline fn destroy(p: Program) void { assert(p.id != 0); c.glDeleteProgram(p.id); log.debug("program destroyed id={}", .{p.id}); diff --git a/src/opengl/Shader.zig b/src/opengl/Shader.zig index 5809141e1..1d6696dcc 100644 --- a/src/opengl/Shader.zig +++ b/src/opengl/Shader.zig @@ -9,7 +9,7 @@ const errors = @import("errors.zig"); id: c.GLuint, -pub fn create(typ: c.GLenum) errors.Error!Shader { +pub inline fn create(typ: c.GLenum) errors.Error!Shader { const id = c.glCreateShader(typ); if (id == 0) { try errors.mustError(); @@ -21,7 +21,7 @@ pub fn create(typ: c.GLenum) errors.Error!Shader { } /// Set the source and compile a shader. -pub fn setSourceAndCompile(s: Shader, source: [:0]const u8) !void { +pub inline fn setSourceAndCompile(s: Shader, source: [:0]const u8) !void { c.glShaderSource(s.id, 1, &@ptrCast([*c]const u8, source), null); c.glCompileShader(s.id); @@ -42,13 +42,13 @@ pub fn setSourceAndCompile(s: Shader, source: [:0]const u8) !void { // // NOTE(mitchellh): we can add a dynamic version that uses an allocator // if we ever need it. -pub fn getInfoLog(s: Shader) [512]u8 { +pub inline fn getInfoLog(s: Shader) [512]u8 { var msg: [512]u8 = undefined; c.glGetShaderInfoLog(s.id, msg.len, null, &msg); return msg; } -pub fn destroy(s: Shader) void { +pub inline fn destroy(s: Shader) void { assert(s.id != 0); c.glDeleteShader(s.id); log.debug("shader destroyed id={}", .{s.id}); diff --git a/src/opengl/VertexArray.zig b/src/opengl/VertexArray.zig new file mode 100644 index 000000000..b78212013 --- /dev/null +++ b/src/opengl/VertexArray.zig @@ -0,0 +1,21 @@ +const VertexArray = @This(); + +const c = @import("c.zig"); + +id: c.GLuint, + +/// Create a single vertex array object. +pub inline fn create() !VertexArray { + var vao: c.GLuint = undefined; + c.glGenVertexArrays(1, &vao); + return VertexArray{ .id = vao }; +} + +/// glBindVertexArray +pub inline fn bind(v: VertexArray) !void { + c.glBindVertexArray(v.id); +} + +pub inline fn destroy(v: VertexArray) void { + c.glDeleteVertexArrays(1, &v.id); +}