make opengl loader context-aware

This commit is contained in:
Mitchell Hashimoto 2022-10-23 19:39:02 -07:00
parent de9731da1f
commit 89a4c59f3c
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
12 changed files with 909 additions and 1559 deletions

View File

@ -242,12 +242,12 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo
// Culling, probably not necessary. We have to change the winding // Culling, probably not necessary. We have to change the winding
// order since our 0,0 is top-left. // order since our 0,0 is top-left.
gl.c.glEnable(gl.c.GL_CULL_FACE); try gl.enable(gl.c.GL_CULL_FACE);
gl.c.glFrontFace(gl.c.GL_CW); try gl.frontFace(gl.c.GL_CW);
// Blending for text // Blending for text
gl.c.glEnable(gl.c.GL_BLEND); try gl.enable(gl.c.GL_BLEND);
gl.c.glBlendFunc(gl.c.GL_SRC_ALPHA, gl.c.GL_ONE_MINUS_SRC_ALPHA); try gl.blendFunc(gl.c.GL_SRC_ALPHA, gl.c.GL_ONE_MINUS_SRC_ALPHA);
// The font size we desire along with the DPI determiend for the window // The font size we desire along with the DPI determiend for the window
const font_size: font.face.DesiredSize = .{ const font_size: font.face.DesiredSize = .{

View File

@ -3,6 +3,7 @@ const Buffer = @This();
const std = @import("std"); const std = @import("std");
const c = @import("c.zig"); const c = @import("c.zig");
const errors = @import("errors.zig"); const errors = @import("errors.zig");
const glad = @import("glad.zig");
id: c.GLuint, id: c.GLuint,
@ -41,7 +42,7 @@ pub const Binding = struct {
usage: Usage, usage: Usage,
) !void { ) !void {
const info = dataInfo(&data); const info = dataInfo(&data);
c.glBufferData(@enumToInt(b.target), info.size, info.ptr, @enumToInt(usage)); glad.context.BufferData.?(@enumToInt(b.target), info.size, info.ptr, @enumToInt(usage));
try errors.getError(); try errors.getError();
} }
@ -53,7 +54,7 @@ pub const Binding = struct {
data: anytype, data: anytype,
) !void { ) !void {
const info = dataInfo(data); const info = dataInfo(data);
c.glBufferSubData(@enumToInt(b.target), @intCast(c_long, offset), info.size, info.ptr); glad.context.BufferSubData.?(@enumToInt(b.target), @intCast(c_long, offset), info.size, info.ptr);
try errors.getError(); try errors.getError();
} }
@ -65,7 +66,7 @@ pub const Binding = struct {
comptime T: type, comptime T: type,
usage: Usage, usage: Usage,
) !void { ) !void {
c.glBufferData(@enumToInt(b.target), @sizeOf(T), null, @enumToInt(usage)); glad.context.BufferData.?(@enumToInt(b.target), @sizeOf(T), null, @enumToInt(usage));
try errors.getError(); try errors.getError();
} }
@ -75,7 +76,7 @@ pub const Binding = struct {
size: usize, size: usize,
usage: Usage, usage: Usage,
) !void { ) !void {
c.glBufferData(@enumToInt(b.target), @intCast(c_long, size), null, @enumToInt(usage)); glad.context.BufferData.?(@enumToInt(b.target), @intCast(c_long, size), null, @enumToInt(usage));
try errors.getError(); try errors.getError();
} }
@ -106,7 +107,7 @@ pub const Binding = struct {
} }
pub inline fn enableAttribArray(_: Binding, idx: c.GLuint) !void { pub inline fn enableAttribArray(_: Binding, idx: c.GLuint) !void {
c.glEnableVertexAttribArray(idx); glad.context.EnableVertexAttribArray.?(idx);
} }
/// Shorthand for vertexAttribPointer that is specialized towards the /// Shorthand for vertexAttribPointer that is specialized towards the
@ -153,7 +154,7 @@ pub const Binding = struct {
/// VertexAttribDivisor /// VertexAttribDivisor
pub fn attributeDivisor(_: Binding, idx: c.GLuint, divisor: c.GLuint) !void { pub fn attributeDivisor(_: Binding, idx: c.GLuint, divisor: c.GLuint) !void {
c.glVertexAttribDivisor(idx, divisor); glad.context.VertexAttribDivisor.?(idx, divisor);
try errors.getError(); try errors.getError();
} }
@ -172,7 +173,7 @@ pub const Binding = struct {
else else
null; null;
c.glVertexAttribPointer(idx, size, typ, normalized_c, stride, offsetPtr); glad.context.VertexAttribPointer.?(idx, size, typ, normalized_c, stride, offsetPtr);
try errors.getError(); try errors.getError();
} }
@ -189,12 +190,12 @@ pub const Binding = struct {
else else
null; null;
c.glVertexAttribIPointer(idx, size, typ, stride, offsetPtr); glad.context.VertexAttribIPointer.?(idx, size, typ, stride, offsetPtr);
try errors.getError(); try errors.getError();
} }
pub inline fn unbind(b: *Binding) void { pub inline fn unbind(b: *Binding) void {
c.glBindBuffer(@enumToInt(b.target), 0); glad.context.BindBuffer.?(@enumToInt(b.target), 0);
b.* = undefined; b.* = undefined;
} }
}; };
@ -202,16 +203,16 @@ pub const Binding = struct {
/// Create a single buffer. /// Create a single buffer.
pub inline fn create() !Buffer { pub inline fn create() !Buffer {
var vbo: c.GLuint = undefined; var vbo: c.GLuint = undefined;
c.glGenBuffers(1, &vbo); glad.context.GenBuffers.?(1, &vbo);
return Buffer{ .id = vbo }; return Buffer{ .id = vbo };
} }
/// glBindBuffer /// glBindBuffer
pub inline fn bind(v: Buffer, target: Target) !Binding { pub inline fn bind(v: Buffer, target: Target) !Binding {
c.glBindBuffer(@enumToInt(target), v.id); glad.context.BindBuffer.?(@enumToInt(target), v.id);
return Binding{ .target = target }; return Binding{ .target = target };
} }
pub inline fn destroy(v: Buffer) void { pub inline fn destroy(v: Buffer) void {
c.glDeleteBuffers(1, &v.id); glad.context.DeleteBuffers.?(1, &v.id);
} }

View File

@ -7,17 +7,18 @@ const log = std.log.scoped(.opengl);
const c = @import("c.zig"); const c = @import("c.zig");
const Shader = @import("Shader.zig"); const Shader = @import("Shader.zig");
const errors = @import("errors.zig"); const errors = @import("errors.zig");
const glad = @import("glad.zig");
id: c.GLuint, id: c.GLuint,
const Binding = struct { const Binding = struct {
pub inline fn unbind(_: Binding) void { pub inline fn unbind(_: Binding) void {
c.glUseProgram(0); glad.context.UseProgram.?(0);
} }
}; };
pub inline fn create() !Program { pub inline fn create() !Program {
const id = c.glCreateProgram(); const id = glad.context.CreateProgram.?();
if (id == 0) try errors.mustError(); if (id == 0) try errors.mustError();
log.debug("program created id={}", .{id}); log.debug("program created id={}", .{id});
@ -44,16 +45,16 @@ pub inline fn createVF(vsrc: [:0]const u8, fsrc: [:0]const u8) !Program {
} }
pub inline fn attachShader(p: Program, s: Shader) !void { pub inline fn attachShader(p: Program, s: Shader) !void {
c.glAttachShader(p.id, s.id); glad.context.AttachShader.?(p.id, s.id);
try errors.getError(); try errors.getError();
} }
pub inline fn link(p: Program) !void { pub inline fn link(p: Program) !void {
c.glLinkProgram(p.id); glad.context.LinkProgram.?(p.id);
// Check if linking succeeded // Check if linking succeeded
var success: c_int = undefined; var success: c_int = undefined;
c.glGetProgramiv(p.id, c.GL_LINK_STATUS, &success); glad.context.GetProgramiv.?(p.id, c.GL_LINK_STATUS, &success);
if (success == c.GL_TRUE) { if (success == c.GL_TRUE) {
log.debug("program linked id={}", .{p.id}); log.debug("program linked id={}", .{p.id});
return; return;
@ -67,7 +68,7 @@ pub inline fn link(p: Program) !void {
} }
pub inline fn use(p: Program) !Binding { pub inline fn use(p: Program) !Binding {
c.glUseProgram(p.id); glad.context.UseProgram.?(p.id);
return Binding{}; return Binding{};
} }
@ -77,7 +78,7 @@ pub inline fn setUniform(
n: [:0]const u8, n: [:0]const u8,
value: anytype, value: anytype,
) !void { ) !void {
const loc = c.glGetUniformLocation( const loc = glad.context.GetUniformLocation.?(
p.id, p.id,
@ptrCast([*c]const u8, n.ptr), @ptrCast([*c]const u8, n.ptr),
); );
@ -88,12 +89,12 @@ pub inline fn setUniform(
// Perform the correct call depending on the type of the value. // Perform the correct call depending on the type of the value.
switch (@TypeOf(value)) { switch (@TypeOf(value)) {
comptime_int => c.glUniform1i(loc, value), comptime_int => glad.context.Uniform1i.?(loc, value),
f32 => c.glUniform1f(loc, value), f32 => glad.context.Uniform1f.?(loc, value),
@Vector(2, f32) => c.glUniform2f(loc, value[0], value[1]), @Vector(2, f32) => glad.context.Uniform2f.?(loc, value[0], value[1]),
@Vector(3, f32) => c.glUniform3f(loc, value[0], value[1], value[2]), @Vector(3, f32) => glad.context.Uniform3f.?(loc, value[0], value[1], value[2]),
@Vector(4, f32) => c.glUniform4f(loc, value[0], value[1], value[2], value[3]), @Vector(4, f32) => glad.context.Uniform4f.?(loc, value[0], value[1], value[2], value[3]),
[4]@Vector(4, f32) => c.glUniformMatrix4fv( [4]@Vector(4, f32) => glad.context.UniformMatrix4fv.?(
loc, loc,
1, 1,
c.GL_FALSE, c.GL_FALSE,
@ -112,12 +113,12 @@ pub inline fn setUniform(
// if we ever need it. // if we ever need it.
pub inline fn getInfoLog(s: Program) [512]u8 { pub inline fn getInfoLog(s: Program) [512]u8 {
var msg: [512]u8 = undefined; var msg: [512]u8 = undefined;
c.glGetProgramInfoLog(s.id, msg.len, null, &msg); glad.context.GetProgramInfoLog.?(s.id, msg.len, null, &msg);
return msg; return msg;
} }
pub inline fn destroy(p: Program) void { pub inline fn destroy(p: Program) void {
assert(p.id != 0); assert(p.id != 0);
c.glDeleteProgram(p.id); glad.context.DeleteProgram.?(p.id);
log.debug("program destroyed id={}", .{p.id}); log.debug("program destroyed id={}", .{p.id});
} }

View File

@ -6,11 +6,12 @@ const log = std.log.scoped(.opengl);
const c = @import("c.zig"); const c = @import("c.zig");
const errors = @import("errors.zig"); const errors = @import("errors.zig");
const glad = @import("glad.zig");
id: c.GLuint, id: c.GLuint,
pub inline fn create(typ: c.GLenum) errors.Error!Shader { pub inline fn create(typ: c.GLenum) errors.Error!Shader {
const id = c.glCreateShader(typ); const id = glad.context.CreateShader.?(typ);
if (id == 0) { if (id == 0) {
try errors.mustError(); try errors.mustError();
unreachable; unreachable;
@ -22,12 +23,12 @@ pub inline fn create(typ: c.GLenum) errors.Error!Shader {
/// Set the source and compile a shader. /// Set the source and compile a shader.
pub inline 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); glad.context.ShaderSource.?(s.id, 1, &@ptrCast([*c]const u8, source), null);
c.glCompileShader(s.id); glad.context.CompileShader.?(s.id);
// Check if compilation succeeded // Check if compilation succeeded
var success: c_int = undefined; var success: c_int = undefined;
c.glGetShaderiv(s.id, c.GL_COMPILE_STATUS, &success); glad.context.GetShaderiv.?(s.id, c.GL_COMPILE_STATUS, &success);
if (success == c.GL_TRUE) return; if (success == c.GL_TRUE) return;
log.err("shader compilation failure id={} message={s}", .{ log.err("shader compilation failure id={} message={s}", .{
s.id, s.id,
@ -44,12 +45,12 @@ pub inline fn setSourceAndCompile(s: Shader, source: [:0]const u8) !void {
// if we ever need it. // if we ever need it.
pub inline fn getInfoLog(s: Shader) [512]u8 { pub inline fn getInfoLog(s: Shader) [512]u8 {
var msg: [512]u8 = undefined; var msg: [512]u8 = undefined;
c.glGetShaderInfoLog(s.id, msg.len, null, &msg); glad.context.GetShaderInfoLog.?(s.id, msg.len, null, &msg);
return msg; return msg;
} }
pub inline fn destroy(s: Shader) void { pub inline fn destroy(s: Shader) void {
assert(s.id != 0); assert(s.id != 0);
c.glDeleteShader(s.id); glad.context.DeleteShader.?(s.id);
log.debug("shader destroyed id={}", .{s.id}); log.debug("shader destroyed id={}", .{s.id});
} }

View File

@ -3,11 +3,12 @@ const Texture = @This();
const std = @import("std"); const std = @import("std");
const c = @import("c.zig"); const c = @import("c.zig");
const errors = @import("errors.zig"); const errors = @import("errors.zig");
const glad = @import("glad.zig");
id: c.GLuint, id: c.GLuint,
pub inline fn active(target: c.GLenum) !void { pub inline fn active(target: c.GLenum) !void {
c.glActiveTexture(target); glad.context.ActiveTexture.?(target);
} }
/// Enun for possible texture binding targets. /// Enun for possible texture binding targets.
@ -74,17 +75,17 @@ pub const Binding = struct {
target: Target, target: Target,
pub inline fn unbind(b: *Binding) void { pub inline fn unbind(b: *Binding) void {
c.glBindTexture(@enumToInt(b.target), 0); glad.context.BindTexture.?(@enumToInt(b.target), 0);
b.* = undefined; b.* = undefined;
} }
pub fn generateMipmap(b: Binding) void { pub fn generateMipmap(b: Binding) void {
c.glGenerateMipmap(@enumToInt(b.target)); glad.context.GenerateMipmap.?(@enumToInt(b.target));
} }
pub fn parameter(b: Binding, name: Parameter, value: anytype) !void { pub fn parameter(b: Binding, name: Parameter, value: anytype) !void {
switch (@TypeOf(value)) { switch (@TypeOf(value)) {
c.GLint => c.glTexParameteri( c.GLint => glad.context.TexParameteri.?(
@enumToInt(b.target), @enumToInt(b.target),
@enumToInt(name), @enumToInt(name),
value, value,
@ -104,7 +105,7 @@ pub const Binding = struct {
typ: DataType, typ: DataType,
data: ?*const anyopaque, data: ?*const anyopaque,
) !void { ) !void {
c.glTexImage2D( glad.context.TexImage2D.?(
@enumToInt(b.target), @enumToInt(b.target),
level, level,
@enumToInt(internal_format), @enumToInt(internal_format),
@ -128,7 +129,7 @@ pub const Binding = struct {
typ: DataType, typ: DataType,
data: ?*const anyopaque, data: ?*const anyopaque,
) !void { ) !void {
c.glTexSubImage2D( glad.context.TexSubImage2D.?(
@enumToInt(b.target), @enumToInt(b.target),
level, level,
xoffset, xoffset,
@ -145,16 +146,16 @@ pub const Binding = struct {
/// Create a single texture. /// Create a single texture.
pub inline fn create() !Texture { pub inline fn create() !Texture {
var id: c.GLuint = undefined; var id: c.GLuint = undefined;
c.glGenTextures(1, &id); glad.context.GenTextures.?(1, &id);
return Texture{ .id = id }; return Texture{ .id = id };
} }
/// glBindTexture /// glBindTexture
pub inline fn bind(v: Texture, target: Target) !Binding { pub inline fn bind(v: Texture, target: Target) !Binding {
c.glBindTexture(@enumToInt(target), v.id); glad.context.BindTexture.?(@enumToInt(target), v.id);
return Binding{ .target = target }; return Binding{ .target = target };
} }
pub inline fn destroy(v: Texture) void { pub inline fn destroy(v: Texture) void {
c.glDeleteTextures(1, &v.id); glad.context.DeleteTextures.?(1, &v.id);
} }

View File

@ -1,26 +1,27 @@
const VertexArray = @This(); const VertexArray = @This();
const c = @import("c.zig"); const c = @import("c.zig");
const glad = @import("glad.zig");
id: c.GLuint, id: c.GLuint,
/// Create a single vertex array object. /// Create a single vertex array object.
pub inline fn create() !VertexArray { pub inline fn create() !VertexArray {
var vao: c.GLuint = undefined; var vao: c.GLuint = undefined;
c.glGenVertexArrays(1, &vao); glad.context.GenVertexArrays.?(1, &vao);
return VertexArray{ .id = vao }; return VertexArray{ .id = vao };
} }
// Unbind any active vertex array. // Unbind any active vertex array.
pub inline fn unbind() !void { pub inline fn unbind() !void {
c.glBindVertexArray(0); glad.context.BindVertexArray.?(0);
} }
/// glBindVertexArray /// glBindVertexArray
pub inline fn bind(v: VertexArray) !void { pub inline fn bind(v: VertexArray) !void {
c.glBindVertexArray(v.id); glad.context.BindVertexArray.?(v.id);
} }
pub inline fn destroy(v: VertexArray) void { pub inline fn destroy(v: VertexArray) void {
c.glDeleteVertexArrays(1, &v.id); glad.context.DeleteVertexArrays.?(1, &v.id);
} }

View File

@ -1,22 +1,23 @@
const c = @import("c.zig"); const c = @import("c.zig");
const errors = @import("errors.zig"); const errors = @import("errors.zig");
const glad = @import("glad.zig");
pub fn clearColor(r: f32, g: f32, b: f32, a: f32) void { pub fn clearColor(r: f32, g: f32, b: f32, a: f32) void {
c.glClearColor(r, g, b, a); glad.context.ClearColor.?(r, g, b, a);
} }
pub fn clear(mask: c.GLbitfield) void { pub fn clear(mask: c.GLbitfield) void {
c.glClear(mask); glad.context.Clear.?(mask);
} }
pub fn drawArrays(mode: c.GLenum, first: c.GLint, count: c.GLsizei) !void { pub fn drawArrays(mode: c.GLenum, first: c.GLint, count: c.GLsizei) !void {
c.glDrawArrays(mode, first, count); glad.context.DrawArrays.?(mode, first, count);
try errors.getError(); try errors.getError();
} }
pub fn drawElements(mode: c.GLenum, count: c.GLsizei, typ: c.GLenum, offset: usize) !void { pub fn drawElements(mode: c.GLenum, count: c.GLsizei, typ: c.GLenum, offset: usize) !void {
const offsetPtr = if (offset == 0) null else @intToPtr(*const anyopaque, offset); const offsetPtr = if (offset == 0) null else @intToPtr(*const anyopaque, offset);
c.glDrawElements(mode, count, typ, offsetPtr); glad.context.DrawElements.?(mode, count, typ, offsetPtr);
try errors.getError(); try errors.getError();
} }
@ -26,17 +27,32 @@ pub fn drawElementsInstanced(
typ: c.GLenum, typ: c.GLenum,
primcount: usize, primcount: usize,
) !void { ) !void {
c.glDrawElementsInstanced(mode, count, typ, null, @intCast(c.GLsizei, primcount)); glad.context.DrawElementsInstanced.?(mode, count, typ, null, @intCast(c.GLsizei, primcount));
try errors.getError();
}
pub fn enable(cap: c.GLenum) !void {
glad.context.Enable.?(cap);
try errors.getError();
}
pub fn frontFace(mode: c.GLenum) !void {
glad.context.FrontFace.?(mode);
try errors.getError();
}
pub fn blendFunc(sfactor: c.GLenum, dfactor: c.GLenum) !void {
glad.context.BlendFunc.?(sfactor, dfactor);
try errors.getError(); try errors.getError();
} }
pub fn viewport(x: c.GLint, y: c.GLint, width: c.GLsizei, height: c.GLsizei) !void { pub fn viewport(x: c.GLint, y: c.GLint, width: c.GLsizei, height: c.GLsizei) !void {
c.glViewport(x, y, width, height); glad.context.Viewport.?(x, y, width, height);
} }
pub fn pixelStore(mode: c.GLenum, value: anytype) !void { pub fn pixelStore(mode: c.GLenum, value: anytype) !void {
switch (@typeInfo(@TypeOf(value))) { switch (@typeInfo(@TypeOf(value))) {
.ComptimeInt, .Int => c.glPixelStorei(mode, value), .ComptimeInt, .Int => glad.context.PixelStorei.?(mode, value),
else => unreachable, else => unreachable,
} }
try errors.getError(); try errors.getError();

View File

@ -1,5 +1,6 @@
const std = @import("std"); const std = @import("std");
const c = @import("c.zig"); const c = @import("c.zig");
const glad = @import("glad.zig");
pub const Error = error{ pub const Error = error{
InvalidEnum, InvalidEnum,
@ -13,7 +14,7 @@ pub const Error = error{
/// getError returns the error (if any) from the last OpenGL operation. /// getError returns the error (if any) from the last OpenGL operation.
pub fn getError() Error!void { pub fn getError() Error!void {
return switch (c.glGetError()) { return switch (glad.context.GetError.?()) {
c.GL_NO_ERROR => {}, c.GL_NO_ERROR => {},
c.GL_INVALID_ENUM => Error.InvalidEnum, c.GL_INVALID_ENUM => Error.InvalidEnum,
c.GL_INVALID_VALUE => Error.InvalidValue, c.GL_INVALID_VALUE => Error.InvalidValue,

View File

@ -1,11 +1,12 @@
const std = @import("std"); const std = @import("std");
const c = @import("c.zig"); const c = @import("c.zig");
const errors = @import("errors.zig"); const errors = @import("errors.zig");
const glad = @import("glad.zig");
/// Returns the number of extensions. /// Returns the number of extensions.
pub fn len() !u32 { pub fn len() !u32 {
var n: c.GLint = undefined; var n: c.GLint = undefined;
c.glGetIntegerv(c.GL_NUM_EXTENSIONS, &n); glad.context.GetIntegerv.?(c.GL_NUM_EXTENSIONS, &n);
try errors.getError(); try errors.getError();
return @intCast(u32, n); return @intCast(u32, n);
} }
@ -23,7 +24,7 @@ pub const Iterator = struct {
pub fn next(self: *Iterator) !?[]const u8 { pub fn next(self: *Iterator) !?[]const u8 {
if (self.i >= self.len) return null; if (self.i >= self.len) return null;
const res = c.glGetStringi(c.GL_EXTENSIONS, self.i); const res = glad.context.GetStringi.?(c.GL_EXTENSIONS, self.i);
try errors.getError(); try errors.getError();
self.i += 1; self.i += 1;
return std.mem.sliceTo(res, 0); return std.mem.sliceTo(res, 0);

View File

@ -1,6 +1,14 @@
const std = @import("std"); const std = @import("std");
const c = @import("c.zig"); const c = @import("c.zig");
pub const Context = c.GladGLContext;
/// This is the current context. Set this var manually prior to calling
/// any of this package's functions. I know its nasty to have a global but
/// this makes it match OpenGL API styles where it also operates on a
/// threadlocal global.
pub threadlocal var context: Context = undefined;
/// Initialize Glad. This is guaranteed to succeed if no errors are returned. /// Initialize Glad. This is guaranteed to succeed if no errors are returned.
/// The getProcAddress param is an anytype so that we can accept multiple /// The getProcAddress param is an anytype so that we can accept multiple
/// forms of the function depending on what we're interfacing with. /// forms of the function depending on what we're interfacing with.
@ -10,18 +18,23 @@ pub fn load(getProcAddress: anytype) !c_int {
const res = switch (@TypeOf(getProcAddress)) { const res = switch (@TypeOf(getProcAddress)) {
// glfw // glfw
GlfwFn => c.gladLoadGL(@ptrCast( GlfwFn => c.gladLoadGLContext(&context, @ptrCast(
std.meta.FnPtr(fn ([*c]const u8) callconv(.C) ?GlProc), std.meta.FnPtr(fn ([*c]const u8) callconv(.C) ?GlProc),
getProcAddress, getProcAddress,
)), )),
// try as-is. If this introduces a compiler error, then add a new case. // try as-is. If this introduces a compiler error, then add a new case.
else => c.gladLoadGL(getProcAddress), else => c.gladLoadGLContext(&context, getProcAddress),
}; };
if (res == 0) return error.GLInitFailed; if (res == 0) return error.GLInitFailed;
return res; return res;
} }
pub fn unload() void {
c.gladLoaderUnloadGLContext(&context);
context = undefined;
}
pub fn versionMajor(res: c_int) c_uint { pub fn versionMajor(res: c_int) c_uint {
// https://github.com/ziglang/zig/issues/13162 // https://github.com/ziglang/zig/issues/13162
// return c.GLAD_VERSION_MAJOR(res); // return c.GLAD_VERSION_MAJOR(res);

File diff suppressed because it is too large Load Diff

1220
vendor/glad/src/gl.c vendored

File diff suppressed because it is too large Load Diff