Platform compatible
Rendering is not a easy work, it needs both software and hardware support. Unfortunately, there are 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 implementation for rendering. GPU vendors offer the implementation. Any program 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
. Code above copies and modifies every time fitting to different systems.
Even worse, some OpenGL version may cause wglGetProcAddress
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 the 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 that 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.