PDA

View Full Version : Extension loading mechanism



M/\dm/\n
09-15-2004, 01:24 AM
I'm just qurios how to solve this problem better. So far I've been parsing extension string, getting pointer adresses & then checking them against NULL. But as far as I know some extensions in some driver revisions are absent in ext string, though returns valid function pointers via wglgetprocaddr are fully functional.
I have few apps that I have to hand over & I'm thinking about different ext loading routine.
I could just call getprocaddr for all the function pointers & check them against NULL without parsing EXT string. If ext pointer != NULL go ahead, else swear or crash with flames... :rolleyes:
And you can allways blame user for using old drivers :very evil:

dorbie
09-15-2004, 03:12 AM
That is an acceptable approach. If you get a pointer you can call the function, just make sure you call it with the context you intend to use the function with active. It is absolutely critical that you have the valid context active.

I remember reading that in at least one case NVIDIA won't publish/advertised extensions although they are implemented (I took this to mean excluding extension strings from the driver) the example I have in mind is ARB_env_crossbar, but the reason offered for this seemed trivial, in this particular case a difference in behavior with bad texture parameters (white vs undefined results). I may have been wrong in my interpretetion of the phrasing used in the note I read, but it seemed that extension strings might be omitted despite being ostensibly supported if the functionality wasn't entirely conformant with the spec.

sqrt[-1]
09-15-2004, 03:43 AM
I would be cautious doing this. Nvidia have been known to implement entry points for "work in progress" extensions.

BTW: I think that ARB_tex_env_crossbar issue was resolved when it was integrated into the core. (Although the extension is still not displayed)

idr
09-15-2004, 07:16 AM
NO NO NO NO!!!!!!!! If it's not in the extension string or "implied" by the version string, do not use the functionality. Period. While just relying on wglGetProcAddress returning non-NULL may happen to work on some drivers, it's not guaranteed to always work. Not only that, it will not port to other platforms. For example, glXGetProcAddress never returns NULL on Linux. So, you could do 'glXGetProcAddress("glFooBarStinkyPants")' and get a value, but you'd better not call that pointer...

There is a published, supported way to test for extension support. Is it really worth potential pain in the future to be lazy and hack around it now? App developers doing pointless, lazy crap like this makes users think OpenGL is garbage.

