The GLAD library in OpenGL developing

ElioWangElioWang
2 min read

Platform compatible

Rendering is not an easy job, it needs both software and hardware support. Unfortunately, there is more than one software/hardware renderer vendor on earth.

For hardware

OpenGL tries to unify different device driver interfaces. It is a standard rather than a library, so OpenGL never provides the implementation for rendering. GPU vendors offer the implementation. Any program that needs to use OpenGL has to load implementation dynamically, writing some dynamic linking code like this:

typedef void (*GENBUFFERS) (GLsizei, GLuint*);
GENBUFFERS glGenBuffers = (GENBUFFERS)wglGetProcAddress("glGenBuffers");
// ... invoke wglGetProcAddress per API

Oh, tremendously boring...

For software

Unfortunately again, different OS provides different interfaces to do that dynamic linking. For APIs, Windows provides wglGetProcAddress, Linux provides glXGetProcAddress, and MacOS provides NSGLGetProcAddress. The code above copies and modifies every time fitting to different systems.

Even worse, some OpenGL versions may cause wglGetProcAddress to fail on Windows. (OpenGL wiki)

Glad there is glad

glad, also alternatives like glew, glee, are used to simplify the checking and linking routine. Now use gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) in a nutshell to make life easier.

glfw is a multi-platform window/event manager library.

Use glad without glfw on windows

Using glfw to initialize glad is a popular way. But for curiosity, can we use wglGetProcAddress to initialize glad?

The answer is yes but not directly. You cannot directly write code like this:

if (!gladLoadGLLoader((GLADloadproc)wglGetProcAddress)) {
    ...
}

Someone failed already. The reason is described here -- the dynamic linking interface is not available to wglGetProcAddress in OpenGL32.DLL. The right way is to mix the wglGetProcAddress and GetProcAddress like this:

void *GetAnyGLFuncAddress(const char *name)
{
    void *p = (void *)wglGetProcAddress(name);
    if (p == 0 ||
       (p == (void*)0x1) || (p == (void*)0x2) || (p == (void*)0x3) ||
       (p == (void*)-1) )
    {
        HMODULE module = LoadLibraryA("opengl32.dll");
        p = (void *)GetProcAddress(module, name);
    }

    return p;
}
if (!gladLoadGLLoader((GLADloadproc)GetAnyGLFuncAddress)) {
    ...
}

This code works well with the Windows OpenGL Context. Full code snippet is available here.

References

0
Subscribe to my newsletter

Read articles from ElioWang directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

ElioWang
ElioWang