Extending The Quake 3 Meshloader

GtkRadiant is a great tool for creating maps, however it's lacking the possibility to use all features of Irrlicht. For example: Quake 3 shader files have no option to apply bump-mapping or parallax-mapping. This tutorial will describe how the Quake 3 mesh loader works and how to modify it to support bump-mapping and parallax-mapping.

Mesh loading procedure

A SceneManager (CSceneManager.cpp) is used for loading a Quake 3 map by calling getMesh("map.bsp"). First a check is made whether the mesh has already been loaded. If that's the case, it won't be loaded again. Otherwise the file is opened for reading.

The SceneManager has about 20 different MeshFileLoaders. Each loader will check whether it can load the file or not. The BSPMeshFileLoader (CBSPMeshFileLoader.cpp) will be the one that is able to load the Quake 3 bsp file. bsp files are not the only file type that is accepted by this mesh loader. It also accepts shader and cfg files. Each type will be loaded differently.

BSP files

This contains the map mesh, texture names and lightmap textures. It is a binary file. It can be created using qeradiant/gtkradiant/zeroradiant, which can be downloaded from http://www.qeradiant.com/cgi-bin/trac.cgi.

Shader files

This file describes how the textures must be drawn. It is a human readable text-file. Here is a sample file:
textures/walls/redbricks
{
 // In quake 3 this is the default shader for redbricks.jpg
 // not defining it in the shader file would have the same effect.
 {
  map textures/walls/redbricks.jpg
 }
 {
  map $lightmap
  blendfunc 
 }
}

textures/walls/glass
{
 surfaceparm nolightmap
 cull none
 {
  map textures/walls/glass.jpg
  blendfunc filter
 }
}

This file must be put in scripts/walls.shader for irrlicht to recognize it. It will be loaded when a texture in textures/walls is loaded. The shader file for images in textures/floors must be scripts/floors.shader.

A manual with all parameters that are supported by Quake 3 can be found at http://www.heppler.com/shader/. Note that not all parameters are supported by irrlicht. For example: the surfaceparm nolightmap setting is ignored, which isn't really a problem since it isn't drawn anyway.

In Irrlicht the default shader does not give the same result as defining no shader. The result is 4 times brighter. To get the same brightness change EMT_LIGHTMAP_M4 to EMT_LIGHTMAP in headers/IQ3Shader.h.

CFG files

If the filename equals levelparameter.cfg, then it is binary. It will be used to fill the LoadParam field of the BSPMeshFileloader. This will affect the behavior of the mesh loader. The format of this file is a Q3LevelLoadParameter struct (include/IQ3Shader.h).

If the filename is different, the file format is human readable text.