Please read a good description (http://www.gamedev.net/reference/articles/article1929.asp) of how to properly use the OpenGL extension mechanism, or please consider using of the of the many freely available (http://glew.sourceforge.net/) , extension (http://elf-stone.com/downloads.php#GLee) loading (http://trenki.50free.org/extgl/) , libraries (http://www.julius.caesar.de/oglext/) . If you don't like any of those, I'm sure you can easilly find (http://www.google.com/search?q=OpenGL+extension+loading+library&sourceid=mozilla-search&start=0&start=0&ie=utf-8&oe=utf-8) some more...

M/\dm/\n
09-15-2004, 09:10 PM
It just seem to be overkill to do double check. What's even more important, your app could skip extension in case something like ext string trim is on (in NV control panel for example). Linux is not in question for given app, though it's a good point you mentioned.

When do we get that glIsExtensionSupported() stuff, seems to be easy to implement even on Diamond or S3 Virge???

[PS]
As far as I know (via Opengl ext viewer) env_crossbar is in core since 1.4. And it's absent in few latest drivers for FX5900, though I remember that it was in ext string some time ago. Is it there under X?

Gong
09-15-2004, 10:45 PM
The NV_texture_env_combine4 extension provides nearly identical functionality to functionality that the ARB_texture_env_crossbar extension provides.
Unfortunately, the ARB_texture_env_crossbar's semantic for what happens when a texture environment stage references a disabled texture does not match NVIDIA's NV_texture_env_combine behavior.
Due to the differing semantics and in order to maintain backward application compatibility and compatibility with the NV_texture_env_combine4 specification, NVIDIA will never advertise the ARB_texture_env_crossbar extension.
The ARB_texture_env_combine semantic is:
Texture blending should be disabled on the texture unit that is referencing the invalid or disabled texture.
The NV_texture_env_combine4 semantic is:
If the <n>th texture unit is disabled, the value of each component is 1.
Fortunately, this semantic is not particularly relevant for most applications because applications typically avoid sourcing a disabled, inconsistent, or invalid texture unit.
NVIDIA recommend that if your application sources other texture units using the GL_COMBINE_ARB texture envionment mode, you first determine that either ARB_texture_env_crossbar or NV_texture_env_combine4 are supported. Then do not assume a particular behavior when sourcing other texture units with GL_COMBINE_ARB environment that are disabled or invalid.
OpenGL 1.4 codifies this practice by integrating the ARB_texture_env_crossbar functionality into the core OpenGL standard.
The OpenGL 1.4 standard says: "If the texture environment for a given enabled texture unit references a disabled texture unit, or an invalid or incomplete texture that is bound to another unit, then the result of texture blending are undefined."

Obli
09-16-2004, 04:30 AM
Originally posted by M/\dm/\n:
When do we get that glIsExtensionSupported() stuff, seems to be easy to implement even on Diamond or S3 Virge???I also would like to know it. Not in the sense I'm interested - my app does not use a fixed buffer and I don't see a good reason to upgrade to the extension (unless the extension string gets 'deprecated' but I guess this won't happen) - but I wonder why it's still not present in the drivers.

Maybe the fact that you have to check the extension string to see if this is supported holds implementors back.
In fact this severely limitates extension usefulness and usability.

Tom Nuydens
09-16-2004, 07:23 AM
Originally posted by Obli:
In fact this severely limitates extension usefulness and usability.glIsExtensionSupported()? Oh puh-lease! We're talking about 25 lines of code here :rolleyes:

-- Tom

idr
09-16-2004, 09:01 AM
The IsExtensionSupported stuff was considered for 2.0, but was dropped. It was dropped because it won't help existing apps that are already broken (and there are lots of them), and new apps can just use one of the numerous extension loading libraries, look at how GLUT does it, etc. The decision was to help people not write buggy code instead of putting a band-aid on the API. That's what I'm trying to do right now. :)

Madman: If you consider writing applications that actually conform to the APIs you are using "overkill", then I really feel sorry for the people using your apps. That may sound harsh, but if you're too lazy to check the frickin' extension string...sheesh!

M/\dm/\n
09-16-2004, 10:14 AM
It's not that I am that lazy, but it just so annoying to add all the frickin stuff of ext loading to every project I make. Especially it gets annoying in case of short demo programs. I don't like the way nvidia is demonstrating cool stuff, because all of the key elements are in some shared/util/stuff files/dirs & it takes quite some time to get to idea. Best example - pbuffer demo in SDK - if you open main file you'll notice that all pbuffer initialization & stuff is somewhere in /shared/utils or smthn.
Well I have written one function that doesn't use fixed buffer & is easy to call ( checkExt("glStuff") ; ) , but it is annoying to copy it to every freakin demo. Even more if I can bypass this $hit & it has worked fine so far.
From my point of view dropping IsExtension supported is realy dumb idea. It could saved some copy/paste time & a lot of extra explanation to people that are looking at the main idea of your code. But nop, well just keep explaining beginners not to use that and this and reserve sapce for that because that is so. IsExt approach could have even saved extra WGLext stuff.
Concerning libraries, they are usually bloated & I prefer using clean GL, where I am responsible for all the stuff going around, moreover I don't want to go all the licencing process in case of commercial app.
Concerning backward compitability I just don't see why it should be any issue. Apps like Doom3 can easily call glIsExtSupp, because all the hw that supports shaders is supported with drivers enough to have this function. S3 wouldn't run that stuff anyways. On the other hand if you are writing frickin balls w lighting, then it's up to you to think that someone with Microsoft generic renderer could run the code (and I guess you are aiming at that audience there too), though if you are writing on new hardware ball tesselation will kill performance on old HW fast enough, so you will have to test on peace o' crap anyway to spot all the errors & FPS there. And string doesn't need to be removed, so old apps should be fine.
All we need is one extra comment: "if you intent to use this f/n remember that peace o' crap might not suport it"

It not that much work to check this stuff everytime, but it is annoying for me & i think glIsExtSupported could have made it better. And after 2 years it would be ideal way to check stuff.

That is my point of view.

dorbie
09-16-2004, 11:16 AM
This situation is slightly ridiculous (crossbar on NVIDIA anyone?), geeze.

P.S. and idr it's not about laziness, you think he doesn't check strings now? You think it takes any real *work* to do this, even if it did there's scores of free examples you could cut 'n paste.

Some engineers care about their code and instinctively hate redundancy & code like this. Objections have nothing to do with the actual labor involved. Even if you find the string you have to also check the pointer to be safe even if it *should* be there according to the string.

Korval
09-16-2004, 01:05 PM
Concerning libraries, they are usually bloated & I prefer using clean GL, where I am responsible for all the stuff going aroundSo, let me make sure I understand this fully. You don't want to use external libraries, but you're willing to use OpenGL (which, btw, is a library). Why do you choose some libraries and not others? And, more importantly, why are you complaining about a problem that others have already solved, simply because you don't like their solution?

Oh, and the whole "IsExtensionSupported" nonsense is an extension, so you'd still have to querry it. It is, also, a very simple piece of code that can be written in 5 minutes by any competent programmer, and there are a number of libraries out there with said code in them.

Complaining about a solved problem just because you choose not to use the solution is silly.


moreover I don't want to go all the licencing process in case of commercial app.Then pick a library that doesn't have a license of any significance.

dorbie
09-16-2004, 02:03 PM
The "isextensionsupported" querry is unquestionably redundant, I can't believe this was seriously proposed by anyone especially considering it'd take a querry to use it. It's 3 lines of code and I doubt it would take 5 minutes if you knew about strstr. There is a serious point about under the table functions to be made here.

Portability is a secondary issue, the windows spec says that wglGetProcAddress should return NULL when it does not succeed, moreover functionality deliberately exists in some implementations that is not supported in the strings, so you can bash madman all you like but he has a point.

I can call wglgetprocaddress and an implementation can return a valid function pointer (instead of NULL which is the correct return for failure) and the folks who implement this and explicitly exported that entry point say "don't call that function it's Lazy sloppy code". Well it might be lazy & sloppy code but it's not the developer that's being lazy and sloppy especially when they know darned well that some of them work and are exported for a reason 'nuff said.

idr
09-16-2004, 03:11 PM
Several of the popular extension loaders use a BSD-like license which allows royalty-free use in commercial apps.

Given the ready availability of extension string testing code, if a person can't be bothered to write:


GLfloat version = atof( glGetString( GL_VERSION ) );

if ( glutIsExtensionSupported( (GLubyte *) "GL_ARB_texture_env_crossbar" )
Then what do you call it if not lazy? :confused: After all, some extensions don't add any functions, so you need that code around anyway! How else do you determine if you can use GL_ARB_texture_non_power_of_two, GL_NV_texture_rectangle, GL_ATI_texture_env_combine3, GL_ARB_texture_env_dot3, etc., etc., etc...

dorbie
09-16-2004, 03:55 PM
Or just use this:


char *isExtensionSupported(const char *extstring)
{
static char *str = NULL;
if (!str) str = (char*) glGetString(GL_EXTENSIONS);
return = strstr(str, extstring);
}How is it lazy? Look the code is there they can cut 'n paste it, it ain't laziness and they don't have to link to any lib.

Calling an objection lazy misses the point, the real issue is confusion caused by wglGetProcAddress calls returning non NULL values for functions that glGetStrings says aren't supported. THAT is the heart of problem and you'll see that clearly if you read his very first post.

yooyo
09-16-2004, 04:08 PM
How about wglAllocateMemoryNV? This function doesn't belong to any extension!!! Actually it belong to WGL_NV_vertex_array_range but this extension are not listed in extension string!!! It might be a driver bug. Using this function app can allocate GPU memory and use for old fashion transfer (with fences). If I use standard approach (check for ext and the map entry points (if any!?)), I'll never get wglAllocateMemoryNV entry point.

Because of that I have made small app that parse glext.h and wglext.h and generate cpp code to map ALL known entry points. Then I check all known extension is it supported and store result in one big structure with bool variables for each known extension. App need to check is some variable true or false before using some extensin feature.

Every few weeks Im checking for new updated glext.h and wglext.h file on OpenGL registry page and regenerate cpp ext mapping file.

If someone like this approach I can send this app for free.

yooyo

dorbie
09-16-2004, 04:09 PM
err... that's a wgl extension. It shouldn't be listed in the OpenGL extension strings (or maybe it should for compatability, but that's probably limited to older stuff, the one you mention is relatively recent).

Try wglGetExtensionsStringEXT, although you probably have to query for that (in the gl string?) ... sigh \/\/\/.

tranders
09-16-2004, 05:21 PM
Originally posted by dorbie:
Or just use this:


char *isExtensionSupported(const char *extstring)
{
static char *str = NULL;
if (!str) str = (char*) glGetString(GL_EXTENSIONS);
return = strstr(str, extstring);
}How is it lazy? Look the code is there they can cut 'n paste it, it ain't laziness and they don't have to link to any lib.A simple strstr lookup isn't sufficient for a reliable lookup because several extension names are substrings of other extension names. Take for example the following extensions:

GL_EXT_texture_env_add
GL_EXT_texture_env_combine
GL_EXT_texture_env_dot3
GL_EXT_texture_env

A strstr lookup for "GL_EXT_texture_env" would find the first extension in the list. Adding a space at the end of the name would work unless the extension is at the end of the list and there is no trailing space. The lookup mechanism is a bit more complicated considering the fact that the extension list is vendor supplied and there are no guarantees about what's supported and what's not.

A quick scan of the registry shows that the following extension names are substrings of other, longer (and probably newer) extension names:

GL_ARB_fragment_program
GL_ARB_shadow
GL_EXT_pixel_transform
GL_EXT_texture
GL_EXT_vertex_array
GL_NV_fragment_program
GL_NV_register_combiners
GL_NV_texture_shader
GL_NV_vertex_array_range
GL_NV_vertex_program
GL_SGIX_async
GL_SGIX_pixel_texture

My motto is to go the extra mile and make sure your code is going to work even when the vendor's driver doesn't follow the specs.

tranders...

tranders
09-16-2004, 05:37 PM
Originally posted by idr:
The decision was to help people not write buggy code instead of putting a band-aid on the API. That's what I'm trying to do right now. :) IMO, if a function were provided that performed a reliable check for the existence of a fully supported extension then everyone's parsing task would be greatly reduced and buggy code could easily be eliminated. Of course you would still have to query for the IsExtensionSupported function :( Parsing the extension string is reasonably easy, but definitely not without its pitfalls.

tranders

Korval
09-16-2004, 06:56 PM
How about wglAllocateMemoryNV? This function doesn't belong to any extension!!!Yes, it does. It belongs to NV_vertex_array_range. Check the VAR spec.

Brolingstanz
09-16-2004, 07:44 PM
hey guys, here's some code that's been around since ... well, for a while anyways:

http://www.opengl.org/resources/tutorials/sig99/advanced99/notes/node395.html

:)

M/\dm/\n
09-16-2004, 08:34 PM
If I recall correctly strstr is very poppular approach in string checking. I've seen it in a lot of places, & I doubt it'll mysteriously go away, though lets hope it will.

It's bad that other OS'es returns not NULL...

BTW I'm still not convinced to add *.lib to project options + check for available *.dll or smthn else for other OS just to check extension string.

dorbie
09-16-2004, 09:53 PM
You're right strstr is *very* popular for this kind of thing, it's even used in the article idr recommended as doing "the right thing" TM.

http://www.gamedev.net/reference/articles/article1929.asp

:)

dorbie
09-16-2004, 10:00 PM
Sqrt, you're right about the crossbar thing getting resolved when put into the core, the spec was changed to say that invalid params produce undefined results instead of white, and obviously the extension string isn't needed when the core version is sufficient.

Hampel
09-16-2004, 10:38 PM
@dorbie: but I only check for the extension string and not for the OGL version number. this is because most drivers provide their hardware supported extensions via the ext string in additon to the OGL version number. But if an extension is not provided in the ext string you could assume it is not supported in hardware and using it will hit a software pass (e.g., GL_ARB_clamp_to_border on GF4MX :mad: )...

dorbie
09-16-2004, 11:42 PM
@Hampel, that is the way it is supposed to work, however there have been examples in the past where this is explicitly not the case, and not just for beta exotic new stuff.

tranders
09-17-2004, 04:22 AM
Originally posted by dorbie:
You're right strstr is *very* popular for this kind of thing, it's even used in the article idr recommended as doing "the right thing" TM.

http://www.gamedev.net/reference/articles/article1929.asp

:) I didn't read that article, but the following statement is in the section discussing extensions:


