diff --git a/src/TextRenderer.zig b/src/TextRenderer.zig index 41871900c..f93a6ef7a 100644 --- a/src/TextRenderer.zig +++ b/src/TextRenderer.zig @@ -55,22 +55,22 @@ pub fn init(alloc: std.mem.Allocator) !TextRenderer { // Generate the texture const tex = try gl.Texture.create(); - var binding = try tex.bind(gl.c.GL_TEXTURE_2D); + var binding = try tex.bind(.@"2D"); defer binding.unbind(); try binding.image2D( 0, - gl.c.GL_RED, + .Red, @intCast(c_int, face.*.glyph.*.bitmap.width), @intCast(c_int, face.*.glyph.*.bitmap.rows), 0, - gl.c.GL_RED, - gl.c.GL_UNSIGNED_BYTE, + .Red, + .UnsignedByte, face.*.glyph.*.bitmap.buffer, ); - try binding.parameter(gl.c.GL_TEXTURE_WRAP_S, gl.c.GL_CLAMP_TO_EDGE); - try binding.parameter(gl.c.GL_TEXTURE_WRAP_T, gl.c.GL_CLAMP_TO_EDGE); - try binding.parameter(gl.c.GL_TEXTURE_MIN_FILTER, gl.c.GL_LINEAR); - try binding.parameter(gl.c.GL_TEXTURE_MAG_FILTER, gl.c.GL_LINEAR); + try binding.parameter(.WrapS, gl.c.GL_CLAMP_TO_EDGE); + try binding.parameter(.WrapT, gl.c.GL_CLAMP_TO_EDGE); + try binding.parameter(.MinFilter, gl.c.GL_LINEAR); + try binding.parameter(.MagFilter, gl.c.GL_LINEAR); // Store the character chars.appendAssumeCapacity(.{ @@ -91,8 +91,8 @@ pub fn init(alloc: std.mem.Allocator) !TextRenderer { const vao = try gl.VertexArray.create(); const vbo = try gl.Buffer.create(); try vao.bind(); - var binding = try vbo.bind(gl.c.GL_ARRAY_BUFFER); - try binding.setDataType([6 * 4]f32, gl.c.GL_DYNAMIC_DRAW); + var binding = try vbo.bind(.ArrayBuffer); + try binding.setDataNull([6 * 4]f32, .DynamicDraw); try binding.enableVertexAttribArray(0); try binding.vertexAttribPointer(0, 4, gl.c.GL_FLOAT, false, 4 * @sizeOf(f32), null); binding.unbind(); @@ -179,9 +179,9 @@ pub fn render( .{ xpos + w, ypos + h, 1.0, 0.0 }, }; - var texbind = try char.tex.bind(gl.c.GL_TEXTURE_2D); + var texbind = try char.tex.bind(.@"2D"); defer texbind.unbind(); - var bind = try self.vbo.bind(gl.c.GL_ARRAY_BUFFER); + var bind = try self.vbo.bind(.ArrayBuffer); try bind.setSubData(0, vert); bind.unbind(); diff --git a/src/opengl/Buffer.zig b/src/opengl/Buffer.zig index 31102cc5f..1104dcf9a 100644 --- a/src/opengl/Buffer.zig +++ b/src/opengl/Buffer.zig @@ -6,21 +6,41 @@ const errors = @import("errors.zig"); id: c.GLuint, +/// Enum for possible binding targets. +pub const Target = enum(c_uint) { + ArrayBuffer = c.GL_ARRAY_BUFFER, + _, +}; + +/// 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, + _, +}; + /// Binding is a bound buffer. By using this for functions that operate /// on bound buffers, you can easily defer unbinding and in safety-enabled /// modes verify that unbound buffers are never accessed. pub const Binding = struct { - target: c.GLenum, + target: Target, /// Sets the data of this bound buffer. The data can be any array-like /// type. The size of the data is automatically determined based on the type. pub inline fn setData( b: Binding, data: anytype, - usage: c.GLenum, + usage: Usage, ) !void { const info = dataInfo(data); - c.glBufferData(b.target, info.size, info.ptr, usage); + c.glBufferData(@enumToInt(b.target), info.size, info.ptr, @enumToInt(usage)); try errors.getError(); } @@ -32,19 +52,19 @@ pub const Binding = struct { data: anytype, ) !void { const info = dataInfo(data); - c.glBufferSubData(b.target, @intCast(c_long, offset), info.size, info.ptr); + c.glBufferSubData(@enumToInt(b.target), @intCast(c_long, offset), info.size, info.ptr); try errors.getError(); } /// Sets the buffer data with a null buffer that is expected to be /// filled in the future using subData. This requires the type just so /// we can setup the data size. - pub inline fn setDataType( + pub inline fn setDataNull( b: Binding, comptime T: type, - usage: c.GLenum, + usage: Usage, ) !void { - c.glBufferData(b.target, @sizeOf(T), null, usage); + c.glBufferData(@enumToInt(b.target), @sizeOf(T), null, @enumToInt(usage)); try errors.getError(); } @@ -97,7 +117,7 @@ pub const Binding = struct { } pub inline fn unbind(b: *Binding) void { - c.glBindBuffer(b.target, 0); + c.glBindBuffer(@enumToInt(b.target), 0); b.* = undefined; } }; @@ -110,8 +130,8 @@ pub inline fn create() !Buffer { } /// glBindBuffer -pub inline fn bind(v: Buffer, target: c.GLenum) !Binding { - c.glBindBuffer(target, v.id); +pub inline fn bind(v: Buffer, target: Target) !Binding { + c.glBindBuffer(@enumToInt(target), v.id); return Binding{ .target = target }; } diff --git a/src/opengl/Texture.zig b/src/opengl/Texture.zig index eafb8979b..566d54a4e 100644 --- a/src/opengl/Texture.zig +++ b/src/opengl/Texture.zig @@ -10,21 +10,83 @@ pub inline fn active(target: c.GLenum) !void { c.glActiveTexture(target); } +/// Enun for possible texture binding targets. +pub const Target = enum(c_uint) { + @"1D" = c.GL_TEXTURE_1D, + @"2D" = c.GL_TEXTURE_2D, + @"3D" = c.GL_TEXTURE_3D, + @"1DArray" = c.GL_TEXTURE_1D_ARRAY, + @"2DArray" = c.GL_TEXTURE_2D_ARRAY, + Rectangle = c.GL_TEXTURE_RECTANGLE, + CubeMap = c.GL_TEXTURE_CUBE_MAP, + Buffer = c.GL_TEXTURE_BUFFER, + @"2DMultisample" = c.GL_TEXTURE_2D_MULTISAMPLE, + @"2DMultisampleArray" = c.GL_TEXTURE_2D_MULTISAMPLE_ARRAY, +}; + +/// Enum for possible texture parameters. +pub const Parameter = enum(c_uint) { + BaseLevel = c.GL_TEXTURE_BASE_LEVEL, + CompareFunc = c.GL_TEXTURE_COMPARE_FUNC, + CompareMode = c.GL_TEXTURE_COMPARE_MODE, + LodBias = c.GL_TEXTURE_LOD_BIAS, + MinFilter = c.GL_TEXTURE_MIN_FILTER, + MagFilter = c.GL_TEXTURE_MAG_FILTER, + MinLod = c.GL_TEXTURE_MIN_LOD, + MaxLod = c.GL_TEXTURE_MAX_LOD, + MaxLevel = c.GL_TEXTURE_MAX_LEVEL, + SwizzleR = c.GL_TEXTURE_SWIZZLE_R, + SwizzleG = c.GL_TEXTURE_SWIZZLE_G, + SwizzleB = c.GL_TEXTURE_SWIZZLE_B, + SwizzleA = c.GL_TEXTURE_SWIZZLE_A, + WrapS = c.GL_TEXTURE_WRAP_S, + WrapT = c.GL_TEXTURE_WRAP_T, + WrapR = c.GL_TEXTURE_WRAP_R, +}; + +/// Internal format enum for texture images. +pub const InternalFormat = enum(c_int) { + Red = c.GL_RED, + + // There are so many more that I haven't filled in. + _, +}; + +/// Format for texture images +pub const Format = enum(c_uint) { + Red = c.GL_RED, + + // There are so many more that I haven't filled in. + _, +}; + +/// Data type for texture images. +pub const DataType = enum(c_uint) { + UnsignedByte = c.GL_UNSIGNED_BYTE, + + // There are so many more that I haven't filled in. + _, +}; + pub const Binding = struct { - target: c.GLenum, + target: Target, pub inline fn unbind(b: *Binding) void { - c.glBindTexture(b.target, 0); + c.glBindTexture(@enumToInt(b.target), 0); b.* = undefined; } pub fn generateMipmap(b: Binding) void { - c.glGenerateMipmap(b.target); + c.glGenerateMipmap(@enumToInt(b.target)); } - pub fn parameter(b: Binding, name: c.GLenum, value: anytype) !void { + pub fn parameter(b: Binding, name: Parameter, value: anytype) !void { switch (@TypeOf(value)) { - c.GLint => c.glTexParameteri(b.target, name, value), + c.GLint => c.glTexParameteri( + @enumToInt(b.target), + @enumToInt(name), + value, + ), else => unreachable, } } @@ -32,23 +94,23 @@ pub const Binding = struct { pub fn image2D( b: Binding, level: c.GLint, - internal_format: c.GLint, + internal_format: InternalFormat, width: c.GLsizei, height: c.GLsizei, border: c.GLint, - format: c.GLenum, - typ: c.GLenum, + format: Format, + typ: DataType, data: ?*const anyopaque, ) !void { c.glTexImage2D( - b.target, + @enumToInt(b.target), level, - internal_format, + @enumToInt(internal_format), width, height, border, - format, - typ, + @enumToInt(format), + @enumToInt(typ), data, ); } @@ -62,8 +124,8 @@ pub inline fn create() !Texture { } /// glBindTexture -pub inline fn bind(v: Texture, target: c.GLenum) !Binding { - c.glBindTexture(target, v.id); +pub inline fn bind(v: Texture, target: Target) !Binding { + c.glBindTexture(@enumToInt(target), v.id); return Binding{ .target = target }; }