Skip to content
Dav1dde edited this page Mar 6, 2018 · 10 revisions

Contents

  1. Basic API
  2. Header Only
  3. Loader
  4. Debugging
  5. Aliasing
  6. Multi Context

Basic API

All public and glad specific symbols follow certain rules:

  1. All symbols contain the API (GL, GLES2, WGL, etc.), in the following this will be marked as {API}
  2. All symbols are equally named across all APIs (e.g. gladLoad{API}Simple)
  3. Functions are prefixed with glad
  4. Structs are prefixed with Glad
  5. Macros are prefixed with GLAD_
  6. Constants/Globals are prefixed with GLAD_
  7. Typedefs are prefixed with GLAD

Initializing 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.

Runtime Checks

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).

Compiletime Checks

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

Examples

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;

Header Only

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;
    }
    // ...
}

Loader

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.

Debugging

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.

Aliasing

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;

Multi Context

TODO

Clone this wiki locally