LOAD_OPENGL_DLL = ''' version(Windows) { private import std.c.windows.windows; } else { private import core.sys.posix.dlfcn; } version(Windows) { private __gshared HMODULE libGL; } else { private __gshared void* libGL; } extern(System) private @nogc alias gladGetProcAddressPtrType = void* function(const(char)*); private __gshared gladGetProcAddressPtrType gladGetProcAddressPtr; %(pre)s bool %(init)s() @nogc { version(Windows) { libGL = LoadLibraryA("opengl32.dll"); if(libGL !is null) { gladGetProcAddressPtr = cast(typeof(gladGetProcAddressPtr))GetProcAddress( libGL, "wglGetProcAddress"); return gladGetProcAddressPtr !is null; } return false; } else { version(OSX) { enum const(char)*[] NAMES = [ "../Frameworks/OpenGL.framework/OpenGL", "/Library/Frameworks/OpenGL.framework/OpenGL", "/System/Library/Frameworks/OpenGL.framework/OpenGL", "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" ]; } else { enum const(char)*[] NAMES = ["libGL.so.1", "libGL.so"]; } foreach(name; NAMES) { libGL = dlopen(name, RTLD_NOW | RTLD_GLOBAL); if(libGL !is null) { version(OSX) { return true; } else { gladGetProcAddressPtr = cast(typeof(gladGetProcAddressPtr))dlsym(libGL, "glXGetProcAddressARB"); return gladGetProcAddressPtr !is null; } } } return false; } } %(pre)s void* %(proc)s(const(char)* namez) @nogc { if(libGL is null) return null; void* result; if(gladGetProcAddressPtr !is null) { result = gladGetProcAddressPtr(namez); } if(result is null) { version(Windows) { result = GetProcAddress(libGL, namez); } else { result = dlsym(libGL, namez); } } return result; } %(pre)s void %(terminate)s() @nogc { version(Windows) { if(libGL !is null) { FreeLibrary(libGL); libGL = null; } } else { if(libGL !is null) { dlclose(libGL); libGL = null; } } } '''