aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Silas Bartha <silas@exvacuum.dev>2025-02-07 11:27:18 -0500
committerLibravatar Silas Bartha <silas@exvacuum.dev>2025-02-07 11:27:18 -0500
commit4da7be39827ea5888ef9c97b1aadf61b0d76347c (patch)
tree15d0ff8f8bcb0e871efb1b2e65c2bc8d07b17565
initial commit (lol)
-rw-r--r--.clang-format18
-rw-r--r--.gitignore3
-rw-r--r--CMakeLists.txt14
l---------compile_commands.json1
-rw-r--r--marble_bust/marble_bust_01.binbin0 -> 416608 bytes
-rw-r--r--marble_bust/marble_bust_01_4k.gltf161
-rw-r--r--marble_bust/textures/marble_bust_01_diff_4k.qoibin0 -> 17442263 bytes
-rw-r--r--marble_bust/textures/marble_bust_01_nor_gl_4k.qoibin0 -> 18591523 bytes
-rw-r--r--marble_bust/textures/marble_bust_01_rough_4k.qoibin0 -> 15629378 bytes
-rw-r--r--mons_3d/CMakeLists.txt41
-rw-r--r--mons_3d/external/glad/include/KHR/khrplatform.h311
-rw-r--r--mons_3d/external/glad/include/glad/gl.h3644
-rw-r--r--mons_3d/external/glad/include/glad/glx.h566
-rw-r--r--mons_3d/external/glad/src/gl.c1786
-rw-r--r--mons_3d/external/glad/src/glx.c352
-rw-r--r--mons_3d/external/mikktspace/include/mikktspace.h145
-rw-r--r--mons_3d/external/mikktspace/src/mikktspace.c1899
-rw-r--r--mons_3d/include/camera.h12
-rw-r--r--mons_3d/include/color.h12
-rw-r--r--mons_3d/include/light.h12
-rw-r--r--mons_3d/include/mesh.h14
-rw-r--r--mons_3d/include/model.h19
-rw-r--r--mons_3d/include/projection.h13
-rw-r--r--mons_3d/include/shader.h35
-rw-r--r--mons_3d/include/texture.h19
-rw-r--r--mons_3d/include/transform.h36
-rw-r--r--mons_3d/include/vertex.h15
-rw-r--r--mons_3d/src/color.c1
-rw-r--r--mons_3d/src/mesh.c124
-rw-r--r--mons_3d/src/model.c15
-rw-r--r--mons_3d/src/projection.c15
-rw-r--r--mons_3d/src/shader.c185
-rw-r--r--mons_3d/src/texture.c55
-rw-r--r--mons_3d/src/transform.c112
-rw-r--r--mons_collections/CMakeLists.txt29
-rw-r--r--mons_collections/include/hashmap.h23
-rw-r--r--mons_collections/src/hashmap.c141
-rw-r--r--mons_exe/CMakeLists.txt36
-rw-r--r--mons_exe/embed/shaders/basic.vert.glsl26
-rw-r--r--mons_exe/embed/shaders/basic_lit.frag.glsl27
-rwxr-xr-xmons_exe/embed_headers.sh10
-rw-r--r--mons_exe/include/embedded/shaders/basic.vert.glsl.h64
-rw-r--r--mons_exe/include/embedded/shaders/basic_lit.frag.glsl.h65
-rw-r--r--mons_exe/include/input.h113
-rw-r--r--mons_exe/src/input.c0
-rw-r--r--mons_exe/src/main.c247
-rw-r--r--mons_gltf/CMakeLists.txt30
-rw-r--r--mons_gltf/include/gltf.h11
-rw-r--r--mons_gltf/src/gltf.c549
-rw-r--r--mons_image/CMakeLists.txt30
-rw-r--r--mons_image/include/image.h19
-rw-r--r--mons_image/include/qoi.h7
-rw-r--r--mons_image/src/image.c6
-rw-r--r--mons_image/src/qoi.c140
-rw-r--r--mons_json/CMakeLists.txt30
-rw-r--r--mons_json/include/json.h52
-rw-r--r--mons_json/src/json.c468
-rw-r--r--mons_math/CMakeLists.txt43
-rw-r--r--mons_math/include/mons_math/mat2.h39
-rw-r--r--mons_math/include/mons_math/mat3.h41
-rw-r--r--mons_math/include/mons_math/mat4.h57
-rw-r--r--mons_math/include/mons_math/matrix.h8
-rw-r--r--mons_math/include/mons_math/quat.h44
-rw-r--r--mons_math/include/mons_math/util.h8
-rw-r--r--mons_math/include/mons_math/vec2.h46
-rw-r--r--mons_math/include/mons_math/vec3.h56
-rw-r--r--mons_math/include/mons_math/vec4.h53
-rw-r--r--mons_math/include/mons_math/vector.h8
-rwxr-xr-xmons_math/run_tests6
-rw-r--r--mons_math/src/mat2.c123
-rw-r--r--mons_math/src/mat3.c237
-rw-r--r--mons_math/src/mat4.c321
-rw-r--r--mons_math/src/quat.c141
-rw-r--r--mons_math/src/util.c7
-rw-r--r--mons_math/src/vec2.c120
-rw-r--r--mons_math/src/vec3.c175
-rw-r--r--mons_math/src/vec4.c149
-rw-r--r--mons_math/tests/mat2_ops.c0
-rw-r--r--mons_math/tests/mat3_ops.c0
-rw-r--r--mons_math/tests/mat4_ops.c0
-rw-r--r--mons_math/tests/test.h14
-rw-r--r--mons_math/tests/vec2_ops.c81
-rw-r--r--mons_math/tests/vec3_ops.c90
-rw-r--r--mons_math/tests/vec4_ops.c81
84 files changed, 13706 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..cb27a7b
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,18 @@
+
+# TabWidth (unsigned)
+# The number of columns used for tab stops.
+TabWidth: 4
+
+# IndentWidth (unsigned)
+# The number of columns to use for indentation.
+IndentWidth: 4
+
+# UseTab (UseTabStyle)
+# The way to use tab characters in the resulting file.
+# Possible values:
+# UT_Never (in configuration: Never) Never use tab.
+# UT_ForIndentation (in configuration: ForIndentation) Use tabs only for indentation.
+# UT_Always (in configuration: Always) Use tabs whenever we need to fill whitespace that spans at least from one tab stop to the next one.
+UseTab: Never
+
+SortIncludes: false
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..64f0cc9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+build
+.ccls-cache
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..9168757
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.14)
+project(mons_math LANGUAGES C)
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_EXPORT_COMPILE_COMMANDS true)
+set(CMAKE_BUILD_TYPE "Debug")
+
+add_subdirectory(./mons_math)
+add_subdirectory(./mons_collections)
+add_subdirectory(./mons_json)
+add_subdirectory(./mons_image)
+add_subdirectory(./mons_3d)
+add_subdirectory(./mons_gltf)
+add_subdirectory(./mons_exe)
+
diff --git a/compile_commands.json b/compile_commands.json
new file mode 120000
index 0000000..25eb4b2
--- /dev/null
+++ b/compile_commands.json
@@ -0,0 +1 @@
+build/compile_commands.json \ No newline at end of file
diff --git a/marble_bust/marble_bust_01.bin b/marble_bust/marble_bust_01.bin
new file mode 100644
index 0000000..a47aa0b
--- /dev/null
+++ b/marble_bust/marble_bust_01.bin
Binary files differ
diff --git a/marble_bust/marble_bust_01_4k.gltf b/marble_bust/marble_bust_01_4k.gltf
new file mode 100644
index 0000000..86ce5cf
--- /dev/null
+++ b/marble_bust/marble_bust_01_4k.gltf
@@ -0,0 +1,161 @@
+{
+ "asset": {
+ "generator": "Khronos glTF Blender I/O v1.6.16",
+ "version": "2.0"
+ },
+ "scene": 0,
+ "scenes": [
+ {
+ "name": "Scene",
+ "nodes": [
+ 0
+ ]
+ }
+ ],
+ "nodes": [
+ {
+ "mesh": 0,
+ "name": "marble_bust_01",
+ "translation": [
+ 0,
+ 0.028335653245449066,
+ 0
+ ]
+ }
+ ],
+ "materials": [
+ {
+ "doubleSided": true,
+ "name": "marble_bust_01",
+ "normalTexture": {
+ "index": 0
+ },
+ "pbrMetallicRoughness": {
+ "baseColorTexture": {
+ "index": 1
+ },
+ "metallicFactor": 0,
+ "metallicRoughnessTexture": {
+ "index": 2
+ }
+ }
+ }
+ ],
+ "meshes": [
+ {
+ "name": "marble_bust_01",
+ "primitives": [
+ {
+ "attributes": {
+ "POSITION": 0,
+ "NORMAL": 1,
+ "TEXCOORD_0": 2
+ },
+ "indices": 3,
+ "material": 0
+ }
+ ]
+ }
+ ],
+ "textures": [
+ {
+ "sampler": 0,
+ "source": 0
+ },
+ {
+ "sampler": 0,
+ "source": 1
+ },
+ {
+ "sampler": 0,
+ "source": 2
+ }
+ ],
+ "images": [
+ {
+ "mimeType": "image/qoi",
+ "name": "marble_bust_01_nor_gl",
+ "uri": "textures/marble_bust_01_nor_gl_4k.qoi"
+ },
+ {
+ "mimeType": "image/qoi",
+ "name": "marble_bust_01_diff",
+ "uri": "textures/marble_bust_01_diff_4k.qoi"
+ },
+ {
+ "mimeType": "image/qoi",
+ "name": "marble_bust_01_arm",
+ "uri": "textures/marble_bust_01_rough_4k.qoi"
+ }
+ ],
+ "accessors": [
+ {
+ "bufferView": 0,
+ "componentType": 5126,
+ "count": 9746,
+ "max": [
+ 0.14886942505836487,
+ 0.48668384552001953,
+ 0.1551172435283661
+ ],
+ "min": [
+ -0.12288019061088562,
+ -0.028259359300136566,
+ -0.1445964276790619
+ ],
+ "type": "VEC3"
+ },
+ {
+ "bufferView": 1,
+ "componentType": 5126,
+ "count": 9746,
+ "type": "VEC3"
+ },
+ {
+ "bufferView": 2,
+ "componentType": 5126,
+ "count": 9746,
+ "type": "VEC2"
+ },
+ {
+ "bufferView": 3,
+ "componentType": 5123,
+ "count": 52368,
+ "type": "SCALAR"
+ }
+ ],
+ "bufferViews": [
+ {
+ "buffer": 0,
+ "byteLength": 116952,
+ "byteOffset": 0
+ },
+ {
+ "buffer": 0,
+ "byteLength": 116952,
+ "byteOffset": 116952
+ },
+ {
+ "buffer": 0,
+ "byteLength": 77968,
+ "byteOffset": 233904
+ },
+ {
+ "buffer": 0,
+ "byteLength": 104736,
+ "byteOffset": 311872
+ }
+ ],
+ "samplers": [
+ {
+ "magFilter": 9729,
+ "minFilter": 9987
+ }
+ ],
+ "buffers": [
+ {
+ "byteLength": 416608,
+ "uri": "marble_bust_01.bin"
+ }
+ ]
+}
diff --git a/marble_bust/textures/marble_bust_01_diff_4k.qoi b/marble_bust/textures/marble_bust_01_diff_4k.qoi
new file mode 100644
index 0000000..4fc4e24
--- /dev/null
+++ b/marble_bust/textures/marble_bust_01_diff_4k.qoi
Binary files differ
diff --git a/marble_bust/textures/marble_bust_01_nor_gl_4k.qoi b/marble_bust/textures/marble_bust_01_nor_gl_4k.qoi
new file mode 100644
index 0000000..72015eb
--- /dev/null
+++ b/marble_bust/textures/marble_bust_01_nor_gl_4k.qoi
Binary files differ
diff --git a/marble_bust/textures/marble_bust_01_rough_4k.qoi b/marble_bust/textures/marble_bust_01_rough_4k.qoi
new file mode 100644
index 0000000..9edca51
--- /dev/null
+++ b/marble_bust/textures/marble_bust_01_rough_4k.qoi
Binary files differ
diff --git a/mons_3d/CMakeLists.txt b/mons_3d/CMakeLists.txt
new file mode 100644
index 0000000..a5583c6
--- /dev/null
+++ b/mons_3d/CMakeLists.txt
@@ -0,0 +1,41 @@
+cmake_minimum_required(VERSION 3.14)
+project(mons_3d LANGUAGES C)
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_EXPORT_COMPILE_COMMANDS true)
+set(CMAKE_BUILD_TYPE "Debug")
+
+add_library(mons_3d
+ SHARED
+ ./src/mesh.c
+ ./src/color.c
+ ./src/model.c
+ ./src/shader.c
+ ./src/texture.c
+ ./src/transform.c
+ ./src/projection.c
+ ./external/glad/src/gl.c
+ ./external/glad/src/glx.c
+ ./external/mikktspace/src/mikktspace.c
+)
+
+target_include_directories(mons_3d PUBLIC
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include"
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/external/glad/include"
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/external/mikktspace/include"
+ "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
+)
+target_compile_options(mons_3d PRIVATE -coverage)
+target_link_options(mons_3d PRIVATE -coverage)
+target_link_libraries(mons_3d PUBLIC mons_collections mons_math mons_image)
+
+include(CTest)
+
+function(TESTCASE NAME)
+ add_executable(test_${NAME} ./tests/${NAME}.c)
+ target_link_libraries(test_${NAME} PUBLIC mons_3d)
+ add_test(
+ NAME ${NAME}
+ COMMAND $<TARGET_FILE:test_${NAME}>
+ )
+endfunction()
+
diff --git a/mons_3d/external/glad/include/KHR/khrplatform.h b/mons_3d/external/glad/include/KHR/khrplatform.h
new file mode 100644
index 0000000..0164644
--- /dev/null
+++ b/mons_3d/external/glad/include/KHR/khrplatform.h
@@ -0,0 +1,311 @@
+#ifndef __khrplatform_h_
+#define __khrplatform_h_
+
+/*
+** Copyright (c) 2008-2018 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Khronos platform-specific types and definitions.
+ *
+ * The master copy of khrplatform.h is maintained in the Khronos EGL
+ * Registry repository at https://github.com/KhronosGroup/EGL-Registry
+ * The last semantic modification to khrplatform.h was at commit ID:
+ * 67a3e0864c2d75ea5287b9f3d2eb74a745936692
+ *
+ * Adopters may modify this file to suit their platform. Adopters are
+ * encouraged to submit platform specific modifications to the Khronos
+ * group so that they can be included in future versions of this file.
+ * Please submit changes by filing pull requests or issues on
+ * the EGL Registry repository linked above.
+ *
+ *
+ * See the Implementer's Guidelines for information about where this file
+ * should be located on your system and for more details of its use:
+ * http://www.khronos.org/registry/implementers_guide.pdf
+ *
+ * This file should be included as
+ * #include <KHR/khrplatform.h>
+ * by Khronos client API header files that use its types and defines.
+ *
+ * The types in khrplatform.h should only be used to define API-specific types.
+ *
+ * Types defined in khrplatform.h:
+ * khronos_int8_t signed 8 bit
+ * khronos_uint8_t unsigned 8 bit
+ * khronos_int16_t signed 16 bit
+ * khronos_uint16_t unsigned 16 bit
+ * khronos_int32_t signed 32 bit
+ * khronos_uint32_t unsigned 32 bit
+ * khronos_int64_t signed 64 bit
+ * khronos_uint64_t unsigned 64 bit
+ * khronos_intptr_t signed same number of bits as a pointer
+ * khronos_uintptr_t unsigned same number of bits as a pointer
+ * khronos_ssize_t signed size
+ * khronos_usize_t unsigned size
+ * khronos_float_t signed 32 bit floating point
+ * khronos_time_ns_t unsigned 64 bit time in nanoseconds
+ * khronos_utime_nanoseconds_t unsigned time interval or absolute time in
+ * nanoseconds
+ * khronos_stime_nanoseconds_t signed time interval in nanoseconds
+ * khronos_boolean_enum_t enumerated boolean type. This should
+ * only be used as a base type when a client API's boolean type is
+ * an enum. Client APIs which use an integer or other type for
+ * booleans cannot use this as the base type for their boolean.
+ *
+ * Tokens defined in khrplatform.h:
+ *
+ * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
+ *
+ * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
+ * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
+ *
+ * Calling convention macros defined in this file:
+ * KHRONOS_APICALL
+ * KHRONOS_APIENTRY
+ * KHRONOS_APIATTRIBUTES
+ *
+ * These may be used in function prototypes as:
+ *
+ * KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
+ * int arg1,
+ * int arg2) KHRONOS_APIATTRIBUTES;
+ */
+
+#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
+# define KHRONOS_STATIC 1
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APICALL
+ *-------------------------------------------------------------------------
+ * This precedes the return type of the function in the function prototype.
+ */
+#if defined(KHRONOS_STATIC)
+ /* If the preprocessor constant KHRONOS_STATIC is defined, make the
+ * header compatible with static linking. */
+# define KHRONOS_APICALL
+#elif defined(_WIN32)
+# define KHRONOS_APICALL __declspec(dllimport)
+#elif defined (__SYMBIAN32__)
+# define KHRONOS_APICALL IMPORT_C
+#elif defined(__ANDROID__)
+# define KHRONOS_APICALL __attribute__((visibility("default")))
+#else
+# define KHRONOS_APICALL
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIENTRY
+ *-------------------------------------------------------------------------
+ * This follows the return type of the function and precedes the function
+ * name in the function prototype.
+ */
+#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
+ /* Win32 but not WinCE */
+# define KHRONOS_APIENTRY __stdcall
+#else
+# define KHRONOS_APIENTRY
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIATTRIBUTES
+ *-------------------------------------------------------------------------
+ * This follows the closing parenthesis of the function prototype arguments.
+ */
+#if defined (__ARMCC_2__)
+#define KHRONOS_APIATTRIBUTES __softfp
+#else
+#define KHRONOS_APIATTRIBUTES
+#endif
+
+/*-------------------------------------------------------------------------
+ * basic type definitions
+ *-----------------------------------------------------------------------*/
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
+
+
+/*
+ * Using <stdint.h>
+ */
+#include <stdint.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+/*
+ * To support platform where unsigned long cannot be used interchangeably with
+ * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
+ * Ideally, we could just use (u)intptr_t everywhere, but this could result in
+ * ABI breakage if khronos_uintptr_t is changed from unsigned long to
+ * unsigned long long or similar (this results in different C++ name mangling).
+ * To avoid changes for existing platforms, we restrict usage of intptr_t to
+ * platforms where the size of a pointer is larger than the size of long.
+ */
+#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
+#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
+#define KHRONOS_USE_INTPTR_T
+#endif
+#endif
+
+#elif defined(__VMS ) || defined(__sgi)
+
+/*
+ * Using <inttypes.h>
+ */
+#include <inttypes.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
+
+/*
+ * Win32
+ */
+typedef __int32 khronos_int32_t;
+typedef unsigned __int32 khronos_uint32_t;
+typedef __int64 khronos_int64_t;
+typedef unsigned __int64 khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__sun__) || defined(__digital__)
+
+/*
+ * Sun or Digital
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#if defined(__arch64__) || defined(_LP64)
+typedef long int khronos_int64_t;
+typedef unsigned long int khronos_uint64_t;
+#else
+typedef long long int khronos_int64_t;
+typedef unsigned long long int khronos_uint64_t;
+#endif /* __arch64__ */
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif 0
+
+/*
+ * Hypothetical platform with no float or int64 support
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#define KHRONOS_SUPPORT_INT64 0
+#define KHRONOS_SUPPORT_FLOAT 0
+
+#else
+
+/*
+ * Generic fallback
+ */
+#include <stdint.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#endif
+
+
+/*
+ * Types that are (so far) the same on all platforms
+ */
+typedef signed char khronos_int8_t;
+typedef unsigned char khronos_uint8_t;
+typedef signed short int khronos_int16_t;
+typedef unsigned short int khronos_uint16_t;
+
+/*
+ * Types that differ between LLP64 and LP64 architectures - in LLP64,
+ * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
+ * to be the only LLP64 architecture in current use.
+ */
+#ifdef KHRONOS_USE_INTPTR_T
+typedef intptr_t khronos_intptr_t;
+typedef uintptr_t khronos_uintptr_t;
+#elif defined(_WIN64)
+typedef signed long long int khronos_intptr_t;
+typedef unsigned long long int khronos_uintptr_t;
+#else
+typedef signed long int khronos_intptr_t;
+typedef unsigned long int khronos_uintptr_t;
+#endif
+
+#if defined(_WIN64)
+typedef signed long long int khronos_ssize_t;
+typedef unsigned long long int khronos_usize_t;
+#else
+typedef signed long int khronos_ssize_t;
+typedef unsigned long int khronos_usize_t;
+#endif
+
+#if KHRONOS_SUPPORT_FLOAT
+/*
+ * Float type
+ */
+typedef float khronos_float_t;
+#endif
+
+#if KHRONOS_SUPPORT_INT64
+/* Time types
+ *
+ * These types can be used to represent a time interval in nanoseconds or
+ * an absolute Unadjusted System Time. Unadjusted System Time is the number
+ * of nanoseconds since some arbitrary system event (e.g. since the last
+ * time the system booted). The Unadjusted System Time is an unsigned
+ * 64 bit value that wraps back to 0 every 584 years. Time intervals
+ * may be either signed or unsigned.
+ */
+typedef khronos_uint64_t khronos_utime_nanoseconds_t;
+typedef khronos_int64_t khronos_stime_nanoseconds_t;
+#endif
+
+/*
+ * Dummy value used to pad enum types to 32 bits.
+ */
+#ifndef KHRONOS_MAX_ENUM
+#define KHRONOS_MAX_ENUM 0x7FFFFFFF
+#endif
+
+/*
+ * Enumerated boolean type
+ *
+ * Values other than zero should be considered to be true. Therefore
+ * comparisons should not be made against KHRONOS_TRUE.
+ */
+typedef enum {
+ KHRONOS_FALSE = 0,
+ KHRONOS_TRUE = 1,
+ KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
+} khronos_boolean_enum_t;
+
+#endif /* __khrplatform_h_ */
diff --git a/mons_3d/external/glad/include/glad/gl.h b/mons_3d/external/glad/include/glad/gl.h
new file mode 100644
index 0000000..3ca1223
--- /dev/null
+++ b/mons_3d/external/glad/include/glad/gl.h
@@ -0,0 +1,3644 @@
+/**
+ * Loader generated by glad 2.0.8 on Sat Feb 1 22:26:11 2025
+ *
+ * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
+ *
+ * Generator: C/C++
+ * Specification: gl
+ * Extensions: 0
+ *
+ * APIs:
+ * - gl:core=4.6
+ *
+ * Options:
+ * - ALIAS = False
+ * - DEBUG = False
+ * - HEADER_ONLY = False
+ * - LOADER = True
+ * - MX = False
+ * - ON_DEMAND = False
+ *
+ * Commandline:
+ * --api='gl:core=4.6' --extensions='' c --loader
+ *
+ * Online:
+ * http://glad.sh/#api=gl%3Acore%3D4.6&extensions=&generator=c&options=LOADER
+ *
+ */
+
+#ifndef GLAD_GL_H_
+#define GLAD_GL_H_
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wreserved-id-macro"
+#endif
+#ifdef __gl_h_
+ #error OpenGL (gl.h) header already included (API: gl), remove previous include!
+#endif
+#define __gl_h_ 1
+#ifdef __gl3_h_
+ #error OpenGL (gl3.h) header already included (API: gl), remove previous include!
+#endif
+#define __gl3_h_ 1
+#ifdef __glext_h_
+ #error OpenGL (glext.h) header already included (API: gl), remove previous include!
+#endif
+#define __glext_h_ 1
+#ifdef __gl3ext_h_
+ #error OpenGL (gl3ext.h) header already included (API: gl), remove previous include!
+#endif
+#define __gl3ext_h_ 1
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#define GLAD_GL
+#define GLAD_OPTION_GL_LOADER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef GLAD_PLATFORM_H_
+#define GLAD_PLATFORM_H_
+
+#ifndef GLAD_PLATFORM_WIN32
+ #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)
+ #define GLAD_PLATFORM_WIN32 1
+ #else
+ #define GLAD_PLATFORM_WIN32 0
+ #endif
+#endif
+
+#ifndef GLAD_PLATFORM_APPLE
+ #ifdef __APPLE__
+ #define GLAD_PLATFORM_APPLE 1
+ #else
+ #define GLAD_PLATFORM_APPLE 0
+ #endif
+#endif
+
+#ifndef GLAD_PLATFORM_EMSCRIPTEN
+ #ifdef __EMSCRIPTEN__
+ #define GLAD_PLATFORM_EMSCRIPTEN 1
+ #else
+ #define GLAD_PLATFORM_EMSCRIPTEN 0
+ #endif
+#endif
+
+#ifndef GLAD_PLATFORM_UWP
+ #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY)
+ #ifdef __has_include
+ #if __has_include(<winapifamily.h>)
+ #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1
+ #endif
+ #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_
+ #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1
+ #endif
+ #endif
+
+ #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY
+ #include <winapifamily.h>
+ #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
+ #define GLAD_PLATFORM_UWP 1
+ #endif
+ #endif
+
+ #ifndef GLAD_PLATFORM_UWP
+ #define GLAD_PLATFORM_UWP 0
+ #endif
+#endif
+
+#ifdef __GNUC__
+ #define GLAD_GNUC_EXTENSION __extension__
+#else
+ #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__)
+ #if defined(GLAD_API_CALL_EXPORT_BUILD)
+ #if defined(__GNUC__)
+ #define GLAD_API_CALL __attribute__ ((dllexport)) extern
+ #else
+ #define GLAD_API_CALL __declspec(dllexport) extern
+ #endif
+ #else
+ #if defined(__GNUC__)
+ #define GLAD_API_CALL __attribute__ ((dllimport)) extern
+ #else
+ #define GLAD_API_CALL __declspec(dllimport) extern
+ #endif
+ #endif
+ #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD)
+ #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern
+ #else
+ #define GLAD_API_CALL extern
+ #endif
+ #else
+ #define GLAD_API_CALL extern
+ #endif
+#endif
+
+#ifdef APIENTRY
+ #define GLAD_API_PTR APIENTRY
+#elif GLAD_PLATFORM_WIN32
+ #define GLAD_API_PTR __stdcall
+#else
+ #define GLAD_API_PTR
+#endif
+
+#ifndef GLAPI
+#define GLAPI GLAD_API_CALL
+#endif
+
+#ifndef GLAPIENTRY
+#define GLAPIENTRY GLAD_API_PTR
+#endif
+
+#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor)
+#define GLAD_VERSION_MAJOR(version) (version / 10000)
+#define GLAD_VERSION_MINOR(version) (version % 10000)
+
+#define GLAD_GENERATOR_VERSION "2.0.8"
+
+typedef void (*GLADapiproc)(void);
+
+typedef GLADapiproc (*GLADloadfunc)(const char *name);
+typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name);
+
+typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...);
+typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...);
+
+#endif /* GLAD_PLATFORM_H_ */
+
+#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_ACTIVE_PROGRAM 0x8259
+#define GL_ACTIVE_RESOURCES 0x92F5
+#define GL_ACTIVE_SUBROUTINES 0x8DE5
+#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48
+#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ACTIVE_VARIABLES 0x9305
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
+#define GL_ALL_SHADER_BITS 0xFFFFFFFF
+#define GL_ALPHA 0x1906
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_ALWAYS 0x0207
+#define GL_AND 0x1501
+#define GL_AND_INVERTED 0x1504
+#define GL_AND_REVERSE 0x1502
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ARRAY_SIZE 0x92FB
+#define GL_ARRAY_STRIDE 0x92FE
+#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
+#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6
+#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1
+#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4
+#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7
+#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3
+#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_AUTO_GENERATE_MIPMAP 0x8295
+#define GL_BACK 0x0405
+#define GL_BACK_LEFT 0x0402
+#define GL_BACK_RIGHT 0x0403
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_BGRA_INTEGER 0x8D9B
+#define GL_BGR_INTEGER 0x8D9A
+#define GL_BLEND 0x0BE2
+#define GL_BLEND_COLOR 0x8005
+#define GL_BLEND_DST 0x0BE0
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_BLEND_SRC 0x0BE1
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLOCK_INDEX 0x92FD
+#define GL_BLUE 0x1905
+#define GL_BLUE_INTEGER 0x8D96
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_BUFFER 0x82E0
+#define GL_BUFFER_ACCESS 0x88BB
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_BINDING 0x9302
+#define GL_BUFFER_DATA_SIZE 0x9303
+#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_STORAGE_FLAGS 0x8220
+#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
+#define GL_BUFFER_USAGE 0x8765
+#define GL_BUFFER_VARIABLE 0x92E5
+#define GL_BYTE 0x1400
+#define GL_CAVEAT_SUPPORT 0x82B8
+#define GL_CCW 0x0901
+#define GL_CLAMP_READ_COLOR 0x891C
+#define GL_CLAMP_TO_BORDER 0x812D
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_CLEAR 0x1500
+#define GL_CLEAR_BUFFER 0x82B4
+#define GL_CLEAR_TEXTURE 0x9365
+#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000
+#define GL_CLIENT_STORAGE_BIT 0x0200
+#define GL_CLIPPING_INPUT_PRIMITIVES 0x82F6
+#define GL_CLIPPING_OUTPUT_PRIMITIVES 0x82F7
+#define GL_CLIP_DEPTH_MODE 0x935D
+#define GL_CLIP_DISTANCE0 0x3000
+#define GL_CLIP_DISTANCE1 0x3001
+#define GL_CLIP_DISTANCE2 0x3002
+#define GL_CLIP_DISTANCE3 0x3003
+#define GL_CLIP_DISTANCE4 0x3004
+#define GL_CLIP_DISTANCE5 0x3005
+#define GL_CLIP_DISTANCE6 0x3006
+#define GL_CLIP_DISTANCE7 0x3007
+#define GL_CLIP_ORIGIN 0x935C
+#define GL_COLOR 0x1800
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_COLOR_ATTACHMENT16 0x8CF0
+#define GL_COLOR_ATTACHMENT17 0x8CF1
+#define GL_COLOR_ATTACHMENT18 0x8CF2
+#define GL_COLOR_ATTACHMENT19 0x8CF3
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT20 0x8CF4
+#define GL_COLOR_ATTACHMENT21 0x8CF5
+#define GL_COLOR_ATTACHMENT22 0x8CF6
+#define GL_COLOR_ATTACHMENT23 0x8CF7
+#define GL_COLOR_ATTACHMENT24 0x8CF8
+#define GL_COLOR_ATTACHMENT25 0x8CF9
+#define GL_COLOR_ATTACHMENT26 0x8CFA
+#define GL_COLOR_ATTACHMENT27 0x8CFB
+#define GL_COLOR_ATTACHMENT28 0x8CFC
+#define GL_COLOR_ATTACHMENT29 0x8CFD
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT30 0x8CFE
+#define GL_COLOR_ATTACHMENT31 0x8CFF
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_COMPONENTS 0x8283
+#define GL_COLOR_ENCODING 0x8296
+#define GL_COLOR_LOGIC_OP 0x0BF2
+#define GL_COLOR_RENDERABLE 0x8286
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_COMMAND_BARRIER_BIT 0x00000040
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_COMPATIBLE_SUBROUTINES 0x8E4B
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_RED 0x8225
+#define GL_COMPRESSED_RED_RGTC1 0x8DBB
+#define GL_COMPRESSED_RG 0x8226
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
+#define GL_COMPRESSED_RG_RGTC2 0x8DBD
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
+#define GL_COMPRESSED_SRGB 0x8C48
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_COMPUTE_SHADER 0x91B9
+#define GL_COMPUTE_SHADER_BIT 0x00000020
+#define GL_COMPUTE_SHADER_INVOCATIONS 0x82F5
+#define GL_COMPUTE_SUBROUTINE 0x92ED
+#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3
+#define GL_COMPUTE_TEXTURE 0x82A0
+#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001
+#define GL_CONTEXT_FLAG_NO_ERROR_BIT 0x00000008
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004
+#define GL_CONTEXT_LOST 0x0507
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB
+#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC
+#define GL_COPY 0x1503
+#define GL_COPY_INVERTED 0x150C
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_READ_BUFFER_BINDING 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
+#define GL_CULL_FACE 0x0B44
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_CURRENT_QUERY 0x8865
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_CW 0x0900
+#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
+#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
+#define GL_DEBUG_LOGGED_MESSAGES 0x9145
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
+#define GL_DEBUG_OUTPUT 0x92E0
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_DEBUG_SEVERITY_HIGH 0x9146
+#define GL_DEBUG_SEVERITY_LOW 0x9148
+#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
+#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
+#define GL_DEBUG_SOURCE_API 0x8246
+#define GL_DEBUG_SOURCE_APPLICATION 0x824A
+#define GL_DEBUG_SOURCE_OTHER 0x824B
+#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_TYPE_MARKER 0x8268
+#define GL_DEBUG_TYPE_OTHER 0x8251
+#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
+#define GL_DEBUG_TYPE_POP_GROUP 0x826A
+#define GL_DEBUG_TYPE_PORTABILITY 0x824F
+#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
+#define GL_DECR 0x1E03
+#define GL_DECR_WRAP 0x8508
+#define GL_DELETE_STATUS 0x8B80
+#define GL_DEPTH 0x1801
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_DEPTH_CLAMP 0x864F
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_DEPTH_COMPONENT32 0x81A7
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH_COMPONENTS 0x8284
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_RENDERABLE 0x8287
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA
+#define GL_DEPTH_TEST 0x0B71
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
+#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
+#define GL_DITHER 0x0BD0
+#define GL_DONT_CARE 0x1100
+#define GL_DOUBLE 0x140A
+#define GL_DOUBLEBUFFER 0x0C32
+#define GL_DOUBLE_MAT2 0x8F46
+#define GL_DOUBLE_MAT2x3 0x8F49
+#define GL_DOUBLE_MAT2x4 0x8F4A
+#define GL_DOUBLE_MAT3 0x8F47
+#define GL_DOUBLE_MAT3x2 0x8F4B
+#define GL_DOUBLE_MAT3x4 0x8F4C
+#define GL_DOUBLE_MAT4 0x8F48
+#define GL_DOUBLE_MAT4x2 0x8F4D
+#define GL_DOUBLE_MAT4x3 0x8F4E
+#define GL_DOUBLE_VEC2 0x8FFC
+#define GL_DOUBLE_VEC3 0x8FFD
+#define GL_DOUBLE_VEC4 0x8FFE
+#define GL_DRAW_BUFFER 0x0C01
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+#define GL_DST_ALPHA 0x0304
+#define GL_DST_COLOR 0x0306
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_STORAGE_BIT 0x0100
+#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_EQUAL 0x0202
+#define GL_EQUIV 0x1509
+#define GL_EXTENSIONS 0x1F03
+#define GL_FALSE 0
+#define GL_FASTEST 0x1101
+#define GL_FILL 0x1B02
+#define GL_FILTER 0x829A
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_FIXED 0x140C
+#define GL_FIXED_ONLY 0x891D
+#define GL_FLOAT 0x1406
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_FRACTIONAL_EVEN 0x8E7C
+#define GL_FRACTIONAL_ODD 0x8E7B
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_FRAGMENT_SHADER_INVOCATIONS 0x82F4
+#define GL_FRAGMENT_SUBROUTINE 0x92EC
+#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2
+#define GL_FRAGMENT_TEXTURE 0x829F
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_FRAMEBUFFER_BLEND 0x828B
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314
+#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312
+#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313
+#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_RENDERABLE 0x8289
+#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_FRONT 0x0404
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_FRONT_FACE 0x0B46
+#define GL_FRONT_LEFT 0x0400
+#define GL_FRONT_RIGHT 0x0401
+#define GL_FULL_SUPPORT 0x82B7
+#define GL_FUNC_ADD 0x8006
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_GEOMETRY_SHADER_BIT 0x00000004
+#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED 0x82F3
+#define GL_GEOMETRY_SUBROUTINE 0x92EB
+#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1
+#define GL_GEOMETRY_TEXTURE 0x829E
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_GEQUAL 0x0206
+#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291
+#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292
+#define GL_GREATER 0x0204
+#define GL_GREEN 0x1904
+#define GL_GREEN_INTEGER 0x8D95
+#define GL_GUILTY_CONTEXT_RESET 0x8253
+#define GL_HALF_FLOAT 0x140B
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_HIGH_INT 0x8DF5
+#define GL_IMAGE_1D 0x904C
+#define GL_IMAGE_1D_ARRAY 0x9052
+#define GL_IMAGE_2D 0x904D
+#define GL_IMAGE_2D_ARRAY 0x9053
+#define GL_IMAGE_2D_MULTISAMPLE 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056
+#define GL_IMAGE_2D_RECT 0x904F
+#define GL_IMAGE_3D 0x904E
+#define GL_IMAGE_BINDING_ACCESS 0x8F3E
+#define GL_IMAGE_BINDING_FORMAT 0x906E
+#define GL_IMAGE_BINDING_LAYER 0x8F3D
+#define GL_IMAGE_BINDING_LAYERED 0x8F3C
+#define GL_IMAGE_BINDING_LEVEL 0x8F3B
+#define GL_IMAGE_BINDING_NAME 0x8F3A
+#define GL_IMAGE_BUFFER 0x9051
+#define GL_IMAGE_CLASS_10_10_10_2 0x82C3
+#define GL_IMAGE_CLASS_11_11_10 0x82C2
+#define GL_IMAGE_CLASS_1_X_16 0x82BE
+#define GL_IMAGE_CLASS_1_X_32 0x82BB
+#define GL_IMAGE_CLASS_1_X_8 0x82C1
+#define GL_IMAGE_CLASS_2_X_16 0x82BD
+#define GL_IMAGE_CLASS_2_X_32 0x82BA
+#define GL_IMAGE_CLASS_2_X_8 0x82C0
+#define GL_IMAGE_CLASS_4_X_16 0x82BC
+#define GL_IMAGE_CLASS_4_X_32 0x82B9
+#define GL_IMAGE_CLASS_4_X_8 0x82BF
+#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8
+#define GL_IMAGE_CUBE 0x9050
+#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
+#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
+#define GL_IMAGE_PIXEL_FORMAT 0x82A9
+#define GL_IMAGE_PIXEL_TYPE 0x82AA
+#define GL_IMAGE_TEXEL_SIZE 0x82A7
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_INCR 0x1E02
+#define GL_INCR_WRAP 0x8507
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_INNOCENT_CONTEXT_RESET 0x8254
+#define GL_INT 0x1404
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274
+#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B
+#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273
+#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A
+#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275
+#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C
+#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272
+#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279
+#define GL_INTERNALFORMAT_PREFERRED 0x8270
+#define GL_INTERNALFORMAT_RED_SIZE 0x8271
+#define GL_INTERNALFORMAT_RED_TYPE 0x8278
+#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277
+#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276
+#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D
+#define GL_INTERNALFORMAT_SUPPORTED 0x826F
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#define GL_INT_IMAGE_1D 0x9057
+#define GL_INT_IMAGE_1D_ARRAY 0x905D
+#define GL_INT_IMAGE_2D 0x9058
+#define GL_INT_IMAGE_2D_ARRAY 0x905E
+#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
+#define GL_INT_IMAGE_2D_RECT 0x905A
+#define GL_INT_IMAGE_3D 0x9059
+#define GL_INT_IMAGE_BUFFER 0x905C
+#define GL_INT_IMAGE_CUBE 0x905B
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
+#define GL_INT_SAMPLER_1D 0x8DC9
+#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_INT_SAMPLER_2D_RECT 0x8DCD
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_BUFFER 0x8DD0
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#define GL_INVALID_INDEX 0xFFFFFFFF
+#define GL_INVALID_OPERATION 0x0502
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVERT 0x150A
+#define GL_ISOLINES 0x8E7A
+#define GL_IS_PER_PATCH 0x92E7
+#define GL_IS_ROW_MAJOR 0x9300
+#define GL_KEEP 0x1E00
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_LAYER_PROVOKING_VERTEX 0x825E
+#define GL_LEFT 0x0406
+#define GL_LEQUAL 0x0203
+#define GL_LESS 0x0201
+#define GL_LINE 0x1B01
+#define GL_LINEAR 0x2601
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_LINES 0x0001
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_SMOOTH 0x0B20
+#define GL_LINE_SMOOTH_HINT 0x0C52
+#define GL_LINE_STRIP 0x0003
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_LINE_WIDTH 0x0B21
+#define GL_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_LINE_WIDTH_RANGE 0x0B22
+#define GL_LINK_STATUS 0x8B82
+#define GL_LOCATION 0x930E
+#define GL_LOCATION_COMPONENT 0x934A
+#define GL_LOCATION_INDEX 0x930F
+#define GL_LOGIC_OP_MODE 0x0BF0
+#define GL_LOSE_CONTEXT_ON_RESET 0x8252
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_LOW_INT 0x8DF3
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MANUAL_GENERATE_MIPMAP 0x8294
+#define GL_MAP_COHERENT_BIT 0x0080
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_PERSISTENT_BIT 0x0040
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MATRIX_STRIDE 0x92FF
+#define GL_MAX 0x8008
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8
+#define GL_MAX_CLIP_DISTANCES 0x0D32
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7
+#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1
+#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA
+#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
+#define GL_MAX_COMBINED_DIMENSIONS 0x8282
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
+#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
+#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39
+#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
+#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
+#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
+#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB
+#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
+#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
+#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
+#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
+#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
+#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB
+#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_MAX_CULL_DISTANCES 0x82F9
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
+#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
+#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
+#define GL_MAX_DEPTH 0x8280
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0
+#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
+#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317
+#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
+#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_HEIGHT 0x827F
+#define GL_MAX_IMAGE_SAMPLES 0x906D
+#define GL_MAX_IMAGE_UNITS 0x8F38
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+#define GL_MAX_LABEL_LENGTH 0x82E8
+#define GL_MAX_LAYERS 0x8281
+#define GL_MAX_NAME_LENGTH 0x92F6
+#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
+#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8
+#define GL_MAX_PATCH_VERTICES 0x8E7D
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_MAX_SAMPLES 0x8D57
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
+#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
+#define GL_MAX_SUBROUTINES 0x8DE7
+#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define GL_MAX_TESS_GEN_LEVEL 0x8E7E
+#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84
+#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_LOCATIONS 0x826E
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2
+#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA
+#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9
+#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5
+#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6
+#define GL_MAX_VERTEX_STREAMS 0x8E71
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VIEWPORTS 0x825B
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_MAX_WIDTH 0x827E
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_MIN 0x8007
+#define GL_MINOR_VERSION 0x821C
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#define GL_MIPMAP 0x8293
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_MIRROR_CLAMP_TO_EDGE 0x8743
+#define GL_MULTISAMPLE 0x809D
+#define GL_NAME_LENGTH 0x92F9
+#define GL_NAND 0x150E
+#define GL_NEAREST 0x2600
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_NEGATIVE_ONE_TO_ONE 0x935E
+#define GL_NEVER 0x0200
+#define GL_NICEST 0x1102
+#define GL_NONE 0
+#define GL_NOOP 0x1505
+#define GL_NOR 0x1508
+#define GL_NOTEQUAL 0x0205
+#define GL_NO_ERROR 0
+#define GL_NO_RESET_NOTIFICATION 0x8261
+#define GL_NUM_ACTIVE_VARIABLES 0x9304
+#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9
+#define GL_NUM_SPIR_V_EXTENSIONS 0x9554
+#define GL_OBJECT_TYPE 0x9112
+#define GL_OFFSET 0x92FC
+#define GL_ONE 1
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB
+#define GL_ONE_MINUS_SRC1_COLOR 0x88FA
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_OR 0x1507
+#define GL_OR_INVERTED 0x150D
+#define GL_OR_REVERSE 0x150B
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D
+#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C
+#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E
+#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_PACK_LSB_FIRST 0x0D01
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SWAP_BYTES 0x0D00
+#define GL_PARAMETER_BUFFER 0x80EE
+#define GL_PARAMETER_BUFFER_BINDING 0x80EF
+#define GL_PATCHES 0x000E
+#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
+#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74
+#define GL_PATCH_VERTICES 0x8E72
+#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_POINT 0x1B00
+#define GL_POINTS 0x0000
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_POINT_SIZE 0x0B11
+#define GL_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_POINT_SIZE_RANGE 0x0B12
+#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define GL_POLYGON_MODE 0x0B40
+#define GL_POLYGON_OFFSET_CLAMP 0x8E1B
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_POLYGON_OFFSET_LINE 0x2A02
+#define GL_POLYGON_OFFSET_POINT 0x2A01
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_SMOOTH 0x0B41
+#define GL_POLYGON_SMOOTH_HINT 0x0C53
+#define GL_PRIMITIVES_GENERATED 0x8C87
+#define GL_PRIMITIVES_SUBMITTED 0x82EF
+#define GL_PRIMITIVE_RESTART 0x8F9D
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221
+#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E
+#define GL_PROGRAM 0x82E2
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_INPUT 0x92E3
+#define GL_PROGRAM_OUTPUT 0x92E4
+#define GL_PROGRAM_PIPELINE 0x82E4
+#define GL_PROGRAM_PIPELINE_BINDING 0x825A
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#define GL_PROGRAM_SEPARABLE 0x8258
+#define GL_PROVOKING_VERTEX 0x8E4F
+#define GL_PROXY_TEXTURE_1D 0x8063
+#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19
+#define GL_PROXY_TEXTURE_2D 0x8064
+#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
+#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#define GL_QUADS 0x0007
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_QUERY 0x82E3
+#define GL_QUERY_BUFFER 0x9192
+#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000
+#define GL_QUERY_BUFFER_BINDING 0x9193
+#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16
+#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A
+#define GL_QUERY_BY_REGION_WAIT 0x8E15
+#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19
+#define GL_QUERY_COUNTER_BITS 0x8864
+#define GL_QUERY_NO_WAIT 0x8E14
+#define GL_QUERY_NO_WAIT_INVERTED 0x8E18
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_QUERY_RESULT_NO_WAIT 0x9194
+#define GL_QUERY_TARGET 0x82EA
+#define GL_QUERY_WAIT 0x8E13
+#define GL_QUERY_WAIT_INVERTED 0x8E17
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_R16 0x822A
+#define GL_R16F 0x822D
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R16_SNORM 0x8F98
+#define GL_R32F 0x822E
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_R3_G3_B2 0x2A10
+#define GL_R8 0x8229
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R8_SNORM 0x8F94
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_READ_BUFFER 0x0C02
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_READ_ONLY 0x88B8
+#define GL_READ_PIXELS 0x828C
+#define GL_READ_PIXELS_FORMAT 0x828D
+#define GL_READ_PIXELS_TYPE 0x828E
+#define GL_READ_WRITE 0x88BA
+#define GL_RED 0x1903
+#define GL_RED_INTEGER 0x8D94
+#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B
+#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A
+#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308
+#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERER 0x1F01
+#define GL_REPEAT 0x2901
+#define GL_REPLACE 0x1E01
+#define GL_RESET_NOTIFICATION_STRATEGY 0x8256
+#define GL_RG 0x8227
+#define GL_RG16 0x822C
+#define GL_RG16F 0x822F
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG16_SNORM 0x8F99
+#define GL_RG32F 0x8230
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#define GL_RG8 0x822B
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB 0x1907
+#define GL_RGB10 0x8052
+#define GL_RGB10_A2 0x8059
+#define GL_RGB10_A2UI 0x906F
+#define GL_RGB12 0x8053
+#define GL_RGB16 0x8054
+#define GL_RGB16F 0x881B
+#define GL_RGB16I 0x8D89
+#define GL_RGB16UI 0x8D77
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGB32F 0x8815
+#define GL_RGB32I 0x8D83
+#define GL_RGB32UI 0x8D71
+#define GL_RGB4 0x804F
+#define GL_RGB5 0x8050
+#define GL_RGB565 0x8D62
+#define GL_RGB5_A1 0x8057
+#define GL_RGB8 0x8051
+#define GL_RGB8I 0x8D8F
+#define GL_RGB8UI 0x8D7D
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGB9_E5 0x8C3D
+#define GL_RGBA 0x1908
+#define GL_RGBA12 0x805A
+#define GL_RGBA16 0x805B
+#define GL_RGBA16F 0x881A
+#define GL_RGBA16I 0x8D88
+#define GL_RGBA16UI 0x8D76
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_RGBA2 0x8055
+#define GL_RGBA32F 0x8814
+#define GL_RGBA32I 0x8D82
+#define GL_RGBA32UI 0x8D70
+#define GL_RGBA4 0x8056
+#define GL_RGBA8 0x8058
+#define GL_RGBA8I 0x8D8E
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RG_INTEGER 0x8228
+#define GL_RIGHT 0x0407
+#define GL_SAMPLER 0x82E6
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_1D_ARRAY 0x8DC0
+#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
+#define GL_SAMPLER_1D_SHADOW 0x8B61
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_SAMPLER_2D_RECT 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_BINDING 0x8919
+#define GL_SAMPLER_BUFFER 0x8DC2
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLES_PASSED 0x8914
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SAMPLE_SHADING 0x8C36
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_SET 0x150F
+#define GL_SHADER 0x82E1
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_SHADER_BINARY_FORMAT_SPIR_V 0x9551
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#define GL_SHADER_IMAGE_ATOMIC 0x82A6
+#define GL_SHADER_IMAGE_LOAD 0x82A4
+#define GL_SHADER_IMAGE_STORE 0x82A5
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
+#define GL_SHADER_STORAGE_BLOCK 0x92E6
+#define GL_SHADER_STORAGE_BUFFER 0x90D2
+#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3
+#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
+#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5
+#define GL_SHADER_STORAGE_BUFFER_START 0x90D4
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_SHORT 0x1402
+#define GL_SIGNALED 0x9119
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_SPIR_V_BINARY 0x9552
+#define GL_SPIR_V_EXTENSIONS 0x9553
+#define GL_SRC1_ALPHA 0x8589
+#define GL_SRC1_COLOR 0x88F9
+#define GL_SRC_ALPHA 0x0302
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_SRC_COLOR 0x0300
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_SRGB_ALPHA 0x8C42
+#define GL_SRGB_READ 0x8297
+#define GL_SRGB_WRITE 0x8298
+#define GL_STACK_OVERFLOW 0x0503
+#define GL_STACK_UNDERFLOW 0x0504
+#define GL_STATIC_COPY 0x88E6
+#define GL_STATIC_DRAW 0x88E4
+#define GL_STATIC_READ 0x88E5
+#define GL_STENCIL 0x1802
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_COMPONENTS 0x8285
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_INDEX 0x1901
+#define GL_STENCIL_INDEX1 0x8D46
+#define GL_STENCIL_INDEX16 0x8D49
+#define GL_STENCIL_INDEX4 0x8D47
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_RENDERABLE 0x8288
+#define GL_STENCIL_TEST 0x0B90
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STEREO 0x0C33
+#define GL_STREAM_COPY 0x88E2
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STREAM_READ 0x88E1
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_SYNC_STATUS 0x9114
+#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75
+#define GL_TESS_CONTROL_SHADER 0x8E88
+#define GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#define GL_TESS_CONTROL_SHADER_PATCHES 0x82F1
+#define GL_TESS_CONTROL_SUBROUTINE 0x92E9
+#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF
+#define GL_TESS_CONTROL_TEXTURE 0x829C
+#define GL_TESS_EVALUATION_SHADER 0x8E87
+#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#define GL_TESS_EVALUATION_SHADER_INVOCATIONS 0x82F2
+#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA
+#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0
+#define GL_TESS_EVALUATION_TEXTURE 0x829D
+#define GL_TESS_GEN_MODE 0x8E76
+#define GL_TESS_GEN_POINT_MODE 0x8E79
+#define GL_TESS_GEN_SPACING 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER 0x8E78
+#define GL_TEXTURE 0x1702
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE_1D 0x0DE0
+#define GL_TEXTURE_1D_ARRAY 0x8C18
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_ALPHA_SIZE 0x805F
+#define GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_BINDING_1D 0x8068
+#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#define GL_TEXTURE_BLUE_SIZE 0x805E
+#define GL_TEXTURE_BLUE_TYPE 0x8C12
+#define GL_TEXTURE_BORDER_COLOR 0x1004
+#define GL_TEXTURE_BUFFER 0x8C2A
+#define GL_TEXTURE_BUFFER_BINDING 0x8C2A
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_BUFFER_OFFSET 0x919D
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F
+#define GL_TEXTURE_BUFFER_SIZE 0x919E
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2
+#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3
+#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_TEXTURE_GATHER 0x82A2
+#define GL_TEXTURE_GATHER_SHADOW 0x82A3
+#define GL_TEXTURE_GREEN_SIZE 0x805D
+#define GL_TEXTURE_GREEN_TYPE 0x8C11
+#define GL_TEXTURE_HEIGHT 0x1001
+#define GL_TEXTURE_IMAGE_FORMAT 0x828F
+#define GL_TEXTURE_IMAGE_TYPE 0x8290
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
+#define GL_TEXTURE_LOD_BIAS 0x8501
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#define GL_TEXTURE_RED_SIZE 0x805C
+#define GL_TEXTURE_RED_TYPE 0x8C10
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TEXTURE_SHADOW 0x82A1
+#define GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#define GL_TEXTURE_TARGET 0x1006
+#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
+#define GL_TEXTURE_VIEW 0x82B5
+#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD
+#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE
+#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC
+#define GL_TEXTURE_WIDTH 0x1000
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF
+#define GL_TIMESTAMP 0x8E28
+#define GL_TIME_ELAPSED 0x88BF
+#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C
+#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C
+#define GL_TRANSFORM_FEEDBACK_OVERFLOW 0x82EC
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED
+#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_TRUE 1
+#define GL_TYPE 0x92FA
+#define GL_UNDEFINED_VERTEX 0x8260
+#define GL_UNIFORM 0x92E1
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA
+#define GL_UNIFORM_BARRIER_BIT 0x00000004
+#define GL_UNIFORM_BLOCK 0x92E2
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNKNOWN_CONTEXT_RESET 0x8255
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129
+#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128
+#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A
+#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_UNPACK_LSB_FIRST 0x0CF1
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SWAP_BYTES 0x0CF0
+#define GL_UNSIGNALED 0x9118
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_INT 0x1405
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#define GL_UNSIGNED_INT_IMAGE_1D 0x9062
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_3D 0x9064
+#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
+#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
+#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_VENDOR 0x1F00
+#define GL_VERSION 0x1F02
+#define GL_VERTEX_ARRAY 0x8074
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_ATTRIB_BINDING 0x82D4
+#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
+#define GL_VERTEX_BINDING_BUFFER 0x8F4F
+#define GL_VERTEX_BINDING_DIVISOR 0x82D6
+#define GL_VERTEX_BINDING_OFFSET 0x82D7
+#define GL_VERTEX_BINDING_STRIDE 0x82D8
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#define GL_VERTEX_SHADER_INVOCATIONS 0x82F0
+#define GL_VERTEX_SUBROUTINE 0x92E8
+#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE
+#define GL_VERTEX_TEXTURE 0x829B
+#define GL_VERTICES_SUBMITTED 0x82EE
+#define GL_VIEWPORT 0x0BA2
+#define GL_VIEWPORT_BOUNDS_RANGE 0x825D
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F
+#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C
+#define GL_VIEW_CLASS_128_BITS 0x82C4
+#define GL_VIEW_CLASS_16_BITS 0x82CA
+#define GL_VIEW_CLASS_24_BITS 0x82C9
+#define GL_VIEW_CLASS_32_BITS 0x82C8
+#define GL_VIEW_CLASS_48_BITS 0x82C7
+#define GL_VIEW_CLASS_64_BITS 0x82C6
+#define GL_VIEW_CLASS_8_BITS 0x82CB
+#define GL_VIEW_CLASS_96_BITS 0x82C5
+#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3
+#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2
+#define GL_VIEW_CLASS_RGTC1_RED 0x82D0
+#define GL_VIEW_CLASS_RGTC2_RG 0x82D1
+#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC
+#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD
+#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE
+#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF
+#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6
+#define GL_WAIT_FAILED 0x911D
+#define GL_WRITE_ONLY 0x88B9
+#define GL_XOR 0x1506
+#define GL_ZERO 0
+#define GL_ZERO_TO_ONE 0x935F
+
+
+#include <KHR/khrplatform.h>
+typedef unsigned int GLenum;
+typedef unsigned char GLboolean;
+typedef unsigned int GLbitfield;
+typedef void GLvoid;
+typedef khronos_int8_t GLbyte;
+typedef khronos_uint8_t GLubyte;
+typedef khronos_int16_t GLshort;
+typedef khronos_uint16_t GLushort;
+typedef int GLint;
+typedef unsigned int GLuint;
+typedef khronos_int32_t GLclampx;
+typedef int GLsizei;
+typedef khronos_float_t GLfloat;
+typedef khronos_float_t GLclampf;
+typedef double GLdouble;
+typedef double GLclampd;
+typedef void *GLeglClientBufferEXT;
+typedef void *GLeglImageOES;
+typedef char GLchar;
+typedef char GLcharARB;
+#ifdef __APPLE__
+typedef void *GLhandleARB;
+#else
+typedef unsigned int GLhandleARB;
+#endif
+typedef khronos_uint16_t GLhalf;
+typedef khronos_uint16_t GLhalfARB;
+typedef khronos_int32_t GLfixed;
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
+typedef khronos_intptr_t GLintptr;
+#else
+typedef khronos_intptr_t GLintptr;
+#endif
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
+typedef khronos_intptr_t GLintptrARB;
+#else
+typedef khronos_intptr_t GLintptrARB;
+#endif
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
+typedef khronos_ssize_t GLsizeiptr;
+#else
+typedef khronos_ssize_t GLsizeiptr;
+#endif
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
+typedef khronos_ssize_t GLsizeiptrARB;
+#else
+typedef khronos_ssize_t GLsizeiptrARB;
+#endif
+typedef khronos_int64_t GLint64;
+typedef khronos_int64_t GLint64EXT;
+typedef khronos_uint64_t GLuint64;
+typedef khronos_uint64_t GLuint64EXT;
+typedef struct __GLsync *GLsync;
+struct _cl_context;
+struct _cl_event;
+typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
+typedef unsigned short GLhalfNV;
+typedef GLintptr GLvdpauSurfaceNV;
+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;
+#define GL_VERSION_4_0 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_0;
+#define GL_VERSION_4_1 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_1;
+#define GL_VERSION_4_2 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_2;
+#define GL_VERSION_4_3 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_3;
+#define GL_VERSION_4_4 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_4;
+#define GL_VERSION_4_5 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_5;
+#define GL_VERSION_4_6 1
+GLAD_API_CALL int GLAD_GL_VERSION_4_6;
+
+
+typedef void (GLAD_API_PTR *PFNGLACTIVESHADERPROGRAMPROC)(GLuint pipeline, GLuint program);
+typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture);
+typedef void (GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader);
+typedef void (GLAD_API_PTR *PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLBEGINQUERYPROC)(GLenum target, GLuint id);
+typedef void (GLAD_API_PTR *PFNGLBEGINQUERYINDEXEDPROC)(GLenum target, GLuint index, GLuint id);
+typedef void (GLAD_API_PTR *PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode);
+typedef void (GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAD_API_PTR *PFNGLBINDBUFFERSBASEPROC)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers);
+typedef void (GLAD_API_PTR *PFNGLBINDBUFFERSRANGEPROC)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizeiptr * sizes);
+typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONPROC)(GLuint program, GLuint color, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer);
+typedef void (GLAD_API_PTR *PFNGLBINDIMAGETEXTUREPROC)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+typedef void (GLAD_API_PTR *PFNGLBINDIMAGETEXTURESPROC)(GLuint first, GLsizei count, const GLuint * textures);
+typedef void (GLAD_API_PTR *PFNGLBINDPROGRAMPIPELINEPROC)(GLuint pipeline);
+typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer);
+typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler);
+typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERSPROC)(GLuint first, GLsizei count, const GLuint * samplers);
+typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture);
+typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREUNITPROC)(GLuint unit, GLuint texture);
+typedef void (GLAD_API_PTR *PFNGLBINDTEXTURESPROC)(GLuint first, GLsizei count, const GLuint * textures);
+typedef void (GLAD_API_PTR *PFNGLBINDTRANSFORMFEEDBACKPROC)(GLenum target, GLuint id);
+typedef void (GLAD_API_PTR *PFNGLBINDVERTEXARRAYPROC)(GLuint array);
+typedef void (GLAD_API_PTR *PFNGLBINDVERTEXBUFFERPROC)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+typedef void (GLAD_API_PTR *PFNGLBINDVERTEXBUFFERSPROC)(GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides);
+typedef void (GLAD_API_PTR *PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONPROC)(GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEIPROC)(GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONIPROC)(GLuint buf, GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor);
+typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEIPROC)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GLAD_API_PTR *PFNGLBLENDFUNCIPROC)(GLuint buf, GLenum src, GLenum dst);
+typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (GLAD_API_PTR *PFNGLBLITNAMEDFRAMEBUFFERPROC)(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (GLAD_API_PTR *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void * data, GLenum usage);
+typedef void (GLAD_API_PTR *PFNGLBUFFERSTORAGEPROC)(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags);
+typedef void (GLAD_API_PTR *PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void * data);
+typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target);
+typedef GLenum (GLAD_API_PTR *PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)(GLuint framebuffer, GLenum target);
+typedef void (GLAD_API_PTR *PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp);
+typedef void (GLAD_API_PTR *PFNGLCLEARPROC)(GLbitfield mask);
+typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERDATAPROC)(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERSUBDATAPROC)(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHPROC)(GLdouble depth);
+typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHFPROC)(GLfloat d);
+typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERDATAPROC)(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLCLEARSTENCILPROC)(GLint s);
+typedef void (GLAD_API_PTR *PFNGLCLEARTEXIMAGEPROC)(GLuint texture, GLint level, GLenum format, GLenum type, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCLEARTEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * data);
+typedef GLenum (GLAD_API_PTR *PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GLAD_API_PTR *PFNGLCLIPCONTROLPROC)(GLenum origin, GLenum depth);
+typedef void (GLAD_API_PTR *PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+typedef void (GLAD_API_PTR *PFNGLCOLORMASKIPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERPROC)(GLuint shader);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data);
+typedef void (GLAD_API_PTR *PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (GLAD_API_PTR *PFNGLCOPYIMAGESUBDATAPROC)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+typedef void (GLAD_API_PTR *PFNGLCOPYNAMEDBUFFERSUBDATAPROC)(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLCREATEBUFFERSPROC)(GLsizei n, GLuint * buffers);
+typedef void (GLAD_API_PTR *PFNGLCREATEFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers);
+typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLCREATEPROGRAMPIPELINESPROC)(GLsizei n, GLuint * pipelines);
+typedef void (GLAD_API_PTR *PFNGLCREATEQUERIESPROC)(GLenum target, GLsizei n, GLuint * ids);
+typedef void (GLAD_API_PTR *PFNGLCREATERENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers);
+typedef void (GLAD_API_PTR *PFNGLCREATESAMPLERSPROC)(GLsizei n, GLuint * samplers);
+typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type);
+typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROGRAMVPROC)(GLenum type, GLsizei count, const GLchar *const* strings);
+typedef void (GLAD_API_PTR *PFNGLCREATETEXTURESPROC)(GLenum target, GLsizei n, GLuint * textures);
+typedef void (GLAD_API_PTR *PFNGLCREATETRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint * ids);
+typedef void (GLAD_API_PTR *PFNGLCREATEVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays);
+typedef void (GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECALLBACKPROC)(GLDEBUGPROC callback, const void * userParam);
+typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECONTROLPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled);
+typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGEINSERTPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf);
+typedef void (GLAD_API_PTR *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint * buffers);
+typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint * framebuffers);
+typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPROC)(GLuint program);
+typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPIPELINESPROC)(GLsizei n, const GLuint * pipelines);
+typedef void (GLAD_API_PTR *PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint * ids);
+typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint * renderbuffers);
+typedef void (GLAD_API_PTR *PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint * samplers);
+typedef void (GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader);
+typedef void (GLAD_API_PTR *PFNGLDELETESYNCPROC)(GLsync sync);
+typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint * textures);
+typedef void (GLAD_API_PTR *PFNGLDELETETRANSFORMFEEDBACKSPROC)(GLsizei n, const GLuint * ids);
+typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint * arrays);
+typedef void (GLAD_API_PTR *PFNGLDEPTHFUNCPROC)(GLenum func);
+typedef void (GLAD_API_PTR *PFNGLDEPTHMASKPROC)(GLboolean flag);
+typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEPROC)(GLdouble n, GLdouble f);
+typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEARRAYVPROC)(GLuint first, GLsizei count, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEINDEXEDPROC)(GLuint index, GLdouble n, GLdouble f);
+typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f);
+typedef void (GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader);
+typedef void (GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap);
+typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXARRAYATTRIBPROC)(GLuint vaobj, GLuint index);
+typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index);
+typedef void (GLAD_API_PTR *PFNGLDISABLEIPROC)(GLenum target, GLuint index);
+typedef void (GLAD_API_PTR *PFNGLDISPATCHCOMPUTEPROC)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+typedef void (GLAD_API_PTR *PFNGLDISPATCHCOMPUTEINDIRECTPROC)(GLintptr indirect);
+typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count);
+typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINDIRECTPROC)(GLenum mode, const void * indirect);
+typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
+typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERPROC)(GLenum buf);
+typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum * bufs);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLint basevertex);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void * indirect);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex);
+typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
+typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices);
+typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex);
+typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKPROC)(GLenum mode, GLuint id);
+typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)(GLenum mode, GLuint id, GLsizei instancecount);
+typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)(GLenum mode, GLuint id, GLuint stream);
+typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount);
+typedef void (GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap);
+typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXARRAYATTRIBPROC)(GLuint vaobj, GLuint index);
+typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index);
+typedef void (GLAD_API_PTR *PFNGLENABLEIPROC)(GLenum target, GLuint index);
+typedef void (GLAD_API_PTR *PFNGLENDCONDITIONALRENDERPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLENDQUERYPROC)(GLenum target);
+typedef void (GLAD_API_PTR *PFNGLENDQUERYINDEXEDPROC)(GLenum target, GLuint index);
+typedef void (GLAD_API_PTR *PFNGLENDTRANSFORMFEEDBACKPROC)(void);
+typedef GLsync (GLAD_API_PTR *PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags);
+typedef void (GLAD_API_PTR *PFNGLFINISHPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLFLUSHPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length);
+typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERPARAMETERIPROC)(GLenum target, GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (GLAD_API_PTR *PFNGLFRONTFACEPROC)(GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint * buffers);
+typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers);
+typedef void (GLAD_API_PTR *PFNGLGENPROGRAMPIPELINESPROC)(GLsizei n, GLuint * pipelines);
+typedef void (GLAD_API_PTR *PFNGLGENQUERIESPROC)(GLsizei n, GLuint * ids);
+typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers);
+typedef void (GLAD_API_PTR *PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint * samplers);
+typedef void (GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures);
+typedef void (GLAD_API_PTR *PFNGLGENTRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint * ids);
+typedef void (GLAD_API_PTR *PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays);
+typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPPROC)(GLenum target);
+typedef void (GLAD_API_PTR *PFNGLGENERATETEXTUREMIPMAPPROC)(GLuint texture);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)(GLuint program, GLuint bufferIndex, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINENAMEPROC)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint * values);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformBlockName);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformName);
+typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders);
+typedef GLint (GLAD_API_PTR *PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean * data);
+typedef void (GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean * data);
+typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 * params);
+typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void ** params);
+typedef void (GLAD_API_PTR *PFNGLGETBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, void * data);
+typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void * img);
+typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)(GLuint texture, GLint level, GLsizei bufSize, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void * pixels);
+typedef GLuint (GLAD_API_PTR *PFNGLGETDEBUGMESSAGELOGPROC)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog);
+typedef void (GLAD_API_PTR *PFNGLGETDOUBLEI_VPROC)(GLenum target, GLuint index, GLdouble * data);
+typedef void (GLAD_API_PTR *PFNGLGETDOUBLEVPROC)(GLenum pname, GLdouble * data);
+typedef GLenum (GLAD_API_PTR *PFNGLGETERRORPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLGETFLOATI_VPROC)(GLenum target, GLuint index, GLfloat * data);
+typedef void (GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat * data);
+typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATAINDEXPROC)(GLuint program, const GLchar * name);
+typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params);
+typedef GLenum (GLAD_API_PTR *PFNGLGETGRAPHICSRESETSTATUSPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 * data);
+typedef void (GLAD_API_PTR *PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 * data);
+typedef void (GLAD_API_PTR *PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint * data);
+typedef void (GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint * data);
+typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATI64VPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint64 * params);
+typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATIVPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat * val);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)(GLuint buffer, GLenum pname, GLint64 * params);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERIVPROC)(GLuint buffer, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPOINTERVPROC)(GLuint buffer, GLenum pname, void ** params);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, void * data);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLuint framebuffer, GLenum attachment, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)(GLuint framebuffer, GLenum pname, GLint * param);
+typedef void (GLAD_API_PTR *PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)(GLuint renderbuffer, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label);
+typedef void (GLAD_API_PTR *PFNGLGETOBJECTPTRLABELPROC)(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label);
+typedef void (GLAD_API_PTR *PFNGLGETPOINTERVPROC)(GLenum pname, void ** params);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMBINARYPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLenum * binaryFormat, void * binary);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINTERFACEIVPROC)(GLuint program, GLenum programInterface, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEINFOLOGPROC)(GLuint pipeline, GLsizei bufSize, GLsizei * length, GLchar * infoLog);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEIVPROC)(GLuint pipeline, GLenum pname, GLint * params);
+typedef GLuint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEINDEXPROC)(GLuint program, GLenum programInterface, const GLchar * name);
+typedef GLint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONPROC)(GLuint program, GLenum programInterface, const GLchar * name);
+typedef GLint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)(GLuint program, GLenum programInterface, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCENAMEPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEIVPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei count, GLsizei * length, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMSTAGEIVPROC)(GLuint program, GLenum shadertype, GLenum pname, GLint * values);
+typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTI64VPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTIVPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTUI64VPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTUIVPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYINDEXEDIVPROC)(GLenum target, GLuint index, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64 * params);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64 * params);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog);
+typedef void (GLAD_API_PTR *PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision);
+typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source);
+typedef void (GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint * params);
+typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name);
+typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGIPROC)(GLenum name, GLuint index);
+typedef GLuint (GLAD_API_PTR *PFNGLGETSUBROUTINEINDEXPROC)(GLuint program, GLenum shadertype, const GLchar * name);
+typedef GLint (GLAD_API_PTR *PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)(GLuint program, GLenum shadertype, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei * length, GLint * values);
+typedef void (GLAD_API_PTR *PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTUREIMAGEPROC)(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERFVPROC)(GLuint texture, GLint level, GLenum pname, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERIVPROC)(GLuint texture, GLint level, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIIVPROC)(GLuint texture, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIUIVPROC)(GLuint texture, GLenum pname, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERFVPROC)(GLuint texture, GLenum pname, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIVPROC)(GLuint texture, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETTEXTURESUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKI64_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint64 * param);
+typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKI_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint * param);
+typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKIVPROC)(GLuint xfb, GLenum pname, GLint * param);
+typedef GLuint (GLAD_API_PTR *PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar * uniformBlockName);
+typedef void (GLAD_API_PTR *PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint * uniformIndices);
+typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar * name);
+typedef void (GLAD_API_PTR *PFNGLGETUNIFORMSUBROUTINEUIVPROC)(GLenum shadertype, GLint location, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETUNIFORMDVPROC)(GLuint program, GLint location, GLdouble * params);
+typedef void (GLAD_API_PTR *PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYINDEXED64IVPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint64 * param);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYINDEXEDIVPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint * param);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYIVPROC)(GLuint vaobj, GLenum pname, GLint * param);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBLDVPROC)(GLuint index, GLenum pname, GLdouble * params);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void ** pointer);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble * params);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETNCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint lod, GLsizei bufSize, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLGETNTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMDVPROC)(GLuint program, GLint location, GLsizei bufSize, GLdouble * params);
+typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMFVPROC)(GLuint program, GLint location, GLsizei bufSize, GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMIVPROC)(GLuint program, GLint location, GLsizei bufSize, GLint * params);
+typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMUIVPROC)(GLuint program, GLint location, GLsizei bufSize, GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLHINTPROC)(GLenum target, GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATEBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATETEXIMAGEPROC)(GLuint texture, GLint level);
+typedef void (GLAD_API_PTR *PFNGLINVALIDATETEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
+typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer);
+typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap);
+typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDIPROC)(GLenum target, GLuint index);
+typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer);
+typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPROC)(GLuint program);
+typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPIPELINEPROC)(GLuint pipeline);
+typedef GLboolean (GLAD_API_PTR *PFNGLISQUERYPROC)(GLuint id);
+typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer);
+typedef GLboolean (GLAD_API_PTR *PFNGLISSAMPLERPROC)(GLuint sampler);
+typedef GLboolean (GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader);
+typedef GLboolean (GLAD_API_PTR *PFNGLISSYNCPROC)(GLsync sync);
+typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture);
+typedef GLboolean (GLAD_API_PTR *PFNGLISTRANSFORMFEEDBACKPROC)(GLuint id);
+typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXARRAYPROC)(GLuint array);
+typedef void (GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width);
+typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program);
+typedef void (GLAD_API_PTR *PFNGLLOGICOPPROC)(GLenum opcode);
+typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERPROC)(GLenum target, GLenum access);
+typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void * (GLAD_API_PTR *PFNGLMAPNAMEDBUFFERPROC)(GLuint buffer, GLenum access);
+typedef void * (GLAD_API_PTR *PFNGLMAPNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIERPROC)(GLbitfield barriers);
+typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIERBYREGIONPROC)(GLbitfield barriers);
+typedef void (GLAD_API_PTR *PFNGLMINSAMPLESHADINGPROC)(GLfloat value);
+typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSPROC)(GLenum mode, const GLint * first, const GLsizei * count, GLsizei drawcount);
+typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTPROC)(GLenum mode, const void * indirect, GLsizei drawcount, GLsizei stride);
+typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)(GLenum mode, const void * indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount);
+typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount, const GLint * basevertex);
+typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void * indirect, GLsizei drawcount, GLsizei stride);
+typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)(GLenum mode, GLenum type, const void * indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERDATAPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLenum usage);
+typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSTORAGEPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLbitfield flags);
+typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)(GLuint framebuffer, GLenum buf);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)(GLuint framebuffer, GLsizei n, const GLenum * bufs);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)(GLuint framebuffer, GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)(GLuint framebuffer, GLenum src);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEPROC)(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar * label);
+typedef void (GLAD_API_PTR *PFNGLOBJECTPTRLABELPROC)(const void * ptr, GLsizei length, const GLchar * label);
+typedef void (GLAD_API_PTR *PFNGLPATCHPARAMETERFVPROC)(GLenum pname, const GLfloat * values);
+typedef void (GLAD_API_PTR *PFNGLPATCHPARAMETERIPROC)(GLenum pname, GLint value);
+typedef void (GLAD_API_PTR *PFNGLPAUSETRANSFORMFEEDBACKPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLPIXELSTOREFPROC)(GLenum pname, GLfloat param);
+typedef void (GLAD_API_PTR *PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param);
+typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint * params);
+typedef void (GLAD_API_PTR *PFNGLPOINTSIZEPROC)(GLfloat size);
+typedef void (GLAD_API_PTR *PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units);
+typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETCLAMPPROC)(GLfloat factor, GLfloat units, GLfloat clamp);
+typedef void (GLAD_API_PTR *PFNGLPOPDEBUGGROUPPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMBINARYPROC)(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETERIPROC)(GLuint program, GLenum pname, GLint value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DPROC)(GLuint program, GLint location, GLdouble v0);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FPROC)(GLuint program, GLint location, GLfloat v0);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IPROC)(GLuint program, GLint location, GLint v0);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIPROC)(GLuint program, GLint location, GLuint v0);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IPROC)(GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLPROVOKINGVERTEXPROC)(GLenum mode);
+typedef void (GLAD_API_PTR *PFNGLPUSHDEBUGGROUPPROC)(GLenum source, GLuint id, GLsizei length, const GLchar * message);
+typedef void (GLAD_API_PTR *PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target);
+typedef void (GLAD_API_PTR *PFNGLREADBUFFERPROC)(GLenum src);
+typedef void (GLAD_API_PTR *PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels);
+typedef void (GLAD_API_PTR *PFNGLREADNPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void * data);
+typedef void (GLAD_API_PTR *PFNGLRELEASESHADERCOMPILERPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLRESUMETRANSFORMFEEDBACKPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert);
+typedef void (GLAD_API_PTR *PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask);
+typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, const GLint * param);
+typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, const GLuint * param);
+typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param);
+typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat * param);
+typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint * param);
+typedef void (GLAD_API_PTR *PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLSCISSORARRAYVPROC)(GLuint first, GLsizei count, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDPROC)(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint * shaders, GLenum binaryFormat, const void * binary, GLsizei length);
+typedef void (GLAD_API_PTR *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length);
+typedef void (GLAD_API_PTR *PFNGLSHADERSTORAGEBLOCKBINDINGPROC)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);
+typedef void (GLAD_API_PTR *PFNGLSPECIALIZESHADERPROC)(GLuint shader, const GLchar * pEntryPoint, GLuint numSpecializationConstants, const GLuint * pConstantIndex, const GLuint * pConstantValue);
+typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask);
+typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask);
+typedef void (GLAD_API_PTR *PFNGLSTENCILMASKPROC)(GLuint mask);
+typedef void (GLAD_API_PTR *PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask);
+typedef void (GLAD_API_PTR *PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass);
+typedef void (GLAD_API_PTR *PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (GLAD_API_PTR *PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLTEXBUFFERRANGEPROC)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAD_API_PTR *PFNGLTEXIMAGE1DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint * params);
+typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params);
+typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE1DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREBARRIERPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREBUFFERPROC)(GLuint texture, GLenum internalformat, GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREBUFFERRANGEPROC)(GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIIVPROC)(GLuint texture, GLenum pname, const GLint * params);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIUIVPROC)(GLuint texture, GLenum pname, const GLuint * params);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERFPROC)(GLuint texture, GLenum pname, GLfloat param);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERFVPROC)(GLuint texture, GLenum pname, const GLfloat * param);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIPROC)(GLuint texture, GLenum pname, GLint param);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIVPROC)(GLuint texture, GLenum pname, const GLint * param);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE1DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels);
+typedef void (GLAD_API_PTR *PFNGLTEXTUREVIEWPROC)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)(GLuint xfb, GLuint index, GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1DPROC)(GLint location, GLdouble x);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1DVPROC)(GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1IPROC)(GLint location, GLint v0);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2DPROC)(GLint location, GLdouble x, GLdouble y);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2DVPROC)(GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3DPROC)(GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3DVPROC)(GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4DPROC)(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4DVPROC)(GLint location, GLsizei count, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
+typedef void (GLAD_API_PTR *PFNGLUNIFORMSUBROUTINESUIVPROC)(GLenum shadertype, GLsizei count, const GLuint * indices);
+typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPBUFFERPROC)(GLenum target);
+typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPNAMEDBUFFERPROC)(GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program);
+typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMSTAGESPROC)(GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program);
+typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPIPELINEPROC)(GLuint pipeline);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBBINDINGPROC)(GLuint vaobj, GLuint attribindex, GLuint bindingindex);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBIFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBLFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYBINDINGDIVISORPROC)(GLuint vaobj, GLuint bindingindex, GLuint divisor);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYELEMENTBUFFERPROC)(GLuint vaobj, GLuint buffer);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBUFFERPROC)(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBUFFERSPROC)(GLuint vaobj, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBBINDINGPROC)(GLuint attribindex, GLuint bindingindex);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint x);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint x);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint x, GLint y);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint x, GLuint y);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint x, GLint y, GLint z);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1DPROC)(GLuint index, GLdouble x);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2DPROC)(GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4DVPROC)(GLuint index, const GLdouble * v);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBLFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBLPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value);
+typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer);
+typedef void (GLAD_API_PTR *PFNGLVERTEXBINDINGDIVISORPROC)(GLuint bindingindex, GLuint divisor);
+typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAD_API_PTR *PFNGLVIEWPORTARRAYVPROC)(GLuint first, GLsizei count, const GLfloat * v);
+typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFVPROC)(GLuint index, const GLfloat * v);
+typedef void (GLAD_API_PTR *PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout);
+
+GLAD_API_CALL PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram;
+#define glActiveShaderProgram glad_glActiveShaderProgram
+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 PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed;
+#define glBeginQueryIndexed glad_glBeginQueryIndexed
+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 PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase;
+#define glBindBuffersBase glad_glBindBuffersBase
+GLAD_API_CALL PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange;
+#define glBindBuffersRange glad_glBindBuffersRange
+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 PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture;
+#define glBindImageTexture glad_glBindImageTexture
+GLAD_API_CALL PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures;
+#define glBindImageTextures glad_glBindImageTextures
+GLAD_API_CALL PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline;
+#define glBindProgramPipeline glad_glBindProgramPipeline
+GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer;
+#define glBindRenderbuffer glad_glBindRenderbuffer
+GLAD_API_CALL PFNGLBINDSAMPLERPROC glad_glBindSampler;
+#define glBindSampler glad_glBindSampler
+GLAD_API_CALL PFNGLBINDSAMPLERSPROC glad_glBindSamplers;
+#define glBindSamplers glad_glBindSamplers
+GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture;
+#define glBindTexture glad_glBindTexture
+GLAD_API_CALL PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit;
+#define glBindTextureUnit glad_glBindTextureUnit
+GLAD_API_CALL PFNGLBINDTEXTURESPROC glad_glBindTextures;
+#define glBindTextures glad_glBindTextures
+GLAD_API_CALL PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback;
+#define glBindTransformFeedback glad_glBindTransformFeedback
+GLAD_API_CALL PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray;
+#define glBindVertexArray glad_glBindVertexArray
+GLAD_API_CALL PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer;
+#define glBindVertexBuffer glad_glBindVertexBuffer
+GLAD_API_CALL PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers;
+#define glBindVertexBuffers glad_glBindVertexBuffers
+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 PFNGLBLENDEQUATIONSEPARATEIPROC glad_glBlendEquationSeparatei;
+#define glBlendEquationSeparatei glad_glBlendEquationSeparatei
+GLAD_API_CALL PFNGLBLENDEQUATIONIPROC glad_glBlendEquationi;
+#define glBlendEquationi glad_glBlendEquationi
+GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc;
+#define glBlendFunc glad_glBlendFunc
+GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate;
+#define glBlendFuncSeparate glad_glBlendFuncSeparate
+GLAD_API_CALL PFNGLBLENDFUNCSEPARATEIPROC glad_glBlendFuncSeparatei;
+#define glBlendFuncSeparatei glad_glBlendFuncSeparatei
+GLAD_API_CALL PFNGLBLENDFUNCIPROC glad_glBlendFunci;
+#define glBlendFunci glad_glBlendFunci
+GLAD_API_CALL PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer;
+#define glBlitFramebuffer glad_glBlitFramebuffer
+GLAD_API_CALL PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer;
+#define glBlitNamedFramebuffer glad_glBlitNamedFramebuffer
+GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData;
+#define glBufferData glad_glBufferData
+GLAD_API_CALL PFNGLBUFFERSTORAGEPROC glad_glBufferStorage;
+#define glBufferStorage glad_glBufferStorage
+GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData;
+#define glBufferSubData glad_glBufferSubData
+GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus;
+#define glCheckFramebufferStatus glad_glCheckFramebufferStatus
+GLAD_API_CALL PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus;
+#define glCheckNamedFramebufferStatus glad_glCheckNamedFramebufferStatus
+GLAD_API_CALL PFNGLCLAMPCOLORPROC glad_glClampColor;
+#define glClampColor glad_glClampColor
+GLAD_API_CALL PFNGLCLEARPROC glad_glClear;
+#define glClear glad_glClear
+GLAD_API_CALL PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData;
+#define glClearBufferData glad_glClearBufferData
+GLAD_API_CALL PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData;
+#define glClearBufferSubData glad_glClearBufferSubData
+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 PFNGLCLEARDEPTHFPROC glad_glClearDepthf;
+#define glClearDepthf glad_glClearDepthf
+GLAD_API_CALL PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData;
+#define glClearNamedBufferData glad_glClearNamedBufferData
+GLAD_API_CALL PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData;
+#define glClearNamedBufferSubData glad_glClearNamedBufferSubData
+GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi;
+#define glClearNamedFramebufferfi glad_glClearNamedFramebufferfi
+GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv;
+#define glClearNamedFramebufferfv glad_glClearNamedFramebufferfv
+GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv;
+#define glClearNamedFramebufferiv glad_glClearNamedFramebufferiv
+GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv;
+#define glClearNamedFramebufferuiv glad_glClearNamedFramebufferuiv
+GLAD_API_CALL PFNGLCLEARSTENCILPROC glad_glClearStencil;
+#define glClearStencil glad_glClearStencil
+GLAD_API_CALL PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage;
+#define glClearTexImage glad_glClearTexImage
+GLAD_API_CALL PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage;
+#define glClearTexSubImage glad_glClearTexSubImage
+GLAD_API_CALL PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync;
+#define glClientWaitSync glad_glClientWaitSync
+GLAD_API_CALL PFNGLCLIPCONTROLPROC glad_glClipControl;
+#define glClipControl glad_glClipControl
+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 PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D;
+#define glCompressedTextureSubImage1D glad_glCompressedTextureSubImage1D
+GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D;
+#define glCompressedTextureSubImage2D glad_glCompressedTextureSubImage2D
+GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D;
+#define glCompressedTextureSubImage3D glad_glCompressedTextureSubImage3D
+GLAD_API_CALL PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData;
+#define glCopyBufferSubData glad_glCopyBufferSubData
+GLAD_API_CALL PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData;
+#define glCopyImageSubData glad_glCopyImageSubData
+GLAD_API_CALL PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData;
+#define glCopyNamedBufferSubData glad_glCopyNamedBufferSubData
+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 PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D;
+#define glCopyTextureSubImage1D glad_glCopyTextureSubImage1D
+GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D;
+#define glCopyTextureSubImage2D glad_glCopyTextureSubImage2D
+GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D;
+#define glCopyTextureSubImage3D glad_glCopyTextureSubImage3D
+GLAD_API_CALL PFNGLCREATEBUFFERSPROC glad_glCreateBuffers;
+#define glCreateBuffers glad_glCreateBuffers
+GLAD_API_CALL PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers;
+#define glCreateFramebuffers glad_glCreateFramebuffers
+GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram;
+#define glCreateProgram glad_glCreateProgram
+GLAD_API_CALL PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines;
+#define glCreateProgramPipelines glad_glCreateProgramPipelines
+GLAD_API_CALL PFNGLCREATEQUERIESPROC glad_glCreateQueries;
+#define glCreateQueries glad_glCreateQueries
+GLAD_API_CALL PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers;
+#define glCreateRenderbuffers glad_glCreateRenderbuffers
+GLAD_API_CALL PFNGLCREATESAMPLERSPROC glad_glCreateSamplers;
+#define glCreateSamplers glad_glCreateSamplers
+GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader;
+#define glCreateShader glad_glCreateShader
+GLAD_API_CALL PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv;
+#define glCreateShaderProgramv glad_glCreateShaderProgramv
+GLAD_API_CALL PFNGLCREATETEXTURESPROC glad_glCreateTextures;
+#define glCreateTextures glad_glCreateTextures
+GLAD_API_CALL PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks;
+#define glCreateTransformFeedbacks glad_glCreateTransformFeedbacks
+GLAD_API_CALL PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays;
+#define glCreateVertexArrays glad_glCreateVertexArrays
+GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace;
+#define glCullFace glad_glCullFace
+GLAD_API_CALL PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback;
+#define glDebugMessageCallback glad_glDebugMessageCallback
+GLAD_API_CALL PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl;
+#define glDebugMessageControl glad_glDebugMessageControl
+GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert;
+#define glDebugMessageInsert glad_glDebugMessageInsert
+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 PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines;
+#define glDeleteProgramPipelines glad_glDeleteProgramPipelines
+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 PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks;
+#define glDeleteTransformFeedbacks glad_glDeleteTransformFeedbacks
+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 PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv;
+#define glDepthRangeArrayv glad_glDepthRangeArrayv
+GLAD_API_CALL PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed;
+#define glDepthRangeIndexed glad_glDepthRangeIndexed
+GLAD_API_CALL PFNGLDEPTHRANGEFPROC glad_glDepthRangef;
+#define glDepthRangef glad_glDepthRangef
+GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader;
+#define glDetachShader glad_glDetachShader
+GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable;
+#define glDisable glad_glDisable
+GLAD_API_CALL PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib;
+#define glDisableVertexArrayAttrib glad_glDisableVertexArrayAttrib
+GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray;
+#define glDisableVertexAttribArray glad_glDisableVertexAttribArray
+GLAD_API_CALL PFNGLDISABLEIPROC glad_glDisablei;
+#define glDisablei glad_glDisablei
+GLAD_API_CALL PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute;
+#define glDispatchCompute glad_glDispatchCompute
+GLAD_API_CALL PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect;
+#define glDispatchComputeIndirect glad_glDispatchComputeIndirect
+GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays;
+#define glDrawArrays glad_glDrawArrays
+GLAD_API_CALL PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect;
+#define glDrawArraysIndirect glad_glDrawArraysIndirect
+GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced;
+#define glDrawArraysInstanced glad_glDrawArraysInstanced
+GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance;
+#define glDrawArraysInstancedBaseInstance glad_glDrawArraysInstancedBaseInstance
+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 PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect;
+#define glDrawElementsIndirect glad_glDrawElementsIndirect
+GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced;
+#define glDrawElementsInstanced glad_glDrawElementsInstanced
+GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance;
+#define glDrawElementsInstancedBaseInstance glad_glDrawElementsInstancedBaseInstance
+GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex;
+#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex
+GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance;
+#define glDrawElementsInstancedBaseVertexBaseInstance glad_glDrawElementsInstancedBaseVertexBaseInstance
+GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements;
+#define glDrawRangeElements glad_glDrawRangeElements
+GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex;
+#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex
+GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback;
+#define glDrawTransformFeedback glad_glDrawTransformFeedback
+GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced;
+#define glDrawTransformFeedbackInstanced glad_glDrawTransformFeedbackInstanced
+GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream;
+#define glDrawTransformFeedbackStream glad_glDrawTransformFeedbackStream
+GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced;
+#define glDrawTransformFeedbackStreamInstanced glad_glDrawTransformFeedbackStreamInstanced
+GLAD_API_CALL PFNGLENABLEPROC glad_glEnable;
+#define glEnable glad_glEnable
+GLAD_API_CALL PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib;
+#define glEnableVertexArrayAttrib glad_glEnableVertexArrayAttrib
+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 PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed;
+#define glEndQueryIndexed glad_glEndQueryIndexed
+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 PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange;
+#define glFlushMappedNamedBufferRange glad_glFlushMappedNamedBufferRange
+GLAD_API_CALL PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri;
+#define glFramebufferParameteri glad_glFramebufferParameteri
+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 PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines;
+#define glGenProgramPipelines glad_glGenProgramPipelines
+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 PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks;
+#define glGenTransformFeedbacks glad_glGenTransformFeedbacks
+GLAD_API_CALL PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays;
+#define glGenVertexArrays glad_glGenVertexArrays
+GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap;
+#define glGenerateMipmap glad_glGenerateMipmap
+GLAD_API_CALL PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap;
+#define glGenerateTextureMipmap glad_glGenerateTextureMipmap
+GLAD_API_CALL PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv;
+#define glGetActiveAtomicCounterBufferiv glad_glGetActiveAtomicCounterBufferiv
+GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib;
+#define glGetActiveAttrib glad_glGetActiveAttrib
+GLAD_API_CALL PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName;
+#define glGetActiveSubroutineName glad_glGetActiveSubroutineName
+GLAD_API_CALL PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName;
+#define glGetActiveSubroutineUniformName glad_glGetActiveSubroutineUniformName
+GLAD_API_CALL PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv;
+#define glGetActiveSubroutineUniformiv glad_glGetActiveSubroutineUniformiv
+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 PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage;
+#define glGetCompressedTextureImage glad_glGetCompressedTextureImage
+GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage;
+#define glGetCompressedTextureSubImage glad_glGetCompressedTextureSubImage
+GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog;
+#define glGetDebugMessageLog glad_glGetDebugMessageLog
+GLAD_API_CALL PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v;
+#define glGetDoublei_v glad_glGetDoublei_v
+GLAD_API_CALL PFNGLGETDOUBLEVPROC glad_glGetDoublev;
+#define glGetDoublev glad_glGetDoublev
+GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError;
+#define glGetError glad_glGetError
+GLAD_API_CALL PFNGLGETFLOATI_VPROC glad_glGetFloati_v;
+#define glGetFloati_v glad_glGetFloati_v
+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 PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv;
+#define glGetFramebufferParameteriv glad_glGetFramebufferParameteriv
+GLAD_API_CALL PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus;
+#define glGetGraphicsResetStatus glad_glGetGraphicsResetStatus
+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 PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v;
+#define glGetInternalformati64v glad_glGetInternalformati64v
+GLAD_API_CALL PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ;
+#define glGetInternalformativ glad_glGetInternalformativ
+GLAD_API_CALL PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv;
+#define glGetMultisamplefv glad_glGetMultisamplefv
+GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v;
+#define glGetNamedBufferParameteri64v glad_glGetNamedBufferParameteri64v
+GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv;
+#define glGetNamedBufferParameteriv glad_glGetNamedBufferParameteriv
+GLAD_API_CALL PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv;
+#define glGetNamedBufferPointerv glad_glGetNamedBufferPointerv
+GLAD_API_CALL PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData;
+#define glGetNamedBufferSubData glad_glGetNamedBufferSubData
+GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv;
+#define glGetNamedFramebufferAttachmentParameteriv glad_glGetNamedFramebufferAttachmentParameteriv
+GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv;
+#define glGetNamedFramebufferParameteriv glad_glGetNamedFramebufferParameteriv
+GLAD_API_CALL PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv;
+#define glGetNamedRenderbufferParameteriv glad_glGetNamedRenderbufferParameteriv
+GLAD_API_CALL PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel;
+#define glGetObjectLabel glad_glGetObjectLabel
+GLAD_API_CALL PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel;
+#define glGetObjectPtrLabel glad_glGetObjectPtrLabel
+GLAD_API_CALL PFNGLGETPOINTERVPROC glad_glGetPointerv;
+#define glGetPointerv glad_glGetPointerv
+GLAD_API_CALL PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary;
+#define glGetProgramBinary glad_glGetProgramBinary
+GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog;
+#define glGetProgramInfoLog glad_glGetProgramInfoLog
+GLAD_API_CALL PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv;
+#define glGetProgramInterfaceiv glad_glGetProgramInterfaceiv
+GLAD_API_CALL PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog;
+#define glGetProgramPipelineInfoLog glad_glGetProgramPipelineInfoLog
+GLAD_API_CALL PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv;
+#define glGetProgramPipelineiv glad_glGetProgramPipelineiv
+GLAD_API_CALL PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex;
+#define glGetProgramResourceIndex glad_glGetProgramResourceIndex
+GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation;
+#define glGetProgramResourceLocation glad_glGetProgramResourceLocation
+GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex;
+#define glGetProgramResourceLocationIndex glad_glGetProgramResourceLocationIndex
+GLAD_API_CALL PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName;
+#define glGetProgramResourceName glad_glGetProgramResourceName
+GLAD_API_CALL PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv;
+#define glGetProgramResourceiv glad_glGetProgramResourceiv
+GLAD_API_CALL PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv;
+#define glGetProgramStageiv glad_glGetProgramStageiv
+GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv;
+#define glGetProgramiv glad_glGetProgramiv
+GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v;
+#define glGetQueryBufferObjecti64v glad_glGetQueryBufferObjecti64v
+GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv;
+#define glGetQueryBufferObjectiv glad_glGetQueryBufferObjectiv
+GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v;
+#define glGetQueryBufferObjectui64v glad_glGetQueryBufferObjectui64v
+GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv;
+#define glGetQueryBufferObjectuiv glad_glGetQueryBufferObjectuiv
+GLAD_API_CALL PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv;
+#define glGetQueryIndexediv glad_glGetQueryIndexediv
+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 PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat;
+#define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat
+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 PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex;
+#define glGetSubroutineIndex glad_glGetSubroutineIndex
+GLAD_API_CALL PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation;
+#define glGetSubroutineUniformLocation glad_glGetSubroutineUniformLocation
+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 PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage;
+#define glGetTextureImage glad_glGetTextureImage
+GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv;
+#define glGetTextureLevelParameterfv glad_glGetTextureLevelParameterfv
+GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv;
+#define glGetTextureLevelParameteriv glad_glGetTextureLevelParameteriv
+GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv;
+#define glGetTextureParameterIiv glad_glGetTextureParameterIiv
+GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv;
+#define glGetTextureParameterIuiv glad_glGetTextureParameterIuiv
+GLAD_API_CALL PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv;
+#define glGetTextureParameterfv glad_glGetTextureParameterfv
+GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv;
+#define glGetTextureParameteriv glad_glGetTextureParameteriv
+GLAD_API_CALL PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage;
+#define glGetTextureSubImage glad_glGetTextureSubImage
+GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying;
+#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying
+GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v;
+#define glGetTransformFeedbacki64_v glad_glGetTransformFeedbacki64_v
+GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v;
+#define glGetTransformFeedbacki_v glad_glGetTransformFeedbacki_v
+GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv;
+#define glGetTransformFeedbackiv glad_glGetTransformFeedbackiv
+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 PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv;
+#define glGetUniformSubroutineuiv glad_glGetUniformSubroutineuiv
+GLAD_API_CALL PFNGLGETUNIFORMDVPROC glad_glGetUniformdv;
+#define glGetUniformdv glad_glGetUniformdv
+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 PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv;
+#define glGetVertexArrayIndexed64iv glad_glGetVertexArrayIndexed64iv
+GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv;
+#define glGetVertexArrayIndexediv glad_glGetVertexArrayIndexediv
+GLAD_API_CALL PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv;
+#define glGetVertexArrayiv glad_glGetVertexArrayiv
+GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv;
+#define glGetVertexAttribIiv glad_glGetVertexAttribIiv
+GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv;
+#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv
+GLAD_API_CALL PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv;
+#define glGetVertexAttribLdv glad_glGetVertexAttribLdv
+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 PFNGLGETNCOMPRESSEDTEXIMAGEPROC glad_glGetnCompressedTexImage;
+#define glGetnCompressedTexImage glad_glGetnCompressedTexImage
+GLAD_API_CALL PFNGLGETNTEXIMAGEPROC glad_glGetnTexImage;
+#define glGetnTexImage glad_glGetnTexImage
+GLAD_API_CALL PFNGLGETNUNIFORMDVPROC glad_glGetnUniformdv;
+#define glGetnUniformdv glad_glGetnUniformdv
+GLAD_API_CALL PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv;
+#define glGetnUniformfv glad_glGetnUniformfv
+GLAD_API_CALL PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv;
+#define glGetnUniformiv glad_glGetnUniformiv
+GLAD_API_CALL PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv;
+#define glGetnUniformuiv glad_glGetnUniformuiv
+GLAD_API_CALL PFNGLHINTPROC glad_glHint;
+#define glHint glad_glHint
+GLAD_API_CALL PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData;
+#define glInvalidateBufferData glad_glInvalidateBufferData
+GLAD_API_CALL PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData;
+#define glInvalidateBufferSubData glad_glInvalidateBufferSubData
+GLAD_API_CALL PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer;
+#define glInvalidateFramebuffer glad_glInvalidateFramebuffer
+GLAD_API_CALL PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData;
+#define glInvalidateNamedFramebufferData glad_glInvalidateNamedFramebufferData
+GLAD_API_CALL PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData;
+#define glInvalidateNamedFramebufferSubData glad_glInvalidateNamedFramebufferSubData
+GLAD_API_CALL PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer;
+#define glInvalidateSubFramebuffer glad_glInvalidateSubFramebuffer
+GLAD_API_CALL PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage;
+#define glInvalidateTexImage glad_glInvalidateTexImage
+GLAD_API_CALL PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage;
+#define glInvalidateTexSubImage glad_glInvalidateTexSubImage
+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 PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline;
+#define glIsProgramPipeline glad_glIsProgramPipeline
+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 PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback;
+#define glIsTransformFeedback glad_glIsTransformFeedback
+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 PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer;
+#define glMapNamedBuffer glad_glMapNamedBuffer
+GLAD_API_CALL PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange;
+#define glMapNamedBufferRange glad_glMapNamedBufferRange
+GLAD_API_CALL PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier;
+#define glMemoryBarrier glad_glMemoryBarrier
+GLAD_API_CALL PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion;
+#define glMemoryBarrierByRegion glad_glMemoryBarrierByRegion
+GLAD_API_CALL PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading;
+#define glMinSampleShading glad_glMinSampleShading
+GLAD_API_CALL PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays;
+#define glMultiDrawArrays glad_glMultiDrawArrays
+GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect;
+#define glMultiDrawArraysIndirect glad_glMultiDrawArraysIndirect
+GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glad_glMultiDrawArraysIndirectCount;
+#define glMultiDrawArraysIndirectCount glad_glMultiDrawArraysIndirectCount
+GLAD_API_CALL PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements;
+#define glMultiDrawElements glad_glMultiDrawElements
+GLAD_API_CALL PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex;
+#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex
+GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect;
+#define glMultiDrawElementsIndirect glad_glMultiDrawElementsIndirect
+GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glad_glMultiDrawElementsIndirectCount;
+#define glMultiDrawElementsIndirectCount glad_glMultiDrawElementsIndirectCount
+GLAD_API_CALL PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData;
+#define glNamedBufferData glad_glNamedBufferData
+GLAD_API_CALL PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage;
+#define glNamedBufferStorage glad_glNamedBufferStorage
+GLAD_API_CALL PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData;
+#define glNamedBufferSubData glad_glNamedBufferSubData
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer;
+#define glNamedFramebufferDrawBuffer glad_glNamedFramebufferDrawBuffer
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers;
+#define glNamedFramebufferDrawBuffers glad_glNamedFramebufferDrawBuffers
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri;
+#define glNamedFramebufferParameteri glad_glNamedFramebufferParameteri
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer;
+#define glNamedFramebufferReadBuffer glad_glNamedFramebufferReadBuffer
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer;
+#define glNamedFramebufferRenderbuffer glad_glNamedFramebufferRenderbuffer
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture;
+#define glNamedFramebufferTexture glad_glNamedFramebufferTexture
+GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer;
+#define glNamedFramebufferTextureLayer glad_glNamedFramebufferTextureLayer
+GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage;
+#define glNamedRenderbufferStorage glad_glNamedRenderbufferStorage
+GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample;
+#define glNamedRenderbufferStorageMultisample glad_glNamedRenderbufferStorageMultisample
+GLAD_API_CALL PFNGLOBJECTLABELPROC glad_glObjectLabel;
+#define glObjectLabel glad_glObjectLabel
+GLAD_API_CALL PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel;
+#define glObjectPtrLabel glad_glObjectPtrLabel
+GLAD_API_CALL PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv;
+#define glPatchParameterfv glad_glPatchParameterfv
+GLAD_API_CALL PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri;
+#define glPatchParameteri glad_glPatchParameteri
+GLAD_API_CALL PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback;
+#define glPauseTransformFeedback glad_glPauseTransformFeedback
+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 PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp;
+#define glPolygonOffsetClamp glad_glPolygonOffsetClamp
+GLAD_API_CALL PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup;
+#define glPopDebugGroup glad_glPopDebugGroup
+GLAD_API_CALL PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex;
+#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex
+GLAD_API_CALL PFNGLPROGRAMBINARYPROC glad_glProgramBinary;
+#define glProgramBinary glad_glProgramBinary
+GLAD_API_CALL PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri;
+#define glProgramParameteri glad_glProgramParameteri
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d;
+#define glProgramUniform1d glad_glProgramUniform1d
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv;
+#define glProgramUniform1dv glad_glProgramUniform1dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f;
+#define glProgramUniform1f glad_glProgramUniform1f
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv;
+#define glProgramUniform1fv glad_glProgramUniform1fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i;
+#define glProgramUniform1i glad_glProgramUniform1i
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv;
+#define glProgramUniform1iv glad_glProgramUniform1iv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui;
+#define glProgramUniform1ui glad_glProgramUniform1ui
+GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv;
+#define glProgramUniform1uiv glad_glProgramUniform1uiv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d;
+#define glProgramUniform2d glad_glProgramUniform2d
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv;
+#define glProgramUniform2dv glad_glProgramUniform2dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f;
+#define glProgramUniform2f glad_glProgramUniform2f
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv;
+#define glProgramUniform2fv glad_glProgramUniform2fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i;
+#define glProgramUniform2i glad_glProgramUniform2i
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv;
+#define glProgramUniform2iv glad_glProgramUniform2iv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui;
+#define glProgramUniform2ui glad_glProgramUniform2ui
+GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv;
+#define glProgramUniform2uiv glad_glProgramUniform2uiv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d;
+#define glProgramUniform3d glad_glProgramUniform3d
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv;
+#define glProgramUniform3dv glad_glProgramUniform3dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f;
+#define glProgramUniform3f glad_glProgramUniform3f
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv;
+#define glProgramUniform3fv glad_glProgramUniform3fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i;
+#define glProgramUniform3i glad_glProgramUniform3i
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv;
+#define glProgramUniform3iv glad_glProgramUniform3iv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui;
+#define glProgramUniform3ui glad_glProgramUniform3ui
+GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv;
+#define glProgramUniform3uiv glad_glProgramUniform3uiv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d;
+#define glProgramUniform4d glad_glProgramUniform4d
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv;
+#define glProgramUniform4dv glad_glProgramUniform4dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f;
+#define glProgramUniform4f glad_glProgramUniform4f
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv;
+#define glProgramUniform4fv glad_glProgramUniform4fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i;
+#define glProgramUniform4i glad_glProgramUniform4i
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv;
+#define glProgramUniform4iv glad_glProgramUniform4iv
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui;
+#define glProgramUniform4ui glad_glProgramUniform4ui
+GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv;
+#define glProgramUniform4uiv glad_glProgramUniform4uiv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv;
+#define glProgramUniformMatrix2dv glad_glProgramUniformMatrix2dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv;
+#define glProgramUniformMatrix2fv glad_glProgramUniformMatrix2fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv;
+#define glProgramUniformMatrix2x3dv glad_glProgramUniformMatrix2x3dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv;
+#define glProgramUniformMatrix2x3fv glad_glProgramUniformMatrix2x3fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv;
+#define glProgramUniformMatrix2x4dv glad_glProgramUniformMatrix2x4dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv;
+#define glProgramUniformMatrix2x4fv glad_glProgramUniformMatrix2x4fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv;
+#define glProgramUniformMatrix3dv glad_glProgramUniformMatrix3dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv;
+#define glProgramUniformMatrix3fv glad_glProgramUniformMatrix3fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv;
+#define glProgramUniformMatrix3x2dv glad_glProgramUniformMatrix3x2dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv;
+#define glProgramUniformMatrix3x2fv glad_glProgramUniformMatrix3x2fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv;
+#define glProgramUniformMatrix3x4dv glad_glProgramUniformMatrix3x4dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv;
+#define glProgramUniformMatrix3x4fv glad_glProgramUniformMatrix3x4fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv;
+#define glProgramUniformMatrix4dv glad_glProgramUniformMatrix4dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv;
+#define glProgramUniformMatrix4fv glad_glProgramUniformMatrix4fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv;
+#define glProgramUniformMatrix4x2dv glad_glProgramUniformMatrix4x2dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv;
+#define glProgramUniformMatrix4x2fv glad_glProgramUniformMatrix4x2fv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv;
+#define glProgramUniformMatrix4x3dv glad_glProgramUniformMatrix4x3dv
+GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv;
+#define glProgramUniformMatrix4x3fv glad_glProgramUniformMatrix4x3fv
+GLAD_API_CALL PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex;
+#define glProvokingVertex glad_glProvokingVertex
+GLAD_API_CALL PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup;
+#define glPushDebugGroup glad_glPushDebugGroup
+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 PFNGLREADNPIXELSPROC glad_glReadnPixels;
+#define glReadnPixels glad_glReadnPixels
+GLAD_API_CALL PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler;
+#define glReleaseShaderCompiler glad_glReleaseShaderCompiler
+GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage;
+#define glRenderbufferStorage glad_glRenderbufferStorage
+GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample;
+#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample
+GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback;
+#define glResumeTransformFeedback glad_glResumeTransformFeedback
+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 PFNGLSCISSORARRAYVPROC glad_glScissorArrayv;
+#define glScissorArrayv glad_glScissorArrayv
+GLAD_API_CALL PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed;
+#define glScissorIndexed glad_glScissorIndexed
+GLAD_API_CALL PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv;
+#define glScissorIndexedv glad_glScissorIndexedv
+GLAD_API_CALL PFNGLSHADERBINARYPROC glad_glShaderBinary;
+#define glShaderBinary glad_glShaderBinary
+GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource;
+#define glShaderSource glad_glShaderSource
+GLAD_API_CALL PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding;
+#define glShaderStorageBlockBinding glad_glShaderStorageBlockBinding
+GLAD_API_CALL PFNGLSPECIALIZESHADERPROC glad_glSpecializeShader;
+#define glSpecializeShader glad_glSpecializeShader
+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 PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange;
+#define glTexBufferRange glad_glTexBufferRange
+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 PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D;
+#define glTexStorage1D glad_glTexStorage1D
+GLAD_API_CALL PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D;
+#define glTexStorage2D glad_glTexStorage2D
+GLAD_API_CALL PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample;
+#define glTexStorage2DMultisample glad_glTexStorage2DMultisample
+GLAD_API_CALL PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D;
+#define glTexStorage3D glad_glTexStorage3D
+GLAD_API_CALL PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample;
+#define glTexStorage3DMultisample glad_glTexStorage3DMultisample
+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 PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier;
+#define glTextureBarrier glad_glTextureBarrier
+GLAD_API_CALL PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer;
+#define glTextureBuffer glad_glTextureBuffer
+GLAD_API_CALL PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange;
+#define glTextureBufferRange glad_glTextureBufferRange
+GLAD_API_CALL PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv;
+#define glTextureParameterIiv glad_glTextureParameterIiv
+GLAD_API_CALL PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv;
+#define glTextureParameterIuiv glad_glTextureParameterIuiv
+GLAD_API_CALL PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf;
+#define glTextureParameterf glad_glTextureParameterf
+GLAD_API_CALL PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv;
+#define glTextureParameterfv glad_glTextureParameterfv
+GLAD_API_CALL PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri;
+#define glTextureParameteri glad_glTextureParameteri
+GLAD_API_CALL PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv;
+#define glTextureParameteriv glad_glTextureParameteriv
+GLAD_API_CALL PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D;
+#define glTextureStorage1D glad_glTextureStorage1D
+GLAD_API_CALL PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D;
+#define glTextureStorage2D glad_glTextureStorage2D
+GLAD_API_CALL PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample;
+#define glTextureStorage2DMultisample glad_glTextureStorage2DMultisample
+GLAD_API_CALL PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D;
+#define glTextureStorage3D glad_glTextureStorage3D
+GLAD_API_CALL PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample;
+#define glTextureStorage3DMultisample glad_glTextureStorage3DMultisample
+GLAD_API_CALL PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D;
+#define glTextureSubImage1D glad_glTextureSubImage1D
+GLAD_API_CALL PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D;
+#define glTextureSubImage2D glad_glTextureSubImage2D
+GLAD_API_CALL PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D;
+#define glTextureSubImage3D glad_glTextureSubImage3D
+GLAD_API_CALL PFNGLTEXTUREVIEWPROC glad_glTextureView;
+#define glTextureView glad_glTextureView
+GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase;
+#define glTransformFeedbackBufferBase glad_glTransformFeedbackBufferBase
+GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange;
+#define glTransformFeedbackBufferRange glad_glTransformFeedbackBufferRange
+GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings;
+#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings
+GLAD_API_CALL PFNGLUNIFORM1DPROC glad_glUniform1d;
+#define glUniform1d glad_glUniform1d
+GLAD_API_CALL PFNGLUNIFORM1DVPROC glad_glUniform1dv;
+#define glUniform1dv glad_glUniform1dv
+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 PFNGLUNIFORM2DPROC glad_glUniform2d;
+#define glUniform2d glad_glUniform2d
+GLAD_API_CALL PFNGLUNIFORM2DVPROC glad_glUniform2dv;
+#define glUniform2dv glad_glUniform2dv
+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 PFNGLUNIFORM3DPROC glad_glUniform3d;
+#define glUniform3d glad_glUniform3d
+GLAD_API_CALL PFNGLUNIFORM3DVPROC glad_glUniform3dv;
+#define glUniform3dv glad_glUniform3dv
+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 PFNGLUNIFORM4DPROC glad_glUniform4d;
+#define glUniform4d glad_glUniform4d
+GLAD_API_CALL PFNGLUNIFORM4DVPROC glad_glUniform4dv;
+#define glUniform4dv glad_glUniform4dv
+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 PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv;
+#define glUniformMatrix2dv glad_glUniformMatrix2dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv;
+#define glUniformMatrix2fv glad_glUniformMatrix2fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv;
+#define glUniformMatrix2x3dv glad_glUniformMatrix2x3dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv;
+#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv;
+#define glUniformMatrix2x4dv glad_glUniformMatrix2x4dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv;
+#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv;
+#define glUniformMatrix3dv glad_glUniformMatrix3dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv;
+#define glUniformMatrix3fv glad_glUniformMatrix3fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv;
+#define glUniformMatrix3x2dv glad_glUniformMatrix3x2dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv;
+#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv;
+#define glUniformMatrix3x4dv glad_glUniformMatrix3x4dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv;
+#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv;
+#define glUniformMatrix4dv glad_glUniformMatrix4dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv;
+#define glUniformMatrix4fv glad_glUniformMatrix4fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv;
+#define glUniformMatrix4x2dv glad_glUniformMatrix4x2dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv;
+#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv
+GLAD_API_CALL PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv;
+#define glUniformMatrix4x3dv glad_glUniformMatrix4x3dv
+GLAD_API_CALL PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv;
+#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv
+GLAD_API_CALL PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv;
+#define glUniformSubroutinesuiv glad_glUniformSubroutinesuiv
+GLAD_API_CALL PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer;
+#define glUnmapBuffer glad_glUnmapBuffer
+GLAD_API_CALL PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer;
+#define glUnmapNamedBuffer glad_glUnmapNamedBuffer
+GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram;
+#define glUseProgram glad_glUseProgram
+GLAD_API_CALL PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages;
+#define glUseProgramStages glad_glUseProgramStages
+GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram;
+#define glValidateProgram glad_glValidateProgram
+GLAD_API_CALL PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline;
+#define glValidateProgramPipeline glad_glValidateProgramPipeline
+GLAD_API_CALL PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding;
+#define glVertexArrayAttribBinding glad_glVertexArrayAttribBinding
+GLAD_API_CALL PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat;
+#define glVertexArrayAttribFormat glad_glVertexArrayAttribFormat
+GLAD_API_CALL PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat;
+#define glVertexArrayAttribIFormat glad_glVertexArrayAttribIFormat
+GLAD_API_CALL PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat;
+#define glVertexArrayAttribLFormat glad_glVertexArrayAttribLFormat
+GLAD_API_CALL PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor;
+#define glVertexArrayBindingDivisor glad_glVertexArrayBindingDivisor
+GLAD_API_CALL PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer;
+#define glVertexArrayElementBuffer glad_glVertexArrayElementBuffer
+GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer;
+#define glVertexArrayVertexBuffer glad_glVertexArrayVertexBuffer
+GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers;
+#define glVertexArrayVertexBuffers glad_glVertexArrayVertexBuffers
+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 PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding;
+#define glVertexAttribBinding glad_glVertexAttribBinding
+GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor;
+#define glVertexAttribDivisor glad_glVertexAttribDivisor
+GLAD_API_CALL PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat;
+#define glVertexAttribFormat glad_glVertexAttribFormat
+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 PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat;
+#define glVertexAttribIFormat glad_glVertexAttribIFormat
+GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer;
+#define glVertexAttribIPointer glad_glVertexAttribIPointer
+GLAD_API_CALL PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d;
+#define glVertexAttribL1d glad_glVertexAttribL1d
+GLAD_API_CALL PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv;
+#define glVertexAttribL1dv glad_glVertexAttribL1dv
+GLAD_API_CALL PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d;
+#define glVertexAttribL2d glad_glVertexAttribL2d
+GLAD_API_CALL PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv;
+#define glVertexAttribL2dv glad_glVertexAttribL2dv
+GLAD_API_CALL PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d;
+#define glVertexAttribL3d glad_glVertexAttribL3d
+GLAD_API_CALL PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv;
+#define glVertexAttribL3dv glad_glVertexAttribL3dv
+GLAD_API_CALL PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d;
+#define glVertexAttribL4d glad_glVertexAttribL4d
+GLAD_API_CALL PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv;
+#define glVertexAttribL4dv glad_glVertexAttribL4dv
+GLAD_API_CALL PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat;
+#define glVertexAttribLFormat glad_glVertexAttribLFormat
+GLAD_API_CALL PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer;
+#define glVertexAttribLPointer glad_glVertexAttribLPointer
+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 PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor;
+#define glVertexBindingDivisor glad_glVertexBindingDivisor
+GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport;
+#define glViewport glad_glViewport
+GLAD_API_CALL PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv;
+#define glViewportArrayv glad_glViewportArrayv
+GLAD_API_CALL PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf;
+#define glViewportIndexedf glad_glViewportIndexedf
+GLAD_API_CALL PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv;
+#define glViewportIndexedfv glad_glViewportIndexedfv
+GLAD_API_CALL PFNGLWAITSYNCPROC glad_glWaitSync;
+#define glWaitSync glad_glWaitSync
+
+
+
+
+
+GLAD_API_CALL int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr);
+GLAD_API_CALL int gladLoadGL( GLADloadfunc load);
+
+
+#ifdef GLAD_GL
+
+GLAD_API_CALL int gladLoaderLoadGL(void);
+GLAD_API_CALL void gladLoaderUnloadGL(void);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/mons_3d/external/glad/include/glad/glx.h b/mons_3d/external/glad/include/glad/glx.h
new file mode 100644
index 0000000..afd8e19
--- /dev/null
+++ b/mons_3d/external/glad/include/glad/glx.h
@@ -0,0 +1,566 @@
+/**
+ * Loader generated by glad 2.0.8 on Sat Feb 1 22:26:11 2025
+ *
+ * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
+ *
+ * Generator: C/C++
+ * Specification: glx
+ * Extensions: 0
+ *
+ * APIs:
+ * - glx=1.4
+ *
+ * Options:
+ * - ALIAS = False
+ * - DEBUG = False
+ * - HEADER_ONLY = False
+ * - LOADER = True
+ * - MX = False
+ * - ON_DEMAND = False
+ *
+ * Commandline:
+ * --api='glx=1.4' --extensions='' c --loader
+ *
+ * Online:
+ * http://glad.sh/#api=glx%3D1.4&extensions=&generator=c&options=LOADER
+ *
+ */
+
+#ifndef GLAD_GLX_H_
+#define GLAD_GLX_H_
+
+#ifdef GLX_H
+ #error GLX header already included (API: glx), remove previous include!
+#endif
+#define GLX_H 1
+
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <glad/gl.h>
+
+#define GLAD_GLX
+#define GLAD_OPTION_GLX_LOADER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef GLAD_PLATFORM_H_
+#define GLAD_PLATFORM_H_
+
+#ifndef GLAD_PLATFORM_WIN32
+ #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)
+ #define GLAD_PLATFORM_WIN32 1
+ #else
+ #define GLAD_PLATFORM_WIN32 0
+ #endif
+#endif
+
+#ifndef GLAD_PLATFORM_APPLE
+ #ifdef __APPLE__
+ #define GLAD_PLATFORM_APPLE 1
+ #else
+ #define GLAD_PLATFORM_APPLE 0
+ #endif
+#endif
+
+#ifndef GLAD_PLATFORM_EMSCRIPTEN
+ #ifdef __EMSCRIPTEN__
+ #define GLAD_PLATFORM_EMSCRIPTEN 1
+ #else
+ #define GLAD_PLATFORM_EMSCRIPTEN 0
+ #endif
+#endif
+
+#ifndef GLAD_PLATFORM_UWP
+ #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY)
+ #ifdef __has_include
+ #if __has_include(<winapifamily.h>)
+ #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1
+ #endif
+ #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_
+ #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1
+ #endif
+ #endif
+
+ #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY
+ #include <winapifamily.h>
+ #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
+ #define GLAD_PLATFORM_UWP 1
+ #endif
+ #endif
+
+ #ifndef GLAD_PLATFORM_UWP
+ #define GLAD_PLATFORM_UWP 0
+ #endif
+#endif
+
+#ifdef __GNUC__
+ #define GLAD_GNUC_EXTENSION __extension__
+#else
+ #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__)
+ #if defined(GLAD_API_CALL_EXPORT_BUILD)
+ #if defined(__GNUC__)
+ #define GLAD_API_CALL __attribute__ ((dllexport)) extern
+ #else
+ #define GLAD_API_CALL __declspec(dllexport) extern
+ #endif
+ #else
+ #if defined(__GNUC__)
+ #define GLAD_API_CALL __attribute__ ((dllimport)) extern
+ #else
+ #define GLAD_API_CALL __declspec(dllimport) extern
+ #endif
+ #endif
+ #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD)
+ #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern
+ #else
+ #define GLAD_API_CALL extern
+ #endif
+ #else
+ #define GLAD_API_CALL extern
+ #endif
+#endif
+
+#ifdef APIENTRY
+ #define GLAD_API_PTR APIENTRY
+#elif GLAD_PLATFORM_WIN32
+ #define GLAD_API_PTR __stdcall
+#else
+ #define GLAD_API_PTR
+#endif
+
+#ifndef GLAPI
+#define GLAPI GLAD_API_CALL
+#endif
+
+#ifndef GLAPIENTRY
+#define GLAPIENTRY GLAD_API_PTR
+#endif
+
+#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor)
+#define GLAD_VERSION_MAJOR(version) (version / 10000)
+#define GLAD_VERSION_MINOR(version) (version % 10000)
+
+#define GLAD_GENERATOR_VERSION "2.0.8"
+
+typedef void (*GLADapiproc)(void);
+
+typedef GLADapiproc (*GLADloadfunc)(const char *name);
+typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name);
+
+typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...);
+typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...);
+
+#endif /* GLAD_PLATFORM_H_ */
+
+#define GLX_ACCUM_ALPHA_SIZE 17
+#define GLX_ACCUM_BLUE_SIZE 16
+#define GLX_ACCUM_BUFFER_BIT 0x00000080
+#define GLX_ACCUM_GREEN_SIZE 15
+#define GLX_ACCUM_RED_SIZE 14
+#define GLX_ALPHA_SIZE 11
+#define GLX_AUX_BUFFERS 7
+#define GLX_AUX_BUFFERS_BIT 0x00000010
+#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
+#define GLX_BAD_ATTRIBUTE 2
+#define GLX_BAD_CONTEXT 5
+#define GLX_BAD_ENUM 7
+#define GLX_BAD_SCREEN 1
+#define GLX_BAD_VALUE 6
+#define GLX_BAD_VISUAL 4
+#define GLX_BLUE_SIZE 10
+#define GLX_BUFFER_SIZE 2
+#define GLX_BufferSwapComplete 1
+#define GLX_COLOR_INDEX_BIT 0x00000002
+#define GLX_COLOR_INDEX_TYPE 0x8015
+#define GLX_CONFIG_CAVEAT 0x20
+#define GLX_DAMAGED 0x8020
+#define GLX_DEPTH_BUFFER_BIT 0x00000020
+#define GLX_DEPTH_SIZE 12
+#define GLX_DIRECT_COLOR 0x8003
+#define GLX_DONT_CARE 0xFFFFFFFF
+#define GLX_DOUBLEBUFFER 5
+#define GLX_DRAWABLE_TYPE 0x8010
+#define GLX_EVENT_MASK 0x801F
+#define GLX_EXTENSIONS 0x3
+#define GLX_EXTENSION_NAME "GLX"
+#define GLX_FBCONFIG_ID 0x8013
+#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
+#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
+#define GLX_GRAY_SCALE 0x8006
+#define GLX_GREEN_SIZE 9
+#define GLX_HEIGHT 0x801E
+#define GLX_LARGEST_PBUFFER 0x801C
+#define GLX_LEVEL 3
+#define GLX_MAX_PBUFFER_HEIGHT 0x8017
+#define GLX_MAX_PBUFFER_PIXELS 0x8018
+#define GLX_MAX_PBUFFER_WIDTH 0x8016
+#define GLX_NONE 0x8000
+#define GLX_NON_CONFORMANT_CONFIG 0x800D
+#define GLX_NO_EXTENSION 3
+#define GLX_PBUFFER 0x8023
+#define GLX_PBUFFER_BIT 0x00000004
+#define GLX_PBUFFER_CLOBBER_MASK 0x08000000
+#define GLX_PBUFFER_HEIGHT 0x8040
+#define GLX_PBUFFER_WIDTH 0x8041
+#define GLX_PIXMAP_BIT 0x00000002
+#define GLX_PRESERVED_CONTENTS 0x801B
+#define GLX_PSEUDO_COLOR 0x8004
+#define GLX_PbufferClobber 0
+#define GLX_RED_SIZE 8
+#define GLX_RENDER_TYPE 0x8011
+#define GLX_RGBA 4
+#define GLX_RGBA_BIT 0x00000001
+#define GLX_RGBA_TYPE 0x8014
+#define GLX_SAMPLES 100001
+#define GLX_SAMPLE_BUFFERS 100000
+#define GLX_SAVED 0x8021
+#define GLX_SCREEN 0x800C
+#define GLX_SLOW_CONFIG 0x8001
+#define GLX_STATIC_COLOR 0x8005
+#define GLX_STATIC_GRAY 0x8007
+#define GLX_STENCIL_BUFFER_BIT 0x00000040
+#define GLX_STENCIL_SIZE 13
+#define GLX_STEREO 6
+#define GLX_TRANSPARENT_ALPHA_VALUE 0x28
+#define GLX_TRANSPARENT_BLUE_VALUE 0x27
+#define GLX_TRANSPARENT_GREEN_VALUE 0x26
+#define GLX_TRANSPARENT_INDEX 0x8009
+#define GLX_TRANSPARENT_INDEX_VALUE 0x24
+#define GLX_TRANSPARENT_RED_VALUE 0x25
+#define GLX_TRANSPARENT_RGB 0x8008
+#define GLX_TRANSPARENT_TYPE 0x23
+#define GLX_TRUE_COLOR 0x8002
+#define GLX_USE_GL 1
+#define GLX_VENDOR 0x1
+#define GLX_VERSION 0x2
+#define GLX_VISUAL_ID 0x800B
+#define GLX_WIDTH 0x801D
+#define GLX_WINDOW 0x8022
+#define GLX_WINDOW_BIT 0x00000001
+#define GLX_X_RENDERABLE 0x8012
+#define GLX_X_VISUAL_TYPE 0x22
+#define __GLX_NUMBER_EVENTS 17
+
+
+#ifndef GLEXT_64_TYPES_DEFINED
+/* This code block is duplicated in glext.h, so must be protected */
+#define GLEXT_64_TYPES_DEFINED
+/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
+/* (as used in the GLX_OML_sync_control extension). */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+#elif defined(__sun__) || defined(__digital__)
+#include <inttypes.h>
+#if defined(__STDC__)
+#if defined(__arch64__) || defined(_LP64)
+typedef long int int64_t;
+typedef unsigned long int uint64_t;
+#else
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#endif /* __arch64__ */
+#endif /* __STDC__ */
+#elif defined( __VMS ) || defined(__sgi)
+#include <inttypes.h>
+#elif defined(__SCO__) || defined(__USLC__)
+#include <stdint.h>
+#elif defined(__UNIXOS2__) || defined(__SOL64__)
+typedef long int int32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#elif defined(_WIN32) && defined(__GNUC__)
+#include <stdint.h>
+#elif defined(_WIN32)
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+/* Fallback if nothing above works */
+#include <inttypes.h>
+#endif
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
+
+#else
+
+#endif
+
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
+
+#else
+
+#endif
+
+
+
+
+
+
+
+typedef XID GLXFBConfigID;
+typedef struct __GLXFBConfigRec *GLXFBConfig;
+typedef XID GLXContextID;
+typedef struct __GLXcontextRec *GLXContext;
+typedef XID GLXPixmap;
+typedef XID GLXDrawable;
+typedef XID GLXWindow;
+typedef XID GLXPbuffer;
+typedef void (GLAD_API_PTR *__GLXextFuncPtr)(void);
+typedef XID GLXVideoCaptureDeviceNV;
+typedef unsigned int GLXVideoDeviceNV;
+typedef XID GLXVideoSourceSGIX;
+typedef XID GLXFBConfigIDSGIX;
+typedef struct __GLXFBConfigRec *GLXFBConfigSGIX;
+typedef XID GLXPbufferSGIX;
+typedef struct {
+ int event_type; /* GLX_DAMAGED or GLX_SAVED */
+ int draw_type; /* GLX_WINDOW or GLX_PBUFFER */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came for SendEvent request */
+ Display *display; /* display the event was read from */
+ GLXDrawable drawable; /* XID of Drawable */
+ unsigned int buffer_mask; /* mask indicating which buffers are affected */
+ unsigned int aux_buffer; /* which aux buffer was affected */
+ int x, y;
+ int width, height;
+ int count; /* if nonzero, at least this many more */
+} GLXPbufferClobberEvent;
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ GLXDrawable drawable; /* drawable on which event was requested in event mask */
+ int event_type;
+ int64_t ust;
+ int64_t msc;
+ int64_t sbc;
+} GLXBufferSwapComplete;
+typedef union __GLXEvent {
+ GLXPbufferClobberEvent glxpbufferclobber;
+ GLXBufferSwapComplete glxbufferswapcomplete;
+ long pad[24];
+} GLXEvent;
+typedef struct {
+ int type;
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ int extension;
+ int evtype;
+ GLXDrawable window;
+ Bool stereo_tree;
+} GLXStereoNotifyEventEXT;
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came for SendEvent request */
+ Display *display; /* display the event was read from */
+ GLXDrawable drawable; /* i.d. of Drawable */
+ int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */
+ int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */
+ unsigned int mask; /* mask indicating which buffers are affected*/
+ int x, y;
+ int width, height;
+ int count; /* if nonzero, at least this many more */
+} GLXBufferClobberEventSGIX;
+typedef struct {
+ char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
+ int networkId;
+} GLXHyperpipeNetworkSGIX;
+typedef struct {
+ char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
+ int channel;
+ unsigned int participationType;
+ int timeSlice;
+} GLXHyperpipeConfigSGIX;
+typedef struct {
+ char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
+ int srcXOrigin, srcYOrigin, srcWidth, srcHeight;
+ int destXOrigin, destYOrigin, destWidth, destHeight;
+} GLXPipeRect;
+typedef struct {
+ char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
+ int XOrigin, YOrigin, maxHeight, maxWidth;
+} GLXPipeRectLimits;
+
+
+#define GLX_VERSION_1_0 1
+GLAD_API_CALL int GLAD_GLX_VERSION_1_0;
+#define GLX_VERSION_1_1 1
+GLAD_API_CALL int GLAD_GLX_VERSION_1_1;
+#define GLX_VERSION_1_2 1
+GLAD_API_CALL int GLAD_GLX_VERSION_1_2;
+#define GLX_VERSION_1_3 1
+GLAD_API_CALL int GLAD_GLX_VERSION_1_3;
+#define GLX_VERSION_1_4 1
+GLAD_API_CALL int GLAD_GLX_VERSION_1_4;
+
+
+typedef GLXFBConfig * (GLAD_API_PTR *PFNGLXCHOOSEFBCONFIGPROC)(Display * dpy, int screen, const int * attrib_list, int * nelements);
+typedef XVisualInfo * (GLAD_API_PTR *PFNGLXCHOOSEVISUALPROC)(Display * dpy, int screen, int * attribList);
+typedef void (GLAD_API_PTR *PFNGLXCOPYCONTEXTPROC)(Display * dpy, GLXContext src, GLXContext dst, unsigned long mask);
+typedef GLXContext (GLAD_API_PTR *PFNGLXCREATECONTEXTPROC)(Display * dpy, XVisualInfo * vis, GLXContext shareList, Bool direct);
+typedef GLXPixmap (GLAD_API_PTR *PFNGLXCREATEGLXPIXMAPPROC)(Display * dpy, XVisualInfo * visual, Pixmap pixmap);
+typedef GLXContext (GLAD_API_PTR *PFNGLXCREATENEWCONTEXTPROC)(Display * dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+typedef GLXPbuffer (GLAD_API_PTR *PFNGLXCREATEPBUFFERPROC)(Display * dpy, GLXFBConfig config, const int * attrib_list);
+typedef GLXPixmap (GLAD_API_PTR *PFNGLXCREATEPIXMAPPROC)(Display * dpy, GLXFBConfig config, Pixmap pixmap, const int * attrib_list);
+typedef GLXWindow (GLAD_API_PTR *PFNGLXCREATEWINDOWPROC)(Display * dpy, GLXFBConfig config, Window win, const int * attrib_list);
+typedef void (GLAD_API_PTR *PFNGLXDESTROYCONTEXTPROC)(Display * dpy, GLXContext ctx);
+typedef void (GLAD_API_PTR *PFNGLXDESTROYGLXPIXMAPPROC)(Display * dpy, GLXPixmap pixmap);
+typedef void (GLAD_API_PTR *PFNGLXDESTROYPBUFFERPROC)(Display * dpy, GLXPbuffer pbuf);
+typedef void (GLAD_API_PTR *PFNGLXDESTROYPIXMAPPROC)(Display * dpy, GLXPixmap pixmap);
+typedef void (GLAD_API_PTR *PFNGLXDESTROYWINDOWPROC)(Display * dpy, GLXWindow win);
+typedef const char * (GLAD_API_PTR *PFNGLXGETCLIENTSTRINGPROC)(Display * dpy, int name);
+typedef int (GLAD_API_PTR *PFNGLXGETCONFIGPROC)(Display * dpy, XVisualInfo * visual, int attrib, int * value);
+typedef GLXContext (GLAD_API_PTR *PFNGLXGETCURRENTCONTEXTPROC)(void);
+typedef Display * (GLAD_API_PTR *PFNGLXGETCURRENTDISPLAYPROC)(void);
+typedef GLXDrawable (GLAD_API_PTR *PFNGLXGETCURRENTDRAWABLEPROC)(void);
+typedef GLXDrawable (GLAD_API_PTR *PFNGLXGETCURRENTREADDRAWABLEPROC)(void);
+typedef int (GLAD_API_PTR *PFNGLXGETFBCONFIGATTRIBPROC)(Display * dpy, GLXFBConfig config, int attribute, int * value);
+typedef GLXFBConfig * (GLAD_API_PTR *PFNGLXGETFBCONFIGSPROC)(Display * dpy, int screen, int * nelements);
+typedef __GLXextFuncPtr (GLAD_API_PTR *PFNGLXGETPROCADDRESSPROC)(const GLubyte * procName);
+typedef void (GLAD_API_PTR *PFNGLXGETSELECTEDEVENTPROC)(Display * dpy, GLXDrawable draw, unsigned long * event_mask);
+typedef XVisualInfo * (GLAD_API_PTR *PFNGLXGETVISUALFROMFBCONFIGPROC)(Display * dpy, GLXFBConfig config);
+typedef Bool (GLAD_API_PTR *PFNGLXISDIRECTPROC)(Display * dpy, GLXContext ctx);
+typedef Bool (GLAD_API_PTR *PFNGLXMAKECONTEXTCURRENTPROC)(Display * dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+typedef Bool (GLAD_API_PTR *PFNGLXMAKECURRENTPROC)(Display * dpy, GLXDrawable drawable, GLXContext ctx);
+typedef int (GLAD_API_PTR *PFNGLXQUERYCONTEXTPROC)(Display * dpy, GLXContext ctx, int attribute, int * value);
+typedef void (GLAD_API_PTR *PFNGLXQUERYDRAWABLEPROC)(Display * dpy, GLXDrawable draw, int attribute, unsigned int * value);
+typedef Bool (GLAD_API_PTR *PFNGLXQUERYEXTENSIONPROC)(Display * dpy, int * errorb, int * event);
+typedef const char * (GLAD_API_PTR *PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display * dpy, int screen);
+typedef const char * (GLAD_API_PTR *PFNGLXQUERYSERVERSTRINGPROC)(Display * dpy, int screen, int name);
+typedef Bool (GLAD_API_PTR *PFNGLXQUERYVERSIONPROC)(Display * dpy, int * maj, int * min);
+typedef void (GLAD_API_PTR *PFNGLXSELECTEVENTPROC)(Display * dpy, GLXDrawable draw, unsigned long event_mask);
+typedef void (GLAD_API_PTR *PFNGLXSWAPBUFFERSPROC)(Display * dpy, GLXDrawable drawable);
+typedef void (GLAD_API_PTR *PFNGLXUSEXFONTPROC)(Font font, int first, int count, int list);
+typedef void (GLAD_API_PTR *PFNGLXWAITGLPROC)(void);
+typedef void (GLAD_API_PTR *PFNGLXWAITXPROC)(void);
+
+GLAD_API_CALL PFNGLXCHOOSEFBCONFIGPROC glad_glXChooseFBConfig;
+#define glXChooseFBConfig glad_glXChooseFBConfig
+GLAD_API_CALL PFNGLXCHOOSEVISUALPROC glad_glXChooseVisual;
+#define glXChooseVisual glad_glXChooseVisual
+GLAD_API_CALL PFNGLXCOPYCONTEXTPROC glad_glXCopyContext;
+#define glXCopyContext glad_glXCopyContext
+GLAD_API_CALL PFNGLXCREATECONTEXTPROC glad_glXCreateContext;
+#define glXCreateContext glad_glXCreateContext
+GLAD_API_CALL PFNGLXCREATEGLXPIXMAPPROC glad_glXCreateGLXPixmap;
+#define glXCreateGLXPixmap glad_glXCreateGLXPixmap
+GLAD_API_CALL PFNGLXCREATENEWCONTEXTPROC glad_glXCreateNewContext;
+#define glXCreateNewContext glad_glXCreateNewContext
+GLAD_API_CALL PFNGLXCREATEPBUFFERPROC glad_glXCreatePbuffer;
+#define glXCreatePbuffer glad_glXCreatePbuffer
+GLAD_API_CALL PFNGLXCREATEPIXMAPPROC glad_glXCreatePixmap;
+#define glXCreatePixmap glad_glXCreatePixmap
+GLAD_API_CALL PFNGLXCREATEWINDOWPROC glad_glXCreateWindow;
+#define glXCreateWindow glad_glXCreateWindow
+GLAD_API_CALL PFNGLXDESTROYCONTEXTPROC glad_glXDestroyContext;
+#define glXDestroyContext glad_glXDestroyContext
+GLAD_API_CALL PFNGLXDESTROYGLXPIXMAPPROC glad_glXDestroyGLXPixmap;
+#define glXDestroyGLXPixmap glad_glXDestroyGLXPixmap
+GLAD_API_CALL PFNGLXDESTROYPBUFFERPROC glad_glXDestroyPbuffer;
+#define glXDestroyPbuffer glad_glXDestroyPbuffer
+GLAD_API_CALL PFNGLXDESTROYPIXMAPPROC glad_glXDestroyPixmap;
+#define glXDestroyPixmap glad_glXDestroyPixmap
+GLAD_API_CALL PFNGLXDESTROYWINDOWPROC glad_glXDestroyWindow;
+#define glXDestroyWindow glad_glXDestroyWindow
+GLAD_API_CALL PFNGLXGETCLIENTSTRINGPROC glad_glXGetClientString;
+#define glXGetClientString glad_glXGetClientString
+GLAD_API_CALL PFNGLXGETCONFIGPROC glad_glXGetConfig;
+#define glXGetConfig glad_glXGetConfig
+GLAD_API_CALL PFNGLXGETCURRENTCONTEXTPROC glad_glXGetCurrentContext;
+#define glXGetCurrentContext glad_glXGetCurrentContext
+GLAD_API_CALL PFNGLXGETCURRENTDISPLAYPROC glad_glXGetCurrentDisplay;
+#define glXGetCurrentDisplay glad_glXGetCurrentDisplay
+GLAD_API_CALL PFNGLXGETCURRENTDRAWABLEPROC glad_glXGetCurrentDrawable;
+#define glXGetCurrentDrawable glad_glXGetCurrentDrawable
+GLAD_API_CALL PFNGLXGETCURRENTREADDRAWABLEPROC glad_glXGetCurrentReadDrawable;
+#define glXGetCurrentReadDrawable glad_glXGetCurrentReadDrawable
+GLAD_API_CALL PFNGLXGETFBCONFIGATTRIBPROC glad_glXGetFBConfigAttrib;
+#define glXGetFBConfigAttrib glad_glXGetFBConfigAttrib
+GLAD_API_CALL PFNGLXGETFBCONFIGSPROC glad_glXGetFBConfigs;
+#define glXGetFBConfigs glad_glXGetFBConfigs
+GLAD_API_CALL PFNGLXGETPROCADDRESSPROC glad_glXGetProcAddress;
+#define glXGetProcAddress glad_glXGetProcAddress
+GLAD_API_CALL PFNGLXGETSELECTEDEVENTPROC glad_glXGetSelectedEvent;
+#define glXGetSelectedEvent glad_glXGetSelectedEvent
+GLAD_API_CALL PFNGLXGETVISUALFROMFBCONFIGPROC glad_glXGetVisualFromFBConfig;
+#define glXGetVisualFromFBConfig glad_glXGetVisualFromFBConfig
+GLAD_API_CALL PFNGLXISDIRECTPROC glad_glXIsDirect;
+#define glXIsDirect glad_glXIsDirect
+GLAD_API_CALL PFNGLXMAKECONTEXTCURRENTPROC glad_glXMakeContextCurrent;
+#define glXMakeContextCurrent glad_glXMakeContextCurrent
+GLAD_API_CALL PFNGLXMAKECURRENTPROC glad_glXMakeCurrent;
+#define glXMakeCurrent glad_glXMakeCurrent
+GLAD_API_CALL PFNGLXQUERYCONTEXTPROC glad_glXQueryContext;
+#define glXQueryContext glad_glXQueryContext
+GLAD_API_CALL PFNGLXQUERYDRAWABLEPROC glad_glXQueryDrawable;
+#define glXQueryDrawable glad_glXQueryDrawable
+GLAD_API_CALL PFNGLXQUERYEXTENSIONPROC glad_glXQueryExtension;
+#define glXQueryExtension glad_glXQueryExtension
+GLAD_API_CALL PFNGLXQUERYEXTENSIONSSTRINGPROC glad_glXQueryExtensionsString;
+#define glXQueryExtensionsString glad_glXQueryExtensionsString
+GLAD_API_CALL PFNGLXQUERYSERVERSTRINGPROC glad_glXQueryServerString;
+#define glXQueryServerString glad_glXQueryServerString
+GLAD_API_CALL PFNGLXQUERYVERSIONPROC glad_glXQueryVersion;
+#define glXQueryVersion glad_glXQueryVersion
+GLAD_API_CALL PFNGLXSELECTEVENTPROC glad_glXSelectEvent;
+#define glXSelectEvent glad_glXSelectEvent
+GLAD_API_CALL PFNGLXSWAPBUFFERSPROC glad_glXSwapBuffers;
+#define glXSwapBuffers glad_glXSwapBuffers
+GLAD_API_CALL PFNGLXUSEXFONTPROC glad_glXUseXFont;
+#define glXUseXFont glad_glXUseXFont
+GLAD_API_CALL PFNGLXWAITGLPROC glad_glXWaitGL;
+#define glXWaitGL glad_glXWaitGL
+GLAD_API_CALL PFNGLXWAITXPROC glad_glXWaitX;
+#define glXWaitX glad_glXWaitX
+
+
+
+
+
+GLAD_API_CALL int gladLoadGLXUserPtr(Display *display, int screen, GLADuserptrloadfunc load, void *userptr);
+GLAD_API_CALL int gladLoadGLX(Display *display, int screen, GLADloadfunc load);
+
+#ifdef GLAD_GLX
+
+GLAD_API_CALL int gladLoaderLoadGLX(Display *display, int screen);
+
+GLAD_API_CALL void gladLoaderUnloadGLX(void);
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/mons_3d/external/glad/src/gl.c b/mons_3d/external/glad/src/gl.c
new file mode 100644
index 0000000..3a09be6
--- /dev/null
+++ b/mons_3d/external/glad/src/gl.c
@@ -0,0 +1,1786 @@
+/**
+ * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glad/gl.h>
+
+#ifndef GLAD_IMPL_UTIL_C_
+#define GLAD_IMPL_UTIL_C_
+
+#ifdef _MSC_VER
+#define GLAD_IMPL_UTIL_SSCANF sscanf_s
+#else
+#define GLAD_IMPL_UTIL_SSCANF sscanf
+#endif
+
+#endif /* GLAD_IMPL_UTIL_C_ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+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;
+int GLAD_GL_VERSION_4_0 = 0;
+int GLAD_GL_VERSION_4_1 = 0;
+int GLAD_GL_VERSION_4_2 = 0;
+int GLAD_GL_VERSION_4_3 = 0;
+int GLAD_GL_VERSION_4_4 = 0;
+int GLAD_GL_VERSION_4_5 = 0;
+int GLAD_GL_VERSION_4_6 = 0;
+
+
+
+PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram = NULL;
+PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL;
+PFNGLATTACHSHADERPROC glad_glAttachShader = NULL;
+PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL;
+PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL;
+PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed = NULL;
+PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL;
+PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL;
+PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL;
+PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL;
+PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL;
+PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase = NULL;
+PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange = NULL;
+PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL;
+PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL;
+PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL;
+PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture = NULL;
+PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures = NULL;
+PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline = NULL;
+PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL;
+PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL;
+PFNGLBINDSAMPLERSPROC glad_glBindSamplers = NULL;
+PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL;
+PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit = NULL;
+PFNGLBINDTEXTURESPROC glad_glBindTextures = NULL;
+PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL;
+PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL;
+PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer = NULL;
+PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers = NULL;
+PFNGLBLENDCOLORPROC glad_glBlendColor = NULL;
+PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL;
+PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL;
+PFNGLBLENDEQUATIONSEPARATEIPROC glad_glBlendEquationSeparatei = NULL;
+PFNGLBLENDEQUATIONIPROC glad_glBlendEquationi = NULL;
+PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL;
+PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL;
+PFNGLBLENDFUNCSEPARATEIPROC glad_glBlendFuncSeparatei = NULL;
+PFNGLBLENDFUNCIPROC glad_glBlendFunci = NULL;
+PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL;
+PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer = NULL;
+PFNGLBUFFERDATAPROC glad_glBufferData = NULL;
+PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL;
+PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL;
+PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL;
+PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus = NULL;
+PFNGLCLAMPCOLORPROC glad_glClampColor = NULL;
+PFNGLCLEARPROC glad_glClear = NULL;
+PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData = NULL;
+PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData = 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;
+PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL;
+PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData = NULL;
+PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv = NULL;
+PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL;
+PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage = NULL;
+PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage = NULL;
+PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL;
+PFNGLCLIPCONTROLPROC glad_glClipControl = 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;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D = NULL;
+PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL;
+PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData = NULL;
+PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData = NULL;
+PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL;
+PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL;
+PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL;
+PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL;
+PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D = NULL;
+PFNGLCREATEBUFFERSPROC glad_glCreateBuffers = NULL;
+PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers = NULL;
+PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL;
+PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines = NULL;
+PFNGLCREATEQUERIESPROC glad_glCreateQueries = NULL;
+PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers = NULL;
+PFNGLCREATESAMPLERSPROC glad_glCreateSamplers = NULL;
+PFNGLCREATESHADERPROC glad_glCreateShader = NULL;
+PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv = NULL;
+PFNGLCREATETEXTURESPROC glad_glCreateTextures = NULL;
+PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks = NULL;
+PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays = NULL;
+PFNGLCULLFACEPROC glad_glCullFace = NULL;
+PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback = NULL;
+PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl = NULL;
+PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert = NULL;
+PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL;
+PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL;
+PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL;
+PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines = 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;
+PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL;
+PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL;
+PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL;
+PFNGLDEPTHMASKPROC glad_glDepthMask = NULL;
+PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL;
+PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL;
+PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL;
+PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL;
+PFNGLDETACHSHADERPROC glad_glDetachShader = NULL;
+PFNGLDISABLEPROC glad_glDisable = NULL;
+PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib = NULL;
+PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL;
+PFNGLDISABLEIPROC glad_glDisablei = NULL;
+PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute = NULL;
+PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect = NULL;
+PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL;
+PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL;
+PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL;
+PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance = NULL;
+PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL;
+PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL;
+PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL;
+PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL;
+PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect = NULL;
+PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL;
+PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL;
+PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced = NULL;
+PFNGLENABLEPROC glad_glEnable = NULL;
+PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib = NULL;
+PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL;
+PFNGLENABLEIPROC glad_glEnablei = NULL;
+PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL;
+PFNGLENDQUERYPROC glad_glEndQuery = NULL;
+PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed = NULL;
+PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL;
+PFNGLFENCESYNCPROC glad_glFenceSync = NULL;
+PFNGLFINISHPROC glad_glFinish = NULL;
+PFNGLFLUSHPROC glad_glFlush = NULL;
+PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL;
+PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange = NULL;
+PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri = 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;
+PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines = NULL;
+PFNGLGENQUERIESPROC glad_glGenQueries = NULL;
+PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL;
+PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL;
+PFNGLGENTEXTURESPROC glad_glGenTextures = NULL;
+PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL;
+PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL;
+PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL;
+PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap = NULL;
+PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv = NULL;
+PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL;
+PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName = NULL;
+PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName = NULL;
+PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv = 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;
+PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage = NULL;
+PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage = NULL;
+PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog = NULL;
+PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v = NULL;
+PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL;
+PFNGLGETERRORPROC glad_glGetError = NULL;
+PFNGLGETFLOATI_VPROC glad_glGetFloati_v = NULL;
+PFNGLGETFLOATVPROC glad_glGetFloatv = NULL;
+PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL;
+PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL;
+PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL;
+PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv = NULL;
+PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus = NULL;
+PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL;
+PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL;
+PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL;
+PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL;
+PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v = NULL;
+PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL;
+PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv = NULL;
+PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv = NULL;
+PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData = NULL;
+PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv = NULL;
+PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv = NULL;
+PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv = NULL;
+PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel = NULL;
+PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel = NULL;
+PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL;
+PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL;
+PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL;
+PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = NULL;
+PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog = NULL;
+PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv = NULL;
+PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex = NULL;
+PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation = NULL;
+PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex = NULL;
+PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName = NULL;
+PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv = NULL;
+PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv = NULL;
+PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL;
+PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v = NULL;
+PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv = NULL;
+PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v = NULL;
+PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv = NULL;
+PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv = 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;
+PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL;
+PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL;
+PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL;
+PFNGLGETSTRINGPROC glad_glGetString = NULL;
+PFNGLGETSTRINGIPROC glad_glGetStringi = NULL;
+PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex = NULL;
+PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation = 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;
+PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage = NULL;
+PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv = NULL;
+PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv = NULL;
+PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv = NULL;
+PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv = NULL;
+PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv = NULL;
+PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv = NULL;
+PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage = NULL;
+PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL;
+PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v = NULL;
+PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v = NULL;
+PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv = NULL;
+PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL;
+PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL;
+PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL;
+PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv = NULL;
+PFNGLGETUNIFORMDVPROC glad_glGetUniformdv = NULL;
+PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL;
+PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL;
+PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL;
+PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv = NULL;
+PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv = NULL;
+PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv = NULL;
+PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL;
+PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL;
+PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv = NULL;
+PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL;
+PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL;
+PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL;
+PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL;
+PFNGLGETNCOMPRESSEDTEXIMAGEPROC glad_glGetnCompressedTexImage = NULL;
+PFNGLGETNTEXIMAGEPROC glad_glGetnTexImage = NULL;
+PFNGLGETNUNIFORMDVPROC glad_glGetnUniformdv = NULL;
+PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv = NULL;
+PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv = NULL;
+PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv = NULL;
+PFNGLHINTPROC glad_glHint = NULL;
+PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData = NULL;
+PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData = NULL;
+PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL;
+PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData = NULL;
+PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData = NULL;
+PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL;
+PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage = NULL;
+PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage = NULL;
+PFNGLISBUFFERPROC glad_glIsBuffer = NULL;
+PFNGLISENABLEDPROC glad_glIsEnabled = NULL;
+PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL;
+PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL;
+PFNGLISPROGRAMPROC glad_glIsProgram = NULL;
+PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline = 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;
+PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = 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;
+PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer = NULL;
+PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange = NULL;
+PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier = NULL;
+PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion = NULL;
+PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading = NULL;
+PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL;
+PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect = NULL;
+PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glad_glMultiDrawArraysIndirectCount = NULL;
+PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL;
+PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glad_glMultiDrawElementsIndirectCount = NULL;
+PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData = NULL;
+PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage = NULL;
+PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData = NULL;
+PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer = NULL;
+PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers = NULL;
+PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri = NULL;
+PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer = NULL;
+PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample = NULL;
+PFNGLOBJECTLABELPROC glad_glObjectLabel = NULL;
+PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel = NULL;
+PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv = NULL;
+PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri = NULL;
+PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = 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;
+PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp = NULL;
+PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup = NULL;
+PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL;
+PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL;
+PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL;
+PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d = NULL;
+PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv = NULL;
+PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f = NULL;
+PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv = NULL;
+PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i = NULL;
+PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv = NULL;
+PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui = NULL;
+PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv = NULL;
+PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d = NULL;
+PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv = NULL;
+PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f = NULL;
+PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv = NULL;
+PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i = NULL;
+PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv = NULL;
+PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui = NULL;
+PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv = NULL;
+PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d = NULL;
+PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv = NULL;
+PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f = NULL;
+PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv = NULL;
+PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i = NULL;
+PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv = NULL;
+PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui = NULL;
+PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv = NULL;
+PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d = NULL;
+PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv = NULL;
+PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f = NULL;
+PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv = NULL;
+PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i = NULL;
+PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv = NULL;
+PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui = NULL;
+PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv = NULL;
+PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL;
+PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup = NULL;
+PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL;
+PFNGLREADBUFFERPROC glad_glReadBuffer = NULL;
+PFNGLREADPIXELSPROC glad_glReadPixels = NULL;
+PFNGLREADNPIXELSPROC glad_glReadnPixels = NULL;
+PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL;
+PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL;
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL;
+PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = 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;
+PFNGLSCISSORARRAYVPROC glad_glScissorArrayv = NULL;
+PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed = NULL;
+PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv = NULL;
+PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL;
+PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL;
+PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding = NULL;
+PFNGLSPECIALIZESHADERPROC glad_glSpecializeShader = 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;
+PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange = 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;
+PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D = NULL;
+PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL;
+PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample = NULL;
+PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL;
+PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample = NULL;
+PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL;
+PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL;
+PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL;
+PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier = NULL;
+PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer = NULL;
+PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange = NULL;
+PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv = NULL;
+PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv = NULL;
+PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf = NULL;
+PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv = NULL;
+PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri = NULL;
+PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv = NULL;
+PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D = NULL;
+PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D = NULL;
+PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample = NULL;
+PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D = NULL;
+PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample = NULL;
+PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D = NULL;
+PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D = NULL;
+PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D = NULL;
+PFNGLTEXTUREVIEWPROC glad_glTextureView = NULL;
+PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase = NULL;
+PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL;
+PFNGLUNIFORM1DPROC glad_glUniform1d = NULL;
+PFNGLUNIFORM1DVPROC glad_glUniform1dv = 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;
+PFNGLUNIFORM2DPROC glad_glUniform2d = NULL;
+PFNGLUNIFORM2DVPROC glad_glUniform2dv = 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;
+PFNGLUNIFORM3DPROC glad_glUniform3d = NULL;
+PFNGLUNIFORM3DVPROC glad_glUniform3dv = 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;
+PFNGLUNIFORM4DPROC glad_glUniform4d = NULL;
+PFNGLUNIFORM4DVPROC glad_glUniform4dv = 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;
+PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv = NULL;
+PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL;
+PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv = NULL;
+PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL;
+PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv = NULL;
+PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL;
+PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv = NULL;
+PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL;
+PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv = NULL;
+PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL;
+PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv = NULL;
+PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL;
+PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv = NULL;
+PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL;
+PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv = NULL;
+PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL;
+PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv = NULL;
+PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL;
+PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv = NULL;
+PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL;
+PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer = NULL;
+PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL;
+PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages = NULL;
+PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL;
+PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline = NULL;
+PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding = NULL;
+PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat = NULL;
+PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat = NULL;
+PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat = NULL;
+PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor = NULL;
+PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer = NULL;
+PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer = NULL;
+PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers = 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;
+PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding = NULL;
+PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL;
+PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat = 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;
+PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat = NULL;
+PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL;
+PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d = NULL;
+PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv = NULL;
+PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d = NULL;
+PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv = NULL;
+PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d = NULL;
+PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv = NULL;
+PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d = NULL;
+PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv = NULL;
+PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat = NULL;
+PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer = 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;
+PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor = NULL;
+PFNGLVIEWPORTPROC glad_glViewport = NULL;
+PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL;
+PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL;
+PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = 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_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_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv");
+ 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_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_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_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_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_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_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_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_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_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_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_4_0( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_0) return;
+ glad_glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC) load(userptr, "glBeginQueryIndexed");
+ glad_glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) load(userptr, "glBindTransformFeedback");
+ glad_glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC) load(userptr, "glBlendEquationSeparatei");
+ glad_glBlendEquationi = (PFNGLBLENDEQUATIONIPROC) load(userptr, "glBlendEquationi");
+ glad_glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC) load(userptr, "glBlendFuncSeparatei");
+ glad_glBlendFunci = (PFNGLBLENDFUNCIPROC) load(userptr, "glBlendFunci");
+ glad_glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) load(userptr, "glDeleteTransformFeedbacks");
+ glad_glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC) load(userptr, "glDrawArraysIndirect");
+ glad_glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC) load(userptr, "glDrawElementsIndirect");
+ glad_glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC) load(userptr, "glDrawTransformFeedback");
+ glad_glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) load(userptr, "glDrawTransformFeedbackStream");
+ glad_glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC) load(userptr, "glEndQueryIndexed");
+ glad_glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) load(userptr, "glGenTransformFeedbacks");
+ glad_glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC) load(userptr, "glGetActiveSubroutineName");
+ glad_glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) load(userptr, "glGetActiveSubroutineUniformName");
+ glad_glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) load(userptr, "glGetActiveSubroutineUniformiv");
+ glad_glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC) load(userptr, "glGetProgramStageiv");
+ glad_glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC) load(userptr, "glGetQueryIndexediv");
+ glad_glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC) load(userptr, "glGetSubroutineIndex");
+ glad_glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) load(userptr, "glGetSubroutineUniformLocation");
+ glad_glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC) load(userptr, "glGetUniformSubroutineuiv");
+ glad_glGetUniformdv = (PFNGLGETUNIFORMDVPROC) load(userptr, "glGetUniformdv");
+ glad_glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) load(userptr, "glIsTransformFeedback");
+ glad_glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC) load(userptr, "glMinSampleShading");
+ glad_glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC) load(userptr, "glPatchParameterfv");
+ glad_glPatchParameteri = (PFNGLPATCHPARAMETERIPROC) load(userptr, "glPatchParameteri");
+ glad_glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) load(userptr, "glPauseTransformFeedback");
+ glad_glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) load(userptr, "glResumeTransformFeedback");
+ glad_glUniform1d = (PFNGLUNIFORM1DPROC) load(userptr, "glUniform1d");
+ glad_glUniform1dv = (PFNGLUNIFORM1DVPROC) load(userptr, "glUniform1dv");
+ glad_glUniform2d = (PFNGLUNIFORM2DPROC) load(userptr, "glUniform2d");
+ glad_glUniform2dv = (PFNGLUNIFORM2DVPROC) load(userptr, "glUniform2dv");
+ glad_glUniform3d = (PFNGLUNIFORM3DPROC) load(userptr, "glUniform3d");
+ glad_glUniform3dv = (PFNGLUNIFORM3DVPROC) load(userptr, "glUniform3dv");
+ glad_glUniform4d = (PFNGLUNIFORM4DPROC) load(userptr, "glUniform4d");
+ glad_glUniform4dv = (PFNGLUNIFORM4DVPROC) load(userptr, "glUniform4dv");
+ glad_glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC) load(userptr, "glUniformMatrix2dv");
+ glad_glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC) load(userptr, "glUniformMatrix2x3dv");
+ glad_glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC) load(userptr, "glUniformMatrix2x4dv");
+ glad_glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC) load(userptr, "glUniformMatrix3dv");
+ glad_glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC) load(userptr, "glUniformMatrix3x2dv");
+ glad_glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC) load(userptr, "glUniformMatrix3x4dv");
+ glad_glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC) load(userptr, "glUniformMatrix4dv");
+ glad_glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC) load(userptr, "glUniformMatrix4x2dv");
+ glad_glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC) load(userptr, "glUniformMatrix4x3dv");
+ glad_glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC) load(userptr, "glUniformSubroutinesuiv");
+}
+static void glad_gl_load_GL_VERSION_4_1( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_1) return;
+ glad_glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC) load(userptr, "glActiveShaderProgram");
+ glad_glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC) load(userptr, "glBindProgramPipeline");
+ glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC) load(userptr, "glClearDepthf");
+ glad_glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC) load(userptr, "glCreateShaderProgramv");
+ glad_glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC) load(userptr, "glDeleteProgramPipelines");
+ glad_glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC) load(userptr, "glDepthRangeArrayv");
+ glad_glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC) load(userptr, "glDepthRangeIndexed");
+ glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC) load(userptr, "glDepthRangef");
+ glad_glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC) load(userptr, "glGenProgramPipelines");
+ glad_glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC) load(userptr, "glGetDoublei_v");
+ glad_glGetFloati_v = (PFNGLGETFLOATI_VPROC) load(userptr, "glGetFloati_v");
+ glad_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) load(userptr, "glGetProgramBinary");
+ glad_glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC) load(userptr, "glGetProgramPipelineInfoLog");
+ glad_glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC) load(userptr, "glGetProgramPipelineiv");
+ glad_glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load(userptr, "glGetShaderPrecisionFormat");
+ glad_glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC) load(userptr, "glGetVertexAttribLdv");
+ glad_glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC) load(userptr, "glIsProgramPipeline");
+ glad_glProgramBinary = (PFNGLPROGRAMBINARYPROC) load(userptr, "glProgramBinary");
+ glad_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) load(userptr, "glProgramParameteri");
+ glad_glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC) load(userptr, "glProgramUniform1d");
+ glad_glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC) load(userptr, "glProgramUniform1dv");
+ glad_glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC) load(userptr, "glProgramUniform1f");
+ glad_glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC) load(userptr, "glProgramUniform1fv");
+ glad_glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC) load(userptr, "glProgramUniform1i");
+ glad_glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC) load(userptr, "glProgramUniform1iv");
+ glad_glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC) load(userptr, "glProgramUniform1ui");
+ glad_glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC) load(userptr, "glProgramUniform1uiv");
+ glad_glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC) load(userptr, "glProgramUniform2d");
+ glad_glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC) load(userptr, "glProgramUniform2dv");
+ glad_glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC) load(userptr, "glProgramUniform2f");
+ glad_glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC) load(userptr, "glProgramUniform2fv");
+ glad_glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC) load(userptr, "glProgramUniform2i");
+ glad_glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC) load(userptr, "glProgramUniform2iv");
+ glad_glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC) load(userptr, "glProgramUniform2ui");
+ glad_glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC) load(userptr, "glProgramUniform2uiv");
+ glad_glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC) load(userptr, "glProgramUniform3d");
+ glad_glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC) load(userptr, "glProgramUniform3dv");
+ glad_glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC) load(userptr, "glProgramUniform3f");
+ glad_glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC) load(userptr, "glProgramUniform3fv");
+ glad_glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC) load(userptr, "glProgramUniform3i");
+ glad_glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC) load(userptr, "glProgramUniform3iv");
+ glad_glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC) load(userptr, "glProgramUniform3ui");
+ glad_glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC) load(userptr, "glProgramUniform3uiv");
+ glad_glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC) load(userptr, "glProgramUniform4d");
+ glad_glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC) load(userptr, "glProgramUniform4dv");
+ glad_glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC) load(userptr, "glProgramUniform4f");
+ glad_glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC) load(userptr, "glProgramUniform4fv");
+ glad_glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC) load(userptr, "glProgramUniform4i");
+ glad_glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC) load(userptr, "glProgramUniform4iv");
+ glad_glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC) load(userptr, "glProgramUniform4ui");
+ glad_glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC) load(userptr, "glProgramUniform4uiv");
+ glad_glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC) load(userptr, "glProgramUniformMatrix2dv");
+ glad_glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC) load(userptr, "glProgramUniformMatrix2fv");
+ glad_glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) load(userptr, "glProgramUniformMatrix2x3dv");
+ glad_glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) load(userptr, "glProgramUniformMatrix2x3fv");
+ glad_glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) load(userptr, "glProgramUniformMatrix2x4dv");
+ glad_glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) load(userptr, "glProgramUniformMatrix2x4fv");
+ glad_glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC) load(userptr, "glProgramUniformMatrix3dv");
+ glad_glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC) load(userptr, "glProgramUniformMatrix3fv");
+ glad_glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) load(userptr, "glProgramUniformMatrix3x2dv");
+ glad_glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) load(userptr, "glProgramUniformMatrix3x2fv");
+ glad_glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) load(userptr, "glProgramUniformMatrix3x4dv");
+ glad_glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) load(userptr, "glProgramUniformMatrix3x4fv");
+ glad_glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC) load(userptr, "glProgramUniformMatrix4dv");
+ glad_glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC) load(userptr, "glProgramUniformMatrix4fv");
+ glad_glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) load(userptr, "glProgramUniformMatrix4x2dv");
+ glad_glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) load(userptr, "glProgramUniformMatrix4x2fv");
+ glad_glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) load(userptr, "glProgramUniformMatrix4x3dv");
+ glad_glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) load(userptr, "glProgramUniformMatrix4x3fv");
+ glad_glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load(userptr, "glReleaseShaderCompiler");
+ glad_glScissorArrayv = (PFNGLSCISSORARRAYVPROC) load(userptr, "glScissorArrayv");
+ glad_glScissorIndexed = (PFNGLSCISSORINDEXEDPROC) load(userptr, "glScissorIndexed");
+ glad_glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC) load(userptr, "glScissorIndexedv");
+ glad_glShaderBinary = (PFNGLSHADERBINARYPROC) load(userptr, "glShaderBinary");
+ glad_glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC) load(userptr, "glUseProgramStages");
+ glad_glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC) load(userptr, "glValidateProgramPipeline");
+ glad_glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC) load(userptr, "glVertexAttribL1d");
+ glad_glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC) load(userptr, "glVertexAttribL1dv");
+ glad_glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC) load(userptr, "glVertexAttribL2d");
+ glad_glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC) load(userptr, "glVertexAttribL2dv");
+ glad_glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC) load(userptr, "glVertexAttribL3d");
+ glad_glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC) load(userptr, "glVertexAttribL3dv");
+ glad_glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC) load(userptr, "glVertexAttribL4d");
+ glad_glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC) load(userptr, "glVertexAttribL4dv");
+ glad_glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC) load(userptr, "glVertexAttribLPointer");
+ glad_glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC) load(userptr, "glViewportArrayv");
+ glad_glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC) load(userptr, "glViewportIndexedf");
+ glad_glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC) load(userptr, "glViewportIndexedfv");
+}
+static void glad_gl_load_GL_VERSION_4_2( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_2) return;
+ glad_glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) load(userptr, "glBindImageTexture");
+ glad_glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) load(userptr, "glDrawArraysInstancedBaseInstance");
+ glad_glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) load(userptr, "glDrawElementsInstancedBaseInstance");
+ glad_glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) load(userptr, "glDrawElementsInstancedBaseVertexBaseInstance");
+ glad_glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) load(userptr, "glDrawTransformFeedbackInstanced");
+ glad_glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) load(userptr, "glDrawTransformFeedbackStreamInstanced");
+ glad_glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) load(userptr, "glGetActiveAtomicCounterBufferiv");
+ glad_glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) load(userptr, "glGetInternalformativ");
+ glad_glMemoryBarrier = (PFNGLMEMORYBARRIERPROC) load(userptr, "glMemoryBarrier");
+ glad_glTexStorage1D = (PFNGLTEXSTORAGE1DPROC) load(userptr, "glTexStorage1D");
+ glad_glTexStorage2D = (PFNGLTEXSTORAGE2DPROC) load(userptr, "glTexStorage2D");
+ glad_glTexStorage3D = (PFNGLTEXSTORAGE3DPROC) load(userptr, "glTexStorage3D");
+}
+static void glad_gl_load_GL_VERSION_4_3( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_3) return;
+ glad_glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC) load(userptr, "glBindVertexBuffer");
+ glad_glClearBufferData = (PFNGLCLEARBUFFERDATAPROC) load(userptr, "glClearBufferData");
+ glad_glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC) load(userptr, "glClearBufferSubData");
+ glad_glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC) load(userptr, "glCopyImageSubData");
+ glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) load(userptr, "glDebugMessageCallback");
+ glad_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) load(userptr, "glDebugMessageControl");
+ glad_glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC) load(userptr, "glDebugMessageInsert");
+ glad_glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC) load(userptr, "glDispatchCompute");
+ glad_glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC) load(userptr, "glDispatchComputeIndirect");
+ glad_glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC) load(userptr, "glFramebufferParameteri");
+ glad_glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC) load(userptr, "glGetDebugMessageLog");
+ glad_glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetFramebufferParameteriv");
+ glad_glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC) load(userptr, "glGetInternalformati64v");
+ glad_glGetObjectLabel = (PFNGLGETOBJECTLABELPROC) load(userptr, "glGetObjectLabel");
+ glad_glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC) load(userptr, "glGetObjectPtrLabel");
+ glad_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv");
+ glad_glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC) load(userptr, "glGetProgramInterfaceiv");
+ glad_glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC) load(userptr, "glGetProgramResourceIndex");
+ glad_glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC) load(userptr, "glGetProgramResourceLocation");
+ glad_glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) load(userptr, "glGetProgramResourceLocationIndex");
+ glad_glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC) load(userptr, "glGetProgramResourceName");
+ glad_glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) load(userptr, "glGetProgramResourceiv");
+ glad_glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC) load(userptr, "glInvalidateBufferData");
+ glad_glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC) load(userptr, "glInvalidateBufferSubData");
+ glad_glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) load(userptr, "glInvalidateFramebuffer");
+ glad_glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) load(userptr, "glInvalidateSubFramebuffer");
+ glad_glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC) load(userptr, "glInvalidateTexImage");
+ glad_glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC) load(userptr, "glInvalidateTexSubImage");
+ glad_glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC) load(userptr, "glMultiDrawArraysIndirect");
+ glad_glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC) load(userptr, "glMultiDrawElementsIndirect");
+ glad_glObjectLabel = (PFNGLOBJECTLABELPROC) load(userptr, "glObjectLabel");
+ glad_glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC) load(userptr, "glObjectPtrLabel");
+ glad_glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC) load(userptr, "glPopDebugGroup");
+ glad_glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC) load(userptr, "glPushDebugGroup");
+ glad_glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC) load(userptr, "glShaderStorageBlockBinding");
+ glad_glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC) load(userptr, "glTexBufferRange");
+ glad_glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC) load(userptr, "glTexStorage2DMultisample");
+ glad_glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC) load(userptr, "glTexStorage3DMultisample");
+ glad_glTextureView = (PFNGLTEXTUREVIEWPROC) load(userptr, "glTextureView");
+ glad_glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC) load(userptr, "glVertexAttribBinding");
+ glad_glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC) load(userptr, "glVertexAttribFormat");
+ glad_glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC) load(userptr, "glVertexAttribIFormat");
+ glad_glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC) load(userptr, "glVertexAttribLFormat");
+ glad_glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC) load(userptr, "glVertexBindingDivisor");
+}
+static void glad_gl_load_GL_VERSION_4_4( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_4) return;
+ glad_glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC) load(userptr, "glBindBuffersBase");
+ glad_glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC) load(userptr, "glBindBuffersRange");
+ glad_glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC) load(userptr, "glBindImageTextures");
+ glad_glBindSamplers = (PFNGLBINDSAMPLERSPROC) load(userptr, "glBindSamplers");
+ glad_glBindTextures = (PFNGLBINDTEXTURESPROC) load(userptr, "glBindTextures");
+ glad_glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC) load(userptr, "glBindVertexBuffers");
+ glad_glBufferStorage = (PFNGLBUFFERSTORAGEPROC) load(userptr, "glBufferStorage");
+ glad_glClearTexImage = (PFNGLCLEARTEXIMAGEPROC) load(userptr, "glClearTexImage");
+ glad_glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC) load(userptr, "glClearTexSubImage");
+}
+static void glad_gl_load_GL_VERSION_4_5( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_5) return;
+ glad_glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC) load(userptr, "glBindTextureUnit");
+ glad_glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC) load(userptr, "glBlitNamedFramebuffer");
+ glad_glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckNamedFramebufferStatus");
+ glad_glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC) load(userptr, "glClearNamedBufferData");
+ glad_glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC) load(userptr, "glClearNamedBufferSubData");
+ glad_glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) load(userptr, "glClearNamedFramebufferfi");
+ glad_glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) load(userptr, "glClearNamedFramebufferfv");
+ glad_glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) load(userptr, "glClearNamedFramebufferiv");
+ glad_glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) load(userptr, "glClearNamedFramebufferuiv");
+ glad_glClipControl = (PFNGLCLIPCONTROLPROC) load(userptr, "glClipControl");
+ glad_glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) load(userptr, "glCompressedTextureSubImage1D");
+ glad_glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) load(userptr, "glCompressedTextureSubImage2D");
+ glad_glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) load(userptr, "glCompressedTextureSubImage3D");
+ glad_glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC) load(userptr, "glCopyNamedBufferSubData");
+ glad_glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC) load(userptr, "glCopyTextureSubImage1D");
+ glad_glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC) load(userptr, "glCopyTextureSubImage2D");
+ glad_glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC) load(userptr, "glCopyTextureSubImage3D");
+ glad_glCreateBuffers = (PFNGLCREATEBUFFERSPROC) load(userptr, "glCreateBuffers");
+ glad_glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC) load(userptr, "glCreateFramebuffers");
+ glad_glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC) load(userptr, "glCreateProgramPipelines");
+ glad_glCreateQueries = (PFNGLCREATEQUERIESPROC) load(userptr, "glCreateQueries");
+ glad_glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC) load(userptr, "glCreateRenderbuffers");
+ glad_glCreateSamplers = (PFNGLCREATESAMPLERSPROC) load(userptr, "glCreateSamplers");
+ glad_glCreateTextures = (PFNGLCREATETEXTURESPROC) load(userptr, "glCreateTextures");
+ glad_glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC) load(userptr, "glCreateTransformFeedbacks");
+ glad_glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC) load(userptr, "glCreateVertexArrays");
+ glad_glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC) load(userptr, "glDisableVertexArrayAttrib");
+ glad_glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC) load(userptr, "glEnableVertexArrayAttrib");
+ glad_glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) load(userptr, "glFlushMappedNamedBufferRange");
+ glad_glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) load(userptr, "glGenerateTextureMipmap");
+ glad_glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) load(userptr, "glGetCompressedTextureImage");
+ glad_glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) load(userptr, "glGetCompressedTextureSubImage");
+ glad_glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC) load(userptr, "glGetGraphicsResetStatus");
+ glad_glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) load(userptr, "glGetNamedBufferParameteri64v");
+ glad_glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedBufferParameteriv");
+ glad_glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC) load(userptr, "glGetNamedBufferPointerv");
+ glad_glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC) load(userptr, "glGetNamedBufferSubData");
+ glad_glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetNamedFramebufferAttachmentParameteriv");
+ glad_glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedFramebufferParameteriv");
+ glad_glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedRenderbufferParameteriv");
+ glad_glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC) load(userptr, "glGetQueryBufferObjecti64v");
+ glad_glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC) load(userptr, "glGetQueryBufferObjectiv");
+ glad_glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC) load(userptr, "glGetQueryBufferObjectui64v");
+ glad_glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC) load(userptr, "glGetQueryBufferObjectuiv");
+ glad_glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC) load(userptr, "glGetTextureImage");
+ glad_glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC) load(userptr, "glGetTextureLevelParameterfv");
+ glad_glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC) load(userptr, "glGetTextureLevelParameteriv");
+ glad_glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC) load(userptr, "glGetTextureParameterIiv");
+ glad_glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC) load(userptr, "glGetTextureParameterIuiv");
+ glad_glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC) load(userptr, "glGetTextureParameterfv");
+ glad_glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC) load(userptr, "glGetTextureParameteriv");
+ glad_glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC) load(userptr, "glGetTextureSubImage");
+ glad_glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC) load(userptr, "glGetTransformFeedbacki64_v");
+ glad_glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC) load(userptr, "glGetTransformFeedbacki_v");
+ glad_glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC) load(userptr, "glGetTransformFeedbackiv");
+ glad_glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC) load(userptr, "glGetVertexArrayIndexed64iv");
+ glad_glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC) load(userptr, "glGetVertexArrayIndexediv");
+ glad_glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC) load(userptr, "glGetVertexArrayiv");
+ glad_glGetnCompressedTexImage = (PFNGLGETNCOMPRESSEDTEXIMAGEPROC) load(userptr, "glGetnCompressedTexImage");
+ glad_glGetnTexImage = (PFNGLGETNTEXIMAGEPROC) load(userptr, "glGetnTexImage");
+ glad_glGetnUniformdv = (PFNGLGETNUNIFORMDVPROC) load(userptr, "glGetnUniformdv");
+ glad_glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC) load(userptr, "glGetnUniformfv");
+ glad_glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC) load(userptr, "glGetnUniformiv");
+ glad_glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC) load(userptr, "glGetnUniformuiv");
+ glad_glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) load(userptr, "glInvalidateNamedFramebufferData");
+ glad_glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) load(userptr, "glInvalidateNamedFramebufferSubData");
+ glad_glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC) load(userptr, "glMapNamedBuffer");
+ glad_glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC) load(userptr, "glMapNamedBufferRange");
+ glad_glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC) load(userptr, "glMemoryBarrierByRegion");
+ glad_glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC) load(userptr, "glNamedBufferData");
+ glad_glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC) load(userptr, "glNamedBufferStorage");
+ glad_glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC) load(userptr, "glNamedBufferSubData");
+ glad_glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) load(userptr, "glNamedFramebufferDrawBuffer");
+ glad_glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) load(userptr, "glNamedFramebufferDrawBuffers");
+ glad_glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) load(userptr, "glNamedFramebufferParameteri");
+ glad_glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) load(userptr, "glNamedFramebufferReadBuffer");
+ glad_glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glNamedFramebufferRenderbuffer");
+ glad_glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) load(userptr, "glNamedFramebufferTexture");
+ glad_glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glNamedFramebufferTextureLayer");
+ glad_glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC) load(userptr, "glNamedRenderbufferStorage");
+ glad_glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glNamedRenderbufferStorageMultisample");
+ glad_glReadnPixels = (PFNGLREADNPIXELSPROC) load(userptr, "glReadnPixels");
+ glad_glTextureBarrier = (PFNGLTEXTUREBARRIERPROC) load(userptr, "glTextureBarrier");
+ glad_glTextureBuffer = (PFNGLTEXTUREBUFFERPROC) load(userptr, "glTextureBuffer");
+ glad_glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC) load(userptr, "glTextureBufferRange");
+ glad_glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC) load(userptr, "glTextureParameterIiv");
+ glad_glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC) load(userptr, "glTextureParameterIuiv");
+ glad_glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC) load(userptr, "glTextureParameterf");
+ glad_glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC) load(userptr, "glTextureParameterfv");
+ glad_glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC) load(userptr, "glTextureParameteri");
+ glad_glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC) load(userptr, "glTextureParameteriv");
+ glad_glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC) load(userptr, "glTextureStorage1D");
+ glad_glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC) load(userptr, "glTextureStorage2D");
+ glad_glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) load(userptr, "glTextureStorage2DMultisample");
+ glad_glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC) load(userptr, "glTextureStorage3D");
+ glad_glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) load(userptr, "glTextureStorage3DMultisample");
+ glad_glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC) load(userptr, "glTextureSubImage1D");
+ glad_glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC) load(userptr, "glTextureSubImage2D");
+ glad_glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC) load(userptr, "glTextureSubImage3D");
+ glad_glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) load(userptr, "glTransformFeedbackBufferBase");
+ glad_glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) load(userptr, "glTransformFeedbackBufferRange");
+ glad_glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC) load(userptr, "glUnmapNamedBuffer");
+ glad_glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC) load(userptr, "glVertexArrayAttribBinding");
+ glad_glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC) load(userptr, "glVertexArrayAttribFormat");
+ glad_glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC) load(userptr, "glVertexArrayAttribIFormat");
+ glad_glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC) load(userptr, "glVertexArrayAttribLFormat");
+ glad_glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC) load(userptr, "glVertexArrayBindingDivisor");
+ glad_glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC) load(userptr, "glVertexArrayElementBuffer");
+ glad_glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC) load(userptr, "glVertexArrayVertexBuffer");
+ glad_glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC) load(userptr, "glVertexArrayVertexBuffers");
+}
+static void glad_gl_load_GL_VERSION_4_6( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GL_VERSION_4_6) return;
+ glad_glMultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC) load(userptr, "glMultiDrawArraysIndirectCount");
+ glad_glMultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) load(userptr, "glMultiDrawElementsIndirectCount");
+ glad_glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC) load(userptr, "glPolygonOffsetClamp");
+ glad_glSpecializeShader = (PFNGLSPECIALIZESHADERPROC) load(userptr, "glSpecializeShader");
+}
+
+
+
+static void glad_gl_free_extensions(char **exts_i) {
+ if (exts_i != NULL) {
+ unsigned int index;
+ for(index = 0; exts_i[index]; index++) {
+ free((void *) (exts_i[index]));
+ }
+ free((void *)exts_i);
+ exts_i = NULL;
+ }
+}
+static int glad_gl_get_extensions( const char **out_exts, char ***out_exts_i) {
+#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0)
+ if (glad_glGetStringi != NULL && glad_glGetIntegerv != NULL) {
+ unsigned int index = 0;
+ unsigned int num_exts_i = 0;
+ char **exts_i = NULL;
+ glad_glGetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i);
+ exts_i = (char **) malloc((num_exts_i + 1) * (sizeof *exts_i));
+ if (exts_i == NULL) {
+ return 0;
+ }
+ for(index = 0; index < num_exts_i; index++) {
+ const char *gl_str_tmp = (const char*) glad_glGetStringi(GL_EXTENSIONS, index);
+ size_t len = strlen(gl_str_tmp) + 1;
+
+ char *local_str = (char*) malloc(len * sizeof(char));
+ if(local_str == NULL) {
+ exts_i[index] = NULL;
+ glad_gl_free_extensions(exts_i);
+ return 0;
+ }
+
+ memcpy(local_str, gl_str_tmp, len * sizeof(char));
+ exts_i[index] = local_str;
+ }
+ exts_i[index] = NULL;
+
+ *out_exts_i = exts_i;
+
+ return 1;
+ }
+#else
+ GLAD_UNUSED(out_exts_i);
+#endif
+ if (glad_glGetString == NULL) {
+ return 0;
+ }
+ *out_exts = (const char *)glad_glGetString(GL_EXTENSIONS);
+ return 1;
+}
+static int glad_gl_has_extension(const char *exts, char **exts_i, const char *ext) {
+ if(exts_i) {
+ unsigned int index;
+ for(index = 0; exts_i[index]; index++) {
+ const char *e = exts_i[index];
+ if(strcmp(e, ext) == 0) {
+ return 1;
+ }
+ }
+ } else {
+ const char *extensions;
+ const char *loc;
+ const char *terminator;
+ extensions = exts;
+ if(extensions == NULL || ext == NULL) {
+ return 0;
+ }
+ while(1) {
+ loc = strstr(extensions, ext);
+ if(loc == NULL) {
+ return 0;
+ }
+ terminator = loc + strlen(ext);
+ if((loc == extensions || *(loc - 1) == ' ') &&
+ (*terminator == ' ' || *terminator == '\0')) {
+ return 1;
+ }
+ extensions = terminator;
+ }
+ }
+ return 0;
+}
+
+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(void) {
+ const char *exts = NULL;
+ char **exts_i = NULL;
+ if (!glad_gl_get_extensions(&exts, &exts_i)) return 0;
+
+ GLAD_UNUSED(glad_gl_has_extension);
+
+ glad_gl_free_extensions(exts_i);
+
+ return 1;
+}
+
+static int glad_gl_find_core_gl(void) {
+ int i;
+ const char* version;
+ const char* prefixes[] = {
+ "OpenGL ES-CM ",
+ "OpenGL ES-CL ",
+ "OpenGL ES ",
+ "OpenGL SC ",
+ NULL
+ };
+ int major = 0;
+ int minor = 0;
+ version = (const char*) glad_glGetString(GL_VERSION);
+ if (!version) return 0;
+ for (i = 0; prefixes[i]; i++) {
+ const size_t length = strlen(prefixes[i]);
+ if (strncmp(version, prefixes[i], length) == 0) {
+ version += length;
+ break;
+ }
+ }
+
+ 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;
+ GLAD_GL_VERSION_4_0 = (major == 4 && minor >= 0) || major > 4;
+ GLAD_GL_VERSION_4_1 = (major == 4 && minor >= 1) || major > 4;
+ GLAD_GL_VERSION_4_2 = (major == 4 && minor >= 2) || major > 4;
+ GLAD_GL_VERSION_4_3 = (major == 4 && minor >= 3) || major > 4;
+ GLAD_GL_VERSION_4_4 = (major == 4 && minor >= 4) || major > 4;
+ GLAD_GL_VERSION_4_5 = (major == 4 && minor >= 5) || major > 4;
+ GLAD_GL_VERSION_4_6 = (major == 4 && minor >= 6) || major > 4;
+
+ return GLAD_MAKE_VERSION(major, minor);
+}
+
+int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) {
+ int version;
+
+ glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString");
+ if(glad_glGetString == NULL) return 0;
+ version = glad_gl_find_core_gl();
+
+ 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_4_0(load, userptr);
+ glad_gl_load_GL_VERSION_4_1(load, userptr);
+ glad_gl_load_GL_VERSION_4_2(load, userptr);
+ glad_gl_load_GL_VERSION_4_3(load, userptr);
+ glad_gl_load_GL_VERSION_4_4(load, userptr);
+ glad_gl_load_GL_VERSION_4_5(load, userptr);
+ glad_gl_load_GL_VERSION_4_6(load, userptr);
+
+ if (!glad_gl_find_extensions_gl()) return 0;
+
+
+
+ return version;
+}
+
+
+int gladLoadGL( GLADloadfunc load) {
+ return gladLoadGLUserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
+}
+
+
+
+
+
+#ifdef GLAD_GL
+
+#ifndef GLAD_LOADER_LIBRARY_C_
+#define GLAD_LOADER_LIBRARY_C_
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#if GLAD_PLATFORM_WIN32
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif
+
+
+static void* glad_get_dlopen_handle(const char *lib_names[], int length) {
+ void *handle = NULL;
+ int i;
+
+ for (i = 0; i < length; ++i) {
+#if GLAD_PLATFORM_WIN32
+ #if GLAD_PLATFORM_UWP
+ size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR);
+ LPWSTR buffer = (LPWSTR) malloc(buffer_size);
+ if (buffer != NULL) {
+ int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size);
+ if (ret != 0) {
+ handle = (void*) LoadPackagedLibrary(buffer, 0);
+ }
+ free((void*) buffer);
+ }
+ #else
+ handle = (void*) LoadLibraryA(lib_names[i]);
+ #endif
+#else
+ handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL);
+#endif
+ if (handle != NULL) {
+ return handle;
+ }
+ }
+
+ return NULL;
+}
+
+static void glad_close_dlopen_handle(void* handle) {
+ if (handle != NULL) {
+#if GLAD_PLATFORM_WIN32
+ FreeLibrary((HMODULE) handle);
+#else
+ dlclose(handle);
+#endif
+ }
+}
+
+static GLADapiproc glad_dlsym_handle(void* handle, const char *name) {
+ if (handle == NULL) {
+ return NULL;
+ }
+
+#if GLAD_PLATFORM_WIN32
+ return (GLADapiproc) GetProcAddress((HMODULE) handle, name);
+#else
+ return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name);
+#endif
+}
+
+#endif /* GLAD_LOADER_LIBRARY_C_ */
+
+typedef void* (GLAD_API_PTR *GLADglprocaddrfunc)(const char*);
+struct _glad_gl_userptr {
+ void *handle;
+ GLADglprocaddrfunc gl_get_proc_address_ptr;
+};
+
+static GLADapiproc glad_gl_get_proc(void *vuserptr, const char *name) {
+ struct _glad_gl_userptr userptr = *(struct _glad_gl_userptr*) vuserptr;
+ GLADapiproc result = NULL;
+
+ if(userptr.gl_get_proc_address_ptr != NULL) {
+ result = GLAD_GNUC_EXTENSION (GLADapiproc) userptr.gl_get_proc_address_ptr(name);
+ }
+ if(result == NULL) {
+ result = glad_dlsym_handle(userptr.handle, name);
+ }
+
+ return result;
+}
+
+static void* _glad_GL_loader_handle = NULL;
+
+static void* glad_gl_dlopen_handle(void) {
+#if GLAD_PLATFORM_APPLE
+ static const char *NAMES[] = {
+ "../Frameworks/OpenGL.framework/OpenGL",
+ "/Library/Frameworks/OpenGL.framework/OpenGL",
+ "/System/Library/Frameworks/OpenGL.framework/OpenGL",
+ "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"
+ };
+#elif GLAD_PLATFORM_WIN32
+ static const char *NAMES[] = {"opengl32.dll"};
+#else
+ static const char *NAMES[] = {
+ #if defined(__CYGWIN__)
+ "libGL-1.so",
+ #endif
+ "libGL.so.1",
+ "libGL.so"
+ };
+#endif
+
+ if (_glad_GL_loader_handle == NULL) {
+ _glad_GL_loader_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0]));
+ }
+
+ return _glad_GL_loader_handle;
+}
+
+static struct _glad_gl_userptr glad_gl_build_userptr(void *handle) {
+ struct _glad_gl_userptr userptr;
+
+ userptr.handle = handle;
+#if GLAD_PLATFORM_APPLE || defined(__HAIKU__)
+ userptr.gl_get_proc_address_ptr = NULL;
+#elif GLAD_PLATFORM_WIN32
+ userptr.gl_get_proc_address_ptr =
+ (GLADglprocaddrfunc) glad_dlsym_handle(handle, "wglGetProcAddress");
+#else
+ userptr.gl_get_proc_address_ptr =
+ (GLADglprocaddrfunc) glad_dlsym_handle(handle, "glXGetProcAddressARB");
+#endif
+
+ return userptr;
+}
+
+int gladLoaderLoadGL(void) {
+ int version = 0;
+ void *handle;
+ int did_load = 0;
+ struct _glad_gl_userptr userptr;
+
+ did_load = _glad_GL_loader_handle == NULL;
+ handle = glad_gl_dlopen_handle();
+ if (handle) {
+ userptr = glad_gl_build_userptr(handle);
+
+ version = gladLoadGLUserPtr(glad_gl_get_proc, &userptr);
+
+ if (did_load) {
+ gladLoaderUnloadGL();
+ }
+ }
+
+ return version;
+}
+
+
+
+void gladLoaderUnloadGL(void) {
+ if (_glad_GL_loader_handle != NULL) {
+ glad_close_dlopen_handle(_glad_GL_loader_handle);
+ _glad_GL_loader_handle = NULL;
+ }
+}
+
+#endif /* GLAD_GL */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/mons_3d/external/glad/src/glx.c b/mons_3d/external/glad/src/glx.c
new file mode 100644
index 0000000..77eca9c
--- /dev/null
+++ b/mons_3d/external/glad/src/glx.c
@@ -0,0 +1,352 @@
+/**
+ * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glad/glx.h>
+
+#ifndef GLAD_IMPL_UTIL_C_
+#define GLAD_IMPL_UTIL_C_
+
+#ifdef _MSC_VER
+#define GLAD_IMPL_UTIL_SSCANF sscanf_s
+#else
+#define GLAD_IMPL_UTIL_SSCANF sscanf
+#endif
+
+#endif /* GLAD_IMPL_UTIL_C_ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+int GLAD_GLX_VERSION_1_0 = 0;
+int GLAD_GLX_VERSION_1_1 = 0;
+int GLAD_GLX_VERSION_1_2 = 0;
+int GLAD_GLX_VERSION_1_3 = 0;
+int GLAD_GLX_VERSION_1_4 = 0;
+
+
+
+PFNGLXCHOOSEFBCONFIGPROC glad_glXChooseFBConfig = NULL;
+PFNGLXCHOOSEVISUALPROC glad_glXChooseVisual = NULL;
+PFNGLXCOPYCONTEXTPROC glad_glXCopyContext = NULL;
+PFNGLXCREATECONTEXTPROC glad_glXCreateContext = NULL;
+PFNGLXCREATEGLXPIXMAPPROC glad_glXCreateGLXPixmap = NULL;
+PFNGLXCREATENEWCONTEXTPROC glad_glXCreateNewContext = NULL;
+PFNGLXCREATEPBUFFERPROC glad_glXCreatePbuffer = NULL;
+PFNGLXCREATEPIXMAPPROC glad_glXCreatePixmap = NULL;
+PFNGLXCREATEWINDOWPROC glad_glXCreateWindow = NULL;
+PFNGLXDESTROYCONTEXTPROC glad_glXDestroyContext = NULL;
+PFNGLXDESTROYGLXPIXMAPPROC glad_glXDestroyGLXPixmap = NULL;
+PFNGLXDESTROYPBUFFERPROC glad_glXDestroyPbuffer = NULL;
+PFNGLXDESTROYPIXMAPPROC glad_glXDestroyPixmap = NULL;
+PFNGLXDESTROYWINDOWPROC glad_glXDestroyWindow = NULL;
+PFNGLXGETCLIENTSTRINGPROC glad_glXGetClientString = NULL;
+PFNGLXGETCONFIGPROC glad_glXGetConfig = NULL;
+PFNGLXGETCURRENTCONTEXTPROC glad_glXGetCurrentContext = NULL;
+PFNGLXGETCURRENTDISPLAYPROC glad_glXGetCurrentDisplay = NULL;
+PFNGLXGETCURRENTDRAWABLEPROC glad_glXGetCurrentDrawable = NULL;
+PFNGLXGETCURRENTREADDRAWABLEPROC glad_glXGetCurrentReadDrawable = NULL;
+PFNGLXGETFBCONFIGATTRIBPROC glad_glXGetFBConfigAttrib = NULL;
+PFNGLXGETFBCONFIGSPROC glad_glXGetFBConfigs = NULL;
+PFNGLXGETPROCADDRESSPROC glad_glXGetProcAddress = NULL;
+PFNGLXGETSELECTEDEVENTPROC glad_glXGetSelectedEvent = NULL;
+PFNGLXGETVISUALFROMFBCONFIGPROC glad_glXGetVisualFromFBConfig = NULL;
+PFNGLXISDIRECTPROC glad_glXIsDirect = NULL;
+PFNGLXMAKECONTEXTCURRENTPROC glad_glXMakeContextCurrent = NULL;
+PFNGLXMAKECURRENTPROC glad_glXMakeCurrent = NULL;
+PFNGLXQUERYCONTEXTPROC glad_glXQueryContext = NULL;
+PFNGLXQUERYDRAWABLEPROC glad_glXQueryDrawable = NULL;
+PFNGLXQUERYEXTENSIONPROC glad_glXQueryExtension = NULL;
+PFNGLXQUERYEXTENSIONSSTRINGPROC glad_glXQueryExtensionsString = NULL;
+PFNGLXQUERYSERVERSTRINGPROC glad_glXQueryServerString = NULL;
+PFNGLXQUERYVERSIONPROC glad_glXQueryVersion = NULL;
+PFNGLXSELECTEVENTPROC glad_glXSelectEvent = NULL;
+PFNGLXSWAPBUFFERSPROC glad_glXSwapBuffers = NULL;
+PFNGLXUSEXFONTPROC glad_glXUseXFont = NULL;
+PFNGLXWAITGLPROC glad_glXWaitGL = NULL;
+PFNGLXWAITXPROC glad_glXWaitX = NULL;
+
+
+static void glad_glx_load_GLX_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GLX_VERSION_1_0) return;
+ glad_glXChooseVisual = (PFNGLXCHOOSEVISUALPROC) load(userptr, "glXChooseVisual");
+ glad_glXCopyContext = (PFNGLXCOPYCONTEXTPROC) load(userptr, "glXCopyContext");
+ glad_glXCreateContext = (PFNGLXCREATECONTEXTPROC) load(userptr, "glXCreateContext");
+ glad_glXCreateGLXPixmap = (PFNGLXCREATEGLXPIXMAPPROC) load(userptr, "glXCreateGLXPixmap");
+ glad_glXDestroyContext = (PFNGLXDESTROYCONTEXTPROC) load(userptr, "glXDestroyContext");
+ glad_glXDestroyGLXPixmap = (PFNGLXDESTROYGLXPIXMAPPROC) load(userptr, "glXDestroyGLXPixmap");
+ glad_glXGetConfig = (PFNGLXGETCONFIGPROC) load(userptr, "glXGetConfig");
+ glad_glXGetCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) load(userptr, "glXGetCurrentContext");
+ glad_glXGetCurrentDrawable = (PFNGLXGETCURRENTDRAWABLEPROC) load(userptr, "glXGetCurrentDrawable");
+ glad_glXIsDirect = (PFNGLXISDIRECTPROC) load(userptr, "glXIsDirect");
+ glad_glXMakeCurrent = (PFNGLXMAKECURRENTPROC) load(userptr, "glXMakeCurrent");
+ glad_glXQueryExtension = (PFNGLXQUERYEXTENSIONPROC) load(userptr, "glXQueryExtension");
+ glad_glXQueryVersion = (PFNGLXQUERYVERSIONPROC) load(userptr, "glXQueryVersion");
+ glad_glXSwapBuffers = (PFNGLXSWAPBUFFERSPROC) load(userptr, "glXSwapBuffers");
+ glad_glXUseXFont = (PFNGLXUSEXFONTPROC) load(userptr, "glXUseXFont");
+ glad_glXWaitGL = (PFNGLXWAITGLPROC) load(userptr, "glXWaitGL");
+ glad_glXWaitX = (PFNGLXWAITXPROC) load(userptr, "glXWaitX");
+}
+static void glad_glx_load_GLX_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GLX_VERSION_1_1) return;
+ glad_glXGetClientString = (PFNGLXGETCLIENTSTRINGPROC) load(userptr, "glXGetClientString");
+ glad_glXQueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRINGPROC) load(userptr, "glXQueryExtensionsString");
+ glad_glXQueryServerString = (PFNGLXQUERYSERVERSTRINGPROC) load(userptr, "glXQueryServerString");
+}
+static void glad_glx_load_GLX_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GLX_VERSION_1_2) return;
+ glad_glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC) load(userptr, "glXGetCurrentDisplay");
+}
+static void glad_glx_load_GLX_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GLX_VERSION_1_3) return;
+ glad_glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) load(userptr, "glXChooseFBConfig");
+ glad_glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC) load(userptr, "glXCreateNewContext");
+ glad_glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC) load(userptr, "glXCreatePbuffer");
+ glad_glXCreatePixmap = (PFNGLXCREATEPIXMAPPROC) load(userptr, "glXCreatePixmap");
+ glad_glXCreateWindow = (PFNGLXCREATEWINDOWPROC) load(userptr, "glXCreateWindow");
+ glad_glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) load(userptr, "glXDestroyPbuffer");
+ glad_glXDestroyPixmap = (PFNGLXDESTROYPIXMAPPROC) load(userptr, "glXDestroyPixmap");
+ glad_glXDestroyWindow = (PFNGLXDESTROYWINDOWPROC) load(userptr, "glXDestroyWindow");
+ glad_glXGetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC) load(userptr, "glXGetCurrentReadDrawable");
+ glad_glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC) load(userptr, "glXGetFBConfigAttrib");
+ glad_glXGetFBConfigs = (PFNGLXGETFBCONFIGSPROC) load(userptr, "glXGetFBConfigs");
+ glad_glXGetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC) load(userptr, "glXGetSelectedEvent");
+ glad_glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC) load(userptr, "glXGetVisualFromFBConfig");
+ glad_glXMakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC) load(userptr, "glXMakeContextCurrent");
+ glad_glXQueryContext = (PFNGLXQUERYCONTEXTPROC) load(userptr, "glXQueryContext");
+ glad_glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC) load(userptr, "glXQueryDrawable");
+ glad_glXSelectEvent = (PFNGLXSELECTEVENTPROC) load(userptr, "glXSelectEvent");
+}
+static void glad_glx_load_GLX_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) {
+ if(!GLAD_GLX_VERSION_1_4) return;
+ glad_glXGetProcAddress = (PFNGLXGETPROCADDRESSPROC) load(userptr, "glXGetProcAddress");
+}
+
+
+
+static int glad_glx_has_extension(Display *display, int screen, const char *ext) {
+#ifndef GLX_VERSION_1_1
+ GLAD_UNUSED(display);
+ GLAD_UNUSED(screen);
+ GLAD_UNUSED(ext);
+#else
+ const char *terminator;
+ const char *loc;
+ const char *extensions;
+
+ if (glXQueryExtensionsString == NULL) {
+ return 0;
+ }
+
+ extensions = glXQueryExtensionsString(display, screen);
+
+ if(extensions == NULL || ext == NULL) {
+ return 0;
+ }
+
+ while(1) {
+ loc = strstr(extensions, ext);
+ if(loc == NULL)
+ break;
+
+ terminator = loc + strlen(ext);
+ if((loc == extensions || *(loc - 1) == ' ') &&
+ (*terminator == ' ' || *terminator == '\0')) {
+ return 1;
+ }
+ extensions = terminator;
+ }
+#endif
+
+ return 0;
+}
+
+static GLADapiproc glad_glx_get_proc_from_userptr(void *userptr, const char* name) {
+ return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name);
+}
+
+static int glad_glx_find_extensions(Display *display, int screen) {
+ GLAD_UNUSED(glad_glx_has_extension);
+ return 1;
+}
+
+static int glad_glx_find_core_glx(Display **display, int *screen) {
+ int major = 0, minor = 0;
+ if(*display == NULL) {
+#ifdef GLAD_GLX_NO_X11
+ GLAD_UNUSED(screen);
+ return 0;
+#else
+ *display = XOpenDisplay(0);
+ if (*display == NULL) {
+ return 0;
+ }
+ *screen = XScreenNumberOfScreen(XDefaultScreenOfDisplay(*display));
+#endif
+ }
+ glXQueryVersion(*display, &major, &minor);
+ GLAD_GLX_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1;
+ GLAD_GLX_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1;
+ GLAD_GLX_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1;
+ GLAD_GLX_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1;
+ GLAD_GLX_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1;
+ return GLAD_MAKE_VERSION(major, minor);
+}
+
+int gladLoadGLXUserPtr(Display *display, int screen, GLADuserptrloadfunc load, void *userptr) {
+ int version;
+ glXQueryVersion = (PFNGLXQUERYVERSIONPROC) load(userptr, "glXQueryVersion");
+ if(glXQueryVersion == NULL) return 0;
+ version = glad_glx_find_core_glx(&display, &screen);
+
+ glad_glx_load_GLX_VERSION_1_0(load, userptr);
+ glad_glx_load_GLX_VERSION_1_1(load, userptr);
+ glad_glx_load_GLX_VERSION_1_2(load, userptr);
+ glad_glx_load_GLX_VERSION_1_3(load, userptr);
+ glad_glx_load_GLX_VERSION_1_4(load, userptr);
+
+ if (!glad_glx_find_extensions(display, screen)) return 0;
+
+
+ return version;
+}
+
+int gladLoadGLX(Display *display, int screen, GLADloadfunc load) {
+ return gladLoadGLXUserPtr(display, screen, glad_glx_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
+}
+
+
+
+#ifdef GLAD_GLX
+
+#ifndef GLAD_LOADER_LIBRARY_C_
+#define GLAD_LOADER_LIBRARY_C_
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#if GLAD_PLATFORM_WIN32
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif
+
+
+static void* glad_get_dlopen_handle(const char *lib_names[], int length) {
+ void *handle = NULL;
+ int i;
+
+ for (i = 0; i < length; ++i) {
+#if GLAD_PLATFORM_WIN32
+ #if GLAD_PLATFORM_UWP
+ size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR);
+ LPWSTR buffer = (LPWSTR) malloc(buffer_size);
+ if (buffer != NULL) {
+ int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size);
+ if (ret != 0) {
+ handle = (void*) LoadPackagedLibrary(buffer, 0);
+ }
+ free((void*) buffer);
+ }
+ #else
+ handle = (void*) LoadLibraryA(lib_names[i]);
+ #endif
+#else
+ handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL);
+#endif
+ if (handle != NULL) {
+ return handle;
+ }
+ }
+
+ return NULL;
+}
+
+static void glad_close_dlopen_handle(void* handle) {
+ if (handle != NULL) {
+#if GLAD_PLATFORM_WIN32
+ FreeLibrary((HMODULE) handle);
+#else
+ dlclose(handle);
+#endif
+ }
+}
+
+static GLADapiproc glad_dlsym_handle(void* handle, const char *name) {
+ if (handle == NULL) {
+ return NULL;
+ }
+
+#if GLAD_PLATFORM_WIN32
+ return (GLADapiproc) GetProcAddress((HMODULE) handle, name);
+#else
+ return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name);
+#endif
+}
+
+#endif /* GLAD_LOADER_LIBRARY_C_ */
+
+typedef void* (GLAD_API_PTR *GLADglxprocaddrfunc)(const char*);
+
+static GLADapiproc glad_glx_get_proc(void *userptr, const char *name) {
+ return GLAD_GNUC_EXTENSION ((GLADapiproc (*)(const char *name)) userptr)(name);
+}
+
+static void* _glx_handle;
+
+static void* glad_glx_dlopen_handle(void) {
+ static const char *NAMES[] = {
+#if defined __CYGWIN__
+ "libGL-1.so",
+#endif
+ "libGL.so.1",
+ "libGL.so"
+ };
+
+ if (_glx_handle == NULL) {
+ _glx_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0]));
+ }
+
+ return _glx_handle;
+}
+
+int gladLoaderLoadGLX(Display *display, int screen) {
+ int version = 0;
+ void *handle = NULL;
+ int did_load = 0;
+ GLADglxprocaddrfunc loader;
+
+ did_load = _glx_handle == NULL;
+ handle = glad_glx_dlopen_handle();
+ if (handle != NULL) {
+ loader = (GLADglxprocaddrfunc) glad_dlsym_handle(handle, "glXGetProcAddressARB");
+ if (loader != NULL) {
+ version = gladLoadGLXUserPtr(display, screen, glad_glx_get_proc, GLAD_GNUC_EXTENSION (void*) loader);
+ }
+
+ if (!version && did_load) {
+ gladLoaderUnloadGLX();
+ }
+ }
+
+ return version;
+}
+
+
+void gladLoaderUnloadGLX() {
+ if (_glx_handle != NULL) {
+ glad_close_dlopen_handle(_glx_handle);
+ _glx_handle = NULL;
+ }
+}
+
+#endif /* GLAD_GLX */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/mons_3d/external/mikktspace/include/mikktspace.h b/mons_3d/external/mikktspace/include/mikktspace.h
new file mode 100644
index 0000000..52c44a7
--- /dev/null
+++ b/mons_3d/external/mikktspace/include/mikktspace.h
@@ -0,0 +1,145 @@
+/** \file mikktspace/mikktspace.h
+ * \ingroup mikktspace
+ */
+/**
+ * Copyright (C) 2011 by Morten S. Mikkelsen
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef __MIKKTSPACE_H__
+#define __MIKKTSPACE_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Author: Morten S. Mikkelsen
+ * Version: 1.0
+ *
+ * The files mikktspace.h and mikktspace.c are designed to be
+ * stand-alone files and it is important that they are kept this way.
+ * Not having dependencies on structures/classes/libraries specific
+ * to the program, in which they are used, allows them to be copied
+ * and used as is into any tool, program or plugin.
+ * The code is designed to consistently generate the same
+ * tangent spaces, for a given mesh, in any tool in which it is used.
+ * This is done by performing an internal welding step and subsequently an order-independent evaluation
+ * of tangent space for meshes consisting of triangles and quads.
+ * This means faces can be received in any order and the same is true for
+ * the order of vertices of each face. The generated result will not be affected
+ * by such reordering. Additionally, whether degenerate (vertices or texture coordinates)
+ * primitives are present or not will not affect the generated results either.
+ * Once tangent space calculation is done the vertices of degenerate primitives will simply
+ * inherit tangent space from neighboring non degenerate primitives.
+ * The analysis behind this implementation can be found in my master's thesis
+ * which is available for download --> http://image.diku.dk/projects/media/morten.mikkelsen.08.pdf
+ * Note that though the tangent spaces at the vertices are generated in an order-independent way,
+ * by this implementation, the interpolated tangent space is still affected by which diagonal is
+ * chosen to split each quad. A sensible solution is to have your tools pipeline always
+ * split quads by the shortest diagonal. This choice is order-independent and works with mirroring.
+ * If these have the same length then compare the diagonals defined by the texture coordinates.
+ * XNormal which is a tool for baking normal maps allows you to write your own tangent space plugin
+ * and also quad triangulator plugin.
+ */
+
+
+typedef int tbool;
+typedef struct SMikkTSpaceContext SMikkTSpaceContext;
+
+typedef struct {
+ // Returns the number of faces (triangles/quads) on the mesh to be processed.
+ int (*m_getNumFaces)(const SMikkTSpaceContext * pContext);
+
+ // Returns the number of vertices on face number iFace
+ // iFace is a number in the range {0, 1, ..., getNumFaces()-1}
+ int (*m_getNumVerticesOfFace)(const SMikkTSpaceContext * pContext, const int iFace);
+
+ // returns the position/normal/texcoord of the referenced face of vertex number iVert.
+ // iVert is in the range {0,1,2} for triangles and {0,1,2,3} for quads.
+ void (*m_getPosition)(const SMikkTSpaceContext * pContext, float fvPosOut[], const int iFace, const int iVert);
+ void (*m_getNormal)(const SMikkTSpaceContext * pContext, float fvNormOut[], const int iFace, const int iVert);
+ void (*m_getTexCoord)(const SMikkTSpaceContext * pContext, float fvTexcOut[], const int iFace, const int iVert);
+
+ // either (or both) of the two setTSpace callbacks can be set.
+ // The call-back m_setTSpaceBasic() is sufficient for basic normal mapping.
+
+ // This function is used to return the tangent and fSign to the application.
+ // fvTangent is a unit length vector.
+ // For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
+ // bitangent = fSign * cross(vN, tangent);
+ // Note that the results are returned unindexed. It is possible to generate a new index list
+ // But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
+ // DO NOT! use an already existing index list.
+ void (*m_setTSpaceBasic)(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert);
+
+ // This function is used to return tangent space results to the application.
+ // fvTangent and fvBiTangent are unit length vectors and fMagS and fMagT are their
+ // true magnitudes which can be used for relief mapping effects.
+ // fvBiTangent is the "real" bitangent and thus may not be perpendicular to fvTangent.
+ // However, both are perpendicular to the vertex normal.
+ // For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
+ // fSign = bIsOrientationPreserving ? 1.0f : (-1.0f);
+ // bitangent = fSign * cross(vN, tangent);
+ // Note that the results are returned unindexed. It is possible to generate a new index list
+ // But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
+ // DO NOT! use an already existing index list.
+ void (*m_setTSpace)(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
+ const tbool bIsOrientationPreserving, const int iFace, const int iVert);
+} SMikkTSpaceInterface;
+
+struct SMikkTSpaceContext
+{
+ SMikkTSpaceInterface * m_pInterface; // initialized with callback functions
+ void * m_pUserData; // pointer to client side mesh data etc. (passed as the first parameter with every interface call)
+};
+
+// these are both thread safe!
+tbool genTangSpaceDefault(const SMikkTSpaceContext * pContext); // Default (recommended) fAngularThreshold is 180 degrees (which means threshold disabled)
+tbool genTangSpace(const SMikkTSpaceContext * pContext, const float fAngularThreshold);
+
+
+// To avoid visual errors (distortions/unwanted hard edges in lighting), when using sampled normal maps, the
+// normal map sampler must use the exact inverse of the pixel shader transformation.
+// The most efficient transformation we can possibly do in the pixel shader is
+// achieved by using, directly, the "unnormalized" interpolated tangent, bitangent and vertex normal: vT, vB and vN.
+// pixel shader (fast transform out)
+// vNout = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
+// where vNt is the tangent space normal. The normal map sampler must likewise use the
+// interpolated and "unnormalized" tangent, bitangent and vertex normal to be compliant with the pixel shader.
+// sampler does (exact inverse of pixel shader):
+// float3 row0 = cross(vB, vN);
+// float3 row1 = cross(vN, vT);
+// float3 row2 = cross(vT, vB);
+// float fSign = dot(vT, row0)<0 ? -1 : 1;
+// vNt = normalize( fSign * float3(dot(vNout,row0), dot(vNout,row1), dot(vNout,row2)) );
+// where vNout is the sampled normal in some chosen 3D space.
+//
+// Should you choose to reconstruct the bitangent in the pixel shader instead
+// of the vertex shader, as explained earlier, then be sure to do this in the normal map sampler also.
+// Finally, beware of quad triangulations. If the normal map sampler doesn't use the same triangulation of
+// quads as your renderer then problems will occur since the interpolated tangent spaces will differ
+// eventhough the vertex level tangent spaces match. This can be solved either by triangulating before
+// sampling/exporting or by using the order-independent choice of diagonal for splitting quads suggested earlier.
+// However, this must be used both by the sampler and your tools/rendering pipeline.
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/mons_3d/external/mikktspace/src/mikktspace.c b/mons_3d/external/mikktspace/src/mikktspace.c
new file mode 100644
index 0000000..0342ae0
--- /dev/null
+++ b/mons_3d/external/mikktspace/src/mikktspace.c
@@ -0,0 +1,1899 @@
+/** \file mikktspace/mikktspace.c
+ * \ingroup mikktspace
+ */
+/**
+ * Copyright (C) 2011 by Morten S. Mikkelsen
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <float.h>
+#include <stdlib.h>
+
+#include "mikktspace.h"
+
+#define TFALSE 0
+#define TTRUE 1
+
+#ifndef M_PI
+#define M_PI 3.1415926535897932384626433832795
+#endif
+
+#define INTERNAL_RND_SORT_SEED 39871946
+
+// internal structure
+typedef struct {
+ float x, y, z;
+} SVec3;
+
+static tbool veq( const SVec3 v1, const SVec3 v2 )
+{
+ return (v1.x == v2.x) && (v1.y == v2.y) && (v1.z == v2.z);
+}
+
+static SVec3 vadd( const SVec3 v1, const SVec3 v2 )
+{
+ SVec3 vRes;
+
+ vRes.x = v1.x + v2.x;
+ vRes.y = v1.y + v2.y;
+ vRes.z = v1.z + v2.z;
+
+ return vRes;
+}
+
+
+static SVec3 vsub( const SVec3 v1, const SVec3 v2 )
+{
+ SVec3 vRes;
+
+ vRes.x = v1.x - v2.x;
+ vRes.y = v1.y - v2.y;
+ vRes.z = v1.z - v2.z;
+
+ return vRes;
+}
+
+static SVec3 vscale(const float fS, const SVec3 v)
+{
+ SVec3 vRes;
+
+ vRes.x = fS * v.x;
+ vRes.y = fS * v.y;
+ vRes.z = fS * v.z;
+
+ return vRes;
+}
+
+static float LengthSquared( const SVec3 v )
+{
+ return v.x*v.x + v.y*v.y + v.z*v.z;
+}
+
+static float Length( const SVec3 v )
+{
+ return sqrtf(LengthSquared(v));
+}
+
+static SVec3 Normalize( const SVec3 v )
+{
+ return vscale(1 / Length(v), v);
+}
+
+static float vdot( const SVec3 v1, const SVec3 v2)
+{
+ return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
+}
+
+
+static tbool NotZero(const float fX)
+{
+ // could possibly use FLT_EPSILON instead
+ return fabsf(fX) > FLT_MIN;
+}
+
+static tbool VNotZero(const SVec3 v)
+{
+ // might change this to an epsilon based test
+ return NotZero(v.x) || NotZero(v.y) || NotZero(v.z);
+}
+
+
+
+typedef struct {
+ int iNrFaces;
+ int * pTriMembers;
+} SSubGroup;
+
+typedef struct {
+ int iNrFaces;
+ int * pFaceIndices;
+ int iVertexRepresentitive;
+ tbool bOrientPreservering;
+} SGroup;
+
+//
+#define MARK_DEGENERATE 1
+#define QUAD_ONE_DEGEN_TRI 2
+#define GROUP_WITH_ANY 4
+#define ORIENT_PRESERVING 8
+
+
+
+typedef struct {
+ int FaceNeighbors[3];
+ SGroup * AssignedGroup[3];
+
+ // normalized first order face derivatives
+ SVec3 vOs, vOt;
+ float fMagS, fMagT; // original magnitudes
+
+ // determines if the current and the next triangle are a quad.
+ int iOrgFaceNumber;
+ int iFlag, iTSpacesOffs;
+ unsigned char vert_num[4];
+} STriInfo;
+
+typedef struct {
+ SVec3 vOs;
+ float fMagS;
+ SVec3 vOt;
+ float fMagT;
+ int iCounter; // this is to average back into quads.
+ tbool bOrient;
+} STSpace;
+
+static int GenerateInitialVerticesIndexList(STriInfo pTriInfos[], int piTriList_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
+static void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
+static void InitTriInfo(STriInfo pTriInfos[], const int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
+static int Build4RuleGroups(STriInfo pTriInfos[], SGroup pGroups[], int piGroupTrianglesBuffer[], const int piTriListIn[], const int iNrTrianglesIn);
+static tbool GenerateTSpaces(STSpace psTspace[], const STriInfo pTriInfos[], const SGroup pGroups[],
+ const int iNrActiveGroups, const int piTriListIn[], const float fThresCos,
+ const SMikkTSpaceContext * pContext);
+
+static int MakeIndex(const int iFace, const int iVert)
+{
+ assert(iVert>=0 && iVert<4 && iFace>=0);
+ return (iFace<<2) | (iVert&0x3);
+}
+
+static void IndexToData(int * piFace, int * piVert, const int iIndexIn)
+{
+ piVert[0] = iIndexIn&0x3;
+ piFace[0] = iIndexIn>>2;
+}
+
+static STSpace AvgTSpace(const STSpace * pTS0, const STSpace * pTS1)
+{
+ STSpace ts_res;
+
+ // this if is important. Due to floating point precision
+ // averaging when ts0==ts1 will cause a slight difference
+ // which results in tangent space splits later on
+ if (pTS0->fMagS==pTS1->fMagS && pTS0->fMagT==pTS1->fMagT &&
+ veq(pTS0->vOs,pTS1->vOs) && veq(pTS0->vOt, pTS1->vOt))
+ {
+ ts_res.fMagS = pTS0->fMagS;
+ ts_res.fMagT = pTS0->fMagT;
+ ts_res.vOs = pTS0->vOs;
+ ts_res.vOt = pTS0->vOt;
+ }
+ else
+ {
+ ts_res.fMagS = 0.5f*(pTS0->fMagS+pTS1->fMagS);
+ ts_res.fMagT = 0.5f*(pTS0->fMagT+pTS1->fMagT);
+ ts_res.vOs = vadd(pTS0->vOs,pTS1->vOs);
+ ts_res.vOt = vadd(pTS0->vOt,pTS1->vOt);
+ if ( VNotZero(ts_res.vOs) ) ts_res.vOs = Normalize(ts_res.vOs);
+ if ( VNotZero(ts_res.vOt) ) ts_res.vOt = Normalize(ts_res.vOt);
+ }
+
+ return ts_res;
+}
+
+
+
+static SVec3 GetPosition(const SMikkTSpaceContext * pContext, const int index);
+static SVec3 GetNormal(const SMikkTSpaceContext * pContext, const int index);
+static SVec3 GetTexCoord(const SMikkTSpaceContext * pContext, const int index);
+
+
+// degen triangles
+static void DegenPrologue(STriInfo pTriInfos[], int piTriList_out[], const int iNrTrianglesIn, const int iTotTris);
+static void DegenEpilogue(STSpace psTspace[], STriInfo pTriInfos[], int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn, const int iTotTris);
+
+
+tbool genTangSpaceDefault(const SMikkTSpaceContext * pContext)
+{
+ return genTangSpace(pContext, 180.0f);
+}
+
+tbool genTangSpace(const SMikkTSpaceContext * pContext, const float fAngularThreshold)
+{
+ // count nr_triangles
+ int * piTriListIn = NULL, * piGroupTrianglesBuffer = NULL;
+ STriInfo * pTriInfos = NULL;
+ SGroup * pGroups = NULL;
+ STSpace * psTspace = NULL;
+ int iNrTrianglesIn = 0, f=0, t=0, i=0;
+ int iNrTSPaces = 0, iTotTris = 0, iDegenTriangles = 0, iNrMaxGroups = 0;
+ int iNrActiveGroups = 0, index = 0;
+ const int iNrFaces = pContext->m_pInterface->m_getNumFaces(pContext);
+ tbool bRes = TFALSE;
+ const float fThresCos = (float) cos((fAngularThreshold*(float)M_PI)/180.0f);
+
+ // verify all call-backs have been set
+ if ( pContext->m_pInterface->m_getNumFaces==NULL ||
+ pContext->m_pInterface->m_getNumVerticesOfFace==NULL ||
+ pContext->m_pInterface->m_getPosition==NULL ||
+ pContext->m_pInterface->m_getNormal==NULL ||
+ pContext->m_pInterface->m_getTexCoord==NULL )
+ return TFALSE;
+
+ // count triangles on supported faces
+ for (f=0; f<iNrFaces; f++)
+ {
+ const int verts = pContext->m_pInterface->m_getNumVerticesOfFace(pContext, f);
+ if (verts==3) ++iNrTrianglesIn;
+ else if (verts==4) iNrTrianglesIn += 2;
+ }
+ if (iNrTrianglesIn<=0) return TFALSE;
+
+ // allocate memory for an index list
+ piTriListIn = (int *) malloc(sizeof(int)*3*iNrTrianglesIn);
+ pTriInfos = (STriInfo *) malloc(sizeof(STriInfo)*iNrTrianglesIn);
+ if (piTriListIn==NULL || pTriInfos==NULL)
+ {
+ if (piTriListIn!=NULL) free(piTriListIn);
+ if (pTriInfos!=NULL) free(pTriInfos);
+ return TFALSE;
+ }
+
+ // make an initial triangle --> face index list
+ iNrTSPaces = GenerateInitialVerticesIndexList(pTriInfos, piTriListIn, pContext, iNrTrianglesIn);
+
+ // make a welded index list of identical positions and attributes (pos, norm, texc)
+ //printf("gen welded index list begin\n");
+ GenerateSharedVerticesIndexList(piTriListIn, pContext, iNrTrianglesIn);
+ //printf("gen welded index list end\n");
+
+ // Mark all degenerate triangles
+ iTotTris = iNrTrianglesIn;
+ iDegenTriangles = 0;
+ for (t=0; t<iTotTris; t++)
+ {
+ const int i0 = piTriListIn[t*3+0];
+ const int i1 = piTriListIn[t*3+1];
+ const int i2 = piTriListIn[t*3+2];
+ const SVec3 p0 = GetPosition(pContext, i0);
+ const SVec3 p1 = GetPosition(pContext, i1);
+ const SVec3 p2 = GetPosition(pContext, i2);
+ if (veq(p0,p1) || veq(p0,p2) || veq(p1,p2)) // degenerate
+ {
+ pTriInfos[t].iFlag |= MARK_DEGENERATE;
+ ++iDegenTriangles;
+ }
+ }
+ iNrTrianglesIn = iTotTris - iDegenTriangles;
+
+ // mark all triangle pairs that belong to a quad with only one
+ // good triangle. These need special treatment in DegenEpilogue().
+ // Additionally, move all good triangles to the start of
+ // pTriInfos[] and piTriListIn[] without changing order and
+ // put the degenerate triangles last.
+ DegenPrologue(pTriInfos, piTriListIn, iNrTrianglesIn, iTotTris);
+
+
+ // evaluate triangle level attributes and neighbor list
+ //printf("gen neighbors list begin\n");
+ InitTriInfo(pTriInfos, piTriListIn, pContext, iNrTrianglesIn);
+ //printf("gen neighbors list end\n");
+
+
+ // based on the 4 rules, identify groups based on connectivity
+ iNrMaxGroups = iNrTrianglesIn*3;
+ pGroups = (SGroup *) malloc(sizeof(SGroup)*iNrMaxGroups);
+ piGroupTrianglesBuffer = (int *) malloc(sizeof(int)*iNrTrianglesIn*3);
+ if (pGroups==NULL || piGroupTrianglesBuffer==NULL)
+ {
+ if (pGroups!=NULL) free(pGroups);
+ if (piGroupTrianglesBuffer!=NULL) free(piGroupTrianglesBuffer);
+ free(piTriListIn);
+ free(pTriInfos);
+ return TFALSE;
+ }
+ //printf("gen 4rule groups begin\n");
+ iNrActiveGroups =
+ Build4RuleGroups(pTriInfos, pGroups, piGroupTrianglesBuffer, piTriListIn, iNrTrianglesIn);
+ //printf("gen 4rule groups end\n");
+
+ //
+
+ psTspace = (STSpace *) malloc(sizeof(STSpace)*iNrTSPaces);
+ if (psTspace==NULL)
+ {
+ free(piTriListIn);
+ free(pTriInfos);
+ free(pGroups);
+ free(piGroupTrianglesBuffer);
+ return TFALSE;
+ }
+ memset(psTspace, 0, sizeof(STSpace)*iNrTSPaces);
+ for (t=0; t<iNrTSPaces; t++)
+ {
+ psTspace[t].vOs.x=1.0f; psTspace[t].vOs.y=0.0f; psTspace[t].vOs.z=0.0f; psTspace[t].fMagS = 1.0f;
+ psTspace[t].vOt.x=0.0f; psTspace[t].vOt.y=1.0f; psTspace[t].vOt.z=0.0f; psTspace[t].fMagT = 1.0f;
+ }
+
+ // make tspaces, each group is split up into subgroups if necessary
+ // based on fAngularThreshold. Finally a tangent space is made for
+ // every resulting subgroup
+ //printf("gen tspaces begin\n");
+ bRes = GenerateTSpaces(psTspace, pTriInfos, pGroups, iNrActiveGroups, piTriListIn, fThresCos, pContext);
+ //printf("gen tspaces end\n");
+
+ // clean up
+ free(pGroups);
+ free(piGroupTrianglesBuffer);
+
+ if (!bRes) // if an allocation in GenerateTSpaces() failed
+ {
+ // clean up and return false
+ free(pTriInfos); free(piTriListIn); free(psTspace);
+ return TFALSE;
+ }
+
+
+ // degenerate quads with one good triangle will be fixed by copying a space from
+ // the good triangle to the coinciding vertex.
+ // all other degenerate triangles will just copy a space from any good triangle
+ // with the same welded index in piTriListIn[].
+ DegenEpilogue(psTspace, pTriInfos, piTriListIn, pContext, iNrTrianglesIn, iTotTris);
+
+ free(pTriInfos); free(piTriListIn);
+
+ index = 0;
+ for (f=0; f<iNrFaces; f++)
+ {
+ const int verts = pContext->m_pInterface->m_getNumVerticesOfFace(pContext, f);
+ if (verts!=3 && verts!=4) continue;
+
+
+ // I've decided to let degenerate triangles and group-with-anythings
+ // vary between left/right hand coordinate systems at the vertices.
+ // All healthy triangles on the other hand are built to always be either or.
+
+ /*// force the coordinate system orientation to be uniform for every face.
+ // (this is already the case for good triangles but not for
+ // degenerate ones and those with bGroupWithAnything==true)
+ bool bOrient = psTspace[index].bOrient;
+ if (psTspace[index].iCounter == 0) // tspace was not derived from a group
+ {
+ // look for a space created in GenerateTSpaces() by iCounter>0
+ bool bNotFound = true;
+ int i=1;
+ while (i<verts && bNotFound)
+ {
+ if (psTspace[index+i].iCounter > 0) bNotFound=false;
+ else ++i;
+ }
+ if (!bNotFound) bOrient = psTspace[index+i].bOrient;
+ }*/
+
+ // set data
+ for (i=0; i<verts; i++)
+ {
+ const STSpace * pTSpace = &psTspace[index];
+ float tang[] = {pTSpace->vOs.x, pTSpace->vOs.y, pTSpace->vOs.z};
+ float bitang[] = {pTSpace->vOt.x, pTSpace->vOt.y, pTSpace->vOt.z};
+ if (pContext->m_pInterface->m_setTSpace!=NULL)
+ pContext->m_pInterface->m_setTSpace(pContext, tang, bitang, pTSpace->fMagS, pTSpace->fMagT, pTSpace->bOrient, f, i);
+ if (pContext->m_pInterface->m_setTSpaceBasic!=NULL)
+ pContext->m_pInterface->m_setTSpaceBasic(pContext, tang, pTSpace->bOrient==TTRUE ? 1.0f : (-1.0f), f, i);
+
+ ++index;
+ }
+ }
+
+ free(psTspace);
+
+
+ return TTRUE;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+typedef struct {
+ float vert[3];
+ int index;
+} STmpVert;
+
+static const int g_iCells = 2048;
+
+#ifdef _MSC_VER
+# define NOINLINE __declspec(noinline)
+#else
+# define NOINLINE __attribute__ ((noinline))
+#endif
+
+// it is IMPORTANT that this function is called to evaluate the hash since
+// inlining could potentially reorder instructions and generate different
+// results for the same effective input value fVal.
+static NOINLINE int FindGridCell(const float fMin, const float fMax, const float fVal)
+{
+ const float fIndex = g_iCells * ((fVal-fMin)/(fMax-fMin));
+ const int iIndex = (int)fIndex;
+ return iIndex < g_iCells ? (iIndex >= 0 ? iIndex : 0) : (g_iCells - 1);
+}
+
+static void MergeVertsFast(int piTriList_in_and_out[], STmpVert pTmpVert[], const SMikkTSpaceContext * pContext, const int iL_in, const int iR_in);
+static void MergeVertsSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int pTable[], const int iEntries);
+static void GenerateSharedVerticesIndexListSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
+
+static void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
+{
+
+ // Generate bounding box
+ int * piHashTable=NULL, * piHashCount=NULL, * piHashOffsets=NULL, * piHashCount2=NULL;
+ STmpVert * pTmpVert = NULL;
+ int i=0, iChannel=0, k=0, e=0;
+ int iMaxCount=0;
+ SVec3 vMin = GetPosition(pContext, 0), vMax = vMin, vDim;
+ float fMin, fMax;
+ for (i=1; i<(iNrTrianglesIn*3); i++)
+ {
+ const int index = piTriList_in_and_out[i];
+
+ const SVec3 vP = GetPosition(pContext, index);
+ if (vMin.x > vP.x) vMin.x = vP.x;
+ else if (vMax.x < vP.x) vMax.x = vP.x;
+ if (vMin.y > vP.y) vMin.y = vP.y;
+ else if (vMax.y < vP.y) vMax.y = vP.y;
+ if (vMin.z > vP.z) vMin.z = vP.z;
+ else if (vMax.z < vP.z) vMax.z = vP.z;
+ }
+
+ vDim = vsub(vMax,vMin);
+ iChannel = 0;
+ fMin = vMin.x; fMax=vMax.x;
+ if (vDim.y>vDim.x && vDim.y>vDim.z)
+ {
+ iChannel=1;
+ fMin = vMin.y;
+ fMax = vMax.y;
+ }
+ else if (vDim.z>vDim.x)
+ {
+ iChannel=2;
+ fMin = vMin.z;
+ fMax = vMax.z;
+ }
+
+ // make allocations
+ piHashTable = (int *) malloc(sizeof(int)*iNrTrianglesIn*3);
+ piHashCount = (int *) malloc(sizeof(int)*g_iCells);
+ piHashOffsets = (int *) malloc(sizeof(int)*g_iCells);
+ piHashCount2 = (int *) malloc(sizeof(int)*g_iCells);
+
+ if (piHashTable==NULL || piHashCount==NULL || piHashOffsets==NULL || piHashCount2==NULL)
+ {
+ if (piHashTable!=NULL) free(piHashTable);
+ if (piHashCount!=NULL) free(piHashCount);
+ if (piHashOffsets!=NULL) free(piHashOffsets);
+ if (piHashCount2!=NULL) free(piHashCount2);
+ GenerateSharedVerticesIndexListSlow(piTriList_in_and_out, pContext, iNrTrianglesIn);
+ return;
+ }
+ memset(piHashCount, 0, sizeof(int)*g_iCells);
+ memset(piHashCount2, 0, sizeof(int)*g_iCells);
+
+ // count amount of elements in each cell unit
+ for (i=0; i<(iNrTrianglesIn*3); i++)
+ {
+ const int index = piTriList_in_and_out[i];
+ const SVec3 vP = GetPosition(pContext, index);
+ const float fVal = iChannel==0 ? vP.x : (iChannel==1 ? vP.y : vP.z);
+ const int iCell = FindGridCell(fMin, fMax, fVal);
+ ++piHashCount[iCell];
+ }
+
+ // evaluate start index of each cell.
+ piHashOffsets[0]=0;
+ for (k=1; k<g_iCells; k++)
+ piHashOffsets[k]=piHashOffsets[k-1]+piHashCount[k-1];
+
+ // insert vertices
+ for (i=0; i<(iNrTrianglesIn*3); i++)
+ {
+ const int index = piTriList_in_and_out[i];
+ const SVec3 vP = GetPosition(pContext, index);
+ const float fVal = iChannel==0 ? vP.x : (iChannel==1 ? vP.y : vP.z);
+ const int iCell = FindGridCell(fMin, fMax, fVal);
+ int * pTable = NULL;
+
+ assert(piHashCount2[iCell]<piHashCount[iCell]);
+ pTable = &piHashTable[piHashOffsets[iCell]];
+ pTable[piHashCount2[iCell]] = i; // vertex i has been inserted.
+ ++piHashCount2[iCell];
+ }
+ for (k=0; k<g_iCells; k++)
+ assert(piHashCount2[k] == piHashCount[k]); // verify the count
+ free(piHashCount2);
+
+ // find maximum amount of entries in any hash entry
+ iMaxCount = piHashCount[0];
+ for (k=1; k<g_iCells; k++)
+ if (iMaxCount<piHashCount[k])
+ iMaxCount=piHashCount[k];
+ pTmpVert = (STmpVert *) malloc(sizeof(STmpVert)*iMaxCount);
+
+
+ // complete the merge
+ for (k=0; k<g_iCells; k++)
+ {
+ // extract table of cell k and amount of entries in it
+ int * pTable = &piHashTable[piHashOffsets[k]];
+ const int iEntries = piHashCount[k];
+ if (iEntries < 2) continue;
+
+ if (pTmpVert!=NULL)
+ {
+ for (e=0; e<iEntries; e++)
+ {
+ int i = pTable[e];
+ const SVec3 vP = GetPosition(pContext, piTriList_in_and_out[i]);
+ pTmpVert[e].vert[0] = vP.x; pTmpVert[e].vert[1] = vP.y;
+ pTmpVert[e].vert[2] = vP.z; pTmpVert[e].index = i;
+ }
+ MergeVertsFast(piTriList_in_and_out, pTmpVert, pContext, 0, iEntries-1);
+ }
+ else
+ MergeVertsSlow(piTriList_in_and_out, pContext, pTable, iEntries);
+ }
+
+ if (pTmpVert!=NULL) { free(pTmpVert); }
+ free(piHashTable);
+ free(piHashCount);
+ free(piHashOffsets);
+}
+
+static void MergeVertsFast(int piTriList_in_and_out[], STmpVert pTmpVert[], const SMikkTSpaceContext * pContext, const int iL_in, const int iR_in)
+{
+ // make bbox
+ int c=0, l=0, channel=0;
+ float fvMin[3], fvMax[3];
+ float dx=0, dy=0, dz=0, fSep=0;
+ for (c=0; c<3; c++)
+ { fvMin[c]=pTmpVert[iL_in].vert[c]; fvMax[c]=fvMin[c]; }
+ for (l=(iL_in+1); l<=iR_in; l++) {
+ for (c=0; c<3; c++) {
+ if (fvMin[c]>pTmpVert[l].vert[c]) fvMin[c]=pTmpVert[l].vert[c];
+ if (fvMax[c]<pTmpVert[l].vert[c]) fvMax[c]=pTmpVert[l].vert[c];
+ }
+ }
+
+ dx = fvMax[0]-fvMin[0];
+ dy = fvMax[1]-fvMin[1];
+ dz = fvMax[2]-fvMin[2];
+
+ channel = 0;
+ if (dy>dx && dy>dz) channel=1;
+ else if (dz>dx) channel=2;
+
+ fSep = 0.5f*(fvMax[channel]+fvMin[channel]);
+
+ // stop if all vertices are NaNs
+ if (!isfinite(fSep))
+ return;
+
+ // terminate recursion when the separation/average value
+ // is no longer strictly between fMin and fMax values.
+ if (fSep>=fvMax[channel] || fSep<=fvMin[channel])
+ {
+ // complete the weld
+ for (l=iL_in; l<=iR_in; l++)
+ {
+ int i = pTmpVert[l].index;
+ const int index = piTriList_in_and_out[i];
+ const SVec3 vP = GetPosition(pContext, index);
+ const SVec3 vN = GetNormal(pContext, index);
+ const SVec3 vT = GetTexCoord(pContext, index);
+
+ tbool bNotFound = TTRUE;
+ int l2=iL_in, i2rec=-1;
+ while (l2<l && bNotFound)
+ {
+ const int i2 = pTmpVert[l2].index;
+ const int index2 = piTriList_in_and_out[i2];
+ const SVec3 vP2 = GetPosition(pContext, index2);
+ const SVec3 vN2 = GetNormal(pContext, index2);
+ const SVec3 vT2 = GetTexCoord(pContext, index2);
+ i2rec=i2;
+
+ //if (vP==vP2 && vN==vN2 && vT==vT2)
+ if (vP.x==vP2.x && vP.y==vP2.y && vP.z==vP2.z &&
+ vN.x==vN2.x && vN.y==vN2.y && vN.z==vN2.z &&
+ vT.x==vT2.x && vT.y==vT2.y && vT.z==vT2.z)
+ bNotFound = TFALSE;
+ else
+ ++l2;
+ }
+
+ // merge if previously found
+ if (!bNotFound)
+ piTriList_in_and_out[i] = piTriList_in_and_out[i2rec];
+ }
+ }
+ else
+ {
+ int iL=iL_in, iR=iR_in;
+ assert((iR_in-iL_in)>0); // at least 2 entries
+
+ // separate (by fSep) all points between iL_in and iR_in in pTmpVert[]
+ while (iL < iR)
+ {
+ tbool bReadyLeftSwap = TFALSE, bReadyRightSwap = TFALSE;
+ while ((!bReadyLeftSwap) && iL<iR)
+ {
+ assert(iL>=iL_in && iL<=iR_in);
+ bReadyLeftSwap = !(pTmpVert[iL].vert[channel]<fSep);
+ if (!bReadyLeftSwap) ++iL;
+ }
+ while ((!bReadyRightSwap) && iL<iR)
+ {
+ assert(iR>=iL_in && iR<=iR_in);
+ bReadyRightSwap = pTmpVert[iR].vert[channel]<fSep;
+ if (!bReadyRightSwap) --iR;
+ }
+ assert( (iL<iR) || !(bReadyLeftSwap && bReadyRightSwap) );
+
+ if (bReadyLeftSwap && bReadyRightSwap)
+ {
+ const STmpVert sTmp = pTmpVert[iL];
+ assert(iL<iR);
+ pTmpVert[iL] = pTmpVert[iR];
+ pTmpVert[iR] = sTmp;
+ ++iL; --iR;
+ }
+ }
+
+ assert(iL==(iR+1) || (iL==iR));
+ if (iL==iR)
+ {
+ const tbool bReadyRightSwap = pTmpVert[iR].vert[channel]<fSep;
+ if (bReadyRightSwap) ++iL;
+ else --iR;
+ }
+
+ // only need to weld when there is more than 1 instance of the (x,y,z)
+ if (iL_in < iR)
+ MergeVertsFast(piTriList_in_and_out, pTmpVert, pContext, iL_in, iR); // weld all left of fSep
+ if (iL < iR_in)
+ MergeVertsFast(piTriList_in_and_out, pTmpVert, pContext, iL, iR_in); // weld all right of (or equal to) fSep
+ }
+}
+
+static void MergeVertsSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int pTable[], const int iEntries)
+{
+ // this can be optimized further using a tree structure or more hashing.
+ int e=0;
+ for (e=0; e<iEntries; e++)
+ {
+ int i = pTable[e];
+ const int index = piTriList_in_and_out[i];
+ const SVec3 vP = GetPosition(pContext, index);
+ const SVec3 vN = GetNormal(pContext, index);
+ const SVec3 vT = GetTexCoord(pContext, index);
+
+ tbool bNotFound = TTRUE;
+ int e2=0, i2rec=-1;
+ while (e2<e && bNotFound)
+ {
+ const int i2 = pTable[e2];
+ const int index2 = piTriList_in_and_out[i2];
+ const SVec3 vP2 = GetPosition(pContext, index2);
+ const SVec3 vN2 = GetNormal(pContext, index2);
+ const SVec3 vT2 = GetTexCoord(pContext, index2);
+ i2rec = i2;
+
+ if (veq(vP,vP2) && veq(vN,vN2) && veq(vT,vT2))
+ bNotFound = TFALSE;
+ else
+ ++e2;
+ }
+
+ // merge if previously found
+ if (!bNotFound)
+ piTriList_in_and_out[i] = piTriList_in_and_out[i2rec];
+ }
+}
+
+static void GenerateSharedVerticesIndexListSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
+{
+ int iNumUniqueVerts = 0, t=0, i=0;
+ for (t=0; t<iNrTrianglesIn; t++)
+ {
+ for (i=0; i<3; i++)
+ {
+ const int offs = t*3 + i;
+ const int index = piTriList_in_and_out[offs];
+
+ const SVec3 vP = GetPosition(pContext, index);
+ const SVec3 vN = GetNormal(pContext, index);
+ const SVec3 vT = GetTexCoord(pContext, index);
+
+ tbool bFound = TFALSE;
+ int t2=0, index2rec=-1;
+ while (!bFound && t2<=t)
+ {
+ int j=0;
+ while (!bFound && j<3)
+ {
+ const int index2 = piTriList_in_and_out[t2*3 + j];
+ const SVec3 vP2 = GetPosition(pContext, index2);
+ const SVec3 vN2 = GetNormal(pContext, index2);
+ const SVec3 vT2 = GetTexCoord(pContext, index2);
+
+ if (veq(vP,vP2) && veq(vN,vN2) && veq(vT,vT2))
+ bFound = TTRUE;
+ else
+ ++j;
+ }
+ if (!bFound) ++t2;
+ }
+
+ assert(bFound);
+ // if we found our own
+ if (index2rec == index) { ++iNumUniqueVerts; }
+
+ piTriList_in_and_out[offs] = index2rec;
+ }
+ }
+}
+
+static int GenerateInitialVerticesIndexList(STriInfo pTriInfos[], int piTriList_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
+{
+ int iTSpacesOffs = 0, f=0, t=0;
+ int iDstTriIndex = 0;
+ for (f=0; f<pContext->m_pInterface->m_getNumFaces(pContext); f++)
+ {
+ const int verts = pContext->m_pInterface->m_getNumVerticesOfFace(pContext, f);
+ if (verts!=3 && verts!=4) continue;
+
+ pTriInfos[iDstTriIndex].iOrgFaceNumber = f;
+ pTriInfos[iDstTriIndex].iTSpacesOffs = iTSpacesOffs;
+
+ if (verts==3)
+ {
+ unsigned char * pVerts = pTriInfos[iDstTriIndex].vert_num;
+ pVerts[0]=0; pVerts[1]=1; pVerts[2]=2;
+ piTriList_out[iDstTriIndex*3+0] = MakeIndex(f, 0);
+ piTriList_out[iDstTriIndex*3+1] = MakeIndex(f, 1);
+ piTriList_out[iDstTriIndex*3+2] = MakeIndex(f, 2);
+ ++iDstTriIndex; // next
+ }
+ else
+ {
+ {
+ pTriInfos[iDstTriIndex+1].iOrgFaceNumber = f;
+ pTriInfos[iDstTriIndex+1].iTSpacesOffs = iTSpacesOffs;
+ }
+
+ {
+ // need an order independent way to evaluate
+ // tspace on quads. This is done by splitting
+ // along the shortest diagonal.
+ const int i0 = MakeIndex(f, 0);
+ const int i1 = MakeIndex(f, 1);
+ const int i2 = MakeIndex(f, 2);
+ const int i3 = MakeIndex(f, 3);
+ const SVec3 T0 = GetTexCoord(pContext, i0);
+ const SVec3 T1 = GetTexCoord(pContext, i1);
+ const SVec3 T2 = GetTexCoord(pContext, i2);
+ const SVec3 T3 = GetTexCoord(pContext, i3);
+ const float distSQ_02 = LengthSquared(vsub(T2,T0));
+ const float distSQ_13 = LengthSquared(vsub(T3,T1));
+ tbool bQuadDiagIs_02;
+ if (distSQ_02<distSQ_13)
+ bQuadDiagIs_02 = TTRUE;
+ else if (distSQ_13<distSQ_02)
+ bQuadDiagIs_02 = TFALSE;
+ else
+ {
+ const SVec3 P0 = GetPosition(pContext, i0);
+ const SVec3 P1 = GetPosition(pContext, i1);
+ const SVec3 P2 = GetPosition(pContext, i2);
+ const SVec3 P3 = GetPosition(pContext, i3);
+ const float distSQ_02 = LengthSquared(vsub(P2,P0));
+ const float distSQ_13 = LengthSquared(vsub(P3,P1));
+
+ bQuadDiagIs_02 = distSQ_13<distSQ_02 ? TFALSE : TTRUE;
+ }
+
+ if (bQuadDiagIs_02)
+ {
+ {
+ unsigned char * pVerts_A = pTriInfos[iDstTriIndex].vert_num;
+ pVerts_A[0]=0; pVerts_A[1]=1; pVerts_A[2]=2;
+ }
+ piTriList_out[iDstTriIndex*3+0] = i0;
+ piTriList_out[iDstTriIndex*3+1] = i1;
+ piTriList_out[iDstTriIndex*3+2] = i2;
+ ++iDstTriIndex; // next
+ {
+ unsigned char * pVerts_B = pTriInfos[iDstTriIndex].vert_num;
+ pVerts_B[0]=0; pVerts_B[1]=2; pVerts_B[2]=3;
+ }
+ piTriList_out[iDstTriIndex*3+0] = i0;
+ piTriList_out[iDstTriIndex*3+1] = i2;
+ piTriList_out[iDstTriIndex*3+2] = i3;
+ ++iDstTriIndex; // next
+ }
+ else
+ {
+ {
+ unsigned char * pVerts_A = pTriInfos[iDstTriIndex].vert_num;
+ pVerts_A[0]=0; pVerts_A[1]=1; pVerts_A[2]=3;
+ }
+ piTriList_out[iDstTriIndex*3+0] = i0;
+ piTriList_out[iDstTriIndex*3+1] = i1;
+ piTriList_out[iDstTriIndex*3+2] = i3;
+ ++iDstTriIndex; // next
+ {
+ unsigned char * pVerts_B = pTriInfos[iDstTriIndex].vert_num;
+ pVerts_B[0]=1; pVerts_B[1]=2; pVerts_B[2]=3;
+ }
+ piTriList_out[iDstTriIndex*3+0] = i1;
+ piTriList_out[iDstTriIndex*3+1] = i2;
+ piTriList_out[iDstTriIndex*3+2] = i3;
+ ++iDstTriIndex; // next
+ }
+ }
+ }
+
+ iTSpacesOffs += verts;
+ assert(iDstTriIndex<=iNrTrianglesIn);
+ }
+
+ for (t=0; t<iNrTrianglesIn; t++)
+ pTriInfos[t].iFlag = 0;
+
+ // return total amount of tspaces
+ return iTSpacesOffs;
+}
+
+static SVec3 GetPosition(const SMikkTSpaceContext * pContext, const int index)
+{
+ int iF, iI;
+ SVec3 res; float pos[3];
+ IndexToData(&iF, &iI, index);
+ pContext->m_pInterface->m_getPosition(pContext, pos, iF, iI);
+ res.x=pos[0]; res.y=pos[1]; res.z=pos[2];
+ return res;
+}
+
+static SVec3 GetNormal(const SMikkTSpaceContext * pContext, const int index)
+{
+ int iF, iI;
+ SVec3 res; float norm[3];
+ IndexToData(&iF, &iI, index);
+ pContext->m_pInterface->m_getNormal(pContext, norm, iF, iI);
+ res.x=norm[0]; res.y=norm[1]; res.z=norm[2];
+ return res;
+}
+
+static SVec3 GetTexCoord(const SMikkTSpaceContext * pContext, const int index)
+{
+ int iF, iI;
+ SVec3 res; float texc[2];
+ IndexToData(&iF, &iI, index);
+ pContext->m_pInterface->m_getTexCoord(pContext, texc, iF, iI);
+ res.x=texc[0]; res.y=texc[1]; res.z=1.0f;
+ return res;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+typedef union {
+ struct
+ {
+ int i0, i1, f;
+ };
+ int array[3];
+} SEdge;
+
+static void BuildNeighborsFast(STriInfo pTriInfos[], SEdge * pEdges, const int piTriListIn[], const int iNrTrianglesIn);
+static void BuildNeighborsSlow(STriInfo pTriInfos[], const int piTriListIn[], const int iNrTrianglesIn);
+
+// returns the texture area times 2
+static float CalcTexArea(const SMikkTSpaceContext * pContext, const int indices[])
+{
+ const SVec3 t1 = GetTexCoord(pContext, indices[0]);
+ const SVec3 t2 = GetTexCoord(pContext, indices[1]);
+ const SVec3 t3 = GetTexCoord(pContext, indices[2]);
+
+ const float t21x = t2.x-t1.x;
+ const float t21y = t2.y-t1.y;
+ const float t31x = t3.x-t1.x;
+ const float t31y = t3.y-t1.y;
+
+ const float fSignedAreaSTx2 = t21x*t31y - t21y*t31x;
+
+ return fSignedAreaSTx2<0 ? (-fSignedAreaSTx2) : fSignedAreaSTx2;
+}
+
+static void InitTriInfo(STriInfo pTriInfos[], const int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
+{
+ int f=0, i=0, t=0;
+ // pTriInfos[f].iFlag is cleared in GenerateInitialVerticesIndexList() which is called before this function.
+
+ // generate neighbor info list
+ for (f=0; f<iNrTrianglesIn; f++)
+ for (i=0; i<3; i++)
+ {
+ pTriInfos[f].FaceNeighbors[i] = -1;
+ pTriInfos[f].AssignedGroup[i] = NULL;
+
+ pTriInfos[f].vOs.x=0.0f; pTriInfos[f].vOs.y=0.0f; pTriInfos[f].vOs.z=0.0f;
+ pTriInfos[f].vOt.x=0.0f; pTriInfos[f].vOt.y=0.0f; pTriInfos[f].vOt.z=0.0f;
+ pTriInfos[f].fMagS = 0;
+ pTriInfos[f].fMagT = 0;
+
+ // assumed bad
+ pTriInfos[f].iFlag |= GROUP_WITH_ANY;
+ }
+
+ // evaluate first order derivatives
+ for (f=0; f<iNrTrianglesIn; f++)
+ {
+ // initial values
+ const SVec3 v1 = GetPosition(pContext, piTriListIn[f*3+0]);
+ const SVec3 v2 = GetPosition(pContext, piTriListIn[f*3+1]);
+ const SVec3 v3 = GetPosition(pContext, piTriListIn[f*3+2]);
+ const SVec3 t1 = GetTexCoord(pContext, piTriListIn[f*3+0]);
+ const SVec3 t2 = GetTexCoord(pContext, piTriListIn[f*3+1]);
+ const SVec3 t3 = GetTexCoord(pContext, piTriListIn[f*3+2]);
+
+ const float t21x = t2.x-t1.x;
+ const float t21y = t2.y-t1.y;
+ const float t31x = t3.x-t1.x;
+ const float t31y = t3.y-t1.y;
+ const SVec3 d1 = vsub(v2,v1);
+ const SVec3 d2 = vsub(v3,v1);
+
+ const float fSignedAreaSTx2 = t21x*t31y - t21y*t31x;
+ //assert(fSignedAreaSTx2!=0);
+ SVec3 vOs = vsub(vscale(t31y,d1), vscale(t21y,d2)); // eq 18
+ SVec3 vOt = vadd(vscale(-t31x,d1), vscale(t21x,d2)); // eq 19
+
+ pTriInfos[f].iFlag |= (fSignedAreaSTx2>0 ? ORIENT_PRESERVING : 0);
+
+ if ( NotZero(fSignedAreaSTx2) )
+ {
+ const float fAbsArea = fabsf(fSignedAreaSTx2);
+ const float fLenOs = Length(vOs);
+ const float fLenOt = Length(vOt);
+ const float fS = (pTriInfos[f].iFlag&ORIENT_PRESERVING)==0 ? (-1.0f) : 1.0f;
+ if ( NotZero(fLenOs) ) pTriInfos[f].vOs = vscale(fS/fLenOs, vOs);
+ if ( NotZero(fLenOt) ) pTriInfos[f].vOt = vscale(fS/fLenOt, vOt);
+
+ // evaluate magnitudes prior to normalization of vOs and vOt
+ pTriInfos[f].fMagS = fLenOs / fAbsArea;
+ pTriInfos[f].fMagT = fLenOt / fAbsArea;
+
+ // if this is a good triangle
+ if ( NotZero(pTriInfos[f].fMagS) && NotZero(pTriInfos[f].fMagT))
+ pTriInfos[f].iFlag &= (~GROUP_WITH_ANY);
+ }
+ }
+
+ // force otherwise healthy quads to a fixed orientation
+ while (t<(iNrTrianglesIn-1))
+ {
+ const int iFO_a = pTriInfos[t].iOrgFaceNumber;
+ const int iFO_b = pTriInfos[t+1].iOrgFaceNumber;
+ if (iFO_a==iFO_b) // this is a quad
+ {
+ const tbool bIsDeg_a = (pTriInfos[t].iFlag&MARK_DEGENERATE)!=0 ? TTRUE : TFALSE;
+ const tbool bIsDeg_b = (pTriInfos[t+1].iFlag&MARK_DEGENERATE)!=0 ? TTRUE : TFALSE;
+
+ // bad triangles should already have been removed by
+ // DegenPrologue(), but just in case check bIsDeg_a and bIsDeg_a are false
+ if ((bIsDeg_a||bIsDeg_b)==TFALSE)
+ {
+ const tbool bOrientA = (pTriInfos[t].iFlag&ORIENT_PRESERVING)!=0 ? TTRUE : TFALSE;
+ const tbool bOrientB = (pTriInfos[t+1].iFlag&ORIENT_PRESERVING)!=0 ? TTRUE : TFALSE;
+ // if this happens the quad has extremely bad mapping!!
+ if (bOrientA!=bOrientB)
+ {
+ //printf("found quad with bad mapping\n");
+ tbool bChooseOrientFirstTri = TFALSE;
+ if ((pTriInfos[t+1].iFlag&GROUP_WITH_ANY)!=0) bChooseOrientFirstTri = TTRUE;
+ else if ( CalcTexArea(pContext, &piTriListIn[t*3+0]) >= CalcTexArea(pContext, &piTriListIn[(t+1)*3+0]) )
+ bChooseOrientFirstTri = TTRUE;
+
+ // force match
+ {
+ const int t0 = bChooseOrientFirstTri ? t : (t+1);
+ const int t1 = bChooseOrientFirstTri ? (t+1) : t;
+ pTriInfos[t1].iFlag &= (~ORIENT_PRESERVING); // clear first
+ pTriInfos[t1].iFlag |= (pTriInfos[t0].iFlag&ORIENT_PRESERVING); // copy bit
+ }
+ }
+ }
+ t += 2;
+ }
+ else
+ ++t;
+ }
+
+ // match up edge pairs
+ {
+ SEdge * pEdges = (SEdge *) malloc(sizeof(SEdge)*iNrTrianglesIn*3);
+ if (pEdges==NULL)
+ BuildNeighborsSlow(pTriInfos, piTriListIn, iNrTrianglesIn);
+ else
+ {
+ BuildNeighborsFast(pTriInfos, pEdges, piTriListIn, iNrTrianglesIn);
+
+ free(pEdges);
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static tbool AssignRecur(const int piTriListIn[], STriInfo psTriInfos[], const int iMyTriIndex, SGroup * pGroup);
+static void AddTriToGroup(SGroup * pGroup, const int iTriIndex);
+
+static int Build4RuleGroups(STriInfo pTriInfos[], SGroup pGroups[], int piGroupTrianglesBuffer[], const int piTriListIn[], const int iNrTrianglesIn)
+{
+ const int iNrMaxGroups = iNrTrianglesIn*3;
+ int iNrActiveGroups = 0;
+ int iOffset = 0, f=0, i=0;
+ (void)iNrMaxGroups; /* quiet warnings in non debug mode */
+ for (f=0; f<iNrTrianglesIn; f++)
+ {
+ for (i=0; i<3; i++)
+ {
+ // if not assigned to a group
+ if ((pTriInfos[f].iFlag&GROUP_WITH_ANY)==0 && pTriInfos[f].AssignedGroup[i]==NULL)
+ {
+ tbool bOrPre;
+ int neigh_indexL, neigh_indexR;
+ const int vert_index = piTriListIn[f*3+i];
+ assert(iNrActiveGroups<iNrMaxGroups);
+ pTriInfos[f].AssignedGroup[i] = &pGroups[iNrActiveGroups];
+ pTriInfos[f].AssignedGroup[i]->iVertexRepresentitive = vert_index;
+ pTriInfos[f].AssignedGroup[i]->bOrientPreservering = (pTriInfos[f].iFlag&ORIENT_PRESERVING)!=0;
+ pTriInfos[f].AssignedGroup[i]->iNrFaces = 0;
+ pTriInfos[f].AssignedGroup[i]->pFaceIndices = &piGroupTrianglesBuffer[iOffset];
+ ++iNrActiveGroups;
+
+ AddTriToGroup(pTriInfos[f].AssignedGroup[i], f);
+ bOrPre = (pTriInfos[f].iFlag&ORIENT_PRESERVING)!=0 ? TTRUE : TFALSE;
+ neigh_indexL = pTriInfos[f].FaceNeighbors[i];
+ neigh_indexR = pTriInfos[f].FaceNeighbors[i>0?(i-1):2];
+ if (neigh_indexL>=0) // neighbor
+ {
+ const tbool bAnswer =
+ AssignRecur(piTriListIn, pTriInfos, neigh_indexL,
+ pTriInfos[f].AssignedGroup[i] );
+
+ const tbool bOrPre2 = (pTriInfos[neigh_indexL].iFlag&ORIENT_PRESERVING)!=0 ? TTRUE : TFALSE;
+ const tbool bDiff = bOrPre!=bOrPre2 ? TTRUE : TFALSE;
+ assert(bAnswer || bDiff);
+ (void)bAnswer, (void)bDiff; /* quiet warnings in non debug mode */
+ }
+ if (neigh_indexR>=0) // neighbor
+ {
+ const tbool bAnswer =
+ AssignRecur(piTriListIn, pTriInfos, neigh_indexR,
+ pTriInfos[f].AssignedGroup[i] );
+
+ const tbool bOrPre2 = (pTriInfos[neigh_indexR].iFlag&ORIENT_PRESERVING)!=0 ? TTRUE : TFALSE;
+ const tbool bDiff = bOrPre!=bOrPre2 ? TTRUE : TFALSE;
+ assert(bAnswer || bDiff);
+ (void)bAnswer, (void)bDiff; /* quiet warnings in non debug mode */
+ }
+
+ // update offset
+ iOffset += pTriInfos[f].AssignedGroup[i]->iNrFaces;
+ // since the groups are disjoint a triangle can never
+ // belong to more than 3 groups. Subsequently something
+ // is completely screwed if this assertion ever hits.
+ assert(iOffset <= iNrMaxGroups);
+ }
+ }
+ }
+
+ return iNrActiveGroups;
+}
+
+static void AddTriToGroup(SGroup * pGroup, const int iTriIndex)
+{
+ pGroup->pFaceIndices[pGroup->iNrFaces] = iTriIndex;
+ ++pGroup->iNrFaces;
+}
+
+static tbool AssignRecur(const int piTriListIn[], STriInfo psTriInfos[],
+ const int iMyTriIndex, SGroup * pGroup)
+{
+ STriInfo * pMyTriInfo = &psTriInfos[iMyTriIndex];
+
+ // track down vertex
+ const int iVertRep = pGroup->iVertexRepresentitive;
+ const int * pVerts = &piTriListIn[3*iMyTriIndex+0];
+ int i=-1;
+ if (pVerts[0]==iVertRep) i=0;
+ else if (pVerts[1]==iVertRep) i=1;
+ else if (pVerts[2]==iVertRep) i=2;
+ assert(i>=0 && i<3);
+
+ // early out
+ if (pMyTriInfo->AssignedGroup[i] == pGroup) return TTRUE;
+ else if (pMyTriInfo->AssignedGroup[i]!=NULL) return TFALSE;
+ if ((pMyTriInfo->iFlag&GROUP_WITH_ANY)!=0)
+ {
+ // first to group with a group-with-anything triangle
+ // determines it's orientation.
+ // This is the only existing order dependency in the code!!
+ if ( pMyTriInfo->AssignedGroup[0] == NULL &&
+ pMyTriInfo->AssignedGroup[1] == NULL &&
+ pMyTriInfo->AssignedGroup[2] == NULL )
+ {
+ pMyTriInfo->iFlag &= (~ORIENT_PRESERVING);
+ pMyTriInfo->iFlag |= (pGroup->bOrientPreservering ? ORIENT_PRESERVING : 0);
+ }
+ }
+ {
+ const tbool bOrient = (pMyTriInfo->iFlag&ORIENT_PRESERVING)!=0 ? TTRUE : TFALSE;
+ if (bOrient != pGroup->bOrientPreservering) return TFALSE;
+ }
+
+ AddTriToGroup(pGroup, iMyTriIndex);
+ pMyTriInfo->AssignedGroup[i] = pGroup;
+
+ {
+ const int neigh_indexL = pMyTriInfo->FaceNeighbors[i];
+ const int neigh_indexR = pMyTriInfo->FaceNeighbors[i>0?(i-1):2];
+ if (neigh_indexL>=0)
+ AssignRecur(piTriListIn, psTriInfos, neigh_indexL, pGroup);
+ if (neigh_indexR>=0)
+ AssignRecur(piTriListIn, psTriInfos, neigh_indexR, pGroup);
+ }
+
+
+
+ return TTRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static tbool CompareSubGroups(const SSubGroup * pg1, const SSubGroup * pg2);
+static void QuickSort(int* pSortBuffer, int iLeft, int iRight, unsigned int uSeed);
+static STSpace EvalTspace(int face_indices[], const int iFaces, const int piTriListIn[], const STriInfo pTriInfos[], const SMikkTSpaceContext * pContext, const int iVertexRepresentitive);
+
+static tbool GenerateTSpaces(STSpace psTspace[], const STriInfo pTriInfos[], const SGroup pGroups[],
+ const int iNrActiveGroups, const int piTriListIn[], const float fThresCos,
+ const SMikkTSpaceContext * pContext)
+{
+ STSpace * pSubGroupTspace = NULL;
+ SSubGroup * pUniSubGroups = NULL;
+ int * pTmpMembers = NULL;
+ int iMaxNrFaces=0, iUniqueTspaces=0, g=0, i=0;
+ for (g=0; g<iNrActiveGroups; g++)
+ if (iMaxNrFaces < pGroups[g].iNrFaces)
+ iMaxNrFaces = pGroups[g].iNrFaces;
+
+ if (iMaxNrFaces == 0) return TTRUE;
+
+ // make initial allocations
+ pSubGroupTspace = (STSpace *) malloc(sizeof(STSpace)*iMaxNrFaces);
+ pUniSubGroups = (SSubGroup *) malloc(sizeof(SSubGroup)*iMaxNrFaces);
+ pTmpMembers = (int *) malloc(sizeof(int)*iMaxNrFaces);
+ if (pSubGroupTspace==NULL || pUniSubGroups==NULL || pTmpMembers==NULL)
+ {
+ if (pSubGroupTspace!=NULL) free(pSubGroupTspace);
+ if (pUniSubGroups!=NULL) free(pUniSubGroups);
+ if (pTmpMembers!=NULL) free(pTmpMembers);
+ return TFALSE;
+ }
+
+
+ iUniqueTspaces = 0;
+ for (g=0; g<iNrActiveGroups; g++)
+ {
+ const SGroup * pGroup = &pGroups[g];
+ int iUniqueSubGroups = 0, s=0;
+
+ for (i=0; i<pGroup->iNrFaces; i++) // triangles
+ {
+ const int f = pGroup->pFaceIndices[i]; // triangle number
+ int index=-1, iVertIndex=-1, iOF_1=-1, iMembers=0, j=0, l=0;
+ SSubGroup tmp_group;
+ tbool bFound;
+ SVec3 n, vOs, vOt;
+ if (pTriInfos[f].AssignedGroup[0]==pGroup) index=0;
+ else if (pTriInfos[f].AssignedGroup[1]==pGroup) index=1;
+ else if (pTriInfos[f].AssignedGroup[2]==pGroup) index=2;
+ assert(index>=0 && index<3);
+
+ iVertIndex = piTriListIn[f*3+index];
+ assert(iVertIndex==pGroup->iVertexRepresentitive);
+
+ // is normalized already
+ n = GetNormal(pContext, iVertIndex);
+
+ // project
+ vOs = vsub(pTriInfos[f].vOs, vscale(vdot(n,pTriInfos[f].vOs), n));
+ vOt = vsub(pTriInfos[f].vOt, vscale(vdot(n,pTriInfos[f].vOt), n));
+ if ( VNotZero(vOs) ) vOs = Normalize(vOs);
+ if ( VNotZero(vOt) ) vOt = Normalize(vOt);
+
+ // original face number
+ iOF_1 = pTriInfos[f].iOrgFaceNumber;
+
+ iMembers = 0;
+ for (j=0; j<pGroup->iNrFaces; j++)
+ {
+ const int t = pGroup->pFaceIndices[j]; // triangle number
+ const int iOF_2 = pTriInfos[t].iOrgFaceNumber;
+
+ // project
+ SVec3 vOs2 = vsub(pTriInfos[t].vOs, vscale(vdot(n,pTriInfos[t].vOs), n));
+ SVec3 vOt2 = vsub(pTriInfos[t].vOt, vscale(vdot(n,pTriInfos[t].vOt), n));
+ if ( VNotZero(vOs2) ) vOs2 = Normalize(vOs2);
+ if ( VNotZero(vOt2) ) vOt2 = Normalize(vOt2);
+
+ {
+ const tbool bAny = ( (pTriInfos[f].iFlag | pTriInfos[t].iFlag) & GROUP_WITH_ANY )!=0 ? TTRUE : TFALSE;
+ // make sure triangles which belong to the same quad are joined.
+ const tbool bSameOrgFace = iOF_1==iOF_2 ? TTRUE : TFALSE;
+
+ const float fCosS = vdot(vOs,vOs2);
+ const float fCosT = vdot(vOt,vOt2);
+
+ assert(f!=t || bSameOrgFace); // sanity check
+ if (bAny || bSameOrgFace || (fCosS>fThresCos && fCosT>fThresCos))
+ pTmpMembers[iMembers++] = t;
+ }
+ }
+
+ // sort pTmpMembers
+ tmp_group.iNrFaces = iMembers;
+ tmp_group.pTriMembers = pTmpMembers;
+ if (iMembers>1)
+ {
+ unsigned int uSeed = INTERNAL_RND_SORT_SEED; // could replace with a random seed?
+ QuickSort(pTmpMembers, 0, iMembers-1, uSeed);
+ }
+
+ // look for an existing match
+ bFound = TFALSE;
+ l=0;
+ while (l<iUniqueSubGroups && !bFound)
+ {
+ bFound = CompareSubGroups(&tmp_group, &pUniSubGroups[l]);
+ if (!bFound) ++l;
+ }
+
+ // assign tangent space index
+ assert(bFound || l==iUniqueSubGroups);
+ //piTempTangIndices[f*3+index] = iUniqueTspaces+l;
+
+ // if no match was found we allocate a new subgroup
+ if (!bFound)
+ {
+ // insert new subgroup
+ int * pIndices = (int *) malloc(sizeof(int)*iMembers);
+ if (pIndices==NULL)
+ {
+ // clean up and return false
+ int s=0;
+ for (s=0; s<iUniqueSubGroups; s++)
+ free(pUniSubGroups[s].pTriMembers);
+ free(pUniSubGroups);
+ free(pTmpMembers);
+ free(pSubGroupTspace);
+ return TFALSE;
+ }
+ pUniSubGroups[iUniqueSubGroups].iNrFaces = iMembers;
+ pUniSubGroups[iUniqueSubGroups].pTriMembers = pIndices;
+ memcpy(pIndices, tmp_group.pTriMembers, iMembers*sizeof(int));
+ pSubGroupTspace[iUniqueSubGroups] =
+ EvalTspace(tmp_group.pTriMembers, iMembers, piTriListIn, pTriInfos, pContext, pGroup->iVertexRepresentitive);
+ ++iUniqueSubGroups;
+ }
+
+ // output tspace
+ {
+ const int iOffs = pTriInfos[f].iTSpacesOffs;
+ const int iVert = pTriInfos[f].vert_num[index];
+ STSpace * pTS_out = &psTspace[iOffs+iVert];
+ assert(pTS_out->iCounter<2);
+ assert(((pTriInfos[f].iFlag&ORIENT_PRESERVING)!=0) == pGroup->bOrientPreservering);
+ if (pTS_out->iCounter==1)
+ {
+ *pTS_out = AvgTSpace(pTS_out, &pSubGroupTspace[l]);
+ pTS_out->iCounter = 2; // update counter
+ pTS_out->bOrient = pGroup->bOrientPreservering;
+ }
+ else
+ {
+ assert(pTS_out->iCounter==0);
+ *pTS_out = pSubGroupTspace[l];
+ pTS_out->iCounter = 1; // update counter
+ pTS_out->bOrient = pGroup->bOrientPreservering;
+ }
+ }
+ }
+
+ // clean up and offset iUniqueTspaces
+ for (s=0; s<iUniqueSubGroups; s++)
+ free(pUniSubGroups[s].pTriMembers);
+ iUniqueTspaces += iUniqueSubGroups;
+ }
+
+ // clean up
+ free(pUniSubGroups);
+ free(pTmpMembers);
+ free(pSubGroupTspace);
+
+ return TTRUE;
+}
+
+static STSpace EvalTspace(int face_indices[], const int iFaces, const int piTriListIn[], const STriInfo pTriInfos[],
+ const SMikkTSpaceContext * pContext, const int iVertexRepresentitive)
+{
+ STSpace res;
+ float fAngleSum = 0;
+ int face=0;
+ res.vOs.x=0.0f; res.vOs.y=0.0f; res.vOs.z=0.0f;
+ res.vOt.x=0.0f; res.vOt.y=0.0f; res.vOt.z=0.0f;
+ res.fMagS = 0; res.fMagT = 0;
+
+ for (face=0; face<iFaces; face++)
+ {
+ const int f = face_indices[face];
+
+ // only valid triangles get to add their contribution
+ if ( (pTriInfos[f].iFlag&GROUP_WITH_ANY)==0 )
+ {
+ SVec3 n, vOs, vOt, p0, p1, p2, v1, v2;
+ float fCos, fAngle, fMagS, fMagT;
+ int i=-1, index=-1, i0=-1, i1=-1, i2=-1;
+ if (piTriListIn[3*f+0]==iVertexRepresentitive) i=0;
+ else if (piTriListIn[3*f+1]==iVertexRepresentitive) i=1;
+ else if (piTriListIn[3*f+2]==iVertexRepresentitive) i=2;
+ assert(i>=0 && i<3);
+
+ // project
+ index = piTriListIn[3*f+i];
+ n = GetNormal(pContext, index);
+ vOs = vsub(pTriInfos[f].vOs, vscale(vdot(n,pTriInfos[f].vOs), n));
+ vOt = vsub(pTriInfos[f].vOt, vscale(vdot(n,pTriInfos[f].vOt), n));
+ if ( VNotZero(vOs) ) vOs = Normalize(vOs);
+ if ( VNotZero(vOt) ) vOt = Normalize(vOt);
+
+ i2 = piTriListIn[3*f + (i<2?(i+1):0)];
+ i1 = piTriListIn[3*f + i];
+ i0 = piTriListIn[3*f + (i>0?(i-1):2)];
+
+ p0 = GetPosition(pContext, i0);
+ p1 = GetPosition(pContext, i1);
+ p2 = GetPosition(pContext, i2);
+ v1 = vsub(p0,p1);
+ v2 = vsub(p2,p1);
+
+ // project
+ v1 = vsub(v1, vscale(vdot(n,v1),n)); if ( VNotZero(v1) ) v1 = Normalize(v1);
+ v2 = vsub(v2, vscale(vdot(n,v2),n)); if ( VNotZero(v2) ) v2 = Normalize(v2);
+
+ // weight contribution by the angle
+ // between the two edge vectors
+ fCos = vdot(v1,v2); fCos=fCos>1?1:(fCos<(-1) ? (-1) : fCos);
+ fAngle = (float) acos(fCos);
+ fMagS = pTriInfos[f].fMagS;
+ fMagT = pTriInfos[f].fMagT;
+
+ res.vOs=vadd(res.vOs, vscale(fAngle,vOs));
+ res.vOt=vadd(res.vOt,vscale(fAngle,vOt));
+ res.fMagS+=(fAngle*fMagS);
+ res.fMagT+=(fAngle*fMagT);
+ fAngleSum += fAngle;
+ }
+ }
+
+ // normalize
+ if ( VNotZero(res.vOs) ) res.vOs = Normalize(res.vOs);
+ if ( VNotZero(res.vOt) ) res.vOt = Normalize(res.vOt);
+ if (fAngleSum>0)
+ {
+ res.fMagS /= fAngleSum;
+ res.fMagT /= fAngleSum;
+ }
+
+ return res;
+}
+
+static tbool CompareSubGroups(const SSubGroup * pg1, const SSubGroup * pg2)
+{
+ tbool bStillSame=TTRUE;
+ int i=0;
+ if (pg1->iNrFaces!=pg2->iNrFaces) return TFALSE;
+ while (i<pg1->iNrFaces && bStillSame)
+ {
+ bStillSame = pg1->pTriMembers[i]==pg2->pTriMembers[i] ? TTRUE : TFALSE;
+ if (bStillSame) ++i;
+ }
+ return bStillSame;
+}
+
+static void QuickSort(int* pSortBuffer, int iLeft, int iRight, unsigned int uSeed)
+{
+ int iL, iR, n, index, iMid, iTmp;
+
+ // Random
+ unsigned int t=uSeed&31;
+ t=(uSeed<<t)|(uSeed>>(32-t));
+ uSeed=uSeed+t+3;
+ // Random end
+
+ iL=iLeft; iR=iRight;
+ n = (iR-iL)+1;
+ assert(n>=0);
+ index = (int) (uSeed%n);
+
+ iMid=pSortBuffer[index + iL];
+
+
+ do
+ {
+ while (pSortBuffer[iL] < iMid)
+ ++iL;
+ while (pSortBuffer[iR] > iMid)
+ --iR;
+
+ if (iL <= iR)
+ {
+ iTmp = pSortBuffer[iL];
+ pSortBuffer[iL] = pSortBuffer[iR];
+ pSortBuffer[iR] = iTmp;
+ ++iL; --iR;
+ }
+ }
+ while (iL <= iR);
+
+ if (iLeft < iR)
+ QuickSort(pSortBuffer, iLeft, iR, uSeed);
+ if (iL < iRight)
+ QuickSort(pSortBuffer, iL, iRight, uSeed);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+static void QuickSortEdges(SEdge * pSortBuffer, int iLeft, int iRight, const int channel, unsigned int uSeed);
+static void GetEdge(int * i0_out, int * i1_out, int * edgenum_out, const int indices[], const int i0_in, const int i1_in);
+
+static void BuildNeighborsFast(STriInfo pTriInfos[], SEdge * pEdges, const int piTriListIn[], const int iNrTrianglesIn)
+{
+ // build array of edges
+ unsigned int uSeed = INTERNAL_RND_SORT_SEED; // could replace with a random seed?
+ int iEntries=0, iCurStartIndex=-1, f=0, i=0;
+ for (f=0; f<iNrTrianglesIn; f++)
+ for (i=0; i<3; i++)
+ {
+ const int i0 = piTriListIn[f*3+i];
+ const int i1 = piTriListIn[f*3+(i<2?(i+1):0)];
+ pEdges[f*3+i].i0 = i0 < i1 ? i0 : i1; // put minimum index in i0
+ pEdges[f*3+i].i1 = !(i0 < i1) ? i0 : i1; // put maximum index in i1
+ pEdges[f*3+i].f = f; // record face number
+ }
+
+ // sort over all edges by i0, this is the pricy one.
+ QuickSortEdges(pEdges, 0, iNrTrianglesIn*3-1, 0, uSeed); // sort channel 0 which is i0
+
+ // sub sort over i1, should be fast.
+ // could replace this with a 64 bit int sort over (i0,i1)
+ // with i0 as msb in the quicksort call above.
+ iEntries = iNrTrianglesIn*3;
+ iCurStartIndex = 0;
+ for (i=1; i<iEntries; i++)
+ {
+ if (pEdges[iCurStartIndex].i0 != pEdges[i].i0)
+ {
+ const int iL = iCurStartIndex;
+ const int iR = i-1;
+ //const int iElems = i-iL;
+ iCurStartIndex = i;
+ QuickSortEdges(pEdges, iL, iR, 1, uSeed); // sort channel 1 which is i1
+ }
+ }
+
+ // sub sort over f, which should be fast.
+ // this step is to remain compliant with BuildNeighborsSlow() when
+ // more than 2 triangles use the same edge (such as a butterfly topology).
+ iCurStartIndex = 0;
+ for (i=1; i<iEntries; i++)
+ {
+ if (pEdges[iCurStartIndex].i0 != pEdges[i].i0 || pEdges[iCurStartIndex].i1 != pEdges[i].i1)
+ {
+ const int iL = iCurStartIndex;
+ const int iR = i-1;
+ //const int iElems = i-iL;
+ iCurStartIndex = i;
+ QuickSortEdges(pEdges, iL, iR, 2, uSeed); // sort channel 2 which is f
+ }
+ }
+
+ // pair up, adjacent triangles
+ for (i=0; i<iEntries; i++)
+ {
+ const int i0=pEdges[i].i0;
+ const int i1=pEdges[i].i1;
+ const int f = pEdges[i].f;
+ tbool bUnassigned_A;
+
+ int i0_A, i1_A;
+ int edgenum_A, edgenum_B=0; // 0,1 or 2
+ GetEdge(&i0_A, &i1_A, &edgenum_A, &piTriListIn[f*3], i0, i1); // resolve index ordering and edge_num
+ bUnassigned_A = pTriInfos[f].FaceNeighbors[edgenum_A] == -1 ? TTRUE : TFALSE;
+
+ if (bUnassigned_A)
+ {
+ // get true index ordering
+ int j=i+1, t;
+ tbool bNotFound = TTRUE;
+ while (j<iEntries && i0==pEdges[j].i0 && i1==pEdges[j].i1 && bNotFound)
+ {
+ tbool bUnassigned_B;
+ int i0_B, i1_B;
+ t = pEdges[j].f;
+ // flip i0_B and i1_B
+ GetEdge(&i1_B, &i0_B, &edgenum_B, &piTriListIn[t*3], pEdges[j].i0, pEdges[j].i1); // resolve index ordering and edge_num
+ //assert(!(i0_A==i1_B && i1_A==i0_B));
+ bUnassigned_B = pTriInfos[t].FaceNeighbors[edgenum_B]==-1 ? TTRUE : TFALSE;
+ if (i0_A==i0_B && i1_A==i1_B && bUnassigned_B)
+ bNotFound = TFALSE;
+ else
+ ++j;
+ }
+
+ if (!bNotFound)
+ {
+ int t = pEdges[j].f;
+ pTriInfos[f].FaceNeighbors[edgenum_A] = t;
+ //assert(pTriInfos[t].FaceNeighbors[edgenum_B]==-1);
+ pTriInfos[t].FaceNeighbors[edgenum_B] = f;
+ }
+ }
+ }
+}
+
+static void BuildNeighborsSlow(STriInfo pTriInfos[], const int piTriListIn[], const int iNrTrianglesIn)
+{
+ int f=0, i=0;
+ for (f=0; f<iNrTrianglesIn; f++)
+ {
+ for (i=0; i<3; i++)
+ {
+ // if unassigned
+ if (pTriInfos[f].FaceNeighbors[i] == -1)
+ {
+ const int i0_A = piTriListIn[f*3+i];
+ const int i1_A = piTriListIn[f*3+(i<2?(i+1):0)];
+
+ // search for a neighbor
+ tbool bFound = TFALSE;
+ int t=0, j=0;
+ while (!bFound && t<iNrTrianglesIn)
+ {
+ if (t!=f)
+ {
+ j=0;
+ while (!bFound && j<3)
+ {
+ // in rev order
+ const int i1_B = piTriListIn[t*3+j];
+ const int i0_B = piTriListIn[t*3+(j<2?(j+1):0)];
+ //assert(!(i0_A==i1_B && i1_A==i0_B));
+ if (i0_A==i0_B && i1_A==i1_B)
+ bFound = TTRUE;
+ else
+ ++j;
+ }
+ }
+
+ if (!bFound) ++t;
+ }
+
+ // assign neighbors
+ if (bFound)
+ {
+ pTriInfos[f].FaceNeighbors[i] = t;
+ //assert(pTriInfos[t].FaceNeighbors[j]==-1);
+ pTriInfos[t].FaceNeighbors[j] = f;
+ }
+ }
+ }
+ }
+}
+
+static void QuickSortEdges(SEdge * pSortBuffer, int iLeft, int iRight, const int channel, unsigned int uSeed)
+{
+ unsigned int t;
+ int iL, iR, n, index, iMid;
+
+ // early out
+ SEdge sTmp;
+ const int iElems = iRight-iLeft+1;
+ if (iElems<2) return;
+ else if (iElems==2)
+ {
+ if (pSortBuffer[iLeft].array[channel] > pSortBuffer[iRight].array[channel])
+ {
+ sTmp = pSortBuffer[iLeft];
+ pSortBuffer[iLeft] = pSortBuffer[iRight];
+ pSortBuffer[iRight] = sTmp;
+ }
+ return;
+ }
+
+ // Random
+ t=uSeed&31;
+ t=(uSeed<<t)|(uSeed>>(32-t));
+ uSeed=uSeed+t+3;
+ // Random end
+
+ iL = iLeft;
+ iR = iRight;
+ n = (iR-iL)+1;
+ assert(n>=0);
+ index = (int) (uSeed%n);
+
+ iMid=pSortBuffer[index + iL].array[channel];
+
+ do
+ {
+ while (pSortBuffer[iL].array[channel] < iMid)
+ ++iL;
+ while (pSortBuffer[iR].array[channel] > iMid)
+ --iR;
+
+ if (iL <= iR)
+ {
+ sTmp = pSortBuffer[iL];
+ pSortBuffer[iL] = pSortBuffer[iR];
+ pSortBuffer[iR] = sTmp;
+ ++iL; --iR;
+ }
+ }
+ while (iL <= iR);
+
+ if (iLeft < iR)
+ QuickSortEdges(pSortBuffer, iLeft, iR, channel, uSeed);
+ if (iL < iRight)
+ QuickSortEdges(pSortBuffer, iL, iRight, channel, uSeed);
+}
+
+// resolve ordering and edge number
+static void GetEdge(int * i0_out, int * i1_out, int * edgenum_out, const int indices[], const int i0_in, const int i1_in)
+{
+ *edgenum_out = -1;
+
+ // test if first index is on the edge
+ if (indices[0]==i0_in || indices[0]==i1_in)
+ {
+ // test if second index is on the edge
+ if (indices[1]==i0_in || indices[1]==i1_in)
+ {
+ edgenum_out[0]=0; // first edge
+ i0_out[0]=indices[0];
+ i1_out[0]=indices[1];
+ }
+ else
+ {
+ edgenum_out[0]=2; // third edge
+ i0_out[0]=indices[2];
+ i1_out[0]=indices[0];
+ }
+ }
+ else
+ {
+ // only second and third index is on the edge
+ edgenum_out[0]=1; // second edge
+ i0_out[0]=indices[1];
+ i1_out[0]=indices[2];
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////// Degenerate triangles ////////////////////////////////////
+
+static void DegenPrologue(STriInfo pTriInfos[], int piTriList_out[], const int iNrTrianglesIn, const int iTotTris)
+{
+ int iNextGoodTriangleSearchIndex=-1;
+ tbool bStillFindingGoodOnes;
+
+ // locate quads with only one good triangle
+ int t=0;
+ while (t<(iTotTris-1))
+ {
+ const int iFO_a = pTriInfos[t].iOrgFaceNumber;
+ const int iFO_b = pTriInfos[t+1].iOrgFaceNumber;
+ if (iFO_a==iFO_b) // this is a quad
+ {
+ const tbool bIsDeg_a = (pTriInfos[t].iFlag&MARK_DEGENERATE)!=0 ? TTRUE : TFALSE;
+ const tbool bIsDeg_b = (pTriInfos[t+1].iFlag&MARK_DEGENERATE)!=0 ? TTRUE : TFALSE;
+ if ((bIsDeg_a^bIsDeg_b)!=0)
+ {
+ pTriInfos[t].iFlag |= QUAD_ONE_DEGEN_TRI;
+ pTriInfos[t+1].iFlag |= QUAD_ONE_DEGEN_TRI;
+ }
+ t += 2;
+ }
+ else
+ ++t;
+ }
+
+ // reorder list so all degen triangles are moved to the back
+ // without reordering the good triangles
+ iNextGoodTriangleSearchIndex = 1;
+ t=0;
+ bStillFindingGoodOnes = TTRUE;
+ while (t<iNrTrianglesIn && bStillFindingGoodOnes)
+ {
+ const tbool bIsGood = (pTriInfos[t].iFlag&MARK_DEGENERATE)==0 ? TTRUE : TFALSE;
+ if (bIsGood)
+ {
+ if (iNextGoodTriangleSearchIndex < (t+2))
+ iNextGoodTriangleSearchIndex = t+2;
+ }
+ else
+ {
+ int t0, t1;
+ // search for the first good triangle.
+ tbool bJustADegenerate = TTRUE;
+ while (bJustADegenerate && iNextGoodTriangleSearchIndex<iTotTris)
+ {
+ const tbool bIsGood = (pTriInfos[iNextGoodTriangleSearchIndex].iFlag&MARK_DEGENERATE)==0 ? TTRUE : TFALSE;
+ if (bIsGood) bJustADegenerate=TFALSE;
+ else ++iNextGoodTriangleSearchIndex;
+ }
+
+ t0 = t;
+ t1 = iNextGoodTriangleSearchIndex;
+ ++iNextGoodTriangleSearchIndex;
+ assert(iNextGoodTriangleSearchIndex > (t+1));
+
+ // swap triangle t0 and t1
+ if (!bJustADegenerate)
+ {
+ int i=0;
+ for (i=0; i<3; i++)
+ {
+ const int index = piTriList_out[t0*3+i];
+ piTriList_out[t0*3+i] = piTriList_out[t1*3+i];
+ piTriList_out[t1*3+i] = index;
+ }
+ {
+ const STriInfo tri_info = pTriInfos[t0];
+ pTriInfos[t0] = pTriInfos[t1];
+ pTriInfos[t1] = tri_info;
+ }
+ }
+ else
+ bStillFindingGoodOnes = TFALSE; // this is not supposed to happen
+ }
+
+ if (bStillFindingGoodOnes) ++t;
+ }
+
+ assert(bStillFindingGoodOnes); // code will still work.
+ assert(iNrTrianglesIn == t);
+}
+
+static void DegenEpilogue(STSpace psTspace[], STriInfo pTriInfos[], int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn, const int iTotTris)
+{
+ int t=0, i=0;
+ // deal with degenerate triangles
+ // punishment for degenerate triangles is O(N^2)
+ for (t=iNrTrianglesIn; t<iTotTris; t++)
+ {
+ // degenerate triangles on a quad with one good triangle are skipped
+ // here but processed in the next loop
+ const tbool bSkip = (pTriInfos[t].iFlag&QUAD_ONE_DEGEN_TRI)!=0 ? TTRUE : TFALSE;
+
+ if (!bSkip)
+ {
+ for (i=0; i<3; i++)
+ {
+ const int index1 = piTriListIn[t*3+i];
+ // search through the good triangles
+ tbool bNotFound = TTRUE;
+ int j=0;
+ while (bNotFound && j<(3*iNrTrianglesIn))
+ {
+ const int index2 = piTriListIn[j];
+ if (index1==index2) bNotFound=TFALSE;
+ else ++j;
+ }
+
+ if (!bNotFound)
+ {
+ const int iTri = j/3;
+ const int iVert = j%3;
+ const int iSrcVert=pTriInfos[iTri].vert_num[iVert];
+ const int iSrcOffs=pTriInfos[iTri].iTSpacesOffs;
+ const int iDstVert=pTriInfos[t].vert_num[i];
+ const int iDstOffs=pTriInfos[t].iTSpacesOffs;
+
+ // copy tspace
+ psTspace[iDstOffs+iDstVert] = psTspace[iSrcOffs+iSrcVert];
+ }
+ }
+ }
+ }
+
+ // deal with degenerate quads with one good triangle
+ for (t=0; t<iNrTrianglesIn; t++)
+ {
+ // this triangle belongs to a quad where the
+ // other triangle is degenerate
+ if ( (pTriInfos[t].iFlag&QUAD_ONE_DEGEN_TRI)!=0 )
+ {
+ SVec3 vDstP;
+ int iOrgF=-1, i=0;
+ tbool bNotFound;
+ unsigned char * pV = pTriInfos[t].vert_num;
+ int iFlag = (1<<pV[0]) | (1<<pV[1]) | (1<<pV[2]);
+ int iMissingIndex = 0;
+ if ((iFlag&2)==0) iMissingIndex=1;
+ else if ((iFlag&4)==0) iMissingIndex=2;
+ else if ((iFlag&8)==0) iMissingIndex=3;
+
+ iOrgF = pTriInfos[t].iOrgFaceNumber;
+ vDstP = GetPosition(pContext, MakeIndex(iOrgF, iMissingIndex));
+ bNotFound = TTRUE;
+ i=0;
+ while (bNotFound && i<3)
+ {
+ const int iVert = pV[i];
+ const SVec3 vSrcP = GetPosition(pContext, MakeIndex(iOrgF, iVert));
+ if (veq(vSrcP, vDstP)==TTRUE)
+ {
+ const int iOffs = pTriInfos[t].iTSpacesOffs;
+ psTspace[iOffs+iMissingIndex] = psTspace[iOffs+iVert];
+ bNotFound=TFALSE;
+ }
+ else
+ ++i;
+ }
+ assert(!bNotFound);
+ }
+ }
+}
diff --git a/mons_3d/include/camera.h b/mons_3d/include/camera.h
new file mode 100644
index 0000000..be795bb
--- /dev/null
+++ b/mons_3d/include/camera.h
@@ -0,0 +1,12 @@
+#ifndef MONS_CAMERA_H
+#define MONS_CAMERA_H
+
+#include "projection.h"
+#include "transform.h"
+
+typedef struct mons_camera {
+ mons_transform transform;
+ mons_projection projection;
+} mons_camera;
+
+#endif
diff --git a/mons_3d/include/color.h b/mons_3d/include/color.h
new file mode 100644
index 0000000..85b68c0
--- /dev/null
+++ b/mons_3d/include/color.h
@@ -0,0 +1,12 @@
+#ifndef MONS_COLOR_H
+#define MONS_COLOR_H
+
+#include "mons_math/vec4.h"
+
+#define MONS_COLOR_BLACK (mons_vec4){0,0,0,1}
+#define MONS_COLOR_WHITE MONS_VEC4_ONE
+#define MONS_COLOR_RED (mons_vec4){1,0,0,1}
+#define MONS_COLOR_GREEN (mons_vec4){0,1,0,1}
+#define MONS_COLOR_BLUE (mons_vec4){0,0,1,1}
+
+#endif
diff --git a/mons_3d/include/light.h b/mons_3d/include/light.h
new file mode 100644
index 0000000..8f1aac2
--- /dev/null
+++ b/mons_3d/include/light.h
@@ -0,0 +1,12 @@
+#ifndef MONS_LIGHT_H
+#define MONS_LIGHT_H
+
+#include "transform.h"
+#include "mons_math/vec4.h"
+
+typedef struct mons_directional_light {
+ mons_transform transform;
+ mons_vec4 color;
+} mons_directional_light;
+
+#endif
diff --git a/mons_3d/include/mesh.h b/mons_3d/include/mesh.h
new file mode 100644
index 0000000..3794697
--- /dev/null
+++ b/mons_3d/include/mesh.h
@@ -0,0 +1,14 @@
+#ifndef MONS_MESH_H
+#define MONS_MESH_H
+
+struct mons_vertex;
+typedef unsigned int mons_vao;
+
+typedef struct mons_mesh {
+ mons_vao vao;
+ unsigned int element_count;
+} mons_mesh;
+
+mons_mesh mons_create_mesh(struct mons_vertex *vertex_array, int vertex_count, int *index_array, int index_count);
+
+#endif
diff --git a/mons_3d/include/model.h b/mons_3d/include/model.h
new file mode 100644
index 0000000..9059d64
--- /dev/null
+++ b/mons_3d/include/model.h
@@ -0,0 +1,19 @@
+#ifndef MONS_MODEL_H
+#define MONS_MODEL_H
+
+#include "mesh.h"
+#include "shader.h"
+#include "transform.h"
+#include "texture.h"
+
+typedef struct mons_model {
+ mons_mesh mesh;
+ mons_program shader;
+ mons_transform transform;
+ mons_texture *textures;
+ unsigned int textures_len;
+} mons_model;
+
+void mons_model_draw(mons_model model);
+
+#endif
diff --git a/mons_3d/include/projection.h b/mons_3d/include/projection.h
new file mode 100644
index 0000000..df0f716
--- /dev/null
+++ b/mons_3d/include/projection.h
@@ -0,0 +1,13 @@
+#ifndef MONS_PROJECTION_H
+#define MONS_PROJECTION_H
+
+typedef struct mons_projection {
+ float near;
+ float far;
+ float fov;
+ float aspect_ratio;
+} mons_projection;
+
+struct mons_mat4 mons_projection_matrix(mons_projection projection);
+
+#endif
diff --git a/mons_3d/include/shader.h b/mons_3d/include/shader.h
new file mode 100644
index 0000000..553c6e4
--- /dev/null
+++ b/mons_3d/include/shader.h
@@ -0,0 +1,35 @@
+#ifndef MONS_SHADER_H
+#define MONS_SHADER_H
+
+#include <glad/gl.h>
+#include <stdbool.h>
+
+typedef unsigned int mons_shader;
+typedef unsigned int mons_program;
+
+typedef enum mons_shader_type {
+ MONS_SHADER_TYPE_VERTEX = GL_VERTEX_SHADER,
+ MONS_SHADER_TYPE_FRAGMENT = GL_FRAGMENT_SHADER,
+} mons_shader_type;
+
+struct mons_vec2;
+struct mons_vec3;
+struct mons_vec4;
+struct mons_mat4;
+
+mons_shader mons_create_shader(mons_shader_type type, char *source, int len);
+mons_program mons_create_program(mons_shader vertex_shader, mons_shader fragment_shader);
+void mons_shader_set_float(mons_program shader, char *uniform_name, float value);
+void mons_shader_set_vec2(mons_program shader, char *uniform_name, struct mons_vec2 value);
+void mons_shader_set_vec3(mons_program shader, char *uniform_name, struct mons_vec3 value);
+void mons_shader_set_vec4(mons_program shader, char *uniform_name, struct mons_vec4 value);
+void mons_shader_set_mat4(mons_program shader, char *uniform_name, struct mons_mat4 value, bool transpose);
+
+void mons_shader_set_float_global(char *uniform_name, float value);
+void mons_shader_set_vec2_global(char *uniform_name, struct mons_vec2 value);
+void mons_shader_set_vec3_global(char *uniform_name, struct mons_vec3 value);
+void mons_shader_set_vec4_global(char *uniform_name, struct mons_vec4 value);
+void mons_shader_set_mat4_global(char *uniform_name, struct mons_mat4 value, bool transpose);
+void mons_shader_apply_global_uniforms(mons_program shader);
+
+#endif
diff --git a/mons_3d/include/texture.h b/mons_3d/include/texture.h
new file mode 100644
index 0000000..4e3d2e4
--- /dev/null
+++ b/mons_3d/include/texture.h
@@ -0,0 +1,19 @@
+#ifndef MONS_TEXTURE_H
+#define MONS_TEXTURE_H
+
+#include "image.h"
+#include "shader.h"
+#include <stdio.h>
+
+typedef struct mons_texture {
+ unsigned int id;
+ unsigned int width;
+ unsigned int height;
+} mons_texture;
+
+mons_texture mons_texture_from_image(mons_image image);
+mons_texture mons_texture_load(FILE *stream);
+
+void mons_texture_bind(mons_program shader, unsigned int unit, mons_texture texture);
+
+#endif
diff --git a/mons_3d/include/transform.h b/mons_3d/include/transform.h
new file mode 100644
index 0000000..840dfc2
--- /dev/null
+++ b/mons_3d/include/transform.h
@@ -0,0 +1,36 @@
+#ifndef MONS_TRANSFORM_H
+#define MONS_TRANSFORM_H
+
+#include "mons_math/mat4.h"
+#include "mons_math/vec3.h"
+#include "mons_math/quat.h"
+
+typedef struct mons_transform {
+ mons_vec3 translation;
+ mons_vec3 scale;
+ mons_quat rotation;
+} mons_transform;
+
+void mons_transform_translate(mons_transform *transform, struct mons_vec3 translation);
+void mons_transform_rotate(mons_transform *transform, struct mons_quat rotation);
+void mons_transform_scale(mons_transform *transform, struct mons_vec3 scale);
+
+mons_mat4 mons_transform_matrix(mons_transform transform);
+
+void mons_transform_set_translation(mons_transform *transform, struct mons_vec3 translation);
+void mons_transform_set_rotation(mons_transform *transform, struct mons_quat rotation);
+void mons_transform_set_scale(mons_transform *transform, struct mons_vec3 scale);
+
+struct mons_vec3 mons_transform_forward(mons_transform transform);
+struct mons_vec3 mons_transform_up(mons_transform transform);
+struct mons_vec3 mons_transform_right(mons_transform transform);
+
+void mons_transform_look_at(mons_transform *transform, mons_vec3 point, mons_vec3 up);
+
+#define MONS_TRANSFORM_IDENTITY (mons_transform) {\
+ MONS_VEC3_ZERO,\
+ MONS_VEC3_ONE,\
+ MONS_QUAT_IDENTITY,\
+}
+
+#endif
diff --git a/mons_3d/include/vertex.h b/mons_3d/include/vertex.h
new file mode 100644
index 0000000..5e95579
--- /dev/null
+++ b/mons_3d/include/vertex.h
@@ -0,0 +1,15 @@
+#ifndef MONS_VERTEX_H
+#define MONS_VERTEX_H
+
+#include "mons_math/vec4.h"
+#include "mons_math/vec3.h"
+#include "mons_math/vec2.h"
+
+typedef struct mons_vertex {
+ mons_vec3 position;
+ mons_vec3 normal;
+ mons_vec4 tangent;
+ mons_vec2 texture_coords;
+} mons_vertex;
+
+#endif
diff --git a/mons_3d/src/color.c b/mons_3d/src/color.c
new file mode 100644
index 0000000..1b1627d
--- /dev/null
+++ b/mons_3d/src/color.c
@@ -0,0 +1 @@
+#include "color.h"
diff --git a/mons_3d/src/mesh.c b/mons_3d/src/mesh.c
new file mode 100644
index 0000000..213a24c
--- /dev/null
+++ b/mons_3d/src/mesh.c
@@ -0,0 +1,124 @@
+#include "mesh.h"
+#include "vertex.h"
+#include "mikktspace.h"
+
+#include <glad/gl.h>
+#include <stdlib.h>
+
+void compute_tangents(mons_vertex *vertex_array, int vertex_count, int *index_array, int index_count);
+
+mons_mesh mons_create_mesh(mons_vertex *vertex_array, int vertex_count, int *index_array, int index_count) {
+ compute_tangents(vertex_array, vertex_count, index_array, index_count);
+ // VAO & VBO
+ unsigned int vao;
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+ unsigned int vbo;
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(mons_vertex) * vertex_count, vertex_array, GL_STATIC_DRAW);
+ unsigned int ebo;
+ glGenBuffers(1, &ebo);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * index_count, index_array, GL_STATIC_DRAW);
+ // Set up vertex attributes
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(mons_vertex), 0);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(mons_vertex), (void*)(sizeof(mons_vec3)));
+ glEnableVertexAttribArray(1);
+ glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(mons_vertex), (void*)(sizeof(mons_vec3) * 2));
+ glEnableVertexAttribArray(2);
+ glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(mons_vertex), (void*)(sizeof(mons_vec3) * 2 + sizeof(mons_vec4)));
+ glEnableVertexAttribArray(3);
+ return (mons_mesh) {
+ .vao = vao,
+ .element_count = index_count,
+ };
+}
+
+struct mesh_data {
+ mons_vertex *vertex_array;
+ int vertex_count;
+ int *index_array;
+ int index_count;
+};
+
+int get_vertex_index(const SMikkTSpaceContext *context, int i_face, int i_vert) {
+ struct mesh_data *mesh_data = context->m_pUserData;
+ int index_index = (i_face * 3) + i_vert;
+ int index = mesh_data->index_array[index_index];
+ return index;
+}
+
+int get_num_faces(const SMikkTSpaceContext *context) {
+ struct mesh_data *mesh_data = context->m_pUserData;
+ return mesh_data->index_count / 3;
+}
+
+int get_num_vertices_of_face(const SMikkTSpaceContext *context, int i_face) {
+ return 3;
+}
+
+void get_position(const SMikkTSpaceContext *context, float *outpos, int i_face, int i_vert) {
+ struct mesh_data *mesh_data = context->m_pUserData;
+ int index = get_vertex_index(context, i_face, i_vert);
+ mons_vertex vertex = mesh_data->vertex_array[index];
+
+ outpos[0] = vertex.position.x;
+ outpos[1] = vertex.position.y;
+ outpos[2] = vertex.position.z;
+}
+
+void get_normal(const SMikkTSpaceContext *context, float *outnormal, int i_face, int i_vert) {
+ struct mesh_data *mesh_data = context->m_pUserData;
+ int index = get_vertex_index(context, i_face, i_vert);
+ mons_vertex vertex = mesh_data->vertex_array[index];
+
+ outnormal[0] = vertex.normal.x;
+ outnormal[1] = vertex.normal.y;
+ outnormal[2] = vertex.normal.z;
+}
+
+void get_tex_coords(const SMikkTSpaceContext *context, float *outuv, int i_face, int i_vert) {
+ struct mesh_data *mesh_data = context->m_pUserData;
+ int index = get_vertex_index(context, i_face, i_vert);
+ mons_vertex vertex = mesh_data->vertex_array[index];
+
+ outuv[0] = vertex.texture_coords.x;
+ outuv[1] = vertex.texture_coords.y;
+}
+
+void set_tspace_basic(const SMikkTSpaceContext *context, const float *tangentu, float f_sign, int i_face, int i_vert) {
+ struct mesh_data *mesh_data = context->m_pUserData;
+ int index = get_vertex_index(context, i_face, i_vert);
+ mons_vertex *vertex = &mesh_data->vertex_array[index];
+
+ vertex->tangent.x = tangentu[0];
+ vertex->tangent.y = tangentu[1];
+ vertex->tangent.z = tangentu[2];
+ vertex->tangent.w = f_sign;
+}
+
+void compute_tangents(mons_vertex *vertex_array, int vertex_count, int *index_array, int index_count) {
+ static SMikkTSpaceInterface iface = {
+ .m_getNumFaces = get_num_faces,
+ .m_getNumVerticesOfFace = get_num_vertices_of_face,
+ .m_getNormal = get_normal,
+ .m_getPosition = get_position,
+ .m_getTexCoord = get_tex_coords,
+ .m_setTSpaceBasic = set_tspace_basic,
+ };
+ struct mesh_data mesh_data = {
+ vertex_array,
+ vertex_count,
+ index_array,
+ index_count,
+ };
+ SMikkTSpaceContext context = {
+ .m_pInterface = &iface,
+ .m_pUserData = &mesh_data,
+ };
+
+ genTangSpaceDefault(&context);
+}
+
diff --git a/mons_3d/src/model.c b/mons_3d/src/model.c
new file mode 100644
index 0000000..ed2e543
--- /dev/null
+++ b/mons_3d/src/model.c
@@ -0,0 +1,15 @@
+#include "model.h"
+#include "texture.h"
+#include "camera.h"
+#include <glad/gl.h>
+
+void mons_model_draw(mons_model model) {
+ glUseProgram(model.shader);
+ mons_shader_apply_global_uniforms(model.shader);
+ mons_shader_set_mat4(model.shader, "transform", mons_transform_matrix(model.transform), GL_TRUE);
+ for (int i = 0; i < model.textures_len; i++) {
+ mons_texture_bind(model.shader, i, model.textures[i]);
+ }
+ glBindVertexArray(model.mesh.vao);
+ glDrawElements(GL_TRIANGLES, model.mesh.element_count, GL_UNSIGNED_INT, 0);
+}
diff --git a/mons_3d/src/projection.c b/mons_3d/src/projection.c
new file mode 100644
index 0000000..287d59e
--- /dev/null
+++ b/mons_3d/src/projection.c
@@ -0,0 +1,15 @@
+#include "projection.h"
+#include <math.h>
+#include "mons_math/mat4.h"
+
+mons_mat4 mons_projection_matrix(mons_projection projection) {
+ float tangent = tanf(projection.fov / 2.0f);
+ float top = projection.near * tangent;
+ float right = top * projection.aspect_ratio;
+ return (mons_mat4){
+ {projection.near / right, 0, 0, 0},
+ {0, projection.near / top, 0, 0},
+ {0, 0, -(projection.far + projection.near) / (projection.far - projection.near), -1},
+ {0, 0, -(2.0f * projection.far * projection.near) / (projection.far - projection.near), 0},
+ };
+}
diff --git a/mons_3d/src/shader.c b/mons_3d/src/shader.c
new file mode 100644
index 0000000..6898a1f
--- /dev/null
+++ b/mons_3d/src/shader.c
@@ -0,0 +1,185 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include "shader.h"
+#include "mons_math/vec4.h"
+#include "mons_math/vec3.h"
+#include "mons_math/vec2.h"
+#include "mons_math/mat4.h"
+#include "hashmap.h"
+#include <stdlib.h>
+
+typedef enum mons_uniform_type {
+ MONS_UNIFORM_INT,
+ MONS_UNIFORM_FLOAT,
+ MONS_UNIFORM_VEC2,
+ MONS_UNIFORM_VEC3,
+ MONS_UNIFORM_VEC4,
+ MONS_UNIFORM_MAT4,
+} mons_uniform_type;
+
+typedef struct mons_uniform_m4 {
+ mons_mat4 matrix;
+ bool transpose;
+} mons_uniform_m4;
+
+typedef union mons_uniform_data {
+ int i;
+ float f;
+ mons_vec2 v2;
+ mons_vec3 v3;
+ mons_vec4 v4;
+ mons_uniform_m4 m4;
+} mons_uniform_data;
+
+typedef struct mons_uniform {
+ mons_uniform_type type;
+ mons_uniform_data data;
+} mons_uniform;
+
+static mons_hashmap *GLOBAL_UNIFORMS = NULL;
+mons_hashmap *get_global_uniforms() {
+ if (GLOBAL_UNIFORMS == NULL) {
+ GLOBAL_UNIFORMS = malloc(sizeof(mons_hashmap));
+ *GLOBAL_UNIFORMS = mons_hashmap_new(sizeof(mons_uniform), 10);
+ }
+ return GLOBAL_UNIFORMS;
+}
+
+void mons_shader_apply_global_uniforms(mons_program shader) {
+ mons_hashmap *global_uniforms = get_global_uniforms();
+ for (int i = 0; i < global_uniforms->len; i++) {
+ mons_hashmap_pair pair;
+ mons_hashmap_at(*global_uniforms, i, &pair);
+ char *name = pair.key;
+ mons_uniform uniform = *(mons_uniform *)pair.value;
+ switch (uniform.type) {
+ case MONS_UNIFORM_INT:
+ // TODO:
+ break;
+ case MONS_UNIFORM_FLOAT:
+ mons_shader_set_float(shader, name, uniform.data.f);
+ break;
+ case MONS_UNIFORM_VEC2:
+ mons_shader_set_vec2(shader, name, uniform.data.v2);
+ break;
+ case MONS_UNIFORM_VEC3:
+ mons_shader_set_vec3(shader, name, uniform.data.v3);
+ break;
+ case MONS_UNIFORM_VEC4:
+ mons_shader_set_vec4(shader, name, uniform.data.v4);
+ break;
+ case MONS_UNIFORM_MAT4:
+ mons_shader_set_mat4(shader, name, uniform.data.m4.matrix, uniform.data.m4.transpose);
+ break;
+ }
+ }
+}
+
+void mons_shader_set_float_global(char *uniform_name, float value) {
+ mons_hashmap *global_uniforms = get_global_uniforms();
+ mons_uniform uniform = {
+ .type = MONS_UNIFORM_FLOAT,
+ .data.f = value,
+ };
+ mons_hashmap_insert(global_uniforms, uniform_name, &uniform);
+}
+
+void mons_shader_set_vec2_global(char *uniform_name, mons_vec2 value) {
+ mons_hashmap *global_uniforms = get_global_uniforms();
+ mons_uniform uniform = {
+ .type = MONS_UNIFORM_VEC2,
+ .data.v2 = value,
+ };
+ mons_hashmap_insert(global_uniforms, uniform_name, &uniform);
+}
+
+void mons_shader_set_vec3_global(char *uniform_name, mons_vec3 value) {
+ mons_hashmap *global_uniforms = get_global_uniforms();
+ mons_uniform uniform = {
+ .type = MONS_UNIFORM_VEC3,
+ .data.v3 = value,
+ };
+ mons_hashmap_insert(global_uniforms, uniform_name, &uniform);
+}
+
+void mons_shader_set_vec4_global(char *uniform_name, mons_vec4 value) {
+ mons_hashmap *global_uniforms = get_global_uniforms();
+ mons_uniform uniform = {
+ .type = MONS_UNIFORM_VEC4,
+ .data.v4 = value,
+ };
+ mons_hashmap_insert(global_uniforms, uniform_name, &uniform);
+}
+
+void mons_shader_set_mat4_global(char *uniform_name, mons_mat4 value, bool transpose) {
+ mons_hashmap *global_uniforms = get_global_uniforms();
+ mons_uniform uniform = {
+ .type = MONS_UNIFORM_MAT4,
+ .data.m4 = {
+ .matrix = value,
+ .transpose = transpose,
+ },
+ };
+ mons_hashmap_insert(global_uniforms, uniform_name, &uniform);
+}
+
+mons_shader mons_create_shader(mons_shader_type shader_type, char *source,
+ int source_length) {
+ unsigned int shader = glCreateShader(shader_type);
+ const char *shader_source = (const char *)source;
+ int shader_len = (int)source_length;
+ glShaderSource(shader, 1, &shader_source, &shader_len);
+ glCompileShader(shader);
+ int success;
+ char info_log[512];
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
+ if (!success) {
+ glGetShaderInfoLog(shader, 512, NULL, info_log);
+ printf("Shader Compilation Failed: %s\n", info_log);
+ }
+ return shader;
+}
+
+mons_program mons_create_program(mons_shader vertex_shader,
+ mons_shader fragment_shader) {
+ unsigned int shader_program = glCreateProgram();
+ glAttachShader(shader_program, vertex_shader);
+ glAttachShader(shader_program, fragment_shader);
+ glLinkProgram(shader_program);
+ int success;
+ char info_log[512];
+ glGetProgramiv(shader_program, GL_LINK_STATUS, &success);
+ if (!success) {
+ glGetProgramInfoLog(shader_program, 512, NULL, info_log);
+ }
+ return shader_program;
+}
+
+void mons_shader_set_float(mons_program shader, char *uniform_name,
+ float value) {
+ glUniform1f(glGetUniformLocation(shader, uniform_name), value);
+}
+
+void mons_shader_set_vec2(mons_program shader, char *uniform_name,
+ mons_vec2 value) {
+ glUniform2fv(glGetUniformLocation(shader, uniform_name), 1,
+ (float *)&value);
+}
+
+void mons_shader_set_vec3(mons_program shader, char *uniform_name,
+ mons_vec3 value) {
+ glUniform3fv(glGetUniformLocation(shader, uniform_name), 1,
+ (float *)&value);
+}
+
+void mons_shader_set_vec4(mons_program shader, char *uniform_name,
+ mons_vec4 value) {
+ glUniform4fv(glGetUniformLocation(shader, uniform_name), 1,
+ (float *)&value);
+}
+
+void mons_shader_set_mat4(mons_program shader, char *uniform_name,
+ mons_mat4 value, bool transpose) {
+ glUniformMatrix4fv(glGetUniformLocation(shader, uniform_name), 1, transpose,
+ (float *)&value);
+}
diff --git a/mons_3d/src/texture.c b/mons_3d/src/texture.c
new file mode 100644
index 0000000..7b2a478
--- /dev/null
+++ b/mons_3d/src/texture.c
@@ -0,0 +1,55 @@
+#include "texture.h"
+#include "qoi.h"
+
+#include <glad/gl.h>
+
+mons_texture mons_texture_load(FILE *stream) {
+ mons_image image = mons_load_qoi(stream);
+ return mons_texture_from_image(image);
+}
+
+mons_texture mons_texture_from_image(mons_image image) {
+ glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST_MIPMAP_LINEAR);
+ glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ unsigned int texture;
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, image.data);
+ glGenerateMipmap(GL_TEXTURE_2D);
+ mons_texture result = {
+ .id = texture,
+ .width = image.width,
+ .height = image.height,
+ };
+ mons_image_free(&image);
+ return result;
+}
+
+char *texure_uniforms[16] = {
+ "base_texture",
+ "normal_texture",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+void mons_texture_bind(mons_program shader, unsigned int unit, mons_texture texture) {
+ glActiveTexture(GL_TEXTURE0 + unit);
+ glUniform1i(glGetUniformLocation(shader, texure_uniforms[unit]), unit);
+ glBindTexture(GL_TEXTURE_2D, texture.id);
+}
diff --git a/mons_3d/src/transform.c b/mons_3d/src/transform.c
new file mode 100644
index 0000000..c4435fc
--- /dev/null
+++ b/mons_3d/src/transform.c
@@ -0,0 +1,112 @@
+#include <math.h>
+#include "transform.h"
+#include "mons_math/vec3.h"
+#include "mons_math/quat.h"
+#include <stdio.h>
+
+mons_mat4 translation_to_mat4(mons_vec3 translation) {
+ mons_mat4 result = MONS_MAT4_IDENTITY;
+ result.m1.w = translation.x;
+ result.m2.w = translation.y;
+ result.m3.w = translation.z;
+ return result;
+}
+
+mons_mat4 scale_to_mat4(mons_vec3 scale) {
+ mons_mat4 result = MONS_MAT4_IDENTITY;
+ result.m1.x = scale.x;
+ result.m2.y = scale.y;
+ result.m3.z = scale.z;
+ return result;
+}
+
+void mons_transform_translate(mons_transform *transform,
+ mons_vec3 translation) {
+ mons_vec3_add_inplace(&transform->translation, translation);
+}
+
+void mons_transform_rotate(mons_transform *transform, mons_quat rotation) {
+ mons_quat_mul_inplace(&transform->rotation, rotation);
+}
+
+void mons_transform_scale(mons_transform *transform, mons_vec3 scale) {
+ mons_vec3_mul_memberwise_inplace(&transform->scale, scale);
+}
+
+mons_mat4 mons_transform_matrix(mons_transform transform) {
+ mons_mat4 translation = translation_to_mat4(transform.translation);
+ mons_mat4 result = translation;
+ mons_mat4_mul_inplace(&result, mons_quat_to_mat4(transform.rotation));
+ mons_mat4_mul_inplace(&result, scale_to_mat4(transform.scale));
+ return result;
+}
+
+mons_vec3 mons_transform_forward(mons_transform transform) {
+ return mons_quat_transform_vec3(transform.rotation, MONS_VEC3_Z);
+}
+
+mons_vec3 mons_transform_up(mons_transform transform) {
+ return mons_quat_transform_vec3(transform.rotation, MONS_VEC3_Y);
+}
+
+mons_vec3 mons_transform_right(mons_transform transform) {
+ return mons_quat_transform_vec3(transform.rotation, MONS_VEC3_X);
+}
+
+void mons_transform_look_at(mons_transform *transform, mons_vec3 point, mons_vec3 up) {
+ mons_vec3 forward = mons_vec3_normalize(mons_vec3_sub(transform->translation, point));
+ mons_vec3 right = mons_vec3_normalize(mons_vec3_cross(up, forward));
+ mons_vec3 new_up = mons_vec3_cross(forward, right);
+ float m00 = right.x;
+ float m01 = right.y;
+ float m02 = right.z;
+ float m10 = new_up.x;
+ float m11 = new_up.y;
+ float m12 = new_up.z;
+ float m20 = forward.x;
+ float m21 = forward.y;
+ float m22 = forward.z;
+
+ float num8 = (m00 + m11) + m22;
+ mons_quat quaternion = {0};
+ if (num8 > 0.0f) {
+ float num = sqrt(num8 + 1.0f);
+ quaternion.w = num * 0.5f;
+ num = 0.5f / num;
+ quaternion.x = (m12 - m21) * num;
+ quaternion.y = (m20 - m02) * num;
+ quaternion.z = (m01 - m10) * num;
+ transform->rotation = quaternion;
+ return;
+ }
+ if ((m00 >= m11) && (m00 >= m22))
+ {
+ float num7 = (float)sqrt(((1.0f + m00) - m11) - m22);
+ float num4 = 0.5f / num7;
+ quaternion.x = 0.5f * num7;
+ quaternion.y = (m01 + m10) * num4;
+ quaternion.z = (m02 + m20) * num4;
+ quaternion.w = (m12 - m21) * num4;
+ transform->rotation = quaternion;
+ return;
+ }
+ if (m11 > m22)
+ {
+ float num6 = (float)sqrt(((1.0f + m11) - m00) - m22);
+ float num3 = 0.5f / num6;
+ quaternion.x = (m10 + m01) * num3;
+ quaternion.y = 0.5f * num6;
+ quaternion.z = (m21 + m12) * num3;
+ quaternion.w = (m20 - m02) * num3;
+ transform->rotation = quaternion;
+ return;
+ }
+ float num5 = (float)sqrt(((1.0f + m22) - m00) - m11);
+ float num2 = 0.5f / num5;
+ quaternion.x = (m20 + m02) * num2;
+ quaternion.y = (m21 + m12) * num2;
+ quaternion.z = 0.5f * num5;
+ quaternion.w = (m01 - m10) * num2;
+ transform->rotation = quaternion;
+ return;
+}
diff --git a/mons_collections/CMakeLists.txt b/mons_collections/CMakeLists.txt
new file mode 100644
index 0000000..9391863
--- /dev/null
+++ b/mons_collections/CMakeLists.txt
@@ -0,0 +1,29 @@
+cmake_minimum_required(VERSION 3.14)
+project(mons_collections LANGUAGES C)
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_EXPORT_COMPILE_COMMANDS true)
+set(CMAKE_BUILD_TYPE "Debug")
+
+add_library(mons_collections
+ SHARED
+ ./src/hashmap.c
+)
+
+target_include_directories(mons_collections PUBLIC
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include"
+ "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
+)
+target_compile_options(mons_collections PRIVATE -coverage)
+target_link_options(mons_collections PRIVATE -coverage)
+
+include(CTest)
+
+function(TESTCASE NAME)
+ add_executable(test_${NAME} ./tests/${NAME}.c)
+ target_link_libraries(test_${NAME} PUBLIC mons_collections)
+ add_test(
+ NAME ${NAME}
+ COMMAND $<TARGET_FILE:test_${NAME}>
+ )
+endfunction()
+
diff --git a/mons_collections/include/hashmap.h b/mons_collections/include/hashmap.h
new file mode 100644
index 0000000..e5e59c4
--- /dev/null
+++ b/mons_collections/include/hashmap.h
@@ -0,0 +1,23 @@
+#ifndef MONS_HASHMAP_H
+#define MONS_HASHMAP_H
+
+typedef struct mons_hashmap_pair {
+ char *key;
+ void *value;
+ struct mons_hashmap_pair *next;
+} mons_hashmap_pair;
+
+typedef struct mons_hashmap {
+ mons_hashmap_pair **data;
+ unsigned int bucket_count;
+ unsigned int member_size;
+ unsigned int len;
+} mons_hashmap;
+
+mons_hashmap mons_hashmap_new(unsigned int member_size, unsigned int buckets);
+void mons_hashmap_free(mons_hashmap *hashmap);
+int mons_hashmap_insert(mons_hashmap *map, char *key, void *value);
+int mons_hashmap_get(mons_hashmap map, char *key, void *out);
+int mons_hashmap_remove(mons_hashmap *map, char *key);
+int mons_hashmap_at(mons_hashmap map, unsigned int index, mons_hashmap_pair *out);
+#endif
diff --git a/mons_collections/src/hashmap.c b/mons_collections/src/hashmap.c
new file mode 100644
index 0000000..c2ff172
--- /dev/null
+++ b/mons_collections/src/hashmap.c
@@ -0,0 +1,141 @@
+#include "hashmap.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#define MONS_HASHMAP_MAX_LOAD_FACTOR 3.0f
+
+unsigned int djb2_hash(unsigned char *str, unsigned int bucket_count) {
+ unsigned long hash = 5381;
+ int c;
+
+ while ((c = *str++)) {
+ hash = ((hash << 5) + hash) + c;
+ }
+
+ return hash % bucket_count;
+}
+
+mons_hashmap mons_hashmap_new(unsigned int member_size, unsigned int buckets) {
+ mons_hashmap result = {
+ .member_size = member_size,
+ .bucket_count = buckets,
+ .data = calloc(buckets, sizeof(mons_hashmap_pair *)),
+ };
+ return result;
+}
+
+int mons_hashmap_rehash(mons_hashmap *map) {
+ // TODO: Expand number of buckets, re-hash all entries
+ return EXIT_SUCCESS;
+}
+
+int mons_hashmap_insert(mons_hashmap *map, char *key, void *value) {
+ unsigned int bucket = djb2_hash((unsigned char*)key, map->bucket_count);
+ mons_hashmap_pair *tail = map->data[bucket];
+ if (tail == NULL) {
+ map->data[bucket] = calloc(1, sizeof(mons_hashmap_pair *));
+ tail = map->data[bucket];
+ } else {
+ mons_hashmap_pair *node = tail;
+ while(1) {
+ if(strcmp(key, node->key) == 0) {
+ memcpy(node->value, value, map->member_size);
+ return EXIT_SUCCESS;
+ }
+ if(node->next == NULL) {
+ tail = node;
+ break;
+ }
+ node = node->next;
+ }
+ tail->next = calloc(1, sizeof(mons_hashmap_pair *));
+ tail = tail->next;
+ }
+ tail->key = calloc(strlen(key) + 1, 1);
+ strcpy(tail->key, key);
+ tail->value = calloc(1, map->member_size);
+ memcpy(tail->value, value, map->member_size);
+ map->len++;
+ if (map->len / map->bucket_count > MONS_HASHMAP_MAX_LOAD_FACTOR) {
+ mons_hashmap_rehash(map);
+ }
+ return EXIT_SUCCESS;
+}
+
+int mons_hashmap_get(mons_hashmap map, char *key, void *out) {
+ unsigned int bucket = djb2_hash((unsigned char*)key, map.bucket_count);
+ mons_hashmap_pair *tail = map.data[bucket];
+ while(tail != NULL) {
+ if(strcmp(key, tail->key) == 0) {
+ memcpy(out, tail->value, map.member_size);
+ return EXIT_SUCCESS;
+ }
+ tail = tail->next;
+ }
+ return EXIT_FAILURE;
+}
+
+int mons_hashmap_remove(mons_hashmap *map, char *key) {
+ unsigned int bucket = djb2_hash((unsigned char*)key, map->bucket_count);
+ mons_hashmap_pair *tail = map->data[bucket];
+ mons_hashmap_pair *prev = NULL;
+ while(tail != NULL) {
+ if(strcmp(key, tail->key) == 0) {
+ if (prev == NULL) {
+ map->data[bucket] = tail->next;
+ } else {
+ prev->next = tail->next;
+ }
+ free(tail->key);
+ free(tail->value);
+ free(tail);
+ map->len--;
+ return EXIT_SUCCESS;
+ }
+ prev = tail;
+ tail = tail->next;
+ }
+ return EXIT_FAILURE;
+}
+
+void mons_hashmap_free(mons_hashmap *hashmap) {
+ for (int i = 0; i < hashmap->bucket_count; i++) {
+ mons_hashmap_pair *node = hashmap->data[i];
+ while(node != NULL) {
+ mons_hashmap_pair *next = node->next;
+ free(node->key);
+ free(node->value);
+ free(node);
+ node = next;
+ }
+ }
+ free(hashmap->data);
+ hashmap->data = NULL;
+ hashmap->bucket_count = 0;
+ hashmap->member_size = 0;
+ hashmap->len = 0;
+}
+
+int mons_hashmap_at(mons_hashmap map, unsigned int index, mons_hashmap_pair *out) {
+ mons_hashmap_pair **bucket = map.data;
+ mons_hashmap_pair *node = *bucket;
+ while(node == NULL) {
+ bucket++;
+ node = *bucket;
+ }
+ for(int i = 0; i < index; i++) {
+ if (node == NULL || node->next == NULL) {
+ bucket++;
+ node = *bucket;
+ while(node == NULL) {
+ bucket++;
+ node = *bucket;
+ }
+ } else {
+ node = node->next;
+ }
+ }
+ *out = *node;
+ return EXIT_SUCCESS;
+}
diff --git a/mons_exe/CMakeLists.txt b/mons_exe/CMakeLists.txt
new file mode 100644
index 0000000..103d1d4
--- /dev/null
+++ b/mons_exe/CMakeLists.txt
@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 3.14)
+project(mons_exe LANGUAGES C)
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_EXPORT_COMPILE_COMMANDS true)
+set(CMAKE_BUILD_TYPE "Debug")
+
+add_custom_target(hexdump_embeds
+ ./embed_headers.sh
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+
+add_executable(mons_exe
+ ./src/main.c
+ ./src/input.c
+)
+
+target_include_directories(mons_exe PUBLIC
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include"
+ "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
+)
+target_compile_options(mons_exe PRIVATE -coverage)
+target_link_options(mons_exe PRIVATE -coverage)
+target_link_libraries(mons_exe PUBLIC mons_3d mons_gltf X11)
+add_dependencies(mons_exe hexdump_embeds)
+
+include(CTest)
+
+function(TESTCASE NAME)
+ add_executable(test_${NAME} ./tests/${NAME}.c)
+ target_link_libraries(test_${NAME} PUBLIC mons_exe)
+ add_test(
+ NAME ${NAME}
+ COMMAND $<TARGET_FILE:test_${NAME}>
+ )
+endfunction()
+
diff --git a/mons_exe/embed/shaders/basic.vert.glsl b/mons_exe/embed/shaders/basic.vert.glsl
new file mode 100644
index 0000000..8164120
--- /dev/null
+++ b/mons_exe/embed/shaders/basic.vert.glsl
@@ -0,0 +1,26 @@
+#version 460 core
+layout (location = 0) in vec3 aPos;
+layout (location = 1) in vec3 aNormal;
+layout (location = 2) in vec4 aTangent;
+layout (location = 3) in vec2 aTexCoord;
+
+out vec3 Normal;
+out vec2 TexCoord;
+out vec3 FragPos;
+out mat3 TBN;
+
+uniform mat4 transform;
+uniform mat4 view;
+uniform mat4 projection;
+
+void main() {
+ gl_Position = projection * view * transform * vec4(aPos, 1.0);
+ FragPos = vec3(transform * vec4(aPos, 1.0));
+ Normal = mat3(transpose(inverse(transform))) * aNormal;
+ TexCoord = aTexCoord;
+
+ vec3 T = normalize(vec3(transform * vec4(aTangent.xyz, 0.0)));
+ vec3 N = normalize(vec3(transform * vec4(aNormal, 0.0)));
+ vec3 B = aTangent.w * cross(N, T);
+ TBN = mat3(T,B,N);
+}
diff --git a/mons_exe/embed/shaders/basic_lit.frag.glsl b/mons_exe/embed/shaders/basic_lit.frag.glsl
new file mode 100644
index 0000000..467174c
--- /dev/null
+++ b/mons_exe/embed/shaders/basic_lit.frag.glsl
@@ -0,0 +1,27 @@
+#version 460 core
+out vec4 FragColor;
+
+in vec3 Normal;
+in vec2 TexCoord;
+in vec3 FragPos;
+in mat3 TBN;
+
+uniform float ambient_strength;
+uniform sampler2D base_texture;
+uniform sampler2D normal_texture;
+
+uniform vec4 light_color;
+uniform vec3 light_position;
+
+void main() {
+ vec4 base_color = texture(base_texture, TexCoord);
+ vec3 normal = texture(normal_texture, TexCoord).rgb;
+ normal = normal * 2.0 - 1.0;
+ normal = normalize(TBN * normal);
+ vec3 light_direction = normalize(light_position - FragPos);
+ float diff = max(dot(normal, light_direction), 0.0);
+ vec4 diffuse_color = diff * light_color;
+ vec4 ambient_color = ambient_strength * light_color;
+
+ FragColor = (ambient_color + diffuse_color) * base_color;
+}
diff --git a/mons_exe/embed_headers.sh b/mons_exe/embed_headers.sh
new file mode 100755
index 0000000..fdbea13
--- /dev/null
+++ b/mons_exe/embed_headers.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+rm -rf ./include/embedded/
+for file in $(find ./embed -type f); do
+ basepath="${file#*/*/}"
+ basedir="${basepath%/*}"
+ mkdir -p "./include/embedded/$basedir"
+ echo "Generating ./include/embedded/$basepath.h"
+ xxd -i "$file" "./include/embedded/$basepath.h"
+done
diff --git a/mons_exe/include/embedded/shaders/basic.vert.glsl.h b/mons_exe/include/embedded/shaders/basic.vert.glsl.h
new file mode 100644
index 0000000..932d8e1
--- /dev/null
+++ b/mons_exe/include/embedded/shaders/basic.vert.glsl.h
@@ -0,0 +1,64 @@
+unsigned char __embed_shaders_basic_vert_glsl[] = {
+ 0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x34, 0x36, 0x30,
+ 0x20, 0x63, 0x6f, 0x72, 0x65, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74,
+ 0x20, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d,
+ 0x20, 0x30, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20,
+ 0x61, 0x50, 0x6f, 0x73, 0x3b, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74,
+ 0x20, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d,
+ 0x20, 0x31, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20,
+ 0x61, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x0a, 0x6c, 0x61, 0x79,
+ 0x6f, 0x75, 0x74, 0x20, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x3d, 0x20, 0x32, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x76, 0x65,
+ 0x63, 0x34, 0x20, 0x61, 0x54, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x74, 0x3b,
+ 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x20, 0x28, 0x6c, 0x6f, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x33, 0x29, 0x20, 0x69,
+ 0x6e, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x61, 0x54, 0x65, 0x78, 0x43,
+ 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x76,
+ 0x65, 0x63, 0x33, 0x20, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x0a,
+ 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x54, 0x65, 0x78,
+ 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x76,
+ 0x65, 0x63, 0x33, 0x20, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6f, 0x73, 0x3b,
+ 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x20, 0x54, 0x42,
+ 0x4e, 0x3b, 0x0a, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20,
+ 0x6d, 0x61, 0x74, 0x34, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f,
+ 0x72, 0x6d, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20,
+ 0x6d, 0x61, 0x74, 0x34, 0x20, 0x76, 0x69, 0x65, 0x77, 0x3b, 0x0a, 0x75,
+ 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x20,
+ 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a,
+ 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29,
+ 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f,
+ 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x6f,
+ 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2a, 0x20, 0x76, 0x69,
+ 0x65, 0x77, 0x20, 0x2a, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f,
+ 0x72, 0x6d, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x61, 0x50,
+ 0x6f, 0x73, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6f, 0x73, 0x20, 0x3d, 0x20,
+ 0x76, 0x65, 0x63, 0x33, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f,
+ 0x72, 0x6d, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x61, 0x50,
+ 0x6f, 0x73, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x3b, 0x0a, 0x20,
+ 0x20, 0x20, 0x20, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x3d, 0x20,
+ 0x6d, 0x61, 0x74, 0x33, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f,
+ 0x73, 0x65, 0x28, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x74,
+ 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x29, 0x29, 0x29, 0x20,
+ 0x2a, 0x20, 0x61, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x0a, 0x20,
+ 0x20, 0x20, 0x20, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x20,
+ 0x3d, 0x20, 0x61, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65,
+ 0x63, 0x33, 0x20, 0x54, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61,
+ 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x76, 0x65, 0x63, 0x33, 0x28, 0x74, 0x72,
+ 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x2a, 0x20, 0x76, 0x65,
+ 0x63, 0x34, 0x28, 0x61, 0x54, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x74, 0x2e,
+ 0x78, 0x79, 0x7a, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x29, 0x29, 0x3b,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x4e, 0x20,
+ 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28,
+ 0x76, 0x65, 0x63, 0x33, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f,
+ 0x72, 0x6d, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x61, 0x4e,
+ 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x29,
+ 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20,
+ 0x42, 0x20, 0x3d, 0x20, 0x61, 0x54, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x74,
+ 0x2e, 0x77, 0x20, 0x2a, 0x20, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x28, 0x4e,
+ 0x2c, 0x20, 0x54, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x42,
+ 0x4e, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x28, 0x54, 0x2c, 0x42,
+ 0x2c, 0x4e, 0x29, 0x3b, 0x0a, 0x7d, 0x0a
+};
+unsigned int __embed_shaders_basic_vert_glsl_len = 727;
diff --git a/mons_exe/include/embedded/shaders/basic_lit.frag.glsl.h b/mons_exe/include/embedded/shaders/basic_lit.frag.glsl.h
new file mode 100644
index 0000000..766f7b5
--- /dev/null
+++ b/mons_exe/include/embedded/shaders/basic_lit.frag.glsl.h
@@ -0,0 +1,65 @@
+unsigned char __embed_shaders_basic_lit_frag_glsl[] = {
+ 0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x34, 0x36, 0x30,
+ 0x20, 0x63, 0x6f, 0x72, 0x65, 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65,
+ 0x63, 0x34, 0x20, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72,
+ 0x3b, 0x0a, 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x4e,
+ 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65,
+ 0x63, 0x32, 0x20, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b,
+ 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x46, 0x72, 0x61,
+ 0x67, 0x50, 0x6f, 0x73, 0x3b, 0x0a, 0x69, 0x6e, 0x20, 0x6d, 0x61, 0x74,
+ 0x33, 0x20, 0x54, 0x42, 0x4e, 0x3b, 0x0a, 0x0a, 0x75, 0x6e, 0x69, 0x66,
+ 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x6d,
+ 0x62, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67,
+ 0x74, 0x68, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20,
+ 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x62, 0x61,
+ 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x3b, 0x0a,
+ 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70,
+ 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c,
+ 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x3b, 0x0a, 0x0a, 0x75,
+ 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20,
+ 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b,
+ 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63,
+ 0x33, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69,
+ 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20,
+ 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63,
+ 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75,
+ 0x72, 0x65, 0x28, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74,
+ 0x75, 0x72, 0x65, 0x2c, 0x20, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72,
+ 0x64, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33,
+ 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x65,
+ 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c,
+ 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x54, 0x65,
+ 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x29, 0x2e, 0x72, 0x67, 0x62, 0x3b,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20,
+ 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x2a, 0x20, 0x32,
+ 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x6e,
+ 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x54, 0x42, 0x4e,
+ 0x20, 0x2a, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x29, 0x3b, 0x0a,
+ 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x6c, 0x69, 0x67,
+ 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65,
+ 0x28, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x20, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6f,
+ 0x73, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61,
+ 0x74, 0x20, 0x64, 0x69, 0x66, 0x66, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78,
+ 0x28, 0x64, 0x6f, 0x74, 0x28, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x2c,
+ 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x64, 0x69,
+ 0x66, 0x66, 0x75, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20,
+ 0x3d, 0x20, 0x64, 0x69, 0x66, 0x66, 0x20, 0x2a, 0x20, 0x6c, 0x69, 0x67,
+ 0x68, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x61, 0x6d, 0x62, 0x69, 0x65,
+ 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x61,
+ 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x6e,
+ 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f,
+ 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20,
+ 0x28, 0x61, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6c,
+ 0x6f, 0x72, 0x20, 0x2b, 0x20, 0x64, 0x69, 0x66, 0x66, 0x75, 0x73, 0x65,
+ 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x29, 0x20, 0x2a, 0x20, 0x62, 0x61,
+ 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x7d, 0x0a
+};
+unsigned int __embed_shaders_basic_lit_frag_glsl_len = 744;
diff --git a/mons_exe/include/input.h b/mons_exe/include/input.h
new file mode 100644
index 0000000..533b7e6
--- /dev/null
+++ b/mons_exe/include/input.h
@@ -0,0 +1,113 @@
+#ifndef MONS_INPUT_H
+#define MONS_INPUT_H
+
+#include <stdbool.h>
+
+typedef enum mons_keycode {
+ MONS_KEY_A = 38,
+ MONS_KEY_B = 56,
+ MONS_KEY_C = 54,
+ MONS_KEY_D = 40,
+ MONS_KEY_E = 26,
+ MONS_KEY_F = 41,
+ MONS_KEY_G = 42,
+ MONS_KEY_H = 43,
+ MONS_KEY_I = 31,
+ MONS_KEY_J = 44,
+ MONS_KEY_K = 45,
+ MONS_KEY_L = 46,
+ MONS_KEY_M = 58,
+ MONS_KEY_N = 57,
+ MONS_KEY_O = 32,
+ MONS_KEY_P = 33,
+ MONS_KEY_Q = 24,
+ MONS_KEY_R = 27,
+ MONS_KEY_S = 39,
+ MONS_KEY_T = 28,
+ MONS_KEY_U = 30,
+ MONS_KEY_V = 55,
+ MONS_KEY_W = 25,
+ MONS_KEY_X = 53,
+ MONS_KEY_Y = 29,
+ MONS_KEY_Z = 52,
+ MONS_KEY_1 = 10,
+ MONS_KEY_2 = 11,
+ MONS_KEY_3 = 12,
+ MONS_KEY_4 = 13,
+ MONS_KEY_5 = 14,
+ MONS_KEY_6 = 15,
+ MONS_KEY_7 = 16,
+ MONS_KEY_8 = 17,
+ MONS_KEY_9 = 18,
+ MONS_KEY_0 = 19,
+ MONS_KEY_F1 = 67,
+ MONS_KEY_F2 = 68,
+ MONS_KEY_F3 = 69,
+ MONS_KEY_F4 = 70,
+ MONS_KEY_F5 = 71,
+ MONS_KEY_F6 = 72,
+ MONS_KEY_F7 = 73,
+ MONS_KEY_F8 = 74,
+ MONS_KEY_F9 = 75,
+ MONS_KEY_F10 = 76,
+ MONS_KEY_F11 = 95,
+ MONS_KEY_F12 = 96,
+ MONS_KEY_ESCAPE = 9,
+ MONS_KEY_UP = 111,
+ MONS_KEY_DOWN = 116,
+ MONS_KEY_LEFT = 113,
+ MONS_KEY_RIGHT = 114,
+ MONS_KEY_GRAVE = 49,
+ MONS_KEY_TAB = 23,
+ MONS_KEY_CAPSLOCK = 66,
+ MONS_KEY_LSHIFT = 50,
+ MONS_KEY_RSHIFT = 62,
+ MONS_KEY_LCTRL = 37,
+ MONS_KEY_RCTRL = 105,
+ MONS_KEY_LSUPER = 133,
+ MONS_KEY_RSUPER = 134,
+ MONS_KEY_LMETA = 64,
+ MONS_KEY_RMETA = 108,
+ MONS_KEY_SPACE = 65,
+ MONS_KEY_MENU = 135,
+ MONS_KEY_ENTER = 36,
+ MONS_KEY_BACKSLASH = 51,
+ MONS_KEY_SLASH = 61,
+ MONS_KEY_COMMA = 59,
+ MONS_KEY_PERIOD = 60,
+ MONS_KEY_SEMICOLON = 47,
+ MONS_KEY_QUOTE = 48,
+ MONS_KEY_LBRACKET = 34,
+ MONS_KEY_RBRACKET = 35,
+ MONS_KEY_MINUS = 20,
+ MONS_KEY_EQUAL = 21,
+ MONS_KEY_BACKSPACE = 22,
+ MONS_KEY_PRINT = 107,
+ MONS_KEY_SCROLLLOCK = 78,
+ MONS_KEY_PAUSE = 127,
+ MONS_KEY_INSERT = 118,
+ MONS_KEY_DELETE = 119,
+ MONS_KEY_HOME = 110,
+ MONS_KEY_END = 115,
+ MONS_KEY_PREV = 112,
+ MONS_KEY_NEXT = 117,
+ MONS_KEY_NUMLOCK = 77,
+ MONS_KEY_NUMPAD_1 = 87,
+ MONS_KEY_NUMPAD_2 = 88,
+ MONS_KEY_NUMPAD_3 = 89,
+ MONS_KEY_NUMPAD_4 = 83,
+ MONS_KEY_NUMPAD_5 = 84,
+ MONS_KEY_NUMPAD_6 = 85,
+ MONS_KEY_NUMPAD_7 = 79,
+ MONS_KEY_NUMPAD_8 = 80,
+ MONS_KEY_NUMPAD_9 = 81,
+ MONS_KEY_NUMPAD_0 = 90,
+ MONS_KEY_NUMPAD_DIV = 106,
+ MONS_KEY_NUMPAD_MUL = 63,
+ MONS_KEY_NUMPAD_MINUS = 82,
+ MONS_KEY_NUMPAD_PLUS = 86,
+ MONS_KEY_NUMPAD_DELETE = 91,
+ MONS_KEY_NUMPAD_ENTER = 104,
+} mons_keycode;
+
+#endif
diff --git a/mons_exe/src/input.c b/mons_exe/src/input.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mons_exe/src/input.c
diff --git a/mons_exe/src/main.c b/mons_exe/src/main.c
new file mode 100644
index 0000000..fab3b8d
--- /dev/null
+++ b/mons_exe/src/main.c
@@ -0,0 +1,247 @@
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+#include <math.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include "glad/gl.h"
+#include "glad/glx.h"
+#include "vertex.h"
+#include "mons_math/vec4.h"
+#include "mons_math/quat.h"
+#include "embedded/shaders/basic.vert.glsl.h"
+#include "embedded/shaders/basic_lit.frag.glsl.h"
+#include "shader.h"
+#include "mesh.h"
+#include "qoi.h"
+#include "texture.h"
+#include "transform.h"
+#include "model.h"
+#include "projection.h"
+#include "json.h"
+#include "hashmap.h"
+#include "gltf.h"
+#include "input.h"
+#include "camera.h"
+#include <memory.h>
+#include "color.h"
+#include "light.h"
+
+struct timespec current_time;
+double delta_time = 0;
+
+int main(void) {
+ // Make Window
+ Display *display = XOpenDisplay(NULL);
+ if (display == NULL) {
+ printf("Cannot connect to X server\n");
+ return EXIT_FAILURE;
+ }
+
+ int screen = DefaultScreen(display);
+
+ int glx_version = gladLoaderLoadGLX(display, screen);
+ if (!glx_version) {
+ printf("Unable to load GLX\n");
+ return EXIT_FAILURE;
+ }
+ printf("Loaded GLX %d.%d\n", GLAD_VERSION_MAJOR(glx_version),
+ GLAD_VERSION_MINOR(glx_version));
+
+ Window root = RootWindow(display, screen);
+
+ GLint visual_attributes[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 24,
+ None};
+ XVisualInfo *visual_info =
+ glXChooseVisual(display, screen, visual_attributes);
+
+ Colormap colormap =
+ XCreateColormap(display, root, visual_info->visual, AllocNone);
+
+ XSetWindowAttributes attributes;
+ attributes.event_mask =
+ ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask;
+ attributes.colormap = colormap;
+
+ Window window = XCreateWindow(
+ display, root, 0, 0, 640, 480, 0, visual_info->depth, InputOutput,
+ visual_info->visual, CWColormap | CWEventMask, &attributes);
+
+ // XSizeHints hints = {
+ // .flags = PMinSize | PMaxSize,
+ // .min_width = 640,
+ // .min_height = 480,
+ // .max_width = 640,
+ // .max_height = 480,
+ // };
+ // XSetWMNormalHints(display, window, &hints);
+ XMapWindow(display, window);
+ XStoreName(display, window, "Hello World!");
+
+ if (!window) {
+ printf("Unable to create window\n");
+ return EXIT_FAILURE;
+ }
+
+ GLXContext context = glXCreateContext(display, visual_info, NULL, GL_TRUE);
+ glXMakeCurrent(display, window, context);
+
+ // Load GL
+ int version = gladLoaderLoadGL();
+ if (!version) {
+ printf("Unable to load GL\n");
+ return EXIT_FAILURE;
+ }
+ printf("Loaded GL %d.%d\n", GLAD_VERSION_MAJOR(version),
+ GLAD_VERSION_MINOR(version));
+
+ XWindowAttributes gwa;
+ XGetWindowAttributes(display, window, &gwa);
+ glViewport(0, 0, gwa.width, gwa.height);
+
+ // Setup Shaders
+ mons_shader vertex_shader = mons_create_shader(
+ MONS_SHADER_TYPE_VERTEX, (char *)__embed_shaders_basic_vert_glsl,
+ __embed_shaders_basic_vert_glsl_len);
+ mons_shader fragment_shader = mons_create_shader(
+ MONS_SHADER_TYPE_FRAGMENT, (char *)__embed_shaders_basic_lit_frag_glsl,
+ __embed_shaders_basic_lit_frag_glsl_len);
+ mons_program shader_program =
+ mons_create_program(vertex_shader, fragment_shader);
+
+ FILE *texture_file = fopen("test.qoi", "rb");
+ mons_texture texture = mons_texture_load(texture_file);
+
+ mons_camera camera = {
+ .projection =
+ {
+ .near = 0.01f,
+ .far = 100.0f,
+ .fov = M_PI / 4.0f,
+ .aspect_ratio = gwa.width / (float)gwa.height,
+ },
+ .transform = {
+ .translation = mons_vec3_mul_i(MONS_VEC3_Z, 3),
+ .rotation = MONS_QUAT_IDENTITY,
+ .scale = MONS_VEC3_ONE, }}; clock_gettime(CLOCK_MONOTONIC_RAW, &current_time);
+ mons_model *models = NULL;
+ int model_count = 0;
+ mons_load_gltf("marble_bust/marble_bust_01_4k.gltf", shader_program,
+ &models, &model_count);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+
+ mons_directional_light light = {
+ .transform = (mons_transform) {
+ .translation = (mons_vec3) { 0.0f, 0.0f, 3.0f },
+ .rotation = MONS_QUAT_IDENTITY,
+ .scale = MONS_VEC3_ONE,
+ },
+ .color = MONS_COLOR_WHITE,
+ };
+ mons_shader_set_vec4_global("light_color", light.color);
+ mons_shader_set_vec3_global("light_position", light.transform.translation);
+
+ float ambient_light = 0.1f;
+ mons_shader_set_float_global("ambient_strength", ambient_light);
+
+ // Main Loop
+ bool key_pressed[256] = {false};
+ bool key_just_pressed[256] = {false};
+ bool quit = false;
+ while (!quit) {
+ memset(key_just_pressed, false, 256);
+ while (XPending(display)) {
+ XEvent xev;
+ XNextEvent(display, &xev);
+ switch (xev.type) {
+ case KeyPress:
+ key_pressed[xev.xkey.keycode] = true;
+ key_just_pressed[xev.xkey.keycode] = true;
+ break;
+ case KeyRelease:
+ key_pressed[xev.xkey.keycode] = false;
+ break;
+ case ConfigureNotify:
+ if (xev.xconfigure.window == window) {
+ camera.projection.aspect_ratio =
+ xev.xconfigure.width / (float)xev.xconfigure.height;
+ glViewport(0, 0, xev.xconfigure.width,
+ xev.xconfigure.height);
+ }
+ default:
+ break;
+ }
+ }
+
+ glClearColor(0.0, 0.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ struct timespec new_time;
+ clock_gettime(CLOCK_MONOTONIC_RAW, &new_time);
+ delta_time = (new_time.tv_sec - current_time.tv_sec) +
+ (new_time.tv_nsec - current_time.tv_nsec) / 1.0e9;
+ current_time = new_time;
+
+ mons_shader_set_mat4_global("view", mons_mat4_inverse(mons_transform_matrix(camera.transform)), GL_TRUE);
+ mons_shader_set_mat4_global("projection", mons_projection_matrix(camera.projection), GL_FALSE);
+ for (int i = 0; i < model_count; i++) {
+ mons_model_draw(models[i]);
+ mons_transform_rotate(&models[i].transform, mons_quat_from_axis_angle(MONS_VEC3_Y, (M_PI / 4.0f) * delta_time));
+ }
+
+ glBindVertexArray(0);
+
+
+ if (key_pressed[MONS_KEY_ESCAPE]) {
+ quit = true;
+ }
+
+ int x_axis_input = key_pressed[MONS_KEY_D] - key_pressed[MONS_KEY_A];
+ mons_transform_translate(
+ &camera.transform,
+ mons_vec3_mul_f(mons_transform_right(camera.transform), delta_time * x_axis_input));
+ int y_axis_input =
+ key_pressed[MONS_KEY_SPACE] - key_pressed[MONS_KEY_LSHIFT];
+ mons_transform_translate(
+ &camera.transform,
+ mons_vec3_mul_f(mons_transform_up(camera.transform), delta_time * y_axis_input));
+ int z_axis_input = key_pressed[MONS_KEY_W] - key_pressed[MONS_KEY_S];
+ mons_transform_translate(
+ &camera.transform,
+ mons_vec3_mul_f(mons_transform_forward(camera.transform), delta_time * -z_axis_input));
+ int y_rot_input =
+ key_pressed[MONS_KEY_RIGHT] - key_pressed[MONS_KEY_LEFT];
+ mons_transform_rotate(
+ &camera.transform,
+ mons_quat_from_axis_angle(MONS_VEC3_Y,
+ -M_PI / 2.0f * y_rot_input * delta_time));
+ int x_rot_input = key_pressed[MONS_KEY_UP] - key_pressed[MONS_KEY_DOWN];
+ mons_transform_rotate(
+ &camera.transform,
+ mons_quat_from_axis_angle(MONS_VEC3_X,
+ M_PI / 2.0f * x_rot_input * delta_time));
+
+ int fov_input = key_pressed[MONS_KEY_MINUS] - key_pressed[MONS_KEY_EQUAL];
+ camera.projection.fov += (fov_input * M_PI / 8.0 * delta_time);
+ if(key_just_pressed[MONS_KEY_BACKSPACE]) {
+ mons_transform_look_at(&camera.transform, MONS_VEC3_ZERO, MONS_VEC3_Y);
+ }
+ glXSwapBuffers(display, window);
+ }
+
+ glDeleteShader(vertex_shader);
+ glDeleteShader(fragment_shader);
+
+ glXMakeCurrent(display, 0, 0);
+ glXDestroyContext(display, context);
+
+ XDestroyWindow(display, window);
+ XFreeColormap(display, colormap);
+ XCloseDisplay(display);
+
+ gladLoaderUnloadGLX();
+
+ return EXIT_SUCCESS;
+}
diff --git a/mons_gltf/CMakeLists.txt b/mons_gltf/CMakeLists.txt
new file mode 100644
index 0000000..3f07fb6
--- /dev/null
+++ b/mons_gltf/CMakeLists.txt
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 3.14)
+project(mons_gltf LANGUAGES C)
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_EXPORT_COMPILE_COMMANDS true)
+set(CMAKE_BUILD_TYPE "Debug")
+
+add_library(mons_gltf
+ SHARED
+ ./src/gltf.c
+)
+
+target_include_directories(mons_gltf PUBLIC
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include"
+ "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
+)
+target_compile_options(mons_gltf PRIVATE -coverage)
+target_link_options(mons_gltf PRIVATE -coverage)
+target_link_libraries(mons_gltf PUBLIC mons_json mons_3d)
+
+include(CTest)
+
+function(TESTCASE NAME)
+ add_executable(test_${NAME} ./tests/${NAME}.c)
+ target_link_libraries(test_${NAME} PUBLIC mons_gltf)
+ add_test(
+ NAME ${NAME}
+ COMMAND $<TARGET_FILE:test_${NAME}>
+ )
+endfunction()
+
diff --git a/mons_gltf/include/gltf.h b/mons_gltf/include/gltf.h
new file mode 100644
index 0000000..d799f26
--- /dev/null
+++ b/mons_gltf/include/gltf.h
@@ -0,0 +1,11 @@
+#ifndef MONS_GLTF_H
+#define MONS_GLTF_H
+
+#include "shader.h"
+#include <stdio.h>
+
+struct mons_model;
+
+int mons_load_gltf(char *path, mons_program shader, struct mons_model **out, int *count);
+
+#endif
diff --git a/mons_gltf/src/gltf.c b/mons_gltf/src/gltf.c
new file mode 100644
index 0000000..10f177c
--- /dev/null
+++ b/mons_gltf/src/gltf.c
@@ -0,0 +1,549 @@
+#include "gltf.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <libgen.h>
+#include <string.h>
+#include "json.h"
+#include "transform.h"
+#include "mons_math/vec3.h"
+#include "mons_math/quat.h"
+#include "vertex.h"
+#include "mesh.h"
+#include "texture.h"
+#include "image.h"
+#include "qoi.h"
+#include "model.h"
+#include "shader.h"
+
+// TODO: Morph Targets
+// TODO: Skins
+
+typedef enum mons_gltf_buffer_view_target {
+ MONS_GLTF_BUFFER_VIEW_ARRAY_BUFFER = 34962,
+ MONS_GLTF_BUFFER_VIEW_ELEMENT_ARRAY_BUFFER = 34963,
+} mons_gltf_buffer_view_target;
+
+typedef struct mons_gltf_buffer_view {
+ int buffer_index;
+ int byte_length;
+ int byte_offset;
+ int byte_stride;
+ mons_gltf_buffer_view_target target;
+} mons_gltf_buffer_view;
+
+typedef enum mons_gltf_accessor_component_type {
+ MONS_GLTF_ACCESSOR_BYTE = 5120,
+ MONS_GLTF_ACCESSOR_UNSIGNED_BYTE = 5121,
+ MONS_GLTF_ACCESSOR_SHORT = 5122,
+ MONS_GLTF_ACCESSOR_UNSIGNED_SHORT = 5123,
+ MONS_GLTF_ACCESSOR_UNSIGNED_INT = 5125,
+ MONS_GLTF_ACCESSOR_FLOAT = 5126,
+} mons_gltf_accessor_component_type;
+
+typedef enum mons_gltf_accessor_type {
+ MONS_GLTF_ACCESSOR_SCALAR = 1,
+ MONS_GLTF_ACCESSOR_VEC2 = 2,
+ MONS_GLTF_ACCESSOR_VEC3 = 3,
+ MONS_GLTF_ACCESSOR_VEC4 = 4,
+ MONS_GLTF_ACCESSOR_MAT2 = 4,
+ MONS_GLTF_ACCESSOR_MAT3 = 9,
+ MONS_GLTF_ACCESSOR_MAT4 = 16,
+} mons_gltf_accessor_type;
+
+typedef struct mons_gltf_accessor {
+ int buffer_view_index;
+ int byte_offset;
+ mons_gltf_accessor_component_type component_type;
+ int count;
+ float *min;
+ float *max;
+ mons_gltf_accessor_type type;
+} mons_gltf_accessor;
+
+typedef enum mons_gltf_primitive_mode {
+ MONS_GLTF_MODE_POINTS,
+ MONS_GLTF_MODE_LINES,
+ MONS_GLTF_MODE_LINE_LOOP,
+ MONS_GLTF_MODE_LINE_STRIP,
+ MONS_GLTF_MODE_TRIANGLES,
+ MONS_GLTF_MODE_TRIANGLE_STRIP,
+ MONS_GLTF_MODE_TRIANGLE_FAN,
+} mons_gltf_primitive_mode;
+
+typedef struct mons_gltf_primitive {
+ mons_hashmap attributes;
+ int indices_accessor;
+ int material;
+ mons_gltf_primitive_mode mode;
+} mons_gltf_primitive;
+
+typedef struct mons_gltf_mesh {
+ mons_gltf_primitive *primitives;
+} mons_gltf_mesh;
+
+typedef struct mons_gltf_texture {
+ int sampler_index;
+ int source_index;
+} mons_gltf_texture;
+
+typedef enum mons_gltf_sampler_filter {
+ MONS_SAMPLER_NEAREST = 9728,
+ MONS_SAMPLER_LINEAR = 9729,
+ MONS_SAMPLER_NEAREST_MIPMAP_NEAREST = 9984,
+ MONS_SAMPLER_LINEAR_MIPMAP_NEAREST = 9985,
+ MONS_SAMPLER_NEAREST_MIPMAP_LINEAR = 9986,
+ MONS_SAMPLER_LINEAR_MIPMAP_LINEAR = 9987,
+} mons_gltf_sampler_filter;
+
+typedef enum mons_gltf_sampler_wrapmode {
+ MONS_SAMPLER_CLAMP_TO_EDGE = 33071,
+ MONS_SAMPLER_MIRRORED_REPEAT = 33648,
+ MONS_SAMPLER_REPEAT = 10497,
+} mons_gltf_sampler_wrapmode;
+
+typedef struct mons_gltf_sampler {
+ mons_gltf_sampler_filter mag_filter;
+ mons_gltf_sampler_filter min_filter;
+ mons_gltf_sampler_wrapmode wrap_s;
+ mons_gltf_sampler_wrapmode wrap_t;
+} mons_gltf_sampler;
+
+typedef struct mons_gltf_material {
+ int base_color_texture_index;
+ int normal_texture_index;
+ int metallic_roughness_texture_index;
+} mons_gltf_material;
+
+int mons_load_gltf(char *path, mons_program shader, mons_model **out, int *count) {
+
+ FILE *stream = fopen(path, "r");
+ // Read JSON into memory
+ fseek(stream, 0L, SEEK_END);
+ unsigned long len = ftell(stream);
+ char *json_buffer = malloc(len);
+ rewind(stream);
+ fread(json_buffer, 1, len, stream);
+ fclose(stream);
+ mons_json_value json;
+ if (mons_json_parse(json_buffer, &json) == EXIT_FAILURE) {
+ printf("Failed to parse JSON\n");
+ return EXIT_FAILURE;
+ }
+
+ mons_json_value asset_info;
+ mons_json_get_value(json, "asset", &asset_info);
+ char *asset_info_str = mons_json_to_string(asset_info);
+ printf("Loading GLTF Asset: %s\n", asset_info_str);
+ free(asset_info_str);
+
+ mons_json_array gltf_nodes_array;
+ mons_json_get_array(json, "nodes", &gltf_nodes_array);
+ printf("GLTF Node Count: %d\n", gltf_nodes_array.len);
+ for (int i = 0; i < gltf_nodes_array.len; i++) {
+ mons_json_value node_info = gltf_nodes_array.values[i];
+ char *name;
+ mons_json_get_string(node_info, "name", &name);
+ printf("\t%d: %s\n", i, name);
+ mons_transform transform = MONS_TRANSFORM_IDENTITY;
+ mons_json_array node_transform_matrix_json;
+ if (mons_json_get_array(node_info, "matrix",
+ &node_transform_matrix_json) == EXIT_SUCCESS) {
+ for (int j = 0; j < node_transform_matrix_json.len; j++) {
+ *(((float *)&transform) + j) =
+ node_transform_matrix_json.values[j].data.number;
+ }
+ } else {
+
+ mons_vec3 translation = MONS_VEC3_ZERO;
+ mons_vec3 scale = MONS_VEC3_ONE;
+ mons_quat rotation = MONS_QUAT_IDENTITY;
+ mons_json_array node_translation_json;
+ mons_json_array node_rotation_json;
+ mons_json_array node_scale_json;
+ int has_translation =
+ (mons_json_get_array(node_info, "translation",
+ &node_translation_json) == EXIT_SUCCESS);
+ int has_rotation =
+ (mons_json_get_array(node_info, "rotation",
+ &node_rotation_json) == EXIT_SUCCESS);
+ int has_scale =
+ (mons_json_get_array(node_info, "scale",
+ &node_translation_json) == EXIT_SUCCESS);
+
+ if (has_translation) {
+ for (int j = 0; j < node_translation_json.len; j++) {
+ *(((float *)&translation) + j) =
+ node_translation_json.values[j].data.number;
+ }
+ printf("TRANSLATION: %f, %f, %f\n", translation.x,
+ translation.y, translation.z);
+ }
+ if (has_rotation) {
+ printf("ROTATION\n");
+ for (int j = 0; j < node_rotation_json.len; j++) {
+ *(((float *)&rotation) + j) =
+ node_rotation_json.values[j].data.number;
+ }
+ }
+ if (has_scale) {
+ printf("SCALE\n");
+ for (int j = 0; j < node_scale_json.len; j++) {
+ *(((float *)&scale) + j) =
+ node_scale_json.values[j].data.number;
+ }
+ }
+ if (has_scale || has_rotation || has_translation) {
+ transform = (mons_transform) {
+ translation,
+ scale,
+ rotation,
+ };
+ }
+ }
+ }
+
+ mons_json_array gltf_scenes_array;
+ mons_json_get_array(json, "scenes", &gltf_scenes_array);
+ printf("GLTF Scene Count: %d\n", gltf_scenes_array.len);
+ for (int i = 0; i < gltf_scenes_array.len; i++) {
+ mons_json_value scene_info = gltf_scenes_array.values[i];
+ char *name;
+ mons_json_get_string(scene_info, "name", &name);
+ printf("\t%d: %s\n", i, name);
+ mons_json_array scene_nodes_array;
+ mons_json_get_array(scene_info, "nodes", &scene_nodes_array);
+ printf("\t%d Nodes:\n", scene_nodes_array.len);
+ for (int j = 0; j < scene_nodes_array.len; j++) {
+ int node_index = scene_nodes_array.values[j].data.number;
+ printf("\t\t%d\n", node_index);
+ }
+ }
+
+ mons_json_array gltf_buffers_array;
+ mons_json_get_array(json, "buffers", &gltf_buffers_array);
+ printf("GLTF Buffer Count: %d\n", gltf_buffers_array.len);
+ FILE **buffers = calloc(gltf_buffers_array.len, sizeof(FILE *));
+ for (int i = 0; i < gltf_buffers_array.len; i++) {
+ mons_json_value buffer_info = gltf_buffers_array.values[i];
+ char *buffer_uri;
+ mons_json_get_string(buffer_info, "uri", &buffer_uri);
+ char *path_copy = strdup(path);
+ char *base_path = dirname(path_copy);
+ char *full_buffer_path =
+ calloc(strlen(base_path) + strlen(buffer_uri) + 2, 1);
+ snprintf(full_buffer_path, strlen(base_path) + strlen(buffer_uri) + 2,
+ "%s/%s", base_path, buffer_uri);
+ printf("\t%d: %s\n", i, full_buffer_path);
+ buffers[i] = fopen(full_buffer_path, "rb");
+ if (buffers[i] == NULL) {
+ printf("Failed to open buffer for reading\n");
+ }
+ free(path_copy);
+ }
+
+ mons_json_array gltf_buffer_views_array;
+ mons_json_get_array(json, "bufferViews", &gltf_buffer_views_array);
+ printf("GLTF Buffer View Count: %d\n", gltf_buffer_views_array.len);
+ mons_gltf_buffer_view *buffer_views =
+ calloc(gltf_buffer_views_array.len, sizeof(mons_gltf_buffer_view));
+ for (int i = 0; i < gltf_buffer_views_array.len; i++) {
+ mons_json_value buffer_view_info = gltf_buffer_views_array.values[i];
+ mons_json_get_int(buffer_view_info, "buffer",
+ &buffer_views[i].buffer_index);
+ mons_json_get_int(buffer_view_info, "byteLength",
+ &buffer_views[i].byte_length);
+ mons_json_get_int(buffer_view_info, "byteOffset",
+ &buffer_views[i].byte_offset);
+ mons_json_get_int(buffer_view_info, "byteStride",
+ &buffer_views[i].byte_stride);
+ mons_json_get_int(buffer_view_info, "target",
+ (int *)(&buffer_views[i].target));
+ printf("%d: %d bytes @ %d+%d, type %d, stride %d\n", i,
+ buffer_views[i].byte_length, buffer_views[i].buffer_index,
+ buffer_views[i].byte_offset, buffer_views[i].target,
+ buffer_views[i].byte_stride);
+ }
+
+ mons_json_array gltf_accessors_array;
+ mons_json_get_array(json, "accessors", &gltf_accessors_array);
+ printf("GLTF Accessor Count: %d\n", gltf_accessors_array.len);
+ mons_gltf_accessor *accessors =
+ calloc(gltf_accessors_array.len, sizeof(mons_gltf_accessor));
+ for (int i = 0; i < gltf_accessors_array.len; i++) {
+ mons_json_value accessor_info = gltf_accessors_array.values[i];
+ mons_json_get_int(accessor_info, "bufferView",
+ &accessors[i].buffer_view_index);
+ mons_json_get_int(accessor_info, "byteOffset",
+ &accessors[i].byte_offset);
+ mons_json_get_int(accessor_info, "componentType",
+ (int *)(&accessors[i].component_type));
+ mons_json_get_int(accessor_info, "count", &accessors[i].count);
+ char *accessor_type;
+ mons_json_get_string(accessor_info, "type", &accessor_type);
+ if (strcmp(accessor_type, "SCALAR") == 0) {
+ accessors[i].type = MONS_GLTF_ACCESSOR_SCALAR;
+ } else if (strcmp(accessor_type, "VEC2") == 0) {
+ accessors[i].type = MONS_GLTF_ACCESSOR_VEC2;
+ } else if (strcmp(accessor_type, "VEC3") == 0) {
+ accessors[i].type = MONS_GLTF_ACCESSOR_VEC3;
+ } else if (strcmp(accessor_type, "VEC4") == 0) {
+ accessors[i].type = MONS_GLTF_ACCESSOR_VEC4;
+ } else if (strcmp(accessor_type, "MAT2") == 0) {
+ accessors[i].type = MONS_GLTF_ACCESSOR_MAT2;
+ } else if (strcmp(accessor_type, "MAT3") == 0) {
+ accessors[i].type = MONS_GLTF_ACCESSOR_MAT3;
+ } else if (strcmp(accessor_type, "MAT4") == 0) {
+ accessors[i].type = MONS_GLTF_ACCESSOR_MAT4;
+ }
+ mons_json_array min_array;
+ if (mons_json_get_array(accessor_info, "min", &min_array) ==
+ EXIT_SUCCESS) {
+ accessors[i].min = calloc(accessors[i].type, sizeof(float));
+ for (int j = 0; j < accessors[i].type; j++) {
+ accessors[i].min[j] = min_array.values[j].data.number;
+ }
+ }
+ mons_json_array max_array;
+ if (mons_json_get_array(accessor_info, "max", &max_array) ==
+ EXIT_SUCCESS) {
+ accessors[i].max = calloc(accessors[i].type, sizeof(float));
+ for (int j = 0; j < accessors[i].type; j++) {
+ accessors[i].max[j] = max_array.values[j].data.number;
+ }
+ }
+ printf("%d: %d %d-component elements @ %d+%d\n", i, accessors[i].count,
+ accessors[i].type, accessors[i].buffer_view_index,
+ accessors[i].byte_offset);
+ if (accessors[i].min != NULL) {
+ printf("\tMin: [");
+ for (int j = 0; j < accessors[i].type; j++) {
+ printf("%f", accessors[i].min[j]);
+ if (j + 1 < accessors[i].type) {
+ printf(", ");
+ } else {
+ printf("]\n");
+ }
+ }
+ }
+ if (accessors[i].max != NULL) {
+ printf("\tMax: [");
+ for (int j = 0; j < accessors[i].type; j++) {
+ printf("%f", accessors[i].max[j]);
+ if (j + 1 < accessors[i].type) {
+ printf(", ");
+ } else {
+ printf("]\n");
+ }
+ }
+ }
+ }
+
+ mons_json_array gltf_images_array;
+ mons_json_get_array(json, "images", &gltf_images_array);
+ printf("GLTF Image Count: %d\n", gltf_images_array.len);
+ mons_image *images = calloc(gltf_images_array.len, sizeof(mons_image));
+ for (int i = 0; i < gltf_images_array.len; i++) {
+ mons_json_value image_info = gltf_images_array.values[i];
+ char *mimetype = NULL;
+ mons_json_get_string(image_info, "mimeType", &mimetype);
+ int buffer_view_index;
+ FILE *image_buffer = NULL;
+ if (mons_json_get_int(image_info, "bufferView", &buffer_view_index) ==
+ EXIT_SUCCESS) {
+ if (mimetype == NULL) {
+ printf(
+ "Cannot load image from buffer view, missing mimetype\n");
+ continue;
+ }
+ mons_gltf_buffer_view image_buffer_view =
+ buffer_views[buffer_view_index];
+ image_buffer = buffers[image_buffer_view.buffer_index];
+ }
+ char *uri = NULL;
+ if(mons_json_get_string(image_info, "uri", &uri) == EXIT_SUCCESS) {
+ char *path_copy = strdup(path);
+ char *base_path = dirname(path_copy);
+ char *full_buffer_path =
+ calloc(strlen(base_path) + strlen(uri) + 2, 1);
+ snprintf(full_buffer_path, strlen(base_path) + strlen(uri) + 2,
+ "%s/%s", base_path, uri);
+ printf("%d: %s\n", i, full_buffer_path);
+ image_buffer = fopen(full_buffer_path, "rb");
+ }
+
+ if(image_buffer == NULL) {
+ printf("Failed to open image buffer for reading\n");
+ continue;
+ }
+ if (strcmp(mimetype, "image/qoi") == 0 ||
+ (uri != NULL && strcmp(strrchr(uri, '.'), "qoi") == 0)) {
+ images[i] = mons_load_qoi(image_buffer);
+ }
+ }
+
+ mons_json_array gltf_samplers_array;
+ mons_json_get_array(json, "samplers", &gltf_samplers_array);
+ printf("GLTF Sampler Count: %d\n", gltf_samplers_array.len);
+ mons_gltf_sampler *samplers = calloc(gltf_samplers_array.len, sizeof(mons_gltf_sampler));
+ for(int i = 0; i < gltf_samplers_array.len; i++) {
+ mons_json_value sampler_info = gltf_samplers_array.values[i];
+ mons_json_get_int(sampler_info, "magFilter", (int*)&samplers[i].mag_filter);
+ mons_json_get_int(sampler_info, "minFilter", (int*)&samplers[i].min_filter);
+ mons_json_get_int(sampler_info, "wrapS", (int*)&samplers[i].wrap_s);
+ mons_json_get_int(sampler_info, "wrapT", (int*)&samplers[i].wrap_t);
+ printf("%d: min %d, mag %d, wrap %d, %d\n", i, samplers[i].min_filter, samplers[i].mag_filter, samplers[i].wrap_s, samplers[i].wrap_t);
+ }
+
+ mons_json_array gltf_textures_array;
+ mons_json_get_array(json, "textures", &gltf_textures_array);
+ printf("GLTF Texture Count: %d\n", gltf_textures_array.len);
+ mons_gltf_texture *textures =
+ calloc(gltf_textures_array.len, sizeof(mons_gltf_texture));
+ for (int i = 0; i < gltf_textures_array.len; i++) {
+ mons_json_value texture_info = gltf_textures_array.values[i];
+ textures[i].sampler_index = -1;
+ textures[i].source_index = -1;
+ mons_json_get_int(texture_info, "sampler", &textures[i].sampler_index);
+ mons_json_get_int(texture_info, "source", &textures[i].source_index);
+ printf("%d: sampler %d, source %d\n", i, textures[i].sampler_index,
+ textures[i].source_index);
+ }
+
+ mons_json_array gltf_materials_array;
+ mons_json_get_array(json, "materials", &gltf_materials_array);
+ mons_gltf_material *materials = calloc(gltf_materials_array.len, sizeof(mons_gltf_material));
+ printf("GLTF Material Count: %d\n", gltf_materials_array.len);
+ for (int i = 0; i < gltf_materials_array.len; i++) {
+ mons_json_value material_info = gltf_materials_array.values[i];
+ mons_json_get_int(material_info, "pbrMetallicRoughness.baseColorTexture.index", &materials[i].base_color_texture_index);
+ mons_json_get_int(material_info, "normalTexture.index", &materials[i].normal_texture_index);
+ mons_json_get_int(material_info, "pbrMetallicRoughness.metallicRoughnessTexture.index", &materials[i].metallic_roughness_texture_index);
+ }
+
+ mons_json_array gltf_mesh_array;
+ mons_json_get_array(json, "meshes", &gltf_mesh_array);
+ printf("GLTF Mesh Count: %d\n", gltf_mesh_array.len);
+ mons_model *models = calloc(gltf_mesh_array.len, sizeof(mons_model));
+ for (int i = 0; i < gltf_mesh_array.len; i++) {
+ mons_json_value mesh_info = gltf_mesh_array.values[i];
+ mons_json_array primitives_array;
+ mons_json_get_array(mesh_info, "primitives", &primitives_array);
+ printf("%d: %d Primitives\n", i, primitives_array.len);
+ for (int j = 0; j < primitives_array.len; j++) {
+ mons_json_value primitive_info = primitives_array.values[j];
+ mons_vertex *vertices;
+ int vertex_count;
+ int position_accessor_index;
+ if (mons_json_get_int(primitive_info, "attributes.POSITION",
+ &position_accessor_index) == EXIT_SUCCESS) {
+ mons_gltf_accessor position_accessor =
+ accessors[position_accessor_index];
+ vertices = calloc(position_accessor.count, sizeof(mons_vertex));
+ mons_gltf_buffer_view position_buffer_view =
+ buffer_views[position_accessor.buffer_view_index];
+ FILE *position_buffer =
+ buffers[position_buffer_view.buffer_index];
+ mons_vec3 *positions =
+ calloc(position_accessor.count, sizeof(mons_vec3));
+ fseek(position_buffer, position_buffer_view.byte_offset,
+ SEEK_SET);
+ fread(positions, sizeof(mons_vec3), position_accessor.count,
+ position_buffer);
+ for (int k = 0; k < position_accessor.count; k++) {
+ vertices[k].position = positions[k];
+ }
+ vertex_count = position_accessor.count;
+ }
+ int texcoord_accessor_index;
+ if (mons_json_get_int(primitive_info, "attributes.TEXCOORD_0",
+ &texcoord_accessor_index) == EXIT_SUCCESS) {
+ mons_gltf_accessor texcoord_accessor =
+ accessors[texcoord_accessor_index];
+ mons_gltf_buffer_view texcoord_buffer_view =
+ buffer_views[texcoord_accessor.buffer_view_index];
+ FILE *texcoord_buffer =
+ buffers[texcoord_buffer_view.buffer_index];
+ mons_vec2 *texcoords =
+ calloc(texcoord_accessor.count, sizeof(mons_vec2));
+ fseek(texcoord_buffer, texcoord_buffer_view.byte_offset,
+ SEEK_SET);
+ fread(texcoords, sizeof(mons_vec2), texcoord_accessor.count,
+ texcoord_buffer);
+ for (int k = 0; k < texcoord_accessor.count; k++) {
+ vertices[k].texture_coords = texcoords[k];
+ }
+ }
+ int index_accessor_index;
+ int *indices;
+ int index_count;
+ if (mons_json_get_int(primitive_info, "indices",
+ &index_accessor_index) == EXIT_SUCCESS) {
+ mons_gltf_accessor index_accessor =
+ accessors[index_accessor_index];
+ mons_gltf_buffer_view index_buffer_view =
+ buffer_views[index_accessor.buffer_view_index];
+ FILE *index_buffer = buffers[index_buffer_view.buffer_index];
+ indices = calloc(index_accessor.count, sizeof(int));
+ unsigned short *index_shorts =
+ calloc(index_accessor.count, sizeof(unsigned short));
+ fseek(index_buffer, index_buffer_view.byte_offset, SEEK_SET);
+ fread(index_shorts, sizeof(unsigned short),
+ index_accessor.count, index_buffer);
+ for (int k = 0; k < index_accessor.count; k++) {
+ indices[k] = index_shorts[k];
+ }
+ index_count = index_accessor.count;
+ }
+ int normal_accessor_index;
+ if (mons_json_get_int(primitive_info, "attributes.NORMAL",
+ &normal_accessor_index) == EXIT_SUCCESS) {
+ mons_gltf_accessor normal_accessor =
+ accessors[normal_accessor_index];
+ mons_gltf_buffer_view normal_buffer_view =
+ buffer_views[normal_accessor.buffer_view_index];
+ FILE *normal_buffer =
+ buffers[normal_buffer_view.buffer_index];
+ mons_vec3 *normals =
+ calloc(normal_accessor.count, sizeof(mons_vec3));
+ fseek(normal_buffer, normal_buffer_view.byte_offset,
+ SEEK_SET);
+ fread(normals, sizeof(mons_vec3), normal_accessor.count,
+ normal_buffer);
+ for (int k = 0; k < normal_accessor.count; k++) {
+ vertices[k].normal = normals[k];
+ }
+ }
+
+ int material_index;
+ mons_json_get_int(primitive_info, "material", &material_index);
+
+ mons_gltf_material material = materials[material_index];
+
+ mons_texture *textures = calloc(3, sizeof(mons_texture));
+ textures[0] = mons_texture_from_image(images[material.base_color_texture_index]);
+ textures[1] = mons_texture_from_image(images[material.normal_texture_index]);
+ textures[2] = mons_texture_from_image(images[material.metallic_roughness_texture_index]);
+
+ models[i] = (mons_model) {
+ .mesh = mons_create_mesh(vertices, vertex_count, indices, index_count),
+ .textures = textures,
+ .textures_len = 3,
+ .shader = shader,
+ .transform = MONS_TRANSFORM_IDENTITY,
+ };
+ }
+ }
+
+ *out = models;
+ *count = gltf_mesh_array.len;
+
+ for (int i = 0; i < gltf_accessors_array.len; i++) {
+ free(accessors[i].min);
+ free(accessors[i].max);
+ }
+ free(accessors);
+ free(buffer_views);
+ free(buffers);
+ mons_json_free(json);
+ return EXIT_SUCCESS;
+}
diff --git a/mons_image/CMakeLists.txt b/mons_image/CMakeLists.txt
new file mode 100644
index 0000000..ddfea1a
--- /dev/null
+++ b/mons_image/CMakeLists.txt
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 3.14)
+project(mons_image LANGUAGES C)
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_EXPORT_COMPILE_COMMANDS true)
+set(CMAKE_BUILD_TYPE "Debug")
+
+add_library(mons_image
+ SHARED
+ ./src/image.c
+ ./src/qoi.c
+)
+
+target_include_directories(mons_image PUBLIC
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include"
+ "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
+)
+target_compile_options(mons_image PRIVATE -coverage)
+target_link_options(mons_image PRIVATE -coverage)
+
+include(CTest)
+
+function(TESTCASE NAME)
+ add_executable(test_${NAME} ./tests/${NAME}.c)
+ target_link_libraries(test_${NAME} PUBLIC mons_image)
+ add_test(
+ NAME ${NAME}
+ COMMAND $<TARGET_FILE:test_${NAME}>
+ )
+endfunction()
+
diff --git a/mons_image/include/image.h b/mons_image/include/image.h
new file mode 100644
index 0000000..8b258aa
--- /dev/null
+++ b/mons_image/include/image.h
@@ -0,0 +1,19 @@
+#ifndef MONS_IMAGE_H
+#define MONS_IMAGE_H
+
+typedef struct mons_pixel {
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+ unsigned char a;
+} mons_pixel;
+
+typedef struct mons_image {
+ unsigned int width;
+ unsigned int height;
+ mons_pixel *data;
+} mons_image;
+
+void mons_image_free(mons_image *image);
+
+#endif
diff --git a/mons_image/include/qoi.h b/mons_image/include/qoi.h
new file mode 100644
index 0000000..0fd7895
--- /dev/null
+++ b/mons_image/include/qoi.h
@@ -0,0 +1,7 @@
+#ifndef MONS_QOI_H
+#define MONS_QOI_H
+#include <stdio.h>
+
+struct mons_image mons_load_qoi(FILE *stream);
+
+#endif
diff --git a/mons_image/src/image.c b/mons_image/src/image.c
new file mode 100644
index 0000000..b8abffe
--- /dev/null
+++ b/mons_image/src/image.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+#include "image.h"
+
+void mons_image_free(mons_image *image) {
+ free(image->data);
+}
diff --git a/mons_image/src/qoi.c b/mons_image/src/qoi.c
new file mode 100644
index 0000000..c290c4e
--- /dev/null
+++ b/mons_image/src/qoi.c
@@ -0,0 +1,140 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <byteswap.h>
+#include <inttypes.h>
+#include "qoi.h"
+#include "image.h"
+
+#define MONS_QOI_RGB 3
+#define MONS_QOI_RGBA 4
+#define MONS_QOI_SRGB_LINEAR_ALPHA 0
+#define MONS_QOI_LINEAR 1
+#define MONS_QOI_HEADER_LEN 14
+
+#define MONS_QOI_OP_RGB 0b11111110
+#define MONS_QOI_OP_RGBA 0b11111111
+#define MONS_QOI_OP_INDEX 0b00000000
+#define MONS_QOI_OP_DIFF 0b01000000
+#define MONS_QOI_OP_LUMA 0b10000000
+#define MONS_QOI_OP_RUN 0b11000000
+
+typedef struct mons_qoi_header {
+ char magic[4];
+ uint32_t width;
+ uint32_t height;
+ uint8_t channels;
+ uint8_t colorspace;
+} mons_qoi_header;
+
+unsigned char pixel_index_hash(mons_pixel pixel) {
+ return (pixel.r * 3 + pixel.g * 5 + pixel.b * 7 + pixel.a * 11) % 64;
+}
+
+mons_image mons_load_qoi(FILE *stream) {
+ mons_qoi_header header;
+ if (fread(&header, MONS_QOI_HEADER_LEN, 1, stream) != 1) {
+ fprintf(stderr, "Error reading QOI header");
+ return (mons_image){0};
+ }
+ header.width = __bswap_32(header.width);
+ header.height = __bswap_32(header.height);
+ mons_pixel previous = {0, 0, 0, 255};
+ mons_pixel previously_seen[64] = {0};
+ mons_image output = {
+ .width = header.width,
+ .height = header.height,
+ .data = calloc(4, header.width * header.height),
+ };
+ for (size_t i = 0; i < header.width * header.height; i++) {
+ unsigned char op;
+ if (fread(&op, 1, 1, stream) != 1) {
+ fprintf(stderr, "Failed reading operation byte!");
+ return (mons_image){0};
+ }
+ switch (op) {
+ case MONS_QOI_OP_RGB: {
+ unsigned char rgb[3];
+ if (fread(&rgb, 1, 3, stream) != 3) {
+ fprintf(stderr, "Failed reading RGB data!");
+ return (mons_image){0};
+ }
+ output.data[i] = (mons_pixel){
+ .r = rgb[0],
+ .g = rgb[1],
+ .b = rgb[2],
+ .a = previous.a,
+ };
+ break;
+ }
+ case MONS_QOI_OP_RGBA: {
+ unsigned char rgba[4];
+ if (fread(&rgba, 1, 4, stream) != 4) {
+ fprintf(stderr, "Failed reading RGBA data!");
+ return (mons_image){0};
+ }
+ output.data[i] = (mons_pixel){
+ .r = rgba[0],
+ .g = rgba[1],
+ .b = rgba[2],
+ .a = rgba[3],
+ };
+ break;
+ }
+ default:
+ switch (op & 0b11000000) {
+ case MONS_QOI_OP_INDEX: {
+ unsigned char index = op & 0b00111111;
+ output.data[i] = previously_seen[index];
+ break;
+ }
+ case MONS_QOI_OP_DIFF: {
+ char r_diff = ((op & 0b00110000) >> 4) - 2;
+ char g_diff = ((op & 0b00001100) >> 2) - 2;
+ char b_diff = (op & 0b00000011) - 2;
+ output.data[i] = (mons_pixel){
+ .r = previous.r + r_diff,
+ .g = previous.g + g_diff,
+ .b = previous.b + b_diff,
+ .a = previous.a,
+ };
+ break;
+ }
+ case MONS_QOI_OP_LUMA: {
+ int g_diff = (op & 0b00111111) - 32;
+ unsigned char second_byte;
+ if (fread(&second_byte, 1, 1, stream) != 1) {
+ fprintf(stderr,
+ "Failed to read second byte of luma operation!");
+ return (mons_image){0};
+ }
+ int r_diff = g_diff - 8 + (((second_byte & 0b11110000) >> 4));
+ int b_diff = g_diff - 8 + (second_byte & 0b00001111);
+ output.data[i] = (mons_pixel){
+ .r = previous.r + r_diff,
+ .g = previous.g + g_diff,
+ .b = previous.b + b_diff,
+ .a = previous.a,
+ };
+ break;
+ }
+ case MONS_QOI_OP_RUN: {
+ unsigned char run = (op & 0b00111111) + 1;
+ for (int j = 0; j < run; j++) {
+ output.data[i++] = previous;
+ }
+ i--;
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ previous = output.data[i];
+ unsigned int hash = pixel_index_hash(output.data[i]);
+ previously_seen[hash] = output.data[i];
+ }
+ fclose(stream);
+
+ return output;
+}
diff --git a/mons_json/CMakeLists.txt b/mons_json/CMakeLists.txt
new file mode 100644
index 0000000..d431313
--- /dev/null
+++ b/mons_json/CMakeLists.txt
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 3.14)
+project(mons_json LANGUAGES C)
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_EXPORT_COMPILE_COMMANDS true)
+set(CMAKE_BUILD_TYPE "Debug")
+
+add_library(mons_json
+ SHARED
+ ./src/json.c
+)
+
+target_include_directories(mons_json PUBLIC
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include"
+ "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
+)
+target_compile_options(mons_json PRIVATE -coverage)
+target_link_options(mons_json PRIVATE -coverage)
+target_link_libraries(mons_json PUBLIC mons_collections)
+
+include(CTest)
+
+function(TESTCASE NAME)
+ add_executable(test_${NAME} ./tests/${NAME}.c)
+ target_link_libraries(test_${NAME} PUBLIC mons_json)
+ add_test(
+ NAME ${NAME}
+ COMMAND $<TARGET_FILE:test_${NAME}>
+ )
+endfunction()
+
diff --git a/mons_json/include/json.h b/mons_json/include/json.h
new file mode 100644
index 0000000..da4ee01
--- /dev/null
+++ b/mons_json/include/json.h
@@ -0,0 +1,52 @@
+#ifndef MONS_JSON_H
+#define MONS_JSON_H
+
+#include <stdbool.h>
+#include "hashmap.h"
+
+struct mons_json_value;
+union mons_json_entry;
+
+typedef struct mons_json_array {
+ struct mons_json_value *values;
+ unsigned int len;
+} mons_json_array;
+
+typedef union mons_json_value_data {
+ char *string;
+ float number;
+ mons_hashmap object;
+ mons_json_array array;
+ bool boolean;
+ void *null;
+} mons_json_value_data;
+
+typedef enum mons_json_value_type {
+ MONS_JSON_STRING,
+ MONS_JSON_NUMBER,
+ MONS_JSON_OBJECT,
+ MONS_JSON_ARRAY,
+ MONS_JSON_BOOL,
+ MONS_JSON_NULL,
+} mons_json_value_type;
+
+typedef struct mons_json_value {
+ mons_json_value_type type;
+ mons_json_value_data data;
+} mons_json_value;
+
+int mons_json_parse(char *json, mons_json_value *out);
+
+char *mons_json_to_string(mons_json_value json);
+
+void mons_json_free(mons_json_value json);
+
+int mons_json_get_value(mons_json_value json, char *name, mons_json_value *out);
+int mons_json_get_int(mons_json_value json, char *name, int *out);
+int mons_json_get_float(mons_json_value json, char *name, float *out);
+int mons_json_get_bool(mons_json_value json, char *name, bool *out);
+int mons_json_get_array(mons_json_value json, char *name, mons_json_array *out);
+int mons_json_get_object(mons_json_value json, char *name, mons_hashmap *out);
+int mons_json_get_string(mons_json_value json, char *name, char **out);
+
+#endif
diff --git a/mons_json/src/json.c b/mons_json/src/json.c
new file mode 100644
index 0000000..7b1cc64
--- /dev/null
+++ b/mons_json/src/json.c
@@ -0,0 +1,468 @@
+#include "json.h"
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+
+int try_parse_string(char **current, mons_json_value *out);
+int try_parse_number(char **current, mons_json_value *out);
+int try_parse_object(char **current, mons_json_value *out);
+int try_parse_value(char **current, mons_json_value *out);
+int try_parse_array(char **current, mons_json_value *out);
+int try_parse_literal(char **current, mons_json_value *out);
+
+int mons_json_parse(char *json, mons_json_value *out) {
+ char *current = json;
+ if (try_parse_value(&current, out) == EXIT_SUCCESS) {
+ return EXIT_SUCCESS;
+ }
+ return EXIT_FAILURE;
+}
+
+int try_parse_value(char **current, mons_json_value *out) {
+ // Trim space
+ while (isspace(**current))
+ (*current)++;
+ if (**current == 0) {
+ return EXIT_FAILURE;
+ }
+
+ if (try_parse_literal(current, out) == EXIT_SUCCESS) {
+ return EXIT_SUCCESS;
+ }
+
+ if (try_parse_array(current, out) == EXIT_SUCCESS) {
+ return EXIT_SUCCESS;
+ }
+
+ if (try_parse_object(current, out) == EXIT_SUCCESS) {
+ return EXIT_SUCCESS;
+ }
+
+ if (try_parse_number(current, out) == EXIT_SUCCESS) {
+ return EXIT_SUCCESS;
+ }
+
+ if (try_parse_string(current, out) == EXIT_SUCCESS) {
+ return EXIT_SUCCESS;
+ }
+
+ return EXIT_FAILURE;
+}
+
+int try_parse_string(char **current, mons_json_value *out) {
+ if (**current != '"') {
+ return EXIT_FAILURE;
+ }
+
+ (*current)++;
+ char *end_of_string = strchr(*current, '"');
+ int string_length = end_of_string - *current;
+ char *buffer = calloc(string_length + 1, sizeof(char));
+ // TODO: Unescape Characters
+ memcpy(buffer, *current, string_length);
+ out->type = MONS_JSON_STRING;
+ out->data.string = buffer;
+ *current += string_length + 1;
+ return EXIT_SUCCESS;
+}
+
+int try_parse_number(char **current, mons_json_value *out) {
+ char *end_of_value = *current;
+ while (!isspace(*end_of_value) && *end_of_value != ',' &&
+ *end_of_value != 0 && *end_of_value != ']' && *end_of_value != '}') {
+ end_of_value++;
+ }
+ int value_length = end_of_value - *current;
+ if (value_length == 0) {
+ return EXIT_FAILURE;
+ }
+ bool has_decimal = false;
+ bool has_exponent = false;
+ for (int i = 0; i < value_length; i++) {
+ if (i == 0 && **current == '-') {
+ continue;
+ }
+ if (!isdigit(*(*current + i))) {
+ switch (*(*current + i)) {
+ case 'e':
+ case 'E':
+ if (has_exponent) {
+ return EXIT_FAILURE;
+ } else {
+ has_exponent = true;
+ }
+ break;
+ case '+':
+ case '-':
+ if (*(*current + i - 1) != 'e' && *(*current +i - 1) != 'E') {
+ return EXIT_FAILURE;
+ }
+ break;
+ case '.':
+ if (has_decimal) {
+ return EXIT_FAILURE;
+ } else {
+ has_decimal = true;
+ }
+ break;
+ default:
+ return EXIT_FAILURE;
+ }
+ }
+ }
+ // Value is a valid number
+ out->type = MONS_JSON_NUMBER;
+ out->data.number = atof(*current);
+ *current += value_length;
+ return EXIT_SUCCESS;
+}
+
+int try_parse_object(char **current, mons_json_value *out) {
+ if (**current != '{') {
+ return EXIT_FAILURE;
+ }
+ (*current)++;
+
+ mons_hashmap map = mons_hashmap_new(sizeof(mons_json_value), 10);
+
+ while (true) {
+ // Trim space
+ while (isspace(**current))
+ (*current)++;
+ if (**current == 0) {
+ printf("ALL WHITESPACE\n");
+ return EXIT_FAILURE;
+ }
+
+ mons_json_value key;
+ if (try_parse_string(current, &key) == EXIT_SUCCESS) {
+ // Trim space
+ while (isspace(**current))
+ (*current)++;
+ if (*current == 0) {
+ return EXIT_FAILURE;
+ }
+
+ if (**current != ':') {
+ return EXIT_FAILURE;
+ }
+ (*current)++;
+ mons_json_value value;
+ if (try_parse_value(current, &value) == EXIT_FAILURE) {
+ return EXIT_FAILURE;
+ }
+ mons_hashmap_insert(&map, key.data.string, &value);
+ continue;
+ } else {
+ // Trim space
+ while (isspace(**current))
+ (*current)++;
+ if (*current == 0) {
+ return EXIT_FAILURE;
+ }
+ switch (**current) {
+ case ',':
+ (*current)++;
+ continue;
+ case '}':
+ (*current)++;
+ out->type = MONS_JSON_OBJECT;
+ out->data.object = map;
+ return EXIT_SUCCESS;
+ default:
+ return EXIT_FAILURE;
+ }
+ }
+ }
+ return EXIT_FAILURE;
+}
+
+int try_parse_array(char **current, mons_json_value *out) {
+ if (**current != '[') {
+ return EXIT_FAILURE;
+ }
+ (*current)++;
+
+ mons_json_array array = {
+ .values = NULL,
+ .len = 0,
+ };
+
+ while (true) {
+ // Trim space
+ while (isspace(**current))
+ (*current)++;
+ if (**current == 0) {
+ return EXIT_FAILURE;
+ }
+
+ mons_json_value value;
+ if (try_parse_value(current, &value) == EXIT_SUCCESS) {
+ array.len++;
+ array.values =
+ realloc(array.values, sizeof(mons_json_value) * array.len);
+ array.values[array.len - 1] = value;
+ continue;
+ } else {
+ // Trim space
+ while (isspace(**current))
+ (*current)++;
+ if (*current == 0) {
+ return EXIT_FAILURE;
+ }
+ switch (**current) {
+ case ',':
+ (*current)++;
+ continue;
+ case ']':
+ (*current)++;
+ out->type = MONS_JSON_ARRAY;
+ out->data.array = array;
+ return EXIT_SUCCESS;
+ default:
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ return EXIT_FAILURE;
+}
+
+int try_parse_literal(char **current, mons_json_value *out) {
+ // Trim space
+ while (isspace(**current))
+ (*current)++;
+ if (**current == 0) {
+ return EXIT_FAILURE;
+ }
+
+ if (strncmp(*current, "true", 4) == 0) {
+ *current += 4;
+ out->type = MONS_JSON_BOOL;
+ out->data.boolean = true;
+ return EXIT_SUCCESS;
+ } else if (strncmp(*current, "false", 5) == 0) {
+ *current += 5;
+ out->type = MONS_JSON_BOOL;
+ out->data.boolean = false;
+ return EXIT_SUCCESS;
+ } else if (strncmp(*current, "null", 4) == 0) {
+ *current += 4;
+ out->type = MONS_JSON_NULL;
+ out->data.null = NULL;
+ return EXIT_SUCCESS;
+ }
+
+ return EXIT_FAILURE;
+}
+
+void json_value_to_string(mons_json_value value, char **buffer,
+ unsigned int *current_len) {
+ switch (value.type) {
+ case MONS_JSON_NULL:
+ *buffer = realloc(*buffer, *current_len + 4);
+ strcpy(*buffer + *current_len, "null");
+ *current_len += 4;
+ break;
+ case MONS_JSON_BOOL:
+ if (value.data.boolean) {
+ *buffer = realloc(*buffer, *current_len + 4);
+ memcpy(*buffer + *current_len, "true", 4);
+ *current_len += 4;
+ break;
+ } else {
+ *buffer = realloc(*buffer, *current_len + 5);
+ memcpy(*buffer + *current_len, "false", 5);
+ *current_len += 5;
+ break;
+ }
+ case MONS_JSON_ARRAY: {
+ *buffer = realloc(*buffer, *current_len + 1);
+ (*buffer)[*current_len] = '[';
+ *current_len += 1;
+ for (int i = 0; i < value.data.array.len; i++) {
+ mons_json_value member = value.data.array.values[i];
+ char *buff = NULL;
+ unsigned int len = 0;
+ json_value_to_string(member, &buff, &len);
+ *buffer = realloc(*buffer, *current_len + len + 1);
+ memcpy(*buffer + *current_len, buff, len);
+ free(buff);
+ *current_len += len;
+ *buffer = realloc(*buffer, *current_len + 1);
+ if (i + 1 < value.data.array.len) {
+ (*buffer)[*current_len] = ',';
+ } else {
+ (*buffer)[*current_len] = ']';
+ }
+ *current_len += 1;
+ }
+ break;
+ }
+ case MONS_JSON_OBJECT:
+ *buffer = realloc(*buffer, *current_len + 1);
+ (*buffer)[*current_len] = '{';
+ *current_len += 1;
+ for (int i = 0; i < value.data.object.len; i++) {
+ mons_hashmap_pair pair;
+ mons_hashmap_at(value.data.object, i, &pair);
+ char *key = pair.key;
+ mons_json_value *entry_value = pair.value;
+ // key
+ *buffer = realloc(*buffer, *current_len + strlen(key) + 3);
+ sprintf(*buffer + *current_len, "\"%s\":", key);
+ *current_len += strlen(key) + 3;
+ char *buff = NULL;
+ unsigned int len = 0;
+ json_value_to_string(*entry_value, &buff, &len);
+ *buffer = realloc(*buffer, *current_len + len + 1);
+ memcpy(*buffer + *current_len, buff, len);
+ free(buff);
+ *current_len += len;
+ *buffer = realloc(*buffer, *current_len + 1);
+ if (i + 1 < value.data.object.len) {
+ (*buffer)[*current_len] = ',';
+ } else {
+ (*buffer)[*current_len] = '}';
+ }
+ *current_len += 1;
+ }
+ break;
+ case MONS_JSON_NUMBER: {
+ unsigned int len = snprintf(0, 0, "%e", value.data.number);
+ *buffer = realloc(*buffer, *current_len + len);
+ sprintf(*buffer + *current_len, "%e", value.data.number);
+ *current_len += len;
+ break;
+ }
+ case MONS_JSON_STRING: {
+ unsigned int len = snprintf(0, 0, "\"%s\"", value.data.string);
+ *buffer = realloc(*buffer, *current_len + len);
+ sprintf(*buffer + *current_len, "\"%s\"", value.data.string);
+ *current_len += len;
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+char *mons_json_to_string(mons_json_value json) {
+ char *buffer = NULL;
+ unsigned int len = 0;
+ json_value_to_string(json, &buffer, &len);
+ buffer = realloc(buffer, len + 1);
+ buffer[len] = 0;
+ return buffer;
+}
+
+void mons_json_free(mons_json_value json) {
+ switch(json.type) {
+ case MONS_JSON_OBJECT:
+ mons_hashmap_free(&json.data.object);
+ break;
+ case MONS_JSON_ARRAY:
+ for(int i = 0; i < json.data.array.len; i++) {
+ mons_json_free(json.data.array.values[i]);
+ }
+ json.data.array.len = 0;
+ free(json.data.array.values);
+ json.data.array.values = NULL;
+ break;
+ case MONS_JSON_STRING:
+ free(json.data.string);
+ json.data.string = NULL;
+ break;
+ default:
+ break;
+ }
+}
+
+int mons_json_get_value(mons_json_value json, char *name, mons_json_value *out) {
+ int name_len = strlen(name);
+ char *name_copy = calloc(name_len + 1, 1);
+ strcpy(name_copy, name);
+ char *field = strtok(name_copy, ".");
+ mons_json_value member = json;
+ while(field != NULL) {
+ char *subscript = strchr(field, '[');
+ int array_index = 0;
+ if(subscript != NULL) {
+ array_index = atoi(subscript + 1);
+ *subscript = 0;
+ }
+
+ if (member.type != MONS_JSON_OBJECT) {
+ return EXIT_FAILURE;
+ }
+ mons_json_value value;
+ if (mons_hashmap_get(member.data.object, field, &value) == EXIT_SUCCESS) {
+ member = value;
+ if (subscript != NULL) {
+ member = member.data.array.values[array_index];
+ }
+ } else {
+ return EXIT_FAILURE;
+ }
+ field = strtok(NULL, ".");
+ }
+ *out = member;
+ return EXIT_SUCCESS;
+}
+
+int mons_json_get_int(mons_json_value json, char *name, int *out) {
+ mons_json_value value = {0};
+ if(mons_json_get_value(json, name, &value) == EXIT_SUCCESS && value.type == MONS_JSON_NUMBER) {
+ *out = value.data.number;
+ return EXIT_SUCCESS;
+ }
+ return EXIT_FAILURE;
+}
+
+int mons_json_get_float(mons_json_value json, char *name, float *out) {
+ mons_json_value value = {0};
+ if(mons_json_get_value(json, name, &value) == EXIT_SUCCESS && value.type == MONS_JSON_NUMBER) {
+ *out = value.data.number;
+ return EXIT_SUCCESS;
+ }
+ return EXIT_FAILURE;
+}
+
+int mons_json_get_bool(mons_json_value json, char *name, bool *out) {
+ mons_json_value value = {0};
+ if(mons_json_get_value(json, name, &value) == EXIT_SUCCESS && value.type == MONS_JSON_BOOL) {
+ *out = value.data.boolean;
+ return EXIT_SUCCESS;
+ }
+ return EXIT_FAILURE;
+}
+
+int mons_json_get_array(mons_json_value json, char *name, mons_json_array *out) {
+ mons_json_value value = {0};
+ if(mons_json_get_value(json, name, &value) == EXIT_SUCCESS && value.type == MONS_JSON_ARRAY) {
+ *out = value.data.array;
+ return EXIT_SUCCESS;
+ }
+ return EXIT_FAILURE;
+}
+
+int mons_json_get_object(mons_json_value json, char *name, mons_hashmap *out) {
+ mons_json_value value = {0};
+ if(mons_json_get_value(json, name, &value) == EXIT_SUCCESS && value.type == MONS_JSON_OBJECT) {
+ *out = value.data.object;
+ return EXIT_SUCCESS;
+ }
+ return EXIT_FAILURE;
+}
+
+int mons_json_get_string(mons_json_value json, char *name, char **out) {
+ mons_json_value value = {0};
+ if(mons_json_get_value(json, name, &value) == EXIT_SUCCESS && value.type == MONS_JSON_STRING) {
+ *out = value.data.string;
+ return EXIT_SUCCESS;
+ }
+ return EXIT_FAILURE;
+}
+
diff --git a/mons_math/CMakeLists.txt b/mons_math/CMakeLists.txt
new file mode 100644
index 0000000..e5d015e
--- /dev/null
+++ b/mons_math/CMakeLists.txt
@@ -0,0 +1,43 @@
+cmake_minimum_required(VERSION 3.14)
+project(mons_math LANGUAGES C)
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_EXPORT_COMPILE_COMMANDS true)
+set(CMAKE_BUILD_TYPE "Debug")
+
+add_library(mons_math
+ SHARED
+ ./src/mat2.c
+ ./src/mat3.c
+ ./src/mat4.c
+ ./src/vec2.c
+ ./src/vec3.c
+ ./src/vec4.c
+ ./src/util.c
+ ./src/quat.c
+)
+
+target_include_directories(mons_math PUBLIC
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include"
+ "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
+)
+target_compile_options(mons_math PRIVATE -coverage)
+target_link_options(mons_math PRIVATE -coverage)
+target_link_libraries(mons_math PUBLIC m)
+
+include(CTest)
+
+function(TESTCASE NAME)
+ add_executable(test_${NAME} ./tests/${NAME}.c)
+ target_link_libraries(test_${NAME} PUBLIC mons_math)
+ add_test(
+ NAME ${NAME}
+ COMMAND $<TARGET_FILE:test_${NAME}>
+ )
+endfunction()
+
+testcase(vec2_ops)
+testcase(vec3_ops)
+testcase(vec4_ops)
+# testcase(mat2_ops)
+# testcase(mat3_ops)
+# testcase(mat4_ops)
diff --git a/mons_math/include/mons_math/mat2.h b/mons_math/include/mons_math/mat2.h
new file mode 100644
index 0000000..b1a8ca0
--- /dev/null
+++ b/mons_math/include/mons_math/mat2.h
@@ -0,0 +1,39 @@
+#ifndef MONS_MAT2_H
+#define MONS_MAT2_H
+
+#include "mons_math/vec2.h"
+
+typedef struct mons_mat2 {
+ mons_vec2 m1;
+ mons_vec2 m2;
+} mons_mat2;
+
+mons_mat2 mons_mat2_add(mons_mat2 a, mons_mat2 b);
+void mons_mat2_add_inplace(mons_mat2 *a, mons_mat2 b);
+
+mons_mat2 mons_mat2_mul_f(mons_mat2 a, float b);
+mons_mat2 mons_mat2_mul_i(mons_mat2 a, int b);
+mons_mat2 mons_mat2_mul(mons_mat2 a, mons_mat2 b);
+
+void mons_mat2_mul_f_inplace(mons_mat2 *a, float b);
+void mons_mat2_mul_i_inplace(mons_mat2 *a, int b);
+
+mons_mat2 mons_mat2_inverse(mons_mat2 a);
+void mons_mat2_inverse_inplace(mons_mat2 *a);
+
+mons_mat2 mons_mat2_transpose(mons_mat2 a);
+void mons_mat2_transpose_inplace(mons_mat2 *a);
+
+mons_vec2 mons_mat2_n1(mons_mat2 a);
+mons_vec2 mons_mat2_n2(mons_mat2 a);
+
+float mons_mat2_determinant(mons_mat2 a);
+mons_mat2 mons_mat2_adjoint(mons_mat2 a);
+mons_mat2 mons_mat2_inverse(mons_mat2 a);
+
+extern const mons_mat2 MONS_MAT2_ZERO;
+extern const mons_mat2 MONS_MAT2_IDENTITY;
+
+int mons_mat2_equal(mons_mat2 a, mons_mat2 b);
+
+#endif
diff --git a/mons_math/include/mons_math/mat3.h b/mons_math/include/mons_math/mat3.h
new file mode 100644
index 0000000..9ca4a64
--- /dev/null
+++ b/mons_math/include/mons_math/mat3.h
@@ -0,0 +1,41 @@
+#ifndef MONS_MAT3_H
+#define MONS_MAT3_H
+
+#include "mons_math/vec3.h"
+
+typedef struct mons_mat3 {
+ mons_vec3 m1;
+ mons_vec3 m2;
+ mons_vec3 m3;
+} mons_mat3;
+
+mons_mat3 mons_mat3_add(mons_mat3 a, mons_mat3 b);
+void mons_mat3_add_inplace(mons_mat3 *a, mons_mat3 b);
+
+mons_mat3 mons_mat3_mul_f(mons_mat3 a, float b);
+mons_mat3 mons_mat3_mul_i(mons_mat3 a, int b);
+mons_mat3 mons_mat3_mul(mons_mat3 a, mons_mat3 b);
+
+void mons_mat3_mul_f_inplace(mons_mat3 *a, float b);
+void mons_mat3_mul_i_inplace(mons_mat3 *a, int b);
+
+mons_mat3 mons_mat3_inverse(mons_mat3 a);
+
+mons_mat3 mons_mat3_transpose(mons_mat3 a);
+void mons_mat3_transpose_inplace(mons_mat3 *a);
+
+mons_vec3 mons_mat3_n1(mons_mat3 a);
+mons_vec3 mons_mat3_n2(mons_mat3 a);
+mons_vec3 mons_mat3_n3(mons_mat3 a);
+
+float mons_mat3_determinant(mons_mat3 a);
+mons_mat3 mons_mat3_minor(mons_mat3 a);
+mons_mat3 mons_mat3_cofactor(mons_mat3 a);
+mons_mat3 mons_mat3_adjoint(mons_mat3 a);
+
+extern const mons_mat3 MONS_MAT3_ZERO;
+extern const mons_mat3 MONS_MAT3_IDENTITY;
+
+int mons_mat3_equal(mons_mat3 a, mons_mat3 b);
+
+#endif
diff --git a/mons_math/include/mons_math/mat4.h b/mons_math/include/mons_math/mat4.h
new file mode 100644
index 0000000..0b949fe
--- /dev/null
+++ b/mons_math/include/mons_math/mat4.h
@@ -0,0 +1,57 @@
+#ifndef MONS_MATH_MATRIX_H
+#define MONS_MATH_MATRIX_H
+
+#include "mons_math/vec4.h"
+
+typedef struct mons_mat4 {
+ mons_vec4 m1;
+ mons_vec4 m2;
+ mons_vec4 m3;
+ mons_vec4 m4;
+} mons_mat4;
+
+mons_mat4 mons_mat4_add(mons_mat4 a, mons_mat4 b);
+void mons_mat4_add_inplace(mons_mat4 *a, mons_mat4 b);
+
+mons_mat4 mons_mat4_mul_f(mons_mat4 a, float b);
+mons_mat4 mons_mat4_mul_i(mons_mat4 a, int b);
+mons_mat4 mons_mat4_mul(mons_mat4 a, mons_mat4 b);
+void mons_mat4_mul_inplace(mons_mat4 *a, mons_mat4 b);
+
+void mons_mat4_mul_f_inplace(mons_mat4 *a, float b);
+void mons_mat4_mul_i_inplace(mons_mat4 *a, int b);
+
+mons_mat4 mons_mat4_inverse(mons_mat4 a);
+
+mons_mat4 mons_mat4_transpose(mons_mat4 a);
+void mons_mat4_transpose_inplace(mons_mat4 *a);
+
+mons_vec4 mons_mat4_n1(mons_mat4 a);
+mons_vec4 mons_mat4_n2(mons_mat4 a);
+mons_vec4 mons_mat4_n3(mons_mat4 a);
+mons_vec4 mons_mat4_n4(mons_mat4 a);
+
+float mons_mat4_determinant(mons_mat4 a);
+
+extern const mons_mat4 MONS_MAT4_ZERO;
+extern const mons_mat4 MONS_MAT4_IDENTITY;
+
+int mons_mat4_equal(mons_mat4 a, mons_mat4 b);
+
+void mons_mat4_print(mons_mat4 mat);
+
+#define MONS_MAT4_ZERO {\
+ { 0, 0, 0, 0 },\
+ { 0, 0, 0, 0 },\
+ { 0, 0, 0, 0 },\
+ { 0, 0, 0, 0 },\
+}
+
+#define MONS_MAT4_IDENTITY {\
+ { 1, 0, 0, 0 },\
+ { 0, 1, 0, 0 },\
+ { 0, 0, 1, 0 },\
+ { 0, 0, 0, 1 },\
+}
+
+#endif
diff --git a/mons_math/include/mons_math/matrix.h b/mons_math/include/mons_math/matrix.h
new file mode 100644
index 0000000..48fdec6
--- /dev/null
+++ b/mons_math/include/mons_math/matrix.h
@@ -0,0 +1,8 @@
+#ifndef MONS_MATRIX_H
+#define MONS_MATRIX_H
+
+#include "mat2.h"
+#include "mat3.h"
+#include "mat4.h"
+
+#endif
diff --git a/mons_math/include/mons_math/quat.h b/mons_math/include/mons_math/quat.h
new file mode 100644
index 0000000..353d7bb
--- /dev/null
+++ b/mons_math/include/mons_math/quat.h
@@ -0,0 +1,44 @@
+#ifndef MONS_QUAT_H
+#define MONS_QUAT_H
+
+struct mons_vec3;
+
+typedef struct mons_quat {
+ float x;
+ float y;
+ float z;
+ float w;
+} mons_quat;
+
+mons_quat mons_quat_from_axis_angle(struct mons_vec3 axis, float angle);
+
+mons_quat mons_quat_mul(mons_quat a, mons_quat b);
+
+void mons_quat_mul_inplace(mons_quat *a, mons_quat b);
+
+mons_quat mons_quat_mul_f(mons_quat a, float b);
+
+void mons_quat_mul_f_inplace(mons_quat *a, float b);
+
+mons_quat mons_quat_mul_i(mons_quat a, int b);
+
+void mons_quat_mul_i_inplace(mons_quat *a, int b);
+
+struct mons_mat4 mons_quat_to_mat4(mons_quat a);
+
+mons_quat mons_quat_normalize(mons_quat a);
+
+void mons_quat_normalize_inplace(mons_quat *a);
+
+struct mons_vec3 mons_quat_transform_vec3(mons_quat quat, struct mons_vec3 vec);
+
+mons_quat mons_quat_conjugate(mons_quat quat);
+
+mons_quat mons_quat_looking_at(struct mons_vec3 eye, struct mons_vec3 target, struct mons_vec3 up);
+
+void mons_quat_print(mons_quat quat);
+
+#define MONS_QUAT_IDENTITY (mons_quat) { 0, 0, 0, 1 }
+
+#endif
+
diff --git a/mons_math/include/mons_math/util.h b/mons_math/include/mons_math/util.h
new file mode 100644
index 0000000..5218243
--- /dev/null
+++ b/mons_math/include/mons_math/util.h
@@ -0,0 +1,8 @@
+#ifndef MONS_MATH_UTIL_H
+#define MONS_MATH_UTIL_H
+
+#define MONS_FLOAT_EQUAL_EPSILON 0.0001f;
+
+int mons_float_approx_equal(float a, float b);
+
+#endif
diff --git a/mons_math/include/mons_math/vec2.h b/mons_math/include/mons_math/vec2.h
new file mode 100644
index 0000000..3fb405d
--- /dev/null
+++ b/mons_math/include/mons_math/vec2.h
@@ -0,0 +1,46 @@
+#ifndef MONS_VEC2_H
+#define MONS_VEC2_H
+
+typedef struct mons_vec2 {
+ float x;
+ float y;
+} mons_vec2;
+
+mons_vec2 mons_vec2_add(mons_vec2 a, mons_vec2 b);
+void mons_vec2_add_inplace(mons_vec2 *a, mons_vec2 b);
+
+mons_vec2 mons_vec2_sub(mons_vec2 a, mons_vec2 b);
+void mons_vec2_sub_inplace(mons_vec2 *a, mons_vec2 b);
+
+mons_vec2 mons_vec2_mul_f(mons_vec2 a, float b);
+mons_vec2 mons_vec2_mul_i(mons_vec2 a, int b);
+float mons_vec2_dot(mons_vec2 a, mons_vec2 b);
+
+void mons_vec2_mul_f_inplace(mons_vec2 *a, float b);
+void mons_vec2_mul_i_inplace(mons_vec2 *a, int b);
+
+mons_vec2 mons_vec2_div_f(mons_vec2 a, float b);
+mons_vec2 mons_vec2_div_i(mons_vec2 a, int b);
+void mons_vec2_div_f_inplace(mons_vec2 *a, float b);
+void mons_vec2_div_i_inplace(mons_vec2 *a, int b);
+
+float mons_vec2_len(mons_vec2 a);
+float mons_vec2_len_squared(mons_vec2 a);
+
+struct mons_vec3 mons_vec2_extend(mons_vec2 a);
+
+int mons_vec2_equal(mons_vec2 a, mons_vec2 b);
+mons_vec2 mons_vec2_negate(mons_vec2 a);
+void mons_vec2_negate_inplace(mons_vec2 *a);
+
+mons_vec2 mons_vec2_normalize(mons_vec2 a);
+void mons_vec2_normalize_inplace(mons_vec2 *a);
+
+#define MONS_VEC2_ZERO (mons_vec2) { 0, 0 }
+#define MONS_VEC2_ONE (mons_vec2) { 1, 1 }
+#define MONS_VEC2_X (mons_vec2) { 1, 0 }
+#define MONS_VEC2_Y (mons_vec2) { 0, 1 }
+#define MONS_VEC2_NEG_X (mons_vec2) {-1,0}
+#define MONS_VEC2_NEG_Y (mons_vec2) {0,-1}
+
+#endif
diff --git a/mons_math/include/mons_math/vec3.h b/mons_math/include/mons_math/vec3.h
new file mode 100644
index 0000000..6b37410
--- /dev/null
+++ b/mons_math/include/mons_math/vec3.h
@@ -0,0 +1,56 @@
+#ifndef MONS_VEC3_H
+#define MONS_VEC3_H
+
+typedef struct mons_vec3 {
+ float x;
+ float y;
+ float z;
+} mons_vec3;
+
+mons_vec3 mons_vec3_add(mons_vec3 a, mons_vec3 b);
+void mons_vec3_add_inplace(mons_vec3 *a, mons_vec3 b);
+
+mons_vec3 mons_vec3_sub(mons_vec3 a, mons_vec3 b);
+void mons_vec3_sub_inplace(mons_vec3 *a, mons_vec3 b);
+
+mons_vec3 mons_vec3_mul_memberwise(mons_vec3 a, mons_vec3 b);
+void mons_vec3_mul_memberwise_inplace(mons_vec3 *a, mons_vec3 b);
+mons_vec3 mons_vec3_mul_f(mons_vec3 a, float b);
+mons_vec3 mons_vec3_mul_i(mons_vec3 a, int b);
+float mons_vec3_dot(mons_vec3 a, mons_vec3 b);
+
+void mons_vec3_mul_f_inplace(mons_vec3 *a, float b);
+void mons_vec3_mul_i_inplace(mons_vec3 *a, int b);
+
+mons_vec3 mons_vec3_div_f(mons_vec3 a, float b);
+mons_vec3 mons_vec3_div_i(mons_vec3 a, int b);
+void mons_vec3_div_f_inplace(mons_vec3 *a, float b);
+void mons_vec3_div_i_inplace(mons_vec3 *a, int b);
+
+mons_vec3 mons_vec3_cross(mons_vec3 a, mons_vec3 b);
+
+float mons_vec3_len(mons_vec3 a);
+float mons_vec3_len_squared(mons_vec3 a);
+
+struct mons_vec2 mons_vec3_truncate(mons_vec3 a);
+struct mons_vec4 mons_vec3_extend(mons_vec3 a);
+
+int mons_vec3_equal(mons_vec3 a, mons_vec3 b);
+mons_vec3 mons_vec3_negate(mons_vec3 a);
+void mons_vec3_negate_inplace(mons_vec3 *a);
+
+mons_vec3 mons_vec3_normalize(mons_vec3 a);
+void mons_vec3_normalize_inplace(mons_vec3 *a);
+
+void mons_vec3_print(mons_vec3 vec);
+
+#define MONS_VEC3_ZERO (mons_vec3) { 0, 0, 0 }
+#define MONS_VEC3_ONE (mons_vec3) { 1, 1, 1 }
+#define MONS_VEC3_X (mons_vec3) { 1, 0, 0 }
+#define MONS_VEC3_Y (mons_vec3) { 0, 1, 0 }
+#define MONS_VEC3_Z (mons_vec3) { 0, 0, 1 }
+#define MONS_VEC3_NEG_X (mons_vec3) {-1,0,0}
+#define MONS_VEC3_NEG_Y (mons_vec3) {0,-1,0}
+#define MONS_VEC3_NEG_Z (mons_vec3) {0,0,-1}
+
+#endif
diff --git a/mons_math/include/mons_math/vec4.h b/mons_math/include/mons_math/vec4.h
new file mode 100644
index 0000000..24a2d8f
--- /dev/null
+++ b/mons_math/include/mons_math/vec4.h
@@ -0,0 +1,53 @@
+#ifndef MONS_MATH_VEC4_H
+#define MONS_MATH_VEC4_H
+
+typedef struct mons_vec4 {
+ float x;
+ float y;
+ float z;
+ float w;
+} mons_vec4;
+
+mons_vec4 mons_vec4_add(mons_vec4 a, mons_vec4 b);
+void mons_vec4_add_inplace(mons_vec4 *a, mons_vec4 b);
+
+mons_vec4 mons_vec4_sub(mons_vec4 a, mons_vec4 b);
+void mons_vec4_sub_inplace(mons_vec4 *a, mons_vec4 b);
+
+mons_vec4 mons_vec4_mul_f(mons_vec4 a, float b);
+mons_vec4 mons_vec4_mul_i(mons_vec4 a, int b);
+float mons_vec4_dot(mons_vec4 a, mons_vec4 b);
+
+void mons_vec4_mul_f_inplace(mons_vec4 *a, float b);
+void mons_vec4_mul_i_inplace(mons_vec4 *a, int b);
+
+mons_vec4 mons_vec4_div_f(mons_vec4 a, float b);
+mons_vec4 mons_vec4_div_i(mons_vec4 a, int b);
+void mons_vec4_div_f_inplace(mons_vec4 *a, float b);
+void mons_vec4_div_i_inplace(mons_vec4 *a, int b);
+
+float mons_vec4_len(mons_vec4 a);
+float mons_vec4_len_squared(mons_vec4 a);
+
+struct mons_vec3 mons_vec4_truncate(mons_vec4 a);
+
+int mons_vec4_equal(mons_vec4 a, mons_vec4 b);
+mons_vec4 mons_vec4_negate(mons_vec4 a);
+void mons_vec4_negate_inplace(mons_vec4 *a);
+mons_vec4 mons_vec4_normalize(mons_vec4 a);
+void mons_vec4_normalize_inplace(mons_vec4 *a);
+
+void mons_vec4_print(mons_vec4 vec);
+
+#define MONS_VEC4_ZERO (mons_vec4) { 0, 0, 0, 0 }
+#define MONS_VEC4_ONE (mons_vec4) { 1, 1, 1, 1 }
+#define MONS_VEC4_X (mons_vec4) { 1, 0, 0, 0 }
+#define MONS_VEC4_Y (mons_vec4) { 0, 1, 0, 0 }
+#define MONS_VEC4_Z (mons_vec4) { 0, 0, 1, 0 }
+#define MONS_VEC4_W (mons_vec4) { 0, 0, 0, 1 }
+#define MONS_VEC4_NEG_X (mons_vec4) {-1,0,0,0}
+#define MONS_VEC4_NEG_Y (mons_vec4) {0,-1,0,0}
+#define MONS_VEC4_NEG_Z (mons_vec4) {0,0,-1,0}
+#define MONS_VEC4_NEG_W (mons_vec4) {0,0,0,-1}
+
+#endif
diff --git a/mons_math/include/mons_math/vector.h b/mons_math/include/mons_math/vector.h
new file mode 100644
index 0000000..2576d26
--- /dev/null
+++ b/mons_math/include/mons_math/vector.h
@@ -0,0 +1,8 @@
+#ifndef MONS_VECTOR_H
+#define MONS_VECTOR_H
+
+#include "vec2.h"
+#include "vec3.h"
+#include "vec4.h"
+
+#endif
diff --git a/mons_math/run_tests b/mons_math/run_tests
new file mode 100755
index 0000000..5a3b9ef
--- /dev/null
+++ b/mons_math/run_tests
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+cmake . -B build &&
+make -C build &&
+ctest --test-dir build --output-on-failure -T Test -T Coverage
+
diff --git a/mons_math/src/mat2.c b/mons_math/src/mat2.c
new file mode 100644
index 0000000..026b165
--- /dev/null
+++ b/mons_math/src/mat2.c
@@ -0,0 +1,123 @@
+#include "mons_math/mat2.h"
+
+const mons_mat2 MONS_MAT2_ZERO = {
+ {0, 0},
+ {0, 0},
+};
+
+const mons_mat2 MONS_MAT2_IDENTITY = {
+ {1, 0},
+ {0, 1},
+};
+
+mons_mat2 mons_mat2_add(mons_mat2 a, mons_mat2 b) {
+ mons_mat2 result = {
+ mons_vec2_add(a.m1, b.m1),
+ mons_vec2_add(a.m2, b.m2),
+ };
+ return result;
+}
+
+void mons_mat2_add_inplace(mons_mat2 *a, mons_mat2 b) {
+ mons_vec2_add_inplace(&a->m1, b.m1);
+ mons_vec2_add_inplace(&a->m2, b.m2);
+}
+
+mons_mat2 mons_mat2_mul_f(mons_mat2 a, float b) {
+ mons_mat2 result = {
+ mons_vec2_mul_f(a.m1, b),
+ mons_vec2_mul_f(a.m2, b),
+ };
+ return result;
+}
+
+mons_mat2 mons_mat2_mul_i(mons_mat2 a, int b) {
+ mons_mat2 result = {
+ mons_vec2_mul_i(a.m1, b),
+ mons_vec2_mul_i(a.m2, b),
+ };
+ return result;
+}
+
+mons_mat2 mons_mat2_mul(mons_mat2 a, mons_mat2 b) {
+ mons_vec2 b_n1 = mons_mat2_n1(b);
+ mons_vec2 b_n2 = mons_mat2_n2(b);
+
+ mons_mat2 result = {
+ {
+ mons_vec2_dot(a.m1, b_n1),
+ mons_vec2_dot(a.m1, b_n2),
+ },
+ {
+ mons_vec2_dot(a.m2, b_n1),
+ mons_vec2_dot(a.m2, b_n2),
+ },
+ };
+ return result;
+}
+
+void mons_mat2_mul_f_inplace(mons_mat2 *a, float b) {
+ mons_vec2_mul_f_inplace(&a->m1, b);
+ mons_vec2_mul_f_inplace(&a->m2, b);
+}
+
+void mons_mat2_mul_i_inplace(mons_mat2 *a, int b) {
+ mons_vec2_mul_i_inplace(&a->m1, b);
+ mons_vec2_mul_i_inplace(&a->m2, b);
+}
+
+mons_mat2 mons_mat2_transpose(mons_mat2 a) {
+ mons_mat2 result = {
+ mons_mat2_n1(a),
+ mons_mat2_n2(a),
+ };
+ return result;
+}
+
+void mons_mat2_transpose_inplace(mons_mat2 *a) { *a = mons_mat2_transpose(*a); }
+
+mons_vec2 mons_mat2_n1(mons_mat2 a) {
+ mons_vec2 result = {
+ a.m1.x,
+ a.m2.x,
+ };
+ return result;
+}
+
+mons_vec2 mons_mat2_n2(mons_mat2 a) {
+ mons_vec2 result = {
+ a.m1.y,
+ a.m2.y,
+ };
+ return result;
+}
+
+float mons_mat2_determinant(mons_mat2 a) {
+ // ad - bc
+ return (a.m1.x * a.m2.y) - (a.m1.y * a.m2.x);
+}
+
+mons_mat2 mons_mat2_adjoint(mons_mat2 a) {
+ /*
+ * d -b
+ * -c a
+ */
+ mons_mat2 result = {{
+ a.m2.y,
+ -a.m1.y,
+ },
+ {
+ -a.m2.x,
+ a.m1.x,
+ }};
+ return result;
+}
+
+mons_mat2 mons_mat2_inverse(mons_mat2 a) {
+ return mons_mat2_mul_f(mons_mat2_adjoint(a),
+ 1.0 / mons_mat2_determinant(a));
+}
+
+int mons_mat2_equal(mons_mat2 a, mons_mat2 b) {
+ return mons_vec2_equal(a.m1, b.m1) && mons_vec2_equal(a.m2, b.m2);
+}
diff --git a/mons_math/src/mat3.c b/mons_math/src/mat3.c
new file mode 100644
index 0000000..f806375
--- /dev/null
+++ b/mons_math/src/mat3.c
@@ -0,0 +1,237 @@
+#include "mons_math/mat3.h"
+#include "mons_math/mat2.h"
+#include "mons_math/vec3.h"
+
+const mons_mat3 MONS_MAT3_ZERO = {
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+};
+
+const mons_mat3 MONS_MAT3_IDENTITY = {
+ {1, 0, 0},
+ {0, 1, 0},
+ {0, 0, 1},
+};
+
+mons_mat3 mons_mat3_add(mons_mat3 a, mons_mat3 b) {
+ mons_mat3 result = {
+ mons_vec3_add(a.m1, b.m1),
+ mons_vec3_add(a.m2, b.m2),
+ mons_vec3_add(a.m3, b.m3),
+ };
+ return result;
+}
+
+void mons_mat3_add_inplace(mons_mat3 *a, mons_mat3 b) {
+ mons_vec3_add_inplace(&a->m1, b.m1);
+ mons_vec3_add_inplace(&a->m2, b.m2);
+ mons_vec3_add_inplace(&a->m3, b.m3);
+}
+
+mons_mat3 mons_mat3_mul_f(mons_mat3 a, float b) {
+ mons_mat3 result = {
+ mons_vec3_mul_f(a.m1, b),
+ mons_vec3_mul_f(a.m2, b),
+ mons_vec3_mul_f(a.m3, b),
+ };
+ return result;
+}
+
+mons_mat3 mons_mat3_mul_i(mons_mat3 a, int b) {
+ mons_mat3 result = {
+ mons_vec3_mul_i(a.m1, b),
+ mons_vec3_mul_i(a.m2, b),
+ mons_vec3_mul_i(a.m3, b),
+ };
+ return result;
+}
+
+mons_mat3 mons_mat3_mul(mons_mat3 a, mons_mat3 b) {
+ mons_vec3 b_n1 = mons_mat3_n1(b);
+ mons_vec3 b_n2 = mons_mat3_n2(b);
+ mons_vec3 b_n3 = mons_mat3_n3(b);
+
+ mons_mat3 result = {
+ {
+ mons_vec3_dot(a.m1, b_n1),
+ mons_vec3_dot(a.m1, b_n2),
+ mons_vec3_dot(a.m1, b_n3),
+ },
+ {
+ mons_vec3_dot(a.m2, b_n1),
+ mons_vec3_dot(a.m2, b_n2),
+ mons_vec3_dot(a.m2, b_n3),
+ },
+ {
+ mons_vec3_dot(a.m3, b_n1),
+ mons_vec3_dot(a.m3, b_n2),
+ mons_vec3_dot(a.m3, b_n3),
+ },
+ };
+ return result;
+}
+
+void mons_mat3_mul_f_inplace(mons_mat3 *a, float b) {
+ mons_vec3_mul_f_inplace(&a->m1, b);
+ mons_vec3_mul_f_inplace(&a->m2, b);
+ mons_vec3_mul_f_inplace(&a->m3, b);
+}
+
+void mons_mat3_mul_i_inplace(mons_mat3 *a, int b) {
+ mons_vec3_mul_i_inplace(&a->m1, b);
+ mons_vec3_mul_i_inplace(&a->m2, b);
+ mons_vec3_mul_i_inplace(&a->m3, b);
+}
+
+mons_mat3 mons_mat3_transpose(mons_mat3 a) {
+ mons_mat3 result = {
+ mons_mat3_n1(a),
+ mons_mat3_n2(a),
+ mons_mat3_n3(a),
+ };
+}
+
+void mons_mat3_transpose_inplace(mons_mat3 *a) { *a = mons_mat3_transpose(*a); }
+
+mons_vec3 mons_mat3_n1(mons_mat3 a) {
+ mons_vec3 result = {
+ a.m1.x,
+ a.m2.x,
+ a.m3.x,
+ };
+ return result;
+}
+
+mons_vec3 mons_mat3_n2(mons_mat3 a) {
+ mons_vec3 result = {
+ a.m1.y,
+ a.m2.y,
+ a.m3.y,
+ };
+ return result;
+}
+
+mons_vec3 mons_mat3_n3(mons_mat3 a) {
+ mons_vec3 result = {
+ a.m1.z,
+ a.m2.z,
+ a.m3.z,
+ };
+ return result;
+}
+
+float mons_mat3_determinant(mons_mat3 a) {
+ /*
+ * a * det(
+ * e f
+ * h i
+ * )
+ * - b * det(
+ * d f
+ * g i
+ * )
+ * + c * det(
+ * d e
+ * g h
+ * )
+ */
+ mons_mat2 efhi = {
+ {a.m2.y, a.m2.z},
+ {a.m3.y, a.m3.z},
+ };
+ mons_mat2 dfgi = {
+ {a.m2.x, a.m2.z},
+ {a.m3.x, a.m3.z},
+ };
+ mons_mat2 degh = {
+ {a.m2.x, a.m2.y},
+ {a.m3.x, a.m3.y},
+ };
+
+ return (a.m1.x * mons_mat2_determinant(efhi)) -
+ (a.m1.y * mons_mat2_determinant(dfgi)) +
+ (a.m1.z * mons_mat2_determinant(degh));
+}
+
+mons_mat3 mons_mat3_minor(mons_mat3 a) {
+ // Get determinants of minors
+ // First row elements
+ mons_mat2 minor_1_1 = {
+ {a.m2.y, a.m2.z},
+ {a.m3.y, a.m3.z},
+ };
+ float det_1_1 = mons_mat2_determinant(minor_1_1);
+ mons_mat2 minor_1_2 = {
+ {a.m2.x, a.m2.z},
+ {a.m3.x, a.m3.z},
+ };
+ float det_1_2 = mons_mat2_determinant(minor_1_2);
+ mons_mat2 minor_1_3 = {
+ {a.m2.x, a.m2.y},
+ {a.m3.x, a.m3.y},
+ };
+ float det_1_3 = mons_mat2_determinant(minor_1_3);
+ // Second row elements
+ mons_mat2 minor_2_1 = {
+ {a.m1.y, a.m1.z},
+ {a.m3.y, a.m3.z},
+ };
+ float det_2_1 = mons_mat2_determinant(minor_2_1);
+ mons_mat2 minor_2_2 = {
+ {a.m1.x, a.m1.z},
+ {a.m3.x, a.m3.z},
+ };
+ float det_2_2 = mons_mat2_determinant(minor_2_2);
+ mons_mat2 minor_2_3 = {
+ {a.m1.x, a.m1.y},
+ {a.m3.x, a.m3.y},
+ };
+ float det_2_3 = mons_mat2_determinant(minor_2_3);
+ // Third row elements
+ mons_mat2 minor_3_1 = {
+ {a.m1.y, a.m1.z},
+ {a.m2.y, a.m2.z},
+ };
+ float det_3_1 = mons_mat2_determinant(minor_3_1);
+ mons_mat2 minor_3_2 = {
+ {a.m1.x, a.m1.z},
+ {a.m2.x, a.m2.z},
+ };
+ float det_3_2 = mons_mat2_determinant(minor_3_2);
+ mons_mat2 minor_3_3 = {
+ {a.m1.x, a.m1.y},
+ {a.m2.x, a.m2.y},
+ };
+ float det_3_3 = mons_mat2_determinant(minor_3_3);
+
+ mons_mat3 result = {
+ {det_1_1, det_1_2, det_1_3},
+ {det_2_1, det_2_2, det_2_3},
+ {det_3_1, det_3_2, det_3_3},
+ };
+ return result;
+}
+
+mons_mat3 mons_mat3_cofactor(mons_mat3 a) {
+ mons_mat3 result = mons_mat3_minor(a);
+ result.m1.y *= -1;
+ result.m2.x *= -1;
+ result.m2.z *= -1;
+ result.m3.y *= -1;
+ return result;
+}
+
+mons_mat3 mons_mat3_adjoint(mons_mat3 a) {
+ return mons_mat3_transpose(mons_mat3_cofactor(a));
+}
+
+mons_mat3 mons_mat3_inverse(mons_mat3 a) {
+ return mons_mat3_mul_f(mons_mat3_adjoint(a),
+ 1.0 / mons_mat3_determinant(a));
+}
+
+int mons_mat3_equal(mons_mat3 a, mons_mat3 b) {
+ return mons_vec3_equal(a.m1, b.m1) && mons_vec3_equal(a.m2, b.m2) &&
+ mons_vec3_equal(a.m3, b.m3);
+}
diff --git a/mons_math/src/mat4.c b/mons_math/src/mat4.c
new file mode 100644
index 0000000..bb92ca8
--- /dev/null
+++ b/mons_math/src/mat4.c
@@ -0,0 +1,321 @@
+#include "mons_math/mat4.h"
+#include "mons_math/mat3.h"
+#include "mons_math/vec4.h"
+#include <stdio.h>
+
+mons_mat4 mons_mat4_add(mons_mat4 a, mons_mat4 b) {
+ mons_mat4 result = {
+ mons_vec4_add(a.m1, b.m1),
+ mons_vec4_add(a.m2, b.m2),
+ mons_vec4_add(a.m3, b.m3),
+ mons_vec4_add(a.m4, b.m4),
+ };
+ return result;
+}
+
+void mons_mat4_add_inplace(mons_mat4 *a, mons_mat4 b) {
+ mons_vec4_add_inplace(&a->m1, b.m1);
+ mons_vec4_add_inplace(&a->m2, b.m2);
+ mons_vec4_add_inplace(&a->m3, b.m3);
+ mons_vec4_add_inplace(&a->m4, b.m4);
+}
+
+mons_mat4 mons_mat4_mul_f(mons_mat4 a, float b) {
+ mons_mat4 result = {
+ mons_vec4_mul_f(a.m1, b),
+ mons_vec4_mul_f(a.m2, b),
+ mons_vec4_mul_f(a.m3, b),
+ mons_vec4_mul_f(a.m4, b),
+ };
+ return result;
+}
+
+mons_mat4 mons_mat4_mul_i(mons_mat4 a, int b) {
+ mons_mat4 result = {
+ mons_vec4_mul_i(a.m1, b),
+ mons_vec4_mul_i(a.m2, b),
+ mons_vec4_mul_i(a.m3, b),
+ mons_vec4_mul_i(a.m4, b),
+ };
+ return result;
+}
+
+void mons_mat4_mul_f_inplace(mons_mat4 *a, float b) {
+ mons_vec4_mul_f_inplace(&a->m1, b);
+ mons_vec4_mul_f_inplace(&a->m2, b);
+ mons_vec4_mul_f_inplace(&a->m3, b);
+ mons_vec4_mul_f_inplace(&a->m4, b);
+}
+
+void mons_mat4_mul_i_inplace(mons_mat4 *a, int b) {
+ mons_vec4_mul_i_inplace(&a->m1, b);
+ mons_vec4_mul_i_inplace(&a->m2, b);
+ mons_vec4_mul_i_inplace(&a->m3, b);
+ mons_vec4_mul_i_inplace(&a->m4, b);
+}
+
+mons_mat4 mons_mat4_mul(mons_mat4 a, mons_mat4 b) {
+ mons_vec4 b_n1 = mons_mat4_n1(b);
+ mons_vec4 b_n2 = mons_mat4_n2(b);
+ mons_vec4 b_n3 = mons_mat4_n3(b);
+ mons_vec4 b_n4 = mons_mat4_n4(b);
+
+ mons_mat4 result = {
+ {
+ mons_vec4_dot(a.m1, b_n1),
+ mons_vec4_dot(a.m1, b_n2),
+ mons_vec4_dot(a.m1, b_n3),
+ mons_vec4_dot(a.m1, b_n4),
+ },
+ {
+ mons_vec4_dot(a.m2, b_n1),
+ mons_vec4_dot(a.m2, b_n2),
+ mons_vec4_dot(a.m2, b_n3),
+ mons_vec4_dot(a.m2, b_n4),
+ },
+ {
+ mons_vec4_dot(a.m3, b_n1),
+ mons_vec4_dot(a.m3, b_n2),
+ mons_vec4_dot(a.m3, b_n3),
+ mons_vec4_dot(a.m3, b_n4),
+ },
+ {
+ mons_vec4_dot(a.m4, b_n1),
+ mons_vec4_dot(a.m4, b_n2),
+ mons_vec4_dot(a.m4, b_n3),
+ mons_vec4_dot(a.m4, b_n4),
+ },
+ };
+ return result;
+}
+
+mons_mat4 mons_mat4_transpose(mons_mat4 a) {
+ mons_mat4 result = {
+ mons_mat4_n1(a),
+ mons_mat4_n2(a),
+ mons_mat4_n3(a),
+ mons_mat4_n4(a),
+ };
+ return result;
+}
+
+void mons_mat4_transpose_inplace(mons_mat4 *a) { *a = mons_mat4_transpose(*a); }
+
+mons_vec4 mons_mat4_n1(mons_mat4 a) {
+ mons_vec4 result = {
+ a.m1.x,
+ a.m2.x,
+ a.m3.x,
+ a.m4.x,
+ };
+ return result;
+}
+
+mons_vec4 mons_mat4_n2(mons_mat4 a) {
+ mons_vec4 result = {
+ a.m1.y,
+ a.m2.y,
+ a.m3.y,
+ a.m4.y,
+ };
+ return result;
+}
+
+mons_vec4 mons_mat4_n3(mons_mat4 a) {
+ mons_vec4 result = {
+ a.m1.z,
+ a.m2.z,
+ a.m3.z,
+ a.m4.z,
+ };
+ return result;
+}
+
+mons_vec4 mons_mat4_n4(mons_mat4 a) {
+ mons_vec4 result = {
+ a.m1.w,
+ a.m2.w,
+ a.m3.w,
+ a.m4.w,
+ };
+ return result;
+}
+
+float mons_mat4_determinant(mons_mat4 a) {
+ mons_mat3 minor_1_1 = {
+ {a.m2.y, a.m2.z, a.m2.w},
+ {a.m3.y, a.m3.z, a.m3.w},
+ {a.m4.y, a.m4.z, a.m4.w},
+ };
+ mons_mat3 minor_1_2 = {
+ {a.m2.x, a.m2.z, a.m2.w},
+ {a.m3.x, a.m3.z, a.m3.w},
+ {a.m4.x, a.m4.z, a.m4.w},
+ };
+ mons_mat3 minor_1_3 = {
+ {a.m2.x, a.m2.y, a.m2.w},
+ {a.m3.x, a.m3.y, a.m3.w},
+ {a.m4.x, a.m4.y, a.m4.w},
+ };
+ mons_mat3 minor_1_4 = {
+ {a.m2.x, a.m2.y, a.m2.z},
+ {a.m3.x, a.m3.y, a.m3.z},
+ {a.m4.x, a.m4.y, a.m4.z},
+ };
+
+ return (a.m1.x * mons_mat3_determinant(minor_1_1)) -
+ (a.m1.y * mons_mat3_determinant(minor_1_2)) +
+ (a.m1.z * mons_mat3_determinant(minor_1_3)) -
+ (a.m1.w * mons_mat3_determinant(minor_1_4));
+}
+
+mons_mat4 mons_mat4_minor(mons_mat4 a) {
+ // First Row
+ mons_mat3 minor_1_1 = {
+ {a.m2.y, a.m2.z, a.m2.w},
+ {a.m3.y, a.m3.z, a.m3.w},
+ {a.m4.y, a.m4.z, a.m4.w},
+ };
+ float det_1_1 = mons_mat3_determinant(minor_1_1);
+ mons_mat3 minor_1_2 = {
+ {a.m2.x, a.m2.z, a.m2.w},
+ {a.m3.x, a.m3.z, a.m3.w},
+ {a.m4.x, a.m4.z, a.m4.w},
+ };
+ float det_1_2 = mons_mat3_determinant(minor_1_2);
+ mons_mat3 minor_1_3 = {
+ {a.m2.x, a.m2.y, a.m2.w},
+ {a.m3.x, a.m3.y, a.m3.w},
+ {a.m4.x, a.m4.y, a.m4.w},
+ };
+ float det_1_3 = mons_mat3_determinant(minor_1_3);
+ mons_mat3 minor_1_4 = {
+ {a.m2.x, a.m2.y, a.m2.z},
+ {a.m3.x, a.m3.y, a.m3.z},
+ {a.m4.x, a.m4.y, a.m4.z},
+ };
+ float det_1_4 = mons_mat3_determinant(minor_1_4);
+ // Second Row
+ mons_mat3 minor_2_1 = {
+ {a.m1.y, a.m1.z, a.m1.w},
+ {a.m3.y, a.m3.z, a.m3.w},
+ {a.m4.y, a.m4.z, a.m4.w},
+ };
+ float det_2_1 = mons_mat3_determinant(minor_2_1);
+ mons_mat3 minor_2_2 = {
+ {a.m1.x, a.m1.z, a.m1.w},
+ {a.m3.x, a.m3.z, a.m3.w},
+ {a.m4.x, a.m4.z, a.m4.w},
+ };
+ float det_2_2 = mons_mat3_determinant(minor_2_2);
+ mons_mat3 minor_2_3 = {
+ {a.m1.x, a.m1.y, a.m1.w},
+ {a.m3.x, a.m3.y, a.m3.w},
+ {a.m4.x, a.m4.y, a.m4.w},
+ };
+ float det_2_3 = mons_mat3_determinant(minor_2_3);
+ mons_mat3 minor_2_4 = {
+ {a.m1.x, a.m1.y, a.m1.z},
+ {a.m3.x, a.m3.y, a.m3.z},
+ {a.m4.x, a.m4.y, a.m4.z},
+ };
+ float det_2_4 = mons_mat3_determinant(minor_2_4);
+ // Third Row
+ mons_mat3 minor_3_1 = {
+ {a.m1.y, a.m1.z, a.m1.w},
+ {a.m2.y, a.m2.z, a.m2.w},
+ {a.m4.y, a.m4.z, a.m4.w},
+ };
+ float det_3_1 = mons_mat3_determinant(minor_3_1);
+ mons_mat3 minor_3_2 = {
+ {a.m1.x, a.m1.z, a.m1.w},
+ {a.m2.x, a.m2.z, a.m2.w},
+ {a.m4.x, a.m4.z, a.m4.w},
+ };
+ float det_3_2 = mons_mat3_determinant(minor_3_2);
+ mons_mat3 minor_3_3 = {
+ {a.m1.x, a.m1.y, a.m1.w},
+ {a.m2.x, a.m2.y, a.m2.w},
+ {a.m4.x, a.m4.y, a.m4.w},
+ };
+ float det_3_3 = mons_mat3_determinant(minor_3_3);
+ mons_mat3 minor_3_4 = {
+ {a.m1.x, a.m1.y, a.m1.z},
+ {a.m2.x, a.m2.y, a.m2.z},
+ {a.m4.x, a.m4.y, a.m4.z},
+ };
+ float det_3_4 = mons_mat3_determinant(minor_3_4);
+ // Fourth Row
+ mons_mat3 minor_4_1 = {
+ {a.m1.y, a.m1.z, a.m1.w},
+ {a.m2.y, a.m2.z, a.m2.w},
+ {a.m3.y, a.m3.z, a.m3.w},
+ };
+ float det_4_1 = mons_mat3_determinant(minor_4_1);
+ mons_mat3 minor_4_2 = {
+ {a.m1.x, a.m1.z, a.m1.w},
+ {a.m2.x, a.m2.z, a.m2.w},
+ {a.m3.x, a.m3.z, a.m3.w},
+ };
+ float det_4_2 = mons_mat3_determinant(minor_4_2);
+ mons_mat3 minor_4_3 = {
+ {a.m1.x, a.m1.y, a.m1.w},
+ {a.m2.x, a.m2.y, a.m2.w},
+ {a.m3.x, a.m3.y, a.m3.w},
+ };
+ float det_4_3 = mons_mat3_determinant(minor_4_3);
+ mons_mat3 minor_4_4 = {
+ {a.m1.x, a.m1.y, a.m1.z},
+ {a.m2.x, a.m2.y, a.m2.z},
+ {a.m3.x, a.m3.y, a.m3.z},
+ };
+ float det_4_4 = mons_mat3_determinant(minor_4_4);
+
+ mons_mat4 result = {
+ {det_1_1, det_1_2, det_1_3, det_1_4},
+ {det_2_1, det_2_2, det_2_3, det_2_4},
+ {det_3_1, det_3_2, det_3_3, det_3_4},
+ {det_4_1, det_4_2, det_4_3, det_4_4},
+ };
+ return result;
+}
+
+mons_mat4 mons_mat4_cofactor(mons_mat4 a) {
+ mons_mat4 result = mons_mat4_minor(a);
+ result.m1.y *= -1;
+ result.m1.w *= -1;
+ result.m2.x *= -1;
+ result.m2.z *= -1;
+ result.m3.y *= -1;
+ result.m3.w *= -1;
+ result.m4.x *= -1;
+ result.m4.z *= -1;
+ return result;
+}
+
+mons_mat4 mons_mat4_adjoint(mons_mat4 a) {
+ return mons_mat4_transpose(mons_mat4_cofactor(a));
+}
+
+mons_mat4 mons_mat4_inverse(mons_mat4 a) {
+ return mons_mat4_mul_f(mons_mat4_adjoint(a),
+ 1.0 / mons_mat4_determinant(a));
+}
+
+int mons_mat4_equal(mons_mat4 a, mons_mat4 b) {
+ return mons_vec4_equal(a.m1, b.m1)
+ && mons_vec4_equal(a.m2, b.m2)
+ && mons_vec4_equal(a.m3, b.m3)
+ && mons_vec4_equal(a.m4, b.m4);
+}
+
+void mons_mat4_mul_inplace(mons_mat4 *a, mons_mat4 b) {
+ *a = mons_mat4_mul(*a, b);
+}
+
+void mons_mat4_print(mons_mat4 mat) {
+ printf("[%.3f %.3f %.3f %.3f]\n", mat.m1.x, mat.m2.x, mat.m3.x, mat.m4.x);
+ printf("[%.3f %.3f %.3f %.3f]\n", mat.m1.y, mat.m2.y, mat.m3.y, mat.m4.y);
+ printf("[%.3f %.3f %.3f %.3f]\n", mat.m1.z, mat.m2.z, mat.m3.z, mat.m4.z);
+ printf("[%.3f %.3f %.3f %.3f]\n", mat.m1.w, mat.m2.w, mat.m3.w, mat.m4.w);
+}
diff --git a/mons_math/src/quat.c b/mons_math/src/quat.c
new file mode 100644
index 0000000..7c6a1cd
--- /dev/null
+++ b/mons_math/src/quat.c
@@ -0,0 +1,141 @@
+#include "mons_math/quat.h"
+#include "mons_math/mat4.h"
+#include "mons_math/vec3.h"
+#include "mons_math/vec4.h"
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+mons_quat mons_quat_from_axis_angle(mons_vec3 axis, float angle) {
+ float half_angle = 0.5f * angle;
+ float s = sinf(half_angle);
+ return (mons_quat){
+ axis.x * s,
+ axis.y * s,
+ axis.z * s,
+ cosf(half_angle),
+ };
+}
+
+mons_quat mons_quat_mul(mons_quat a, mons_quat b) {
+ return (mons_quat){
+ (a.w * b.x) + (a.x * b.w) + (a.y * b.z) - (a.z * b.y),
+ (a.w * b.y) + (a.y * b.w) + (a.z * b.x) - (a.x * b.z),
+ (a.w * b.z) + (a.z * b.w) + (a.x * b.y) - (a.y * b.x),
+ (a.w * b.w) - (a.x * b.x) - (a.y * b.y) - (a.z * b.z),
+ };
+}
+
+void mons_quat_mul_inplace(mons_quat *a, mons_quat b) {
+ *a = mons_quat_mul(*a, b);
+}
+
+mons_quat mons_quat_mul_f(mons_quat a, float b) {
+ return (mons_quat){
+ a.x * b,
+ a.y * b,
+ a.z * b,
+ a.w * b,
+ };
+}
+
+void mons_quat_mul_f_inplace(mons_quat *a, float b) {
+ a->x *= b;
+ a->y *= b;
+ a->z *= b;
+ a->w *= b;
+}
+
+mons_quat mons_quat_mul_i(mons_quat a, int b) {
+ return (mons_quat){
+ a.x * b,
+ a.y * b,
+ a.z * b,
+ a.w * b,
+ };
+}
+
+void mons_quat_mul_i_inplace(mons_quat *a, int b) {
+ a->x *= b;
+ a->y *= b;
+ a->z *= b;
+ a->w *= b;
+}
+
+mons_mat4 mons_quat_to_mat4(mons_quat a) {
+ return (mons_mat4){
+ {
+ 1.0 - (2.0 * a.y * a.y) - (2.0 * a.z * a.z),
+ (2.0 * a.x * a.y) - (2.0 * a.w * a.z),
+ (2.0 * a.x * a.z) + (2.0 * a.w * a.y),
+ 0.0,
+ },
+ {
+ (2.0 * a.x * a.y) + (2.0 * a.w * a.z),
+ 1.0 - (2.0 * a.x * a.x) - (2.0 * a.z * a.z),
+ (2.0 * a.y * a.z) - (2.0 * a.w * a.x),
+ 0.0,
+ },
+ {
+ (2.0 * a.x * a.z) - (2.0 * a.w * a.y),
+ (2.0 * a.y * a.z) + (2.0 * a.w * a.x),
+ 1.0 - (2.0 * a.x * a.x) - (2.0 * a.y * a.y),
+ 0.0,
+ },
+ {
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ },
+ };
+}
+
+mons_quat mons_quat_normalize(mons_quat a) {
+ mons_vec4 normalized = mons_vec4_normalize(*((mons_vec4 *)&a));
+ return *((mons_quat *)&normalized);
+}
+
+void mons_quat_normalize_inplace(mons_quat *a) {
+ mons_vec4_normalize_inplace((mons_vec4 *)a);
+}
+
+mons_vec3 mons_quat_transform_vec3(mons_quat quat, mons_vec3 vec) {
+ mons_vec3 quat_vec = (mons_vec3){quat.x, quat.y, quat.z};
+ float s = quat.w;
+
+ return mons_vec3_add(
+ mons_vec3_add(
+ mons_vec3_mul_f(quat_vec, mons_vec3_dot(quat_vec, vec) * 2.0f),
+ mons_vec3_mul_f(vec, s * s - mons_vec3_dot(quat_vec, quat_vec))),
+ mons_vec3_mul_f(mons_vec3_cross(quat_vec, vec), 2.0f * s));
+}
+
+mons_quat mons_quat_conjugate(mons_quat quat) {
+ return (mons_quat){
+ .x = -quat.x,
+ .y = -quat.y,
+ .z = -quat.z,
+ .w = quat.w,
+ };
+}
+
+mons_quat mons_quat_looking_at(mons_vec3 eye, mons_vec3 target, mons_vec3 up) {
+ mons_vec3 f = mons_vec3_normalize(mons_vec3_sub(target, eye));
+ mons_vec3 side = mons_vec3_normalize(mons_vec3_cross(up, f));
+ mons_vec3 b = mons_vec3_normalize(mons_vec3_add(f, MONS_VEC3_NEG_Z));
+ mons_quat p = mons_quat_from_axis_angle(mons_vec3_cross(b, f), mons_vec3_dot(b,f));
+ mons_vec3 r = (mons_vec3) {
+ p.w*p.w + p.x*p.x - p.y*p.y - p.z*p.z,
+ (2.0f * p.x * p.y) - (2.0f * p.w * p.z),
+ (2.0f * p.x * p.z) + (2.0f * p.w * p.y),
+ };
+ b = mons_vec3_normalize(mons_vec3_add(side, r));
+ mons_quat q = mons_quat_from_axis_angle(mons_vec3_cross(b,side), mons_vec3_dot(b, side));
+
+ return mons_quat_mul(p, q);
+}
+
+void mons_quat_print(mons_quat quat) {
+ mons_vec4_print(*(mons_vec4*)&quat);
+}
diff --git a/mons_math/src/util.c b/mons_math/src/util.c
new file mode 100644
index 0000000..f0f3ec0
--- /dev/null
+++ b/mons_math/src/util.c
@@ -0,0 +1,7 @@
+#include "mons_math/util.h"
+#include <math.h>
+
+int mons_float_approx_equal(float a, float b) {
+ return fabs(a - b) < MONS_FLOAT_EQUAL_EPSILON;
+}
+
diff --git a/mons_math/src/vec2.c b/mons_math/src/vec2.c
new file mode 100644
index 0000000..590397d
--- /dev/null
+++ b/mons_math/src/vec2.c
@@ -0,0 +1,120 @@
+#include "mons_math/vec2.h"
+#include "mons_math/util.h"
+#include "mons_math/vec3.h"
+#include <math.h>
+
+mons_vec2 mons_vec2_add(mons_vec2 a, mons_vec2 b) {
+ mons_vec2 result = {
+ a.x + b.x,
+ a.y + b.y,
+ };
+ return result;
+}
+
+void mons_vec2_add_inplace(mons_vec2 *a, mons_vec2 b) {
+ a->x += b.x;
+ a->y += b.y;
+}
+
+mons_vec2 mons_vec2_sub(mons_vec2 a, mons_vec2 b) {
+ mons_vec2 result = {
+ a.x - b.x,
+ a.y - b.y,
+ };
+ return result;
+}
+
+void mons_vec2_sub_inplace(mons_vec2 *a, mons_vec2 b) {
+ a->x -= b.x;
+ a->y -= b.y;
+}
+
+mons_vec2 mons_vec2_mul_f(mons_vec2 a, float b) {
+ mons_vec2 result = {
+ a.x * b,
+ a.y * b,
+ };
+ return result;
+}
+
+mons_vec2 mons_vec2_mul_i(mons_vec2 a, int b) {
+ mons_vec2 result = {
+ a.x * b,
+ a.y * b,
+ };
+ return result;
+}
+
+float mons_vec2_dot(mons_vec2 a, mons_vec2 b) {
+ return (a.x * b.x) + (a.y * b.y);
+}
+
+void mons_vec2_mul_f_inplace(mons_vec2 *a, float b) {
+ a->x *= b;
+ a->y *= b;
+}
+
+void mons_vec2_mul_i_inplace(mons_vec2 *a, int b) {
+ a->x *= b;
+ a->y *= b;
+}
+
+float mons_vec2_len(mons_vec2 a) { return sqrtf(mons_vec2_len_squared(a)); }
+
+float mons_vec2_len_squared(mons_vec2 a) { return (a.x * a.x) + (a.y * a.y); }
+
+mons_vec3 mons_vec2_extend(mons_vec2 a) {
+ mons_vec3 result = {
+ a.x,
+ a.y,
+ 0.0,
+ };
+ return result;
+}
+
+int mons_vec2_equal(mons_vec2 a, mons_vec2 b) {
+ return mons_float_approx_equal(a.x, b.x) &&
+ mons_float_approx_equal(a.y, b.y);
+}
+
+mons_vec2 mons_vec2_div_f(mons_vec2 a, float b) {
+ return (mons_vec2) {
+ a.x / b,
+ a.y / b,
+ };
+}
+
+mons_vec2 mons_vec2_div_i(mons_vec2 a, int b) {
+ return (mons_vec2) {
+ a.x / b,
+ a.y / b,
+ };
+}
+
+void mons_vec2_div_f_inplace(mons_vec2 *a, float b) {
+ a->x /= b;
+ a->y /= b;
+}
+
+void mons_vec2_div_i_inplace(mons_vec2 *a, int b) {
+ a->x /= b;
+ a->y /= b;
+}
+
+mons_vec2 mons_vec2_negate(mons_vec2 a) {
+ return mons_vec2_mul_i(a, -1);
+}
+
+void mons_vec2_negate_inplace(mons_vec2 *a) {
+ mons_vec2_mul_i_inplace(a, -1);
+}
+
+mons_vec2 mons_vec2_normalize(mons_vec2 a) {
+ float len = mons_vec2_len(a);
+ return mons_vec2_div_f(a, len);
+}
+
+void mons_vec2_normalize_inplace(mons_vec2 *a) {
+ float len = mons_vec2_len(*a);
+ mons_vec2_div_f_inplace(a, len);
+}
diff --git a/mons_math/src/vec3.c b/mons_math/src/vec3.c
new file mode 100644
index 0000000..725f5b3
--- /dev/null
+++ b/mons_math/src/vec3.c
@@ -0,0 +1,175 @@
+#include "mons_math/vec3.h"
+#include "mons_math/vec2.h"
+#include "mons_math/vec4.h"
+#include "mons_math/util.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+mons_vec3 mons_vec3_add(mons_vec3 a, mons_vec3 b) {
+ mons_vec3 result = {
+ a.x + b.x,
+ a.y + b.y,
+ a.z + b.z,
+ };
+ return result;
+}
+
+void mons_vec3_add_inplace(mons_vec3 *a, mons_vec3 b) {
+ a->x += b.x;
+ a->y += b.y;
+ a->z += b.z;
+}
+
+mons_vec3 mons_vec3_sub(mons_vec3 a, mons_vec3 b) {
+ mons_vec3 result = {
+ a.x - b.x,
+ a.y - b.y,
+ a.z - b.z,
+ };
+ return result;
+}
+
+void mons_vec3_sub_inplace(mons_vec3 *a, mons_vec3 b) {
+ a->x -= b.x;
+ a->y -= b.y;
+ a->z -= b.z;
+}
+
+mons_vec3 mons_vec3_mul_f(mons_vec3 a, float b) {
+ mons_vec3 result = {
+ a.x * b,
+ a.y * b,
+ a.z * b,
+ };
+ return result;
+}
+
+mons_vec3 mons_vec3_mul_i(mons_vec3 a, int b) {
+ mons_vec3 result = {
+ a.x * b,
+ a.y * b,
+ a.z * b,
+ };
+ return result;
+}
+
+float mons_vec3_dot(mons_vec3 a, mons_vec3 b) {
+ return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
+}
+
+void mons_vec3_mul_f_inplace(mons_vec3 *a, float b) {
+ a->x *= b;
+ a->y *= b;
+ a->z *= b;
+}
+
+void mons_vec3_mul_i_inplace(mons_vec3 *a, int b) {
+ a->x *= b;
+ a->y *= b;
+ a->z *= b;
+}
+
+float mons_vec3_len(mons_vec3 a) { return sqrtf(mons_vec3_len_squared(a)); }
+
+float mons_vec3_len_squared(mons_vec3 a) {
+ return (a.x * a.x) + (a.y * a.y) + (a.z * a.z);
+}
+
+mons_vec4 mons_vec3_extend(mons_vec3 a) {
+ mons_vec4 result = {
+ a.x,
+ a.y,
+ a.z,
+ 0.0,
+ };
+ return result;
+}
+
+mons_vec2 mons_vec3_truncate(mons_vec3 a) {
+ mons_vec2 result = {
+ a.x,
+ a.y,
+ };
+ return result;
+}
+
+int mons_vec3_equal(mons_vec3 a, mons_vec3 b) {
+ return mons_float_approx_equal(a.x, b.x)
+ && mons_float_approx_equal(a.y, b.y)
+ && mons_float_approx_equal(a.z, b.z);
+}
+
+mons_vec3 mons_vec3_div_f(mons_vec3 a, float b) {
+ return (mons_vec3) {
+ a.x / b,
+ a.y / b,
+ a.z / b,
+ };
+}
+
+void mons_vec3_div_f_inplace(mons_vec3 *a, float b) {
+ a->x /= b;
+ a->y /= b;
+ a->z /= b;
+}
+
+mons_vec3 mons_vec3_div_i(mons_vec3 a, int b) {
+ return (mons_vec3) {
+ a.x / b,
+ a.y / b,
+ a.z / b,
+ };
+}
+
+void mons_vec3_div_i_inplace(mons_vec3 *a, int b) {
+ a->x /= b;
+ a->y /= b;
+ a->z /= b;
+}
+
+mons_vec3 mons_vec3_negate(mons_vec3 a) {
+ return mons_vec3_mul_i(a, -1);
+}
+
+void mons_vec3_negate_inplace(mons_vec3 *a) {
+ return mons_vec3_mul_i_inplace(a, -1);
+}
+
+mons_vec3 mons_vec3_normalize(mons_vec3 a) {
+ float length = mons_vec3_len(a);
+ return mons_vec3_div_f(a, length);
+}
+
+void mons_vec3_normalize_inplace(mons_vec3 *a) {
+ float length = mons_vec3_len(*a);
+ mons_vec3_div_f_inplace(a, length);
+}
+
+mons_vec3 mons_vec3_cross(mons_vec3 a, mons_vec3 b) {
+ return (mons_vec3) {
+ (a.y * b.z) - (a.z * b.y),
+ (a.z * b.x) - (a.x * b.z),
+ (a.x * b.y) - (a.y * b.x),
+ };
+}
+
+mons_vec3 mons_vec3_mul_memberwise(mons_vec3 a, mons_vec3 b) {
+ return (mons_vec3) {
+ a.x * b.x,
+ a.y * b.y,
+ a.z * b.z,
+ };
+}
+
+void mons_vec3_mul_memberwise_inplace(mons_vec3 *a, mons_vec3 b) {
+ a->x *= b.x;
+ a->y *= b.y;
+ a->z *= b.z;
+}
+
+void mons_vec3_print(mons_vec3 vec) {
+ printf("[%f, %f, %f]", vec.x, vec.y, vec.z);
+}
+
diff --git a/mons_math/src/vec4.c b/mons_math/src/vec4.c
new file mode 100644
index 0000000..d4474ee
--- /dev/null
+++ b/mons_math/src/vec4.c
@@ -0,0 +1,149 @@
+#include "mons_math/vec4.h"
+#include "mons_math/vec3.h"
+#include "mons_math/util.h"
+#include <math.h>
+#include <stdio.h>
+
+mons_vec4 mons_vec4_add(mons_vec4 a, mons_vec4 b) {
+ mons_vec4 result = {
+ a.x + b.x,
+ a.y + b.y,
+ a.z + b.z,
+ a.w + b.w,
+ };
+ return result;
+}
+
+void mons_vec4_add_inplace(mons_vec4 *a, mons_vec4 b) {
+ a->x += b.x;
+ a->y += b.y;
+ a->z += b.z;
+ a->w += b.w;
+}
+
+mons_vec4 mons_vec4_sub(mons_vec4 a, mons_vec4 b) {
+ mons_vec4 result = {
+ a.x - b.x,
+ a.y - b.y,
+ a.z - b.z,
+ a.w - b.w,
+ };
+ return result;
+}
+
+void mons_vec4_sub_inplace(mons_vec4 *a, mons_vec4 b) {
+ a->x -= b.x;
+ a->y -= b.y;
+ a->z -= b.z;
+ a->w -= b.w;
+}
+
+mons_vec4 mons_vec4_mul_f(mons_vec4 a, float b) {
+ mons_vec4 result = {
+ a.x * b,
+ a.y * b,
+ a.z * b,
+ a.w * b,
+ };
+ return result;
+}
+
+mons_vec4 mons_vec4_mul_i(mons_vec4 a, int b) {
+ mons_vec4 result = {
+ a.x * b,
+ a.y * b,
+ a.z * b,
+ a.w * b,
+ };
+ return result;
+}
+
+void mons_vec4_mul_f_inplace(mons_vec4 *a, float b) {
+ a->x *= b;
+ a->y *= b;
+ a->z *= b;
+ a->w *= b;
+}
+
+void mons_vec4_mul_i_inplace(mons_vec4 *a, int b) {
+ a->x *= b;
+ a->y *= b;
+ a->z *= b;
+ a->w *= b;
+}
+
+mons_vec4 mons_vec4_div_f(mons_vec4 a, float b) {
+ return (mons_vec4) {
+ a.x / b,
+ a.y / b,
+ a.z / b,
+ a.w / b,
+ };
+}
+
+mons_vec4 mons_vec4_div_i(mons_vec4 a, int b) {
+ return (mons_vec4) {
+ a.x / b,
+ a.y / b,
+ a.z / b,
+ a.w / b,
+ };
+}
+
+void mons_vec4_div_f_inplace(mons_vec4 *a, float b) {
+ a->x /= b;
+ a->y /= b;
+ a->z /= b;
+ a->w /= b;
+}
+
+void mons_vec4_div_i_inplace(mons_vec4 *a, int b) {
+ a->x /= b;
+ a->y /= b;
+ a->z /= b;
+ a->w /= b;
+}
+
+float mons_vec4_dot(mons_vec4 a, mons_vec4 b) {
+ return (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w);
+}
+
+float mons_vec4_len(mons_vec4 a) { return sqrt(mons_vec4_len_squared(a)); }
+
+float mons_vec4_len_squared(mons_vec4 a) {
+ return (a.x * a.x) + (a.y * a.y) + (a.z * a.z) + (a.w * a.w);
+}
+
+mons_vec3 mons_vec4_truncate(mons_vec4 a) {
+ mons_vec3 result = {a.x, a.y, a.z};
+ return result;
+}
+
+int mons_vec4_equal(mons_vec4 a, mons_vec4 b) {
+ return mons_float_approx_equal(a.x, b.x)
+ && mons_float_approx_equal(a.y, b.y)
+ && mons_float_approx_equal(a.z, b.z)
+ && mons_float_approx_equal(a.w, b.w);
+}
+
+mons_vec4 mons_vec4_negate(mons_vec4 a) {
+ return mons_vec4_mul_i(a, -1);
+}
+
+void mons_vec4_negate_inplace(mons_vec4 *a) {
+ mons_vec4_mul_i_inplace(a, -1);
+}
+
+mons_vec4 mons_vec4_normalize(mons_vec4 a) {
+ float len = mons_vec4_len(a);
+ return mons_vec4_div_f(a, len);
+}
+
+void mons_vec4_normalize_inplace(mons_vec4 *a) {
+ float len = mons_vec4_len(*a);
+ mons_vec4_div_f_inplace(a, len);
+}
+
+void mons_vec4_print(mons_vec4 vec) {
+ printf("[%f, %f, %f, %f]", vec.x, vec.y, vec.z, vec.w);
+}
diff --git a/mons_math/tests/mat2_ops.c b/mons_math/tests/mat2_ops.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mons_math/tests/mat2_ops.c
diff --git a/mons_math/tests/mat3_ops.c b/mons_math/tests/mat3_ops.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mons_math/tests/mat3_ops.c
diff --git a/mons_math/tests/mat4_ops.c b/mons_math/tests/mat4_ops.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mons_math/tests/mat4_ops.c
diff --git a/mons_math/tests/test.h b/mons_math/tests/test.h
new file mode 100644
index 0000000..ce94b2e
--- /dev/null
+++ b/mons_math/tests/test.h
@@ -0,0 +1,14 @@
+#ifndef TEST_H
+#define TEST_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ASSERT(cond) {\
+ if (!(cond)) {\
+ fprintf(stderr, "Assertion Failed @ %s:%d (%s): %s", __func__, __LINE__, __FILE__, #cond);\
+ exit(EXIT_FAILURE);\
+ }\
+}
+
+#endif
diff --git a/mons_math/tests/vec2_ops.c b/mons_math/tests/vec2_ops.c
new file mode 100644
index 0000000..c7c6d7a
--- /dev/null
+++ b/mons_math/tests/vec2_ops.c
@@ -0,0 +1,81 @@
+#include "mons_math/vec2.h"
+#include "mons_math/vec3.h"
+#include "mons_math/util.h"
+#include "test.h"
+
+int main(void) {
+ mons_vec2 a = {2.0, 3.0};
+ mons_vec2 b = {6.0, 5.0};
+
+ // Add
+ mons_vec2 sum = mons_vec2_add(a, b);
+ ASSERT(mons_vec2_equal(sum, (mons_vec2){8.0, 8.0}));
+
+ // Add in Place
+ mons_vec2_add_inplace(&a, b);
+ ASSERT(mons_vec2_equal(a, sum));
+
+ // Subtract
+ mons_vec2 diff = mons_vec2_sub(sum, b);
+ ASSERT(mons_vec2_equal(diff, (mons_vec2){2.0, 3.0}));
+
+ // Subtract in Place
+ mons_vec2_sub_inplace(&a, b);
+ ASSERT(mons_vec2_equal(diff, a));
+
+ // Multiply (float)
+ mons_vec2 product_f = mons_vec2_mul_f(a, -3.0);
+ ASSERT(mons_vec2_equal(product_f, (mons_vec2){-6.0, -9.0}))
+
+ // Multiply in Place (float)
+ mons_vec2_mul_f_inplace(&a, 3.0);
+ ASSERT(mons_vec2_equal(mons_vec2_negate(product_f), a))
+
+ // Divide (float)
+ mons_vec2 quotient_f = mons_vec2_div_f(product_f, 3.0);
+ mons_vec2_negate_inplace(&quotient_f);
+ ASSERT(mons_vec2_equal(quotient_f, (mons_vec2){2.0, 3.0}));
+
+ // Divide in Place (float)
+ mons_vec2_div_f_inplace(&a, 3.0);
+ ASSERT(mons_vec2_equal(quotient_f, a));
+
+ // Multiply (int)
+ mons_vec2 product_i = mons_vec2_mul_i(a, -3);
+ ASSERT(mons_vec2_equal(product_i, (mons_vec2){-6.0, -9.0}))
+
+ // Multiply in Place (int)
+ mons_vec2_mul_i_inplace(&a, 3);
+ ASSERT(mons_vec2_equal(mons_vec2_negate(product_i), a))
+
+ // Divide (int)
+ mons_vec2 quotient_i = mons_vec2_div_i(product_i, 3);
+ mons_vec2_negate_inplace(&quotient_i);
+ ASSERT(mons_vec2_equal(quotient_i, (mons_vec2){2.0, 3.0}));
+
+ // Divide in Place (int)
+ mons_vec2_div_i_inplace(&a, 3);
+ ASSERT(mons_vec2_equal(quotient_i, a));
+
+ // Get Length
+ float a_len = mons_vec2_len(a);
+ ASSERT(mons_float_approx_equal(a_len, 3.60555));
+
+ // Dot Product
+ float dot = mons_vec2_dot(a, b);
+ ASSERT(mons_float_approx_equal(dot, 27.0));
+
+ // Extend
+ mons_vec3 extended = mons_vec2_extend(a);
+ ASSERT(mons_vec3_equal(extended, (mons_vec3){a.x, a.y, 0.0}));
+
+ // Normalize
+ mons_vec2 normalized = mons_vec2_normalize(a);
+ ASSERT(mons_float_approx_equal(mons_vec2_len(normalized), 1.0));
+
+ // Normalize in Place
+ mons_vec2_normalize_inplace(&a);
+ ASSERT(mons_float_approx_equal(mons_vec2_len(a), 1.0));
+
+ return EXIT_SUCCESS;
+}
diff --git a/mons_math/tests/vec3_ops.c b/mons_math/tests/vec3_ops.c
new file mode 100644
index 0000000..e29b396
--- /dev/null
+++ b/mons_math/tests/vec3_ops.c
@@ -0,0 +1,90 @@
+#include "mons_math/vec2.h"
+#include "mons_math/vec3.h"
+#include "mons_math/vec4.h"
+#include "mons_math/util.h"
+#include "test.h"
+
+int main(void) {
+ mons_vec3 a = {2.0, 3.0, 4.0};
+ mons_vec3 b = {6.0, 5.0, 4.0};
+
+ // Add
+ mons_vec3 sum = mons_vec3_add(a, b);
+ ASSERT(mons_vec3_equal(sum, (mons_vec3){8.0, 8.0, 8.0}));
+
+ // Add in Place
+ mons_vec3_add_inplace(&a, b);
+ ASSERT(mons_vec3_equal(a, sum));
+
+ // Subtract
+ mons_vec3 diff = mons_vec3_sub(sum, b);
+ ASSERT(mons_vec3_equal(diff, (mons_vec3){2.0, 3.0, 4.0}));
+
+ // Subtract in Place
+ mons_vec3_sub_inplace(&a, b);
+ ASSERT(mons_vec3_equal(diff, a));
+
+ // Multiply (float)
+ mons_vec3 product_f = mons_vec3_mul_f(a, -3.0);
+ ASSERT(mons_vec3_equal(product_f, (mons_vec3){-6.0, -9.0, -12.0}))
+
+ // Multiply in Place (float)
+ mons_vec3_mul_f_inplace(&a, 3.0);
+ ASSERT(mons_vec3_equal(mons_vec3_negate(product_f), a))
+
+ // Divide (float)
+ mons_vec3 quotient_f = mons_vec3_div_f(product_f, 3.0);
+ mons_vec3_negate_inplace(&quotient_f);
+ ASSERT(mons_vec3_equal(quotient_f, (mons_vec3){2.0, 3.0, 4.0}));
+
+ // Divide in Place (float)
+ mons_vec3_div_f_inplace(&a, 3.0);
+ ASSERT(mons_vec3_equal(quotient_f, a));
+
+ // Multiply (int)
+ mons_vec3 product_i = mons_vec3_mul_i(a, -3);
+ ASSERT(mons_vec3_equal(product_i, (mons_vec3){-6.0, -9.0, -12.0}))
+
+ // Multiply in Place (int)
+ mons_vec3_mul_i_inplace(&a, 3);
+ ASSERT(mons_vec3_equal(mons_vec3_negate(product_i), a))
+
+ // Divide (int)
+ mons_vec3 quotient_i = mons_vec3_div_i(product_i, 3);
+ mons_vec3_negate_inplace(&quotient_i);
+ ASSERT(mons_vec3_equal(quotient_i, (mons_vec3){2.0, 3.0, 4.0}));
+
+ // Divide in Place (int)
+ mons_vec3_div_i_inplace(&a, 3);
+ ASSERT(mons_vec3_equal(quotient_i, a));
+
+ // Get Length
+ float a_len = mons_vec3_len(a);
+ ASSERT(mons_float_approx_equal(a_len, 5.38516));
+
+ // Dot Product
+ float dot = mons_vec3_dot(a, b);
+ ASSERT(mons_float_approx_equal(dot, 43.0));
+
+ // Cross Product
+ mons_vec3 cross = mons_vec3_cross(a, b);
+ ASSERT(mons_vec3_equal(cross, (mons_vec3){-8.0, 16.0, -8.0}));
+
+ // Extend
+ mons_vec4 extended = mons_vec3_extend(a);
+ ASSERT(mons_vec4_equal(extended, (mons_vec4){a.x, a.y, a.z, 0.0}));
+
+ // Truncate
+ mons_vec2 truncated = mons_vec3_truncate(a);
+ ASSERT(mons_vec2_equal(truncated, (mons_vec2){a.x, a.y}));
+
+ // Normalize
+ mons_vec3 normalized = mons_vec3_normalize(a);
+ ASSERT(mons_float_approx_equal(mons_vec3_len(normalized), 1.0));
+
+ // Normalize in Place
+ mons_vec3_normalize_inplace(&a);
+ ASSERT(mons_float_approx_equal(mons_vec3_len(a), 1.0));
+
+ return EXIT_SUCCESS;
+}
diff --git a/mons_math/tests/vec4_ops.c b/mons_math/tests/vec4_ops.c
new file mode 100644
index 0000000..e7837c4
--- /dev/null
+++ b/mons_math/tests/vec4_ops.c
@@ -0,0 +1,81 @@
+#include "mons_math/vec3.h"
+#include "mons_math/vec4.h"
+#include "mons_math/util.h"
+#include "test.h"
+
+int main(void) {
+ mons_vec4 a = {2.0, 3.0, 4.0, 5.0};
+ mons_vec4 b = {6.0, 5.0, 4.0, 3.0};
+
+ // Add
+ mons_vec4 sum = mons_vec4_add(a, b);
+ ASSERT(mons_vec4_equal(sum, (mons_vec4){8.0, 8.0, 8.0, 8.0}));
+
+ // Add in Place
+ mons_vec4_add_inplace(&a, b);
+ ASSERT(mons_vec4_equal(a, sum));
+
+ // Subtract
+ mons_vec4 diff = mons_vec4_sub(sum, b);
+ ASSERT(mons_vec4_equal(diff, (mons_vec4){2.0, 3.0, 4.0, 5.0}));
+
+ // Subtract in Place
+ mons_vec4_sub_inplace(&a, b);
+ ASSERT(mons_vec4_equal(diff, a));
+
+ // Multiply (float)
+ mons_vec4 product_f = mons_vec4_mul_f(a, -3.0);
+ ASSERT(mons_vec4_equal(product_f, (mons_vec4){-6.0, -9.0, -12.0, -15.0}))
+
+ // Multiply in Place (float)
+ mons_vec4_mul_f_inplace(&a, 3.0);
+ ASSERT(mons_vec4_equal(mons_vec4_negate(product_f), a))
+
+ // Divide (float)
+ mons_vec4 quotient_f = mons_vec4_div_f(product_f, 3.0);
+ mons_vec4_negate_inplace(&quotient_f);
+ ASSERT(mons_vec4_equal(quotient_f, (mons_vec4){2.0, 3.0, 4.0, 5.0}));
+
+ // Divide in Place (float)
+ mons_vec4_div_f_inplace(&a, 3.0);
+ ASSERT(mons_vec4_equal(quotient_f, a));
+
+ // Multiply (int)
+ mons_vec4 product_i = mons_vec4_mul_i(a, -3);
+ ASSERT(mons_vec4_equal(product_i, (mons_vec4){-6.0, -9.0, -12.0, -15.0}))
+
+ // Multiply in Place (int)
+ mons_vec4_mul_i_inplace(&a, 3);
+ ASSERT(mons_vec4_equal(mons_vec4_negate(product_i), a))
+
+ // Divide (int)
+ mons_vec4 quotient_i = mons_vec4_div_i(product_i, 3);
+ mons_vec4_negate_inplace(&quotient_i);
+ ASSERT(mons_vec4_equal(quotient_i, (mons_vec4){2.0, 3.0, 4.0, 5.0}));
+
+ // Divide in Place (int)
+ mons_vec4_div_i_inplace(&a, 3);
+ ASSERT(mons_vec4_equal(quotient_i, a));
+
+ // Get Length
+ float a_len = mons_vec4_len(a);
+ ASSERT(mons_float_approx_equal(a_len, 7.34846));
+
+ // Dot Product
+ float dot = mons_vec4_dot(a, b);
+ ASSERT(mons_float_approx_equal(dot, 58.0));
+
+ // Truncate
+ mons_vec3 truncated = mons_vec4_truncate(a);
+ ASSERT(mons_vec3_equal(truncated, (mons_vec3){a.x, a.y, a.z}));
+
+ // Normalize
+ mons_vec4 normalized = mons_vec4_normalize(a);
+ ASSERT(mons_float_approx_equal(mons_vec4_len(normalized), 1.0));
+
+ // Normalize in Place
+ mons_vec4_normalize_inplace(&a);
+ ASSERT(mons_float_approx_equal(mons_vec4_len(a), 1.0));
+
+ return EXIT_SUCCESS;
+}