What is a Glide Wrapper?

I think what stimulates all these articles is primarly e-mail. I received some feedback earlier today with someone asking me "What is a Glide wrapper?". He said he surfed around the net looking for an FAQ of some sort but couldn't find anything. I remember earlier people asking about technical overviews of what a Glide wrapper is. I figure that I'll provide the high level aspect as well as a low level aspect in one article. It should give you a brief overview for the beginner, and maybe a technical aspect for the more intermediate user. It won't be of much help to the expert who is already knows how to code a wrapper.

Just finished the article and think it would be a nice touch to put a table of contents with little anchors:

Table of Contents

What is a video card and a monitor?
Please, please, please skip this
Okay so I'm starting from the very very very basics. We got a computer and a monitor. Your CPU & memory do a huge amounts of number crunching and your keyboard is an input device for your PC. The monitor is an output device, we know that. Well the monitor requires approximately 5 wires out of that DB15. It needs R, G, B, hsync and vsync... These 5 wires exclusively define the resolution you are looking at as well as what is displayed at those resolutions. (Side note: be aware that if you are at different color depths at the same resolution, it makes no different to your monitor. That is an exclusive property of your video card) A TV requires the same 5 wires except that the vsync is "hardwired" to 60Hz and the hsync is hardwired to about 15KHz. On a side topic, our monitors cannot sync down to 15KHz horizontal which is why we can't watch TV on our monitors.

The video card takes a linear array of pixels (or memory units) and translates them from digital to analog with a D/A converter. What do I mean? Well assume you are in 640x480 @ 24-bit color. Each pixel is represented by 24 bits of color which means it requires 640 * 480 * 3 = 921 600 bytes of RAM to be at that resolution. This 640x480 @ 24-bit screen is held in video RAM on your video card, so you need at least a 1MB video card. Assume that all the elements in the array were zero. The D/A converter converts the digital input (0) to an analog output which is low (the electron gun turns off at the moment it goes over the phosphor which is suppose to light up the respective pixel). Now if all the elements in the array were set to high, or 255, then the analog output would be high (the electron gun throws electrons at the phosphor which lights up to full brightness when the gun is going over that pixel. The type of phosphor defines the color.) Colors like gray which are RGB 128,128,128 would translate to an analog output of between low and high and hence the monitor would light up the phosphor half way.

So basically all the video card does is convert that 640x480 @ 24-bit color array of pixels into an analog signal which is sent 60Hz (times a second) on your monitor. (This means that the video card must scan through the entire 1MB of data, convert the signal into analog 60 times a second, this is where RAMDAC and pixel clock comes into effect). It must convert those pixels along with the correct shade of the color. So basically it linearly interpolates from the low voltage to the high voltage, 0 being the low and 255 being the high. I don't know the exact voltaged passed over the DB15 cable but it shouldn't be too hard to find out. Now if we are at 640x480 @ 16-bit color, what is the different? Well the video card just interpolates which is crappier set of colors, so the monitor receives different discrete values on its R, G and B lines. The hsync and vsync lines are unchanged. Hence the D/A converter just does the same thing and you end up with less shades of colors. But now 640 * 480 * 2bytes/pixel = 614 440 bytes. The video card only needs to scan through 0.6MB of data 60 times a second. This is why you can go to higher refresh rates at lower color depths. Again these are video card limitations and have to do with RAMDAC. I could explain more in depth but this is hardly what the article is about.

2D card versus a 3D card
Again, SKIP THIS... It is for beginners.
Now are you wondering what is the difference between an ATI Mach64, a really really cheap Cirrus Logic, a TNT and a Voodoo2? Well let's put it this way. Initial video cards such as the older Cirrus Logics as well as every other 2D card are simply used to accomplished the task as described above. They were merely stores of a digital representation of the screen which simply told the monitor what the image should look like every 1/60s of the second. The monitor doesn't remember crap all, the video card has to tell it ALL THE TIME.

