Extension loading mechanism

Crossbar has been integrated into the core so no problems. What I did when I used extensions was to see if nv_texture_env_combine4 was avail. If yes then I assumed crossbar is supported. Otherwise I checked the ext. string for arb_crossbar. I use my own ext. loading lib and I use gl core version(1.4) + extensions. It makes writing gl libs easier because of no dependancies like you get with extensions. I think I only use one extensions, ie. nv reg.cmbs and everything else uses gl core. The dumping to sw mode has been non-problematic. End users can always change the gfx settings to get in hw mode or you can have a bench mark running to see what mode gives best IQ and fps numbers. I kind of prefer sw fallback as I can see gfx effects that my hw doesn’t do natively.

I rewrote my original post if anyone noticed :slight_smile:

I just came across an old SGI document about extension checking. Their code is a little different from what I posted earlier, which is the only reason I’m posting the link. :slight_smile:

That is is it viable solution to skipp ext string parsing if I must check function pointers later anyway.
No, it is not a viable solution. There’s no reason not to check the extension string, and every reason to do so.

First, it costs nothing. It’s all initialization stuff that takes far less than 1ms anyway.

Second, as you point out, various platforms behave differently. Why bother having a lot of “#ifdef WINDOWS” code when you have to write it the long way for another platform anyway? Plus, as you point out, it isn’t even guarenteed to work, as many driver expose extension functions for extensions that are in development, but not meant to be used.

My current project are for win32 so:
#ifdef
–crossplatform
Beta drivers are, in my case, better than nothing, so I’d rather take a risk.
And as the code is for demonstrational purposes, I’d prefer less code for other people to read, GL version number + GLSL through fn pointers and all.

OK, OK + warning in comments :smiley:
[Case closed]

I just want to say that I’ve tried some extension loading libraries and some of them have terrible bugs that can make your app crash when you have newer versions of opengl than the one that existed when the library was done. My advice is to use only libraries when you really need it.

You know, it really wouldn’t be that hard to create a library called something like “opengl20_32.dll” and make it expose all the OpenGL functions that are part of the 2.0 API, and internally, it would LoadLibrary the opengl32 library, extract extensions, and punt/error on functions it couldn’t get.

As far as I know, none of the extensions libraries actually do it this way. I wonder why? It’d be pretty slick. #include <gl20.h> and off you go, no specific extensions references needed!

Originally posted by jwatte:
[b]You know, it really wouldn’t be that hard to create a library called something like “opengl20_32.dll” and make it expose all the OpenGL functions that are part of the 2.0 API, and internally, it would LoadLibrary the opengl32 library, extract extensions, and punt/error on functions it couldn’t get.

As far as I know, none of the extensions libraries actually do it this way. I wonder why? It’d be pretty slick. #include <gl20.h> and off you go, no specific extensions references needed![/b]
AFAIK, it’s a bit harder than that since opengl32.dll always gives you valid function pointer (ie. you don’t have to reinitialize all the addresses linked with the dll when you change of rendering context).
But if your app only ever uses one rendering context, then it is easy to do.

In my app I do it mostly this way, I include something like “opengl_1_5.h” then I only have to call opengl_1_5::initialize(); (here it’s not done automatically, because opengl32.dll initializes its own pointers when you create the rendering context and I’m not bypassing wgl calls).
The thing to remember is that it’s context specific, and when changing of rendering context you have to reinitialize it.

As for extension checking, my philosophy is to only check the version string. So I know it’s a bad idea to call opengl_1_5::initialize() when the drivers returned 1.1 :wink: .

When the drivers return 1.5 it only means that it’s compliant with OpenGL 1.5 specs, but in practice it does not implies that it supports all the core features in hardware (and sometimes, not even in software, ie GeForce 2 + multisampling).
But even so I only check the extension string for extensions that aren’t in the core features (eg anisotropic filtering).

After all, all the core features are not guaranteed to have a corresponding ARB extension in the extension string (crossbar is a perfect example, but sometimes some core features don’t even have a similar extension and have been directly introduced as core features).

With this method, the only thing that can happen is that you can use functions linked to a feature that isn’t supported (ex: compressed textures) either in hardware or software.
So your program will work (ie. it will not crash because of a null function pointer) but of course the rendering will not be correct.

