Rendering Quake 2 Maps

These last few days I’ve been investigating (and experimenting with) the internal format of Quake 2 maps.

Screnshot of the first map of the game, rendered from the player's start position.
First map of the game, rendered from the player’s start position.

Internally, Quake 2 maps consist in a BSP tree, containing “visibility” information. This is due to the fact that the Quake 2 engine is a hybrid between BSP tree engines and Portal engines. The engine uses the tree to quickly determine the leaf that the camera is currently in, and then it uses visibility information to discard large chunks of the map at rendering time.

The format is relatively simple to read. It consists in a set of blobs with a directory. This makes it straightforward to load from C or C++.

The biggest difficulty I bumped into was finding a format suitable to prepare this data for OpenGL (let’s remember this format was created in 1997). In particular I found that there was too much “distance” between the leaves in the BSP tree and its attributes, requiring traversing a few tables to reach from a leaf that is known to be visible to the vertex coordinates that form its polygons.

Thankfully, I was able to come up with a mechanism to transform all polygons beforehand and avoid table jumps every frame :)

At this time, the renderer has a very simple illumination model, with directional lights and specular highlights.

The next steps that I would like to implement would be to implement texture mapping (ideally reading the original .wal files the game provides in its pak files) and geometry discarding via the PVS calculation.

Here are some screenshots.

Screenshot of the exterior room in base1.bsp
Exterior room in base1.bsp
Screenshot of the room at the start of the second map (base2.bsp)
Room at the start of the second map (base2.bsp)