... One thing you need to watch out for, though, is accidentally matching a substring. For example, if you're trying to use the EXT_texture_env extension, and the implementation doesn't support it, but it does support EXT_texture_env_dot3, then calling something like:

strstr("GL_EXT_texture_env", extensionsList);

is going to give you positive results, making you think that the EXT_texture_env extension is supported, when it's really not. The CheckExtension() function in the demo program included with this article shows one way to avoid this problem.

You will note that the CheckExtension() function does NOT use strstr, so I would not recommend that anyone use that method if they want to avoid bugs in their application as was first stated.

--tranders

P.S. Note that in the quoted example the author has inverted the strstr arguments and should read as:


strstr(extensionsList,"GL_EXT_texture_env");

yooyo
09-17-2004, 05:10 AM
Originally posted by Korval:

How about wglAllocateMemoryNV? This function doesn't belong to any extension!!!Yes, it does. It belongs to NV_vertex_array_range. Check the VAR spec.Well, take a look in wglext.h and you'll see it belong to WGL_NV_vertex_array_range.
WGL_NV_vertex_array_range are not listed in WGL ext list returned from driver.

yooyo

Korval
09-17-2004, 09:19 AM
Well, take a look in wglext.h and you'll see it belong to WGL_NV_vertex_array_range.The header is meaningless; the extension specification tells you where things come from.