Uber-checking is IMHO worthless. In the philosophy described above, if we only support 1.5 or higher, it’s not going to help us to know whether or not the hardware is really capable of handling all core features (even if it says so via the version string).
The only thing uber-checking does add is a pretty message to the user telling him he has to buy newer hardware. But then again, it’s a lot of hassle, because it’s impossible to be 100% sure about every single feature.

[quote] You know, it really wouldn’t be that hard to create a library called something like “opengl20_32.dll” and make it expose all the OpenGL functions that are part of the 2.0 API, and internally, it would LoadLibrary the opengl32 library, extract extensions, and punt/error on functions it couldn’t get.

As far as I know, none of the extensions libraries actually do it this way. I wonder why? It’d be pretty slick. #include <gl20.h> and off you go, no specific extensions references needed!
AFAIK, it’s a bit harder than that since opengl32.dll always gives you valid function pointer (ie. you don’t have to reinitialize all the addresses linked with the dll when you change of rendering context).
But if your app only ever uses one rendering context, then it is easy to do.

In my app I do it mostly this way, I include something like “opengl_1_5.h” then I only have to call opengl_1_5::initialize(); (here it’s not done automatically, because opengl32.dll initializes its own pointers when you create the rendering context and I’m not bypassing wgl calls).
The thing to remember is that it’s context specific, and when changing of rendering context you have to reinitialize it.
[/QUOTE]I have two questions about this.

  • It would be possible to make two new functions that replace wglMakeCurrent and wglCreateContext and handle context switch automatically?

  • Making a opengl20_32.dll wouldn’t introduce a new indirection level that would slow down every call?

Originally posted by martiño:
[b]

  • It would be possible to make two new functions that replace wglMakeCurrent and wglCreateContext and handle context switch automatically?[/b]
    The problem with replacing wglMakeCurrent and wglCreateContext (and others, such as wglDeleteContext) is to be sure not clashing at the link level with the Windows native version. The thing is that you still need to use native wglContext calls in the implementation of your replacement, plus the user will probably want to use the other wgl functions. So you’ll also have a problem with header conflicts if the user includes windows.h.

I think it may be possible to avoid those header/linker clashes with some macro hacks. Such as

[b]

  • Making a opengl20_32.dll wouldn’t introduce a new indirection level that would slow down every call?[/b]
    Yes, it would be slower than directly having function pointers directly from wglGetProcAddress.
    Opengl32.dll is already slower than that because of one indirection.
    Opengl20_32.dll would also add a level of indirection on native pointers from wglGetProcAddress (for gl 1.2 -> 2.0), and another level of indirection on top of opengl32.dll (for 1.0 -> 1.1, because unfortunately you cannot query the addresses for these on Windows).

But I don’t think this overhead would be a problem unless you’re still frenetically using glVertex.

  • It would be possible to make two new functions that replace wglMakeCurrent and wglCreateContext and handle context switch automatically?
    Yes, that’s quite possible. It would make wglMakeCurrent() somewhat more expensive, but it’s already very expensive so that’s not a big loss. And you could special-case the case where all currently open contexts use the same functions (which is likely to be almost always).
  • Making a opengl20_32.dll wouldn’t introduce a new indirection level that would slow down every call?
    That depends on your linkage model. On Windows, it would be reasonably cheap, if you turned all the functions into global function pointers, but remained using the regular function call syntax (yay modern syntax!).

not clashing at the link level with the Windows native version
You don’t have to link statically against the original openGL library – in fact, that would be un-wise. You can just LoadLibrary() it in the start-up of opengl20_32.dll, and extract whatever pointers you want to whatever names you with to use (say, prefix them with win32_ ).

Hi,

if it helps, I did an extension loading library generator way back 2002 for my own project. I have posted it here:

<a href=“http://www.thetenthplanet.de/extparse” target=“_blank”>
http://www.thetenthplanet.de/extparse</a>

I was simply fed of manually tracking function pointers and prototypes, so I hacked up a thing that will parse the glext.h and wglext.h files and generate the source for an extension loading lib that has all of the functions it encounters.

The generator itself is not an example of beautiful software design though :smiley:

Here is a my extension loading library, with glext.h and wglext.h parser tool. Sorry, windows only :slight_smile:

GLExtMap

yooyo