Easy usage of GL 3.1 / 3.2 extensions in C++

I recently wanted to use some of the newer functionality found in OpenGL 3.1 and 3.2. However since I was using glew and it only supports GL versions up to 3.0, I had to manually add and initialize unsupported functions myself. This can be quite a pain, so I decided to write some code to automate this process (and replace glew).

It works in two steps

In the first step all the gl and wgl functions found in “glext.h” and “wglext.h” are parsed and stored in two files called “glfunc_test.h” and “glfunc_test.cpp”

In the second step a small win32 project is compiled which includes both these files. The resulting program creates a OpenGL context and requests function pointers to every function in “glext.h” and “wglext.h”. It spits out two files “opengl.h” and “opengl.cpp”. “opengl.h” contains function pointer declarations for all the gl/wgl functions supported by your video driver and “opengl.cpp” contains the definitions and a function to initialize the function pointers.

After generating “opengl.cpp” and “opengl.h” they can be included in your own opengl projects to have easy access to the GL/WGL extensions supported by your video card.

I don’t know how useful this is going to be to anyone, or if something like this already exists. It was useful to me so thats why I’m posting it here. If you have any questions you can put them in this thread.

The files can be found here:

http://rapidshare.com/files/298161299/gl_func.rar

or

http://www.megaupload.com/?d=ENJG8KRB

Good luck with that file requiring paid-access.

Here’s the way:


// file gl_extensions.h
#ifndef OPENGL_MACRO
	#define OPENGL_MACRO(proc,proctype) extern PFN##proctype##PROC proc
	#define OPTIONAL_EXT(proc,proctype) extern PFN##proctype##PROC proc
#endif



OPENGL_MACRO(glCompressedTexImage2D,GLCOMPRESSEDTEXIMAGE2D);
OPENGL_MACRO(glGenerateMipmap,GLGENERATEMIPMAP);

OPENGL_MACRO(glGenBuffers,GLGENBUFFERS);
OPENGL_MACRO(glBindBuffer,GLBINDBUFFER);
OPENGL_MACRO(glBufferData,GLBUFFERDATA);
OPENGL_MACRO(glMapBuffer,GLMAPBUFFER);
OPENGL_MACRO(glUnmapBuffer,GLUNMAPBUFFER);
OPENGL_MACRO(glDeleteBuffers,GLDELETEBUFFERS);
OPENGL_MACRO(glGetBufferParameteriv,GLGETBUFFERPARAMETERIV);
....
OPTIONAL_EXT(glRenderbufferStorageMultisampleCoverageNV,GLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENV);

(copy/paste, double-click, ctrl+shift+U to convert to uppercase)


// file engine_init.cpp

#define OPENGL_MACRO(proc,proctype) PFN##proctype##PROC proc
#define OPTIONAL_EXT(proc,proctype) PFN##proctype##PROC proc
#include "gl_extensions.h"

static PROC uglGetProcAddress(const char* pName,bool IsOptional){
	PROC res = wglGetProcAddress(pName);
	if(res || IsOptional)return res;
	MessageBoxA(0,pName,"Missing OpenGL extension proc!",0);
	ExitProcess(0);
}
static void InitGLExtentions(){
	#define OPENGL_MACRO(proc,proctype) proc = (PFN##proctype##PROC)uglGetProcAddress(#proc,false)
	#define OPTIONAL_EXT(proc,proctype) proc = (PFN##proctype##PROC)uglGetProcAddress(#proc,true)
	#include "gl_extensions.h"

}


// file whatever.cpp or whatever.h
#include "gl_extensions.h"

...
glActiveTexture(...);

Of course, at places you need to include gl.h and glext.h beforehand.

Soo, you want to use a given ext-proc? Just paste its name in that header-file, together with its uppercase name. Done.

a) it doesn’t require paid access, just click on free user.

b) The reason I made this is exactly because I don’t want to manually add every extension I want to use, like your method requires

a) "This file can only be downloaded by becoming a Premium member

There are no more download slots available for free users right now. If you don’t want to become a premium member, you might want to try again later."

Try MediaFire :slight_smile:

b) there are around 114 useful extension-procs. It takes <5 minutes to “manually” (or via simple regexp) add them. It takes <3 seconds to add a new one when you need it :slight_smile: . Plus, this reduces IntelliSense clutter.

Finally got a slot, and it’s nice :wink: . Does exactly what I meant by regexp. Lists all 1714 func, of which ~100 are strict GL3.x . And then, glfunc_test.cpp ouch :slight_smile: . You know, you could’ve made that into a loop ^^. And removed the AddFunctionDec()/etc string clutter.

Here’s a mirror host of that file: http://dl.getdropbox.com/u/1969613/openglForum/gl_func.rar

What do you mean?

Automation is always helpful. Thanks!
And you should parse gl3.h too.

Hey, does any one know of there is something like this for strict GL 3.2? Is Ilian’s method the best way just now? I guess 100 or so procs isn’t so much.

ijc12: Is is ok to try and edit your code to parse gl3.h? :slight_smile:

sure, you can post the results here if you like

I only looked briefly at gl3.h, I tried to compile my own (3.2 forward compatible) engine with it and it had several functions depreciated even though they shouldn’t have been. So I don’t think it’s 100% correct yet.

