Merge pull request #49 from bjornbytes/shader-block

ShaderBlock
This commit is contained in:
Bjorn Swenson 2018-08-07 15:17:06 -07:00 committed by GitHub
commit 06379f33ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 1390 additions and 653 deletions

View File

@ -261,6 +261,7 @@ set(LOVR_SRC
src/api/types/randomGenerator.c
src/api/types/rasterizer.c
src/api/types/shader.c
src/api/types/shaderBlock.c
src/api/types/shapes.c
src/api/types/soundData.c
src/api/types/source.c

View File

@ -56,6 +56,7 @@ extern const luaL_Reg lovrModelData[];
extern const luaL_Reg lovrRandomGenerator[];
extern const luaL_Reg lovrRasterizer[];
extern const luaL_Reg lovrShader[];
extern const luaL_Reg lovrShaderBlock[];
extern const luaL_Reg lovrShape[];
extern const luaL_Reg lovrSliderJoint[];
extern const luaL_Reg lovrSoundData[];
@ -73,6 +74,7 @@ extern const char* ArcModes[];
extern const char* AttributeTypes[];
extern const char* BlendAlphaModes[];
extern const char* BlendModes[];
extern const char* BufferUsages[];
extern const char* CompareModes[];
extern const char* ControllerAxes[];
extern const char* ControllerButtons[];
@ -90,7 +92,6 @@ extern const char* MaterialColors[];
extern const char* MaterialScalars[];
extern const char* MaterialTextures[];
extern const char* MeshDrawModes[];
extern const char* MeshUsages[];
extern const char* ShapeTypes[];
extern const char* SourceTypes[];
extern const char* StencilActions[];
@ -114,3 +115,5 @@ Blob* luax_readblob(lua_State* L, int index, const char* debug);
Seed luax_checkrandomseed(lua_State* L, int index);
void luax_checkvariant(lua_State* L, int index, Variant* variant);
int luax_pushvariant(lua_State* L, Variant* variant);
int luax_checkuniform(lua_State* L, int index, const Uniform* uniform, void* dest, const char* debug);
void luax_checkuniformtype(lua_State* L, int index, UniformType* baseType, int* components);

View File

@ -45,6 +45,13 @@ const char* BlendModes[] = {
NULL
};
const char* BufferUsages[] = {
[USAGE_STATIC] = "static",
[USAGE_DYNAMIC] = "dynamic",
[USAGE_STREAM] = "stream",
NULL
};
const char* CompareModes[] = {
[COMPARE_NONE] = "always",
[COMPARE_EQUAL] = "equal",
@ -111,13 +118,6 @@ const char* MeshDrawModes[] = {
NULL
};
const char* MeshUsages[] = {
[MESH_STATIC] = "static",
[MESH_DYNAMIC] = "dynamic",
[MESH_STREAM] = "stream",
NULL
};
const char* StencilActions[] = {
[STENCIL_REPLACE] = "replace",
[STENCIL_INCREMENT] = "increment",
@ -241,6 +241,7 @@ int l_lovrGraphicsInit(lua_State* L) {
luax_registertype(L, "Mesh", lovrMesh);
luax_registertype(L, "Model", lovrModel);
luax_registertype(L, "Shader", lovrShader);
luax_registertype(L, "ShaderBlock", lovrShaderBlock);
luax_registertype(L, "Texture", lovrTexture);
luax_extendtype(L, "Texture", "Canvas", lovrTexture, lovrCanvas);
lovrGraphicsInit();
@ -326,6 +327,14 @@ int l_lovrGraphicsGetDimensions(lua_State* L) {
return 2;
}
int l_lovrGraphicsGetSupported(lua_State* L) {
GraphicsFeatures features = lovrGraphicsGetSupported();
lua_newtable(L);
lua_pushboolean(L, features.writableBlocks);
lua_setfield(L, -2, "writableBlocks");
return 1;
}
int l_lovrGraphicsGetSystemLimits(lua_State* L) {
GraphicsLimits limits = lovrGraphicsGetLimits();
lua_newtable(L);
@ -852,6 +861,59 @@ int l_lovrGraphicsNewAnimator(lua_State* L) {
return 1;
}
int l_lovrGraphicsNewShaderBlock(lua_State* L) {
vec_uniform_t uniforms;
vec_init(&uniforms);
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushnil(L);
while (lua_next(L, 1) != 0) {
Uniform uniform;
// Name
strncpy(uniform.name, luaL_checkstring(L, -2), LOVR_MAX_UNIFORM_LENGTH - 1);
if (lua_type(L, -1) == LUA_TSTRING) {
uniform.count = 1;
luax_checkuniformtype(L, -1, &uniform.type, &uniform.components);
} else {
luaL_checktype(L, -1, LUA_TTABLE);
lua_rawgeti(L, -1, 1);
luax_checkuniformtype(L, -1, &uniform.type, &uniform.components);
lua_pop(L, 1);
lua_rawgeti(L, -1, 2);
uniform.count = luaL_optinteger(L, -1, 1);
lua_pop(L, 1);
}
lovrAssert(uniform.count >= 1, "Uniform count must be positive, got %d for '%s'", uniform.count, uniform.name);
vec_push(&uniforms, uniform);
// Pop the table, leaving the key for lua_next to nom
lua_pop(L, 1);
}
BlockType type = BLOCK_UNIFORM;
BufferUsage usage = USAGE_DYNAMIC;
if (lua_istable(L, 2)) {
lua_getfield(L, 2, "usage");
usage = luaL_checkoption(L, -1, "dynamic", BufferUsages);
lua_pop(L, 1);
lua_getfield(L, 2, "writable");
type = lua_toboolean(L, -1) ? BLOCK_STORAGE : BLOCK_UNIFORM;
lua_pop(L, 1);
}
ShaderBlock* block = lovrShaderBlockCreate(&uniforms, type, usage);
luax_pushobject(L, block);
vec_deinit(&uniforms);
return 1;
}
int l_lovrGraphicsNewCanvas(lua_State* L) {
int width = luaL_checkinteger(L, 1);
int height = luaL_checkinteger(L, 2);
@ -986,7 +1048,7 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
}
MeshDrawMode drawMode = luaL_checkoption(L, drawModeIndex, "fan", MeshDrawModes);
MeshUsage usage = luaL_checkoption(L, drawModeIndex + 1, "dynamic", MeshUsages);
BufferUsage usage = luaL_checkoption(L, drawModeIndex + 1, "dynamic", BufferUsages);
Mesh* mesh = lovrMeshCreate(count, format, drawMode, usage);
if (dataIndex) {
@ -1126,6 +1188,7 @@ const luaL_Reg lovrGraphics[] = {
{ "getWidth", l_lovrGraphicsGetWidth },
{ "getHeight", l_lovrGraphicsGetHeight },
{ "getDimensions", l_lovrGraphicsGetDimensions },
{ "getSupported", l_lovrGraphicsGetSupported },
{ "getSystemLimits", l_lovrGraphicsGetSystemLimits },
{ "getStats", l_lovrGraphicsGetStats },
@ -1195,6 +1258,7 @@ const luaL_Reg lovrGraphics[] = {
{ "newMesh", l_lovrGraphicsNewMesh },
{ "newModel", l_lovrGraphicsNewModel },
{ "newShader", l_lovrGraphicsNewShader },
{ "newShaderBlock", l_lovrGraphicsNewShaderBlock },
{ "newTexture", l_lovrGraphicsNewTexture },
{ NULL, NULL }

View File

@ -4,11 +4,166 @@
struct TempData {
void* data;
size_t size;
int size;
};
static struct TempData tempData;
int luax_checkuniform(lua_State* L, int index, const Uniform* uniform, void* dest, const char* debug) {
Blob* blob = luax_totype(L, index, Blob);
int components = uniform->components;
int count = uniform->count;
if (uniform->type == UNIFORM_MATRIX) {
components *= components;
}
if (blob) {
size_t elements = count * components;
const char* s = elements == 1 ? "" : "s";
size_t capacity;
switch (uniform->type) {
case UNIFORM_FLOAT:
case UNIFORM_MATRIX:
capacity = blob->size / sizeof(float);
lovrAssert(capacity >= elements, "Blob can only hold %d float%s, at least %d needed for uniform '%s'", capacity, s, elements, debug);
memcpy(dest, blob->data, elements * sizeof(float));
break;
case UNIFORM_INT:
capacity = blob->size / sizeof(int);
lovrAssert(capacity >= elements, "Blob can only hold %d int%s, at least %d needed for uniform '%s'", capacity, s, elements, debug);
memcpy(dest, blob->data, elements * sizeof(int));
break;
case UNIFORM_SAMPLER:
lovrThrow("Texture uniform '%s' can not be updated with a Blob", debug);
}
return 0;
}
if (components == 1) {
bool isTable = lua_istable(L, index);
if (isTable) {
int length = lua_objlen(L, index);
length = MIN(length, count);
for (int i = 0; i < length; i++) {
lua_rawgeti(L, index, i + 1);
switch (uniform->type) {
case UNIFORM_FLOAT: *((float*) dest + i) = luaL_checknumber(L, -1); break;
case UNIFORM_INT: *((int*) dest + i) = luaL_checkinteger(L, -1); break;
case UNIFORM_SAMPLER: *((Texture**) dest + i) = luax_checktype(L, -1, Texture); break;
default: break;
}
lua_pop(L, 1);
}
} else {
for (int i = 0; i < count; i++) {
switch (uniform->type) {
case UNIFORM_FLOAT: *((float*) dest + i) = luaL_checknumber(L, index + i); break;
case UNIFORM_INT: *((int*) dest + i) = luaL_checkinteger(L, index + i); break;
case UNIFORM_SAMPLER: *((Texture**) dest + i) = luax_checktype(L, index + i, Texture); break;
default: break;
}
}
}
} else {
luaL_checktype(L, index, LUA_TTABLE);
lua_rawgeti(L, index, 1);
bool wrappedTable = lua_istable(L, -1) || luax_totype(L, -1, Transform);
lua_pop(L, 1);
if (wrappedTable) {
int length = lua_objlen(L, index);
length = MIN(length, count);
for (int i = 0; i < length; i++) {
lua_rawgeti(L, index, i + 1);
if (uniform->type == UNIFORM_MATRIX && lua_isuserdata(L, -1)) {
Transform* transform = luax_checktype(L, -1, Transform);
memcpy((float*) dest + i * components, transform->matrix, 16 * sizeof(float));
continue;
}
for (int j = 0; j < components; j++) {
lua_rawgeti(L, -1, j + 1);
switch (uniform->type) {
case UNIFORM_FLOAT:
case UNIFORM_MATRIX:
*((float*) dest + i * components + j) = luaL_checknumber(L, -1);
case UNIFORM_INT:
*((int*) dest + i * components + j) = luaL_checkinteger(L, -1);
break;
case UNIFORM_SAMPLER: lovrThrow("Unreachable");
}
lua_pop(L, 1);
}
lua_pop(L, 1);
}
} else {
for (int i = 0; i < count; i++) {
if (uniform->type == UNIFORM_MATRIX && lua_isuserdata(L, index + i)) {
Transform* transform = luax_checktype(L, index + i, Transform);
memcpy((float*) dest + i * components, transform->matrix, 16 * sizeof(float));
continue;
}
luaL_checktype(L, index + i, LUA_TTABLE);
for (int j = 0; j < components; j++) {
lua_rawgeti(L, index + i, j + 1);
switch (uniform->type) {
case UNIFORM_FLOAT:
case UNIFORM_MATRIX:
*((float*) dest + i * components + j) = luaL_checknumber(L, -1);
break;
case UNIFORM_INT:
*((float*) dest + i * components + j) = luaL_checknumber(L, -1);
break;
case UNIFORM_SAMPLER: lovrThrow("Unreachable");
}
}
}
}
}
return 0;
}
void luax_checkuniformtype(lua_State* L, int index, UniformType* baseType, int* components) {
size_t length;
lovrAssert(lua_type(L, index) == LUA_TSTRING, "Uniform types must be strings, got %s", lua_typename(L, index));
const char* type = lua_tolstring(L, index, &length);
if (!strcmp(type, "float")) {
*baseType = UNIFORM_FLOAT;
*components = 1;
} else if (!strcmp(type, "int")) {
*baseType = UNIFORM_INT;
*components = 1;
} else {
int n = type[length - 1] - '0';
lovrAssert(n >= 2 && n <= 4, "Unknown uniform type '%s'", type);
if (type[0] == 'v' && type[1] == 'e' && type[2] == 'c' && length == 4) {
*baseType = UNIFORM_FLOAT;
*components = n;
} else if (type[0] == 'i' && type[1] == 'v' && type[2] == 'e' && type[3] == 'c' && length == 5) {
*baseType = UNIFORM_INT;
*components = n;
} else if (type[0] == 'm' && type[1] == 'a' && type[2] == 't' && length == 4) {
*baseType = UNIFORM_MATRIX;
*components = n;
} else {
lovrThrow("Unknown uniform type '%s'", type);
}
}
}
int l_lovrShaderHasUniform(lua_State* L) {
Shader* shader = luax_checktype(L, 1, Shader);
const char* name = luaL_checkstring(L, 2);
@ -19,151 +174,44 @@ int l_lovrShaderHasUniform(lua_State* L) {
int l_lovrShaderSend(lua_State* L) {
Shader* shader = luax_checktype(L, 1, Shader);
const char* name = luaL_checkstring(L, 2);
lua_settop(L, 3);
const Uniform* uniform = lovrShaderGetUniform(shader, name);
lovrAssert(uniform, "Unknown shader variable '%s'", name);
int count;
int components;
size_t size;
UniformType type;
bool present = lovrShaderGetUniform(shader, name, &count, &components, &size, &type);
if (!present) {
return luaL_error(L, "Unknown shader variable '%s'", name);
}
if (tempData.size < size) {
tempData.size = size;
if (tempData.size < uniform->size) {
tempData.size = uniform->size;
tempData.data = realloc(tempData.data, tempData.size);
}
int* ints = (int*) tempData.data;
float* floats = (float*) tempData.data;
Texture** textures = (Texture**) tempData.data;
int n = 1;
if (components > 1 && lua_istable(L, 3)) {
lua_rawgeti(L, 3, 1);
if (!lua_istable(L, -1)) {
lua_newtable(L);
lua_pushvalue(L, 3);
lua_rawseti(L, -2, 1);
} else {
lua_pop(L, 1);
}
n = lua_objlen(L, -1);
if (n != count) {
return luaL_error(L, "Expected %d element%s for array '%s', got %d", count, count == 1 ? "" : "s", name, n);
}
luax_checkuniform(L, 3, uniform, tempData.data, name);
switch (uniform->type) {
case UNIFORM_FLOAT: lovrShaderSetFloat(shader, uniform->name, tempData.data, uniform->count * uniform->components); break;
case UNIFORM_INT: lovrShaderSetInt(shader, uniform->name, tempData.data, uniform->count * uniform->components); break;
case UNIFORM_MATRIX: lovrShaderSetMatrix(shader, uniform->name, tempData.data, uniform->count * uniform->components * uniform->components); break;
case UNIFORM_SAMPLER: lovrShaderSetTexture(shader, uniform->name, tempData.data, uniform->count); break;
}
return 0;
}
Blob* blob = luax_totype(L, 3, Blob);
switch (type) {
case UNIFORM_FLOAT:
if (blob) {
n = count;
floats = (float*) blob->data;
size_t count = n * components;
size_t capacity = blob->size / sizeof(float);
const char* s = capacity == 1 ? "" : "s";
lovrAssert(capacity >= count, "Blob can only hold %d float%s, at least %d needed", capacity, s, count);
} else if (components == 1) {
floats[0] = luaL_checknumber(L, 3);
} else {
luaL_checktype(L, 3, LUA_TTABLE);
for (int i = 0; i < n; i++) {
lua_rawgeti(L, -1, i + 1);
if (lua_type(L, -1) != LUA_TTABLE || (int) lua_objlen(L, -1) != components) {
return luaL_error(L, "Expected %d components for uniform '%s' #%d, got %d", components, name, lua_objlen(L, -1));
}
for (int j = 0; j < components; j++) {
lua_rawgeti(L, -1, j + 1);
floats[i * components + j] = luaL_checknumber(L, -1);
lua_pop(L, 1);
}
lua_pop(L, 1);
}
}
lovrShaderSetFloat(shader, name, floats, n * components);
break;
case UNIFORM_INT:
if (blob) {
n = count;
ints = (int*) blob->data;
size_t count = n * components;
size_t capacity = blob->size / sizeof(int);
const char* s = capacity == 1 ? "" : "s";
lovrAssert(capacity >= count, "Blob can only hold %d int%s, at least %d needed", capacity, s, count);
} else if (components == 1) {
ints[0] = luaL_checkinteger(L, 3);
} else {
luaL_checktype(L, 3, LUA_TTABLE);
for (int i = 0; i < n; i++) {
lua_rawgeti(L, -1, i + 1);
if (lua_type(L, -1) != LUA_TTABLE || (int) lua_objlen(L, -1) != components) {
return luaL_error(L, "Expected %d components for uniform '%s' #%d, got %d", components, name, lua_objlen(L, -1));
}
for (int j = 0; j < components; j++) {
lua_rawgeti(L, -1, j + 1);
ints[i * components + j] = luaL_checkinteger(L, -1);
lua_pop(L, 1);
}
lua_pop(L, 1);
}
}
lovrShaderSetInt(shader, name, ints, n * components);
break;
case UNIFORM_MATRIX:
if (blob) {
n = count;
floats = (float*) blob->data;
size_t count = n * components * components;
size_t capacity = blob->size / sizeof(float);
const char* s = capacity == 1 ? "x" : "ces";
lovrAssert(capacity >= count, "Blob can only hold %d matri%s, at least %d needed", capacity, s, count);
} else if (components == 4 && lua_isuserdata(L, 3)) {
Transform* transform = luax_checktype(L, 3, Transform);
memcpy(floats, transform->matrix, 16 * sizeof(float));
} else {
luaL_checktype(L, 3, LUA_TTABLE);
for (int i = 0; i < n; i++) {
lua_rawgeti(L, -1, i + 1);
for (int j = 0; j < components * components; j++) {
lua_rawgeti(L, -1, j + 1);
floats[i * components * components + j] = luaL_checknumber(L, -1);
lua_pop(L, 1);
}
lua_pop(L, 1);
}
}
lovrShaderSetMatrix(shader, name, floats, n * components * components);
break;
case UNIFORM_SAMPLER:
if (components == 1) {
textures[0] = luax_checktype(L, 3, Texture);
} else {
luaL_checktype(L, 3, LUA_TTABLE);
for (int i = 0; i < n; i++) {
lua_rawgeti(L, -1, i + 1);
textures[i] = luax_checktype(L, -1, Texture);
lua_pop(L, 1);
}
}
lovrShaderSetTexture(shader, name, textures, n);
break;
default: break;
}
int l_lovrShaderGetBlock(lua_State* L) {
Shader* shader = luax_checktype(L, 1, Shader);
const char* name = luaL_checkstring(L, 2);
ShaderBlock* block = lovrShaderGetBlock(shader, name);
luax_pushobject(L, block);
return 1;
}
int l_lovrShaderSetBlock(lua_State* L) {
Shader* shader = luax_checktype(L, 1, Shader);
const char* name = luaL_checkstring(L, 2);
ShaderBlock* block = luax_checktype(L, 3, ShaderBlock);
lovrShaderSetBlock(shader, name, block);
return 0;
}
const luaL_Reg lovrShader[] = {
{ "hasUniform", l_lovrShaderHasUniform },
{ "send", l_lovrShaderSend },
{ "getBlock", l_lovrShaderGetBlock },
{ "setBlock", l_lovrShaderSetBlock },
{ NULL, NULL }
};

View File

@ -0,0 +1,61 @@
#include "api.h"
#include "graphics/shader.h"
#include "math/transform.h"
int l_lovrShaderBlockIsWritable(lua_State* L) {
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
lua_pushboolean(L, lovrShaderBlockGetType(block) == BLOCK_STORAGE);
return 1;
}
int l_lovrShaderBlockGetSize(lua_State* L) {
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
lua_pushinteger(L, lovrShaderBlockGetSize(block));
return 1;
}
int l_lovrShaderBlockGetOffset(lua_State* L) {
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
const char* field = luaL_checkstring(L, 2);
const Uniform* uniform = lovrShaderBlockGetUniform(block, field);
lua_pushinteger(L, uniform->offset);
return 1;
}
int l_lovrShaderBlockSend(lua_State* L) {
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
if (lua_type(L, 2) == LUA_TSTRING) {
const char* name = luaL_checkstring(L, 2);
const Uniform* uniform = lovrShaderBlockGetUniform(block, name);
lovrAssert(uniform, "Unknown uniform for ShaderBlock '%s'", name);
uint8_t* data = ((uint8_t*) lovrShaderBlockMap(block)) + uniform->offset;
luax_checkuniform(L, 3, uniform, data, name);
return 0;
} else {
Blob* blob = luax_checktype(L, 1, Blob);
void* data = lovrShaderBlockMap(block);
size_t blockSize = lovrShaderBlockGetSize(block);
size_t copySize = MIN(blockSize, blob->size);
memcpy(data, blob->data, copySize);
lua_pushinteger(L, copySize);
return 1;
}
}
int l_lovrShaderBlockGetShaderCode(lua_State* L) {
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
const char* blockName = luaL_checkstring(L, 2);
size_t length;
char* code = lovrShaderBlockGetShaderCode(block, blockName, &length);
lua_pushlstring(L, code, length);
return 1;
}
const luaL_Reg lovrShaderBlock[] = {
{ "isWritable", l_lovrShaderBlockIsWritable },
{ "getSize", l_lovrShaderBlockGetSize },
{ "getOffset", l_lovrShaderBlockGetOffset },
{ "send", l_lovrShaderBlockSend },
{ "getShaderCode", l_lovrShaderBlockGetShaderCode },
{ NULL, NULL }
};

View File

@ -104,7 +104,7 @@ void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const cha
vertexFormatAppend(&format, "lovrPosition", ATTR_FLOAT, 3);
vertexFormatAppend(&format, "lovrNormal", ATTR_FLOAT, 3);
vertexFormatAppend(&format, "lovrTexCoord", ATTR_FLOAT, 2);
state.defaultMesh = lovrMeshCreate(64, format, MESH_TRIANGLES, MESH_STREAM);
state.defaultMesh = lovrMeshCreate(64, format, MESH_TRIANGLES, USAGE_STREAM);
lovrGraphicsReset();
state.initialized = true;
}

View File

@ -67,6 +67,10 @@ typedef enum {
WINDING_COUNTERCLOCKWISE
} Winding;
typedef struct {
bool writableBlocks;
} GraphicsFeatures;
typedef struct {
bool initialized;
float pointSizes[2];
@ -165,6 +169,7 @@ void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const cha
void lovrGraphicsGetDimensions(int* width, int* height);
int lovrGraphicsGetMSAA();
void lovrGraphicsSetCamera(Camera* camera, bool clear);
GraphicsFeatures lovrGraphicsGetSupported();
GraphicsLimits lovrGraphicsGetLimits();
GraphicsStats lovrGraphicsGetStats();

View File

@ -17,15 +17,9 @@ typedef enum {
MESH_TRIANGLE_FAN
} MeshDrawMode;
typedef enum {
MESH_STATIC,
MESH_DYNAMIC,
MESH_STREAM
} MeshUsage;
typedef struct Mesh Mesh;
Mesh* lovrMeshCreate(uint32_t count, VertexFormat format, MeshDrawMode drawMode, MeshUsage usage);
Mesh* lovrMeshCreate(uint32_t count, VertexFormat format, MeshDrawMode drawMode, BufferUsage usage);
void lovrMeshDestroy(void* ref);
void lovrMeshAttachAttribute(Mesh* mesh, Mesh* other, const char* name, int divisor);
void lovrMeshDetachAttribute(Mesh* mesh, const char* name);

View File

@ -63,7 +63,7 @@ Model* lovrModelCreate(ModelData* modelData) {
model->modelData = modelData;
model->aabbDirty = true;
model->mesh = lovrMeshCreate(modelData->vertexData->count, modelData->vertexData->format, MESH_TRIANGLES, MESH_STATIC);
model->mesh = lovrMeshCreate(modelData->vertexData->count, modelData->vertexData->format, MESH_TRIANGLES, USAGE_STATIC);
VertexPointer vertices = lovrMeshMapVertices(model->mesh, 0, modelData->vertexData->count, false, true);
memcpy(vertices.raw, modelData->vertexData->blob.data, modelData->vertexData->count * modelData->vertexData->format.stride);

View File

@ -23,6 +23,7 @@
// Types
#define MAX_TEXTURES 16
#define MAX_BLOCK_BUFFERS 8
#define LOVR_SHADER_POSITION 0
#define LOVR_SHADER_NORMAL 1
@ -31,8 +32,6 @@
#define LOVR_SHADER_TANGENT 4
#define LOVR_SHADER_BONES 5
#define LOVR_SHADER_BONE_WEIGHTS 6
#define LOVR_MAX_UNIFORM_LENGTH 64
#define LOVR_MAX_ATTRIBUTE_LENGTH 64
static struct {
Texture* defaultTexture;
@ -55,6 +54,7 @@ static struct {
uint32_t indexBuffer;
uint32_t program;
Texture* textures[MAX_TEXTURES];
uint32_t blockBuffers[2][MAX_BLOCK_BUFFERS];
uint32_t vertexArray;
uint32_t vertexBuffer;
float viewport[4];
@ -64,31 +64,36 @@ static struct {
GraphicsStats stats;
} state;
typedef struct {
GLchar name[LOVR_MAX_UNIFORM_LENGTH];
GLenum glType;
int location;
int count;
int components;
struct ShaderBlock {
Ref ref;
BlockType type;
BufferUsage usage;
vec_uniform_t uniforms;
map_int_t uniformMap;
uint32_t buffer;
GLenum target;
size_t size;
UniformType type;
union {
void* data;
int* ints;
float* floats;
Texture** textures;
} value;
int baseTextureSlot;
bool dirty;
} Uniform;
void* data;
bool mapped;
};
typedef map_t(Uniform) map_uniform_t;
typedef struct {
int index;
int binding;
ShaderBlock* source;
vec_uniform_t uniforms;
} UniformBlock;
typedef vec_t(UniformBlock) vec_block_t;
struct Shader {
Ref ref;
uint32_t program;
map_uniform_t uniforms;
vec_uniform_t uniforms;
vec_block_t blocks[2];
map_int_t attributes;
map_int_t uniformMap;
map_int_t blockMap;
};
struct Texture {
@ -232,11 +237,11 @@ static bool isTextureFormatCompressed(TextureFormat format) {
}
}
static GLenum convertMeshUsage(MeshUsage usage) {
static GLenum convertBufferUsage(BufferUsage usage) {
switch (usage) {
case MESH_STATIC: return GL_STATIC_DRAW;
case MESH_DYNAMIC: return GL_DYNAMIC_DRAW;
case MESH_STREAM: return GL_STREAM_DRAW;
case USAGE_STATIC: return GL_STATIC_DRAW;
case USAGE_DYNAMIC: return GL_DYNAMIC_DRAW;
case USAGE_STREAM: return GL_STREAM_DRAW;
}
}
@ -284,7 +289,7 @@ static UniformType getUniformType(GLenum type, const char* debug) {
case GL_SAMPLER_2D_ARRAY:
return UNIFORM_SAMPLER;
default:
lovrThrow("Unsupported uniform type '%s'", debug);
lovrThrow("Unsupported uniform type for uniform '%s'", debug);
return UNIFORM_FLOAT;
}
}
@ -315,6 +320,58 @@ static int getUniformComponents(GLenum type) {
}
}
static size_t getUniformTypeLength(const Uniform* uniform) {
size_t size = 0;
if (uniform->count > 1) {
size += 2 + floor(log10(uniform->count)) + 1; // "[count]"
}
switch (uniform->type) {
case UNIFORM_MATRIX: size += 3; break;
case UNIFORM_FLOAT: size += uniform->components == 1 ? 5 : 4; break;
case UNIFORM_INT: size += uniform->components == 1 ? 3 : 5; break;
default: break;
}
return size;
}
static const char* getUniformTypeName(const Uniform* uniform) {
switch (uniform->type) {
case UNIFORM_FLOAT:
switch (uniform->components) {
case 1: return "float";
case 2: return "vec2";
case 3: return "vec3";
case 4: return "vec4";
}
break;
case UNIFORM_INT:
switch (uniform->components) {
case 1: return "int";
case 2: return "ivec2";
case 3: return "ivec3";
case 4: return "ivec4";
}
break;
case UNIFORM_MATRIX:
switch (uniform->components) {
case 2: return "mat2";
case 3: return "mat3";
case 4: return "mat4";
}
break;
default: break;
}
lovrThrow("Unreachable");
return "";
}
// GPU
static void lovrGpuBindFramebuffer(uint32_t framebuffer) {
@ -358,6 +415,17 @@ void lovrGpuDirtyTexture(int slot) {
state.textures[slot] = NULL;
}
static void lovrGpuBindBlockBuffer(BlockType type, uint32_t buffer, int slot) {
if (state.blockBuffers[type][slot] != buffer) {
state.blockBuffers[type][slot] = buffer;
#ifdef EMSCRIPTEN
glBindBufferBase(GL_UNIFORM_BUFFER, slot, buffer);
#else
glBindBufferBase(type == BLOCK_UNIFORM ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER, slot, buffer);
#endif
}
}
static void lovrGpuBindVertexArray(uint32_t vertexArray) {
if (state.vertexArray != vertexArray) {
state.vertexArray = vertexArray;
@ -786,6 +854,20 @@ void lovrGpuDraw(DrawCommand* command) {
void lovrGpuPresent() {
memset(&state.stats, 0, sizeof(state.stats));
#ifdef __APPLE__
// For some reason instancing doesn't work on macOS unless you reset the shader every frame
lovrGpuUseProgram(0);
#endif
}
GraphicsFeatures lovrGraphicsGetSupported() {
return (GraphicsFeatures) {
#ifdef EMSCRIPTEN
.writableBlocks = false
#else
.writableBlocks = GLAD_GL_ARB_shader_storage_buffer_object
#endif
};
}
GraphicsLimits lovrGraphicsGetLimits() {
@ -1239,14 +1321,85 @@ Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource) {
glVertexAttribI4iv(LOVR_SHADER_BONES, (int[4]) { 0., 0., 0., 0. });
glVertexAttrib4fv(LOVR_SHADER_BONE_WEIGHTS, (float[4]) { 1., 0., 0., 0. });
// Uniform blocks
int32_t blockCount;
glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &blockCount);
lovrAssert(blockCount <= MAX_BLOCK_BUFFERS, "Shader has too many read-only blocks (%d) the max is %d", blockCount, MAX_BLOCK_BUFFERS);
map_init(&shader->blockMap);
vec_block_t* uniformBlocks = &shader->blocks[BLOCK_UNIFORM];
vec_init(uniformBlocks);
vec_reserve(uniformBlocks, blockCount);
for (int i = 0; i < blockCount; i++) {
UniformBlock block = { .index = i, .binding = i, .source = NULL };
glUniformBlockBinding(program, block.index, block.binding);
vec_init(&block.uniforms);
char name[LOVR_MAX_UNIFORM_LENGTH];
glGetActiveUniformBlockName(program, i, LOVR_MAX_UNIFORM_LENGTH, NULL, name);
int blockId = (i << 1) + BLOCK_UNIFORM;
map_set(&shader->blockMap, name, blockId);
vec_push(uniformBlocks, block);
}
// Shader storage buffers and their buffer variables
vec_block_t* storageBlocks = &shader->blocks[BLOCK_STORAGE];
vec_init(storageBlocks);
#ifndef EMSCRIPTEN
if (GLAD_GL_ARB_shader_storage_buffer_object && GLAD_GL_ARB_program_interface_query) {
// Iterate over storage blocks, setting their binding and pushing them onto the block vector
int storageCount;
glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &storageCount);
lovrAssert(storageCount <= MAX_BLOCK_BUFFERS, "Shader has too many writable blocks (%d) the max is %d", storageCount, MAX_BLOCK_BUFFERS);
vec_reserve(storageBlocks, storageCount);
for (int i = 0; i < storageCount; i++) {
UniformBlock block = { .index = i, .binding = i, .source = NULL };
glShaderStorageBlockBinding(program, block.index, block.binding);
vec_init(&block.uniforms);
char name[LOVR_MAX_UNIFORM_LENGTH];
glGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, i, LOVR_MAX_UNIFORM_LENGTH, NULL, name);
int blockId = (i << 1) + BLOCK_STORAGE;
map_set(&shader->blockMap, name, blockId);
vec_push(storageBlocks, block);
}
// Iterate over buffer variables, pushing them onto the uniform list of the correct block
int bufferVariableCount;
glGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &bufferVariableCount);
for (int i = 0; i < bufferVariableCount; i++) {
Uniform uniform;
enum { blockIndex, offset, glType, count, arrayStride, matrixStride, propCount };
int values[propCount];
GLenum properties[propCount] = { GL_BLOCK_INDEX, GL_OFFSET, GL_TYPE, GL_ARRAY_SIZE, GL_ARRAY_STRIDE, GL_MATRIX_STRIDE };
glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, i, propCount, properties, sizeof(values), NULL, values);
glGetProgramResourceName(program, GL_BUFFER_VARIABLE, i, LOVR_MAX_UNIFORM_LENGTH, NULL, uniform.name);
uniform.type = getUniformType(values[glType], uniform.name);
uniform.components = getUniformComponents(uniform.type);
uniform.count = values[count];
uniform.offset = values[offset];
if (uniform.count > 1) {
uniform.size = uniform.count * values[arrayStride];
} else if (uniform.type == UNIFORM_MATRIX) {
uniform.size = values[matrixStride] * uniform.components;
} else {
uniform.size = 4 * (uniform.components == 3 ? 4 : uniform.components);
}
vec_push(&storageBlocks->data[values[blockIndex]].uniforms, uniform);
}
}
#endif
// Uniform introspection
int32_t uniformCount;
int textureSlot = 0;
map_init(&shader->uniforms);
map_init(&shader->uniformMap);
vec_init(&shader->uniforms);
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount);
for (int i = 0; i < uniformCount; i++) {
for (uint32_t i = 0; i < (uint32_t) uniformCount; i++) {
Uniform uniform;
glGetActiveUniform(program, i, LOVR_MAX_UNIFORM_LENGTH, NULL, &uniform.count, &uniform.glType, uniform.name);
GLenum glType;
glGetActiveUniform(program, i, LOVR_MAX_UNIFORM_LENGTH, NULL, &uniform.count, &glType, uniform.name);
char* subscript = strchr(uniform.name, '[');
if (subscript) {
@ -1254,11 +1407,31 @@ Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource) {
}
uniform.location = glGetUniformLocation(program, uniform.name);
uniform.type = getUniformType(uniform.glType, uniform.name);
uniform.components = getUniformComponents(uniform.glType);
uniform.type = getUniformType(glType, uniform.name);
uniform.components = getUniformComponents(glType);
uniform.baseTextureSlot = (uniform.type == UNIFORM_SAMPLER) ? textureSlot : -1;
if (uniform.location == -1) {
int blockIndex;
glGetActiveUniformsiv(program, 1, &i, GL_UNIFORM_BLOCK_INDEX, &blockIndex);
if (blockIndex != -1) {
UniformBlock* block = &shader->blocks[BLOCK_UNIFORM].data[blockIndex];
glGetActiveUniformsiv(program, 1, &i, GL_UNIFORM_OFFSET, &uniform.offset);
glGetActiveUniformsiv(program, 1, &i, GL_UNIFORM_SIZE, &uniform.count);
if (uniform.count > 1) {
int stride;
glGetActiveUniformsiv(program, 1, &i, GL_UNIFORM_ARRAY_STRIDE, &stride);
uniform.size = stride * uniform.count;
} else if (uniform.type == UNIFORM_MATRIX) {
int matrixStride;
glGetActiveUniformsiv(program, 1, &i, GL_UNIFORM_MATRIX_STRIDE, &matrixStride);
uniform.size = uniform.components * matrixStride;
} else {
uniform.size = 4 * (uniform.components == 3 ? 4 : uniform.components);
}
vec_push(&block->uniforms, uniform);
continue;
} else if (uniform.location == -1) {
continue;
}
@ -1321,7 +1494,8 @@ Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource) {
}
}
map_set(&shader->uniforms, uniform.name, uniform);
map_set(&shader->uniformMap, uniform.name, shader->uniforms.length);
vec_push(&shader->uniforms, uniform);
textureSlot += (uniform.type == UNIFORM_SAMPLER) ? uniform.count : 0;
}
@ -1354,23 +1528,28 @@ Shader* lovrShaderCreateDefault(DefaultShader type) {
void lovrShaderDestroy(void* ref) {
Shader* shader = ref;
glDeleteProgram(shader->program);
const char* key;
map_iter_t iter = map_iter(&shader->uniforms);
while ((key = map_next(&shader->uniforms, &iter)) != NULL) {
Uniform* uniform = map_get(&shader->uniforms, key);
free(uniform->value.data);
for (int i = 0; i < shader->uniforms.length; i++) {
free(shader->uniforms.data[i].value.data);
}
map_deinit(&shader->uniforms);
for (BlockType type = BLOCK_UNIFORM; type <= BLOCK_STORAGE; type++) {
UniformBlock* block; int i;
vec_foreach_ptr(&shader->blocks[type], block, i) {
lovrRelease(block->source);
}
}
vec_deinit(&shader->uniforms);
vec_deinit(&shader->blocks[BLOCK_UNIFORM]);
vec_deinit(&shader->blocks[BLOCK_STORAGE]);
map_deinit(&shader->attributes);
map_deinit(&shader->uniformMap);
map_deinit(&shader->blockMap);
free(shader);
}
void lovrShaderBind(Shader* shader) {
map_iter_t iter = map_iter(&shader->uniforms);
const char* key;
while ((key = map_next(&shader->uniforms, &iter)) != NULL) {
Uniform* uniform = map_get(&shader->uniforms, key);
int i;
Uniform* uniform;
vec_foreach_ptr(&shader->uniforms, uniform, i) {
if (uniform->type != UNIFORM_SAMPLER && !uniform->dirty) {
continue;
}
@ -1408,18 +1587,24 @@ void lovrShaderBind(Shader* shader) {
case UNIFORM_SAMPLER:
for (int i = 0; i < count; i++) {
GLenum uniformTextureType;
switch (uniform->glType) {
case GL_SAMPLER_2D: uniformTextureType = GL_TEXTURE_2D; break;
case GL_SAMPLER_3D: uniformTextureType = GL_TEXTURE_3D; break;
case GL_SAMPLER_CUBE: uniformTextureType = GL_TEXTURE_CUBE_MAP; break;
case GL_SAMPLER_2D_ARRAY: uniformTextureType = GL_TEXTURE_2D_ARRAY; break;
}
lovrGpuBindTexture(uniform->value.textures[i], uniform->baseTextureSlot + i);
}
break;
}
}
// Bind uniform blocks
UniformBlock* block;
for (BlockType type = BLOCK_UNIFORM; type <= BLOCK_STORAGE; type++) {
vec_foreach_ptr(&shader->blocks[type], block, i) {
if (block->source) {
lovrShaderBlockUnmap(block->source);
lovrGpuBindBlockBuffer(type, block->source->buffer, block->binding);
} else {
lovrGpuBindBlockBuffer(type, 0, block->binding);
}
}
}
}
int lovrShaderGetAttributeId(Shader* shader, const char* name) {
@ -1428,31 +1613,28 @@ int lovrShaderGetAttributeId(Shader* shader, const char* name) {
}
bool lovrShaderHasUniform(Shader* shader, const char* name) {
return map_get(&shader->uniforms, name) != NULL;
return map_get(&shader->uniformMap, name) != NULL;
}
bool lovrShaderGetUniform(Shader* shader, const char* name, int* count, int* components, size_t* size, UniformType* type) {
Uniform* uniform = map_get(&shader->uniforms, name);
if (!uniform) {
const Uniform* lovrShaderGetUniform(Shader* shader, const char* name) {
int* index = map_get(&shader->uniformMap, name);
if (!index) {
return false;
}
*count = uniform->count;
*components = uniform->components;
*size = uniform->size;
*type = uniform->type;
return true;
return &shader->uniforms.data[*index];
}
static void lovrShaderSetUniform(Shader* shader, const char* name, UniformType type, void* data, int count, size_t size, const char* debug) {
Uniform* uniform = map_get(&shader->uniforms, name);
if (!uniform) {
static void lovrShaderSetUniform(Shader* shader, const char* name, UniformType type, void* data, int count, int size, const char* debug) {
int* index = map_get(&shader->uniformMap, name);
if (!index) {
return;
}
Uniform* uniform = &shader->uniforms.data[*index];
const char* plural = (uniform->size / size) > 1 ? "s" : "";
lovrAssert(uniform->type == type, "Unable to send %ss to uniform %s", debug, uniform->name);
lovrAssert(count * size <= uniform->size, "Expected at most %d %s%s for uniform %s, got %d", uniform->size / size, debug, plural, uniform->name, count);
lovrAssert(uniform->type == type, "Unable to send %ss to uniform %s", debug, name);
lovrAssert(count * size <= uniform->size, "Expected at most %d %s%s for uniform %s, got %d", uniform->size / size, debug, plural, name, count);
if (!uniform->dirty && !memcmp(uniform->value.data, data, count * size)) {
return;
@ -1478,16 +1660,182 @@ void lovrShaderSetTexture(Shader* shader, const char* name, Texture** data, int
lovrShaderSetUniform(shader, name, UNIFORM_SAMPLER, data, count, sizeof(Texture*), "texture");
}
ShaderBlock* lovrShaderGetBlock(Shader* shader, const char* name) {
int* id = map_get(&shader->blockMap, name);
lovrAssert(id, "No shader block named '%s'", name);
int type = *id & 1;
int index = *id >> 1;
UniformBlock* block = &shader->blocks[type].data[index];
return block->source;
}
void lovrShaderSetBlock(Shader* shader, const char* name, ShaderBlock* source) {
int* id = map_get(&shader->blockMap, name);
lovrAssert(id, "No shader block named '%s'", name);
int type = *id & 1;
int index = *id >> 1;
UniformBlock* block = &shader->blocks[type].data[index];
if (source != block->source) {
if (source) {
lovrAssert(block->uniforms.length == source->uniforms.length, "ShaderBlock must have same number of uniforms as block definition in Shader");
for (int i = 0; i < block->uniforms.length; i++) {
const Uniform* u = &block->uniforms.data[i];
const Uniform* v = &source->uniforms.data[i];
lovrAssert(u->type == v->type, "Shader is not compatible with ShaderBlock, check type of variable '%s'", v->name);
lovrAssert(u->offset == v->offset, "Shader is not compatible with ShaderBlock, check order of variable '%s'", v->name);
//lovrAssert(u->size == v->size, "Shader is not compatible with ShaderBlock, check count of variable '%s'", v->name);
}
}
lovrRetain(source);
lovrRelease(block->source);
block->source = source;
}
}
// ShaderBlock
ShaderBlock* lovrShaderBlockCreate(vec_uniform_t* uniforms, BlockType type, BufferUsage usage) {
ShaderBlock* block = lovrAlloc(ShaderBlock, lovrShaderBlockDestroy);
if (!block) return NULL;
lovrAssert(type != BLOCK_STORAGE || lovrGraphicsGetSupported().writableBlocks, "Writable ShaderBlocks are not supported on this system");
vec_init(&block->uniforms);
vec_extend(&block->uniforms, uniforms);
map_init(&block->uniformMap);
int i;
Uniform* uniform;
size_t size = 0;
vec_foreach_ptr(&block->uniforms, uniform, i) {
// Calculate size and offset
size_t align;
if (uniform->count > 1 || uniform->type == UNIFORM_MATRIX) {
align = 16 * (uniform->type == UNIFORM_MATRIX ? uniform->components : 1);
uniform->size = align * uniform->count;
} else {
align = (uniform->components + (uniform->components == 3)) * 4;
uniform->size = uniform->components * 4;
}
uniform->offset = (size + (align - 1)) & -align;
size = uniform->offset + uniform->size;
// Write index to uniform lookup
map_set(&block->uniformMap, uniform->name, i);
}
#ifdef EMSCRIPTEN
block->target = GL_UNIFORM_BUFFER;
#else
block->target = block->type == BLOCK_UNIFORM ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER;
#endif
block->type = type;
block->usage = convertBufferUsage(usage);
block->size = size;
block->data = calloc(1, size);
glGenBuffers(1, &block->buffer);
lovrGpuBindBlockBuffer(block->type, block->buffer, 0);
glBufferData(block->target, size, NULL, usage);
return block;
}
void lovrShaderBlockDestroy(void* ref) {
ShaderBlock* block = ref;
glDeleteBuffers(1, &block->buffer);
vec_deinit(&block->uniforms);
map_deinit(&block->uniformMap);
free(block->data);
free(block);
}
size_t lovrShaderBlockGetSize(ShaderBlock* block) {
return block->size;
}
BlockType lovrShaderBlockGetType(ShaderBlock* block) {
return block->type;
}
char* lovrShaderBlockGetShaderCode(ShaderBlock* block, const char* blockName, size_t* length) {
// Calculate
size_t size = 0;
size_t tab = 2;
size += 15; // "layout(std140) "
size += block->type == BLOCK_UNIFORM ? 7 : 6; // "uniform" || "buffer"
size += 1; // " "
size += strlen(blockName);
size += 3; // " {\n"
for (int i = 0; i < block->uniforms.length; i++) {
size += tab;
size += getUniformTypeLength(&block->uniforms.data[i]);
size += 1; // " "
size += strlen(block->uniforms.data[i].name);
size += 2; // ";\n"
}
size += 3; // "};\n"
// Allocate
char* code = malloc(size + 1);
// Concatenate
char* s = code;
s += sprintf(s, "layout(std140) %s %s {\n", block->type == BLOCK_UNIFORM ? "uniform" : "buffer", blockName);
for (int i = 0; i < block->uniforms.length; i++) {
const Uniform* uniform = &block->uniforms.data[i];
if (uniform->count > 1) {
s += sprintf(s, " %s %s[%d];\n", getUniformTypeName(uniform), uniform->name, uniform->count);
} else {
s += sprintf(s, " %s %s;\n", getUniformTypeName(uniform), uniform->name);
}
}
s += sprintf(s, "};\n");
*s = '\0';
*length = size;
return code;
}
const Uniform* lovrShaderBlockGetUniform(ShaderBlock* block, const char* name) {
int* index = map_get(&block->uniformMap, name);
if (!index) return NULL;
return &block->uniforms.data[*index];
}
void* lovrShaderBlockMap(ShaderBlock* block) {
block->mapped = true;
return block->data;
}
void lovrShaderBlockUnmap(ShaderBlock* block) {
if (!block->mapped) {
return;
}
lovrGpuBindBlockBuffer(block->type, block->buffer, 0);
glBufferData(block->target, block->size, NULL, block->usage);
glBufferSubData(block->target, 0, block->size, block->data);
block->mapped = false;
}
// Mesh
Mesh* lovrMeshCreate(uint32_t count, VertexFormat format, MeshDrawMode drawMode, MeshUsage usage) {
Mesh* lovrMeshCreate(uint32_t count, VertexFormat format, MeshDrawMode drawMode, BufferUsage usage) {
Mesh* mesh = lovrAlloc(Mesh, lovrMeshDestroy);
if (!mesh) return NULL;
mesh->count = count;
mesh->format = format;
mesh->drawMode = drawMode;
mesh->usage = convertMeshUsage(usage);
mesh->usage = convertBufferUsage(usage);
glGenBuffers(1, &mesh->vbo);
glGenBuffers(1, &mesh->ibo);
@ -1692,7 +2040,7 @@ void lovrMeshUnmapVertices(Mesh* mesh) {
size_t stride = mesh->format.stride;
lovrGpuBindVertexBuffer(mesh->vbo);
if (mesh->usage == MESH_STREAM) {
if (mesh->usage == USAGE_STREAM) {
glBufferData(GL_ARRAY_BUFFER, mesh->count * stride, mesh->data.bytes, mesh->usage);
} else {
size_t offset = mesh->dirtyStart * stride;

View File

@ -1,8 +1,24 @@
#include "graphics/texture.h"
#include "lib/map/map.h"
#include "lib/vec/vec.h"
#include <stdbool.h>
#pragma once
#define LOVR_MAX_UNIFORM_LENGTH 64
#define LOVR_MAX_ATTRIBUTE_LENGTH 64
typedef enum {
USAGE_STATIC,
USAGE_DYNAMIC,
USAGE_STREAM
} BufferUsage;
typedef enum {
BLOCK_UNIFORM,
BLOCK_STORAGE
} BlockType;
typedef enum {
UNIFORM_FLOAT,
UNIFORM_MATRIX,
@ -19,7 +35,28 @@ typedef enum {
MAX_DEFAULT_SHADERS
} DefaultShader;
typedef struct {
char name[LOVR_MAX_UNIFORM_LENGTH];
UniformType type;
int components;
int count;
int location;
int offset;
int size;
union {
void* data;
int* ints;
float* floats;
Texture** textures;
} value;
int baseTextureSlot;
bool dirty;
} Uniform;
typedef vec_t(Uniform) vec_uniform_t;
typedef struct Shader Shader;
typedef struct ShaderBlock ShaderBlock;
Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource);
Shader* lovrShaderCreateDefault(DefaultShader type);
@ -27,8 +64,19 @@ void lovrShaderDestroy(void* ref);
void lovrShaderBind(Shader* shader);
int lovrShaderGetAttributeId(Shader* shader, const char* name);
bool lovrShaderHasUniform(Shader* shader, const char* name);
bool lovrShaderGetUniform(Shader* shader, const char* name, int* count, int* components, size_t* size, UniformType* type);
const Uniform* lovrShaderGetUniform(Shader* shader, const char* name);
void lovrShaderSetFloat(Shader* shader, const char* name, float* data, int count);
void lovrShaderSetInt(Shader* shader, const char* name, int* data, int count);
void lovrShaderSetMatrix(Shader* shader, const char* name, float* data, int count);
void lovrShaderSetTexture(Shader* shader, const char* name, Texture** data, int count);
ShaderBlock* lovrShaderGetBlock(Shader* shader, const char* name);
void lovrShaderSetBlock(Shader* shader, const char* name, ShaderBlock* block);
ShaderBlock* lovrShaderBlockCreate(vec_uniform_t* uniforms, BlockType type, BufferUsage usage);
void lovrShaderBlockDestroy(void* ref);
size_t lovrShaderBlockGetSize(ShaderBlock* block);
BlockType lovrShaderBlockGetType(ShaderBlock* block);
char* lovrShaderBlockGetShaderCode(ShaderBlock* block, const char* blockName, size_t* length);
const Uniform* lovrShaderBlockGetUniform(ShaderBlock* block, const char* name);
void* lovrShaderBlockMap(ShaderBlock* block);
void lovrShaderBlockUnmap(ShaderBlock* block);

View File

@ -1,12 +1,15 @@
/*
OpenGL, OpenGL ES loader generated by glad 0.1.25 on Sat Jul 21 14:28:38 2018.
OpenGL, OpenGL ES loader generated by glad 0.1.26 on Fri Aug 3 00:32:58 2018.
Language/Generator: C/C++
Specification: gl
APIs: gl=3.3, gles2=3.0
Profile: core
Extensions:
GL_ARB_compute_shader,
GL_ARB_program_interface_query,
GL_ARB_shader_storage_buffer_object,
GL_ARB_texture_storage,
GL_ARB_viewport_array,
GL_EXT_texture_compression_s3tc,
@ -19,9 +22,9 @@
Omit khrplatform: True
Commandline:
--profile="core" --api="gl=3.3,gles2=3.0" --generator="c" --spec="gl" --no-loader --local-files --omit-khrplatform --extensions="GL_ARB_texture_storage,GL_ARB_viewport_array,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_sRGB,GL_NV_stereo_view_rendering,GL_NV_viewport_array2"
--profile="core" --api="gl=3.3,gles2=3.0" --generator="c" --spec="gl" --no-loader --local-files --omit-khrplatform --extensions="GL_ARB_compute_shader,GL_ARB_program_interface_query,GL_ARB_shader_storage_buffer_object,GL_ARB_texture_storage,GL_ARB_viewport_array,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_sRGB,GL_NV_stereo_view_rendering,GL_NV_viewport_array2"
Online:
http://glad.dav1d.de/#profile=core&language=c&specification=gl&api=gl%3D3.3&api=gles2%3D3.0&extensions=GL_ARB_texture_storage&extensions=GL_ARB_viewport_array&extensions=GL_EXT_texture_compression_s3tc&extensions=GL_EXT_texture_filter_anisotropic&extensions=GL_EXT_texture_sRGB&extensions=GL_NV_stereo_view_rendering&extensions=GL_NV_viewport_array2
http://glad.dav1d.de/#profile=core&language=c&specification=gl&api=gl%3D3.3&api=gles2%3D3.0&extensions=GL_ARB_compute_shader&extensions=GL_ARB_program_interface_query&extensions=GL_ARB_shader_storage_buffer_object&extensions=GL_ARB_texture_storage&extensions=GL_ARB_viewport_array&extensions=GL_EXT_texture_compression_s3tc&extensions=GL_EXT_texture_filter_anisotropic&extensions=GL_EXT_texture_sRGB&extensions=GL_NV_stereo_view_rendering&extensions=GL_NV_viewport_array2
*/
#include <stdio.h>
@ -29,7 +32,7 @@
#include <string.h>
#include "glad.h"
struct gladGLversionStruct GLVersion;
struct gladGLversionStruct GLVersion = { 0, 0 };
#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0)
#define _GLAD_IS_SOME_NEW_VERSION 1
@ -128,431 +131,443 @@ static int has_ext(const char *ext) {
return 0;
}
int GLAD_GL_VERSION_1_0;
int GLAD_GL_VERSION_1_1;
int GLAD_GL_VERSION_1_2;
int GLAD_GL_VERSION_1_3;
int GLAD_GL_VERSION_1_4;
int GLAD_GL_VERSION_1_5;
int GLAD_GL_VERSION_2_0;
int GLAD_GL_VERSION_2_1;
int GLAD_GL_VERSION_3_0;
int GLAD_GL_VERSION_3_1;
int GLAD_GL_VERSION_3_2;
int GLAD_GL_VERSION_3_3;
int GLAD_GL_ES_VERSION_2_0;
int GLAD_GL_ES_VERSION_3_0;
PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D;
PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui;
PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate;
PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer;
PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D;
PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv;
PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv;
PFNGLBINDSAMPLERPROC glad_glBindSampler;
PFNGLLINEWIDTHPROC glad_glLineWidth;
PFNGLCOLORP3UIVPROC glad_glColorP3uiv;
PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v;
PFNGLCOMPILESHADERPROC glad_glCompileShader;
PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying;
PFNGLDEPTHRANGEFPROC glad_glDepthRangef;
PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer;
PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui;
PFNGLVERTEXP4UIPROC glad_glVertexP4ui;
PFNGLENABLEIPROC glad_glEnablei;
PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui;
PFNGLCREATESHADERPROC glad_glCreateShader;
PFNGLISBUFFERPROC glad_glIsBuffer;
PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv;
PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers;
PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D;
PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D;
PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f;
PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate;
PFNGLHINTPROC glad_glHint;
PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s;
PFNGLSAMPLEMASKIPROC glad_glSampleMaski;
PFNGLVERTEXP2UIPROC glad_glVertexP2ui;
PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv;
PFNGLPOINTSIZEPROC glad_glPointSize;
PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv;
PFNGLDELETEPROGRAMPROC glad_glDeleteProgram;
PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv;
PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage;
PFNGLWAITSYNCPROC glad_glWaitSync;
PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv;
PFNGLUNIFORM3IPROC glad_glUniform3i;
PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv;
PFNGLUNIFORM3FPROC glad_glUniform3f;
PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv;
PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv;
PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui;
PFNGLCOLORMASKIPROC glad_glColorMaski;
PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi;
PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays;
PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback;
PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui;
PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv;
PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex;
PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D;
PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv;
PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv;
PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback;
PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui;
PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers;
PFNGLDRAWARRAYSPROC glad_glDrawArrays;
PFNGLUNIFORM1UIPROC glad_glUniform1ui;
PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i;
PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui;
PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d;
PFNGLCLEARPROC glad_glClear;
PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri;
PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName;
PFNGLISENABLEDPROC glad_glIsEnabled;
PFNGLSTENCILOPPROC glad_glStencilOp;
PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D;
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv;
PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub;
PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation;
PFNGLTEXIMAGE1DPROC glad_glTexImage1D;
PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv;
PFNGLGETTEXIMAGEPROC glad_glGetTexImage;
PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v;
PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers;
PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders;
PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer;
PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays;
PFNGLISVERTEXARRAYPROC glad_glIsVertexArray;
PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray;
PFNGLGETQUERYIVPROC glad_glGetQueryiv;
PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv;
PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices;
PFNGLISSHADERPROC glad_glIsShader;
PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv;
PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv;
PFNGLENABLEPROC glad_glEnable;
PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv;
PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation;
PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv;
PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv;
PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui;
PFNGLGETUNIFORMFVPROC glad_glGetUniformfv;
PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv;
PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv;
PFNGLDRAWBUFFERPROC glad_glDrawBuffer;
PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv;
PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced;
PFNGLFLUSHPROC glad_glFlush;
PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv;
PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv;
PFNGLFENCESYNCPROC glad_glFenceSync;
PFNGLCOLORP3UIPROC glad_glColorP3ui;
PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv;
PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender;
PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv;
PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv;
PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate;
PFNGLGENSAMPLERSPROC glad_glGenSamplers;
PFNGLCLAMPCOLORPROC glad_glClampColor;
PFNGLUNIFORM4IVPROC glad_glUniform4iv;
PFNGLCLEARSTENCILPROC glad_glClearStencil;
PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv;
PFNGLGENTEXTURESPROC glad_glGenTextures;
PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv;
PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv;
PFNGLISSYNCPROC glad_glIsSync;
PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName;
PFNGLUNIFORM2IPROC glad_glUniform2i;
PFNGLUNIFORM2FPROC glad_glUniform2f;
PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui;
PFNGLGETPROGRAMIVPROC glad_glGetProgramiv;
PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer;
PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer;
PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange;
PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D;
PFNGLGENQUERIESPROC glad_glGenQueries;
PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui;
PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D;
PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v;
PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers;
PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D;
PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer;
PFNGLISENABLEDIPROC glad_glIsEnabledi;
PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui;
PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed;
PFNGLUNIFORM2IVPROC glad_glUniform2iv;
PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv;
PFNGLUNIFORM4UIVPROC glad_glUniform4uiv;
PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D;
PFNGLGETSHADERIVPROC glad_glGetShaderiv;
PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer;
PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation;
PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset;
PFNGLGETDOUBLEVPROC glad_glGetDoublev;
PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d;
PFNGLGETUNIFORMIVPROC glad_glGetUniformiv;
PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv;
PFNGLUNIFORM3FVPROC glad_glUniform3fv;
PFNGLDEPTHRANGEPROC glad_glDepthRange;
PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer;
PFNGLMAPBUFFERPROC glad_glMapBuffer;
PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D;
PFNGLDELETESYNCPROC glad_glDeleteSync;
PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D;
PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv;
PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements;
PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv;
PFNGLUNIFORM3IVPROC glad_glUniform3iv;
PFNGLPOLYGONMODEPROC glad_glPolygonMode;
PFNGLDRAWBUFFERSPROC glad_glDrawBuffers;
PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv;
PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary;
PFNGLUSEPROGRAMPROC glad_glUseProgram;
PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog;
PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback;
PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray;
PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers;
PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv;
PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex;
PFNGLUNIFORM2UIVPROC glad_glUniform2uiv;
PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D;
PFNGLFINISHPROC glad_glFinish;
PFNGLDELETESHADERPROC glad_glDeleteShader;
PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv;
PFNGLVIEWPORTPROC glad_glViewport;
PFNGLUNIFORM1UIVPROC glad_glUniform1uiv;
PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings;
PFNGLUNIFORM2UIPROC glad_glUniform2ui;
PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i;
PFNGLCLEARDEPTHPROC glad_glClearDepth;
PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv;
PFNGLTEXPARAMETERFPROC glad_glTexParameterf;
PFNGLTEXPARAMETERIPROC glad_glTexParameteri;
PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource;
PFNGLTEXBUFFERPROC glad_glTexBuffer;
PFNGLPIXELSTOREIPROC glad_glPixelStorei;
PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram;
PFNGLPIXELSTOREFPROC glad_glPixelStoref;
PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v;
PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv;
PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ;
PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv;
PFNGLLINKPROGRAMPROC glad_glLinkProgram;
PFNGLBINDTEXTUREPROC glad_glBindTexture;
PFNGLGETSTRINGPROC glad_glGetString;
PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv;
PFNGLDETACHSHADERPROC glad_glDetachShader;
PFNGLENDQUERYPROC glad_glEndQuery;
PFNGLNORMALP3UIPROC glad_glNormalP3ui;
PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui;
PFNGLDELETETEXTURESPROC glad_glDeleteTextures;
PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate;
PFNGLDELETEQUERIESPROC glad_glDeleteQueries;
PFNGLNORMALP3UIVPROC glad_glNormalP3uiv;
PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f;
PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d;
PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv;
PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s;
PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex;
PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage;
PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri;
PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf;
PFNGLUNIFORM1FPROC glad_glUniform1f;
PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv;
PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage;
PFNGLUNIFORM1IPROC glad_glUniform1i;
PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib;
PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D;
PFNGLDISABLEPROC glad_glDisable;
PFNGLLOGICOPPROC glad_glLogicOp;
PFNGLUNIFORM4UIPROC glad_glUniform4ui;
PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer;
PFNGLCULLFACEPROC glad_glCullFace;
PFNGLGETSTRINGIPROC glad_glGetStringi;
PFNGLATTACHSHADERPROC glad_glAttachShader;
PFNGLQUERYCOUNTERPROC glad_glQueryCounter;
PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex;
PFNGLSHADERBINARYPROC glad_glShaderBinary;
PFNGLDRAWELEMENTSPROC glad_glDrawElements;
PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv;
PFNGLUNIFORM1IVPROC glad_glUniform1iv;
PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv;
PFNGLREADBUFFERPROC glad_glReadBuffer;
PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv;
PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced;
PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap;
PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv;
PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f;
PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv;
PFNGLPOINTPARAMETERIPROC glad_glPointParameteri;
PFNGLBLENDCOLORPROC glad_glBlendColor;
PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv;
PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer;
PFNGLPOINTPARAMETERFPROC glad_glPointParameterf;
PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s;
PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer;
PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv;
PFNGLISPROGRAMPROC glad_glIsProgram;
PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv;
PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv;
PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler;
PFNGLUNIFORM4IPROC glad_glUniform4i;
PFNGLACTIVETEXTUREPROC glad_glActiveTexture;
PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray;
PFNGLREADPIXELSPROC glad_glReadPixels;
PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv;
PFNGLUNIFORM4FPROC glad_glUniform4f;
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample;
PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv;
PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex;
PFNGLSTENCILFUNCPROC glad_glStencilFunc;
PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding;
PFNGLCOLORP4UIPROC glad_glColorP4ui;
PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv;
PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog;
PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i;
PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData;
PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate;
PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui;
PFNGLGENBUFFERSPROC glad_glGenBuffers;
PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv;
PFNGLBLENDFUNCPROC glad_glBlendFunc;
PFNGLCREATEPROGRAMPROC glad_glCreateProgram;
PFNGLTEXIMAGE3DPROC glad_glTexImage3D;
PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer;
PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex;
PFNGLGETINTEGER64VPROC glad_glGetInteger64v;
PFNGLSCISSORPROC glad_glScissor;
PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv;
PFNGLGETBOOLEANVPROC glad_glGetBooleanv;
PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv;
PFNGLUNIFORM3UIVPROC glad_glUniform3uiv;
PFNGLCLEARCOLORPROC glad_glClearColor;
PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv;
PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv;
PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v;
PFNGLCOLORP4UIVPROC glad_glColorP4uiv;
PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv;
PFNGLUNIFORM3UIPROC glad_glUniform3ui;
PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv;
PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv;
PFNGLUNIFORM2FVPROC glad_glUniform2fv;
PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv;
PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange;
PFNGLCLEARDEPTHFPROC glad_glClearDepthf;
PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv;
PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks;
PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv;
PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv;
PFNGLDEPTHFUNCPROC glad_glDepthFunc;
PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D;
PFNGLPROGRAMBINARYPROC glad_glProgramBinary;
PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv;
PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv;
PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui;
PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync;
PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui;
PFNGLCOLORMASKPROC glad_glColorMask;
PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv;
PFNGLBLENDEQUATIONPROC glad_glBlendEquation;
PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation;
PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback;
PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv;
PFNGLUNIFORM4FVPROC glad_glUniform4fv;
PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback;
PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv;
PFNGLISSAMPLERPROC glad_glIsSampler;
PFNGLVERTEXP3UIPROC glad_glVertexP3ui;
PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor;
PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D;
PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks;
PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D;
PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex;
PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus;
PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender;
PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv;
PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation;
PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv;
PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv;
PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements;
PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv;
PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase;
PFNGLBUFFERSUBDATAPROC glad_glBufferSubData;
PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv;
PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange;
PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture;
PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays;
PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv;
PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv;
PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat;
PFNGLDISABLEIPROC glad_glDisablei;
PFNGLSHADERSOURCEPROC glad_glShaderSource;
PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers;
PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv;
PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback;
PFNGLGETSYNCIVPROC glad_glGetSynciv;
PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv;
PFNGLBEGINQUERYPROC glad_glBeginQuery;
PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv;
PFNGLBINDBUFFERPROC glad_glBindBuffer;
PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv;
PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv;
PFNGLBUFFERDATAPROC glad_glBufferData;
PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv;
PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui;
PFNGLGETERRORPROC glad_glGetError;
PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui;
PFNGLGETFLOATVPROC glad_glGetFloatv;
PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D;
PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv;
PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv;
PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i;
PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv;
PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv;
PFNGLGETINTEGERVPROC glad_glGetIntegerv;
PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv;
PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D;
PFNGLISQUERYPROC glad_glIsQuery;
PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv;
PFNGLTEXIMAGE2DPROC glad_glTexImage2D;
PFNGLSTENCILMASKPROC glad_glStencilMask;
PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv;
PFNGLISTEXTUREPROC glad_glIsTexture;
PFNGLUNIFORM1FVPROC glad_glUniform1fv;
PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv;
PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv;
PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv;
PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData;
PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv;
PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d;
PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f;
PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv;
PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v;
PFNGLDEPTHMASKPROC glad_glDepthMask;
PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s;
PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample;
PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex;
PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample;
PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform;
PFNGLFRONTFACEPROC glad_glFrontFace;
int GLAD_GL_EXT_texture_sRGB;
int GLAD_GL_EXT_texture_filter_anisotropic;
int GLAD_GL_ARB_viewport_array;
int GLAD_GL_NV_stereo_view_rendering;
int GLAD_GL_NV_viewport_array2;
int GLAD_GL_ARB_texture_storage;
int GLAD_GL_EXT_texture_compression_s3tc;
PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D;
PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv;
PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf;
PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv;
PFNGLSCISSORARRAYVPROC glad_glScissorArrayv;
PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed;
PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv;
PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv;
PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed;
PFNGLGETFLOATI_VPROC glad_glGetFloati_v;
PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v;
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_ES_VERSION_2_0 = 0;
int GLAD_GL_ES_VERSION_3_0 = 0;
PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL;
PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL;
PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL;
PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL;
PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL;
PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL;
PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL;
PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL;
PFNGLLINEWIDTHPROC glad_glLineWidth = NULL;
PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL;
PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL;
PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL;
PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL;
PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL;
PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL;
PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui = NULL;
PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL;
PFNGLENABLEIPROC glad_glEnablei = NULL;
PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL;
PFNGLCREATESHADERPROC glad_glCreateShader = NULL;
PFNGLISBUFFERPROC glad_glIsBuffer = NULL;
PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL;
PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL;
PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL;
PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL;
PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL;
PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL;
PFNGLHINTPROC glad_glHint = NULL;
PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL;
PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL;
PFNGLVERTEXP2UIPROC glad_glVertexP2ui = NULL;
PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL;
PFNGLPOINTSIZEPROC glad_glPointSize = NULL;
PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL;
PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL;
PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL;
PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL;
PFNGLWAITSYNCPROC glad_glWaitSync = NULL;
PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL;
PFNGLUNIFORM3IPROC glad_glUniform3i = NULL;
PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL;
PFNGLUNIFORM3FPROC glad_glUniform3f = NULL;
PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL;
PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL;
PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL;
PFNGLCOLORMASKIPROC glad_glColorMaski = NULL;
PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL;
PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL;
PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL;
PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL;
PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL;
PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL;
PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL;
PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL;
PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL;
PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL;
PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui = NULL;
PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL;
PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL;
PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL;
PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL;
PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL;
PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL;
PFNGLCLEARPROC glad_glClear = NULL;
PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL;
PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL;
PFNGLISENABLEDPROC glad_glIsEnabled = NULL;
PFNGLSTENCILOPPROC glad_glStencilOp = NULL;
PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL;
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL;
PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL;
PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL;
PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL;
PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL;
PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL;
PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL;
PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL;
PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL;
PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL;
PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL;
PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL;
PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL;
PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL;
PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL;
PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL;
PFNGLISSHADERPROC glad_glIsShader = NULL;
PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL;
PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL;
PFNGLENABLEPROC glad_glEnable = NULL;
PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL;
PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL;
PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL;
PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv = NULL;
PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL;
PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL;
PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL;
PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL;
PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL;
PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL;
PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL;
PFNGLFLUSHPROC glad_glFlush = NULL;
PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL;
PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL;
PFNGLFENCESYNCPROC glad_glFenceSync = NULL;
PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL;
PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL;
PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL;
PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL;
PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv = NULL;
PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL;
PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL;
PFNGLCLAMPCOLORPROC glad_glClampColor = NULL;
PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL;
PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL;
PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL;
PFNGLGENTEXTURESPROC glad_glGenTextures = NULL;
PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL;
PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL;
PFNGLISSYNCPROC glad_glIsSync = NULL;
PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL;
PFNGLUNIFORM2IPROC glad_glUniform2i = NULL;
PFNGLUNIFORM2FPROC glad_glUniform2f = NULL;
PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL;
PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL;
PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL;
PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL;
PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL;
PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL;
PFNGLGENQUERIESPROC glad_glGenQueries = NULL;
PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL;
PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL;
PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL;
PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL;
PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL;
PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL;
PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL;
PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL;
PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL;
PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL;
PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL;
PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL;
PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL;
PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL;
PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL;
PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL;
PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL;
PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL;
PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL;
PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL;
PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL;
PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL;
PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL;
PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL;
PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL;
PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL;
PFNGLDELETESYNCPROC glad_glDeleteSync = NULL;
PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL;
PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL;
PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL;
PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL;
PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL;
PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL;
PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL;
PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL;
PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL;
PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL;
PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL;
PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL;
PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL;
PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL;
PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL;
PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL;
PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL;
PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL;
PFNGLFINISHPROC glad_glFinish = NULL;
PFNGLDELETESHADERPROC glad_glDeleteShader = NULL;
PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL;
PFNGLVIEWPORTPROC glad_glViewport = NULL;
PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL;
PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL;
PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL;
PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL;
PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL;
PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL;
PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL;
PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL;
PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL;
PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL;
PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL;
PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL;
PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL;
PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL;
PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv = NULL;
PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL;
PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL;
PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL;
PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL;
PFNGLGETSTRINGPROC glad_glGetString = NULL;
PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL;
PFNGLDETACHSHADERPROC glad_glDetachShader = NULL;
PFNGLENDQUERYPROC glad_glEndQuery = NULL;
PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL;
PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL;
PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL;
PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL;
PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL;
PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL;
PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL;
PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL;
PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL;
PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL;
PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL;
PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL;
PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL;
PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL;
PFNGLUNIFORM1FPROC glad_glUniform1f = NULL;
PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL;
PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL;
PFNGLUNIFORM1IPROC glad_glUniform1i = NULL;
PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL;
PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL;
PFNGLDISABLEPROC glad_glDisable = NULL;
PFNGLLOGICOPPROC glad_glLogicOp = NULL;
PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL;
PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL;
PFNGLCULLFACEPROC glad_glCullFace = NULL;
PFNGLGETSTRINGIPROC glad_glGetStringi = NULL;
PFNGLATTACHSHADERPROC glad_glAttachShader = NULL;
PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL;
PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL;
PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL;
PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL;
PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL;
PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL;
PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL;
PFNGLREADBUFFERPROC glad_glReadBuffer = NULL;
PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL;
PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL;
PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL;
PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL;
PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL;
PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL;
PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL;
PFNGLBLENDCOLORPROC glad_glBlendColor = NULL;
PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL;
PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL;
PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL;
PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL;
PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL;
PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL;
PFNGLISPROGRAMPROC glad_glIsProgram = NULL;
PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL;
PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL;
PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL;
PFNGLUNIFORM4IPROC glad_glUniform4i = NULL;
PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL;
PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL;
PFNGLREADPIXELSPROC glad_glReadPixels = NULL;
PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL;
PFNGLUNIFORM4FPROC glad_glUniform4f = NULL;
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL;
PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL;
PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL;
PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL;
PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL;
PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL;
PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL;
PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL;
PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL;
PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL;
PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL;
PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL;
PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL;
PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL;
PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL;
PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL;
PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL;
PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL;
PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL;
PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL;
PFNGLSCISSORPROC glad_glScissor = NULL;
PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL;
PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL;
PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv = NULL;
PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL;
PFNGLCLEARCOLORPROC glad_glClearColor = NULL;
PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL;
PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL;
PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL;
PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL;
PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL;
PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL;
PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL;
PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL;
PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL;
PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL;
PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL;
PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL;
PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL;
PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL;
PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL;
PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL;
PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL;
PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL;
PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL;
PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL;
PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL;
PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL;
PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL;
PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL;
PFNGLCOLORMASKPROC glad_glColorMask = NULL;
PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL;
PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL;
PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL;
PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL;
PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL;
PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL;
PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL;
PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL;
PFNGLISSAMPLERPROC glad_glIsSampler = NULL;
PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL;
PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL;
PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL;
PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL;
PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL;
PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL;
PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL;
PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL;
PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL;
PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL;
PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL;
PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL;
PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL;
PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL;
PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL;
PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL;
PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL;
PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL;
PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL;
PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL;
PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL;
PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL;
PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL;
PFNGLDISABLEIPROC glad_glDisablei = NULL;
PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL;
PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL;
PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL;
PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL;
PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL;
PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv = NULL;
PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL;
PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL;
PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL;
PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL;
PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL;
PFNGLBUFFERDATAPROC glad_glBufferData = NULL;
PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL;
PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL;
PFNGLGETERRORPROC glad_glGetError = NULL;
PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL;
PFNGLGETFLOATVPROC glad_glGetFloatv = NULL;
PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL;
PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL;
PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL;
PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL;
PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL;
PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL;
PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL;
PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL;
PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL;
PFNGLISQUERYPROC glad_glIsQuery = NULL;
PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL;
PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL;
PFNGLSTENCILMASKPROC glad_glStencilMask = NULL;
PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL;
PFNGLISTEXTUREPROC glad_glIsTexture = NULL;
PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL;
PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL;
PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL;
PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL;
PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL;
PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL;
PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL;
PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL;
PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL;
PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL;
PFNGLDEPTHMASKPROC glad_glDepthMask = NULL;
PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL;
PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL;
PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL;
PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL;
PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL;
PFNGLFRONTFACEPROC glad_glFrontFace = NULL;
int GLAD_GL_ARB_program_interface_query = 0;
int GLAD_GL_ARB_compute_shader = 0;
int GLAD_GL_EXT_texture_sRGB = 0;
int GLAD_GL_EXT_texture_filter_anisotropic = 0;
int GLAD_GL_ARB_shader_storage_buffer_object = 0;
int GLAD_GL_ARB_viewport_array = 0;
int GLAD_GL_NV_stereo_view_rendering = 0;
int GLAD_GL_NV_viewport_array2 = 0;
int GLAD_GL_ARB_texture_storage = 0;
int GLAD_GL_EXT_texture_compression_s3tc = 0;
PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute = NULL;
PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect = NULL;
PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = NULL;
PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex = NULL;
PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName = NULL;
PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv = NULL;
PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation = NULL;
PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex = NULL;
PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding = NULL;
PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D = NULL;
PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL;
PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL;
PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL;
PFNGLSCISSORARRAYVPROC glad_glScissorArrayv = NULL;
PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed = NULL;
PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv = NULL;
PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL;
PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL;
PFNGLGETFLOATI_VPROC glad_glGetFloati_v = NULL;
PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v = NULL;
static void load_GL_VERSION_1_0(GLADloadproc load) {
if(!GLAD_GL_VERSION_1_0) return;
glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace");
@ -966,6 +981,24 @@ static void load_GL_VERSION_3_3(GLADloadproc load) {
glad_glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)load("glSecondaryColorP3ui");
glad_glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)load("glSecondaryColorP3uiv");
}
static void load_GL_ARB_compute_shader(GLADloadproc load) {
if(!GLAD_GL_ARB_compute_shader) return;
glad_glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)load("glDispatchCompute");
glad_glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC)load("glDispatchComputeIndirect");
}
static void load_GL_ARB_program_interface_query(GLADloadproc load) {
if(!GLAD_GL_ARB_program_interface_query) return;
glad_glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC)load("glGetProgramInterfaceiv");
glad_glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC)load("glGetProgramResourceIndex");
glad_glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC)load("glGetProgramResourceName");
glad_glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)load("glGetProgramResourceiv");
glad_glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC)load("glGetProgramResourceLocation");
glad_glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)load("glGetProgramResourceLocationIndex");
}
static void load_GL_ARB_shader_storage_buffer_object(GLADloadproc load) {
if(!GLAD_GL_ARB_shader_storage_buffer_object) return;
glad_glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC)load("glShaderStorageBlockBinding");
}
static void load_GL_ARB_texture_storage(GLADloadproc load) {
if(!GLAD_GL_ARB_texture_storage) return;
glad_glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)load("glTexStorage1D");
@ -987,6 +1020,9 @@ static void load_GL_ARB_viewport_array(GLADloadproc load) {
}
static int find_extensionsGL(void) {
if (!get_exts()) return 0;
GLAD_GL_ARB_compute_shader = has_ext("GL_ARB_compute_shader");
GLAD_GL_ARB_program_interface_query = has_ext("GL_ARB_program_interface_query");
GLAD_GL_ARB_shader_storage_buffer_object = has_ext("GL_ARB_shader_storage_buffer_object");
GLAD_GL_ARB_texture_storage = has_ext("GL_ARB_texture_storage");
GLAD_GL_ARB_viewport_array = has_ext("GL_ARB_viewport_array");
GLAD_GL_EXT_texture_compression_s3tc = has_ext("GL_EXT_texture_compression_s3tc");
@ -1072,6 +1108,9 @@ int gladLoadGLLoader(GLADloadproc load) {
load_GL_VERSION_3_3(load);
if (!find_extensionsGL()) return 0;
load_GL_ARB_compute_shader(load);
load_GL_ARB_program_interface_query(load);
load_GL_ARB_shader_storage_buffer_object(load);
load_GL_ARB_texture_storage(load);
load_GL_ARB_viewport_array(load);
return GLVersion.major != 0 || GLVersion.minor != 0;

View File

@ -1,12 +1,15 @@
/*
OpenGL, OpenGL ES loader generated by glad 0.1.25 on Sat Jul 21 14:28:38 2018.
OpenGL, OpenGL ES loader generated by glad 0.1.26 on Fri Aug 3 00:32:58 2018.
Language/Generator: C/C++
Specification: gl
APIs: gl=3.3, gles2=3.0
Profile: core
Extensions:
GL_ARB_compute_shader,
GL_ARB_program_interface_query,
GL_ARB_shader_storage_buffer_object,
GL_ARB_texture_storage,
GL_ARB_viewport_array,
GL_EXT_texture_compression_s3tc,
@ -19,9 +22,9 @@
Omit khrplatform: True
Commandline:
--profile="core" --api="gl=3.3,gles2=3.0" --generator="c" --spec="gl" --no-loader --local-files --omit-khrplatform --extensions="GL_ARB_texture_storage,GL_ARB_viewport_array,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_sRGB,GL_NV_stereo_view_rendering,GL_NV_viewport_array2"
--profile="core" --api="gl=3.3,gles2=3.0" --generator="c" --spec="gl" --no-loader --local-files --omit-khrplatform --extensions="GL_ARB_compute_shader,GL_ARB_program_interface_query,GL_ARB_shader_storage_buffer_object,GL_ARB_texture_storage,GL_ARB_viewport_array,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_sRGB,GL_NV_stereo_view_rendering,GL_NV_viewport_array2"
Online:
http://glad.dav1d.de/#profile=core&language=c&specification=gl&api=gl%3D3.3&api=gles2%3D3.0&extensions=GL_ARB_texture_storage&extensions=GL_ARB_viewport_array&extensions=GL_EXT_texture_compression_s3tc&extensions=GL_EXT_texture_filter_anisotropic&extensions=GL_EXT_texture_sRGB&extensions=GL_NV_stereo_view_rendering&extensions=GL_NV_viewport_array2
http://glad.dav1d.de/#profile=core&language=c&specification=gl&api=gl%3D3.3&api=gles2%3D3.0&extensions=GL_ARB_compute_shader&extensions=GL_ARB_program_interface_query&extensions=GL_ARB_shader_storage_buffer_object&extensions=GL_ARB_texture_storage&extensions=GL_ARB_viewport_array&extensions=GL_EXT_texture_compression_s3tc&extensions=GL_EXT_texture_filter_anisotropic&extensions=GL_EXT_texture_sRGB&extensions=GL_NV_stereo_view_rendering&extensions=GL_NV_viewport_array2
*/
@ -860,7 +863,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void);
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
#define GL_MAX_SAMPLES 0x8D57
#define GL_INDEX 0x8222
#define GL_FRAMEBUFFER_SRGB 0x8DB9
#define GL_HALF_FLOAT 0x140B
#define GL_MAP_READ_BIT 0x0001
@ -2325,6 +2327,91 @@ typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC)(GLenum target, GLenum inte
GLAPI PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ;
#define glGetInternalformativ glad_glGetInternalformativ
#endif
#define GL_COMPUTE_SHADER 0x91B9
#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB
#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267
#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC
#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED
#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
#define GL_COMPUTE_SHADER_BIT 0x00000020
#define GL_UNIFORM 0x92E1
#define GL_UNIFORM_BLOCK 0x92E2
#define GL_PROGRAM_INPUT 0x92E3
#define GL_PROGRAM_OUTPUT 0x92E4
#define GL_BUFFER_VARIABLE 0x92E5
#define GL_SHADER_STORAGE_BLOCK 0x92E6
#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
#define GL_VERTEX_SUBROUTINE 0x92E8
#define GL_TESS_CONTROL_SUBROUTINE 0x92E9
#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA
#define GL_GEOMETRY_SUBROUTINE 0x92EB
#define GL_FRAGMENT_SUBROUTINE 0x92EC
#define GL_COMPUTE_SUBROUTINE 0x92ED
#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE
#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF
#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0
#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1
#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2
#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3
#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4
#define GL_ACTIVE_RESOURCES 0x92F5
#define GL_MAX_NAME_LENGTH 0x92F6
#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8
#define GL_NAME_LENGTH 0x92F9
#define GL_TYPE 0x92FA
#define GL_ARRAY_SIZE 0x92FB
#define GL_OFFSET 0x92FC
#define GL_BLOCK_INDEX 0x92FD
#define GL_ARRAY_STRIDE 0x92FE
#define GL_MATRIX_STRIDE 0x92FF
#define GL_IS_ROW_MAJOR 0x9300
#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
#define GL_BUFFER_BINDING 0x9302
#define GL_BUFFER_DATA_SIZE 0x9303
#define GL_NUM_ACTIVE_VARIABLES 0x9304
#define GL_ACTIVE_VARIABLES 0x9305
#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306
#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307
#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308
#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309
#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A
#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B
#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C
#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D
#define GL_LOCATION 0x930E
#define GL_LOCATION_INDEX 0x930F
#define GL_IS_PER_PATCH 0x92E7
#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A
#define GL_COMPATIBLE_SUBROUTINES 0x8E4B
#define GL_SHADER_STORAGE_BUFFER 0x90D2
#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3
#define GL_SHADER_STORAGE_BUFFER_START 0x90D4
#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5
#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6
#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7
#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8
#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9
#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA
#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB
#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39
#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
#define GL_MAX_VIEWPORTS 0x825B
#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C
#define GL_VIEWPORT_BOUNDS_RANGE 0x825D
@ -2353,6 +2440,45 @@ GLAPI PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ;
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
#ifndef GL_ARB_compute_shader
#define GL_ARB_compute_shader 1
GLAPI int GLAD_GL_ARB_compute_shader;
typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
GLAPI PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute;
#define glDispatchCompute glad_glDispatchCompute
typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC)(GLintptr indirect);
GLAPI PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect;
#define glDispatchComputeIndirect glad_glDispatchComputeIndirect
#endif
#ifndef GL_ARB_program_interface_query
#define GL_ARB_program_interface_query 1
GLAPI int GLAD_GL_ARB_program_interface_query;
typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC)(GLuint program, GLenum programInterface, GLenum pname, GLint *params);
GLAPI PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv;
#define glGetProgramInterfaceiv glad_glGetProgramInterfaceiv
typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC)(GLuint program, GLenum programInterface, const GLchar *name);
GLAPI PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex;
#define glGetProgramResourceIndex glad_glGetProgramResourceIndex
typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
GLAPI PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName;
#define glGetProgramResourceName glad_glGetProgramResourceName
typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);
GLAPI PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv;
#define glGetProgramResourceiv glad_glGetProgramResourceiv
typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC)(GLuint program, GLenum programInterface, const GLchar *name);
GLAPI PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation;
#define glGetProgramResourceLocation glad_glGetProgramResourceLocation
typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)(GLuint program, GLenum programInterface, const GLchar *name);
GLAPI PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex;
#define glGetProgramResourceLocationIndex glad_glGetProgramResourceLocationIndex
#endif
#ifndef GL_ARB_shader_storage_buffer_object
#define GL_ARB_shader_storage_buffer_object 1
GLAPI int GLAD_GL_ARB_shader_storage_buffer_object;
typedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);
GLAPI PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding;
#define glShaderStorageBlockBinding glad_glShaderStorageBlockBinding
#endif
#ifndef GL_ARB_texture_storage
#define GL_ARB_texture_storage 1
GLAPI int GLAD_GL_ARB_texture_storage;