Then came accelerated cards like the ATI Mach64 or Mach32. They had no 3D features but did accelerated 2D. They'd have functions to accelerated line drawing so rather than using your own Bresenham algorithm and set each and every pixel on or off in that 2D array, you told the video card "draw a line from point a to point b" and it turned each individual pixel on and off. Other accelerated features were to move blocks of memory on your video card. Which is essentially how Windows moves windows around. You must notice how when you move a window (with that feature in "Display->Effects->Show window contents while dragging" on) that the window moves pretty damn fast, but the stuff being drawn behind the window kinda fills in. Well the reason that is happening is because the window is being moved using simply video card accelerated functions. Move block of RAM from here to here, whereas the background is being drawn in pixel by pixel. (Please let me know if I'm bullshiting, I think I'm not).

That's about as interesting as 2D gets. Drawing lines, rectangles and moving around memory. 3D is a totally different issue and from a technical standpoint requires a totally different CORE, as in core functionality in the IC. This is why 3Dfx found it so easy to just create a 3D only card because 2D and 3D didn't really rely on each other.

Most common misconceptions are that a card like an S3 will play Quake worse than a Matrox Mystique which is suppose to be a 3D card. Obviously all you internet gurus know that, but games like Quake, in software mode, actually set each and every pixel on the screen at least 30 times a second. They calculate the damn color of EACH AND EVERY PIXEL 30 times a second. This means that whether you have a shitty 2D cirrus card, a better 2D accelerated card, or a shitty 3D card. Quake will be the SAME, exactly the same for all of you. I can't stress that enough. I always have people telling me "maybe it runs faster on his machine because he has an ATI x or a Diamond y versus my S3". Nope, very very minor speed differences.

3D is a different issue. Right now all 3D graphics makers are following the research of SGI and just taking the idea of triangles. All a 3D card is an accelerated drawer of triangles. ALL 3D GAMES ARE MADE UP OF TRIANGLES. Remember, you shouldn't be reading this if you know that =). All a 3D card does is draw a triangle. What software rasterizers do is draw triangles. That is why it is so easy to port a game like the original Quake which was designed for a 2D card over to 3D. 3D chip designers are merely following in SGI's footsteps and implmenting all the research that SGI has done. Just wait until the dudes pass SGI. Then you'll see them hit a wall. It is going to be entertaining. Maybe they'll do Talisman (hah hah hah).

Up to this point you are probably not believing me. Yes, video cards are pretty shitty cards. They used to just translate an array of pixels over to analog, the 2D core just draws some lines and moves memory. Nothing else. The 3D core does nothing other than draw triangles. Eg. give it 3 coordiantes on the screen and it draws the triangle in the middle. Sure it "interpolates" millions of different numbers in order to get texture mapping, gouraud shading, specular lighting, bump mapping and all that. But all it is is a glorified interpolator. And you would realize that if you coded a software rasterizer. And the dudes making the Pyramid 3D did realize that.

What I mean by this is that most of the features on a 3D card can be done just by interpolating more variables on a per pixel basis. Dedicated 3D cards do this a lot better and in parellel with the CPU, which is why there is a market for 3D cards.

What is OpenGL, DirectX, and Glide?
I seem to be full of BS today, don't I? Now we will be dealing primarly with 3D cards. You know those things that can't even MOVE MEMORY blocks around. Those things that CANNOT draw 2D lines except by drawing a triangle. Remember the core functions of a 2D and 3D card are totally different. We now we are dealing in the domain of triangles and only triangles. So to clear the screen, you must draw 2 triangles the size of the screen and colored black. Sounds inefficient? Well it is better to design a small set of functions that are incredibly fast than a larger set of functions that take more transistor space and can't be clocked as high. It is quite funny to realize that the map drawn in Motoracer, the lines are actually lots of little triangles. The text in Unreal or Quake are all made up of triangles with texture mapped numbers and letters. Everything in every 3D game is made up of triangles including the mouse pointer, the health, the menu, everything.

