IntroductionWith the happy release of the new glsetup program, as well as full drivers for Voodoo1 and Voodoo2 chipset cards, it is a most frabjous day for would-be OpenGL game developers. There's only one hitch - notice I said "full drivers", not "a full ICD". At the time I write this Matrox has just released its final ICD for G200 and G400 cards, and as far as I can tell every single 3D card of any consequence now has full OpenGL support. And I do mean of ANY consequence, in the course of supporting my Azteroidz OGL rendered game, I've yet to find a 3D card I can't get the game running on. The ProblemSupporting hardware acceleration with OpenGL is normally as easy as writing an OpenGL program; if the user has 3d hardware, then it will be used to accelerate OpenGL programs via its OpenGL ICD. Enter the problem: the ICD driver was designed long before the introduction of the Voodoo1 and it really wasn't meant for supporting more than one graphics card (ie a separate 3D card and 2D card for example). Therefore it is *IMPOSSIBLE* to have an ICD driver for cards that meet this criteria. Enter the Voodoo1/2 cards, they do have a full OpenGL driver, named 3dfxvgl.dll, but it is not an ICD and as such will not be supported by linking your application to opengl32.lib. So how does an ICD work? Not so fast my eager reader - first some fundamentals. OpenGL drivers on windows machines are implemented as a DLL named (appropriately enough) OpenGL32.dll. Every 32-bit windows OS comes with this DLL (except the very original Win95 retail edition, for which it is available as a free download from Microsoft). This is the MS software OpenGL renderer, which is a full implementation of OpenGL 1.1. Now, when you clunk in that favorite 3D card and install the drivers for it, it also installs another OpenGL driver which is named differently depending on your card, (as am example - in the case of my RivaTNT its something like nvogl.dll) it also updates the registry to tell the system that an ICD has been installed and what the name of the ICD dll is. So enter an OpenGL program, it loads OpenGL32.dll when it starts (automagically because it was linked to opengl32.lib), and when it makes OpenGL function calls they are directed at the OpenGL32.dll, which in turn forwards them on to the ICD driver. The SolutionThe solution to this problem is *NOT* to bind your program to OpenGL32.lib. Instead you must manually load the correct driver - either 3dfxvgl.dll in the case of a Voodoo1 or Voodoo2 card or opengl32.dll in the case of everything else. The Details When I sat down to make this whole process work for my Azteroidz game, there were a few things that I wanted:
So I banged out some code, it seemed to work, and I released a new version of Azteroidz. Shortly thereafter the problem emails started trickling back, it seems I had overlooked something. That something was the fact that some GDI calls (SwapBuffers for example) themselves call WGL OpenGL functions internally. Therefore if you are using a OpenGL driver named opengl32.dll you must call the GDI functions, and if you are not using a driver named opengl32.dll you must NOT call the GDI functions. The Source code: OpenGL.h For the latest code, go here. Using the OpenGL moduleUsing the module is really simple, just stick to the following steps:
You're probably thinking that this doesn't sound all the simple, but really it is. As an example I've also included a quick spinning cube OpenGL program to give you a working example. Sample code that uses the other sample code: gldemo2.c Comments on the sample code GLDemo2.c actually demonstrates quite a few different things in addition to dynamic-loading of the opengl driver, starting with full-screen mode (which judging by how often this question is asked in the opengl newsgroup, oughtta make it worth a look-see for most people right there). Hopefully the code itself is fairly self-explanatory, I've tried to comment it fairly well. What it doesnt demonstrate well however, is how to setup a proper camera. Those of you more familiar with OpenGL are doubtless gasping in horror at the fact that I put the camera transform in the projection matrix. And yes I know that this is technically a no-no, as it invalidates OpenGL's fogging and lighting operations. However, in self-defense I'll just point out that this code was originally written a long time ago to run on a MiniDriver which has neither fogging nor lighting (so there). Still readers should beware that this is wrong, evil and just plain bad. Do not imitate my laziness, put the camera in the modelview matrix where it belongs - something I will leave to a future article. Is all this renaming stuff really necessary Actually you could probably get by without it by compiling the opengl.c module with a few changes as a lib file. However, because you would be dealing with GDI functions etc, link order would become important, complexity would begin spiraling upward, life as we know it would end, and I decided it wasn't worth the bother. I'd like to give a special thanks to Dan Mintz for his help in adding support for the full list of OpenGL functions to the module, as well as help with testing on various card/driver combinations. by Ryan Haksi
Discuss this article in the forums
See Also: © 1999-2011 Gamedev.net. All rights reserved. Terms of Use Privacy Policy
|