123 lines
7 KiB
Markdown
123 lines
7 KiB
Markdown
#### GLQuake {#Heading17}
|
|
|
|
The second (and, according to current plans, last) port of Quake to a
|
|
hardware accelerator was an OpenGL version, GLQuake, a native Win32
|
|
application. I have no intention of getting into the 3-D API wars
|
|
currently raging; the observation I want to make here is that GLQuake
|
|
uses two-pass alpha lighting, and runs very well on fast chips such as
|
|
the 3Dfx, but rather slowly on most of the current group of
|
|
accelerators. The accelerators coming out this year should all run
|
|
GLQuake fine, however. It's also worth noting that we'll be using
|
|
two-pass alpha lighting in the N64 port of Quake; in fact, it looks like
|
|
the N64's hardware is capable of performing both texture-tiling and
|
|
alpha-lighting in a single pass, which is pretty much an ideal
|
|
hardware-acceleration architecture: It's as good looking and generally
|
|
faster than surface caching, without the need to build, download, and
|
|
cache surfaces, and much better looking and about as fast as Gouraud
|
|
shading. We hope to see similar capabilities implemented in PC
|
|
accelerators and exposed by 3-D APIs in the near future.
|
|
|
|
Dynamic lighting is done differently in GLQuake than in software Quake.
|
|
It could have been implemented by changing the light maps, as usual, but
|
|
current OpenGL drivers are not very fast at downloading textures (when
|
|
the light maps are used as in GLQuake); also, it takes time to identify
|
|
and change the affected light maps. Instead, GLQuake simply alpha-blends
|
|
an approximate sphere around the light source. This requires very little
|
|
calculation and no texture downloading, and as a bonus allows dynamic
|
|
lights to be colored, so a rocket, for example, can cast a yellowish
|
|
light.
|
|
|
|
Unlike Quake or VQuake, GLQuake does not use the edge list and draws all
|
|
polygons in the potentially visible set. Because OpenGL drivers are not
|
|
currently very fast at selecting new textures, GLQuake sorts polygons by
|
|
texture, so that all polygons that use a given texture are drawn
|
|
together. Once texture selection is faster, it might be worthwhile to
|
|
draw back-to-front with z-fill, because some hardware can do z-fill
|
|
faster than z-compare, or to draw front-to-back, so that z-buffering can
|
|
reject as many pixels as possible, saving display-memory writes. GLQuake
|
|
also avoids having to do z-buffer clearing by splitting the z range into
|
|
two parts, and alternating between the two parts from frame to frame; at
|
|
the same time, the z-compare polarity is switched (from
|
|
greater-than-or-equal to less-than-or-equal), so that the previous
|
|
frame's z values are always considered more distant than the current
|
|
frame's.
|
|
|
|
GLQuake was very easy to develop, taking only a weekend to get up and
|
|
running, and that leads to another important point: OpenGL is also an
|
|
excellent API on which to build tools. QuakeEd, the tool we use to build
|
|
levels, is written for OpenGL running on Win32, and when John needed a
|
|
3-D texture editing tool for modifying model skins, he was able to write
|
|
it in one night by building it on OpenGL. After we finished Quake, we
|
|
realized that about half our code and half our time was spent on tools,
|
|
rather than on the game engine itself, and the artists' and level
|
|
designers' productivity is heavily dependent on the tools they have to
|
|
use; considering all that, we'd be foolish not to use OpenGL, which is
|
|
very well suited to such tasks.
|
|
|
|
One good illustration of how much easier a good 3-D API can make
|
|
development is how quickly John was able to add two eye-candy features
|
|
to GLQuake: dynamic shadows and reflections. Dynamic shadows were
|
|
implemented by projecting a model's silhouette onto the ground plane,
|
|
then alpha-blending that silhouette into the world. This doesn't always
|
|
work properly—for example, if the player is standing at the edge of a
|
|
cliff, the shadow sticks out in the air—but it was added in a few hours,
|
|
and most of the time looks terrific. Implementing it properly will take
|
|
only a day or two more and should run adequately fast; it's a simple
|
|
matter of projecting the silhouette into the world, and onto the
|
|
surfaces it encounters.
|
|
|
|
Reflections are a bit more complex, but again were implemented in a day.
|
|
A special texture is designated as a mirror surface; when this is
|
|
encountered while drawing, a hole is left. Then the z-range is changed
|
|
so that everything drawn next is considered more distant than the scene
|
|
just drawn, and a second scene is drawn, this time from the reflected
|
|
viewpoint behind the mirror; this causes the mirror to be behind any
|
|
nearer objects in the true scene. The only drawback to this approach
|
|
(apart from the extra processing time to draw two scenes) is that
|
|
because of the z-range change, the mirror must be against a sealed wall,
|
|
with nothing in the PVS behind it, to ensure that a hole is left into
|
|
which the reflection can be drawn. (Note that an OpenGL stencil buffer
|
|
would be ideal here, but while OpenGL accelerators can be relied upon to
|
|
support z-buffering and alpha-blending in hardware, the same is not yet
|
|
true of stencil buffers.) As a final step, a marbled texture is blended
|
|
into the mirror surface, to make the surface itself less than perfectly
|
|
reflective and visible enough to seem real.
|
|
|
|
Both alpha-blending and z-buffering are relatively new to PC games, but
|
|
are standard equipment on accelerators, and it's a lot of fun seeing
|
|
what sorts of previously very difficult effects can now be up and
|
|
working in a matter of hours.
|
|
|
|
#### WinQuake {#Heading18}
|
|
|
|
I'm not going to spend much time on the Win32 port of Quake; most of
|
|
what I learned doing this consists of tedious details that are doubtless
|
|
well covered elsewhere, and frankly it wasn't a particularly interesting
|
|
task and was harder than I expected, and I'm pretty much tired of the
|
|
whole thing. However, I will say that Win32 is clearly the future,
|
|
especially now that NT is coming on strong, and like it or not, you had
|
|
best learn to write games for Win32. Also, Internet gaming is becoming
|
|
ever more important, and Win32's built-in TCP/IP support is a big
|
|
advantage over DOS; that alone was enough to convince us we had to port
|
|
Quake. As a last comment, I'd say that it is nice to have Windows take
|
|
care of device configuration and interfacing—now if only we could get
|
|
manufacturers to write drivers for those devices that actually worked
|
|
reliably! This will come as no surprise to veteran Windows programmers,
|
|
who have suffered through years of buggy 2-D Windows drivers, but if
|
|
you're new to Windows programming, be prepared to run into and learn to
|
|
work around—or at least document in your readme files—driver bugs on a
|
|
regular basis.
|
|
|
|
Still, when you get down to it, the future of gaming is a networked
|
|
Win32 world, and that's that, so if you haven't already moved to Win32,
|
|
I'd say it's time.
|
|
|
|
#### QuakeWorld {#Heading19}
|
|
|
|
QuakeWorld is a native Win32 multiplayer-only version of Quake, and was
|
|
done as a learning experience; it is not a commercial product, but is
|
|
freely distributed on the Internet. The idea behind it was to try to
|
|
improve the multiplayer experience, especially for people linked by
|
|
modem, by reducing actual and perceived latency. Before I discuss
|
|
QuakeWorld, however, I should discuss the evolution of Quake's
|
|
multiplayer code.
|