Early C4 Engine Development Worklog
July 3, 2003
- Completely redesigned the collision detection architecture. All geometries are now handled uniformly by a general collision detection algorithm. Swept sphere collisions can now occur with arbitrary geometrical shapes.
- Removed the restriction that the torus primitive be circular. It can now be elliptical.
- Added a flag that forces tangent fields to be calculated numerically for primitive geometries instead of analytically.
- Added a geometry space identifier to the
GeometryObject
class that indicates into what coordinate space its vertices have been transformed. Geometry can exist in world space, object space, or group space. - Implemented portal vertex insertion and removal tools in the World Editor.
- Implemented registration mechanisms for controller, property, entity, and effect construction procedures. Templatized the classes encapsulating the construction procedures.
- Added a
World
pointer to theNode
class. Every node now knows in what world it exists. - Created subclasses for the World Editor's node info window that are specific to geometries, lights, etc.
- Added recognition of spawn location and spectator location markers in the Game Module.
- Implemented undo for the Replace Material command in the World Editor.
- Added a list of particle systems to the
World
class so that particle systems now belong to the world in which they exist instead of being stored in a global list by the Particle Manager. - Implemented a diagnostic mode that displays certain collision detection data.
- Fixed a very minor glitch in the color picker window.
- Wrote a tridiagonal linear system solver that will be used for cubic splines. A discussion of both of these will appear in the 2nd edition of Mathematics for 3D Game Programming & Computer Graphics.
- Implemented microfacet shading (both isotropic and anisotropic) for metallic surfaces. This code will also appear in the 2nd edition of Mathematics for 3D Game Programming & Computer Graphics.
May 22, 2003
- Created a Math Utilities library and moved various standalone math routines into the
Math
namespace. - Moved the 256-entry sine and cosine tables from the Particle Manager to the Math Utilities.
- Implemented the
Manipulator
class hierarchy. Manipulators encapsulate all of the object interaction functionality used by the World Editor. Manipulators also contain any extra rendering code used to display non-geometric objects, editor handles, light ranges, etc. This code was previously split between Node subclasses and anEditorData
chunk stored within each node. TheEditorData
structure has now been removed. Object
subclasses have been created for all primitive geometries, portals, and zones.- An generic auxiliary object slot has been added to the
InfiniteZone
class to accommodate the need for the World Editor to store data somewhere. - Implemented a geometric primitive that represents a rectangular plate with an elliptical hole cut out of it.
- Implemented a geometric primitive that represents a right rectangular pyramid.
- Removed the texture map resources used to render portals and zones. They are now stored directly in the code (the textures are very simple).
- Implemented a mechanism through which an object construction procedure can be registered. This allows different modules to define their own object types and construct them when a world resource is loaded.
- The World Editor and Model Importer have been split out into standalone plugin modules. These were the last tools still left in the core engine—all tools now reside in their own modules.
- Made some significant changes to the Resource Manager to better accommodate the definition of new resource types in plugin modules. [If the C++ standard had better defined the intended behavior of the
export
keyword, and compilers actually implemented it, a lot of trouble would have been avoided here.] - Implemented separate panes for geometries, lights, portals/zones, and markers in the World Editor. Also created better icons.
- A toggle has been implemented that allows certain geometric primitives to be automatically capped when they are drawn in the World Editor. The box and cylinder geometries receive both a bottom endcap and a top endcap. The pyramid, cone, and dome geometries receive only a bottom endcap. When multiple primitives are created through automatic capping, they are also grouped as required by the shadowing system.
- Redesigned the resizing algorithm in the World Editor. Capped geometries can now be resized as a single object.
- Implemented automatic multiple selection for groups that contain a geometry with caps.
- Added a safety mechanism to the World Editor that will delete empty groups if everything in them is deleted. Of course, the groups come back if the operation is undone.
- Implemented portal vertex manipulation in the World Editor.
- Created base classes for several of the template utility classes and moved code not dependent on template parameters down so that it doesn't get duplicated. This reduced overall code size by more than 10 percent.
- Implemented a mechanism through which manipulators can cache rendering data that remains constant as long as the viewport it's rendering into isn't changing.
- Added support for line strip and indexed lines render types in the Graphics Manager. Also added a render state bit for line smoothing.
- Completed all light source and sound source tools in the World Editor.
- Implemented location marker and cube map marker tools in the World Editor.
- Implemented preliminary support for the
GL_ARB_vertex_buffer_object
extension. - Cancelled plans to support the
GL_NV_vertex_array_range
extension.
April 11, 2003
- The sound buffer position notification mechanism in DirectX 9.0a is totally broken. The Sound Manager's dependency on this necessary-for-streaming feature has been removed and replaced by a slightly less elegant timer that fires several times over the span of the main mixing buffer and polls the play position.
- Removed upward dependencies from the Input Manager. Hooks are now exposed where the Input Manager needs to call into higher-level code such as the input configuration window.
- Made some significant revisions to the new Resource Manager.
- Implemented full support for S3TC texture compression.
- Implemented optimized support for multiple texture formats in a single texture resource. Only the format that is actually used is loaded into memory.
- Texture images loaded from resources are now removed from memory after being transferred to OpenGL. This reduces RAM usage by a ton. The only drawback is that a graphics system restart takes longer now because textures have to be loaded from the disk again.
- Added a filter procedure to the
FileMgr::BuildFileList()
function. - Expanded the
ListBox
functionality so that it can handle multiple selected items. - Exposed the
ListItem
class so that it could be subclassed. List items can now draw themselves however they want. - Added a resource catalog for imported resource types. Targa files, text files, and 3DSMax exports now reside in the Import folder.
- Redesigned the texture import dialog. It now allows specification of S3TC compression, HILO bump maps, and the recently added texture flags.
- The following tools have been split out into Tool Manager plugin modules:
- Sound Player
- Movie Player
- Model Viewer
- Texture Viewer
- Texture Importer
- String Importer
- Font Generator
- Added support for HILO textures in the Texture Viewer tool.
- Mipmaps can now be viewed in the Texture Viewer tool by hitting Ctrl-M (PC) or Cmd-M (Mac).
- Made some performance improvements in the Sound Player tool.
- Made several code design improvements in the World Editor.
- Fixed a bug in the World Editor's rectangle zoom tool.
- Fixed a minor glitch that would cause the extension-enabled flag to be ignored for any extensions that were core features of the currently installed OpenGL implementation (e.g., it would be impossible to turn off texture compression under OpenGL 1.3 or higher).
- Fixed a minor bug in the fragment shader code for point light sources (affects ATI hardware only).
March 28, 2003
- The engine now requires support for the
GL_EXT_draw_range_elements
extension. (As a core feature of OpenGL 1.2, this extension is supported by all vendors that we care about.) - Added support for the
GL_SGIS_generate_mipmap
extension. A new texture flag has been defined to indicate that mipmaps should be automatically generated by OpenGL. - Added support for subtractive blending modes using the
GL_EXT_blend_subtract
extension. - Removed support for the
GL_EXT_compiled_vertex_array
extension. Superseded by theglDrawRangeElements
function and future support for vertex array range functionality. - Removed support for the
GL_EXT_secondary_color
extension — it's no longer being used. - Whether trilinear filtering is used is now controlled by the
textureTrilinear
system variable. A new texture flag has been defined to force a texture to used trilinear filtering. - Implemented support for per-pass face culling state. This enables special effect algorithms to render back-facing polygons on one pass and front-facing polygons on another pass.
- Created a translucency material attribute. Currently experimenting with the translucency effect.
- Changed the Movie Manager functions
Activate()
andDeactivate()
toInitialize()
andTerminate()
to be consistent with the same functions in the Network Manager. - Made some minor changes to the Movie Manager necessary to support playback of audio files. Any audio file in a format recognized by QuickTime can now be played as a movie.
- Added duration and position queries to the
Movie
class. - Completely rewrote the Resource Manager.
- The location of resources is now determined by the catalog in which they reside. Catalogs allow related resources to be collected in the same place. A single type of catalog is defined in the Resource Manager that encapsulates a root path leading to a group of resources. Game modules may define additional catalog types that grab resources from arbitrary locations. For example, an application might define a catalog that extracts resources from a pack-file.
- The current resource layout hasn't been changed, but the organization in future builds will take advantage of the packaging capabilities.
- Resource types may now indicate whether resource names include an extension. Movie resource names must now specify the extension used in the file name since different formats are supported.
- Applications may register catalogs with the Resource Manager so that they can be selected when importing various types of data. Import dialogs in future builds will display a target catalog list.
- The Graphics Manager now uses conventional vertex arrays with vertex programs. This reduces the overhead of switching in and out of vertex program mode and makes ARB vertex programs easier to read. It also seems to be liked by drivers more.
- The MacOS build now requires a G4 processor.
March 19, 2003
- Changed the internal texture format passed to
glTexImage()
to force 8 bits per component. ATI drivers were dropping down to something less, causing ugly banding. - Changed binding to vertex attribute arrays in ARB vertex programs to be conformant with the spec.
- Added more robust error reporting to the vertex/fragment program loading code.
- Fixed an overflow problem that showed up when using
GL_ATI_fragment_shader
to perform environment-mapped bump mapping.
March 7, 2003
- Added support for rectangle textures using the
GL_NV_texture_rectangle
extension. Rectangle textures are not restricted to power-of-two sizes, but cannot have mipmaps and cannot use repeating wrap modes. - Added support for the
GL_ATI_separate_stencil
extension. This enables an optimization on ATI hardware that is equivalent to the functionality provided by theGL_EXT_stencil_two_side
extension. Both allow stencil shadow volumes to be rendered in a single pass by using separate stencil operations for front-facing and back-facing polygons. - Added occlusion query functionality to the Graphics Manager and the World Manager using the
GL_NV_occlusion_query
extension. An occlusion query can now be performed during the ambient rendering pass, and its result can be used after the lighting passes to render special effects. - Added support for the
GL_NV_point_sprite
extension. Particle systems may now specify theparticlePointSprite
flag indicating that its particles should be rendered as point sprites, if available. This allows a 75% reduction in vertex processing for some particle systems. - Added support for anisotropic texture filtering using the
GL_EXT_texture_filter_anisotropic
extension. The maximum anisotropy used during filtering is controlled by thetextureAnisotropy
system variable. A value of 1 corresponds to no anisotropic filtering. - Updated texture format and added support for compressed texture images. Changed texture resource extension to
.tex
. - Developed a Tool Manager class and implemented a tool plugin architecture. The texture viewer utility has now been split out into a plugin, and other built-in tools will follow.
March 27, 2002
- The game module is now present in the executable download. Spectator camera controls have now been moved there, and it is now possible to insert a player into the world. Issuing the "spawn" command in the command console will put the player in the world, and issuing the "spectate" command will take him out.
- The game play menus have not yet been added, but certain setup dialogs can be accessed through the command console. Type "display" to bring up the Display Setup dialog, and type "input" to bring up the Setup Controls dialog.
- The player can fire the plasma gun at this time. No other weapons are implemented yet.
- No collision detection is implemented at this time, so the player can run through anything, and the plasma bursts will never hit anything either.
- This build still uses a single hard-wired light source. Build 14 will use the actual light sources placed in the world with the world editor.
- Shadow-casting set determination will not be implemented until build 14, so objects that are not visible themselves will not cast a shadow. If you see shadows blinking out, that's why.
- The shadow faceting sometimes visible on the character is a known issue with the stencil shadow design. Ways to eliminate this artifact will be explored in the future.
- The executables and data are now separate downloads. They just need to be unzipped into the same directory.
- This fixes all previously know world editor bugs.
- Grouping has been implemented in the world editor. There currently is no visual indication that a group exists (there will be), and ungrouping is not yet implemented (grouping can be undone, however). Grouping is necessary for two things: 1) level of detail synchronization, and 2) connected shadow volume consistency (this allows a really nice optimization).
- It is now REQUIRED that objects sharing edges belong to the same group. For instance, if you create a cylinder and two endcaps, you must select all three objects and then group them. I'm thinking that in the future objects will be created as a group with their endcaps already present, but this will not be implemented for a few more builds.
- The world format in this build is not backwards compatible.
- The world editor will now pick selected objects before unselected objects when you click in a viewport. In some cases, this may prevent you from selecting an object for which another (already selected) object covers the same space in the viewport. Just deselect the other object first.
January 26, 2002
- Added auto-panning to the world editor so that viewports will pan when the cursor goes out-of-bounds while drawing, moving, rotating, or resizing.
- Implemented the multiple undo architecture for the level editor.
- Implemented selection picking in the world editor.
- Implemented the move and rotate tools in the world editor.
- Added constraints to the move and rotate tools so that holding down shift only allows an object to be moved horizontally or vertically or rotated in increments of 45 degrees.
- Added handles to the world editor. Objects can only be rotated or resized by grabbing handles -- they also determine the center of rotation and constraints on what dimensions of an object get resized.
- Implemented the pulldown menus for the world editor.
- Added checkmarks and command keys to the
MenuItem
class. - Added load and save functionality to the world editor. The same functionality is used to load worlds for actual gameplay.
- Added a name box to the file picker for saving files.
- Implemented the undo mechanism for resizing objects in the world editor.
January 12, 2002
- Redesigned the entire shading system. The graphics manager is quickly moving towards a real-time global lighting and shadowing engine.
- Wrote the ambient shader setup code. This handles anything that does not involve an actual light source, including ambient illumination, emission, and environmental reflections. Environment-mapped bump mapping also happens here.
- Added ambient light transition zones to the ambient shader. This allows objects straddling the boundary between two zones to have a gradually changing ambient light color.
- Implemented an algorithm that clips an arbitrary convex polyhedron against a plane. The algorithm maintains edge connectivity and face adjacency information.
- Implemented a new polygon triangulation algorithm that handles polygons having three or more collinear vertices. This arises during T-junction elimination. This algorithm will appear in the article "T-Junction Elimination and Retriangulation", in Game Programming Gems 3 to be published in July, 2002.
- Wrote an extension to the polygon triangulation algorithm so that it can handle concave polygons and arbitrary planar regions having nonzero genus.
- Updated the particle system code and improved the way that line particles are rendered.
- Implemented a new node enumeration mechanism that iterates through all of the subnodes having particular type of a given root node.
- Updated the surface marking code to use the new node enumeration code.
- Implemented a transform and bounding volume invalidation mechanism for the global node tree.
- Removed support for the
WGL_3DFX_gamma_control
extension. - Improved the texture hashing scheme so that it is more robust and treats texture resources and procedurally-generated textures the same way.
- Rewrote the Resource Manager. It is now more general and resource locations can be customized to support things like packfiles.
- Designed a general vertex program for rendering volumetric fog.
- Implemented the infinite light shader setup code.
- Designed a system for allocating and calculating vertex attribute arrays on the CPU for machines that don't have a GPU with programmable vertex shader capabilities.
- Began writing the C4 World Editor.
- Implemented orthographic and perspective viewports for the world editor.
- Implemented gridline rendering in the world editor.
- Implemented viewport pan and zoom tools in the world editor.
- Implemented viewport configuration controls in the world editor.
- Implemented geometry drawing tools in the world editor.
- Added a snap-to-grid toggle for geometry drawing in the world editor.
- Added a draw-from-center toggle for geometry drawing in the world editor.
- Improved the window centering code for the internal interface system.
- Designed a new texture map format that allows multiple image formats to exist in the same resource. The format chosen at run time depends on the graphics hardware capabilities.
- Updated the skybox rendering code.
August 4, 2001
- Wrote the Movie Manager. A QuickTime Movie can now be played into any window or any texture map. The Movie Manager can also be used to stream audio tracks in any format that QuickTime supports.
- Enhanced the texture map resource format so that multiple images can be stored in a single texture. This is good for things like cube texture maps, which require six images.
- Added flags to the Ray structure which can be used to control what kinds of objects the ray can intersect. This is useful for ignoring objects which do not cast shadows or should not appear in an environment map.
- Added support for the
GL_EXT_abgr
,GL_EXT_bgra
andGL_EXT_packed_pixels
extensions. - Upgraded the Input Manager under Windows to use DirectInput 8.
- Improved the way that the Input Manager handles being switched into the background.
July 28, 2001
- Made dozens of small enhancements and fixes that accumulated into a long list while I was working on the book.
- Changed usage of MacOS
FSSpec
records to the recommended method. - Added diagnostic tools which allow normal and tangent vectors to be seen in real-time.
- Implemented a direct reflection color for environment mapping.
- Improved bump map construction code.
- Changed default shader blend mode to replace.
- Added the EAX environment size field to the Sound Manager.
July 18, 2001
- Finished writing the book Mathematics for 3D Game Programming & Computer Graphics, to be published by Charles River Media in December.
- Implemented the Cook-Torrance BRDF physically-based lighting model in the shader system. This enables accurate isotropic and anisotropic reflections based on surface roughness and specular properties. A detailed analysis of this lighting model is presented in Chapter 6 of my book.
- Rewrote the fluid surface simulation code. It is now very clean and based entirely on the 2D wave equation with viscous damping. The new model now correctly takes wave speed and viscosity into account. The entire final chapter of my book provides a thorough discussion of the technique that is now used in the engine.
- Added support for different types of ADPCM wave files that are floating around out there.
- Added hooks to the Resource Manager that allow custom resource loading routines to be installed.
March 24, 2001
- Finished implementing complete support for the following lighting equation on Nvidia GeForce and ATI Radeon hardware.
color = [D * T * (N · L) + S * G * (N · H)4] * X + A * T + E * M
D = diffuse reflection color * primary light color S = specular reflection color * primary light color A = diffuse reflection color * ambient light color E = emission color T = primary texture color G = gloss map color X = shadow map color M = emission map color N = bump map normal vector L = vertex space direction to light H = vertex space halfway vector
- Components of the above equation can be used in any combination. The G term can be a separate texture map or it can be stored in the alpha channel of another texture. The N · H term can be replaced by an environment map to achieve true environment-mapped bump mapping (GeForce 3 only). The shader system renders objects using per-pixel lighting with as few passes as possible. Almost everything can be done in a single pass on GeForce 3 hardware. Vertex programs are used where appropriate to perform vertex space basis calculations and texture shader setup.
- Designed a new architecture for assigning texture mapping coordinates to world structures. Textures are now transformed in 2D texture space and then wrapped onto a structure using a structure-specific function. This method also makes vertex space basis calculations very easy.
- Added support for emission maps in the 3DSMax geometry export plugin and in the model import dialog.
March 17, 2001
- Added code which stores complex register combiner settings in OpenGL display lists.
- Implemented complete support for emission maps.
- Added the ability for a normal map to contain an alpha channel gloss map.
- Redesigned the shader initialization code for per-pixel lighting. Shaders now assemble themselves out of much simpler components.
- Implemented environment-mapped bump mapping using the
GL_NV_texture_shader
extension. - Moved the
SmokeTrail
particle system code to the Game Module. - Implemented support for the
GL_NV_mac_get_proc_address
extension.
March 10, 2001
- Implemented a complete pulldown menu system.
- Moved all of the title window functionality into pulldown menus.
- Added a Tools menu which provides access to utility windows and import functionality.
- Added an
ImportMgr
class and separated all of the actual import code from the user interface code for the import windows. - Made various improvements to the Window Manager and dialog element classes.
- Implemented support for anisotropic texture filtering using the
GL_EXT_anisotropic_texture_filter
extension. - Added a color array to the surface marking class so that marking edges will fade based on their vertex normals. This eliminates the hard edges that could previously appear on highly curved surfaces.
March 3, 2001
- Upgraded the 3DSMax geometry plugin so that it exports gloss map and bump map information.
- Added vertex space basis calculations to the model importer and to the real-time mesh deformation code.
- Added the ability for the alpha channel of a texture map to be used as a gloss map.
- Added a sort function to the
ListBox
interface element. - Made massive improvements to the model import dialogs. Users can now deactivate parts of an exported geometry, change diffuse, emission, and specular colors, and select texture maps, bump maps, and gloss maps for each part.
February 24, 2001
- Made several improvements to the terrain code. Terrain collision detection and shadow generation are now more accurate.
- Improved the code which blends the seams between neighboring lightmaps.
- Updated the model format and model import code so that it possesses the same general attribute array and texture map capabilities that world structures now support.
- Moved all edge finding code for shadows into the model import code so that those calculations are no longer necessary when a shadow is added to a model.
- Implemented multiple levels of detail for shadow volumes. Previously, the shadow always corresponded to a model's lowest level of detail.
January 27, 2001
- Improved the transparent object distance sorting algorithm.
- Changed the way that light map saturation is handled so that color hues are not altered.
- Added a format field to texture maps.
- Added a user-configurable desktop color to the Window Manager.
- Implemented stream classes for loading and saving resource data. This encapsulates information such as endianness, making load/save code simpler.
- Added a flag to the
LightSource
class in the Ray Tracer which inhibits the light source's participation in light map generation. This is useful for placing a single light in the world that is used for real-time illumination in place of several other lights which may exist for higher-detail lightmaps.
January 20, 2001
- Changed the rendering order of shadow volumes so that they are rendered before the object to which they are attached.
- Reduced the amount of data written to a world resource for invisible geometries.
- Removed the intermediary classes
PlanarStructure
andCylindricalStructure
and moved their specialized visibility tests into the baseStructure
class. - Added spherical and cylindrical geometry placeholders for special effects. This allows the visibility of certain effects to be determined using the global zone/portal and BSP tree algorithms.
- Added a rising smoke effect to the Game Module which is attached to torches.
- Implemented a new sorting algorithm for transparent objects. The new system allows transparent objects to be attached to other transparent objects so that they're rendered consecutively. This is nice for things like scorch marks on transparent surfaces.
- Added a two-sided flag to the 3DSMax geometry export plugin so that parts of a model may have backfaces rendered in the engine.
- Improved the way that input elements are deactivated when the input mode is changed; for example, when switching from game controls to user interface input.
January 13, 2001
- Added a texgen light map flag to the
Geometry
class which will suppress the generation of light map coordinates for geometries that generate them at run time (e.g., the fluid geometry). - Improved light map sample coordinate generation for primitives whose geometry doesn't cover the entire area that its light map covers. This eliminates many edge darkening artifacts on some of the curved surfaces.
- Restructured the layout of zone and environment classes so that they use the same code to define the volumes of space that they affect.
- Added sphere and cylinder volume types which can be used as zones or environments.
- Added clipping planes to the zone and environment volumes so that they can be carved into more flexible shapes.
- Added file name type-out matching to the file picker dialog box.
- Added an auto-scroll option to the
ListBox
dialog element that will display the current selection when it is changed. - Added default text and window colors to the Window Manager which can be changed by the user.
January 6, 2001
- Added code that handles cases in which static light map sampling points fall outside a geometry's clipping planes. Projecting the sampling point onto the plane eliminates darkening artifacts that can occur in corners where mutually clipped geometries meet.
- Added a natural plane function to all of the geometry classes in the Ray Tracer. These are useful for clipping adjacent geometries to the planes formed naturally by a primitive (such as the end planes of a cylinder).
- Added a flag which indicates whether the sky box should be rendered when a certain zone is rendered. Previously, the sky box was only rendered when the topmost zone in the hierarchy was visible.
- Implemented the vertex lighting option for world geometry as an alternative to static light mapping. This really helps load time and rendering performance in outdoor environments where there may be hundreds of trees which don't really need light maps for anything other than their trunks.
- Finalized the Ray Tracer intersection code for the terrain geometry.
December 23, 2000
- Made several general enhancements to the terrain collision detection code.
- Began implementing the Ray Tracer intersection code for terrain geometry.
- Added the Information component class to the Ray Tracer. This is used to store general types of data which is shared among more than one component in a scene.
- Added the ability to create multiple terrain geometry objects which draw from the same height field data. This is useful for dividing a large outdoor area into smaller blocks which may reside in different zones. It also improves dynamic lighting performance considerably.
- Implemented a light map expansion technique which helps eliminate discontinuities visible in the light maps of adjacent geometries.
- Added an origin point to the
BoxZone
class so that nodes containing such a zone don't need to have a translation. - Added code to the World Builder which compares multiple bounding spheres for a structure (calculated through different methods) and selects the best one.
December 16, 2000
- Simplified most of the conventional lighting code in the main rendering pipeline.
- Upgraded the quality of light map generation for terrain geometry.
- Implemented the collision detection algorithm for terrain geometry.
- Added simple collision detection to chase cameras so that they won't go through walls.
- Added a mechanism to the character collision code which makes uphill motion appear much smoother.
- Modified the Macintosh versions of the Sound Manager and Network Manager so that they are able to run in the Carbon environment.
December 9, 2000
- Added bump mapping flags to the
Shader
class which control certain lighting variables and specify optimization hints. - Implemented bump mapping for point and spot light sources.
- Wrote vertex programs for bump mapping with point and spot light source attenuation.
- Implemented a mechanism for invalidating vertex space light direction and halfway vectors for bump-mapped objects which do not have the
bumpDynamic
flag set. - Wrote a vertex program component assembler for generating vertex programs at run time. This replaces the combinatorial explosion of canned programs that was starting to materialize. Small pieces of vertex program code are now stored in the executable and put together at run time to create a complete program that fits a shader's needs.
- Removed the
VertexProgramResource
resource type. - Consolidated infinite, point, and spot light types into a single light class.
- Extended the
Environment
class so that it describes a lighting model for a region of the world in addition to the acoustic properties that it previously maintained. Ambient light settings and all static light sources now belong to environments.
December 2, 2000
- Implemented the convention of texture map slots in the shader system. Instead of just having a list of texture maps, each renderable object now possesses a table of texture maps whose entries may be zero. Particular indexes within the table have semantic meaning such as ordinary texture map, light map, normal map, and gloss map.
- Implemented register combiner state settings for all 21 possible types of rendering passes for per-pixel bump mapping. The pass(es) chosen for an object depend on the number of available texture units, number of available general combiner stages, and whether the object is to be rendered with a texture map, specularity, gloss map, and/or shadow map.
- Implemented vertex programs for each of the 21 bump mapping passes which calculate vertex space light direction and halfway vectors.
- Added support for per-stage constant color inputs for register combiners.
- Added a scroll size to the
ScrollBar
class which lets you specify how far to scroll when the user clicks the up or down arrows.
November 18, 2000
- Added separate conventional array state and vertex attribute array state flags to the Graphics Manager.
- Added specialized shader structures for several different lighting configurations.
- Added a control panel that allows you to enable/disable any OpenGL extensions. This works without having to restart the engine.
- Implemented more versatile support for conventional OpenGL lighting. The engine now supports diffuse, specular, and emission material colors for every renderable object.
- Added support for multiple light maps in the World Builder. This is needed to provide different light maps which are used depending on what hardware features are available. For instance, the N · L term should not be included in the light map when performing per-pixel bump mapping.
- Expanded the world and model resources so that objects can have an arbitrarily number of textures applied to them. Each texture also carries a type such as light map or bump map.
November 11, 2000
- Added a blending mode for modulating by the contents of the destination alpha channel. This is used for the smooth self-shadowing term during the specular pass for per-pixel bump mapping.
- Added a scale factor to the normal map generator allowing one to control how pronounced the bumps in a normal map are.
- Implemented bump mapping for the ATI Radeon using the
GL_EXT_texture_env_dot3
extension and three texture units. - Implemented NV20 vertex programs for vertex space light direction and halfway vector calculations.
- Began writing a book tentatively entitled Mathematics for 3D Game Programming and Computer Graphics which will be published by Charles River Media (the same company who published Game Programming Gems).
November 4, 2000
- Overhauled the way in which attributes are applied in the Ray Tracer. Each of a geometry's attributes now modify the surface shading state in a single function.
- Rearranged and simplified parts of the Ray Tracer which work with attributes.
- Rewrote most of the real-time shader architecture. Shaders can now hold multiple textures, they have their own set of vertex attribute arrays, and they can be invoked for multiple passes. The first time that a particular shader is used, it calculates the number of passes that it needs and which textures should be used on each pass. This removes some computation from the old rendering pipeline and turns it into precomputed data.
- Moved the remaining light setup code out of the main rendering execution pipeline. This is now completely precomputed on a per-view basis.
- Moved the wireframe rendering pass to a separate subroutine.
- Implemented support for the
GL_EXT_texture_env_combine
andGL_EXT_texture_env_dot3
extensions.
October 28, 2000
- Finished client-to-server multiplayer communications code.
- Added a
SpectatorCamera
class to the Game Module. - Refined the wave propagation code for fluid surfaces.
- Added normal map generation to the texture importer (this is used to import bump maps).
- Added a component count to the texture coordinate array in the
Shader
class so that 3D coordinates could be specified. This will be used for 3D textures as well as vector arrays for per-pixel lighting effects. - Implemented shaders for per-pixel bump mapping. Full bump mapping is done in two parts: a diffuse reflection pass and a specular reflection pass.
- Added a tangent vector to the Ray Tracer's hit data structure so that a local tangent space coordinate system could be derived from a ray intersection.
- Added the
BumpMapAttribute
class to the Ray Tracer and implemented normal vector perturbation.
October 21, 2000
- Implemented a general property list architecture allows arbitrary data to be associated with any structure in the world.
- Ripped out the old material data structures and replaced them with properties.
- Added a default property list to the World Manager. If a structure does not have a property of a certain type, then the default property can be used instead.
- Added an overridable collision function to the
Character
class similar to the function which already exists for theProjectile
class. This allows the Game Module to implement a custom response whenever a character collides with a structure. - Added a teleport destination property to the Game Module. This property is attached to structures which teleport characters when they collide with it.
- Finished moving all world building functionality to World Editor window.
- Implemented full support for the
GL_NV_vertex_program
extension. - Implemented preliminary support for some yet-to-be-disclosed Nvidia extensions.
October 14, 2000
- Implemented general plane clipping in the World Builder. Any geometry can now be clipped by an arbitrary number of planes, and the new vertices are automatically fused to adjacent structures in the world.
- Implemented a calculation which determines how large a light map should be for a geometry after it is clipped.
- Added a general normal vector and winding reversal subroutine to the World Builder which operates on any of the possible render types (such as triangle fans or quad strips).
- Added a light map flags field to the
Geometry
class. - Modified the
TextureMapAttribute
class so that it can still be used even if the texture map that it references is not available. - Implemented several generic texture mapping topologies. Geometries can now be auto-mapped using planar, radial, cylindrical, polar, or toric mappings.
- Changed the primitive type for the revolved cubic spline geometry from indexed triangles to indexed quads.
- Made some of the interactions between the World Builder and each geometry class a little cleaner.
- Implemented preliminary support for the
GL_NV_vertex_array_range
andGL_NV_fence
extensions.
October 7, 2000
- Added a generalized global variable system to the engine core. This system manages persistent variables which can be created at any time by the engine or by the Game Module. These variables are written to a config file, and they can be edited by the user in the command console.
- Removed the old Preferences Manager and replaced it with global variables and a config file which is executed at startup.
- Generalized the input element binding functionality so that any element can be bound to an action or to a series of commands.
- Implemented a generic file selection dialog.
- Implemented a general pixel map blitting function (along with an Altivec accelerated version).
- Implemented a new layout for the Host Game dialog in the Game Module which now includes a picture of the selected world.
- Improved collision detection efficiency a little bit.
- Added full support for elliptical geometry to the Ray Tracer and the World Manager.
- Removed all half- and quarter-geometry primitives in favor of absorbing them into the general clipping plane architecture. Efficiency is reduced slightly, but it makes a negligible difference at run time -- the savings in less code duplication and a simpler geometry hierarchy more than pays for it.
September 30, 2000
- Implemented automatic global vertex fusion. This ensures that coincident vertices belonging to adjacent structures actually have the same exact global coordinates, which is the first step in preventing seams.
- Implemented automatic global T-junction elimination. Whenever a vertex belonging to one structure falls on an edge of an adjacent structure, a new vertex is added to the adjacent structure at the exact same coordinates. This makes every world absolutely free of seams.
- Made surface markings more memory efficient by implementing a multiple-size vertex array.
- Added a flag to the Model class which suppresses rendering of the model through the normal world view. This is useful for rendering the local player model in an FPS since the model shouldn't be rendered from the player's perspective, but should still appear in mirrors and portals.
- Added a collision padding parameter to the Zone class so that structures that stick out of the zone a little bit are still considered for collision detection within a certain distance of the zone boundary.
- Added the ability for any geometry in the World Builder to link to another detail group which doesn't contain it. This allows a level designer to indicate that the geometry should change detail level at the same time as the group.
- Added an altitude angle to the
LocationMarker
class. - Added a minimum alpha setting to the
TunnelMarker
class. - Added collision detection to the spectator camera in the Game Module.
- Added a location type to the Game Module which indicates where the spectator camera should be placed when a world is loaded.
- Implemented window minimization functionality in the Window Manager.
- Implemented a texture viewer window.
- Made massive changes to the Resource Manager. Everything has now been changed from number based to name based.
- Removed the
CursorType
type -- cursors are now identified by their texture map name. - Removed constants for selecting fonts -- fonts are now identified by their resource name.
- Added an extended version of the
FileMgr::BuildFileSpecList()
function which builds a list of files whose names begin with a given string. - Moved the animation import functionality to the Model Viewer window. Animations for a specific model are now identified by names which start with the model's name.
September 23, 2000
- Implemented a geometry class for soft light cones around spot lights.
- Added a parameter to the
Geometry
class which controls the minimum number of subdivisions that a curved surface must always have. - Added a flag to the Geometry class which allows certain structures to live in their own object space instead of global space.
- Implemented the
EmissionAttribute
class in the Ray Tracer. This attribute provides a way for a surface to appear to give off light. - Implemented invisible geometries, which exist for the purposes of collision detection, but don't render anything.
- Added collision flags to every structure in the world so that geometry may be penetrable to some types of objects but solid to others.
- Added specialized visibility test functions to the
Structure
classes to achieve more efficient culling. - Improved the collision detection algorithm for torus-based structures and revolved cubic spline structures.
- Added a post-processing function to the light map generation code in the World Builder.
- Added an application-definable type field to location markers.
- Added a callback function to tunnel markers so that applications can modify a tunnel's transform during gameplay to get floating effects, etc.
- Moved all rendering options from the Graphics Manager to the World Manager.
- Added more rendering options to the Display Settings dialog.
- Added code to disable Alt-Tab and the Start menu on Windows systems.
September 16, 2000
- Implemented a better solution to the degeneracy problems that can arise during portal clipping.
- Implemented the
Torus
geometry class in the Ray Tracer and the World Builder. - Added support for dark lights (lights which subtract color from the surfaces that they illuminate) in the Ray Tracer.
- Added primitive geometry classes to the Ray Tracer corresponding to the first quadrant of each of the circular geometries. Using these is a bit more efficient than chopping down a larger primitive with a clipping plane.
- Added an optional tangent array to all geometry classes which can be used when a single tangent vector does not provide enough information to calculate tangent planes at every vertex. This was necessary to correctly apply dynamic lights to geometries such as domes and tori.
- Implemented line particles and added a flag to the
ParticleSystem
class which causes particles to render as a line connecting their current positions to their previous positions. - Implemented preliminary support for the
GL_NV_vertex_program
extension.
September 9, 2000
- Implemented analytical root solvers for arbitrary cubic and quartic polynomials.
- Implemented a general revolved cubic spline geometry class. This allows a level designer to specify a set of points which represent the radius of a cylindrically symmetrical object at various heights above the object's base. The World Builder calculates a smooth cubic spline connecting the given points and revolves the spline about the local z-axis. Ray intersection calculations involving this geometry class are mathematically precise. The object isn't just surrounded by a bounding cylinder for collision detection -- the points of intersection of a line with the actual cubic surface are determined allowing accurate interaction with other objects.
- Added adaptive subdivision to the revolved cubic spline geometry. This puts the vertical subdivisions where they need to be (where the curvature is the greatest) in order to give the object the best possible appearance.
- Upgraded the input configuration window so that it uses the recently implemented hierarchical interface context architecture.
- Tweaked the Game Module code which controls the conditions under which a grenade comes to a rest.
September 2, 2000
- Implemented sky boxes -- boxes with up to six sides which move with the camera and contain a distant background image. When rendering a scene, the World Manager keeps track of which portions of the skybox can be seen through portals leading to the outside world and then renders only those parts which are visible.
- Added sky box parameters to the World Builder, including rotation parameters for creating outer space effects.
- Added sky box support to the Ray Tracer so that environment maps pick up the sky box texture maps instead of just the background color when a ray doesn't hit anything.
- Added the ability to specify color arrays for
Renderable
objects using 4-byte colors in addition to 4-float colors. - Improved the appearance of dynamic lights when they are very close to curved surfaces.
- Implemented automatic mirror detection in the
TunnelView
class and added a winding direction state to the Graphics Manager which is flipped when rendering through a mirror. - Tweaked several special effects so that they render symmetrically through mirrors.
- Implemented automatic texture coordinate alignment in the World Editor.
- Added a rocket exhaust glow effect to the Game Module.
August 26, 2000
- Implemented a subfrustum projection matrix calculation for the
TunnelView
class which enables optimal use of hardware clipping for remotely rendered scenes through portals and mirrors. - Added fading parameters to the
TunnelMarker
class so that the transparency of the structure covering the tunnel can be adjusted based on the camera's distance from the tunnel. - Finished all optimizations for portal and tunnel rendering. The engine now performs very optimal geometry visibility culling through portals.
- Added a portal count to the graphics stats window.
- Added a function to the World Manager which enumerates all structures which intersect a given sphere. This is now used to determine what structures are illuminated by dynamic lights and what structures to which surface markings need to be applied.
- Implemented a primitive geometry class in the Ray Tracer for an inverted disk (a plate with a hole cut out of it).
- Added primitive geometry classes to the Ray Tracer corresponding to the positive halves of each of the circular geometries.
August 19, 2000
- Ripped out the enhanced BSP tree code. It wasn't working out as well as I had hoped.
- Implemented a generalized
View
class (and specialized subclasses) which represent the viewer. These will allow easier implementation of remote scene rendering (e.g., areas visible through teleporters or viewscreens). These also make the architecture for switching between the World Manager views, the Window Manager views, and anyViewport
interface elements a lot cleaner. - Implemented a remote rendering architecture which allows a scene to be rendered from multiple perspectives. This is used to produce effects such as video screens, mirrors, and teleporters through which the player can see distance regions of the world.
- Added the
TunnelMarker
class to the World Editor which specifies the location, shape, and target region for a remote rendering portal. - Added the
SoundMarker
class to the World Editor which indicates that a sound should emanate from a specific location in the World. - Added a list of sound sources to the Volume class. Sound sources belong to the smallest volume which contains their audible ranges.
- Added more precise distance functions to each structure so that dynamic lights would illuminate fewer objects that were outside their ranges.
- Added a focal length setting (which controls the field of view) to the World Manager.
August 12, 2000
- Implemented an entirely new architecture for large-scale geometry management, collision detection, and visibility determination. Worlds are now organized into a hierarchical tree of disjoint zones, each of which has its own BSP tree storing the geometry contained in the zone. When rendering, the World Manager determines inside which zone the camera lies and renders that zone's BSP tree first.
- Implemented a portal architecture which connects zones to other zones at the same level in the tree or to enclosing zones. After the BSP tree for the zone containing the camera is rendered, the World Manager scans through the list of portals for that zone. If a portal is visible, then the zone to which that portal connects is rendered in a recursive manner, but restricted to the view volume determined by the camera position and the vertices of the portal. (Thus, all world geometry rendered during a single frame must be connected to the zone containing the camera through a path of visible portals.)
- Enhanced the BSP tree design so that structures which intersect another structure's splitting plane are no longer referenced by both the positive and negative subspaces. Instead, the set of structures which intersect the splitting plane for a particular BSP tree node are further organized into another mini-BSP tree using a splitting plane perpendicular to the original splitting plane. This can happen a third time using the splitting plane perpendicular to the first two, but any geometry remaining after that (which must intersect the structure which originally split it) is just crammed onto the same BSP node.
- Implemented the following Zone subclasses:
InfiniteZone
,PolyhedronZone
,CylinderZone
,SphereZone
, andBoxZone
. - Generalized the sphere-frustum and cylinder-frustum intersection tests to work with the arbitrary polyhedral view volumes created by portals.
- Upgraded the obstruction, collision, and sound occlusion detection code to operate on the new zone hierarchy and BSP tree format.
- Removed the BSP tree for environmental volumes and replaced it with a hierarchical volume tree.
- Added an
InfiniteVolume
class to act as the top level volume in the environmental volume tree. - Added geometry flags for indicating whether structures can receive surface markings or dynamic lighting.
August 5, 2000
- Improved the surface marking triangle generation algorithm. It now creates an optimal set of triangles corresponding to the intersection of a surface with the marking boundaries.
- Implemented a generalized shader architecture. Multiple texture layers and special effects on all renderable objects are now represented by a series of
Shader
classes. - Implemented high-quality dynamic light sources using the new shader architecture.
- Improved the method by which lists of renderable objects are sorted. It is now possible to specify for each renderable object which shader (and thus which texture map) to sort by.
- Added an optimization to the
ChainStructure
rendering code. - Added the rocket launcher code and the
Rocket
projectile class to the Game Module. - Added dynamic lighting effects to the Game Module.
July 29, 2000
- Created a special
ChainGeometry
class which, during a world build, organizes a group of appropriately positioned transparent geometries into a one-sided BSP tree, or "chain". During gameplay, the correspondingChainStructure
class is then able to render all of the transparent faces in back-to-front order. This will be used primarily to render plantlife, whose texture maps generally contain a lot of transparent regions. - Rewrote most of the Display Manager. The DirectDraw code has been replaced by the equivalent Win32 function calls, the MacOS DrawSprocket code has been simplified, and the gamma loading subroutine can now be overridden (allowing the OpenGL context to install its own gamma loader).
- Added support for the
WGL_3DFX_gamma_control
extension. - Implemented display fading functionality for the Windows build (it's been Mac-only for a while).
- Added the
Global
base class template which provides a more elegant way to clean up a global pointer to an object when an exception is thrown from its constructor. - Added the
ObjectWrapper
,SharedWrapper
, andArrayWrapper
classes to encapsulate safe pointers to normal objects, reference counted objects, and arrays, respectively.
July 22, 2000
- Gave the Window Manager a major overhaul. The
Window
class andInterfaceElement
class are now derived from a newInterfaceContext
class, which is itself derived from theDrawContext
class. - Implemented a hierarchical interface element architecture. Every interface element now exists in its own local coordinate space. This will allow for easy implementation of scrolling control panels in the World Editor.
- Added the
ColorBox
interface element and the associatedColorPicker
dialog box to serve as a standard interface for choosing RGBA colors in the World Editor. - Added the ability to insert division lines into the
PopupMenu
interface element. - Added the Build Settings panel to the World Editor.
- Added a clip rectangle stack to the
DrawContext
class. - Implemented 2D clipping in text renderer.
- Added underwater behavior for the grenades in the game module.
- Implemented support for the
GL_NV_fog_distance
extension.
July 15, 2000
- Designed
Link
andLinkTarget
classes to provide a leak-proof general mechanism for cross linking between different objects. - Added boundary and interior points to the water ripple effect. Water geometry can now be carved into any arbitrary shape.
- Improved light map and environment map generation in the Ray Tracer.
- Started implementing the terrain classes in the Ray Tracer and the World Manager.
- Fixed a collision detection problem for characters when running into surfaces forming an acute angle with the ground.
- Implemented auto-scrolling for the
PopupMenu
interface element. - Finally decided that it was necessary to add general 2D draw contexts to the Window Manager. Added the
DrawContext
class which encapsulates a pixel map, a current color, a current pattern, and a clipping rectangle. It also has a movable origin. - Implemented clipping for all 2D drawing primitives. Everything is now clipped to the draw context bounds and the current clipping rectangle.
July 8, 2000
- Moved the water and fire effects into their own Structure classes and added corresponding geometry classes to the Ray Tracer and World Builder.
- Implemented per-vertex light map displacement for liquid surfaces. This allows shadows to be mapped onto the waves in the correct manner.
- Added water collision reactions to the game module. Lobbing a grenade into the water now creates waves emanating from the point of impact.
- Added generalized support for texture coordinate generation. TexGen modes currently supported are object linear, sphere map, normal vector, and reflection vector.
- Implemented support for the
GL_EXT_secondary_color
extension. - Implemented support for the
GL_NV_register_combiners
extension. - Rewrote the multipass/multitexture management portion of the main
Renderable
execution pipeline so that it could handle arbitrary register combinations. - Implemented per-pixel light map modulated specular highlight (phong) shading and applied it to the water effect.
- Added the
ReflectionAttribute
class to the Ray Tracer. - Added the
CubeMapMarker
class to the Ray Tracer and World Builder. This object is used to mark locations where cube environment maps should be ray traced when a world is built. These maps can then be referenced by geometry having the reflection attribute.
July 1, 2000
- Added a special object structure to the BSP tree building code which allows special effects such as fire to exist in the global tree, and thus drawn in the correct back-to-front order with respect to other transparent structures.
- Designed the mechanism for loading and saving world editor data and implemented C++ class serialization for all Ray Tracer objects.
- Implemented support for the
GL_EXT_texture_edge_clamp
extension. - Added support for command shortcut keys in the Window Manager.
- Implemented the ability to resize windows with real-time feedback.
- Implemented texture map copy-back from the frame buffer. This will be used to copy the contents of a 3D viewport back into a window's texture array whenever the viewport is updated.
- Added orthographic projection support to the 3D viewport dialog element.
- Changed the MacOS sound streaming thread from cooperative to preemptive, now that the operating system can handle file access in preemptive threads.
- Improved operating system event handling for both Windows and MacOS builds.
- Made the necessary changes to build the engine with Visual C++. Going from a standard-conformant compiler to Microsoft's lame compiler is a royal pain.
- Finished the File Manager reference documentation.
June 24, 2000
- Implemented dynamic level of detail for all world structures. The level of detail is chosen based on the size of each structure, its distance from the camera, and a user-defined bias.
- Implemented BSP tree order rendering for transparent world structures. Transparent structures are now rendered in back to front order after all opaque structures and after all movable objects.
- Added flags field to the
Node
class in the World Builder. These flags let the World Builder know that each subnode shares some special property with the other subnodes on the same branch. For instance, this allows one to create a detail group in which every object must change its level of detail at the same time. - Added flag to the
Geometry
class which controls whether mipmaps are generated for its light map. - Added scorch marks for grenade explosions in the game module.
June 17, 2000
- Added
Cone
geometry class to the World Builder. - Implemented collision detection for cone structures.
- Added maximum slope cut-off in the collision detection system. This prevents characters from walking up inclines that are too steep.
- Added better controls for curved surface subdivision to the World Builder.
- Added support for alternate texture map and light map natural parameterizations to the World Builder.
- Improved Sound Manager performance a bit.
June 10, 2000
- Implemented general surface marking system. Scorch marks and blood splatters can now be applied to any surface in the game.
- Added normalize render state to the
Renderable
class. This enables or disables theGL_NORMALIZE
state. - Moved the following windows to the game module: Title, Host Game, Join Game, Setup Player, Chat, and Scoreboard.
- Added notification function to the game module that lets it know when it's queried for server information.
- Improved Memory Manager copy and fill performance.
- Wrote reference documentation for the game module functions which are called from the Message Manager.
June 3, 2000
- Modified the Message Manager sending algorithm to better handle high volume outgoing message traffic.
- Added automatic port selection to the Network Manager.
- Added message flags to the Message class which specify special properties such as whether the message should be sent reliably.
- Finished the Network Manager reference documentation.
- Worked on reference documentation for the File Manager, Time Manager, and Utility Library.
May 27, 2000
- Added a network status window which displays the state of the network packet buffers.
- Beefed up security in the Network Manager to better handle junk packet attacks.
- Worked around an evil nasty bug in WinSock that can cause the wrong data to get sent across the wire.
- Added the protocol number to the server query broadcast message.
- Finished the Message Manager reference documentation.
- Started the Network Manager reference documentation.
May 20, 2000
- Added 32-bit parameter to network control packets.
- Moved protocol check to the Network Manager level.
- Moved max connections check to the Network Manager level.
- Improved packet encryption architecture a little bit.
- Added settings for reliable packet resend attempts.
- Beefed up network file transfer architecture.
- Added file request and transfer completion code to the download window.
- Moved chat message display code into the game module.
- Improved handling of connection timeouts.
May 13, 2000
- Finalized client-server network topology implementation.
- Added connect, disconnect, and timeout messages for notifying other players when someone enters or leaves a game.
- Added client orientation state update messages which are sent to the server at regular intervals.
- Fixed a rare problem in which the wrong texture map can get used right after another texture map is updated.
- Fixed a problem in which repetitively hitting the escape or tilde key could cause these keys to stop being recognized.
May 6, 2000
- Added a function to the World Manager which places a sound source in the world and applies all of the necessary spatialization effects.
- Added a modifier matrix to the
Bone
class. This allows an additional transform to be applied to a bone after the animation transform is applied. - Added spine twisting to the
Soldier
class. No matter what animation is playing, the soldier now smoothly twists his upper body to point in the direction that the player is looking. - Implemented tumbling motion for the
Grenade
projectile. - Added a small random delay to sounds attached to a Fire object so that if someone spawns or teleports into an area where they can hear a bunch of torches, the sounds aren't all in phase.
- Implemented random spawn location selection.
- Fixed a small problem with the OpenGL material state change code in the
Renderable
execution pipeline.
April 29, 2000
- Finished complete support for EAX environmental audio extensions.
- Added Environment component class to the world editor. Environments define certain properties, such as acoustics, that apply to a region of the world.
- Implemented secondary BSP tree for environment volumes. EAX listener properties are now modified depending on which environment the camera is located in.
- Added
Material
class to the world editor. Material information is now referenced by every piece of geometry in the world and describes characteristics such as elasticity, frictional properties, and acoustical properties. - Implemented sound source obstruction effects. When a spatialized sound is played, the material of any structure between the sound source and the listener is used to apply obstruction effects to the sound.
- Added
Location
marker class to the world editor. This is used for things like spawn locations and teleport destinations. - Moved most byte-swapping code into the structures on which they operate.
- Added better diagnostics to engine initialization code.
- Improved default scorch mark texture map.
- Added Audio Settings window.
April 22, 2000
- Added "Anchor to Origin" option to animation import dialog. This allows you to force a character to remain at the same position throughout an animation which would normally carry the character away from the origin.
- Implemented Fighter player class in the game module. This class serves as a base for the other player classes and takes care of simple motion sequences such as running, jumping, and turning.
- Added
MaterializeEffect
particle system to the game module. - Redesigned default particle texture map -- looks much better now.
- Added support for material diffuse colors to the
Renderable
class. - Added fading functionality to the
Model
class. - Expanded input configuration window to support an unlimited number of controls.
- Implemented basic support for EAX environmental audio extensions.
April 15, 2000
- Implemented line-of-sight obstruction determination. This is similar to collision detection, but doesn't look for the nearest collision and doesn't return any information about the point of collision itself. It's just a yes or no answer to the question "Can I see point A from point B?".
- Wrote surface marking system for scorch marks, blood splatters, etc.
- Added collision handling routines for projectiles.
- Implemented character-environment interactive collision detection, including sliding on walls and climbing stairs.
- Wrote
ChaseCamera
camera class for following players around. - Added
Grenade
projectile class to the game module. - Added weapon switching controls to the game module.
- Implemented multiple world editor viewport configurations.
- Added routine to the math library that takes an arbitrary 3D vector and returns another vector which is perpendicular to it.
April 8, 2000
- Implemented global collision detection.
- Ripped out animation sequencing code -- I'm not happy with it.
- Added frustum primitive geometry type (for visualizing cylinder-frustum intersection tests).
- Added shadow outline display for model debugging purposes.
- Beefed up shadow edge finder to handle edges shared by more than two triangles.
- Implemented weapon swapping code in the
Soldier
class.
April 1, 2000
- Added build progress window.
- Began working on the world editor window.
- Added code to clamp the cursor to the active monitor's rectangle.
- Fixed case when fog settings would not get restored after changing monitor resolutions.
- Added minimum and maximum values to
Animator
class. - Added automatic transform/position updating to the
Model
class. This is used for animation loops and transitions in which the model has been moved away from the origin. The position and orientation of the model is smoothly updated at the point that the animation loops or blends into another animation sequence. - Added
Soldier
player class to the game module. - Added
PlasmaGun
weapon class to the game module.
March 25, 2000
- Improved BSP tree construction so that fewer nodes are created.
- Added ability to have a projectile with no model so that projectiles made completely out of particles could be used.
- Took out
ParticleType
data type and changedParticleSystem
class so that you have to explicitly specify a texture map. - Implemented plasma burst projectile.
- Added input action for firing your gun.
- Wrote animation sequencing system. This includes all animation transitions and all frame-based events (for things like sound effects).
March 18, 2000
- Added a stats windows that lists how many vertices, faces, structures, etc., were rendered in a single frame.
- Removed sub-namespace for the Ray Tracer components and renamed some classes to avoid conflicts with class names in the C4 namespace.
- Added plane-frustum intersection test to the Camera class.
- Implemented BSP tree visibility culling.
- Added subclasses to the Structure class to accommodate specialized collision detection.
March 11, 2000
- Implemented cylinder-frustum intersection test. This algorithm will appear in the forthcoming book Game Programming Gems.
- Applied cylinder visibility test to shadow volumes.
- Finished BSP tree construction code in the World Builder.
- Put separate AltiVec build back into the project.
- Added cylinder primitive geometry type (for bounding volume display).
- Added plate primitive geometry type (for splitting plane display).
- Added
Vector4D
class which is now used to represent planes.
March 4, 2000
- Started game module project and moved all game-specific code to it.
- Had to roll my own run-time libraries to get cross-module exception handling to work.
- Updated config window to work with new input system features.
- Implemented cube environment map generation in the World Builder.
- Added supersampling settings to the Ray Tracer.
February 26, 2000
- Hooked up input to the local player.
- Generalized input system so that game-specific actions could be added.
- Implemented spectator mode for when there is no local player.
- Added precalculated per-frame bounding volumes to the animation resource.
- Designed system for dynamically loaded game modules.
February 19, 2000
- Implemented projection matrix based polygon offset. This technique will appear in the forthcoming book Game Programming Gems.
- Generalized the system for run-time generated textures.
- Established a division between general engine code and game-specific code.
- Added rendering options to the Mesh class to allow the enabling or disabling of things like shadows.
- Added light source attenuation factors.
- Removed Pair template.
- Added ability to install new console commands.
February 12, 2000
- Added plasma particle type.
- Designed generated texture for plasma flow.
- Added even more texture mapping support to the 3D Studio MAX plugins.
- Added animation modes to the model window.
February 5, 2000
- Beefed up 3D Studio MAX plugins to greatly increase support for different texture mapping styles.
- Rewrote model import system (mainly to extend mapping capabilities).
- Added light sources to the world resource.
- Finished model window functionality.
- Improved stencil shadowing system.
- Added
IconButton
interface element.
January 29, 2000
- Added skeleton display to the model window.
- Upgraded 3D Studio MAX plugins to support release 3.1 and added a way to extend the skeletal hierarchy.
- Added Marker object class to the World Builder. This class holds the location and properties of intangible objects such as sound sources, special effects, and spawn locations.
- Implemented a marker for the fire effect.
- Added support for all OpenGL fog modes.
- Added environmental properties to the world resource. These include things like ambient light and fog parameters.
- Removed support for the
GL_EXT_clip_volume_hint
extension. It never makes any difference.
January 22, 2000
- Removed
ColorARGB
class (all usages changed toColorRGBA
). - Added supersampling levels to lightmap generation.
- Added ability to specify texture wrapping modes in s and t directions separately.
- Added lightmap wrapping mode specification to Ray Tracer geometry classes.
- Implemented box, disk, annulus, cylinder, and dome geometry classes in the Ray Tracer.
- Implemented point and spot light classes in the Ray Tracer.
- Added texture matrix to the
TextureMapAttribute
class. - Added ability to reverse normals for all geometry classes.
- Hooked up diffuse color attribute to the World Builder.
- Added ability to attach a sound to the fire effect.
- Implemented screenshot function.
January 15, 2000
- Implemented lightmap generation system in the Ray Tracer.
- Added rendering order variable to the
Renderable
class so that transparent objects could be forced to render last. - Added function to the Time Manager for retrieving the current date and time.
- Modified fire objects so that they all use the same dynamic texture instead of each one having its own.
- Designed BSP tree architecture which allows the splitting planes to hold complex geometry.
- Implemented Structure base class which holds the geometry for a BSP tree node.
- Added tessellation system to the Ray Tracer for generating vertex data.
- Designed file format for world geometry.
- Wrote the World Builder -- this takes a scene from the world editor, builds a BSP tree, uses the Ray Tracer to generate light maps, and writes out a world resource.
January 8, 2000
- Implemented system for generating cool electrical effects.
- Added support for triangle fans, triangle strips, and quad strips.
- Modified the Text Manager to allow easier addition of new fonts.
- Generalized object type designation to allow easier addition of new object subclasses.
- Overhauled the attribute system in the Ray Tracer so that it parallels the capabilities of 3D hardware.
December 25, 1999
- Added fog render state to the
Renderable
class. - Added wireframe render state to the
Renderable
class. - Integrated cube environment map functionality into the texture combination algorithm.
- Finished the unified
Renderable
execution pipeline. Everything in the engine which can be rendered is now sorted by the texture maps that it uses and by its rendering state. When the list of renderable objects is executed, all of the details of multitexture combinations, multiple passes, and state changes now happen automatically and in optimal order. - Added rendering options to the display settings.
December 18, 1999
- Implemented texture combination modes and the multitexture/multipass algorithm.
- Added support for the
GL_EXT_texture_env_add
extension. - Added stencil buffer render state to the
Renderable
class. - Implemented stencil buffer based shadowing system. Models can now cast shadows on their environment, other models, and even themselves.
- Added animation controls to the model window.
- Simplified the
StringID
type and removed the consequently no-longer-used Array template.
December 11, 1999
- Added level of detail controls to the model import window.
- Added level of detail functionality to the model window.
- Began research on the global visibility and collision detection systems.
- Added constant color render state to the
Renderable
class. - Implemented bounding volume display.
December 4, 1999
- Added Windows support to font generator.
- Tweaked font generation a little bit to produce better spacing.
- Updated model resource format to let it take advantage of the recent rendering engine improvements.
- Finished dynamic level of detail system for rigid and deformable meshes.
- Began experimenting with fractal tree generation.
November 27, 1999
- Implemented new generalized rendering architecture. Every renderable object is now subclassed from a new
Renderable
class which encapsulates all of the vertex buffer, texture, and state information needed to draw itself. - Included support for arbitrary multitexturing, which uses as many texture units as are available in hardware and reverts to multiple passes if there are more texture layers than the hardware can handle.
- Added support for several vertex buffer primitives.
- Modified several systems to use new vertex buffer types where appropriate.
- Implemented sort-by-state rendering to minimize hardware state changes.
- Improved texture map resource management.
- Added
RemoveAll()
function to theList
template.
November 20, 1999
- Redesigned menu architecture. Every menu now exists as a separate window, allowing it to extend outside the window that it is attached to, as well as enabling some other effects.
- Improved texture map dicing algorithm for window contents.
- Fixed bug that screwed up shadows for windows with small height.
- Integrated AltiVec build into standard MacOS build. The startup code now detects the AltiVec processor and sets some function pointers accordingly.
- Implemented covariant normal transformation in the Ray Tracer.
- Added support for the
GL_EXT_clip_volume_hint
extension. - Removed device list from control settings window.
- Integrated font generation tool into C4 source.
November 13, 1999
- Rewrote the Network Manager. There is now no limit on the number of simultaneous connections, and symmetric support for reliable and unreliable packets has been added. Also removed restriction on IP port numbers.
- Changed
List
template so that adding an object to a list would automatically remove it from any other list that it was a member of, removing the need to callDetach()
. - Added fix to the Input Manager to handle cases when the user presses multiple keys/buttons which map to the same action.