dorbie
09-17-2004, 10:34 AM
tranders, sorry you're right, I didn't read the article either, I just did a quick grep for strstr without checking the context. My bad, still I've seen plenty of examples similar to mine.

idr
09-17-2004, 11:39 AM
You can use strstr, and I think glutIsExtensionSupported does. You just have to check that the string returned by strstr exactly matches the desired string. In terms of lines of code, this is about the shortest, correct (I haven't actually tested this code, caveat emptor) function I can think of.

</font><blockquote><font size="1" face="Verdana, Arial">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">GLboolean is_ext_supported( const char * ext_wanted, const char * ext_string )
{
const size_t len = strlen( ext_wanted );
while (ext_string != NULL) {
ext_string = strstr( ext_string, ext_wanted );
if ( ext_string != NULL ) {
if ((ext_string[len] == '\0')

M/\dm/\n
09-17-2004, 11:40 AM
Yup, I forgot about extensions that doesn't use fn's, like: BGR, CUBE_MAP. There is no way but to parse string. After thinking more I can imagine why API check could have been dropped. Unfortunately there are some things that just can't be fixed under OpenGL, usually they are ones that should have been there from the very beginning. I hope that this trend will never make GL too broken to fix.

However, I will skip extension test for things like GLSL (4 extensions), NV texture combiners etc. under Win32, as it seem to be overkill to do 4x check.
GLSL case:
the rigght way
1)Check GLSL support
2)Check SHO support
3)Check VSHO support
4)Check FSHO support
//get pointers
4)Check for NULLS
the wrong (my) way
//get pointers
1)Check for NULLS