Cool, well I might not have time to do it until the weekend. But I’ll definitely post it here if I get it done.

I had a quick go at editing your code in glfunc to make it parse gl3.h it seems to work. there is no .exe in that zip so you need to compile it all yourself (boost is required)

i changed it so that the parsing parts go: for gl3.h

std::string gl3;
LoadTextFile("GL\\gl3.h", gl3);
IterateFunctions(gl3, GL3_H);

std::string wglext;
LoadTextFile("GL\\wglext.h", wglext);
IterateFunctions(wglext, WGLEXT_H);

std::string outPath = "glinit\\";
std::string fileName = "glfunc_test";

BuildHeader(outPath, fileName, GL3_H);
BuildCPP(outPath, fileName, GL3_H);

for glext.h

std::string glext;
LoadTextFile("GL\\glext.h", glext);
IterateFunctions(glext, GLEXT_H);

std::string wglext;
LoadTextFile("GL\\wglext.h", wglext);
IterateFunctions(wglext, WGLEXT_H);

std::string outPath = "glinit\\";
std::string fileName = "glfunc_test";

BuildHeader(outPath, fileName, GLEXT_H);
BuildCPP(outPath, fileName, GLEXT_H);

But glinit doesn’t work when you parse for gl3.h because it’s trying to get pointers to functions that are not extensions returnable from wglGetProcAddress (or maybe I am wrong? Any hints?). I’ll try and fix that this weekend, but for now here is a half working version, if anyone wants to fix it for me :slight_smile:

edit: I guess the functions it is not registering can be accessed anyway from the opengl32.lib as per normal, maybe :slight_smile:

www.phasersonkill.com/dl/gl%20func.zip

I’m no DLL expert but when you use the windows native dll functions instead of wglGetProcAdress it does seem to return non-null function pointers

e.g:


HMODULE handle = GetModuleHandle(L"opengl32.dll");

glCullFace = (PFNGLCULLFACEPROC)GetProcAddress(handle, "glCullFace");
if(glCullFace) {
	AddFunctionDec("PFNGLCULLFACEPROC glCullFace");
	AddFunctionDef("PFNGLCULLFACEPROC glCullFace");
        AddFunctionInit("PFNGLCULLFACEPROC","glCullFace");
}


So maybe that would work

so you can’t just use the non extension calls as you would from normal windows gl (is that gl 1.1?)

ijc12, you obvioulsy know more about DLLs than I do, your method worked, so I have changed your code to use a brute force method checking wglGetExtension first and then if it returns NULL checking GetProcAddress.

There is one problem with your regex, it has trouble around glGetString and so everything from glGetString to glViewport is defined incorrectly in the output code, that’s only 9 functions though :slight_smile: i fixed them by hand the and the new opengl.h/cpp seems to work on a simple example of mine.

here is the source again.
www.phasersonkill.com/dl/gl%20func.zip

Well this is the first time I’ve worked with explicit linking to a dll. Before I only used implicit linking with “.lib” files, or simple static linking to my own libraries. So the next part may contain some nonsense :slight_smile:

I’m not sure why wglGetProcAddress doesn’t return function pointers for some of those functions. As you said they are probably implicitly linked trough “opengl32.lib”, and obtaining function pointers to them would probably cause conflicts with function prototypes defined in gl.h. But since gl3.h doesn’t define any prototypes by default (?) you can’t even use these functions with implicit linking when using gl3.h.

I think it would be better to just drop the implicit linking entirely and load the dll manually and initialize every function trough
the windows DLL functions instead of using wglGetProcAddress. I was working on that today, but I ran into some problems, because a few of the basic wgl functions to establish a context etc have prototypes in wingdi.h (expecting implicit linking), so I can’t define a function pointer with the same name or I get a “trying to redefine function blabla” error :p. So yeah… I dunno. I guess the situation isn’t ideal right now.

Fortunately, there’s no reason to enforce runtime loading of those funcs via GetProcAddress() :slight_smile: .

what do you mean? which functions?

glCullFace and co.
Btw, I like the results in the “\output” folder, where the .cpp loads only ~340 procs. Maybe so far I was only seeing some intermediate results, where for each dynamically loaded proc, a string gets concatenated.
thumbs up

I tried not using GetProcAddress() for glCullface etc. and just including gl3.h in my project but it complained that glCullface wasn’t defined. Admittedly I tried it only quickly before work this morning. Using GetProcAddress() with them and the same project worked fine.
Can you please explain in more detail.

No hints Ilian? What’s the best way of accessing this stuff with gl3.h

I finally got a GL3.2 and glsl 1.5 test app up and running using this, TBH i didn’t really have to change much aside from the shader source, i can’t comment on it’s completeness.

I modified the program a little bit, the intermediate step wasn’t really necessary so I removed that. I also modified some of the regexps because of the error James mentioned.

There are now 2 executables, “glinit_gl3.exe” to generate a gl 3.2 forward compatible interface based on gl3.h

And “glinit_glext.exe” to generate a gl 3.2 compatibility profile interface based on the latest version of glext.h

http://www.megaupload.com/?d=FSUMSPHG