Now what are OpenGL, DirectX and Glide? Well from a standpoint of 3D cards, they are simply APIs which let the card draw triangles. It means that the coder or game developer uses one of those techniques to draw a triangle. One is not necessarily better than the other. All three of those APIs do essentially the same thing, they all let the video card know the coordinates of the triangles, what textures to use and the colors of the vertices. Stuff like that. They are all basically the same thing and there is no real difference from a user's perspective.

Then why do you hear about OpenGL, DirectX, and Glide? Why doesn't everyone just use the same API? Well because everyone is in a power struggle. 3Dfx's proprietary API is Glide, SGI's (OpenGL) which IMHO is/was the best API is an open standard with a committee, and Direct3D (which is part of DirectX) is Microsoft's API. Everyone has their own interests in pushing their API. Microsoft so that they can control the standard without any opposition. This will make it easier for themselves to exploit 3D card functionality (imagine integrating it into the OS, wacky awesome and much faster than the crappy 2D cores). Glide is 3Dfx's attempt to control the market and make everyone pick up a Voodoo or Banshee series of cards. SGI's (OpenGL) is the most cross platform compatible API; the API of choice for Carmack and hence the API of choice for many developers. It is was also light years ahead of DirectX years ago, but now DirectX has caught up. Obviously this is an issue of debate so go search "OpenGL vs DirectX" on some search engine.

In my humble opinion MS will defeat all and Direct3D is our new standard, so there is nothing to fight about, it is just a matter of time.

What is a wrapper?
We seem to have 3 APIs over here that accomplish the same task of drawing triangles. We also have this power struggle which makes developers write for different APIs, so we have tons of games out there each supporting their own selection of API, sometimes two of them or maybe even all three. We also have all the manufacturers of every video card attempting to support whichever APIs they can. 3Dfx supports all three, albeit not very well. Companies like Matrox, ATI and nVidia support Direct3D and OpenGL because Glide is proprietary to 3Dfx. Companies like 3Dfx also make pathetic excuses at supporting OpenGL by creating a miniGL driver rather than a full OpenGL ICD.

Considering that all the APIs are similar, a wrapper is something that simply routes one API to another. Let's say that a game like Unreal renders using Glide exclusively. What we need to do is use a Glide Direct3D wrapper or a Glide OpenGL and hence we can take a Glide game and run it on one of the other APIs. This means that companies other than 3Dfx will be able to run Glide games whereas previously they were not able to. This is a big problem with 3Dfx which is why there is such a buzz about Glide wrappers. Because a lot of users buy 3Dfx cards not because they are the best, but because they have a monopoly on Glide and therefore a monopoly on 3D acceleration on a hand full of games.

What I mean is that there are a lot of Glide only games and since it is 3Dfx's API, competiting companies are not able to create Glide drivers. There are a bunch of games that support Glide and users, because of that, tend to purchase 3Dfx cards. In order to make the market more fair, a Glide wrapper would be ideal. It would allow competing companies to actually run those Glide only games accelerated using their supported APIs.

There are also other wrappers. SciTech has developed a very functional OpenGL Direct3D wrapper. Some people seem to enjoy using this with the Glide OpenGL wrapper and this is possible. Let's just compare what is happening when we are using wrappers.