Might get little bit more complicated when SHLANG 1xx comes out

idr
09-17-2004, 11:42 AM
Sigh...


GLboolean is_ext_supported( const char * ext_wanted, const char * ext_string )
{
const size_t len = strlen( ext_wanted );
while (ext_string != NULL) {
ext_string = strstr( ext_string, ext_wanted );
if ( ext_string != NULL ) {
if ((ext_string[len] == '\0') OR (ext_string[len] == ' ')) {
return GL_TRUE;
}
else {
ext_string += len;
}
}
}

return GL_FALSE;
}

M/\dm/\n
09-17-2004, 12:06 PM
Thanks that's exactly what I am using for years now ;)

Hampel
09-17-2004, 12:09 PM
shouldn't it be:

if ((ext_string[len] == '\0') OR (isspace(ext_string[len]))) {

idr
09-18-2004, 06:26 PM
Hample,

Using isspace would work, but the spec is clear that only spaces are used to separate extension strings. At the top of page 254 (page 268 of the PDF) of the 2.0 spec says:



The EXTENSIONS string contains a spec separated list of extension names (the extension names themselves do not contain any spaces).
Since it says "space separated" and not "white space separated", it is safe to assume that only the ASCII space character is used.

knackered
09-19-2004, 08:34 AM
Wow, how pointless was that thread?
Now I feel empty inside.

Obli
09-20-2004, 02:54 AM
Originally posted by Tom Nuydens:
glIsExtensionSupported()? Oh puh-lease! We're talking about 25 lines of code here :rolleyes: I meant to say that it does not solve the problem of having to parse the extension string manually. Since it is an extension, you have to read it from the string and then init.
So, apps with fixed-buffers (which are crashing now) still crashes while apps wich manage the ext string correctly probably won't use the extension at all.

As dorbie says, it's redudant. I would also add that sometimes, some string cooking may be needed so, for example to split the string in substrings and compile (in the sense of showing) a list of supported extensions.

As for the extension-loading libraries, I don't like them. More in general, I don't want to link to external libaries unless they are hard to implement. For example, I use my own extension loading procedures but I happly link to libvorbis.
I raccomand everyone to have the ext-loading mechanism in the program and not in an extenral library. Sure it's grunt work but someone must do it.

By the way, why this is in advanced?

rgpc
09-20-2004, 03:57 AM
Just use GLEW and be done with it (or one of the other extension loaders).


glewInit();
if ( GLEW_ARB_texture_env_combine )
// Do stuff....

M/\dm/\n
09-20-2004, 04:25 AM
This thread is not even beginner anymore, just a BS.

I wanted to know what's professionals point of view in case of extension loading. That is is it viable solution to skipp ext string parsing if I must check function pointers later anyway.

ANSWER:
Yes I can if I use WIN32 as it allways returns nulls in case of unsupported extensions, from FM. Results can be that app may crash if ext is still in debug phase, or it may work fine even when string says it shouldn't.
If I use Linux, MAC or something else, it might not work (must RTFM)
If extension doesn't have functions then I must parse the string anyway.
Checking for GL ver number might kick you in the *** as NV supports GL1.5 but doesn't have crossbar. Still If I would call for fn pointers I'd get them (I guess) & this stuff would work with one exception (if I have a bug in my program) output can get white which is not undefined as undefined may mean it can be red, mixed or nothing...

JD
09-20-2004, 09:37 AM
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 :)

