Whinge about OpenGL extension headers

This is a follow on from a post on the beginners forum - ‘Where to get OpenGL 1.2 Headers’

Something has been seriously bugging me for ages - this ludicrous situation over the various OpenGL header files. How many times is a given forum asked where to get these illusive little babies? And how many different versions of them exist? Bloody hundreds, so it seems.

I had just started to set up a series of headers for inclusion into all my openGL apps. Then I saw Lev’s post saying he’s written his own headers and a .lib loader. I was going to email him and for a copy … And I thought what the hell am I doing this for? Why is it down to each individual to re-invent the wheel for each version of OpenGL? If Microsoft said if you want to program for Windows you have to write you’re own windows.h they’d be the laughing stock of the IT world. However, this is normal for openGL programmers. What’s going on?

Why can’t the verious vendors get together and form some mechanism whereby each time new extensions are released, the headers are automatically updated and made available - immediately? The most complete set I’ve yet seen are from the Mesa3D implementation. But it shouldn’t be up to other individuals to do this work. It’s simply laziness, or totally disorganisation, which has brought this entire situation about.

How about every member of the ARB puts a couple of grand into a kitty every year to pay a contract programmer (there’s enough of 'em) to be responsible for this, and writting code to load the damn things? Company ‘A’ produces a new extension. They submit the info to this guy. He includes the stuff. Sends back to company ‘A’ for validation. Every Friday he then publishes the new header, with loading code. Firstly, everyone would be working from the same base code. Wouldn’t that be so nice? Secondly, every company’s web site could just link to a common repository (OpenGL.org?), and there’d be no ambiguity as to which files where needed. And it’s not exactly as if it’s really that much work once it’s set up.

It strikes me that this should be a mandatory requirement rather than an unreasonable request. Ok, we all know that MS deserves to be thrown out of the ARB. And quite honestly, if nvidia turned around and said that they were no longer going to support D3D, I think that API would die a death. I’m not actually suggesting they should do because the competing API’s are healthy for each other which suits us all, but it’s food for thought. But the OpenGL vendors should be making it as easy as possible for people to use OpenGL - but for newcomers it’s a total nightmare.

The reason this all started, was because I wanted headers with glCompressedTexImage2D … not glCompressedTexImage2DARB. Why not the ARB version? Because it’s now a core feature and should be exposed as such. I assume all the drivers support both version by now (I know nvidia does). But could I find them? Hell no - not until I looked at mesa on the off chance. And as to the documentation on it … well - try a search in google - you’ll find 4 entries, two of which are in Chinese, and the other two from cvs.lokigames.com!!! This isn’t exactly what you’d call proactive marketing for the API.

OK whinge over. Reading back it wasn’t exactly a well thought out argument, but I’m sure you get the idea.

Regards

The problem is that there is no higher OpenGL in windows than 1.1, meaning you’ll have to use extensions or manually load the OpenGL 1.3 function pointers.

The point I’m making is that everyone seems to be writing there own loading functions … there must be thousands of them out there now! It should be centralised!

I agree that this should be centalized, but who should do this? SGI is not that interested in OpenGL anymore (their glext.h is quite old, extension registry is updated rarely), both NVIDIA and ATI would have “problems” supporting both NV and ATI stuff. I don’t see any solution in the near future…

Some day I also thought that there are many resources where one can grab some useful extension loading code… but this is actually not the case - different projects use different extensions and since its a boring job to write the loading code people only write what they need. The only useable loading code I’ve found was NVIDIA’s glh, but it has a few problems, to name two of them: it has only NV extensions support(means no ATI) and its a part of huge SDK, and many many people around the earth only have a lame 56k connection so its not a that easy to download the SDK - especially if you don’t need the most stuff from this SDK. And the version I have(maybe outdated, dunno) has no OpenGL 1.3 support (enumerants)

I also want to use core functions instead of ARB extensions, but according to google there aren’t any opengl 1.3 header files. Thats why I’ve written a header with a “yet another loading lib” - but I tried to make it useable and included support for both NV and ATI extensions and OpenGL 1.3 enumerants and functions. And the feedback I’ve received so far has been very very positive. BTW there’s no need to mail me its on my website(profile).

Regards,
-Lev

[This message has been edited by Lev (edited 03-03-2002).]

Just the other day I was thinking of writing a tool that ‘parses’ an extension specification and generates/updates the header file automatically. This hasn’t already been done by any chance, has it?

– Tom

As I speak I’m having a break from writing my own gl/glext/loader headers, and you’re right - it’s boring. That’s why I got on my high horse yesterday - my mind was going numb.

That’s why I suggested the vendors bit the bullet and got an outsider to do this. It would make life so much easier for everyone.

Tom - I think that’s a damn fine idea - I used to generate automatic HTML from a given set of data - writing a parser as you suggest wouldn’t actually be that difficult/different. Especially for the reason I’ve been putting this off for ages - give it two weeks or so and it’ll need updating, ad infinitum. Is there a web collection of function names/enumerants already out there? That’s probably wishful thinking … but ya never know

EDIT - I want to include ATI stuff too. I have plenty of resources on nvidia stuff, but diddly squat on ATI. It’s not like I can even test on ATI to make sure it all works!!!

[This message has been edited by Shag (edited 03-04-2002).]

actually, tom, thats the way nvidia generates its extension-headers

they have some sort of script in this way:
GL_DAVEX_MY_BIG_EXTENSION
{
GL_DAVEX_ENUM0 = 0xblah;
GL_DAVEX_ENUM1 = 0xblah+1;
glMyBigExtensionFunc1fDAVEX(GLfloat);
glMyBigExtensionFunc2fDAVEX(GLfloat,GLfloat);
}

for guys that like script-parsing that could be easily done i guess (ok, the 0xblah+1 is not that usefull i guess ) to convert that to a headerfile…

good luck would be cool…

oh, and dont forget to include the

GL_VERSION_1_3 {
}

and GL_VERSION_2_0 {
}
parts to parse!

would be cool…

Having “centralised” header would be very good, of course.
If we cant count on IHVs, then what about some Source Forge project?

Before it happens, a bit of “manual parsing” + preprocessor trick can simplify adding new extensions.
You can type info on each function once into single file and reuse it, instead of repeating it 4 times (in typedef, declare ptr, define ptr and wglGetProcAddress)

Create 3 files:

  1. gl_ext_private.h

  2. gl_ext.h

  3. gl_ext.c

  4. gl_ext_private.h

#ifndef GL_EXT_DECLARATION
#error Do not include this file directly.
#endif

GL_EXT_DECLARATION(GLvoid , glVertexAttrib3fNV , (GLuint index, GLfloat x, GLfloat y, GLfloat z))
GL_EXT_DECLARATION(GLvoid , glCombinerParameterfvNV , (GLenum, const GLfloat *))
GL_EXT_DECLARATION(GLvoid , glDrawRangeElementsEXT , (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *))
GL_EXT_DECLARATION(GLvoid , glUnlockArraysEXT , (GLvoid))
GL_EXT_DECLARATION(GLboolean , glTestFenceNV , (GLuint fence))
GL_EXT_DECLARATION(WGLvoid*, wglAllocateMemoryNV , (WGLuint size, WGLfloat readfreq, WGLfloat writefreq, WGLfloat priority))
...
// for obvious reasons i omit rest of functions here      [img]http://www.opengl.org/discussion_boards/ubb/wink.gif[/img]
// the rule is simple:
// GL_EXT_DECLARATION( <return_type> , <function_name> , <argument_list> )
// where <argument_list> is surrouned with additional braces.

#undef GL_EXT_DECLARATION

The file is “private”, because it should not be #included directly by user. It should contain nothing else but declarations in above form.

Do not put any definition of the GL_EXT_DECLARATION macro there, because it must be #defined just before #including, and #undef’ined just after.

Do not add directives at top & bottom of file like these:
#ifndef XXX
#define XXX
(…)
#endif
because the file must be #included several times with different definitions of GL_EXT_DECLARATION macro.

  1. gl_ext.h
    This is the file to be #included by user.
// declare function pointers and define their types:
#define GL_EXT_DECLARATION(_RetType_, _glFnName_, _ArgList_) \
typedef _RetType_ (APIENTRY* _glFnName_##_t) _ArgList_; \
extern _glFnName_##_t _glFnName_;
#include <gl_ext_private.h>

// call it once in your code:
void InitGLExtensions();

// paste #definitions of extensions' tokens here
  1. gl_ext.c
// this will define function pointers:
#define GL_EXT_DECLARATION(_RetType_, _glFnName_, _ArgList_)  _glFnName_##_t _glFnName_;
#include <gl_ext_private.h>

// and this will load function addresses:
void InitGLExtensions()
{
#define GL_EXT_DECLARATION(_RetType_, _glFnName_, _ArgList_)  _glFnName_ = (_glFnName_##_t)wglGetProcAddress(#_glFnName_);
#include <gl_ext_private.h>
}

[This message has been edited by Carmacksutra (edited 03-04-2002).]

[This message has been edited by Carmacksutra (edited 03-04-2002).]

[This message has been edited by Carmacksutra (edited 03-04-2002).]

[This message has been edited by Carmacksutra (edited 03-04-2002).]

I’ve been working on a parser that takes the extension specs directly off the opengl registry site, to create header and cpp files which define function prototypes, function pointers, and constants. It also has a function to initialise all the function pointers, querying the wgl and gl strings to find out if they are supported etc.
It’s a tricky task (made annoying by the definition of things like GL_ARB_multitexture, which have now been given useful empty definitions on the registry site), but when it’s done, I’ll put the lib and source code on my companies web site, so you can all download it.
Only trouble is, the registry is not being kept fully up to date - but there is an option in my program for manually adding spec text files yourself - means you’ll have to do your own (mostly empty) spec for the extension you want to support.

Oh, btw, it’s dialog driven, and I’ve settled on MFC because I’m most familiar with it - sorry linux/irix users…maybe you can alter the source code to work on those platforms (use, say, java for the dialog - or make it command line)

I thought I’d just throw my code into the open as well

gl_extensions.h:

//'extern' function pointer declaration for use in headers
#define FP_DECLARE(name,ret,parms) typedef ret (APIENTRY *FP_##name)##parms;\
	extern FP_##name name
//example:
// the following two lines:
//	typedef void (APIENTRY *FP_glLockArraysEXT)(GLint,GLsizei);
//	extern FP_glLockArraysEXT glLockArraysEXT;
// get replaced by:
//	FP_DECLARE(glLockArraysEXT,void,(GLint,GLsizei))

//FP_DEFINE will be used in the .cpp file that wants to export the function pointer
#define FP_DEFINE(name) FP_##name name=NULL
//the '=NULL' thingy is merely a safeguard against stray pointers
//example:
//  FP_glLockArraysEXT=NULL;
// can be abbreviated like this:
//  FP_DEFINE(glLockArrays);
//a macro that ties in wonderfully with the function pointer macros to help querying GL extensions
#define GL_FP_GRAB(name) (name=(FP_##name)wglGetProcAddress(#name))

bool grab_extensions();

FP_DECLARE(glActiveTextureARB,void,(GLenum));
FP_DECLARE(glMultiTexCoord2fARB,void,(GLenum,GLfloat,GLfloat));
FP_DECLARE(glFogCoordfEXT,void,(GLfloat));

This gives me typedefs for the function pointers, extern declarations, matching definitions (including NULLing of the pointers) and an importer macro.

As you can see, this is similar to what Carmacksutra suggests. I find it a bit easier to check for errors with this approach. OTOH I need to specify each extension function seperately, but the macros sure cut down on typing

gl_extensions.cpp:

#include "gl_extensions.h"

FP_DEFINE(glActiveTextureARB);
FP_DEFINE(glMultiTexCoord2fARB);
FP_DEFINE(glFogCoordfEXT);

bool
grab_extensions()
{
	if (GL_FP_GRAB(glMultiTexCoord2fARB)&&
		GL_FP_GRAB(glActiveTextureARB)&&
		GL_FP_GRAB(glFogCoordfEXT))
	{
		int tex_units;
		glGetIntegerv(GL_MAX_ACTIVE_TEXTURES_ARB,&tex_units);
		if (tex_units>=2) return(true);
	}
	return(false);
}

[This message has been edited by zeckensack (edited 03-05-2002).]

Originally posted by Lev:
Thats why I’ve written a header with a “yet another loading lib” - but I tried to make it useable and included support for both NV and ATI extensions and OpenGL 1.3 enumerants and functions.

Lev,

It seems you do not check the existence of the functions you declare. With NVidia’s gl.h (installed by the driver, on Linux), I get hundred of errors like this:

In file included from extgl.c:75:
extgl.h:346: glBlendColor' redeclared as different kind of symbol /usr/include/GL/gl.h:2066: previous declaration of glBlendColor’

Julien.

Originally posted by Carmacksutra:
[b]

[quote]

GL_EXT_DECLARATION(WGLvoid*, wglAllocateMemoryNV , (WGLuint size, WGLfloat readfreq, WGLfloat writefreq, WGLfloat priority))

#define GL_EXT_DECLARATION(RetType, glFnName, ArgList) glFnName = (glFnName##_t)wglGetProcAddress(#glFnName);

[/b][/QUOTE]

Hey, don’t forget us, in the bright glX side

Julien.

[This message has been edited by deepmind (edited 03-05-2002).]

What would be ideal would be a decent database system which listed all parameters for each function, including all the enumerants. Not only would this make life very simple to generate headers etc - it would also be a great learning tool. Just look up a function and see exactly what you can do with it …

Originally posted by deepmind:
[b] [quote]

In file included from extgl.c:75:
extgl.h:346: glBlendColor' redeclared as different kind of symbol /usr/include/GL/gl.h:2066: previous declaration of glBlendColor’

Julien.[/b][/QUOTE]

It doesn’t work with Linux yet. I’ll improve that as soon as I have some time to install linux (I blew up my linux installation).

-Lev

Originally posted by Lev:
[b] [quote]

In file included from extgl.c:75:
extgl.h:346: glBlendColor' redeclared as different kind of symbol /usr/include/GL/gl.h:2066: previous declaration of glBlendColor’

It doesn’t work with Linux yet. I’ll improve that as soon as I have some time to install linux (I blew up my linux installation).

[/b][/QUOTE]
In order to get rid of those conflicting declarations, you can use macro shadowing. e.g.:

… (declare function glBlendColorLEV()) …
#define glBlendColor glBlendColorLEV

This should work everywhere, assuming you don’t permit anyone to include gl.h or glext.h directly.

Julien.

Actually one only needs to check if opengl_1_2 or opengl_1_3 are defined, and if yes do not redefine the 1.2 and 1.3 functions.

-Lev

[This message has been edited by Lev (edited 03-05-2002).]