abrash-black-book/70-07.md
2013-12-30 20:26:41 +11:00

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.