idr
09-23-2004, 12:33 PM
I just came across an old SGI (http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi/0650/bks/SGI_Developer/books/OpenGLonSGI/sgi_html/ch05.html#id19561) 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. :)

Korval
09-23-2004, 02:29 PM
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.

M/\dm/\n
09-23-2004, 09:34 PM
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 :D
[Case closed]

martiño
09-25-2004, 05:13 PM
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.

jwatte
09-25-2004, 06:03 PM
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!

GPSnoopy
09-26-2004, 05:13 AM
Originally posted by jwatte:
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.

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 ;) .

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.

martiño
09-26-2004, 08:11 AM
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.
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?

GPSnoopy
09-26-2004, 09:59 AM
Originally posted by martiño:

- It would be possible to make two new functions that replace wglMakeCurrent and wglCreateContext and handle context switch automatically?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


- Making a opengl20_32.dll wouldn't introduce a new indirection level that would slow down every call?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.

jwatte
09-27-2004, 02:39 PM
- 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 versionYou 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_ ).

Christian Schüler
09-28-2004, 02:52 PM
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>
(http://www.thetenthplanet.de/extparse)

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 :D

yooyo
09-29-2004, 04:31 AM
Here is a my extension loading library, with glext.h and wglext.h parser tool. Sorry, windows only :)

GLExtMap (http://rttv.users.sbb.co.yu/extmapper.zip)

yooyo