The GLAD library in OpenGL developing
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
Subscribe to my newsletter
Read articles from ElioWang directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by