We have Unreal and a 3Dfx; assume Unreal is a Glide only game. 3Dfx inherently supports Glide (Glide is merely a thin abstraction API for 3Dfx's card). So we run Unreal, the function calls go from Unreal Glide 3Dfx video card. Now assume we use a Glide Direct3D wrapper with Unreal and assume we are using an nVidia Riva TNT as the 3D card of choice. Since the nVidia card cannot support Glide we must use the wrapper as stated. Now the functions go from Unreal Glide Direct3D nVidia D3D driver nVidia Riva TNT. Now let us say we are extremely crazy and we find that the Glide OpenGL wrappers are more functional than the Glide Direct3D wrappers. But we still want to use our video card's D3D drivers. Well we can combine the OpenGL Direct3D wrapper with the Glide OpenGL wrapper. So now we got Unreal from Unreal Glide OpenGL Direct3D nVidia D3D driver nVidia Riva TNT. Don't get me wrong, with all this wrapping you get some serious performance hit. I don't know what it is exactly, but the mere ability to do this is extremely interesting. The overall point is that the ability to wrap allows an endless choice of possibilites.

I have no idea if I confused you or not, but essentially a Glide wrapper is something that allows you to play 3Dfx only games on non-3Dfx based video cards.

So why do I want a Glide wrapper when all my games are supported in hardware with my current 3D card (which ain't a Voodoo)? Well you don't need a wrapper what so ever. You shouldn't even be here. There are a couple of games out there like NHL 98, Need for Speed II, Starsiege: Tribes, and Diablo 2 (just to name a few) that are Glide only games, and hence 3Dfx only games. Actually they support software rasterization, but why let the CPU draw those triangles when you have a dedicated triangle drawing video card for you. So to run these games accelerated the Glide wrapper might be of some use, to put it mildly.

The wrapper from a technical standpoint.
You know what? I was planning on drawing some cool diagrams and doing something cool for this, but it turns out that I am extremely lazy. I also am noticing now that I'm concentrating that there is not really much to explain here.

Glide is an API which has a bunch of functions. These functions access all the functionality of the Voodoo or Banshee card. (I just noticed something, 3Dfx likes to make mistakes don't they. They have 2 documents included with their SDK. One states how you may NOT reproduce any part of it, yet the other doesn't mind. Ahh well. That's life. =) Here is a convienant list of them: (I just cut and paste and am too lazy to remove the trailing numbers from the 126 Glide functions).

API REFERENCE
grAADrawLine 5
grAADrawPoint 6
grAADrawPolygon 7
grAADrawPolygonVertexList 8
grAADrawTriangle 9
grAlphaBlendFunction 10
grAlphaCombine 13
grAlphaControlsITRGBLighting 16
grAlphaTestFunction 17
grAlphaTestReferenceValue 18
grBufferClear 19
grBufferNumPending 20
grBufferSwap 21
grChromakeyMode 22
grChromakeyValue 23
grClipWindow 24
grColorCombine 25
grColorMask 28
grConstantColorValue 29
grCullMode 30
grDepthBiasLevel 31
grDepthBufferFunction 32
grDepthBufferMode 33
grDepthMask 35
grDisableAllEffects 36
grDitherMode 37
grDrawLine 38
grDrawPlanarPolygon 39
grDrawPlanarPolygonVertexList 40
grDrawPoint 41
grDrawPolygon 42
grDrawPolygonVertexList 43
grDrawTriangle 44
grErrorSetCallback 45
grFogColorValue 46
grFogMode 47
grFogTable 48
grGammaCorrectionValue 49
grGlideGetVersion 50
grGlideGetState 51
grGlideInit 52
grGlideSetState 53
grGlideShutdown 54
grHints 55
grLfbConstantAlpha 57
grLfbConstantDepth 58
grLfbLock 59
grLfbReadRegion 62
grLfbUnlock 63
grLfbWriteRegion 64
grRenderBuffer 66
grSstControlMode 67
grSstIdle 68
grSstIsBusy 69
grSstOrigin 70
grSstPerfStats 71
grSstQueryBoards 72
grSstQueryHardware 73
grSstResetPerfStats 74
grSstScreenHeight 75
grSstScreenWidth 76
grSstSelect 77
grSstStatus 78
grSstVideoLine 79
grSstVRetraceOn 80
grSstWinClose 81
grSstWinOpen 82
grTexCalcMemRequired 84
grTexClampMode 85
grTexCombine 86
grTexDetailControl 90
grTexDownloadMipMap 91
grTexDownloadMipMapLevel 92
grTexDownloadMipMapLevelPartial 93
grTexDownloadTable 94
grTexDownloadTablePartial 95
grTexFilterMode 96
grTexLodBiasValue 97
grTexMinAddress 98
grTexMaxAddress 99
grTexMipMapMode 100
grTexMultibase 101
grTexMultibaseAddress 102
grTexNCCTable 103
grTexSource 104
grTexTextureMemRequired 105
gu3dfGetInfo 106
gu3dfLoad 107
guAADrawTriangleWithClip 108
guAlphaSource 109
guColorCombineFunction 110
guDrawTriangleWithClip 113
guFogGenerateExp 114
guFogGenerateExp2 115
guFogGenerateLinear 116
guFogTableIndexToW 117
guTexAllocateMemory 118
guTexChangeAttributes 120
guTexCombineFunction 122
guTexDownloadMipMap 124
guTexDownloadMipMapLevel 125
guTexGetCurrentMipMap 126
guTexGetMipMapInfo 127
guTexMemQueryAvail 128
guTexMemReset 129
guTexSource 130

So we take these 126 functions and basically attempt to reproduce their functionality using another set of functions which OpenGL or Direct3D have. Now it sounds pretty simple from a certain standpoint. Well the main problem is that the functions are not that 1:1. Many of them are, but for example, texture management on Glide is much more to the metal than Direct3D or OpenGL. That usually poses a problem. Glide also supports many more blending methods than OpenGL or Direct3D. Using clever tricks you can reproduce them all. Not all Glide software uses the archiac blending functions anyway.

Ahhh. Now I know what it is you want to know, you want to know what a DLL is. You understand the concept of a Glide wrapper, but how does it really work.

What is a DLL, GLIDE2X.DLL specifically?.
Microsoft's fifth wonder. A pretty cool thing anyway and not that Microsoft specific (at least theoretically), I just needed a way to start the paragraph off. So a DLL is a dynamic link library. What happens is that there are a set of functions in that library and you have C code somewhere else which links to a LIB which has the "function names" defined in it. There is also a .H file which has the prototypes for the functions (how to use them). Well anyway, so you use these functions and unlike regular C functions such as strcpy or printf, they are not linked into your EXE. (What I mean by that is that when you include strcpy in your regular ANSI C program and compile it, you actually have a copy of the strcpy function in your EXE. With a DLL no copy of the function exists in your EXE and hence this method is much more space efficient). They are simply left there with a pointer off to a specific DLL and the name of the function. What happens is that at runtime your EXE loads up, it sees that it needs functions from this DLL and therefore it loads up the DLLs and at runtime it loads the respective functions from the DLL.

BTW: Why does IE4 load up faster than Netscape. Well IE4's DLLs are all loaded up by the OS on bootup, so all it has to load up is the EXE in order for it to run. Netscape's DLLs ain't loaded up on bootup and hence have to be loaded up on the spot as well as the EXE. You get some really cool code reuse things going on with DLLs and some really nasty screw up withs replacing DLLs with newer/older versions.

Let us reiterate. A DLL is a library of functions. Now a Glide game uses these functions to draw all the triangles. Only 3Dfx is allowed to legally produce a DLL with this interface, at least that is what they think. What you can do with a DLL is create another one with the exact same interface, eg. the exact same function names and parameters and replace that Glide DLL with your own and the software will now call your DLL. Now if you implement similar functionality with your DLL, like for the "grDrawTriangle" function you draw a triangle, you will get similar output. This is basically how a Glide wrapper is written. All the coders know the interface to the GLIDE2X.DLL which is the end DLL which every game must access to run on a Voodoo. You simulate its functionality using another API such as OpenGL or Direct3D and voila, you have a Glide wrapper.

In conclusion, I know we ain't suppose to say that, but my English teacher isn't around. In conclusion I just wrote about 3,500 words in approximately 2 hours.

I hope I may have cleared up some stuff. Although the article was not nearly as in depth as I had hoped it to be, I feel that it might provide you with some useful information. If you think it might be necessary to delve into more detail with one aspect of the article please send me an e-mail.



Khalid Shaikh
[12:05AM] February 21, 1999
All trademarks and copyrights owned by their respective companies.