-
Notifications
You must be signed in to change notification settings - Fork 457
All public and glad specific symbols follow certain rules:
- All symbols contain the API (GL, GLES2, WGL, etc.), in the following this will be marked as
{API}
- All symbols are equally named across all APIs (e.g.
gladLoad{API}Simple
) - Functions are prefixed with
glad
- Structs are prefixed with
Glad
- Macros are prefixed with
GLAD_
- Constants/Globals are prefixed with
GLAD_
- Typedefs are prefixed with
GLAD
Everything generated by glad needs to be initialized through one loader function. Glad exposes two with similiar APIs by default:
typedef void* (* GLADloadproc)(const char *name, void* userptr);
typedef void* (* GLADsimpleloadproc)(const char *name);
GLAPI int gladLoad{API}(GLADloadproc load, void* userptr);
GLAPI int gladLoad{API}Simple(GLADsimpleloadproc load);
gladLoadGL
allows you to pass a userpointer which will be forwarded to your loader function,
this allows you to write a loader function which is independent of global state (useful for e.g. Qt).
In most cases you will be using gladLoad{API}Simple
, most libraries like GLFW or SDL already
provide a loader which is compatible with this function.
The return value of gladLoad{API}
and gladLoad{API}Simple
is the actual loaded version of the API.
The version is calculated using the formula major * 10 + minor
. On error 0 is returned.
NOTE: since some APIs require additional information in order to be initialized the loader signature may vary depending on the API (e.g. WGL and EGL have different signatures).
NOTE: initializing an API more than once is undefined behaviour.
After glad was initialized a few variables will be populated. Glad creates a global boolean for every version and extension generated.
GLAPI int GLAD_{API}_VERSION_3_0;
GLAPI int GLAD_{API}_VERSION_3_1;
// ...
GLAPI int GLAD_{API}_EXT_texture_buffer_object;
GLAPI int GLAD_{API}_KHR_debug;
// ...
If a version/extension was successfully loaded the global will be set to true (1).
Sometimes you want to write glad agnostic code, for this glad generates and defines a few macros dependent on the generation options used.
#define GLAD_{API}
#define GLAD_OPTION_{API}_LOADER
#define GLAD_OPTION_{API}_ALIAS
Initializing glad with glfwGetProcAddress
and extracting the loaded major and minor versions:
int version = gladLoadGLSimple((GLADsimpleloadproc) glfwGetProcAddress);
if (version == 0)
{
std::cout << "Failed to initialize OpenGL context" << std::endl;
return -1;
}
// Successfully loaded OpenGL
std::cout << "Loaded OpenGL " << version / 10 << "." << version % 10 << std::endl;
The header only option combines source and header into a single header file.
The implementation will be guarded by GLAD_{API}_IMPLEMENTATION
. In order to not end
up with missing symbols you need to define this macro ONE SOURCE file before including
glad.
Example for GL:
#define GLAD_GL_IMPLEMENTATION
#include <glad/gl.h>
int main(void) {
// ...
if (!gladLoadGLSimple((GLADsimpleloadproc) glfwGetProcAddress)) {
return -1;
}
// ...
}
The loader option adds an internal loader into the generated files. This is useful if you are not using a library that cotains a loader (e.g. you're not using GLFW, SDL, Qt or similar).
The following function will be added:
GLAPI int gladLoad{API}InternalLoader();
Some APIs (egl
, gles1
, gles2
, glx
) should be unloaded at the end of the program, this can be done through:
GLAPI void gladUnload{API}InternalLoader();
NOTE: Even after multiple calls to gladLoad{API}InternalLoader()
only one call to gladUnload{API}InternalLoader()
is required.
The debugging option adds an additional layer of indirection allowing you to intercept and modify any call made.
Usually glad works like this glClear() -> glad_glClear()
using the debug option it looks like this
glClear() -> glad_debug_glClear() -> glad_glClear()
. glClear()
is a macro, glad_glClear()
contains the actual
function pointer.
By default the added indirection (glad_debug_glClear
) calls the "pre callback", then the actual function and afterwards the "post callback".
Callbacks can be set with the following functions:
typedef void (* GLADcallback)(const char *name, void *funcptr, int len_args, ...);
void gladSet{API}PreCallback(GLADcallback cb);
void gladSet{API}PostCallback(GLADcallback cb);
By default the "pre callback" clears all errors and the "post callback" checks for an error using glGetError
.
NOTE: the debug option cannot be used together with the multi context option.
Enables automatic alias resolution. A lot of OpenGL features exist in multiple extensions, and some of them have been moved into core. The result is a bunch of functions which are named differently but do the same.
Glad will automatically include all extensions which have an alias to a function you specified in the feature set and at runtime all functions (if not available) will be initialized using their aliases.
An excerpt of the generated code:
// executed after initial loading phase:
if (glVertexAttrib2sv == NULL && glVertexAttrib2svARB != NULL) glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)glVertexAttrib2svARB;
if (glVertexAttrib2sv == NULL && glVertexAttrib2svNV != NULL) glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)glVertexAttrib2svNV;
TODO