From 89a4c59f3ccbec6b9fa286106c72a46b9e546f54 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 23 Oct 2022 19:39:02 -0700 Subject: [PATCH 01/13] make opengl loader context-aware --- src/Window.zig | 8 +- src/opengl/Buffer.zig | 25 +- src/opengl/Program.zig | 31 +- src/opengl/Shader.zig | 13 +- src/opengl/Texture.zig | 19 +- src/opengl/VertexArray.zig | 9 +- src/opengl/draw.zig | 30 +- src/opengl/errors.zig | 3 +- src/opengl/extensions.zig | 5 +- src/opengl/glad.zig | 17 +- vendor/glad/include/glad/gl.h | 1088 ++++++++++------------------- vendor/glad/src/gl.c | 1220 ++++++++++++--------------------- 12 files changed, 909 insertions(+), 1559 deletions(-) diff --git a/src/Window.zig b/src/Window.zig index dd1485e5d..cef35d70d 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -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 // order since our 0,0 is top-left. - gl.c.glEnable(gl.c.GL_CULL_FACE); - gl.c.glFrontFace(gl.c.GL_CW); + try gl.enable(gl.c.GL_CULL_FACE); + try gl.frontFace(gl.c.GL_CW); // Blending for text - gl.c.glEnable(gl.c.GL_BLEND); - gl.c.glBlendFunc(gl.c.GL_SRC_ALPHA, gl.c.GL_ONE_MINUS_SRC_ALPHA); + try gl.enable(gl.c.GL_BLEND); + 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 const font_size: font.face.DesiredSize = .{ diff --git a/src/opengl/Buffer.zig b/src/opengl/Buffer.zig index 242e8a57c..647656640 100644 --- a/src/opengl/Buffer.zig +++ b/src/opengl/Buffer.zig @@ -3,6 +3,7 @@ const Buffer = @This(); const std = @import("std"); const c = @import("c.zig"); const errors = @import("errors.zig"); +const glad = @import("glad.zig"); id: c.GLuint, @@ -41,7 +42,7 @@ pub const Binding = struct { usage: Usage, ) !void { 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(); } @@ -53,7 +54,7 @@ pub const Binding = struct { data: anytype, ) !void { 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(); } @@ -65,7 +66,7 @@ pub const Binding = struct { comptime T: type, usage: Usage, ) !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(); } @@ -75,7 +76,7 @@ pub const Binding = struct { size: usize, usage: Usage, ) !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(); } @@ -106,7 +107,7 @@ pub const Binding = struct { } pub inline fn enableAttribArray(_: Binding, idx: c.GLuint) !void { - c.glEnableVertexAttribArray(idx); + glad.context.EnableVertexAttribArray.?(idx); } /// Shorthand for vertexAttribPointer that is specialized towards the @@ -153,7 +154,7 @@ pub const Binding = struct { /// VertexAttribDivisor pub fn attributeDivisor(_: Binding, idx: c.GLuint, divisor: c.GLuint) !void { - c.glVertexAttribDivisor(idx, divisor); + glad.context.VertexAttribDivisor.?(idx, divisor); try errors.getError(); } @@ -172,7 +173,7 @@ pub const Binding = struct { else null; - c.glVertexAttribPointer(idx, size, typ, normalized_c, stride, offsetPtr); + glad.context.VertexAttribPointer.?(idx, size, typ, normalized_c, stride, offsetPtr); try errors.getError(); } @@ -189,12 +190,12 @@ pub const Binding = struct { else null; - c.glVertexAttribIPointer(idx, size, typ, stride, offsetPtr); + glad.context.VertexAttribIPointer.?(idx, size, typ, stride, offsetPtr); try errors.getError(); } pub inline fn unbind(b: *Binding) void { - c.glBindBuffer(@enumToInt(b.target), 0); + glad.context.BindBuffer.?(@enumToInt(b.target), 0); b.* = undefined; } }; @@ -202,16 +203,16 @@ pub const Binding = struct { /// Create a single buffer. pub inline fn create() !Buffer { var vbo: c.GLuint = undefined; - c.glGenBuffers(1, &vbo); + glad.context.GenBuffers.?(1, &vbo); return Buffer{ .id = vbo }; } /// glBindBuffer 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 }; } pub inline fn destroy(v: Buffer) void { - c.glDeleteBuffers(1, &v.id); + glad.context.DeleteBuffers.?(1, &v.id); } diff --git a/src/opengl/Program.zig b/src/opengl/Program.zig index 7ac6d243f..5140b7517 100644 --- a/src/opengl/Program.zig +++ b/src/opengl/Program.zig @@ -7,17 +7,18 @@ const log = std.log.scoped(.opengl); const c = @import("c.zig"); const Shader = @import("Shader.zig"); const errors = @import("errors.zig"); +const glad = @import("glad.zig"); id: c.GLuint, const Binding = struct { pub inline fn unbind(_: Binding) void { - c.glUseProgram(0); + glad.context.UseProgram.?(0); } }; pub inline fn create() !Program { - const id = c.glCreateProgram(); + const id = glad.context.CreateProgram.?(); if (id == 0) try errors.mustError(); 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 { - c.glAttachShader(p.id, s.id); + glad.context.AttachShader.?(p.id, s.id); try errors.getError(); } pub inline fn link(p: Program) !void { - c.glLinkProgram(p.id); + glad.context.LinkProgram.?(p.id); // Check if linking succeeded 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) { log.debug("program linked id={}", .{p.id}); return; @@ -67,7 +68,7 @@ pub inline fn link(p: Program) !void { } pub inline fn use(p: Program) !Binding { - c.glUseProgram(p.id); + glad.context.UseProgram.?(p.id); return Binding{}; } @@ -77,7 +78,7 @@ pub inline fn setUniform( n: [:0]const u8, value: anytype, ) !void { - const loc = c.glGetUniformLocation( + const loc = glad.context.GetUniformLocation.?( p.id, @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. switch (@TypeOf(value)) { - comptime_int => c.glUniform1i(loc, value), - f32 => c.glUniform1f(loc, value), - @Vector(2, f32) => c.glUniform2f(loc, value[0], value[1]), - @Vector(3, f32) => c.glUniform3f(loc, value[0], value[1], value[2]), - @Vector(4, f32) => c.glUniform4f(loc, value[0], value[1], value[2], value[3]), - [4]@Vector(4, f32) => c.glUniformMatrix4fv( + comptime_int => glad.context.Uniform1i.?(loc, value), + f32 => glad.context.Uniform1f.?(loc, value), + @Vector(2, f32) => glad.context.Uniform2f.?(loc, value[0], value[1]), + @Vector(3, f32) => glad.context.Uniform3f.?(loc, value[0], value[1], value[2]), + @Vector(4, f32) => glad.context.Uniform4f.?(loc, value[0], value[1], value[2], value[3]), + [4]@Vector(4, f32) => glad.context.UniformMatrix4fv.?( loc, 1, c.GL_FALSE, @@ -112,12 +113,12 @@ pub inline fn setUniform( // if we ever need it. pub inline fn getInfoLog(s: Program) [512]u8 { var msg: [512]u8 = undefined; - c.glGetProgramInfoLog(s.id, msg.len, null, &msg); + glad.context.GetProgramInfoLog.?(s.id, msg.len, null, &msg); return msg; } pub inline fn destroy(p: Program) void { assert(p.id != 0); - c.glDeleteProgram(p.id); + glad.context.DeleteProgram.?(p.id); log.debug("program destroyed id={}", .{p.id}); } diff --git a/src/opengl/Shader.zig b/src/opengl/Shader.zig index 1d6696dcc..d5962c875 100644 --- a/src/opengl/Shader.zig +++ b/src/opengl/Shader.zig @@ -6,11 +6,12 @@ const log = std.log.scoped(.opengl); const c = @import("c.zig"); const errors = @import("errors.zig"); +const glad = @import("glad.zig"); id: c.GLuint, pub inline fn create(typ: c.GLenum) errors.Error!Shader { - const id = c.glCreateShader(typ); + const id = glad.context.CreateShader.?(typ); if (id == 0) { try errors.mustError(); unreachable; @@ -22,12 +23,12 @@ pub inline fn create(typ: c.GLenum) errors.Error!Shader { /// Set the source and compile a shader. 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); + glad.context.ShaderSource.?(s.id, 1, &@ptrCast([*c]const u8, source), null); + glad.context.CompileShader.?(s.id); // Check if compilation succeeded 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; log.err("shader compilation failure id={} message={s}", .{ s.id, @@ -44,12 +45,12 @@ pub inline fn setSourceAndCompile(s: Shader, source: [:0]const u8) !void { // if we ever need it. pub inline fn getInfoLog(s: Shader) [512]u8 { var msg: [512]u8 = undefined; - c.glGetShaderInfoLog(s.id, msg.len, null, &msg); + glad.context.GetShaderInfoLog.?(s.id, msg.len, null, &msg); return msg; } pub inline fn destroy(s: Shader) void { assert(s.id != 0); - c.glDeleteShader(s.id); + glad.context.DeleteShader.?(s.id); log.debug("shader destroyed id={}", .{s.id}); } diff --git a/src/opengl/Texture.zig b/src/opengl/Texture.zig index 09bbe043f..446f0a9ad 100644 --- a/src/opengl/Texture.zig +++ b/src/opengl/Texture.zig @@ -3,11 +3,12 @@ const Texture = @This(); const std = @import("std"); const c = @import("c.zig"); const errors = @import("errors.zig"); +const glad = @import("glad.zig"); id: c.GLuint, pub inline fn active(target: c.GLenum) !void { - c.glActiveTexture(target); + glad.context.ActiveTexture.?(target); } /// Enun for possible texture binding targets. @@ -74,17 +75,17 @@ pub const Binding = struct { target: Target, pub inline fn unbind(b: *Binding) void { - c.glBindTexture(@enumToInt(b.target), 0); + glad.context.BindTexture.?(@enumToInt(b.target), 0); b.* = undefined; } 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 { switch (@TypeOf(value)) { - c.GLint => c.glTexParameteri( + c.GLint => glad.context.TexParameteri.?( @enumToInt(b.target), @enumToInt(name), value, @@ -104,7 +105,7 @@ pub const Binding = struct { typ: DataType, data: ?*const anyopaque, ) !void { - c.glTexImage2D( + glad.context.TexImage2D.?( @enumToInt(b.target), level, @enumToInt(internal_format), @@ -128,7 +129,7 @@ pub const Binding = struct { typ: DataType, data: ?*const anyopaque, ) !void { - c.glTexSubImage2D( + glad.context.TexSubImage2D.?( @enumToInt(b.target), level, xoffset, @@ -145,16 +146,16 @@ pub const Binding = struct { /// Create a single texture. pub inline fn create() !Texture { var id: c.GLuint = undefined; - c.glGenTextures(1, &id); + glad.context.GenTextures.?(1, &id); return Texture{ .id = id }; } /// glBindTexture 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 }; } pub inline fn destroy(v: Texture) void { - c.glDeleteTextures(1, &v.id); + glad.context.DeleteTextures.?(1, &v.id); } diff --git a/src/opengl/VertexArray.zig b/src/opengl/VertexArray.zig index 718ec9b9f..6222a2b68 100644 --- a/src/opengl/VertexArray.zig +++ b/src/opengl/VertexArray.zig @@ -1,26 +1,27 @@ const VertexArray = @This(); const c = @import("c.zig"); +const glad = @import("glad.zig"); id: c.GLuint, /// Create a single vertex array object. pub inline fn create() !VertexArray { var vao: c.GLuint = undefined; - c.glGenVertexArrays(1, &vao); + glad.context.GenVertexArrays.?(1, &vao); return VertexArray{ .id = vao }; } // Unbind any active vertex array. pub inline fn unbind() !void { - c.glBindVertexArray(0); + glad.context.BindVertexArray.?(0); } /// glBindVertexArray pub inline fn bind(v: VertexArray) !void { - c.glBindVertexArray(v.id); + glad.context.BindVertexArray.?(v.id); } pub inline fn destroy(v: VertexArray) void { - c.glDeleteVertexArrays(1, &v.id); + glad.context.DeleteVertexArrays.?(1, &v.id); } diff --git a/src/opengl/draw.zig b/src/opengl/draw.zig index bcb573812..e23997471 100644 --- a/src/opengl/draw.zig +++ b/src/opengl/draw.zig @@ -1,22 +1,23 @@ const c = @import("c.zig"); const errors = @import("errors.zig"); +const glad = @import("glad.zig"); 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 { - c.glClear(mask); + glad.context.Clear.?(mask); } 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(); } 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); - c.glDrawElements(mode, count, typ, offsetPtr); + glad.context.DrawElements.?(mode, count, typ, offsetPtr); try errors.getError(); } @@ -26,17 +27,32 @@ pub fn drawElementsInstanced( typ: c.GLenum, primcount: usize, ) !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(); } 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 { switch (@typeInfo(@TypeOf(value))) { - .ComptimeInt, .Int => c.glPixelStorei(mode, value), + .ComptimeInt, .Int => glad.context.PixelStorei.?(mode, value), else => unreachable, } try errors.getError(); diff --git a/src/opengl/errors.zig b/src/opengl/errors.zig index e95c81b7e..86639a53a 100644 --- a/src/opengl/errors.zig +++ b/src/opengl/errors.zig @@ -1,5 +1,6 @@ const std = @import("std"); const c = @import("c.zig"); +const glad = @import("glad.zig"); pub const Error = error{ InvalidEnum, @@ -13,7 +14,7 @@ pub const Error = error{ /// getError returns the error (if any) from the last OpenGL operation. pub fn getError() Error!void { - return switch (c.glGetError()) { + return switch (glad.context.GetError.?()) { c.GL_NO_ERROR => {}, c.GL_INVALID_ENUM => Error.InvalidEnum, c.GL_INVALID_VALUE => Error.InvalidValue, diff --git a/src/opengl/extensions.zig b/src/opengl/extensions.zig index 086c154ec..e58da3084 100644 --- a/src/opengl/extensions.zig +++ b/src/opengl/extensions.zig @@ -1,11 +1,12 @@ const std = @import("std"); const c = @import("c.zig"); const errors = @import("errors.zig"); +const glad = @import("glad.zig"); /// Returns the number of extensions. pub fn len() !u32 { var n: c.GLint = undefined; - c.glGetIntegerv(c.GL_NUM_EXTENSIONS, &n); + glad.context.GetIntegerv.?(c.GL_NUM_EXTENSIONS, &n); try errors.getError(); return @intCast(u32, n); } @@ -23,7 +24,7 @@ pub const Iterator = struct { pub fn next(self: *Iterator) !?[]const u8 { 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(); self.i += 1; return std.mem.sliceTo(res, 0); diff --git a/src/opengl/glad.zig b/src/opengl/glad.zig index 9d216a28c..84e08ff00 100644 --- a/src/opengl/glad.zig +++ b/src/opengl/glad.zig @@ -1,6 +1,14 @@ const std = @import("std"); 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. /// The getProcAddress param is an anytype so that we can accept multiple /// 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)) { // glfw - GlfwFn => c.gladLoadGL(@ptrCast( + GlfwFn => c.gladLoadGLContext(&context, @ptrCast( std.meta.FnPtr(fn ([*c]const u8) callconv(.C) ?GlProc), getProcAddress, )), // 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; return res; } +pub fn unload() void { + c.gladLoaderUnloadGLContext(&context); + context = undefined; +} + pub fn versionMajor(res: c_int) c_uint { // https://github.com/ziglang/zig/issues/13162 // return c.GLAD_VERSION_MAJOR(res); diff --git a/vendor/glad/include/glad/gl.h b/vendor/glad/include/glad/gl.h index 8b2c8a8f8..2f71276dc 100644 --- a/vendor/glad/include/glad/gl.h +++ b/vendor/glad/include/glad/gl.h @@ -1,5 +1,7 @@ /** - * Loader generated by glad 2.0.0-beta on Mon Apr 4 21:32:54 2022 + * Loader generated by glad 2.0.0 on Mon Oct 24 00:13:28 2022 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 * * Generator: C/C++ * Specification: gl @@ -13,15 +15,14 @@ * - DEBUG = False * - HEADER_ONLY = False * - LOADER = True - * - MX = False - * - MX_GLOBAL = False + * - MX = True * - ON_DEMAND = False * * Commandline: - * --api='gl:core=3.3' --extensions='' c --loader + * --api='gl:core=3.3' --extensions='' c --loader --mx * * Online: - * http://glad.sh/#api=gl%3Acore%3D3.3&extensions=&generator=c&options=LOADER + * http://glad.sh/#api=gl%3Acore%3D3.3&extensions=&generator=c&options=LOADER%2CMX * */ @@ -54,6 +55,7 @@ #define GLAD_GL #define GLAD_OPTION_GL_LOADER +#define GLAD_OPTION_GL_MX #ifdef __cplusplus extern "C" { @@ -115,6 +117,8 @@ extern "C" { #define GLAD_GNUC_EXTENSION #endif +#define GLAD_UNUSED(x) (void)(x) + #ifndef GLAD_API_CALL #if defined(GLAD_API_CALL_EXPORT) #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) @@ -161,7 +165,7 @@ extern "C" { #define GLAD_VERSION_MAJOR(version) (version / 10000) #define GLAD_VERSION_MINOR(version) (version % 10000) -#define GLAD_GENERATOR_VERSION "2.0.0-beta" +#define GLAD_GENERATOR_VERSION "2.0.0" typedef void (*GLADapiproc)(void); @@ -1059,29 +1063,17 @@ typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void); #define GL_VERSION_1_0 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_0; #define GL_VERSION_1_1 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_1; #define GL_VERSION_1_2 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_2; #define GL_VERSION_1_3 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_3; #define GL_VERSION_1_4 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_4; #define GL_VERSION_1_5 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_5; #define GL_VERSION_2_0 1 -GLAD_API_CALL int GLAD_GL_VERSION_2_0; #define GL_VERSION_2_1 1 -GLAD_API_CALL int GLAD_GL_VERSION_2_1; #define GL_VERSION_3_0 1 -GLAD_API_CALL int GLAD_GL_VERSION_3_0; #define GL_VERSION_3_1 1 -GLAD_API_CALL int GLAD_GL_VERSION_3_1; #define GL_VERSION_3_2 1 -GLAD_API_CALL int GLAD_GL_VERSION_3_2; #define GL_VERSION_3_3 1 -GLAD_API_CALL int GLAD_GL_VERSION_3_3; typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture); @@ -1429,707 +1421,383 @@ typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint si typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); typedef void (GLAD_API_PTR *PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture; -#define glActiveTexture glad_glActiveTexture -GLAD_API_CALL PFNGLATTACHSHADERPROC glad_glAttachShader; -#define glAttachShader glad_glAttachShader -GLAD_API_CALL PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; -#define glBeginConditionalRender glad_glBeginConditionalRender -GLAD_API_CALL PFNGLBEGINQUERYPROC glad_glBeginQuery; -#define glBeginQuery glad_glBeginQuery -GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; -#define glBeginTransformFeedback glad_glBeginTransformFeedback -GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; -#define glBindAttribLocation glad_glBindAttribLocation -GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer; -#define glBindBuffer glad_glBindBuffer -GLAD_API_CALL PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; -#define glBindBufferBase glad_glBindBufferBase -GLAD_API_CALL PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; -#define glBindBufferRange glad_glBindBufferRange -GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; -#define glBindFragDataLocation glad_glBindFragDataLocation -GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; -#define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed -GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; -#define glBindFramebuffer glad_glBindFramebuffer -GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; -#define glBindRenderbuffer glad_glBindRenderbuffer -GLAD_API_CALL PFNGLBINDSAMPLERPROC glad_glBindSampler; -#define glBindSampler glad_glBindSampler -GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture; -#define glBindTexture glad_glBindTexture -GLAD_API_CALL PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; -#define glBindVertexArray glad_glBindVertexArray -GLAD_API_CALL PFNGLBLENDCOLORPROC glad_glBlendColor; -#define glBlendColor glad_glBlendColor -GLAD_API_CALL PFNGLBLENDEQUATIONPROC glad_glBlendEquation; -#define glBlendEquation glad_glBlendEquation -GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; -#define glBlendEquationSeparate glad_glBlendEquationSeparate -GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc; -#define glBlendFunc glad_glBlendFunc -GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; -#define glBlendFuncSeparate glad_glBlendFuncSeparate -GLAD_API_CALL PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; -#define glBlitFramebuffer glad_glBlitFramebuffer -GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData; -#define glBufferData glad_glBufferData -GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; -#define glBufferSubData glad_glBufferSubData -GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; -#define glCheckFramebufferStatus glad_glCheckFramebufferStatus -GLAD_API_CALL PFNGLCLAMPCOLORPROC glad_glClampColor; -#define glClampColor glad_glClampColor -GLAD_API_CALL PFNGLCLEARPROC glad_glClear; -#define glClear glad_glClear -GLAD_API_CALL PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; -#define glClearBufferfi glad_glClearBufferfi -GLAD_API_CALL PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; -#define glClearBufferfv glad_glClearBufferfv -GLAD_API_CALL PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; -#define glClearBufferiv glad_glClearBufferiv -GLAD_API_CALL PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; -#define glClearBufferuiv glad_glClearBufferuiv -GLAD_API_CALL PFNGLCLEARCOLORPROC glad_glClearColor; -#define glClearColor glad_glClearColor -GLAD_API_CALL PFNGLCLEARDEPTHPROC glad_glClearDepth; -#define glClearDepth glad_glClearDepth -GLAD_API_CALL PFNGLCLEARSTENCILPROC glad_glClearStencil; -#define glClearStencil glad_glClearStencil -GLAD_API_CALL PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; -#define glClientWaitSync glad_glClientWaitSync -GLAD_API_CALL PFNGLCOLORMASKPROC glad_glColorMask; -#define glColorMask glad_glColorMask -GLAD_API_CALL PFNGLCOLORMASKIPROC glad_glColorMaski; -#define glColorMaski glad_glColorMaski -GLAD_API_CALL PFNGLCOMPILESHADERPROC glad_glCompileShader; -#define glCompileShader glad_glCompileShader -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; -#define glCompressedTexImage1D glad_glCompressedTexImage1D -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; -#define glCompressedTexImage2D glad_glCompressedTexImage2D -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; -#define glCompressedTexImage3D glad_glCompressedTexImage3D -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; -#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; -#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; -#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D -GLAD_API_CALL PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; -#define glCopyBufferSubData glad_glCopyBufferSubData -GLAD_API_CALL PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; -#define glCopyTexImage1D glad_glCopyTexImage1D -GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; -#define glCopyTexImage2D glad_glCopyTexImage2D -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; -#define glCopyTexSubImage1D glad_glCopyTexSubImage1D -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; -#define glCopyTexSubImage2D glad_glCopyTexSubImage2D -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; -#define glCopyTexSubImage3D glad_glCopyTexSubImage3D -GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram; -#define glCreateProgram glad_glCreateProgram -GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader; -#define glCreateShader glad_glCreateShader -GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace; -#define glCullFace glad_glCullFace -GLAD_API_CALL PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; -#define glDeleteBuffers glad_glDeleteBuffers -GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; -#define glDeleteFramebuffers glad_glDeleteFramebuffers -GLAD_API_CALL PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; -#define glDeleteProgram glad_glDeleteProgram -GLAD_API_CALL PFNGLDELETEQUERIESPROC glad_glDeleteQueries; -#define glDeleteQueries glad_glDeleteQueries -GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; -#define glDeleteRenderbuffers glad_glDeleteRenderbuffers -GLAD_API_CALL PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; -#define glDeleteSamplers glad_glDeleteSamplers -GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader; -#define glDeleteShader glad_glDeleteShader -GLAD_API_CALL PFNGLDELETESYNCPROC glad_glDeleteSync; -#define glDeleteSync glad_glDeleteSync -GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures; -#define glDeleteTextures glad_glDeleteTextures -GLAD_API_CALL PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; -#define glDeleteVertexArrays glad_glDeleteVertexArrays -GLAD_API_CALL PFNGLDEPTHFUNCPROC glad_glDepthFunc; -#define glDepthFunc glad_glDepthFunc -GLAD_API_CALL PFNGLDEPTHMASKPROC glad_glDepthMask; -#define glDepthMask glad_glDepthMask -GLAD_API_CALL PFNGLDEPTHRANGEPROC glad_glDepthRange; -#define glDepthRange glad_glDepthRange -GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader; -#define glDetachShader glad_glDetachShader -GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable; -#define glDisable glad_glDisable -GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; -#define glDisableVertexAttribArray glad_glDisableVertexAttribArray -GLAD_API_CALL PFNGLDISABLEIPROC glad_glDisablei; -#define glDisablei glad_glDisablei -GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; -#define glDrawArrays glad_glDrawArrays -GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; -#define glDrawArraysInstanced glad_glDrawArraysInstanced -GLAD_API_CALL PFNGLDRAWBUFFERPROC glad_glDrawBuffer; -#define glDrawBuffer glad_glDrawBuffer -GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; -#define glDrawBuffers glad_glDrawBuffers -GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements; -#define glDrawElements glad_glDrawElements -GLAD_API_CALL PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; -#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex -GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; -#define glDrawElementsInstanced glad_glDrawElementsInstanced -GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; -#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex -GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; -#define glDrawRangeElements glad_glDrawRangeElements -GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; -#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex -GLAD_API_CALL PFNGLENABLEPROC glad_glEnable; -#define glEnable glad_glEnable -GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; -#define glEnableVertexAttribArray glad_glEnableVertexAttribArray -GLAD_API_CALL PFNGLENABLEIPROC glad_glEnablei; -#define glEnablei glad_glEnablei -GLAD_API_CALL PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; -#define glEndConditionalRender glad_glEndConditionalRender -GLAD_API_CALL PFNGLENDQUERYPROC glad_glEndQuery; -#define glEndQuery glad_glEndQuery -GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; -#define glEndTransformFeedback glad_glEndTransformFeedback -GLAD_API_CALL PFNGLFENCESYNCPROC glad_glFenceSync; -#define glFenceSync glad_glFenceSync -GLAD_API_CALL PFNGLFINISHPROC glad_glFinish; -#define glFinish glad_glFinish -GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush; -#define glFlush glad_glFlush -GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; -#define glFlushMappedBufferRange glad_glFlushMappedBufferRange -GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; -#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; -#define glFramebufferTexture glad_glFramebufferTexture -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; -#define glFramebufferTexture1D glad_glFramebufferTexture1D -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; -#define glFramebufferTexture2D glad_glFramebufferTexture2D -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; -#define glFramebufferTexture3D glad_glFramebufferTexture3D -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; -#define glFramebufferTextureLayer glad_glFramebufferTextureLayer -GLAD_API_CALL PFNGLFRONTFACEPROC glad_glFrontFace; -#define glFrontFace glad_glFrontFace -GLAD_API_CALL PFNGLGENBUFFERSPROC glad_glGenBuffers; -#define glGenBuffers glad_glGenBuffers -GLAD_API_CALL PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; -#define glGenFramebuffers glad_glGenFramebuffers -GLAD_API_CALL PFNGLGENQUERIESPROC glad_glGenQueries; -#define glGenQueries glad_glGenQueries -GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; -#define glGenRenderbuffers glad_glGenRenderbuffers -GLAD_API_CALL PFNGLGENSAMPLERSPROC glad_glGenSamplers; -#define glGenSamplers glad_glGenSamplers -GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures; -#define glGenTextures glad_glGenTextures -GLAD_API_CALL PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; -#define glGenVertexArrays glad_glGenVertexArrays -GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; -#define glGenerateMipmap glad_glGenerateMipmap -GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; -#define glGetActiveAttrib glad_glGetActiveAttrib -GLAD_API_CALL PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; -#define glGetActiveUniform glad_glGetActiveUniform -GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; -#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName -GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; -#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv -GLAD_API_CALL PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; -#define glGetActiveUniformName glad_glGetActiveUniformName -GLAD_API_CALL PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; -#define glGetActiveUniformsiv glad_glGetActiveUniformsiv -GLAD_API_CALL PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; -#define glGetAttachedShaders glad_glGetAttachedShaders -GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; -#define glGetAttribLocation glad_glGetAttribLocation -GLAD_API_CALL PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; -#define glGetBooleani_v glad_glGetBooleani_v -GLAD_API_CALL PFNGLGETBOOLEANVPROC glad_glGetBooleanv; -#define glGetBooleanv glad_glGetBooleanv -GLAD_API_CALL PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; -#define glGetBufferParameteri64v glad_glGetBufferParameteri64v -GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; -#define glGetBufferParameteriv glad_glGetBufferParameteriv -GLAD_API_CALL PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; -#define glGetBufferPointerv glad_glGetBufferPointerv -GLAD_API_CALL PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; -#define glGetBufferSubData glad_glGetBufferSubData -GLAD_API_CALL PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; -#define glGetCompressedTexImage glad_glGetCompressedTexImage -GLAD_API_CALL PFNGLGETDOUBLEVPROC glad_glGetDoublev; -#define glGetDoublev glad_glGetDoublev -GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError; -#define glGetError glad_glGetError -GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv; -#define glGetFloatv glad_glGetFloatv -GLAD_API_CALL PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; -#define glGetFragDataIndex glad_glGetFragDataIndex -GLAD_API_CALL PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; -#define glGetFragDataLocation glad_glGetFragDataLocation -GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; -#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv -GLAD_API_CALL PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; -#define glGetInteger64i_v glad_glGetInteger64i_v -GLAD_API_CALL PFNGLGETINTEGER64VPROC glad_glGetInteger64v; -#define glGetInteger64v glad_glGetInteger64v -GLAD_API_CALL PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; -#define glGetIntegeri_v glad_glGetIntegeri_v -GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv; -#define glGetIntegerv glad_glGetIntegerv -GLAD_API_CALL PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; -#define glGetMultisamplefv glad_glGetMultisamplefv -GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; -#define glGetProgramInfoLog glad_glGetProgramInfoLog -GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; -#define glGetProgramiv glad_glGetProgramiv -GLAD_API_CALL PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; -#define glGetQueryObjecti64v glad_glGetQueryObjecti64v -GLAD_API_CALL PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; -#define glGetQueryObjectiv glad_glGetQueryObjectiv -GLAD_API_CALL PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; -#define glGetQueryObjectui64v glad_glGetQueryObjectui64v -GLAD_API_CALL PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; -#define glGetQueryObjectuiv glad_glGetQueryObjectuiv -GLAD_API_CALL PFNGLGETQUERYIVPROC glad_glGetQueryiv; -#define glGetQueryiv glad_glGetQueryiv -GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; -#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv -GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; -#define glGetSamplerParameterIiv glad_glGetSamplerParameterIiv -GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; -#define glGetSamplerParameterIuiv glad_glGetSamplerParameterIuiv -GLAD_API_CALL PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; -#define glGetSamplerParameterfv glad_glGetSamplerParameterfv -GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; -#define glGetSamplerParameteriv glad_glGetSamplerParameteriv -GLAD_API_CALL PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; -#define glGetShaderInfoLog glad_glGetShaderInfoLog -GLAD_API_CALL PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; -#define glGetShaderSource glad_glGetShaderSource -GLAD_API_CALL PFNGLGETSHADERIVPROC glad_glGetShaderiv; -#define glGetShaderiv glad_glGetShaderiv -GLAD_API_CALL PFNGLGETSTRINGPROC glad_glGetString; -#define glGetString glad_glGetString -GLAD_API_CALL PFNGLGETSTRINGIPROC glad_glGetStringi; -#define glGetStringi glad_glGetStringi -GLAD_API_CALL PFNGLGETSYNCIVPROC glad_glGetSynciv; -#define glGetSynciv glad_glGetSynciv -GLAD_API_CALL PFNGLGETTEXIMAGEPROC glad_glGetTexImage; -#define glGetTexImage glad_glGetTexImage -GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; -#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv -GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; -#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv -GLAD_API_CALL PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; -#define glGetTexParameterIiv glad_glGetTexParameterIiv -GLAD_API_CALL PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; -#define glGetTexParameterIuiv glad_glGetTexParameterIuiv -GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; -#define glGetTexParameterfv glad_glGetTexParameterfv -GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; -#define glGetTexParameteriv glad_glGetTexParameteriv -GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; -#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying -GLAD_API_CALL PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; -#define glGetUniformBlockIndex glad_glGetUniformBlockIndex -GLAD_API_CALL PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; -#define glGetUniformIndices glad_glGetUniformIndices -GLAD_API_CALL PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; -#define glGetUniformLocation glad_glGetUniformLocation -GLAD_API_CALL PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; -#define glGetUniformfv glad_glGetUniformfv -GLAD_API_CALL PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; -#define glGetUniformiv glad_glGetUniformiv -GLAD_API_CALL PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; -#define glGetUniformuiv glad_glGetUniformuiv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; -#define glGetVertexAttribIiv glad_glGetVertexAttribIiv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; -#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv -GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; -#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv -GLAD_API_CALL PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; -#define glGetVertexAttribdv glad_glGetVertexAttribdv -GLAD_API_CALL PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; -#define glGetVertexAttribfv glad_glGetVertexAttribfv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; -#define glGetVertexAttribiv glad_glGetVertexAttribiv -GLAD_API_CALL PFNGLHINTPROC glad_glHint; -#define glHint glad_glHint -GLAD_API_CALL PFNGLISBUFFERPROC glad_glIsBuffer; -#define glIsBuffer glad_glIsBuffer -GLAD_API_CALL PFNGLISENABLEDPROC glad_glIsEnabled; -#define glIsEnabled glad_glIsEnabled -GLAD_API_CALL PFNGLISENABLEDIPROC glad_glIsEnabledi; -#define glIsEnabledi glad_glIsEnabledi -GLAD_API_CALL PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; -#define glIsFramebuffer glad_glIsFramebuffer -GLAD_API_CALL PFNGLISPROGRAMPROC glad_glIsProgram; -#define glIsProgram glad_glIsProgram -GLAD_API_CALL PFNGLISQUERYPROC glad_glIsQuery; -#define glIsQuery glad_glIsQuery -GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; -#define glIsRenderbuffer glad_glIsRenderbuffer -GLAD_API_CALL PFNGLISSAMPLERPROC glad_glIsSampler; -#define glIsSampler glad_glIsSampler -GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader; -#define glIsShader glad_glIsShader -GLAD_API_CALL PFNGLISSYNCPROC glad_glIsSync; -#define glIsSync glad_glIsSync -GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture; -#define glIsTexture glad_glIsTexture -GLAD_API_CALL PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; -#define glIsVertexArray glad_glIsVertexArray -GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth; -#define glLineWidth glad_glLineWidth -GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram; -#define glLinkProgram glad_glLinkProgram -GLAD_API_CALL PFNGLLOGICOPPROC glad_glLogicOp; -#define glLogicOp glad_glLogicOp -GLAD_API_CALL PFNGLMAPBUFFERPROC glad_glMapBuffer; -#define glMapBuffer glad_glMapBuffer -GLAD_API_CALL PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; -#define glMapBufferRange glad_glMapBufferRange -GLAD_API_CALL PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; -#define glMultiDrawArrays glad_glMultiDrawArrays -GLAD_API_CALL PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; -#define glMultiDrawElements glad_glMultiDrawElements -GLAD_API_CALL PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; -#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex -GLAD_API_CALL PFNGLPIXELSTOREFPROC glad_glPixelStoref; -#define glPixelStoref glad_glPixelStoref -GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei; -#define glPixelStorei glad_glPixelStorei -GLAD_API_CALL PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; -#define glPointParameterf glad_glPointParameterf -GLAD_API_CALL PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; -#define glPointParameterfv glad_glPointParameterfv -GLAD_API_CALL PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; -#define glPointParameteri glad_glPointParameteri -GLAD_API_CALL PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; -#define glPointParameteriv glad_glPointParameteriv -GLAD_API_CALL PFNGLPOINTSIZEPROC glad_glPointSize; -#define glPointSize glad_glPointSize -GLAD_API_CALL PFNGLPOLYGONMODEPROC glad_glPolygonMode; -#define glPolygonMode glad_glPolygonMode -GLAD_API_CALL PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; -#define glPolygonOffset glad_glPolygonOffset -GLAD_API_CALL PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; -#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex -GLAD_API_CALL PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; -#define glProvokingVertex glad_glProvokingVertex -GLAD_API_CALL PFNGLQUERYCOUNTERPROC glad_glQueryCounter; -#define glQueryCounter glad_glQueryCounter -GLAD_API_CALL PFNGLREADBUFFERPROC glad_glReadBuffer; -#define glReadBuffer glad_glReadBuffer -GLAD_API_CALL PFNGLREADPIXELSPROC glad_glReadPixels; -#define glReadPixels glad_glReadPixels -GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; -#define glRenderbufferStorage glad_glRenderbufferStorage -GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; -#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample -GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; -#define glSampleCoverage glad_glSampleCoverage -GLAD_API_CALL PFNGLSAMPLEMASKIPROC glad_glSampleMaski; -#define glSampleMaski glad_glSampleMaski -GLAD_API_CALL PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; -#define glSamplerParameterIiv glad_glSamplerParameterIiv -GLAD_API_CALL PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; -#define glSamplerParameterIuiv glad_glSamplerParameterIuiv -GLAD_API_CALL PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; -#define glSamplerParameterf glad_glSamplerParameterf -GLAD_API_CALL PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; -#define glSamplerParameterfv glad_glSamplerParameterfv -GLAD_API_CALL PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; -#define glSamplerParameteri glad_glSamplerParameteri -GLAD_API_CALL PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; -#define glSamplerParameteriv glad_glSamplerParameteriv -GLAD_API_CALL PFNGLSCISSORPROC glad_glScissor; -#define glScissor glad_glScissor -GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource; -#define glShaderSource glad_glShaderSource -GLAD_API_CALL PFNGLSTENCILFUNCPROC glad_glStencilFunc; -#define glStencilFunc glad_glStencilFunc -GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; -#define glStencilFuncSeparate glad_glStencilFuncSeparate -GLAD_API_CALL PFNGLSTENCILMASKPROC glad_glStencilMask; -#define glStencilMask glad_glStencilMask -GLAD_API_CALL PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; -#define glStencilMaskSeparate glad_glStencilMaskSeparate -GLAD_API_CALL PFNGLSTENCILOPPROC glad_glStencilOp; -#define glStencilOp glad_glStencilOp -GLAD_API_CALL PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; -#define glStencilOpSeparate glad_glStencilOpSeparate -GLAD_API_CALL PFNGLTEXBUFFERPROC glad_glTexBuffer; -#define glTexBuffer glad_glTexBuffer -GLAD_API_CALL PFNGLTEXIMAGE1DPROC glad_glTexImage1D; -#define glTexImage1D glad_glTexImage1D -GLAD_API_CALL PFNGLTEXIMAGE2DPROC glad_glTexImage2D; -#define glTexImage2D glad_glTexImage2D -GLAD_API_CALL PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; -#define glTexImage2DMultisample glad_glTexImage2DMultisample -GLAD_API_CALL PFNGLTEXIMAGE3DPROC glad_glTexImage3D; -#define glTexImage3D glad_glTexImage3D -GLAD_API_CALL PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; -#define glTexImage3DMultisample glad_glTexImage3DMultisample -GLAD_API_CALL PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; -#define glTexParameterIiv glad_glTexParameterIiv -GLAD_API_CALL PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; -#define glTexParameterIuiv glad_glTexParameterIuiv -GLAD_API_CALL PFNGLTEXPARAMETERFPROC glad_glTexParameterf; -#define glTexParameterf glad_glTexParameterf -GLAD_API_CALL PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; -#define glTexParameterfv glad_glTexParameterfv -GLAD_API_CALL PFNGLTEXPARAMETERIPROC glad_glTexParameteri; -#define glTexParameteri glad_glTexParameteri -GLAD_API_CALL PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; -#define glTexParameteriv glad_glTexParameteriv -GLAD_API_CALL PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; -#define glTexSubImage1D glad_glTexSubImage1D -GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; -#define glTexSubImage2D glad_glTexSubImage2D -GLAD_API_CALL PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; -#define glTexSubImage3D glad_glTexSubImage3D -GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; -#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings -GLAD_API_CALL PFNGLUNIFORM1FPROC glad_glUniform1f; -#define glUniform1f glad_glUniform1f -GLAD_API_CALL PFNGLUNIFORM1FVPROC glad_glUniform1fv; -#define glUniform1fv glad_glUniform1fv -GLAD_API_CALL PFNGLUNIFORM1IPROC glad_glUniform1i; -#define glUniform1i glad_glUniform1i -GLAD_API_CALL PFNGLUNIFORM1IVPROC glad_glUniform1iv; -#define glUniform1iv glad_glUniform1iv -GLAD_API_CALL PFNGLUNIFORM1UIPROC glad_glUniform1ui; -#define glUniform1ui glad_glUniform1ui -GLAD_API_CALL PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; -#define glUniform1uiv glad_glUniform1uiv -GLAD_API_CALL PFNGLUNIFORM2FPROC glad_glUniform2f; -#define glUniform2f glad_glUniform2f -GLAD_API_CALL PFNGLUNIFORM2FVPROC glad_glUniform2fv; -#define glUniform2fv glad_glUniform2fv -GLAD_API_CALL PFNGLUNIFORM2IPROC glad_glUniform2i; -#define glUniform2i glad_glUniform2i -GLAD_API_CALL PFNGLUNIFORM2IVPROC glad_glUniform2iv; -#define glUniform2iv glad_glUniform2iv -GLAD_API_CALL PFNGLUNIFORM2UIPROC glad_glUniform2ui; -#define glUniform2ui glad_glUniform2ui -GLAD_API_CALL PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; -#define glUniform2uiv glad_glUniform2uiv -GLAD_API_CALL PFNGLUNIFORM3FPROC glad_glUniform3f; -#define glUniform3f glad_glUniform3f -GLAD_API_CALL PFNGLUNIFORM3FVPROC glad_glUniform3fv; -#define glUniform3fv glad_glUniform3fv -GLAD_API_CALL PFNGLUNIFORM3IPROC glad_glUniform3i; -#define glUniform3i glad_glUniform3i -GLAD_API_CALL PFNGLUNIFORM3IVPROC glad_glUniform3iv; -#define glUniform3iv glad_glUniform3iv -GLAD_API_CALL PFNGLUNIFORM3UIPROC glad_glUniform3ui; -#define glUniform3ui glad_glUniform3ui -GLAD_API_CALL PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; -#define glUniform3uiv glad_glUniform3uiv -GLAD_API_CALL PFNGLUNIFORM4FPROC glad_glUniform4f; -#define glUniform4f glad_glUniform4f -GLAD_API_CALL PFNGLUNIFORM4FVPROC glad_glUniform4fv; -#define glUniform4fv glad_glUniform4fv -GLAD_API_CALL PFNGLUNIFORM4IPROC glad_glUniform4i; -#define glUniform4i glad_glUniform4i -GLAD_API_CALL PFNGLUNIFORM4IVPROC glad_glUniform4iv; -#define glUniform4iv glad_glUniform4iv -GLAD_API_CALL PFNGLUNIFORM4UIPROC glad_glUniform4ui; -#define glUniform4ui glad_glUniform4ui -GLAD_API_CALL PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; -#define glUniform4uiv glad_glUniform4uiv -GLAD_API_CALL PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; -#define glUniformBlockBinding glad_glUniformBlockBinding -GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; -#define glUniformMatrix2fv glad_glUniformMatrix2fv -GLAD_API_CALL PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; -#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv -GLAD_API_CALL PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; -#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv -GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; -#define glUniformMatrix3fv glad_glUniformMatrix3fv -GLAD_API_CALL PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; -#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv -GLAD_API_CALL PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; -#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv -GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; -#define glUniformMatrix4fv glad_glUniformMatrix4fv -GLAD_API_CALL PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; -#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv -GLAD_API_CALL PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; -#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv -GLAD_API_CALL PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; -#define glUnmapBuffer glad_glUnmapBuffer -GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram; -#define glUseProgram glad_glUseProgram -GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; -#define glValidateProgram glad_glValidateProgram -GLAD_API_CALL PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; -#define glVertexAttrib1d glad_glVertexAttrib1d -GLAD_API_CALL PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; -#define glVertexAttrib1dv glad_glVertexAttrib1dv -GLAD_API_CALL PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; -#define glVertexAttrib1f glad_glVertexAttrib1f -GLAD_API_CALL PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; -#define glVertexAttrib1fv glad_glVertexAttrib1fv -GLAD_API_CALL PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; -#define glVertexAttrib1s glad_glVertexAttrib1s -GLAD_API_CALL PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; -#define glVertexAttrib1sv glad_glVertexAttrib1sv -GLAD_API_CALL PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; -#define glVertexAttrib2d glad_glVertexAttrib2d -GLAD_API_CALL PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; -#define glVertexAttrib2dv glad_glVertexAttrib2dv -GLAD_API_CALL PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; -#define glVertexAttrib2f glad_glVertexAttrib2f -GLAD_API_CALL PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; -#define glVertexAttrib2fv glad_glVertexAttrib2fv -GLAD_API_CALL PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; -#define glVertexAttrib2s glad_glVertexAttrib2s -GLAD_API_CALL PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; -#define glVertexAttrib2sv glad_glVertexAttrib2sv -GLAD_API_CALL PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; -#define glVertexAttrib3d glad_glVertexAttrib3d -GLAD_API_CALL PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; -#define glVertexAttrib3dv glad_glVertexAttrib3dv -GLAD_API_CALL PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; -#define glVertexAttrib3f glad_glVertexAttrib3f -GLAD_API_CALL PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; -#define glVertexAttrib3fv glad_glVertexAttrib3fv -GLAD_API_CALL PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; -#define glVertexAttrib3s glad_glVertexAttrib3s -GLAD_API_CALL PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; -#define glVertexAttrib3sv glad_glVertexAttrib3sv -GLAD_API_CALL PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; -#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv -GLAD_API_CALL PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; -#define glVertexAttrib4Niv glad_glVertexAttrib4Niv -GLAD_API_CALL PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; -#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv -GLAD_API_CALL PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; -#define glVertexAttrib4Nub glad_glVertexAttrib4Nub -GLAD_API_CALL PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; -#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv -GLAD_API_CALL PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; -#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv -GLAD_API_CALL PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; -#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv -GLAD_API_CALL PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; -#define glVertexAttrib4bv glad_glVertexAttrib4bv -GLAD_API_CALL PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; -#define glVertexAttrib4d glad_glVertexAttrib4d -GLAD_API_CALL PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; -#define glVertexAttrib4dv glad_glVertexAttrib4dv -GLAD_API_CALL PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; -#define glVertexAttrib4f glad_glVertexAttrib4f -GLAD_API_CALL PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; -#define glVertexAttrib4fv glad_glVertexAttrib4fv -GLAD_API_CALL PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; -#define glVertexAttrib4iv glad_glVertexAttrib4iv -GLAD_API_CALL PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; -#define glVertexAttrib4s glad_glVertexAttrib4s -GLAD_API_CALL PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; -#define glVertexAttrib4sv glad_glVertexAttrib4sv -GLAD_API_CALL PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; -#define glVertexAttrib4ubv glad_glVertexAttrib4ubv -GLAD_API_CALL PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; -#define glVertexAttrib4uiv glad_glVertexAttrib4uiv -GLAD_API_CALL PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; -#define glVertexAttrib4usv glad_glVertexAttrib4usv -GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; -#define glVertexAttribDivisor glad_glVertexAttribDivisor -GLAD_API_CALL PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; -#define glVertexAttribI1i glad_glVertexAttribI1i -GLAD_API_CALL PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; -#define glVertexAttribI1iv glad_glVertexAttribI1iv -GLAD_API_CALL PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; -#define glVertexAttribI1ui glad_glVertexAttribI1ui -GLAD_API_CALL PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; -#define glVertexAttribI1uiv glad_glVertexAttribI1uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; -#define glVertexAttribI2i glad_glVertexAttribI2i -GLAD_API_CALL PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; -#define glVertexAttribI2iv glad_glVertexAttribI2iv -GLAD_API_CALL PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; -#define glVertexAttribI2ui glad_glVertexAttribI2ui -GLAD_API_CALL PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; -#define glVertexAttribI2uiv glad_glVertexAttribI2uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; -#define glVertexAttribI3i glad_glVertexAttribI3i -GLAD_API_CALL PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; -#define glVertexAttribI3iv glad_glVertexAttribI3iv -GLAD_API_CALL PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; -#define glVertexAttribI3ui glad_glVertexAttribI3ui -GLAD_API_CALL PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; -#define glVertexAttribI3uiv glad_glVertexAttribI3uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; -#define glVertexAttribI4bv glad_glVertexAttribI4bv -GLAD_API_CALL PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; -#define glVertexAttribI4i glad_glVertexAttribI4i -GLAD_API_CALL PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; -#define glVertexAttribI4iv glad_glVertexAttribI4iv -GLAD_API_CALL PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; -#define glVertexAttribI4sv glad_glVertexAttribI4sv -GLAD_API_CALL PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; -#define glVertexAttribI4ubv glad_glVertexAttribI4ubv -GLAD_API_CALL PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; -#define glVertexAttribI4ui glad_glVertexAttribI4ui -GLAD_API_CALL PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; -#define glVertexAttribI4uiv glad_glVertexAttribI4uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; -#define glVertexAttribI4usv glad_glVertexAttribI4usv -GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; -#define glVertexAttribIPointer glad_glVertexAttribIPointer -GLAD_API_CALL PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; -#define glVertexAttribP1ui glad_glVertexAttribP1ui -GLAD_API_CALL PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; -#define glVertexAttribP1uiv glad_glVertexAttribP1uiv -GLAD_API_CALL PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; -#define glVertexAttribP2ui glad_glVertexAttribP2ui -GLAD_API_CALL PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; -#define glVertexAttribP2uiv glad_glVertexAttribP2uiv -GLAD_API_CALL PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; -#define glVertexAttribP3ui glad_glVertexAttribP3ui -GLAD_API_CALL PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; -#define glVertexAttribP3uiv glad_glVertexAttribP3uiv -GLAD_API_CALL PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; -#define glVertexAttribP4ui glad_glVertexAttribP4ui -GLAD_API_CALL PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; -#define glVertexAttribP4uiv glad_glVertexAttribP4uiv -GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; -#define glVertexAttribPointer glad_glVertexAttribPointer -GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport; -#define glViewport glad_glViewport -GLAD_API_CALL PFNGLWAITSYNCPROC glad_glWaitSync; -#define glWaitSync glad_glWaitSync +typedef struct GladGLContext { + void* userptr; + + int VERSION_1_0; + int VERSION_1_1; + int VERSION_1_2; + int VERSION_1_3; + int VERSION_1_4; + int VERSION_1_5; + int VERSION_2_0; + int VERSION_2_1; + int VERSION_3_0; + int VERSION_3_1; + int VERSION_3_2; + int VERSION_3_3; + + PFNGLACTIVETEXTUREPROC ActiveTexture; + PFNGLATTACHSHADERPROC AttachShader; + PFNGLBEGINCONDITIONALRENDERPROC BeginConditionalRender; + PFNGLBEGINQUERYPROC BeginQuery; + PFNGLBEGINTRANSFORMFEEDBACKPROC BeginTransformFeedback; + PFNGLBINDATTRIBLOCATIONPROC BindAttribLocation; + PFNGLBINDBUFFERPROC BindBuffer; + PFNGLBINDBUFFERBASEPROC BindBufferBase; + PFNGLBINDBUFFERRANGEPROC BindBufferRange; + PFNGLBINDFRAGDATALOCATIONPROC BindFragDataLocation; + PFNGLBINDFRAGDATALOCATIONINDEXEDPROC BindFragDataLocationIndexed; + PFNGLBINDFRAMEBUFFERPROC BindFramebuffer; + PFNGLBINDRENDERBUFFERPROC BindRenderbuffer; + PFNGLBINDSAMPLERPROC BindSampler; + PFNGLBINDTEXTUREPROC BindTexture; + PFNGLBINDVERTEXARRAYPROC BindVertexArray; + PFNGLBLENDCOLORPROC BlendColor; + PFNGLBLENDEQUATIONPROC BlendEquation; + PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate; + PFNGLBLENDFUNCPROC BlendFunc; + PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate; + PFNGLBLITFRAMEBUFFERPROC BlitFramebuffer; + PFNGLBUFFERDATAPROC BufferData; + PFNGLBUFFERSUBDATAPROC BufferSubData; + PFNGLCHECKFRAMEBUFFERSTATUSPROC CheckFramebufferStatus; + PFNGLCLAMPCOLORPROC ClampColor; + PFNGLCLEARPROC Clear; + PFNGLCLEARBUFFERFIPROC ClearBufferfi; + PFNGLCLEARBUFFERFVPROC ClearBufferfv; + PFNGLCLEARBUFFERIVPROC ClearBufferiv; + PFNGLCLEARBUFFERUIVPROC ClearBufferuiv; + PFNGLCLEARCOLORPROC ClearColor; + PFNGLCLEARDEPTHPROC ClearDepth; + PFNGLCLEARSTENCILPROC ClearStencil; + PFNGLCLIENTWAITSYNCPROC ClientWaitSync; + PFNGLCOLORMASKPROC ColorMask; + PFNGLCOLORMASKIPROC ColorMaski; + PFNGLCOMPILESHADERPROC CompileShader; + PFNGLCOMPRESSEDTEXIMAGE1DPROC CompressedTexImage1D; + PFNGLCOMPRESSEDTEXIMAGE2DPROC CompressedTexImage2D; + PFNGLCOMPRESSEDTEXIMAGE3DPROC CompressedTexImage3D; + PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC CompressedTexSubImage1D; + PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC CompressedTexSubImage2D; + PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC CompressedTexSubImage3D; + PFNGLCOPYBUFFERSUBDATAPROC CopyBufferSubData; + PFNGLCOPYTEXIMAGE1DPROC CopyTexImage1D; + PFNGLCOPYTEXIMAGE2DPROC CopyTexImage2D; + PFNGLCOPYTEXSUBIMAGE1DPROC CopyTexSubImage1D; + PFNGLCOPYTEXSUBIMAGE2DPROC CopyTexSubImage2D; + PFNGLCOPYTEXSUBIMAGE3DPROC CopyTexSubImage3D; + PFNGLCREATEPROGRAMPROC CreateProgram; + PFNGLCREATESHADERPROC CreateShader; + PFNGLCULLFACEPROC CullFace; + PFNGLDELETEBUFFERSPROC DeleteBuffers; + PFNGLDELETEFRAMEBUFFERSPROC DeleteFramebuffers; + PFNGLDELETEPROGRAMPROC DeleteProgram; + PFNGLDELETEQUERIESPROC DeleteQueries; + PFNGLDELETERENDERBUFFERSPROC DeleteRenderbuffers; + PFNGLDELETESAMPLERSPROC DeleteSamplers; + PFNGLDELETESHADERPROC DeleteShader; + PFNGLDELETESYNCPROC DeleteSync; + PFNGLDELETETEXTURESPROC DeleteTextures; + PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays; + PFNGLDEPTHFUNCPROC DepthFunc; + PFNGLDEPTHMASKPROC DepthMask; + PFNGLDEPTHRANGEPROC DepthRange; + PFNGLDETACHSHADERPROC DetachShader; + PFNGLDISABLEPROC Disable; + PFNGLDISABLEVERTEXATTRIBARRAYPROC DisableVertexAttribArray; + PFNGLDISABLEIPROC Disablei; + PFNGLDRAWARRAYSPROC DrawArrays; + PFNGLDRAWARRAYSINSTANCEDPROC DrawArraysInstanced; + PFNGLDRAWBUFFERPROC DrawBuffer; + PFNGLDRAWBUFFERSPROC DrawBuffers; + PFNGLDRAWELEMENTSPROC DrawElements; + PFNGLDRAWELEMENTSBASEVERTEXPROC DrawElementsBaseVertex; + PFNGLDRAWELEMENTSINSTANCEDPROC DrawElementsInstanced; + PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC DrawElementsInstancedBaseVertex; + PFNGLDRAWRANGEELEMENTSPROC DrawRangeElements; + PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC DrawRangeElementsBaseVertex; + PFNGLENABLEPROC Enable; + PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray; + PFNGLENABLEIPROC Enablei; + PFNGLENDCONDITIONALRENDERPROC EndConditionalRender; + PFNGLENDQUERYPROC EndQuery; + PFNGLENDTRANSFORMFEEDBACKPROC EndTransformFeedback; + PFNGLFENCESYNCPROC FenceSync; + PFNGLFINISHPROC Finish; + PFNGLFLUSHPROC Flush; + PFNGLFLUSHMAPPEDBUFFERRANGEPROC FlushMappedBufferRange; + PFNGLFRAMEBUFFERRENDERBUFFERPROC FramebufferRenderbuffer; + PFNGLFRAMEBUFFERTEXTUREPROC FramebufferTexture; + PFNGLFRAMEBUFFERTEXTURE1DPROC FramebufferTexture1D; + PFNGLFRAMEBUFFERTEXTURE2DPROC FramebufferTexture2D; + PFNGLFRAMEBUFFERTEXTURE3DPROC FramebufferTexture3D; + PFNGLFRAMEBUFFERTEXTURELAYERPROC FramebufferTextureLayer; + PFNGLFRONTFACEPROC FrontFace; + PFNGLGENBUFFERSPROC GenBuffers; + PFNGLGENFRAMEBUFFERSPROC GenFramebuffers; + PFNGLGENQUERIESPROC GenQueries; + PFNGLGENRENDERBUFFERSPROC GenRenderbuffers; + PFNGLGENSAMPLERSPROC GenSamplers; + PFNGLGENTEXTURESPROC GenTextures; + PFNGLGENVERTEXARRAYSPROC GenVertexArrays; + PFNGLGENERATEMIPMAPPROC GenerateMipmap; + PFNGLGETACTIVEATTRIBPROC GetActiveAttrib; + PFNGLGETACTIVEUNIFORMPROC GetActiveUniform; + PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC GetActiveUniformBlockName; + PFNGLGETACTIVEUNIFORMBLOCKIVPROC GetActiveUniformBlockiv; + PFNGLGETACTIVEUNIFORMNAMEPROC GetActiveUniformName; + PFNGLGETACTIVEUNIFORMSIVPROC GetActiveUniformsiv; + PFNGLGETATTACHEDSHADERSPROC GetAttachedShaders; + PFNGLGETATTRIBLOCATIONPROC GetAttribLocation; + PFNGLGETBOOLEANI_VPROC GetBooleani_v; + PFNGLGETBOOLEANVPROC GetBooleanv; + PFNGLGETBUFFERPARAMETERI64VPROC GetBufferParameteri64v; + PFNGLGETBUFFERPARAMETERIVPROC GetBufferParameteriv; + PFNGLGETBUFFERPOINTERVPROC GetBufferPointerv; + PFNGLGETBUFFERSUBDATAPROC GetBufferSubData; + PFNGLGETCOMPRESSEDTEXIMAGEPROC GetCompressedTexImage; + PFNGLGETDOUBLEVPROC GetDoublev; + PFNGLGETERRORPROC GetError; + PFNGLGETFLOATVPROC GetFloatv; + PFNGLGETFRAGDATAINDEXPROC GetFragDataIndex; + PFNGLGETFRAGDATALOCATIONPROC GetFragDataLocation; + PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC GetFramebufferAttachmentParameteriv; + PFNGLGETINTEGER64I_VPROC GetInteger64i_v; + PFNGLGETINTEGER64VPROC GetInteger64v; + PFNGLGETINTEGERI_VPROC GetIntegeri_v; + PFNGLGETINTEGERVPROC GetIntegerv; + PFNGLGETMULTISAMPLEFVPROC GetMultisamplefv; + PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog; + PFNGLGETPROGRAMIVPROC GetProgramiv; + PFNGLGETQUERYOBJECTI64VPROC GetQueryObjecti64v; + PFNGLGETQUERYOBJECTIVPROC GetQueryObjectiv; + PFNGLGETQUERYOBJECTUI64VPROC GetQueryObjectui64v; + PFNGLGETQUERYOBJECTUIVPROC GetQueryObjectuiv; + PFNGLGETQUERYIVPROC GetQueryiv; + PFNGLGETRENDERBUFFERPARAMETERIVPROC GetRenderbufferParameteriv; + PFNGLGETSAMPLERPARAMETERIIVPROC GetSamplerParameterIiv; + PFNGLGETSAMPLERPARAMETERIUIVPROC GetSamplerParameterIuiv; + PFNGLGETSAMPLERPARAMETERFVPROC GetSamplerParameterfv; + PFNGLGETSAMPLERPARAMETERIVPROC GetSamplerParameteriv; + PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog; + PFNGLGETSHADERSOURCEPROC GetShaderSource; + PFNGLGETSHADERIVPROC GetShaderiv; + PFNGLGETSTRINGPROC GetString; + PFNGLGETSTRINGIPROC GetStringi; + PFNGLGETSYNCIVPROC GetSynciv; + PFNGLGETTEXIMAGEPROC GetTexImage; + PFNGLGETTEXLEVELPARAMETERFVPROC GetTexLevelParameterfv; + PFNGLGETTEXLEVELPARAMETERIVPROC GetTexLevelParameteriv; + PFNGLGETTEXPARAMETERIIVPROC GetTexParameterIiv; + PFNGLGETTEXPARAMETERIUIVPROC GetTexParameterIuiv; + PFNGLGETTEXPARAMETERFVPROC GetTexParameterfv; + PFNGLGETTEXPARAMETERIVPROC GetTexParameteriv; + PFNGLGETTRANSFORMFEEDBACKVARYINGPROC GetTransformFeedbackVarying; + PFNGLGETUNIFORMBLOCKINDEXPROC GetUniformBlockIndex; + PFNGLGETUNIFORMINDICESPROC GetUniformIndices; + PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation; + PFNGLGETUNIFORMFVPROC GetUniformfv; + PFNGLGETUNIFORMIVPROC GetUniformiv; + PFNGLGETUNIFORMUIVPROC GetUniformuiv; + PFNGLGETVERTEXATTRIBIIVPROC GetVertexAttribIiv; + PFNGLGETVERTEXATTRIBIUIVPROC GetVertexAttribIuiv; + PFNGLGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv; + PFNGLGETVERTEXATTRIBDVPROC GetVertexAttribdv; + PFNGLGETVERTEXATTRIBFVPROC GetVertexAttribfv; + PFNGLGETVERTEXATTRIBIVPROC GetVertexAttribiv; + PFNGLHINTPROC Hint; + PFNGLISBUFFERPROC IsBuffer; + PFNGLISENABLEDPROC IsEnabled; + PFNGLISENABLEDIPROC IsEnabledi; + PFNGLISFRAMEBUFFERPROC IsFramebuffer; + PFNGLISPROGRAMPROC IsProgram; + PFNGLISQUERYPROC IsQuery; + PFNGLISRENDERBUFFERPROC IsRenderbuffer; + PFNGLISSAMPLERPROC IsSampler; + PFNGLISSHADERPROC IsShader; + PFNGLISSYNCPROC IsSync; + PFNGLISTEXTUREPROC IsTexture; + PFNGLISVERTEXARRAYPROC IsVertexArray; + PFNGLLINEWIDTHPROC LineWidth; + PFNGLLINKPROGRAMPROC LinkProgram; + PFNGLLOGICOPPROC LogicOp; + PFNGLMAPBUFFERPROC MapBuffer; + PFNGLMAPBUFFERRANGEPROC MapBufferRange; + PFNGLMULTIDRAWARRAYSPROC MultiDrawArrays; + PFNGLMULTIDRAWELEMENTSPROC MultiDrawElements; + PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC MultiDrawElementsBaseVertex; + PFNGLPIXELSTOREFPROC PixelStoref; + PFNGLPIXELSTOREIPROC PixelStorei; + PFNGLPOINTPARAMETERFPROC PointParameterf; + PFNGLPOINTPARAMETERFVPROC PointParameterfv; + PFNGLPOINTPARAMETERIPROC PointParameteri; + PFNGLPOINTPARAMETERIVPROC PointParameteriv; + PFNGLPOINTSIZEPROC PointSize; + PFNGLPOLYGONMODEPROC PolygonMode; + PFNGLPOLYGONOFFSETPROC PolygonOffset; + PFNGLPRIMITIVERESTARTINDEXPROC PrimitiveRestartIndex; + PFNGLPROVOKINGVERTEXPROC ProvokingVertex; + PFNGLQUERYCOUNTERPROC QueryCounter; + PFNGLREADBUFFERPROC ReadBuffer; + PFNGLREADPIXELSPROC ReadPixels; + PFNGLRENDERBUFFERSTORAGEPROC RenderbufferStorage; + PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC RenderbufferStorageMultisample; + PFNGLSAMPLECOVERAGEPROC SampleCoverage; + PFNGLSAMPLEMASKIPROC SampleMaski; + PFNGLSAMPLERPARAMETERIIVPROC SamplerParameterIiv; + PFNGLSAMPLERPARAMETERIUIVPROC SamplerParameterIuiv; + PFNGLSAMPLERPARAMETERFPROC SamplerParameterf; + PFNGLSAMPLERPARAMETERFVPROC SamplerParameterfv; + PFNGLSAMPLERPARAMETERIPROC SamplerParameteri; + PFNGLSAMPLERPARAMETERIVPROC SamplerParameteriv; + PFNGLSCISSORPROC Scissor; + PFNGLSHADERSOURCEPROC ShaderSource; + PFNGLSTENCILFUNCPROC StencilFunc; + PFNGLSTENCILFUNCSEPARATEPROC StencilFuncSeparate; + PFNGLSTENCILMASKPROC StencilMask; + PFNGLSTENCILMASKSEPARATEPROC StencilMaskSeparate; + PFNGLSTENCILOPPROC StencilOp; + PFNGLSTENCILOPSEPARATEPROC StencilOpSeparate; + PFNGLTEXBUFFERPROC TexBuffer; + PFNGLTEXIMAGE1DPROC TexImage1D; + PFNGLTEXIMAGE2DPROC TexImage2D; + PFNGLTEXIMAGE2DMULTISAMPLEPROC TexImage2DMultisample; + PFNGLTEXIMAGE3DPROC TexImage3D; + PFNGLTEXIMAGE3DMULTISAMPLEPROC TexImage3DMultisample; + PFNGLTEXPARAMETERIIVPROC TexParameterIiv; + PFNGLTEXPARAMETERIUIVPROC TexParameterIuiv; + PFNGLTEXPARAMETERFPROC TexParameterf; + PFNGLTEXPARAMETERFVPROC TexParameterfv; + PFNGLTEXPARAMETERIPROC TexParameteri; + PFNGLTEXPARAMETERIVPROC TexParameteriv; + PFNGLTEXSUBIMAGE1DPROC TexSubImage1D; + PFNGLTEXSUBIMAGE2DPROC TexSubImage2D; + PFNGLTEXSUBIMAGE3DPROC TexSubImage3D; + PFNGLTRANSFORMFEEDBACKVARYINGSPROC TransformFeedbackVaryings; + PFNGLUNIFORM1FPROC Uniform1f; + PFNGLUNIFORM1FVPROC Uniform1fv; + PFNGLUNIFORM1IPROC Uniform1i; + PFNGLUNIFORM1IVPROC Uniform1iv; + PFNGLUNIFORM1UIPROC Uniform1ui; + PFNGLUNIFORM1UIVPROC Uniform1uiv; + PFNGLUNIFORM2FPROC Uniform2f; + PFNGLUNIFORM2FVPROC Uniform2fv; + PFNGLUNIFORM2IPROC Uniform2i; + PFNGLUNIFORM2IVPROC Uniform2iv; + PFNGLUNIFORM2UIPROC Uniform2ui; + PFNGLUNIFORM2UIVPROC Uniform2uiv; + PFNGLUNIFORM3FPROC Uniform3f; + PFNGLUNIFORM3FVPROC Uniform3fv; + PFNGLUNIFORM3IPROC Uniform3i; + PFNGLUNIFORM3IVPROC Uniform3iv; + PFNGLUNIFORM3UIPROC Uniform3ui; + PFNGLUNIFORM3UIVPROC Uniform3uiv; + PFNGLUNIFORM4FPROC Uniform4f; + PFNGLUNIFORM4FVPROC Uniform4fv; + PFNGLUNIFORM4IPROC Uniform4i; + PFNGLUNIFORM4IVPROC Uniform4iv; + PFNGLUNIFORM4UIPROC Uniform4ui; + PFNGLUNIFORM4UIVPROC Uniform4uiv; + PFNGLUNIFORMBLOCKBINDINGPROC UniformBlockBinding; + PFNGLUNIFORMMATRIX2FVPROC UniformMatrix2fv; + PFNGLUNIFORMMATRIX2X3FVPROC UniformMatrix2x3fv; + PFNGLUNIFORMMATRIX2X4FVPROC UniformMatrix2x4fv; + PFNGLUNIFORMMATRIX3FVPROC UniformMatrix3fv; + PFNGLUNIFORMMATRIX3X2FVPROC UniformMatrix3x2fv; + PFNGLUNIFORMMATRIX3X4FVPROC UniformMatrix3x4fv; + PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv; + PFNGLUNIFORMMATRIX4X2FVPROC UniformMatrix4x2fv; + PFNGLUNIFORMMATRIX4X3FVPROC UniformMatrix4x3fv; + PFNGLUNMAPBUFFERPROC UnmapBuffer; + PFNGLUSEPROGRAMPROC UseProgram; + PFNGLVALIDATEPROGRAMPROC ValidateProgram; + PFNGLVERTEXATTRIB1DPROC VertexAttrib1d; + PFNGLVERTEXATTRIB1DVPROC VertexAttrib1dv; + PFNGLVERTEXATTRIB1FPROC VertexAttrib1f; + PFNGLVERTEXATTRIB1FVPROC VertexAttrib1fv; + PFNGLVERTEXATTRIB1SPROC VertexAttrib1s; + PFNGLVERTEXATTRIB1SVPROC VertexAttrib1sv; + PFNGLVERTEXATTRIB2DPROC VertexAttrib2d; + PFNGLVERTEXATTRIB2DVPROC VertexAttrib2dv; + PFNGLVERTEXATTRIB2FPROC VertexAttrib2f; + PFNGLVERTEXATTRIB2FVPROC VertexAttrib2fv; + PFNGLVERTEXATTRIB2SPROC VertexAttrib2s; + PFNGLVERTEXATTRIB2SVPROC VertexAttrib2sv; + PFNGLVERTEXATTRIB3DPROC VertexAttrib3d; + PFNGLVERTEXATTRIB3DVPROC VertexAttrib3dv; + PFNGLVERTEXATTRIB3FPROC VertexAttrib3f; + PFNGLVERTEXATTRIB3FVPROC VertexAttrib3fv; + PFNGLVERTEXATTRIB3SPROC VertexAttrib3s; + PFNGLVERTEXATTRIB3SVPROC VertexAttrib3sv; + PFNGLVERTEXATTRIB4NBVPROC VertexAttrib4Nbv; + PFNGLVERTEXATTRIB4NIVPROC VertexAttrib4Niv; + PFNGLVERTEXATTRIB4NSVPROC VertexAttrib4Nsv; + PFNGLVERTEXATTRIB4NUBPROC VertexAttrib4Nub; + PFNGLVERTEXATTRIB4NUBVPROC VertexAttrib4Nubv; + PFNGLVERTEXATTRIB4NUIVPROC VertexAttrib4Nuiv; + PFNGLVERTEXATTRIB4NUSVPROC VertexAttrib4Nusv; + PFNGLVERTEXATTRIB4BVPROC VertexAttrib4bv; + PFNGLVERTEXATTRIB4DPROC VertexAttrib4d; + PFNGLVERTEXATTRIB4DVPROC VertexAttrib4dv; + PFNGLVERTEXATTRIB4FPROC VertexAttrib4f; + PFNGLVERTEXATTRIB4FVPROC VertexAttrib4fv; + PFNGLVERTEXATTRIB4IVPROC VertexAttrib4iv; + PFNGLVERTEXATTRIB4SPROC VertexAttrib4s; + PFNGLVERTEXATTRIB4SVPROC VertexAttrib4sv; + PFNGLVERTEXATTRIB4UBVPROC VertexAttrib4ubv; + PFNGLVERTEXATTRIB4UIVPROC VertexAttrib4uiv; + PFNGLVERTEXATTRIB4USVPROC VertexAttrib4usv; + PFNGLVERTEXATTRIBDIVISORPROC VertexAttribDivisor; + PFNGLVERTEXATTRIBI1IPROC VertexAttribI1i; + PFNGLVERTEXATTRIBI1IVPROC VertexAttribI1iv; + PFNGLVERTEXATTRIBI1UIPROC VertexAttribI1ui; + PFNGLVERTEXATTRIBI1UIVPROC VertexAttribI1uiv; + PFNGLVERTEXATTRIBI2IPROC VertexAttribI2i; + PFNGLVERTEXATTRIBI2IVPROC VertexAttribI2iv; + PFNGLVERTEXATTRIBI2UIPROC VertexAttribI2ui; + PFNGLVERTEXATTRIBI2UIVPROC VertexAttribI2uiv; + PFNGLVERTEXATTRIBI3IPROC VertexAttribI3i; + PFNGLVERTEXATTRIBI3IVPROC VertexAttribI3iv; + PFNGLVERTEXATTRIBI3UIPROC VertexAttribI3ui; + PFNGLVERTEXATTRIBI3UIVPROC VertexAttribI3uiv; + PFNGLVERTEXATTRIBI4BVPROC VertexAttribI4bv; + PFNGLVERTEXATTRIBI4IPROC VertexAttribI4i; + PFNGLVERTEXATTRIBI4IVPROC VertexAttribI4iv; + PFNGLVERTEXATTRIBI4SVPROC VertexAttribI4sv; + PFNGLVERTEXATTRIBI4UBVPROC VertexAttribI4ubv; + PFNGLVERTEXATTRIBI4UIPROC VertexAttribI4ui; + PFNGLVERTEXATTRIBI4UIVPROC VertexAttribI4uiv; + PFNGLVERTEXATTRIBI4USVPROC VertexAttribI4usv; + PFNGLVERTEXATTRIBIPOINTERPROC VertexAttribIPointer; + PFNGLVERTEXATTRIBP1UIPROC VertexAttribP1ui; + PFNGLVERTEXATTRIBP1UIVPROC VertexAttribP1uiv; + PFNGLVERTEXATTRIBP2UIPROC VertexAttribP2ui; + PFNGLVERTEXATTRIBP2UIVPROC VertexAttribP2uiv; + PFNGLVERTEXATTRIBP3UIPROC VertexAttribP3ui; + PFNGLVERTEXATTRIBP3UIVPROC VertexAttribP3uiv; + PFNGLVERTEXATTRIBP4UIPROC VertexAttribP4ui; + PFNGLVERTEXATTRIBP4UIVPROC VertexAttribP4uiv; + PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer; + PFNGLVIEWPORTPROC Viewport; + PFNGLWAITSYNCPROC WaitSync; + + void* glad_loader_handle; +} GladGLContext; -GLAD_API_CALL int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr); -GLAD_API_CALL int gladLoadGL( GLADloadfunc load); + +GLAD_API_CALL int gladLoadGLContextUserPtr(GladGLContext *context, GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadGLContext(GladGLContext *context, GLADloadfunc load); #ifdef GLAD_GL -GLAD_API_CALL int gladLoaderLoadGL(void); -GLAD_API_CALL void gladLoaderUnloadGL(void); +GLAD_API_CALL int gladLoaderLoadGLContext(GladGLContext *context); +GLAD_API_CALL void gladLoaderUnloadGLContext(GladGLContext *context); #endif diff --git a/vendor/glad/src/gl.c b/vendor/glad/src/gl.c index 840cefc57..ad49f387a 100644 --- a/vendor/glad/src/gl.c +++ b/vendor/glad/src/gl.c @@ -1,3 +1,6 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ #include #include #include @@ -20,749 +23,393 @@ extern "C" { -int GLAD_GL_VERSION_1_0 = 0; -int GLAD_GL_VERSION_1_1 = 0; -int GLAD_GL_VERSION_1_2 = 0; -int GLAD_GL_VERSION_1_3 = 0; -int GLAD_GL_VERSION_1_4 = 0; -int GLAD_GL_VERSION_1_5 = 0; -int GLAD_GL_VERSION_2_0 = 0; -int GLAD_GL_VERSION_2_1 = 0; -int GLAD_GL_VERSION_3_0 = 0; -int GLAD_GL_VERSION_3_1 = 0; -int GLAD_GL_VERSION_3_2 = 0; -int GLAD_GL_VERSION_3_3 = 0; -PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; -PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; -PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; -PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; -PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; -PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; -PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; -PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; -PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; -PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; -PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL; -PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; -PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; -PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; -PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; -PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; -PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; -PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; -PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; -PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; -PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; -PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; -PFNGLBUFFERDATAPROC glad_glBufferData = NULL; -PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; -PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; -PFNGLCLEARPROC glad_glClear = NULL; -PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; -PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; -PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; -PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; -PFNGLCLEARCOLORPROC glad_glClearColor = NULL; -PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; -PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; -PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; -PFNGLCOLORMASKPROC glad_glColorMask = NULL; -PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; -PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; -PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; -PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; -PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; -PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; -PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; -PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; -PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; -PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; -PFNGLCREATESHADERPROC glad_glCreateShader = NULL; -PFNGLCULLFACEPROC glad_glCullFace = NULL; -PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; -PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; -PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; -PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; -PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; -PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; -PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; -PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; -PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; -PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; -PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; -PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; -PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; -PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; -PFNGLDISABLEPROC glad_glDisable = NULL; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; -PFNGLDISABLEIPROC glad_glDisablei = NULL; -PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; -PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; -PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; -PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; -PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; -PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL; -PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; -PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; -PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; -PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; -PFNGLENABLEPROC glad_glEnable = NULL; -PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; -PFNGLENABLEIPROC glad_glEnablei = NULL; -PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; -PFNGLENDQUERYPROC glad_glEndQuery = NULL; -PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; -PFNGLFENCESYNCPROC glad_glFenceSync = NULL; -PFNGLFINISHPROC glad_glFinish = NULL; -PFNGLFLUSHPROC glad_glFlush = NULL; -PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; -PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; -PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; -PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; -PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; -PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; -PFNGLFRONTFACEPROC glad_glFrontFace = NULL; -PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; -PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; -PFNGLGENQUERIESPROC glad_glGenQueries = NULL; -PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; -PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; -PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; -PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; -PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; -PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; -PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; -PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; -PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; -PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL; -PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; -PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; -PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; -PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; -PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; -PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; -PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; -PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; -PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; -PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; -PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; -PFNGLGETERRORPROC glad_glGetError = NULL; -PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; -PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL; -PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; -PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; -PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; -PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; -PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; -PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; -PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; -PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; -PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL; -PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; -PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL; -PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; -PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; -PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL; -PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL; -PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; -PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; -PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; -PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; -PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; -PFNGLGETSTRINGPROC glad_glGetString = NULL; -PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; -PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; -PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; -PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; -PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; -PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; -PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; -PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; -PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; -PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; -PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; -PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; -PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; -PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; -PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; -PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; -PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; -PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; -PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; -PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; -PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; -PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; -PFNGLHINTPROC glad_glHint = NULL; -PFNGLISBUFFERPROC glad_glIsBuffer = NULL; -PFNGLISENABLEDPROC glad_glIsEnabled = NULL; -PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; -PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; -PFNGLISPROGRAMPROC glad_glIsProgram = NULL; -PFNGLISQUERYPROC glad_glIsQuery = NULL; -PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; -PFNGLISSAMPLERPROC glad_glIsSampler = NULL; -PFNGLISSHADERPROC glad_glIsShader = NULL; -PFNGLISSYNCPROC glad_glIsSync = NULL; -PFNGLISTEXTUREPROC glad_glIsTexture = NULL; -PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; -PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; -PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; -PFNGLLOGICOPPROC glad_glLogicOp = NULL; -PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; -PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; -PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; -PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; -PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; -PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; -PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; -PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; -PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; -PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; -PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; -PFNGLPOINTSIZEPROC glad_glPointSize = NULL; -PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; -PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; -PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; -PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; -PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL; -PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; -PFNGLREADPIXELSPROC glad_glReadPixels = NULL; -PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; -PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; -PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; -PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL; -PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL; -PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; -PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; -PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; -PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; -PFNGLSCISSORPROC glad_glScissor = NULL; -PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; -PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; -PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; -PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; -PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; -PFNGLSTENCILOPPROC glad_glStencilOp = NULL; -PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; -PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; -PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; -PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; -PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; -PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; -PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL; -PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; -PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; -PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; -PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; -PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; -PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; -PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; -PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; -PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; -PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; -PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; -PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; -PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; -PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; -PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; -PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; -PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; -PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; -PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; -PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; -PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; -PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; -PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; -PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; -PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; -PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; -PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; -PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; -PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; -PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; -PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; -PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; -PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; -PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; -PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; -PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; -PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; -PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; -PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; -PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; -PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; -PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; -PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; -PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; -PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; -PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; -PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; -PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; -PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; -PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; -PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; -PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; -PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; -PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; -PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; -PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; -PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; -PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; -PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; -PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; -PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; -PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; -PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; -PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; -PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; -PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; -PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; -PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; -PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; -PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; -PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; -PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; -PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; -PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; -PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; -PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; -PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; -PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; -PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; -PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; -PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; -PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; -PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; -PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; -PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; -PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; -PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; -PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; -PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; -PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; -PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; -PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; -PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; -PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; -PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; -PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; -PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; -PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; -PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; -PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; -PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; -PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; -PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; -PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; -PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL; -PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL; -PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL; -PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL; -PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL; -PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL; -PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL; -PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL; -PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; -PFNGLVIEWPORTPROC glad_glViewport = NULL; -PFNGLWAITSYNCPROC glad_glWaitSync = NULL; -static void glad_gl_load_GL_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_0) return; - glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc"); - glad_glClear = (PFNGLCLEARPROC) load(userptr, "glClear"); - glad_glClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor"); - glad_glClearDepth = (PFNGLCLEARDEPTHPROC) load(userptr, "glClearDepth"); - glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil"); - glad_glColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask"); - glad_glCullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace"); - glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc"); - glad_glDepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask"); - glad_glDepthRange = (PFNGLDEPTHRANGEPROC) load(userptr, "glDepthRange"); - glad_glDisable = (PFNGLDISABLEPROC) load(userptr, "glDisable"); - glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC) load(userptr, "glDrawBuffer"); - glad_glEnable = (PFNGLENABLEPROC) load(userptr, "glEnable"); - glad_glFinish = (PFNGLFINISHPROC) load(userptr, "glFinish"); - glad_glFlush = (PFNGLFLUSHPROC) load(userptr, "glFlush"); - glad_glFrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace"); - glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv"); - glad_glGetDoublev = (PFNGLGETDOUBLEVPROC) load(userptr, "glGetDoublev"); - glad_glGetError = (PFNGLGETERRORPROC) load(userptr, "glGetError"); - glad_glGetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv"); - glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv"); - glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); - glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC) load(userptr, "glGetTexImage"); - glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load(userptr, "glGetTexLevelParameterfv"); - glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load(userptr, "glGetTexLevelParameteriv"); - glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv"); - glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv"); - glad_glHint = (PFNGLHINTPROC) load(userptr, "glHint"); - glad_glIsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled"); - glad_glLineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth"); - glad_glLogicOp = (PFNGLLOGICOPPROC) load(userptr, "glLogicOp"); - glad_glPixelStoref = (PFNGLPIXELSTOREFPROC) load(userptr, "glPixelStoref"); - glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei"); - glad_glPointSize = (PFNGLPOINTSIZEPROC) load(userptr, "glPointSize"); - glad_glPolygonMode = (PFNGLPOLYGONMODEPROC) load(userptr, "glPolygonMode"); - glad_glReadBuffer = (PFNGLREADBUFFERPROC) load(userptr, "glReadBuffer"); - glad_glReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels"); - glad_glScissor = (PFNGLSCISSORPROC) load(userptr, "glScissor"); - glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc"); - glad_glStencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask"); - glad_glStencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp"); - glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC) load(userptr, "glTexImage1D"); - glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D"); - glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf"); - glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv"); - glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri"); - glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv"); - glad_glViewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); +static void glad_gl_load_GL_VERSION_1_0(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_1_0) return; + context->BlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc"); + context->Clear = (PFNGLCLEARPROC) load(userptr, "glClear"); + context->ClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor"); + context->ClearDepth = (PFNGLCLEARDEPTHPROC) load(userptr, "glClearDepth"); + context->ClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil"); + context->ColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask"); + context->CullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace"); + context->DepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc"); + context->DepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask"); + context->DepthRange = (PFNGLDEPTHRANGEPROC) load(userptr, "glDepthRange"); + context->Disable = (PFNGLDISABLEPROC) load(userptr, "glDisable"); + context->DrawBuffer = (PFNGLDRAWBUFFERPROC) load(userptr, "glDrawBuffer"); + context->Enable = (PFNGLENABLEPROC) load(userptr, "glEnable"); + context->Finish = (PFNGLFINISHPROC) load(userptr, "glFinish"); + context->Flush = (PFNGLFLUSHPROC) load(userptr, "glFlush"); + context->FrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace"); + context->GetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv"); + context->GetDoublev = (PFNGLGETDOUBLEVPROC) load(userptr, "glGetDoublev"); + context->GetError = (PFNGLGETERRORPROC) load(userptr, "glGetError"); + context->GetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv"); + context->GetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv"); + context->GetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + context->GetTexImage = (PFNGLGETTEXIMAGEPROC) load(userptr, "glGetTexImage"); + context->GetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load(userptr, "glGetTexLevelParameterfv"); + context->GetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load(userptr, "glGetTexLevelParameteriv"); + context->GetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv"); + context->GetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv"); + context->Hint = (PFNGLHINTPROC) load(userptr, "glHint"); + context->IsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled"); + context->LineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth"); + context->LogicOp = (PFNGLLOGICOPPROC) load(userptr, "glLogicOp"); + context->PixelStoref = (PFNGLPIXELSTOREFPROC) load(userptr, "glPixelStoref"); + context->PixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei"); + context->PointSize = (PFNGLPOINTSIZEPROC) load(userptr, "glPointSize"); + context->PolygonMode = (PFNGLPOLYGONMODEPROC) load(userptr, "glPolygonMode"); + context->ReadBuffer = (PFNGLREADBUFFERPROC) load(userptr, "glReadBuffer"); + context->ReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels"); + context->Scissor = (PFNGLSCISSORPROC) load(userptr, "glScissor"); + context->StencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc"); + context->StencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask"); + context->StencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp"); + context->TexImage1D = (PFNGLTEXIMAGE1DPROC) load(userptr, "glTexImage1D"); + context->TexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D"); + context->TexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf"); + context->TexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv"); + context->TexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri"); + context->TexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv"); + context->Viewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); } -static void glad_gl_load_GL_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_1) return; - glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture"); - glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) load(userptr, "glCopyTexImage1D"); - glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D"); - glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) load(userptr, "glCopyTexSubImage1D"); - glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D"); - glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures"); - glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays"); - glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements"); - glad_glGenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures"); - glad_glIsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture"); - glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset"); - glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) load(userptr, "glTexSubImage1D"); - glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D"); +static void glad_gl_load_GL_VERSION_1_1(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_1_1) return; + context->BindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture"); + context->CopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) load(userptr, "glCopyTexImage1D"); + context->CopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D"); + context->CopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) load(userptr, "glCopyTexSubImage1D"); + context->CopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D"); + context->DeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures"); + context->DrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays"); + context->DrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements"); + context->GenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures"); + context->IsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture"); + context->PolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset"); + context->TexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) load(userptr, "glTexSubImage1D"); + context->TexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D"); } -static void glad_gl_load_GL_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_2) return; - glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load(userptr, "glCopyTexSubImage3D"); - glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load(userptr, "glDrawRangeElements"); - glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC) load(userptr, "glTexImage3D"); - glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load(userptr, "glTexSubImage3D"); +static void glad_gl_load_GL_VERSION_1_2(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_1_2) return; + context->CopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load(userptr, "glCopyTexSubImage3D"); + context->DrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load(userptr, "glDrawRangeElements"); + context->TexImage3D = (PFNGLTEXIMAGE3DPROC) load(userptr, "glTexImage3D"); + context->TexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load(userptr, "glTexSubImage3D"); } -static void glad_gl_load_GL_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_3) return; - glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture"); - glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) load(userptr, "glCompressedTexImage1D"); - glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D"); - glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load(userptr, "glCompressedTexImage3D"); - glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) load(userptr, "glCompressedTexSubImage1D"); - glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D"); - glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load(userptr, "glCompressedTexSubImage3D"); - glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) load(userptr, "glGetCompressedTexImage"); - glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage"); +static void glad_gl_load_GL_VERSION_1_3(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_1_3) return; + context->ActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture"); + context->CompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) load(userptr, "glCompressedTexImage1D"); + context->CompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D"); + context->CompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load(userptr, "glCompressedTexImage3D"); + context->CompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) load(userptr, "glCompressedTexSubImage1D"); + context->CompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D"); + context->CompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load(userptr, "glCompressedTexSubImage3D"); + context->GetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) load(userptr, "glGetCompressedTexImage"); + context->SampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage"); } -static void glad_gl_load_GL_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_4) return; - glad_glBlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor"); - glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation"); - glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate"); - glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) load(userptr, "glMultiDrawArrays"); - glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) load(userptr, "glMultiDrawElements"); - glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC) load(userptr, "glPointParameterf"); - glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC) load(userptr, "glPointParameterfv"); - glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC) load(userptr, "glPointParameteri"); - glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC) load(userptr, "glPointParameteriv"); +static void glad_gl_load_GL_VERSION_1_4(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_1_4) return; + context->BlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor"); + context->BlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation"); + context->BlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate"); + context->MultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) load(userptr, "glMultiDrawArrays"); + context->MultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) load(userptr, "glMultiDrawElements"); + context->PointParameterf = (PFNGLPOINTPARAMETERFPROC) load(userptr, "glPointParameterf"); + context->PointParameterfv = (PFNGLPOINTPARAMETERFVPROC) load(userptr, "glPointParameterfv"); + context->PointParameteri = (PFNGLPOINTPARAMETERIPROC) load(userptr, "glPointParameteri"); + context->PointParameteriv = (PFNGLPOINTPARAMETERIVPROC) load(userptr, "glPointParameteriv"); } -static void glad_gl_load_GL_VERSION_1_5( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_5) return; - glad_glBeginQuery = (PFNGLBEGINQUERYPROC) load(userptr, "glBeginQuery"); - glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer"); - glad_glBufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData"); - glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData"); - glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers"); - glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC) load(userptr, "glDeleteQueries"); - glad_glEndQuery = (PFNGLENDQUERYPROC) load(userptr, "glEndQuery"); - glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers"); - glad_glGenQueries = (PFNGLGENQUERIESPROC) load(userptr, "glGenQueries"); - glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv"); - glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load(userptr, "glGetBufferPointerv"); - glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) load(userptr, "glGetBufferSubData"); - glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) load(userptr, "glGetQueryObjectiv"); - glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load(userptr, "glGetQueryObjectuiv"); - glad_glGetQueryiv = (PFNGLGETQUERYIVPROC) load(userptr, "glGetQueryiv"); - glad_glIsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer"); - glad_glIsQuery = (PFNGLISQUERYPROC) load(userptr, "glIsQuery"); - glad_glMapBuffer = (PFNGLMAPBUFFERPROC) load(userptr, "glMapBuffer"); - glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load(userptr, "glUnmapBuffer"); +static void glad_gl_load_GL_VERSION_1_5(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_1_5) return; + context->BeginQuery = (PFNGLBEGINQUERYPROC) load(userptr, "glBeginQuery"); + context->BindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer"); + context->BufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData"); + context->BufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData"); + context->DeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers"); + context->DeleteQueries = (PFNGLDELETEQUERIESPROC) load(userptr, "glDeleteQueries"); + context->EndQuery = (PFNGLENDQUERYPROC) load(userptr, "glEndQuery"); + context->GenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers"); + context->GenQueries = (PFNGLGENQUERIESPROC) load(userptr, "glGenQueries"); + context->GetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv"); + context->GetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load(userptr, "glGetBufferPointerv"); + context->GetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) load(userptr, "glGetBufferSubData"); + context->GetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) load(userptr, "glGetQueryObjectiv"); + context->GetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load(userptr, "glGetQueryObjectuiv"); + context->GetQueryiv = (PFNGLGETQUERYIVPROC) load(userptr, "glGetQueryiv"); + context->IsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer"); + context->IsQuery = (PFNGLISQUERYPROC) load(userptr, "glIsQuery"); + context->MapBuffer = (PFNGLMAPBUFFERPROC) load(userptr, "glMapBuffer"); + context->UnmapBuffer = (PFNGLUNMAPBUFFERPROC) load(userptr, "glUnmapBuffer"); } -static void glad_gl_load_GL_VERSION_2_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_2_0) return; - glad_glAttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader"); - glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation"); - glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate"); - glad_glCompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader"); - glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram"); - glad_glCreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader"); - glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram"); - glad_glDeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader"); - glad_glDetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader"); - glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray"); - glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load(userptr, "glDrawBuffers"); - glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray"); - glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib"); - glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform"); - glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders"); - glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation"); - glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog"); - glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv"); - glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog"); - glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource"); - glad_glGetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv"); - glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation"); - glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv"); - glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv"); - glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv"); - glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) load(userptr, "glGetVertexAttribdv"); - glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv"); - glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv"); - glad_glIsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram"); - glad_glIsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader"); - glad_glLinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram"); - glad_glShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource"); - glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate"); - glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate"); - glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate"); - glad_glUniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f"); - glad_glUniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv"); - glad_glUniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i"); - glad_glUniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv"); - glad_glUniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f"); - glad_glUniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv"); - glad_glUniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i"); - glad_glUniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv"); - glad_glUniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f"); - glad_glUniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv"); - glad_glUniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i"); - glad_glUniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv"); - glad_glUniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f"); - glad_glUniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv"); - glad_glUniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i"); - glad_glUniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv"); - glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv"); - glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv"); - glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv"); - glad_glUseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram"); - glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram"); - glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) load(userptr, "glVertexAttrib1d"); - glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) load(userptr, "glVertexAttrib1dv"); - glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f"); - glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv"); - glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) load(userptr, "glVertexAttrib1s"); - glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) load(userptr, "glVertexAttrib1sv"); - glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) load(userptr, "glVertexAttrib2d"); - glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) load(userptr, "glVertexAttrib2dv"); - glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f"); - glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv"); - glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) load(userptr, "glVertexAttrib2s"); - glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) load(userptr, "glVertexAttrib2sv"); - glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) load(userptr, "glVertexAttrib3d"); - glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) load(userptr, "glVertexAttrib3dv"); - glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f"); - glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv"); - glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) load(userptr, "glVertexAttrib3s"); - glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) load(userptr, "glVertexAttrib3sv"); - glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) load(userptr, "glVertexAttrib4Nbv"); - glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) load(userptr, "glVertexAttrib4Niv"); - glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) load(userptr, "glVertexAttrib4Nsv"); - glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) load(userptr, "glVertexAttrib4Nub"); - glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) load(userptr, "glVertexAttrib4Nubv"); - glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) load(userptr, "glVertexAttrib4Nuiv"); - glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) load(userptr, "glVertexAttrib4Nusv"); - glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) load(userptr, "glVertexAttrib4bv"); - glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) load(userptr, "glVertexAttrib4d"); - glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) load(userptr, "glVertexAttrib4dv"); - glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f"); - glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv"); - glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) load(userptr, "glVertexAttrib4iv"); - glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) load(userptr, "glVertexAttrib4s"); - glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) load(userptr, "glVertexAttrib4sv"); - glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) load(userptr, "glVertexAttrib4ubv"); - glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) load(userptr, "glVertexAttrib4uiv"); - glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) load(userptr, "glVertexAttrib4usv"); - glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer"); +static void glad_gl_load_GL_VERSION_2_0(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_2_0) return; + context->AttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader"); + context->BindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation"); + context->BlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate"); + context->CompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader"); + context->CreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram"); + context->CreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader"); + context->DeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram"); + context->DeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader"); + context->DetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader"); + context->DisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray"); + context->DrawBuffers = (PFNGLDRAWBUFFERSPROC) load(userptr, "glDrawBuffers"); + context->EnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray"); + context->GetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib"); + context->GetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform"); + context->GetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders"); + context->GetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation"); + context->GetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog"); + context->GetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv"); + context->GetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog"); + context->GetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource"); + context->GetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv"); + context->GetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation"); + context->GetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv"); + context->GetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv"); + context->GetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv"); + context->GetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) load(userptr, "glGetVertexAttribdv"); + context->GetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv"); + context->GetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv"); + context->IsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram"); + context->IsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader"); + context->LinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram"); + context->ShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource"); + context->StencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate"); + context->StencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate"); + context->StencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate"); + context->Uniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f"); + context->Uniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv"); + context->Uniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i"); + context->Uniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv"); + context->Uniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f"); + context->Uniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv"); + context->Uniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i"); + context->Uniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv"); + context->Uniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f"); + context->Uniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv"); + context->Uniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i"); + context->Uniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv"); + context->Uniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f"); + context->Uniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv"); + context->Uniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i"); + context->Uniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv"); + context->UniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv"); + context->UniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv"); + context->UniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv"); + context->UseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram"); + context->ValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram"); + context->VertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) load(userptr, "glVertexAttrib1d"); + context->VertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) load(userptr, "glVertexAttrib1dv"); + context->VertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f"); + context->VertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv"); + context->VertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) load(userptr, "glVertexAttrib1s"); + context->VertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) load(userptr, "glVertexAttrib1sv"); + context->VertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) load(userptr, "glVertexAttrib2d"); + context->VertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) load(userptr, "glVertexAttrib2dv"); + context->VertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f"); + context->VertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv"); + context->VertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) load(userptr, "glVertexAttrib2s"); + context->VertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) load(userptr, "glVertexAttrib2sv"); + context->VertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) load(userptr, "glVertexAttrib3d"); + context->VertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) load(userptr, "glVertexAttrib3dv"); + context->VertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f"); + context->VertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv"); + context->VertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) load(userptr, "glVertexAttrib3s"); + context->VertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) load(userptr, "glVertexAttrib3sv"); + context->VertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) load(userptr, "glVertexAttrib4Nbv"); + context->VertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) load(userptr, "glVertexAttrib4Niv"); + context->VertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) load(userptr, "glVertexAttrib4Nsv"); + context->VertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) load(userptr, "glVertexAttrib4Nub"); + context->VertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) load(userptr, "glVertexAttrib4Nubv"); + context->VertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) load(userptr, "glVertexAttrib4Nuiv"); + context->VertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) load(userptr, "glVertexAttrib4Nusv"); + context->VertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) load(userptr, "glVertexAttrib4bv"); + context->VertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) load(userptr, "glVertexAttrib4d"); + context->VertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) load(userptr, "glVertexAttrib4dv"); + context->VertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f"); + context->VertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv"); + context->VertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) load(userptr, "glVertexAttrib4iv"); + context->VertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) load(userptr, "glVertexAttrib4s"); + context->VertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) load(userptr, "glVertexAttrib4sv"); + context->VertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) load(userptr, "glVertexAttrib4ubv"); + context->VertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) load(userptr, "glVertexAttrib4uiv"); + context->VertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) load(userptr, "glVertexAttrib4usv"); + context->VertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer"); } -static void glad_gl_load_GL_VERSION_2_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_2_1) return; - glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load(userptr, "glUniformMatrix2x3fv"); - glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load(userptr, "glUniformMatrix2x4fv"); - glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load(userptr, "glUniformMatrix3x2fv"); - glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load(userptr, "glUniformMatrix3x4fv"); - glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load(userptr, "glUniformMatrix4x2fv"); - glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load(userptr, "glUniformMatrix4x3fv"); +static void glad_gl_load_GL_VERSION_2_1(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_2_1) return; + context->UniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load(userptr, "glUniformMatrix2x3fv"); + context->UniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load(userptr, "glUniformMatrix2x4fv"); + context->UniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load(userptr, "glUniformMatrix3x2fv"); + context->UniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load(userptr, "glUniformMatrix3x4fv"); + context->UniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load(userptr, "glUniformMatrix4x2fv"); + context->UniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load(userptr, "glUniformMatrix4x3fv"); } -static void glad_gl_load_GL_VERSION_3_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_3_0) return; - glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) load(userptr, "glBeginConditionalRender"); - glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load(userptr, "glBeginTransformFeedback"); - glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); - glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); - glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) load(userptr, "glBindFragDataLocation"); - glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); - glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); - glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load(userptr, "glBindVertexArray"); - glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer"); - glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); - glad_glClampColor = (PFNGLCLAMPCOLORPROC) load(userptr, "glClampColor"); - glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load(userptr, "glClearBufferfi"); - glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load(userptr, "glClearBufferfv"); - glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load(userptr, "glClearBufferiv"); - glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load(userptr, "glClearBufferuiv"); - glad_glColorMaski = (PFNGLCOLORMASKIPROC) load(userptr, "glColorMaski"); - glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); - glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); - glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load(userptr, "glDeleteVertexArrays"); - glad_glDisablei = (PFNGLDISABLEIPROC) load(userptr, "glDisablei"); - glad_glEnablei = (PFNGLENABLEIPROC) load(userptr, "glEnablei"); - glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) load(userptr, "glEndConditionalRender"); - glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load(userptr, "glEndTransformFeedback"); - glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange"); - glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); - glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load(userptr, "glFramebufferTexture1D"); - glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); - glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load(userptr, "glFramebufferTexture3D"); - glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer"); - glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); - glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); - glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load(userptr, "glGenVertexArrays"); - glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); - glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load(userptr, "glGetBooleani_v"); - glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load(userptr, "glGetFragDataLocation"); - glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); - glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); - glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); - glad_glGetStringi = (PFNGLGETSTRINGIPROC) load(userptr, "glGetStringi"); - glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) load(userptr, "glGetTexParameterIiv"); - glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) load(userptr, "glGetTexParameterIuiv"); - glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load(userptr, "glGetTransformFeedbackVarying"); - glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load(userptr, "glGetUniformuiv"); - glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load(userptr, "glGetVertexAttribIiv"); - glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load(userptr, "glGetVertexAttribIuiv"); - glad_glIsEnabledi = (PFNGLISENABLEDIPROC) load(userptr, "glIsEnabledi"); - glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); - glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); - glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load(userptr, "glIsVertexArray"); - glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load(userptr, "glMapBufferRange"); - glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); - glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample"); - glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) load(userptr, "glTexParameterIiv"); - glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) load(userptr, "glTexParameterIuiv"); - glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load(userptr, "glTransformFeedbackVaryings"); - glad_glUniform1ui = (PFNGLUNIFORM1UIPROC) load(userptr, "glUniform1ui"); - glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load(userptr, "glUniform1uiv"); - glad_glUniform2ui = (PFNGLUNIFORM2UIPROC) load(userptr, "glUniform2ui"); - glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load(userptr, "glUniform2uiv"); - glad_glUniform3ui = (PFNGLUNIFORM3UIPROC) load(userptr, "glUniform3ui"); - glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load(userptr, "glUniform3uiv"); - glad_glUniform4ui = (PFNGLUNIFORM4UIPROC) load(userptr, "glUniform4ui"); - glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load(userptr, "glUniform4uiv"); - glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) load(userptr, "glVertexAttribI1i"); - glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) load(userptr, "glVertexAttribI1iv"); - glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) load(userptr, "glVertexAttribI1ui"); - glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) load(userptr, "glVertexAttribI1uiv"); - glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) load(userptr, "glVertexAttribI2i"); - glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) load(userptr, "glVertexAttribI2iv"); - glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) load(userptr, "glVertexAttribI2ui"); - glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) load(userptr, "glVertexAttribI2uiv"); - glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) load(userptr, "glVertexAttribI3i"); - glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) load(userptr, "glVertexAttribI3iv"); - glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) load(userptr, "glVertexAttribI3ui"); - glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) load(userptr, "glVertexAttribI3uiv"); - glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) load(userptr, "glVertexAttribI4bv"); - glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load(userptr, "glVertexAttribI4i"); - glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load(userptr, "glVertexAttribI4iv"); - glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) load(userptr, "glVertexAttribI4sv"); - glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) load(userptr, "glVertexAttribI4ubv"); - glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load(userptr, "glVertexAttribI4ui"); - glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load(userptr, "glVertexAttribI4uiv"); - glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) load(userptr, "glVertexAttribI4usv"); - glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load(userptr, "glVertexAttribIPointer"); +static void glad_gl_load_GL_VERSION_3_0(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_3_0) return; + context->BeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) load(userptr, "glBeginConditionalRender"); + context->BeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load(userptr, "glBeginTransformFeedback"); + context->BindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + context->BindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + context->BindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) load(userptr, "glBindFragDataLocation"); + context->BindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); + context->BindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); + context->BindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load(userptr, "glBindVertexArray"); + context->BlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer"); + context->CheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); + context->ClampColor = (PFNGLCLAMPCOLORPROC) load(userptr, "glClampColor"); + context->ClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load(userptr, "glClearBufferfi"); + context->ClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load(userptr, "glClearBufferfv"); + context->ClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load(userptr, "glClearBufferiv"); + context->ClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load(userptr, "glClearBufferuiv"); + context->ColorMaski = (PFNGLCOLORMASKIPROC) load(userptr, "glColorMaski"); + context->DeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); + context->DeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); + context->DeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load(userptr, "glDeleteVertexArrays"); + context->Disablei = (PFNGLDISABLEIPROC) load(userptr, "glDisablei"); + context->Enablei = (PFNGLENABLEIPROC) load(userptr, "glEnablei"); + context->EndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) load(userptr, "glEndConditionalRender"); + context->EndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load(userptr, "glEndTransformFeedback"); + context->FlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange"); + context->FramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); + context->FramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load(userptr, "glFramebufferTexture1D"); + context->FramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); + context->FramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load(userptr, "glFramebufferTexture3D"); + context->FramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer"); + context->GenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); + context->GenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); + context->GenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load(userptr, "glGenVertexArrays"); + context->GenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); + context->GetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load(userptr, "glGetBooleani_v"); + context->GetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load(userptr, "glGetFragDataLocation"); + context->GetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); + context->GetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + context->GetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); + context->GetStringi = (PFNGLGETSTRINGIPROC) load(userptr, "glGetStringi"); + context->GetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) load(userptr, "glGetTexParameterIiv"); + context->GetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) load(userptr, "glGetTexParameterIuiv"); + context->GetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load(userptr, "glGetTransformFeedbackVarying"); + context->GetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load(userptr, "glGetUniformuiv"); + context->GetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load(userptr, "glGetVertexAttribIiv"); + context->GetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load(userptr, "glGetVertexAttribIuiv"); + context->IsEnabledi = (PFNGLISENABLEDIPROC) load(userptr, "glIsEnabledi"); + context->IsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); + context->IsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); + context->IsVertexArray = (PFNGLISVERTEXARRAYPROC) load(userptr, "glIsVertexArray"); + context->MapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load(userptr, "glMapBufferRange"); + context->RenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); + context->RenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample"); + context->TexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) load(userptr, "glTexParameterIiv"); + context->TexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) load(userptr, "glTexParameterIuiv"); + context->TransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load(userptr, "glTransformFeedbackVaryings"); + context->Uniform1ui = (PFNGLUNIFORM1UIPROC) load(userptr, "glUniform1ui"); + context->Uniform1uiv = (PFNGLUNIFORM1UIVPROC) load(userptr, "glUniform1uiv"); + context->Uniform2ui = (PFNGLUNIFORM2UIPROC) load(userptr, "glUniform2ui"); + context->Uniform2uiv = (PFNGLUNIFORM2UIVPROC) load(userptr, "glUniform2uiv"); + context->Uniform3ui = (PFNGLUNIFORM3UIPROC) load(userptr, "glUniform3ui"); + context->Uniform3uiv = (PFNGLUNIFORM3UIVPROC) load(userptr, "glUniform3uiv"); + context->Uniform4ui = (PFNGLUNIFORM4UIPROC) load(userptr, "glUniform4ui"); + context->Uniform4uiv = (PFNGLUNIFORM4UIVPROC) load(userptr, "glUniform4uiv"); + context->VertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) load(userptr, "glVertexAttribI1i"); + context->VertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) load(userptr, "glVertexAttribI1iv"); + context->VertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) load(userptr, "glVertexAttribI1ui"); + context->VertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) load(userptr, "glVertexAttribI1uiv"); + context->VertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) load(userptr, "glVertexAttribI2i"); + context->VertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) load(userptr, "glVertexAttribI2iv"); + context->VertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) load(userptr, "glVertexAttribI2ui"); + context->VertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) load(userptr, "glVertexAttribI2uiv"); + context->VertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) load(userptr, "glVertexAttribI3i"); + context->VertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) load(userptr, "glVertexAttribI3iv"); + context->VertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) load(userptr, "glVertexAttribI3ui"); + context->VertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) load(userptr, "glVertexAttribI3uiv"); + context->VertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) load(userptr, "glVertexAttribI4bv"); + context->VertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load(userptr, "glVertexAttribI4i"); + context->VertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load(userptr, "glVertexAttribI4iv"); + context->VertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) load(userptr, "glVertexAttribI4sv"); + context->VertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) load(userptr, "glVertexAttribI4ubv"); + context->VertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load(userptr, "glVertexAttribI4ui"); + context->VertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load(userptr, "glVertexAttribI4uiv"); + context->VertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) load(userptr, "glVertexAttribI4usv"); + context->VertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load(userptr, "glVertexAttribIPointer"); } -static void glad_gl_load_GL_VERSION_3_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_3_1) return; - glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); - glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); - glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load(userptr, "glCopyBufferSubData"); - glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load(userptr, "glDrawArraysInstanced"); - glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load(userptr, "glDrawElementsInstanced"); - glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load(userptr, "glGetActiveUniformBlockName"); - glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load(userptr, "glGetActiveUniformBlockiv"); - glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC) load(userptr, "glGetActiveUniformName"); - glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load(userptr, "glGetActiveUniformsiv"); - glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); - glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load(userptr, "glGetUniformBlockIndex"); - glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load(userptr, "glGetUniformIndices"); - glad_glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC) load(userptr, "glPrimitiveRestartIndex"); - glad_glTexBuffer = (PFNGLTEXBUFFERPROC) load(userptr, "glTexBuffer"); - glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load(userptr, "glUniformBlockBinding"); +static void glad_gl_load_GL_VERSION_3_1(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_3_1) return; + context->BindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + context->BindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + context->CopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load(userptr, "glCopyBufferSubData"); + context->DrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load(userptr, "glDrawArraysInstanced"); + context->DrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load(userptr, "glDrawElementsInstanced"); + context->GetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load(userptr, "glGetActiveUniformBlockName"); + context->GetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load(userptr, "glGetActiveUniformBlockiv"); + context->GetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC) load(userptr, "glGetActiveUniformName"); + context->GetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load(userptr, "glGetActiveUniformsiv"); + context->GetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + context->GetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load(userptr, "glGetUniformBlockIndex"); + context->GetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load(userptr, "glGetUniformIndices"); + context->PrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC) load(userptr, "glPrimitiveRestartIndex"); + context->TexBuffer = (PFNGLTEXBUFFERPROC) load(userptr, "glTexBuffer"); + context->UniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load(userptr, "glUniformBlockBinding"); } -static void glad_gl_load_GL_VERSION_3_2( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_3_2) return; - glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load(userptr, "glClientWaitSync"); - glad_glDeleteSync = (PFNGLDELETESYNCPROC) load(userptr, "glDeleteSync"); - glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glDrawElementsBaseVertex"); - glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) load(userptr, "glDrawElementsInstancedBaseVertex"); - glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) load(userptr, "glDrawRangeElementsBaseVertex"); - glad_glFenceSync = (PFNGLFENCESYNCPROC) load(userptr, "glFenceSync"); - glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC) load(userptr, "glFramebufferTexture"); - glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load(userptr, "glGetBufferParameteri64v"); - glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load(userptr, "glGetInteger64i_v"); - glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC) load(userptr, "glGetInteger64v"); - glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) load(userptr, "glGetMultisamplefv"); - glad_glGetSynciv = (PFNGLGETSYNCIVPROC) load(userptr, "glGetSynciv"); - glad_glIsSync = (PFNGLISSYNCPROC) load(userptr, "glIsSync"); - glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glMultiDrawElementsBaseVertex"); - glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC) load(userptr, "glProvokingVertex"); - glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC) load(userptr, "glSampleMaski"); - glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) load(userptr, "glTexImage2DMultisample"); - glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) load(userptr, "glTexImage3DMultisample"); - glad_glWaitSync = (PFNGLWAITSYNCPROC) load(userptr, "glWaitSync"); +static void glad_gl_load_GL_VERSION_3_2(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_3_2) return; + context->ClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load(userptr, "glClientWaitSync"); + context->DeleteSync = (PFNGLDELETESYNCPROC) load(userptr, "glDeleteSync"); + context->DrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glDrawElementsBaseVertex"); + context->DrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) load(userptr, "glDrawElementsInstancedBaseVertex"); + context->DrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) load(userptr, "glDrawRangeElementsBaseVertex"); + context->FenceSync = (PFNGLFENCESYNCPROC) load(userptr, "glFenceSync"); + context->FramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC) load(userptr, "glFramebufferTexture"); + context->GetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load(userptr, "glGetBufferParameteri64v"); + context->GetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load(userptr, "glGetInteger64i_v"); + context->GetInteger64v = (PFNGLGETINTEGER64VPROC) load(userptr, "glGetInteger64v"); + context->GetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) load(userptr, "glGetMultisamplefv"); + context->GetSynciv = (PFNGLGETSYNCIVPROC) load(userptr, "glGetSynciv"); + context->IsSync = (PFNGLISSYNCPROC) load(userptr, "glIsSync"); + context->MultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glMultiDrawElementsBaseVertex"); + context->ProvokingVertex = (PFNGLPROVOKINGVERTEXPROC) load(userptr, "glProvokingVertex"); + context->SampleMaski = (PFNGLSAMPLEMASKIPROC) load(userptr, "glSampleMaski"); + context->TexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) load(userptr, "glTexImage2DMultisample"); + context->TexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) load(userptr, "glTexImage3DMultisample"); + context->WaitSync = (PFNGLWAITSYNCPROC) load(userptr, "glWaitSync"); } -static void glad_gl_load_GL_VERSION_3_3( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_3_3) return; - glad_glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) load(userptr, "glBindFragDataLocationIndexed"); - glad_glBindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler"); - glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers"); - glad_glGenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers"); - glad_glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC) load(userptr, "glGetFragDataIndex"); - glad_glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) load(userptr, "glGetQueryObjecti64v"); - glad_glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) load(userptr, "glGetQueryObjectui64v"); - glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) load(userptr, "glGetSamplerParameterIiv"); - glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) load(userptr, "glGetSamplerParameterIuiv"); - glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv"); - glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv"); - glad_glIsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler"); - glad_glQueryCounter = (PFNGLQUERYCOUNTERPROC) load(userptr, "glQueryCounter"); - glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) load(userptr, "glSamplerParameterIiv"); - glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) load(userptr, "glSamplerParameterIuiv"); - glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf"); - glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv"); - glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri"); - glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv"); - glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load(userptr, "glVertexAttribDivisor"); - glad_glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC) load(userptr, "glVertexAttribP1ui"); - glad_glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC) load(userptr, "glVertexAttribP1uiv"); - glad_glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC) load(userptr, "glVertexAttribP2ui"); - glad_glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC) load(userptr, "glVertexAttribP2uiv"); - glad_glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC) load(userptr, "glVertexAttribP3ui"); - glad_glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC) load(userptr, "glVertexAttribP3uiv"); - glad_glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC) load(userptr, "glVertexAttribP4ui"); - glad_glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC) load(userptr, "glVertexAttribP4uiv"); +static void glad_gl_load_GL_VERSION_3_3(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_3_3) return; + context->BindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) load(userptr, "glBindFragDataLocationIndexed"); + context->BindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler"); + context->DeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers"); + context->GenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers"); + context->GetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC) load(userptr, "glGetFragDataIndex"); + context->GetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) load(userptr, "glGetQueryObjecti64v"); + context->GetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) load(userptr, "glGetQueryObjectui64v"); + context->GetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) load(userptr, "glGetSamplerParameterIiv"); + context->GetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) load(userptr, "glGetSamplerParameterIuiv"); + context->GetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv"); + context->GetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv"); + context->IsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler"); + context->QueryCounter = (PFNGLQUERYCOUNTERPROC) load(userptr, "glQueryCounter"); + context->SamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) load(userptr, "glSamplerParameterIiv"); + context->SamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) load(userptr, "glSamplerParameterIuiv"); + context->SamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf"); + context->SamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv"); + context->SamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri"); + context->SamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv"); + context->VertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load(userptr, "glVertexAttribDivisor"); + context->VertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC) load(userptr, "glVertexAttribP1ui"); + context->VertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC) load(userptr, "glVertexAttribP1uiv"); + context->VertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC) load(userptr, "glVertexAttribP2ui"); + context->VertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC) load(userptr, "glVertexAttribP2uiv"); + context->VertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC) load(userptr, "glVertexAttribP3ui"); + context->VertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC) load(userptr, "glVertexAttribP3uiv"); + context->VertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC) load(userptr, "glVertexAttribP4ui"); + context->VertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC) load(userptr, "glVertexAttribP4uiv"); } @@ -773,27 +420,27 @@ static void glad_gl_load_GL_VERSION_3_3( GLADuserptrloadfunc load, void* userptr #define GLAD_GL_IS_SOME_NEW_VERSION 0 #endif -static int glad_gl_get_extensions( int version, const char **out_exts, unsigned int *out_num_exts_i, char ***out_exts_i) { +static int glad_gl_get_extensions(GladGLContext *context, int version, const char **out_exts, unsigned int *out_num_exts_i, char ***out_exts_i) { #if GLAD_GL_IS_SOME_NEW_VERSION if(GLAD_VERSION_MAJOR(version) < 3) { #else - (void) version; - (void) out_num_exts_i; - (void) out_exts_i; + GLAD_UNUSED(version); + GLAD_UNUSED(out_num_exts_i); + GLAD_UNUSED(out_exts_i); #endif - if (glad_glGetString == NULL) { + if (context->GetString == NULL) { return 0; } - *out_exts = (const char *)glad_glGetString(GL_EXTENSIONS); + *out_exts = (const char *)context->GetString(GL_EXTENSIONS); #if GLAD_GL_IS_SOME_NEW_VERSION } else { unsigned int index = 0; unsigned int num_exts_i = 0; char **exts_i = NULL; - if (glad_glGetStringi == NULL || glad_glGetIntegerv == NULL) { + if (context->GetStringi == NULL || context->GetIntegerv == NULL) { return 0; } - glad_glGetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i); + context->GetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i); if (num_exts_i > 0) { exts_i = (char **) malloc(num_exts_i * (sizeof *exts_i)); } @@ -801,7 +448,7 @@ static int glad_gl_get_extensions( int version, const char **out_exts, unsigned return 0; } for(index = 0; index < num_exts_i; index++) { - const char *gl_str_tmp = (const char*) glad_glGetStringi(GL_EXTENSIONS, index); + const char *gl_str_tmp = (const char*) context->GetStringi(GL_EXTENSIONS, index); size_t len = strlen(gl_str_tmp) + 1; char *local_str = (char*) malloc(len * sizeof(char)); @@ -865,20 +512,20 @@ static GLADapiproc glad_gl_get_proc_from_userptr(void *userptr, const char* name return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); } -static int glad_gl_find_extensions_gl( int version) { +static int glad_gl_find_extensions_gl(GladGLContext *context, int version) { const char *exts = NULL; unsigned int num_exts_i = 0; char **exts_i = NULL; - if (!glad_gl_get_extensions(version, &exts, &num_exts_i, &exts_i)) return 0; + if (!glad_gl_get_extensions(context, version, &exts, &num_exts_i, &exts_i)) return 0; - (void) glad_gl_has_extension; + GLAD_UNUSED(glad_gl_has_extension); glad_gl_free_extensions(exts_i, num_exts_i); return 1; } -static int glad_gl_find_core_gl(void) { +static int glad_gl_find_core_gl(GladGLContext *context) { int i; const char* version; const char* prefixes[] = { @@ -890,7 +537,7 @@ static int glad_gl_find_core_gl(void) { }; int major = 0; int minor = 0; - version = (const char*) glad_glGetString(GL_VERSION); + version = (const char*) context->GetString(GL_VERSION); if (!version) return 0; for (i = 0; prefixes[i]; i++) { const size_t length = strlen(prefixes[i]); @@ -902,44 +549,44 @@ static int glad_gl_find_core_gl(void) { GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); - GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; - GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; - GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; - GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; - GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; - GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; - GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; - GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; - GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; - GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; - GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; - GLAD_GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; + context->VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + context->VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + context->VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + context->VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + context->VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + context->VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; + context->VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + context->VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; + context->VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + context->VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; + context->VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; + context->VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; return GLAD_MAKE_VERSION(major, minor); } -int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) { +int gladLoadGLContextUserPtr(GladGLContext *context, GLADuserptrloadfunc load, void *userptr) { int version; - glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); - if(glad_glGetString == NULL) return 0; - if(glad_glGetString(GL_VERSION) == NULL) return 0; - version = glad_gl_find_core_gl(); + context->GetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + if(context->GetString == NULL) return 0; + if(context->GetString(GL_VERSION) == NULL) return 0; + version = glad_gl_find_core_gl(context); - glad_gl_load_GL_VERSION_1_0(load, userptr); - glad_gl_load_GL_VERSION_1_1(load, userptr); - glad_gl_load_GL_VERSION_1_2(load, userptr); - glad_gl_load_GL_VERSION_1_3(load, userptr); - glad_gl_load_GL_VERSION_1_4(load, userptr); - glad_gl_load_GL_VERSION_1_5(load, userptr); - glad_gl_load_GL_VERSION_2_0(load, userptr); - glad_gl_load_GL_VERSION_2_1(load, userptr); - glad_gl_load_GL_VERSION_3_0(load, userptr); - glad_gl_load_GL_VERSION_3_1(load, userptr); - glad_gl_load_GL_VERSION_3_2(load, userptr); - glad_gl_load_GL_VERSION_3_3(load, userptr); + glad_gl_load_GL_VERSION_1_0(context, load, userptr); + glad_gl_load_GL_VERSION_1_1(context, load, userptr); + glad_gl_load_GL_VERSION_1_2(context, load, userptr); + glad_gl_load_GL_VERSION_1_3(context, load, userptr); + glad_gl_load_GL_VERSION_1_4(context, load, userptr); + glad_gl_load_GL_VERSION_1_5(context, load, userptr); + glad_gl_load_GL_VERSION_2_0(context, load, userptr); + glad_gl_load_GL_VERSION_2_1(context, load, userptr); + glad_gl_load_GL_VERSION_3_0(context, load, userptr); + glad_gl_load_GL_VERSION_3_1(context, load, userptr); + glad_gl_load_GL_VERSION_3_2(context, load, userptr); + glad_gl_load_GL_VERSION_3_3(context, load, userptr); - if (!glad_gl_find_extensions_gl(version)) return 0; + if (!glad_gl_find_extensions_gl(context, version)) return 0; @@ -947,8 +594,8 @@ int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) { } -int gladLoadGL( GLADloadfunc load) { - return gladLoadGLUserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +int gladLoadGLContext(GladGLContext *context, GLADloadfunc load) { + return gladLoadGLContextUserPtr(context, glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); } @@ -1044,9 +691,8 @@ static GLADapiproc glad_gl_get_proc(void *vuserptr, const char *name) { return result; } -static void* _gl_handle = NULL; -static void* glad_gl_dlopen_handle(void) { +static void* glad_gl_dlopen_handle(GladGLContext *context) { #if GLAD_PLATFORM_APPLE static const char *NAMES[] = { "../Frameworks/OpenGL.framework/OpenGL", @@ -1066,11 +712,11 @@ static void* glad_gl_dlopen_handle(void) { }; #endif - if (_gl_handle == NULL) { - _gl_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); + if (context->glad_loader_handle == NULL) { + context->glad_loader_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); } - return _gl_handle; + return context->glad_loader_handle; } static struct _glad_gl_userptr glad_gl_build_userptr(void *handle) { @@ -1090,21 +736,21 @@ static struct _glad_gl_userptr glad_gl_build_userptr(void *handle) { return userptr; } -int gladLoaderLoadGL(void) { +int gladLoaderLoadGLContext(GladGLContext *context) { int version = 0; void *handle; int did_load = 0; struct _glad_gl_userptr userptr; - did_load = _gl_handle == NULL; - handle = glad_gl_dlopen_handle(); + did_load = context->glad_loader_handle == NULL; + handle = glad_gl_dlopen_handle(context); if (handle) { userptr = glad_gl_build_userptr(handle); - version = gladLoadGLUserPtr(glad_gl_get_proc, &userptr); + version = gladLoadGLContextUserPtr(context,glad_gl_get_proc, &userptr); if (did_load) { - gladLoaderUnloadGL(); + gladLoaderUnloadGLContext(context); } } @@ -1113,10 +759,10 @@ int gladLoaderLoadGL(void) { -void gladLoaderUnloadGL(void) { - if (_gl_handle != NULL) { - glad_close_dlopen_handle(_gl_handle); - _gl_handle = NULL; +void gladLoaderUnloadGLContext(GladGLContext *context) { + if (context->glad_loader_handle != NULL) { + glad_close_dlopen_handle(context->glad_loader_handle); + context->glad_loader_handle = NULL; } } From 9913bba2e805cd6647bf050feeabea95b90e4f25 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 23 Oct 2022 20:18:10 -0700 Subject: [PATCH 02/13] introduce renderer thread logic (not starting it yet) --- src/renderer.zig | 1 + src/renderer/OpenGL.zig | 33 ++++++++++++ src/renderer/Thread.zig | 113 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 src/renderer/Thread.zig diff --git a/src/renderer.zig b/src/renderer.zig index d55b2565f..5696a853d 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -8,6 +8,7 @@ //! setup (OpenGL has a context, Vulkan has a surface, etc.) pub const OpenGL = @import("renderer/OpenGL.zig"); +pub const Thread = @import("renderer/Thread.zig"); test { @import("std").testing.refAllDecls(@This()); diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index e56f832a0..5d5a4cb1f 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -2,6 +2,8 @@ pub const OpenGL = @This(); const std = @import("std"); +const builtin = @import("builtin"); +const glfw = @import("glfw"); const assert = std.debug.assert; const testing = std.testing; const Allocator = std.mem.Allocator; @@ -320,6 +322,37 @@ pub fn deinit(self: *OpenGL) void { self.* = undefined; } +/// Callback called by renderer.Thread when it begins. +pub fn threadEnter(window: glfw.Window) !void { + // We need to make the OpenGL context current. OpenGL requires + // that a single thread own the a single OpenGL context (if any). This + // ensures that the context switches over to our thread. Important: + // the prior thread MUST have detached the context prior to calling + // this entrypoint. + try glfw.makeContextCurrent(window); + errdefer glfw.makeContextCurrent(null) catch |err| + log.warn("failed to cleanup OpenGL context err={}", .{err}); + try glfw.swapInterval(1); + + // Load OpenGL bindings. This API is context-aware so this sets + // a threadlocal context for these pointers. + const version = try gl.glad.load(switch (builtin.zig_backend) { + .stage1 => glfw.getProcAddress, + else => &glfw.getProcAddress, + }); + errdefer gl.glad.unload(); + log.info("loaded OpenGL {}.{}", .{ + gl.glad.versionMajor(version), + gl.glad.versionMinor(version), + }); +} + +/// Callback called by renderer.Thread when it exits. +pub fn threadExit() void { + gl.glad.unload(); + glfw.makeContextCurrent(null) catch {}; +} + /// rebuildCells rebuilds all the GPU cells from our CPU state. This is a /// slow operation but ensures that the GPU state exactly matches the CPU state. /// In steady-state operation, we use some GPU tricks to send down stale data diff --git a/src/renderer/Thread.zig b/src/renderer/Thread.zig new file mode 100644 index 000000000..729198fcc --- /dev/null +++ b/src/renderer/Thread.zig @@ -0,0 +1,113 @@ +//! Represents the renderer thread logic. The renderer thread is able to +//! be woken up to render. +pub const Thread = @This(); + +const std = @import("std"); +const builtin = @import("builtin"); +const glfw = @import("glfw"); +const libuv = @import("libuv"); +const renderer = @import("../renderer.zig"); +const gl = @import("../opengl.zig"); + +const Allocator = std.mem.Allocator; +const log = std.log.named(.renderer_thread); + +/// The main event loop for the application. The user data of this loop +/// is always the allocator used to create the loop. This is a convenience +/// so that users of the loop always have an allocator. +loop: libuv.Loop, + +/// This can be used to wake up the renderer and force a render safely from +/// any thread. +wakeup: libuv.Async, + +/// Initialize the thread. This does not START the thread. This only sets +/// up all the internal state necessary prior to starting the thread. It +/// is up to the caller to start the thread with the threadMain entrypoint. +pub fn init(alloc: Allocator) !Thread { + // We always store allocator pointer on the loop data so that + // handles can use our global allocator. + const allocPtr = try alloc.create(Allocator); + errdefer alloc.destroy(allocPtr); + allocPtr.* = alloc; + + // Create our event loop. + var loop = try libuv.Loop.init(alloc); + errdefer loop.deinit(alloc); + loop.setData(allocPtr); + + // This async handle is used to "wake up" the renderer and force a render. + var async_h = try libuv.Async.init(alloc, loop, (struct { + fn callback(_: *libuv.Async) void {} + }).callback); + errdefer async_h.close((struct { + fn callback(h: *libuv.Async) void { + const loop_alloc = h.loop().getData(Allocator).?.*; + h.deinit(loop_alloc); + } + }).callback); + + return Thread{ + .alloc = alloc, + .loop = loop, + .notifier = async_h, + }; +} + +/// Clean up the thread. This is only safe to call once the thread +/// completes executing; the caller must join prior to this. +pub fn deinit(self: *Thread) void { + // Get a copy to our allocator + const alloc_ptr = self.loop.getData(Allocator).?; + const alloc = alloc_ptr.*; + + // Run the loop one more time, because destroying our other things + // like windows usually cancel all our event loop stuff and we need + // one more run through to finalize all the closes. + _ = self.loop.run(.default) catch |err| + log.err("error finalizing event loop: {}", .{err}); + + // Dealloc our allocator copy + alloc.destroy(alloc_ptr); + + self.loop.deinit(alloc); +} + +/// The main entrypoint for the thread. +pub fn threadMain( + window: glfw.Window, + renderer_impl: *const renderer.OpenGL, +) void { + // Call child function so we can use errors... + threadMain_( + window, + renderer_impl, + ) catch |err| { + // In the future, we should expose this on the thread struct. + log.warn("error in renderer err={}", .{err}); + }; +} + +fn threadMain_( + self: *const Thread, + window: glfw.Window, + renderer_impl: *const renderer.OpenGL, +) !void { + const Renderer = switch (@TypeOf(renderer_impl)) { + .Pointer => |p| p.child, + .Struct => |s| s, + }; + + // Run our thread start/end callbacks. This is important because some + // renderers have to do per-thread setup. For example, OpenGL has to set + // some thread-local state since that is how it works. + if (@hasDecl(Renderer, "threadEnter")) try renderer_impl.threadEnter(window); + defer if (@hasDecl(Renderer, "threadExit")) renderer_impl.threadExit(); + + // Setup our timer handle which is used to perform the actual render. + // TODO + + // Run + log.debug("starting renderer thread", .{}); + try self.loop.run(.default); +} From b347ff458b36b95b5b0541a36a2a4b4d5ff139e8 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 23 Oct 2022 20:55:04 -0700 Subject: [PATCH 03/13] prepare our render state on the window --- src/Window.zig | 20 +++++++++++++- src/renderer.zig | 1 + src/renderer/OpenGL.zig | 60 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/Window.zig b/src/Window.zig index cef35d70d..9fc43e824 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -56,6 +56,9 @@ focused: bool, /// The renderer for this window. renderer: renderer.OpenGL, +/// The render state +renderer_state: renderer.State, + /// The underlying pty for this window. pty: Pty, @@ -455,6 +458,10 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo var io_arena = std.heap.ArenaAllocator.init(alloc); errdefer io_arena.deinit(); + // The mutex used to protect our renderer state. + var mutex = try alloc.create(std.Thread.Mutex); + errdefer alloc.destroy(mutex); + self.* = .{ .alloc = alloc, .alloc_io_arena = io_arena, @@ -464,6 +471,16 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo .cursor = cursor, .focused = false, .renderer = renderer_impl, + .renderer_state = .{ + .mutex = mutex, + .cursor = .{ + .style = .blinking_block, + .visible = true, + .blink = false, + }, + .terminal = &self.terminal, + .devmode = if (!DevMode.enabled) null else &DevMode.instance, + }, .pty = pty, .command = cmd, .mouse = .{}, @@ -591,6 +608,7 @@ pub fn destroy(self: *Window) void { self.font_lib.deinit(); self.alloc_io_arena.deinit(); + self.alloc.destroy(self.renderer_state.mutex); } pub fn shouldClose(self: Window) bool { @@ -1632,7 +1650,7 @@ fn renderTimerCallback(t: *libuv.Timer) void { log.err("error calling updateCells in render timer err={}", .{err}); // Render the grid - win.renderer.render() catch |err| { + win.renderer.draw() catch |err| { log.err("error rendering grid: {}", .{err}); return; }; diff --git a/src/renderer.zig b/src/renderer.zig index 5696a853d..2a711ee15 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -9,6 +9,7 @@ pub const OpenGL = @import("renderer/OpenGL.zig"); pub const Thread = @import("renderer/Thread.zig"); +pub const State = @import("renderer/State.zig"); test { @import("std").testing.refAllDecls(@This()); diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 5d5a4cb1f..e0f231b56 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -9,6 +9,8 @@ const testing = std.testing; const Allocator = std.mem.Allocator; const Atlas = @import("../Atlas.zig"); const font = @import("../font/main.zig"); +const imgui = @import("imgui"); +const renderer = @import("../renderer.zig"); const terminal = @import("../terminal/main.zig"); const Terminal = terminal.Terminal; const gl = @import("../opengl.zig"); @@ -353,6 +355,62 @@ pub fn threadExit() void { glfw.makeContextCurrent(null) catch {}; } +/// The primary render callback that is completely thread-safe. +pub fn render( + self: *OpenGL, + window: glfw.Window, + state: renderer.State, +) !void { + // Update all our data as tightly as possible within the mutex. + var gl_bg = self.background; + { + state.mutex.lock(); + defer state.mutex.unlock(); + + // Setup our cursor state + self.cursor_visible = state.cursor.visible and !state.cursor.blink; + self.cursor_style = CursorStyle.fromTerminal(state.cursor.style) orelse .box; + + // Swap bg/fg if the terminal is reversed + const bg = self.background; + const fg = self.foreground; + defer { + self.background = bg; + self.foreground = fg; + } + if (state.terminal.modes.reverse_colors) { + gl_bg = fg; + self.background = fg; + self.foreground = bg; + } + + try self.rebuildCells(state.terminal); + try self.finalizeCells(state.terminal); + if (state.devmode) |dm| try dm.update(); + } + + // Clear the surface + gl.clearColor( + @intToFloat(f32, self.background.r) / 255, + @intToFloat(f32, self.background.g) / 255, + @intToFloat(f32, self.background.b) / 255, + 1.0, + ); + gl.clear(gl.c.GL_COLOR_BUFFER_BIT); + + // We're out of the critical path now. Let's first render our terminal. + try self.draw(); + + // If we have devmode, then render that + if (state.devmode) |dm| { + const data = try dm.render(); + imgui.ImplOpenGL3.renderDrawData(data); + } + + // Swap our window buffers + try window.swapBuffers(); +} + /// rebuildCells rebuilds all the GPU cells from our CPU state. This is a /// slow operation but ensures that the GPU state exactly matches the CPU state. /// In steady-state operation, we use some GPU tricks to send down stale data @@ -830,7 +888,7 @@ fn flushAtlas(self: *OpenGL) !void { /// Render renders the current cell state. This will not modify any of /// the cells. -pub fn render(self: *OpenGL) !void { +pub fn draw(self: *OpenGL) !void { const t = trace(@src()); defer t.end(); From aeb592bae9e7e5eaf46af901e194b541bb310693 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 23 Oct 2022 21:04:52 -0700 Subject: [PATCH 04/13] move to new renderstate, new render method --- src/DevMode.zig | 4 +- src/Window.zig | 102 ++++++---------------------------------- src/renderer/OpenGL.zig | 8 ++-- 3 files changed, 21 insertions(+), 93 deletions(-) diff --git a/src/DevMode.zig b/src/DevMode.zig index 4089076dd..7e1e73842 100644 --- a/src/DevMode.zig +++ b/src/DevMode.zig @@ -27,7 +27,7 @@ window: ?*Window = null, /// Update the state associated with the dev mode. This should generally /// only be called paired with a render since it otherwise wastes CPU /// cycles. -pub fn update(self: *DevMode) !void { +pub fn update(self: *const DevMode) !void { imgui.ImplOpenGL3.newFrame(); imgui.ImplGlfw.newFrame(); imgui.newFrame(); @@ -82,7 +82,7 @@ fn helpMarker(desc: [:0]const u8) void { } } -fn atlasInfo(self: *DevMode, atlas: *Atlas, tex: ?usize) !void { +fn atlasInfo(self: *const DevMode, atlas: *Atlas, tex: ?usize) !void { _ = self; imgui.text("Dimensions: %d x %d", atlas.size, atlas.size); diff --git a/src/Window.zig b/src/Window.zig index 9fc43e824..ba5947334 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -120,19 +120,6 @@ const Cursor = struct { /// Timer for cursor blinking. timer: libuv.Timer, - /// Current cursor style. This can be set by escape sequences. To get - /// the default style, the config has to be referenced. - style: terminal.CursorStyle = .default, - - /// Whether the cursor is visible at all. This should not be used for - /// "blink" settings, see "blink" for that. This is used to turn the - /// cursor ON or OFF. - visible: bool = true, - - /// Whether the cursor is currently blinking. If it is blinking, then - /// the cursor will not be rendered. - blink: bool = false, - /// Start (or restart) the timer. This is idempotent. pub fn startTimer(self: Cursor) !void { try self.timer.start( @@ -460,6 +447,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo // The mutex used to protect our renderer state. var mutex = try alloc.create(std.Thread.Mutex); + mutex.* = .{}; errdefer alloc.destroy(mutex); self.* = .{ @@ -486,10 +474,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo .mouse = .{}, .terminal = term, .terminal_stream = .{ .handler = self }, - .terminal_cursor = .{ - .timer = timer, - .style = .blinking_block, - }, + .terminal_cursor = .{ .timer = timer }, .render_timer = try RenderTimer.init(loop, self, 6, 12), .pty_stream = stream, .config = config, @@ -1487,10 +1472,10 @@ fn cursorTimerCallback(t: *libuv.Timer) void { // If the cursor is currently invisible, then we do nothing. Ideally // in this state the timer would be cancelled but no big deal. - if (!win.terminal_cursor.visible) return; + if (!win.renderer_state.cursor.visible) return; // Swap blink state and schedule a render - win.terminal_cursor.blink = !win.terminal_cursor.blink; + win.renderer_state.cursor.blink = !win.renderer_state.cursor.blink; win.render_timer.schedule() catch unreachable; } @@ -1528,9 +1513,13 @@ fn ttyRead(t: *libuv.Tty, n: isize, buf: []const u8) void { return; }; + // We are modifying terminal state from here on out + win.renderer_state.mutex.lock(); + defer win.renderer_state.mutex.unlock(); + // Whenever a character is typed, we ensure the cursor is in the // non-blink state so it is rendered if visible. - win.terminal_cursor.blink = false; + win.renderer_state.cursor.blink = false; if (win.terminal_cursor.timer.isActive() catch false) { _ = win.terminal_cursor.timer.again() catch null; } @@ -1600,72 +1589,9 @@ fn renderTimerCallback(t: *libuv.Timer) void { const win = t.getData(Window).?; - // Setup our cursor settings - if (win.focused) { - win.renderer.cursor_visible = win.terminal_cursor.visible and !win.terminal_cursor.blink; - win.renderer.cursor_style = renderer.OpenGL.CursorStyle.fromTerminal(win.terminal_cursor.style) orelse .box; - } else { - win.renderer.cursor_visible = true; - win.renderer.cursor_style = .box_hollow; - } - - // Calculate foreground and background colors - const bg = win.renderer.background; - const fg = win.renderer.foreground; - defer { - win.renderer.background = bg; - win.renderer.foreground = fg; - } - if (win.terminal.modes.reverse_colors) { - win.renderer.background = fg; - win.renderer.foreground = bg; - } - - // Set our background - const gl_bg: struct { - r: f32, - g: f32, - b: f32, - a: f32, - } = if (win.terminal.modes.reverse_colors) .{ - .r = @intToFloat(f32, fg.r) / 255, - .g = @intToFloat(f32, fg.g) / 255, - .b = @intToFloat(f32, fg.b) / 255, - .a = 1.0, - } else .{ - .r = win.bg_r, - .g = win.bg_g, - .b = win.bg_b, - .a = win.bg_a, - }; - gl.clearColor(gl_bg.r, gl_bg.g, gl_bg.b, gl_bg.a); - gl.clear(gl.c.GL_COLOR_BUFFER_BIT); - - // For now, rebuild all cells - win.renderer.rebuildCells(&win.terminal) catch |err| - log.err("error calling rebuildCells in render timer err={}", .{err}); - - // Finalize the cells prior to render - win.renderer.finalizeCells(&win.terminal) catch |err| - log.err("error calling updateCells in render timer err={}", .{err}); - - // Render the grid - win.renderer.draw() catch |err| { - log.err("error rendering grid: {}", .{err}); - return; - }; - - if (DevMode.enabled and DevMode.instance.visible) { - DevMode.instance.update() catch unreachable; - const data = DevMode.instance.render() catch unreachable; - imgui.ImplOpenGL3.renderDrawData(data); - } - - // Swap - win.window.swapBuffers() catch |err| { - log.err("error swapping buffers: {}", .{err}); - return; - }; + // Render + win.renderer.render(win.window, win.renderer_state) catch |err| + log.warn("error rendering err={}", .{err}); // Record our run win.render_timer.tick(); @@ -1805,7 +1731,7 @@ pub fn setMode(self: *Window, mode: terminal.Mode, enabled: bool) !void { }, .cursor_visible => { - self.terminal_cursor.visible = enabled; + self.renderer_state.cursor.visible = enabled; }, .alt_screen_save_cursor_clear_enter => { @@ -1918,7 +1844,7 @@ pub fn setCursorStyle( self: *Window, style: terminal.CursorStyle, ) !void { - self.terminal_cursor.style = style; + self.renderer_state.cursor.style = style; } pub fn decaln(self: *Window) !void { diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index e0f231b56..c79455f34 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -386,7 +386,7 @@ pub fn render( try self.rebuildCells(state.terminal); try self.finalizeCells(state.terminal); - if (state.devmode) |dm| try dm.update(); + if (state.devmode) |dm| if (dm.visible) try dm.update(); } // Clear the surface @@ -403,8 +403,10 @@ pub fn render( // If we have devmode, then render that if (state.devmode) |dm| { - const data = try dm.render(); - imgui.ImplOpenGL3.renderDrawData(data); + if (dm.visible) { + const data = try dm.render(); + imgui.ImplOpenGL3.renderDrawData(data); + } } // Swap our window buffers From 77b981950c41a17372a2b915a99214fce4e25a15 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 23 Oct 2022 21:15:58 -0700 Subject: [PATCH 05/13] pkg/libuv: Idle handles --- pkg/libuv/Idle.zig | 66 ++++++++++++++++++++++++++++++++++++++++++++++ pkg/libuv/main.zig | 2 ++ 2 files changed, 68 insertions(+) create mode 100644 pkg/libuv/Idle.zig diff --git a/pkg/libuv/Idle.zig b/pkg/libuv/Idle.zig new file mode 100644 index 000000000..0e3a64e5b --- /dev/null +++ b/pkg/libuv/Idle.zig @@ -0,0 +1,66 @@ +//! Idle handles will run the given callback once per loop iteration, right +//! before the uv_prepare_t handles. +const Idle = @This(); + +const std = @import("std"); +const Allocator = std.mem.Allocator; +const testing = std.testing; +const c = @import("c.zig"); +const errors = @import("error.zig"); +const Loop = @import("Loop.zig"); +const Handle = @import("handle.zig").Handle; + +handle: *c.uv_idle_t, + +pub usingnamespace Handle(Idle); + +pub fn init(alloc: Allocator, loop: Loop) !Idle { + var handle = try alloc.create(c.uv_idle_t); + errdefer alloc.destroy(handle); + + try errors.convertError(c.uv_idle_init(loop.loop, handle)); + return Idle{ .handle = handle }; +} + +pub fn deinit(self: *Idle, alloc: Allocator) void { + alloc.destroy(self.handle); + self.* = undefined; +} + +/// Start the handle with the given callback. This function always succeeds, +/// except when cb is NULL. +pub fn start(self: Idle, comptime cb: fn (*Idle) void) !void { + const Wrapper = struct { + pub fn callback(arg: [*c]c.uv_idle_t) callconv(.C) void { + var newSelf: Idle = .{ .handle = arg }; + @call(.{ .modifier = .always_inline }, cb, .{&newSelf}); + } + }; + + try errors.convertError(c.uv_idle_start(self.handle, Wrapper.callback)); +} + +/// Stop the handle, the callback will no longer be called. +pub fn stop(self: Idle) !void { + try errors.convertError(c.uv_idle_stop(self.handle)); +} + +test "Idle" { + var loop = try Loop.init(testing.allocator); + defer loop.deinit(testing.allocator); + var h = try init(testing.allocator, loop); + defer h.deinit(testing.allocator); + + var called: bool = false; + h.setData(&called); + try h.start((struct { + fn callback(t: *Idle) void { + t.getData(bool).?.* = true; + t.close(null); + } + }).callback); + + _ = try loop.run(.default); + + try testing.expect(called); +} diff --git a/pkg/libuv/main.zig b/pkg/libuv/main.zig index 4e528b1e2..060dd3e3a 100644 --- a/pkg/libuv/main.zig +++ b/pkg/libuv/main.zig @@ -3,6 +3,7 @@ const stream = @import("stream.zig"); pub const Loop = @import("Loop.zig"); pub const Async = @import("Async.zig"); +pub const Idle = @import("Idle.zig"); pub const Pipe = @import("Pipe.zig"); pub const Timer = @import("Timer.zig"); pub const Tty = @import("Tty.zig"); @@ -27,6 +28,7 @@ test { _ = Loop; _ = Async; + _ = Idle; _ = Pipe; _ = Timer; _ = Tty; From aa3d13294737b41fccddc4a6c215e6dabe52c146 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 24 Oct 2022 09:02:11 -0700 Subject: [PATCH 06/13] run rendering on another real thread (still bugs) --- pkg/libuv/main.zig | 1 + src/Window.zig | 52 ++++++++++++++++-- src/renderer/OpenGL.zig | 8 ++- src/renderer/State.zig | 40 ++++++++++++++ src/renderer/Thread.zig | 115 +++++++++++++++++++++++++++++----------- 5 files changed, 180 insertions(+), 36 deletions(-) create mode 100644 src/renderer/State.zig diff --git a/pkg/libuv/main.zig b/pkg/libuv/main.zig index 060dd3e3a..3db629b42 100644 --- a/pkg/libuv/main.zig +++ b/pkg/libuv/main.zig @@ -1,6 +1,7 @@ const std = @import("std"); const stream = @import("stream.zig"); +pub const c = @import("c.zig"); pub const Loop = @import("Loop.zig"); pub const Async = @import("Async.zig"); pub const Idle = @import("Idle.zig"); diff --git a/src/Window.zig b/src/Window.zig index ba5947334..c76800184 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -59,6 +59,12 @@ renderer: renderer.OpenGL, /// The render state renderer_state: renderer.State, +/// The renderer thread manager +renderer_thread: renderer.Thread, + +/// The actual thread +renderer_thr: std.Thread, + /// The underlying pty for this window. pty: Pty, @@ -450,6 +456,15 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo mutex.* = .{}; errdefer alloc.destroy(mutex); + // Create the renderer thread + var render_thread = try renderer.Thread.init( + alloc, + window, + &self.renderer, + &self.renderer_state, + ); + errdefer render_thread.deinit(); + self.* = .{ .alloc = alloc, .alloc_io_arena = io_arena, @@ -459,6 +474,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo .cursor = cursor, .focused = false, .renderer = renderer_impl, + .renderer_thread = render_thread, .renderer_state = .{ .mutex = mutex, .cursor = .{ @@ -469,6 +485,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo .terminal = &self.terminal, .devmode = if (!DevMode.enabled) null else &DevMode.instance, }, + .renderer_thr = undefined, .pty = pty, .command = cmd, .mouse = .{}, @@ -489,7 +506,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo // Setup our callbacks and user data window.setUserPointer(self); - window.setSizeCallback(sizeCallback); + //window.setSizeCallback(sizeCallback); window.setCharCallback(charCallback); window.setKeyCallback(keyCallback); window.setFocusCallback(focusCallback); @@ -537,10 +554,33 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo DevMode.instance.window = self; } + // Unload our context prior to switching over to the renderer thread + // because OpenGL requires it to be unloaded. + gl.glad.unload(); + try glfw.makeContextCurrent(null); + + // Start our renderer thread + self.renderer_thr = try std.Thread.spawn( + .{}, + renderer.Thread.threadMain, + .{&self.renderer_thread}, + ); + return self; } pub fn destroy(self: *Window) void { + { + // Stop rendering thread + self.renderer_thread.stop.send() catch |err| + log.err("error notifying renderer thread to stop, may stall err={}", .{err}); + self.renderer_thr.join(); + + // We need to become the active rendering thread again + self.renderer.threadEnter(self.window) catch unreachable; + self.renderer_thread.deinit(); + } + if (DevMode.enabled) { // Clear the window DevMode.instance.window = null; @@ -1470,6 +1510,10 @@ fn cursorTimerCallback(t: *libuv.Timer) void { const win = t.getData(Window) orelse return; + // We are modifying renderer state from here on out + win.renderer_state.mutex.lock(); + defer win.renderer_state.mutex.unlock(); + // If the cursor is currently invisible, then we do nothing. Ideally // in this state the timer would be cancelled but no big deal. if (!win.renderer_state.cursor.visible) return; @@ -1589,9 +1633,9 @@ fn renderTimerCallback(t: *libuv.Timer) void { const win = t.getData(Window).?; - // Render - win.renderer.render(win.window, win.renderer_state) catch |err| - log.warn("error rendering err={}", .{err}); + // Trigger a render + win.renderer_thread.wakeup.send() catch |err| + log.err("error sending render notification err={}", .{err}); // Record our run win.render_timer.tick(); diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index c79455f34..a6908e1b4 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -325,7 +325,9 @@ pub fn deinit(self: *OpenGL) void { } /// Callback called by renderer.Thread when it begins. -pub fn threadEnter(window: glfw.Window) !void { +pub fn threadEnter(self: *const OpenGL, window: glfw.Window) !void { + _ = self; + // We need to make the OpenGL context current. OpenGL requires // that a single thread own the a single OpenGL context (if any). This // ensures that the context switches over to our thread. Important: @@ -350,7 +352,9 @@ pub fn threadEnter(window: glfw.Window) !void { } /// Callback called by renderer.Thread when it exits. -pub fn threadExit() void { +pub fn threadExit(self: *const OpenGL) void { + _ = self; + gl.glad.unload(); glfw.makeContextCurrent(null) catch {}; } diff --git a/src/renderer/State.zig b/src/renderer/State.zig new file mode 100644 index 000000000..25963ded5 --- /dev/null +++ b/src/renderer/State.zig @@ -0,0 +1,40 @@ +//! This is the render state that is given to a renderer. + +const std = @import("std"); +const DevMode = @import("../DevMode.zig"); +const terminal = @import("../terminal/main.zig"); + +/// The mutex that must be held while reading any of the data in the +/// members of this state. Note that the state itself is NOT protected +/// by the mutex and is NOT thread-safe, only the members values of the +/// state (i.e. the terminal, devmode, etc. values). +mutex: *std.Thread.Mutex, + +/// A new screen size if the screen was resized. +resize: ?Resize = null, + +/// Cursor configuration for rendering +cursor: Cursor, + +/// The terminal data. +terminal: *terminal.Terminal, + +/// The devmode data. +devmode: ?*const DevMode = null, + +pub const Cursor = struct { + /// Current cursor style. This can be set by escape sequences. To get + /// the default style, the config has to be referenced. + style: terminal.CursorStyle = .default, + + /// Whether the cursor is visible at all. This should not be used for + /// "blink" settings, see "blink" for that. This is used to turn the + /// cursor ON or OFF. + visible: bool = true, + + /// Whether the cursor is currently blinking. If it is blinking, then + /// the cursor will not be rendered. + blink: bool = false, +}; + +pub const Resize = struct {}; diff --git a/src/renderer/Thread.zig b/src/renderer/Thread.zig index 729198fcc..4cb12f99f 100644 --- a/src/renderer/Thread.zig +++ b/src/renderer/Thread.zig @@ -10,7 +10,7 @@ const renderer = @import("../renderer.zig"); const gl = @import("../opengl.zig"); const Allocator = std.mem.Allocator; -const log = std.log.named(.renderer_thread); +const log = std.log.scoped(.renderer_thread); /// The main event loop for the application. The user data of this loop /// is always the allocator used to create the loop. This is a convenience @@ -21,10 +21,27 @@ loop: libuv.Loop, /// any thread. wakeup: libuv.Async, +/// This can be used to stop the renderer on the next loop iteration. +stop: libuv.Async, + +/// The windo we're rendering to. +window: glfw.Window, + +/// The underlying renderer implementation. +renderer: *renderer.OpenGL, + +/// Pointer to the shared state that is used to generate the final render. +state: *const renderer.State, + /// Initialize the thread. This does not START the thread. This only sets /// up all the internal state necessary prior to starting the thread. It /// is up to the caller to start the thread with the threadMain entrypoint. -pub fn init(alloc: Allocator) !Thread { +pub fn init( + alloc: Allocator, + window: glfw.Window, + renderer_impl: *renderer.OpenGL, + state: *const renderer.State, +) !Thread { // We always store allocator pointer on the loop data so that // handles can use our global allocator. const allocPtr = try alloc.create(Allocator); @@ -37,10 +54,17 @@ pub fn init(alloc: Allocator) !Thread { loop.setData(allocPtr); // This async handle is used to "wake up" the renderer and force a render. - var async_h = try libuv.Async.init(alloc, loop, (struct { - fn callback(_: *libuv.Async) void {} + var wakeup_h = try libuv.Async.init(alloc, loop, renderCallback); + errdefer wakeup_h.close((struct { + fn callback(h: *libuv.Async) void { + const loop_alloc = h.loop().getData(Allocator).?.*; + h.deinit(loop_alloc); + } }).callback); - errdefer async_h.close((struct { + + // This async handle is used to stop the loop and force the thread to end. + var stop_h = try libuv.Async.init(alloc, loop, stopCallback); + errdefer stop_h.close((struct { fn callback(h: *libuv.Async) void { const loop_alloc = h.loop().getData(Allocator).?.*; h.deinit(loop_alloc); @@ -48,9 +72,12 @@ pub fn init(alloc: Allocator) !Thread { }).callback); return Thread{ - .alloc = alloc, .loop = loop, - .notifier = async_h, + .wakeup = wakeup_h, + .stop = stop_h, + .window = window, + .renderer = renderer_impl, + .state = state, }; } @@ -61,6 +88,20 @@ pub fn deinit(self: *Thread) void { const alloc_ptr = self.loop.getData(Allocator).?; const alloc = alloc_ptr.*; + // Schedule our handles to close + self.stop.close((struct { + fn callback(h: *libuv.Async) void { + const handle_alloc = h.loop().getData(Allocator).?.*; + h.deinit(handle_alloc); + } + }).callback); + self.wakeup.close((struct { + fn callback(h: *libuv.Async) void { + const handle_alloc = h.loop().getData(Allocator).?.*; + h.deinit(handle_alloc); + } + }).callback); + // Run the loop one more time, because destroying our other things // like windows usually cancel all our event loop stuff and we need // one more run through to finalize all the closes. @@ -74,40 +115,54 @@ pub fn deinit(self: *Thread) void { } /// The main entrypoint for the thread. -pub fn threadMain( - window: glfw.Window, - renderer_impl: *const renderer.OpenGL, -) void { +pub fn threadMain(self: *Thread) void { // Call child function so we can use errors... - threadMain_( - window, - renderer_impl, - ) catch |err| { + self.threadMain_() catch |err| { // In the future, we should expose this on the thread struct. log.warn("error in renderer err={}", .{err}); }; } -fn threadMain_( - self: *const Thread, - window: glfw.Window, - renderer_impl: *const renderer.OpenGL, -) !void { - const Renderer = switch (@TypeOf(renderer_impl)) { - .Pointer => |p| p.child, - .Struct => |s| s, - }; - +fn threadMain_(self: *Thread) !void { // Run our thread start/end callbacks. This is important because some // renderers have to do per-thread setup. For example, OpenGL has to set // some thread-local state since that is how it works. - if (@hasDecl(Renderer, "threadEnter")) try renderer_impl.threadEnter(window); - defer if (@hasDecl(Renderer, "threadExit")) renderer_impl.threadExit(); + const Renderer = RendererType(); + if (@hasDecl(Renderer, "threadEnter")) try self.renderer.threadEnter(self.window); + defer if (@hasDecl(Renderer, "threadExit")) self.renderer.threadExit(); - // Setup our timer handle which is used to perform the actual render. - // TODO + // Set up our async handler to support rendering + self.wakeup.setData(self); + defer self.wakeup.setData(null); // Run log.debug("starting renderer thread", .{}); - try self.loop.run(.default); + defer log.debug("exiting renderer thread", .{}); + _ = try self.loop.run(.default); +} + +fn renderCallback(h: *libuv.Async) void { + const t = h.getData(Thread) orelse { + // This shouldn't happen so we log it. + log.warn("render callback fired without data set", .{}); + return; + }; + + t.renderer.render(t.window, t.state.*) catch |err| + log.warn("error rendering err={}", .{err}); +} + +fn stopCallback(h: *libuv.Async) void { + h.loop().stop(); +} + +// This is unnecessary right now but is logic we'll need for when we +// abstract renderers out. +fn RendererType() type { + const self: Thread = undefined; + return switch (@typeInfo(@TypeOf(self.renderer))) { + .Pointer => |p| p.child, + .Struct => |s| s, + else => unreachable, + }; } From ce384c235674827312fb3ce3b5070919ff7ded45 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 24 Oct 2022 09:27:09 -0700 Subject: [PATCH 07/13] renderer: extract the size structs to a shared file --- src/renderer.zig | 1 + src/renderer/OpenGL.zig | 74 ++--------------------------- src/renderer/size.zig | 101 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 71 deletions(-) create mode 100644 src/renderer/size.zig diff --git a/src/renderer.zig b/src/renderer.zig index 2a711ee15..a5d62a725 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -7,6 +7,7 @@ //! APIs. The renderers in this package assume that the renderer is already //! setup (OpenGL has a context, Vulkan has a surface, etc.) +pub usingnamespace @import("renderer/size.zig"); pub const OpenGL = @import("renderer/OpenGL.zig"); pub const Thread = @import("renderer/Thread.zig"); pub const State = @import("renderer/State.zig"); diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index a6908e1b4..652da0a91 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -32,10 +32,10 @@ const CellsLRU = lru.AutoHashMap(struct { alloc: std.mem.Allocator, /// Current dimensions for this grid. -size: GridSize, +size: renderer.GridSize, /// Current cell dimensions for this grid. -cell_size: CellSize, +cell_size: renderer.CellSize, /// The current set of cells to render. cells: std.ArrayListUnmanaged(GPUCell), @@ -787,7 +787,7 @@ pub fn updateCell( /// Set the screen size for rendering. This will update the projection /// used for the shader so that the scaling of the grid is correct. -pub fn setScreenSize(self: *OpenGL, dim: ScreenSize) !void { +pub fn setScreenSize(self: *OpenGL, dim: renderer.ScreenSize) !void { // Update the projection uniform within our shader const bind = try self.program.use(); defer bind.unbind(); @@ -960,71 +960,3 @@ pub fn draw(self: *OpenGL) !void { self.cells.items.len, ); } - -/// The dimensions of a single "cell" in the terminal grid. -/// -/// The dimensions are dependent on the current loaded set of font glyphs. -/// We calculate the width based on the widest character and the height based -/// on the height requirement for an underscore (the "lowest" -- visually -- -/// character). -/// -/// The units for the width and height are in world space. They have to -/// be normalized using the screen projection. -/// -/// TODO(mitchellh): we should recalculate cell dimensions when new glyphs -/// are loaded. -const CellSize = struct { - width: f32, - height: f32, -}; - -/// The dimensions of the screen that the grid is rendered to. This is the -/// terminal screen, so it is likely a subset of the window size. The dimensions -/// should be in pixels. -const ScreenSize = struct { - width: u32, - height: u32, -}; - -/// The dimensions of the grid itself, in rows/columns units. -const GridSize = struct { - const Unit = u32; - - columns: Unit = 0, - rows: Unit = 0, - - /// Update the columns/rows for the grid based on the given screen and - /// cell size. - fn update(self: *GridSize, screen: ScreenSize, cell: CellSize) void { - self.columns = @floatToInt(Unit, @intToFloat(f32, screen.width) / cell.width); - self.rows = @floatToInt(Unit, @intToFloat(f32, screen.height) / cell.height); - } -}; - -test "GridSize update exact" { - var grid: GridSize = .{}; - grid.update(.{ - .width = 100, - .height = 40, - }, .{ - .width = 5, - .height = 10, - }); - - try testing.expectEqual(@as(GridSize.Unit, 20), grid.columns); - try testing.expectEqual(@as(GridSize.Unit, 4), grid.rows); -} - -test "GridSize update rounding" { - var grid: GridSize = .{}; - grid.update(.{ - .width = 20, - .height = 40, - }, .{ - .width = 6, - .height = 15, - }); - - try testing.expectEqual(@as(GridSize.Unit, 3), grid.columns); - try testing.expectEqual(@as(GridSize.Unit, 2), grid.rows); -} diff --git a/src/renderer/size.zig b/src/renderer/size.zig new file mode 100644 index 000000000..cce9ca4b1 --- /dev/null +++ b/src/renderer/size.zig @@ -0,0 +1,101 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const font = @import("../font/main.zig"); + +const log = std.log.scoped(.renderer_size); + +/// The dimensions of a single "cell" in the terminal grid. +/// +/// The dimensions are dependent on the current loaded set of font glyphs. +/// We calculate the width based on the widest character and the height based +/// on the height requirement for an underscore (the "lowest" -- visually -- +/// character). +/// +/// The units for the width and height are in world space. They have to +/// be normalized for any renderer implementation. +pub const CellSize = struct { + width: f32, + height: f32, + + /// Initialize the cell size information from a font group. This ensures + /// that all renderers use the same cell sizing information for the same + /// fonts. + pub fn init(alloc: Allocator, group: *font.GroupCache) !CellSize { + // Get our cell metrics based on a regular font ascii 'M'. Why 'M'? + // Doesn't matter, any normal ASCII will do we're just trying to make + // sure we use the regular font. + const metrics = metrics: { + const index = (try group.indexForCodepoint(alloc, 'M', .regular, .text)).?; + const face = try group.group.faceFromIndex(index); + break :metrics face.metrics; + }; + log.debug("cell dimensions={}", .{metrics}); + + return CellSize{ + .width = metrics.cell_width, + .height = metrics.cell_height, + }; + } +}; + +/// The dimensions of the screen that the grid is rendered to. This is the +/// terminal screen, so it is likely a subset of the window size. The dimensions +/// should be in pixels. +pub const ScreenSize = struct { + width: u32, + height: u32, +}; + +/// The dimensions of the grid itself, in rows/columns units. +pub const GridSize = struct { + const Unit = u32; + + columns: Unit = 0, + rows: Unit = 0, + + /// Initialize a grid size based on a screen and cell size. + pub fn init(screen: ScreenSize, cell: CellSize) GridSize { + var result: GridSize = undefined; + result.update(screen, cell); + return result; + } + + /// Update the columns/rows for the grid based on the given screen and + /// cell size. + pub fn update(self: *GridSize, screen: ScreenSize, cell: CellSize) void { + self.columns = @floatToInt(Unit, @intToFloat(f32, screen.width) / cell.width); + self.rows = @floatToInt(Unit, @intToFloat(f32, screen.height) / cell.height); + } +}; + +test "GridSize update exact" { + const testing = std.testing; + + var grid: GridSize = .{}; + grid.update(.{ + .width = 100, + .height = 40, + }, .{ + .width = 5, + .height = 10, + }); + + try testing.expectEqual(@as(GridSize.Unit, 20), grid.columns); + try testing.expectEqual(@as(GridSize.Unit, 4), grid.rows); +} + +test "GridSize update rounding" { + const testing = std.testing; + + var grid: GridSize = .{}; + grid.update(.{ + .width = 20, + .height = 40, + }, .{ + .width = 6, + .height = 15, + }); + + try testing.expectEqual(@as(GridSize.Unit, 3), grid.columns); + try testing.expectEqual(@as(GridSize.Unit, 2), grid.rows); +} From 45ff936ddf119db143c1cade4dffa45c9929deee Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 24 Oct 2022 09:32:51 -0700 Subject: [PATCH 08/13] no longer store grid size on the renderer --- src/Window.zig | 40 ++++++++++++++++++++++++++++------------ src/renderer/OpenGL.zig | 12 ++++-------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/Window.zig b/src/Window.zig index c76800184..38033c1de 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -89,6 +89,9 @@ terminal_cursor: Cursor, /// Render at least 60fps. render_timer: RenderTimer, +/// The dimensions of the grid in rows and columns. +grid_size: renderer.GridSize, + /// The reader/writer stream for the pty. pty_stream: libuv.Tty, @@ -377,6 +380,12 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo .b = config.foreground.b, }; + // Calculate our grid size based on known dimensions. + const grid_size = renderer.GridSize.init( + .{ .width = window_size.width, .height = window_size.height }, + renderer_impl.cell_size, + ); + // Set a minimum size that is cols=10 h=4. This matches Mac's Terminal.app // but is otherwise somewhat arbitrary. try window.setSizeLimits(.{ @@ -386,8 +395,8 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo // Create our pty var pty = try Pty.open(.{ - .ws_row = @intCast(u16, renderer_impl.size.rows), - .ws_col = @intCast(u16, renderer_impl.size.columns), + .ws_row = @intCast(u16, grid_size.rows), + .ws_col = @intCast(u16, grid_size.columns), .ws_xpixel = @intCast(u16, window_size.width), .ws_ypixel = @intCast(u16, window_size.height), }); @@ -430,7 +439,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo try stream.readStart(ttyReadAlloc, ttyRead); // Create our terminal - var term = try terminal.Terminal.init(alloc, renderer_impl.size.columns, renderer_impl.size.rows); + var term = try terminal.Terminal.init(alloc, grid_size.columns, grid_size.rows); errdefer term.deinit(alloc); // Setup a timer for blinking the cursor @@ -492,6 +501,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo .terminal = term, .terminal_stream = .{ .handler = self }, .terminal_cursor = .{ .timer = timer }, + .grid_size = grid_size, .render_timer = try RenderTimer.init(loop, self, 6, 12), .pty_stream = stream, .config = config, @@ -703,21 +713,27 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void { }; }; - // Update our grid so that the projections on render are correct. - const win = window.getUserPointer(Window) orelse return; - win.renderer.setScreenSize(.{ + const screen_size: renderer.ScreenSize = .{ .width = px_size.width, .height = px_size.height, - }) catch |err| log.err("error updating grid screen size err={}", .{err}); + }; + + // Update our grid so that the projections on render are correct. + const win = window.getUserPointer(Window) orelse return; + win.renderer.setScreenSize(screen_size) catch |err| + log.err("error updating grid screen size err={}", .{err}); + + // Recalculate our grid size + win.grid_size.update(screen_size, win.renderer.cell_size); // Update the size of our terminal state - win.terminal.resize(win.alloc, win.renderer.size.columns, win.renderer.size.rows) catch |err| + win.terminal.resize(win.alloc, win.grid_size.columns, win.grid_size.rows) catch |err| log.err("error updating terminal size: {}", .{err}); // Update the size of our pty win.pty.setSize(.{ - .ws_row = @intCast(u16, win.renderer.size.rows), - .ws_col = @intCast(u16, win.renderer.size.columns), + .ws_row = @intCast(u16, win.grid_size.rows), + .ws_col = @intCast(u16, win.grid_size.columns), .ws_xpixel = @intCast(u16, width), .ws_ypixel = @intCast(u16, height), }) catch |err| log.err("error updating pty screen size err={}", .{err}); @@ -1050,7 +1066,7 @@ fn scrollCallback(window: glfw.Window, xoff: f64, yoff: f64) void { // Positive is up const sign: isize = if (yoff > 0) -1 else 1; - const delta: isize = sign * @max(@divFloor(win.renderer.size.rows, 15), 1); + const delta: isize = sign * @max(@divFloor(win.grid_size.rows, 15), 1); log.info("scroll: delta={}", .{delta}); win.terminal.scrollViewport(.{ .delta = delta }) catch |err| log.err("error scrolling viewport err={}", .{err}); @@ -1800,7 +1816,7 @@ pub fn setMode(self: *Window, mode: terminal.Mode, enabled: bool) !void { self.terminal.setDeccolmSupported(enabled); // Force resize back to the window size - self.terminal.resize(self.alloc, self.renderer.size.columns, self.renderer.size.rows) catch |err| + self.terminal.resize(self.alloc, self.grid_size.columns, self.grid_size.rows) catch |err| log.err("error updating terminal size: {}", .{err}); }, diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 652da0a91..c1857ba3a 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -31,9 +31,6 @@ const CellsLRU = lru.AutoHashMap(struct { alloc: std.mem.Allocator, -/// Current dimensions for this grid. -size: renderer.GridSize, - /// Current cell dimensions for this grid. cell_size: renderer.CellSize, @@ -293,7 +290,6 @@ pub fn init(alloc: Allocator, font_group: *font.GroupCache) !OpenGL { .cells = .{}, .cells_lru = CellsLRU.init(0), .cell_size = .{ .width = metrics.cell_width, .height = metrics.cell_height }, - .size = .{ .rows = 0, .columns = 0 }, .program = program, .vao = vao, .ebo = ebo, @@ -804,21 +800,21 @@ pub fn setScreenSize(self: *OpenGL, dim: renderer.ScreenSize) !void { ); // Recalculate the rows/columns. - self.size.update(dim, self.cell_size); + const grid_size = renderer.GridSize.init(dim, self.cell_size); // Update our LRU. We arbitrarily support a certain number of pages here. // We also always support a minimum number of caching in case a user // is resizing tiny then growing again we can save some of the renders. - const evicted = try self.cells_lru.resize(self.alloc, @max(80, self.size.rows * 10)); + const evicted = try self.cells_lru.resize(self.alloc, @max(80, grid_size.rows * 10)); if (evicted) |list| for (list) |*value| value.deinit(self.alloc); // Update our shaper - var shape_buf = try self.alloc.alloc(font.Shaper.Cell, self.size.columns * 2); + var shape_buf = try self.alloc.alloc(font.Shaper.Cell, grid_size.columns * 2); errdefer self.alloc.free(shape_buf); self.alloc.free(self.font_shaper.cell_buf); self.font_shaper.cell_buf = shape_buf; - log.debug("screen size screen={} grid={}, cell={}", .{ dim, self.size, self.cell_size }); + log.debug("screen size screen={} grid={}, cell={}", .{ dim, grid_size, self.cell_size }); } /// Updates the font texture atlas if it is dirty. From dc908cb73d89482193c1dfdb8a379a16fe25ba27 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 24 Oct 2022 09:52:08 -0700 Subject: [PATCH 09/13] support screen size, rip out shared state --- src/Window.zig | 42 ++++++++++++++++++----------------- src/renderer/OpenGL.zig | 49 +++++++++++++++++++++++++++++++++-------- src/renderer/State.zig | 5 ++--- src/renderer/Thread.zig | 6 ++--- 4 files changed, 67 insertions(+), 35 deletions(-) diff --git a/src/Window.zig b/src/Window.zig index 38033c1de..5bf10b6aa 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -367,8 +367,11 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo // Create our terminal grid with the initial window size const window_size = try window.getSize(); + const screen_size: renderer.ScreenSize = .{ + .width = window_size.width, + .height = window_size.height, + }; var renderer_impl = try renderer.OpenGL.init(alloc, font_group); - try renderer_impl.setScreenSize(.{ .width = window_size.width, .height = window_size.height }); renderer_impl.background = .{ .r = config.background.r, .g = config.background.g, @@ -381,10 +384,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo }; // Calculate our grid size based on known dimensions. - const grid_size = renderer.GridSize.init( - .{ .width = window_size.width, .height = window_size.height }, - renderer_impl.cell_size, - ); + const grid_size = renderer.GridSize.init(screen_size, renderer_impl.cell_size); // Set a minimum size that is cols=10 h=4. This matches Mac's Terminal.app // but is otherwise somewhat arbitrary. @@ -486,6 +486,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo .renderer_thread = render_thread, .renderer_state = .{ .mutex = mutex, + .resize_screen = screen_size, .cursor = .{ .style = .blinking_block, .visible = true, @@ -516,7 +517,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo // Setup our callbacks and user data window.setUserPointer(self); - //window.setSizeCallback(sizeCallback); + window.setSizeCallback(sizeCallback); window.setCharCallback(charCallback); window.setKeyCallback(keyCallback); window.setFocusCallback(focusCallback); @@ -718,18 +719,15 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void { .height = px_size.height, }; - // Update our grid so that the projections on render are correct. const win = window.getUserPointer(Window) orelse return; - win.renderer.setScreenSize(screen_size) catch |err| - log.err("error updating grid screen size err={}", .{err}); + + // Resize usually forces a redraw + win.render_timer.schedule() catch |err| + log.err("error scheduling render timer in sizeCallback err={}", .{err}); // Recalculate our grid size win.grid_size.update(screen_size, win.renderer.cell_size); - // Update the size of our terminal state - win.terminal.resize(win.alloc, win.grid_size.columns, win.grid_size.rows) catch |err| - log.err("error updating terminal size: {}", .{err}); - // Update the size of our pty win.pty.setSize(.{ .ws_row = @intCast(u16, win.grid_size.rows), @@ -738,14 +736,18 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void { .ws_ypixel = @intCast(u16, height), }) catch |err| log.err("error updating pty screen size err={}", .{err}); - // Update our viewport for this context to be the entire window. - // OpenGL works in pixels, so we have to use the pixel size. - gl.viewport(0, 0, @intCast(i32, px_size.width), @intCast(i32, px_size.height)) catch |err| - log.err("error updating OpenGL viewport err={}", .{err}); + // Enter the critical area that we want to keep small + { + win.renderer_state.mutex.lock(); + defer win.renderer_state.mutex.unlock(); - // Draw - win.render_timer.schedule() catch |err| - log.err("error scheduling render timer in sizeCallback err={}", .{err}); + // We need to setup our render state to store our new pending size + win.renderer_state.resize_screen = screen_size; + + // Update the size of our terminal state + win.terminal.resize(win.alloc, win.grid_size.columns, win.grid_size.rows) catch |err| + log.err("error updating terminal size: {}", .{err}); + } } fn charCallback(window: glfw.Window, codepoint: u21) void { diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index c1857ba3a..ddb189804 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -359,14 +359,24 @@ pub fn threadExit(self: *const OpenGL) void { pub fn render( self: *OpenGL, window: glfw.Window, - state: renderer.State, + state: *renderer.State, ) !void { + // Data we extract out of the critical area. + const Critical = struct { + devmode_data: ?*imgui.DrawData, + screen_size: ?renderer.ScreenSize, + }; + // Update all our data as tightly as possible within the mutex. var gl_bg = self.background; - { + const critical: Critical = critical: { state.mutex.lock(); defer state.mutex.unlock(); + // If we're resizing, then handle that now. + if (state.resize_screen) |size| try self.setScreenSize(size); + defer state.resize_screen = null; + // Setup our cursor state self.cursor_visible = state.cursor.visible and !state.cursor.blink; self.cursor_style = CursorStyle.fromTerminal(state.cursor.style) orelse .box; @@ -384,9 +394,33 @@ pub fn render( self.foreground = bg; } + // Build our GPU cells try self.rebuildCells(state.terminal); try self.finalizeCells(state.terminal); - if (state.devmode) |dm| if (dm.visible) try dm.update(); + + // Build our devmode draw data + const devmode_data = devmode_data: { + if (state.devmode) |dm| { + if (dm.visible) { + try dm.update(); + break :devmode_data try dm.render(); + } + } + + break :devmode_data null; + }; + + break :critical .{ + .devmode_data = devmode_data, + .screen_size = state.resize_screen, + }; + }; + + // If we are resizing we need to update the viewport + if (critical.screen_size) |size| { + // Update our viewport for this context to be the entire window. + // OpenGL works in pixels, so we have to use the pixel size. + try gl.viewport(0, 0, @intCast(i32, size.width), @intCast(i32, size.height)); } // Clear the surface @@ -402,11 +436,8 @@ pub fn render( try self.draw(); // If we have devmode, then render that - if (state.devmode) |dm| { - if (dm.visible) { - const data = try dm.render(); - imgui.ImplOpenGL3.renderDrawData(data); - } + if (critical.devmode_data) |data| { + imgui.ImplOpenGL3.renderDrawData(data); } // Swap our window buffers @@ -783,7 +814,7 @@ pub fn updateCell( /// Set the screen size for rendering. This will update the projection /// used for the shader so that the scaling of the grid is correct. -pub fn setScreenSize(self: *OpenGL, dim: renderer.ScreenSize) !void { +fn setScreenSize(self: *OpenGL, dim: renderer.ScreenSize) !void { // Update the projection uniform within our shader const bind = try self.program.use(); defer bind.unbind(); diff --git a/src/renderer/State.zig b/src/renderer/State.zig index 25963ded5..2c3e6c36c 100644 --- a/src/renderer/State.zig +++ b/src/renderer/State.zig @@ -3,6 +3,7 @@ const std = @import("std"); const DevMode = @import("../DevMode.zig"); const terminal = @import("../terminal/main.zig"); +const renderer = @import("../renderer.zig"); /// The mutex that must be held while reading any of the data in the /// members of this state. Note that the state itself is NOT protected @@ -11,7 +12,7 @@ const terminal = @import("../terminal/main.zig"); mutex: *std.Thread.Mutex, /// A new screen size if the screen was resized. -resize: ?Resize = null, +resize_screen: ?renderer.ScreenSize, /// Cursor configuration for rendering cursor: Cursor, @@ -36,5 +37,3 @@ pub const Cursor = struct { /// the cursor will not be rendered. blink: bool = false, }; - -pub const Resize = struct {}; diff --git a/src/renderer/Thread.zig b/src/renderer/Thread.zig index 4cb12f99f..ed598ec4e 100644 --- a/src/renderer/Thread.zig +++ b/src/renderer/Thread.zig @@ -31,7 +31,7 @@ window: glfw.Window, renderer: *renderer.OpenGL, /// Pointer to the shared state that is used to generate the final render. -state: *const renderer.State, +state: *renderer.State, /// Initialize the thread. This does not START the thread. This only sets /// up all the internal state necessary prior to starting the thread. It @@ -40,7 +40,7 @@ pub fn init( alloc: Allocator, window: glfw.Window, renderer_impl: *renderer.OpenGL, - state: *const renderer.State, + state: *renderer.State, ) !Thread { // We always store allocator pointer on the loop data so that // handles can use our global allocator. @@ -148,7 +148,7 @@ fn renderCallback(h: *libuv.Async) void { return; }; - t.renderer.render(t.window, t.state.*) catch |err| + t.renderer.render(t.window, t.state) catch |err| log.warn("error rendering err={}", .{err}); } From b4859625bf0ff1f06e6a03e0f1fd55ccb7b9c170 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 24 Oct 2022 10:01:38 -0700 Subject: [PATCH 10/13] bring back out of focus no blink --- src/Window.zig | 17 ++++++----------- src/renderer/OpenGL.zig | 9 +++++++-- src/renderer/State.zig | 3 +++ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/Window.zig b/src/Window.zig index 5bf10b6aa..4067e3822 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -50,9 +50,6 @@ cursor: glfw.Cursor, /// Imgui context imgui_ctx: if (DevMode.enabled) *imgui.Context else void, -/// Whether the window is currently focused -focused: bool, - /// The renderer for this window. renderer: renderer.OpenGL, @@ -481,11 +478,11 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo .font_group = font_group, .window = window, .cursor = cursor, - .focused = false, .renderer = renderer_impl, .renderer_thread = render_thread, .renderer_state = .{ .mutex = mutex, + .focused = false, .resize_screen = screen_size, .cursor = .{ .style = .blinking_block, @@ -1004,22 +1001,20 @@ fn focusCallback(window: glfw.Window, focused: bool) void { const win = window.getUserPointer(Window) orelse return; - // If we aren't changing focus state, do nothing. I don't think this - // can happen but it costs very little to check. - if (win.focused == focused) return; - // We have to schedule a render because no matter what we're changing // the cursor. If we're focused its reappearing, if we're not then // its changing to hollow and not blinking. win.render_timer.schedule() catch unreachable; - // Set our focused state on the window. - win.focused = focused; - if (focused) win.terminal_cursor.startTimer() catch unreachable else win.terminal_cursor.stopTimer() catch unreachable; + + // We are modifying renderer state from here on out + win.renderer_state.mutex.lock(); + defer win.renderer_state.mutex.unlock(); + win.renderer_state.focused = focused; } fn refreshCallback(window: glfw.Window) void { diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index ddb189804..7ae9b8bea 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -378,8 +378,13 @@ pub fn render( defer state.resize_screen = null; // Setup our cursor state - self.cursor_visible = state.cursor.visible and !state.cursor.blink; - self.cursor_style = CursorStyle.fromTerminal(state.cursor.style) orelse .box; + if (state.focused) { + self.cursor_visible = state.cursor.visible and !state.cursor.blink; + self.cursor_style = CursorStyle.fromTerminal(state.cursor.style) orelse .box; + } else { + self.cursor_visible = true; + self.cursor_style = .box_hollow; + } // Swap bg/fg if the terminal is reversed const bg = self.background; diff --git a/src/renderer/State.zig b/src/renderer/State.zig index 2c3e6c36c..f03182f27 100644 --- a/src/renderer/State.zig +++ b/src/renderer/State.zig @@ -11,6 +11,9 @@ const renderer = @import("../renderer.zig"); /// state (i.e. the terminal, devmode, etc. values). mutex: *std.Thread.Mutex, +/// True if the window is focused +focused: bool, + /// A new screen size if the screen was resized. resize_screen: ?renderer.ScreenSize, From 536f5c44878cf7fb5b7536379d2eec237f168c50 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 24 Oct 2022 10:04:40 -0700 Subject: [PATCH 11/13] set proper opengl background --- src/renderer/OpenGL.zig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 7ae9b8bea..40ad1e036 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -363,12 +363,12 @@ pub fn render( ) !void { // Data we extract out of the critical area. const Critical = struct { + gl_bg: terminal.color.RGB, devmode_data: ?*imgui.DrawData, screen_size: ?renderer.ScreenSize, }; // Update all our data as tightly as possible within the mutex. - var gl_bg = self.background; const critical: Critical = critical: { state.mutex.lock(); defer state.mutex.unlock(); @@ -394,7 +394,6 @@ pub fn render( self.foreground = fg; } if (state.terminal.modes.reverse_colors) { - gl_bg = fg; self.background = fg; self.foreground = bg; } @@ -416,6 +415,7 @@ pub fn render( }; break :critical .{ + .gl_bg = self.background, .devmode_data = devmode_data, .screen_size = state.resize_screen, }; @@ -430,9 +430,9 @@ pub fn render( // Clear the surface gl.clearColor( - @intToFloat(f32, self.background.r) / 255, - @intToFloat(f32, self.background.g) / 255, - @intToFloat(f32, self.background.b) / 255, + @intToFloat(f32, critical.gl_bg.r) / 255, + @intToFloat(f32, critical.gl_bg.g) / 255, + @intToFloat(f32, critical.gl_bg.b) / 255, 1.0, ); gl.clear(gl.c.GL_COLOR_BUFFER_BIT); From c0f96f591bb4c0d83fd43a6ea52e5ae4898f1368 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 24 Oct 2022 10:50:42 -0700 Subject: [PATCH 12/13] remove render timer from window --- src/Window.zig | 68 ++++++++++++++++------------------------- src/renderer/Thread.zig | 48 +++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 44 deletions(-) diff --git a/src/Window.zig b/src/Window.zig index 4067e3822..20c775c6b 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -25,8 +25,6 @@ const Config = @import("config.zig").Config; const input = @import("input.zig"); const DevMode = @import("DevMode.zig"); -const RenderTimer = max_timer.MaxTimer(renderTimerCallback); - const log = std.log.scoped(.window); // The preallocation size for the write request pool. This should be big @@ -83,9 +81,6 @@ terminal_stream: terminal.Stream(*Window), /// Cursor state. terminal_cursor: Cursor, -/// Render at least 60fps. -render_timer: RenderTimer, - /// The dimensions of the grid in rows and columns. grid_size: renderer.GridSize, @@ -500,7 +495,6 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo .terminal_stream = .{ .handler = self }, .terminal_cursor = .{ .timer = timer }, .grid_size = grid_size, - .render_timer = try RenderTimer.init(loop, self, 6, 12), .pty_stream = stream, .config = config, .bg_r = @intToFloat(f32, config.background.r) / 255.0, @@ -616,8 +610,6 @@ pub fn destroy(self: *Window) void { } }).callback); - self.render_timer.deinit(); - // We have to dealloc our window in the close callback because // we can't free some of the memory associated with the window // until the stream is closed. @@ -668,6 +660,13 @@ fn queueWrite(self: *Window, data: []const u8) !void { } } +/// This queues a render operation with the renderer thread. The render +/// isn't guaranteed to happen immediately but it will happen as soon as +/// practical. +fn queueRender(self: *const Window) !void { + try self.renderer_thread.wakeup.send(); +} + /// The cursor position from glfw directly is in screen coordinates but /// all our internal state works in pixels. fn cursorPosToPixels(self: Window, pos: glfw.Window.CursorPos) glfw.Window.CursorPos { @@ -719,7 +718,7 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void { const win = window.getUserPointer(Window) orelse return; // Resize usually forces a redraw - win.render_timer.schedule() catch |err| + win.queueRender() catch |err| log.err("error scheduling render timer in sizeCallback err={}", .{err}); // Recalculate our grid size @@ -758,7 +757,7 @@ fn charCallback(window: glfw.Window, codepoint: u21) void { // If the event was handled by imgui, ignore it. if (imgui.IO.get()) |io| { if (io.cval().WantCaptureKeyboard) { - win.render_timer.schedule() catch |err| + win.queueRender() catch |err| log.err("error scheduling render timer err={}", .{err}); } } else |_| {} @@ -773,7 +772,7 @@ fn charCallback(window: glfw.Window, codepoint: u21) void { // Anytime is character is created, we have to clear the selection if (win.terminal.selection != null) { win.terminal.selection = null; - win.render_timer.schedule() catch |err| + win.queueRender() catch |err| log.err("error scheduling render in charCallback err={}", .{err}); } @@ -781,7 +780,7 @@ fn charCallback(window: glfw.Window, codepoint: u21) void { // TODO: detect if we're at the bottom to avoid the render call here. win.terminal.scrollViewport(.{ .bottom = {} }) catch |err| log.err("error scrolling viewport err={}", .{err}); - win.render_timer.schedule() catch |err| + win.queueRender() catch |err| log.err("error scheduling render in charCallback err={}", .{err}); // Write the character to the pty @@ -806,7 +805,7 @@ fn keyCallback( // If the event was handled by imgui, ignore it. if (imgui.IO.get()) |io| { if (io.cval().WantCaptureKeyboard) { - win.render_timer.schedule() catch |err| + win.queueRender() catch |err| log.err("error scheduling render timer err={}", .{err}); } } else |_| {} @@ -927,7 +926,7 @@ fn keyCallback( .toggle_dev_mode => if (DevMode.enabled) { DevMode.instance.visible = !DevMode.instance.visible; - win.render_timer.schedule() catch unreachable; + win.queueRender() catch unreachable; } else log.warn("dev mode was not compiled into this binary", .{}), } @@ -1004,7 +1003,7 @@ fn focusCallback(window: glfw.Window, focused: bool) void { // We have to schedule a render because no matter what we're changing // the cursor. If we're focused its reappearing, if we're not then // its changing to hollow and not blinking. - win.render_timer.schedule() catch unreachable; + win.queueRender() catch unreachable; if (focused) win.terminal_cursor.startTimer() catch unreachable @@ -1024,7 +1023,7 @@ fn refreshCallback(window: glfw.Window) void { const win = window.getUserPointer(Window) orelse return; // The point of this callback is to schedule a render, so do that. - win.render_timer.schedule() catch unreachable; + win.queueRender() catch unreachable; } fn scrollCallback(window: glfw.Window, xoff: f64, yoff: f64) void { @@ -1036,7 +1035,7 @@ fn scrollCallback(window: glfw.Window, xoff: f64, yoff: f64) void { // If our dev mode window is visible then we always schedule a render on // cursor move because the cursor might touch our windows. if (DevMode.enabled and DevMode.instance.visible) { - win.render_timer.schedule() catch |err| + win.queueRender() catch |err| log.err("error scheduling render timer err={}", .{err}); // If the mouse event was handled by imgui, ignore it. @@ -1071,7 +1070,7 @@ fn scrollCallback(window: glfw.Window, xoff: f64, yoff: f64) void { // Schedule render since scrolling usually does something. // TODO(perf): we can only schedule render if we know scrolling // did something - win.render_timer.schedule() catch unreachable; + win.queueRender() catch unreachable; } /// The type of action to report for a mouse event. @@ -1256,7 +1255,7 @@ fn mouseButtonCallback( // If our dev mode window is visible then we always schedule a render on // cursor move because the cursor might touch our windows. if (DevMode.enabled and DevMode.instance.visible) { - win.render_timer.schedule() catch |err| + win.queueRender() catch |err| log.err("error scheduling render timer in cursorPosCallback err={}", .{err}); // If the mouse event was handled by imgui, ignore it. @@ -1326,7 +1325,7 @@ fn mouseButtonCallback( // Selection is always cleared if (win.terminal.selection != null) { win.terminal.selection = null; - win.render_timer.schedule() catch |err| + win.queueRender() catch |err| log.err("error scheduling render in mouseButtinCallback err={}", .{err}); } } @@ -1345,7 +1344,7 @@ fn cursorPosCallback( // If our dev mode window is visible then we always schedule a render on // cursor move because the cursor might touch our windows. if (DevMode.enabled and DevMode.instance.visible) { - win.render_timer.schedule() catch |err| + win.queueRender() catch |err| log.err("error scheduling render timer in cursorPosCallback err={}", .{err}); // If the mouse event was handled by imgui, ignore it. @@ -1380,7 +1379,7 @@ fn cursorPosCallback( if (win.mouse.click_state[@enumToInt(input.MouseButton.left)] != .press) return; // All roads lead to requiring a re-render at this pont. - win.render_timer.schedule() catch |err| + win.queueRender() catch |err| log.err("error scheduling render timer in cursorPosCallback err={}", .{err}); // Convert to pixels from screen coords @@ -1533,7 +1532,7 @@ fn cursorTimerCallback(t: *libuv.Timer) void { // Swap blink state and schedule a render win.renderer_state.cursor.blink = !win.renderer_state.cursor.blink; - win.render_timer.schedule() catch unreachable; + win.queueRender() catch unreachable; } fn ttyReadAlloc(t: *libuv.Tty, size: usize) ?[]u8 { @@ -1582,7 +1581,7 @@ fn ttyRead(t: *libuv.Tty, n: isize, buf: []const u8) void { } // Schedule a render - win.render_timer.schedule() catch unreachable; + win.queueRender() catch unreachable; // Process the terminal data. This is an extremely hot part of the // terminal emulator, so we do some abstraction leakage to avoid @@ -1639,21 +1638,6 @@ fn ttyWrite(req: *libuv.WriteReq, status: i32) void { //log.info("WROTE: {d}", .{status}); } -fn renderTimerCallback(t: *libuv.Timer) void { - const tracy = trace(@src()); - tracy.color(0x006E7F); // blue-ish - defer tracy.end(); - - const win = t.getData(Window).?; - - // Trigger a render - win.renderer_thread.wakeup.send() catch |err| - log.err("error sending render notification err={}", .{err}); - - // Record our run - win.render_timer.tick(); -} - //------------------------------------------------------------------- // Stream Callbacks @@ -1722,7 +1706,7 @@ pub fn eraseDisplay(self: *Window, mode: terminal.EraseDisplay) !void { if (mode == .complete) { // Whenever we erase the full display, scroll to bottom. try self.terminal.scrollViewport(.{ .bottom = {} }); - try self.render_timer.schedule(); + try self.queueRender(); } self.terminal.eraseDisplay(mode); @@ -1775,7 +1759,7 @@ pub fn setMode(self: *Window, mode: terminal.Mode, enabled: bool) !void { self.terminal.modes.reverse_colors = enabled; // Schedule a render since we changed colors - try self.render_timer.schedule(); + try self.queueRender(); }, .origin => { @@ -1803,7 +1787,7 @@ pub fn setMode(self: *Window, mode: terminal.Mode, enabled: bool) !void { self.terminal.primaryScreen(opts); // Schedule a render since we changed screens - try self.render_timer.schedule(); + try self.queueRender(); }, .bracketed_paste => self.bracketed_paste = true, diff --git a/src/renderer/Thread.zig b/src/renderer/Thread.zig index ed598ec4e..9a6b71605 100644 --- a/src/renderer/Thread.zig +++ b/src/renderer/Thread.zig @@ -24,6 +24,9 @@ wakeup: libuv.Async, /// This can be used to stop the renderer on the next loop iteration. stop: libuv.Async, +/// The timer used for rendering +render_h: libuv.Timer, + /// The windo we're rendering to. window: glfw.Window, @@ -54,7 +57,7 @@ pub fn init( loop.setData(allocPtr); // This async handle is used to "wake up" the renderer and force a render. - var wakeup_h = try libuv.Async.init(alloc, loop, renderCallback); + var wakeup_h = try libuv.Async.init(alloc, loop, wakeupCallback); errdefer wakeup_h.close((struct { fn callback(h: *libuv.Async) void { const loop_alloc = h.loop().getData(Allocator).?.*; @@ -71,10 +74,20 @@ pub fn init( } }).callback); + // The primary timer for rendering. + var render_h = try libuv.Timer.init(alloc, loop); + errdefer render_h.close((struct { + fn callback(h: *libuv.Timer) void { + const loop_alloc = h.loop().getData(Allocator).?.*; + h.deinit(loop_alloc); + } + }).callback); + return Thread{ .loop = loop, .wakeup = wakeup_h, .stop = stop_h, + .render_h = render_h, .window = window, .renderer = renderer_impl, .state = state, @@ -101,6 +114,12 @@ pub fn deinit(self: *Thread) void { h.deinit(handle_alloc); } }).callback); + self.render_h.close((struct { + fn callback(h: *libuv.Timer) void { + const handle_alloc = h.loop().getData(Allocator).?.*; + h.deinit(handle_alloc); + } + }).callback); // Run the loop one more time, because destroying our other things // like windows usually cancel all our event loop stuff and we need @@ -124,6 +143,10 @@ pub fn threadMain(self: *Thread) void { } fn threadMain_(self: *Thread) !void { + // Get a copy to our allocator + // const alloc_ptr = self.loop.getData(Allocator).?; + // const alloc = alloc_ptr.*; + // Run our thread start/end callbacks. This is important because some // renderers have to do per-thread setup. For example, OpenGL has to set // some thread-local state since that is how it works. @@ -135,13 +158,34 @@ fn threadMain_(self: *Thread) !void { self.wakeup.setData(self); defer self.wakeup.setData(null); + // Set up our timer and start it for rendering + self.render_h.setData(self); + defer self.render_h.setData(null); + try self.wakeup.send(); + // Run log.debug("starting renderer thread", .{}); defer log.debug("exiting renderer thread", .{}); _ = try self.loop.run(.default); } -fn renderCallback(h: *libuv.Async) void { +fn wakeupCallback(h: *libuv.Async) void { + const t = h.getData(Thread) orelse { + // This shouldn't happen so we log it. + log.warn("render callback fired without data set", .{}); + return; + }; + + // If the timer is already active then we don't have to do anything. + const active = t.render_h.isActive() catch true; + if (active) return; + + // Timer is not active, let's start it + t.render_h.start(renderCallback, 10, 0) catch |err| + log.warn("render timer failed to start err={}", .{err}); +} + +fn renderCallback(h: *libuv.Timer) void { const t = h.getData(Thread) orelse { // This shouldn't happen so we log it. log.warn("render callback fired without data set", .{}); From c2ce158342f4b51a1e1dd24522f36b3b69faa28e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 24 Oct 2022 10:54:38 -0700 Subject: [PATCH 13/13] remove the max timer --- src/Window.zig | 1 - src/max_timer.zig | 109 ---------------------------------------------- 2 files changed, 110 deletions(-) delete mode 100644 src/max_timer.zig diff --git a/src/Window.zig b/src/Window.zig index 20c775c6b..91b82b8af 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -19,7 +19,6 @@ const font = @import("font/main.zig"); const Command = @import("Command.zig"); const SegmentedPool = @import("segmented_pool.zig").SegmentedPool; const trace = @import("tracy").trace; -const max_timer = @import("max_timer.zig"); const terminal = @import("terminal/main.zig"); const Config = @import("config.zig").Config; const input = @import("input.zig"); diff --git a/src/max_timer.zig b/src/max_timer.zig deleted file mode 100644 index bacfa0b92..000000000 --- a/src/max_timer.zig +++ /dev/null @@ -1,109 +0,0 @@ -const std = @import("std"); -const assert = std.debug.assert; -const Allocator = std.mem.Allocator; -const libuv = @import("libuv"); - -/// A coalescing timer that forces a run after a certain maximum time -/// since the last run. This is used for example by the renderer to try -/// to render at a high FPS but gracefully fall back under high IO load so -/// that we can process more data and increase throughput. -pub fn MaxTimer(comptime cb: fn (*libuv.Timer) void) type { - return struct { - const Self = @This(); - - /// The underlying libuv timer. - timer: libuv.Timer, - - /// The maximum time between timer calls. This is best effort based on - /// event loop load. If the event loop is busy, the timer will be run on - /// the next available tick. - max: u64, - - /// The fastest the timer will ever run. - min: u64, - - /// The last time this timer ran. - last: u64 = 0, - - /// This handle is used to wake up the event loop when the timer - /// is restarted. - async_h: libuv.Async, - - pub fn init( - loop: libuv.Loop, - data: ?*anyopaque, - min: u64, - max: u64, - ) !Self { - const alloc = loop.getData(Allocator).?.*; - var timer = try libuv.Timer.init(alloc, loop); - timer.setData(data); - - // The async handle is used to wake up the event loop. This is - // necessary since stop/starting a timer doesn't trigger the - // poll on the backend fd. - var async_h = try libuv.Async.init(alloc, loop, (struct { - fn callback(_: *libuv.Async) void {} - }).callback); - - // The maximum time can't be less than the interval otherwise this - // will just constantly fire. if (max < min) return error.MaxShorterThanTimer; - return Self{ - .timer = timer, - .min = min, - .max = max, - .async_h = async_h, - }; - } - - pub fn deinit(self: *Self) void { - self.async_h.close((struct { - fn callback(h: *libuv.Async) void { - const alloc = h.loop().getData(Allocator).?.*; - h.deinit(alloc); - } - }).callback); - - self.timer.close((struct { - fn callback(t: *libuv.Timer) void { - const alloc = t.loop().getData(Allocator).?.*; - t.deinit(alloc); - } - }).callback); - } - - /// This should be called from the callback to update the last called time. - pub fn tick(self: *Self) void { - self.timer.loop().updateTime(); - self.last = self.timer.loop().now(); - self.timer.stop() catch unreachable; - } - - /// Schedule the timer to run. If the timer is not started, it'll - /// run on the next min tick. If the timer is started, this will - /// delay the timer up to max time since the last run. - pub fn schedule(self: *Self) !void { - // If the timer hasn't been started, start it now and schedule - // a tick as soon as possible. - if (!try self.timer.isActive()) { - try self.timer.start(cb, self.min, self.min); - - // We have to send an async message to wake up the - // event loop. Starting a timer doesn't write to the fd. - try self.async_h.send(); - return; - } - - // If we are past the max time, we run the timer now. - try self.timer.stop(); - self.timer.loop().updateTime(); - const timeout = if (self.timer.loop().now() - self.last > self.max) - 0 - else - self.min; - - // We still have time, restart the timer so that it is min time away. - try self.timer.start(cb, timeout, 0); - } - }; -}