Lib3d Version 0.1.7 - Fast, Free 3D
Overview
Lib3d is a high performance 3d library for X windows and DOS. Lib3d
implements Gouraud shading and Z-buffer rasterization, with support
for 8, 16 and 32 bit graphics modes. Lib3d will make 160,000
lit, z-buffered, Gouraud shaded triangles per second on a
standard Pentium 100.
Compared to other renderers, this makes Lib3d about 3.5 times faster
than TAGL v22, many times faster than Mesa, and perhaps half as fast as a
good commercial renderer.
Lib3d is distributed under the GNU Library General Public License,
which allows use in commercial products subject to some quite
reasonable conditions.
Development of lib3d is ongoing and contributions are invited. Lib3d
has been developed under Linux and is also known to compile and run
under Solaris. Ports to other 32 bit architectures and operating
systems should be very simple. A contributed DOS port is included starting
at version 0.1.5.
Any comments, patches, contributions, bug fixes, etc. are more than
welcome. Email me at
keithw@ozemail.com.au.
Mailing List
There is now a mailing list for Lib3d. To subscribe, send a message
body containing the word 'subscribe' to:
lib3d-users-request@hermetica.com
To send a message to the list:
lib3d-users@hermetica.com
The mailing list is archived
here.
Links
Alligator Descarte has a page with some sample images:
http://www.hermetica.com/technologia/lib3d/
Getting It
The latest distribution (source only) is available
as a .tar.gz archive,
or as a zip file.
There is a mirror site in the US:
ftp://ftp.mcqueen.com/pub/graphics/lib3d
Timings
Timed on a Pentium 100 running Linux 1.3.93,
DGA interface,
300x250 viewport,
8bpp dithered visual,
full Z buffer,
single light,
ambient+diffuse lighting,
no precalculated lighting or other dirty tricks:
Rotating a teapot on its vertical axis:
3751 poly teapot, no clipping: 160k poly/sec flat, 138k/sec smooth.
3751 poly teapot, clipping: 112k poly/sec flat, 95k/sec smooth.
240 poly teapot, no clipping: 50k poly/sec, 41k/sec smooth.
240 poly teapot, clipping: 23k poly/sec, 20k/sec smooth.
Timings for a 16 bpp visual are about 10% below these results.
Comparision with Other Renderers
Mesa and commercial renderers provide additional
functionality, particularly texture mapping, and hardware support
which isn't present in lib3d as yet. Mesa is unique amongst the free
renderers in having a comprehensive, stable and well-documented API.
Much has been made of Mesa's relatively poor performance. Lib3d
originated from work I was doing looking at improving Mesa's
performance in the case where display lists are used. In that
situation, Mesa holds internally all of the information required to
construct a Lib3d-style optimized representation, and perform
rendering at comparable rates. The task of performing this
unification is left as an exercise for the reader.
Changes:
A DOS port has been contributed by Markus Oberhumer
(markus.oberhumer@jk.uni-linz.ac.at), and is included starting with v0.1.5.
Here is his description:
In the meanwhile I've ported lib3d to MSDOS using djgpp v2 + gcc
2.7.2. [...] It uses the free Allegro graphics library for low-level
video management. Allegro is available from many places, e.g. ftp://x2ftp.oulu.fi/pub/msdos/programming/djgpp2
Versions 0.1.7 and 0.1.6:
Fixes for the DOS port.
Fix for DGA support at higher bit depths.
Version 0.1.5:
DOS port contributed by Markus Oberhumer
(markus.oberhumer@jk.uni-linz.ac.at)
Support for mulitple pixel depth X servers, contributed by
Tim Rowley (tor@cs.brown.edu)
Xlib interface - render into a window/widget of your choice,
bypassing the standard, platform independent interface. Based
on work by Alligator Descartes (descarte@hermetica.com)
Experimental DGA support under XFree86.
Directory structure reorganization.
Changes to try to help compilation with earlier versions of g++.
Removed the private classes from FlatPipeline and SmoothPipeline,
which were giving problems with even quite recent g++'s.
Sundry bugfixes, particularly with regards to colour ramps.
Fix the Pipeline pointer initialization bug in v0.1.4.
Version 0.1.4:
Gouraud shading.
Calculation of vertex normals in ModelBuilder to support gouraud
shading.
Swapped parameter names in Camera::setParameters() to concur with
usage and functionality. Reported by Alligator Descartes
(descarte@hermetica.com)
Version 0.1.3:
Bugfix for XShm detection, contributed by Oleg Girko (ol@niif.ru).
Bugfix for HrTimer initialization, contributed by Frank M. Siegert
(frank@miranda.tue.schwaben.de)
Fix for clipping bug, reported by Henning Schmiedehausen
(barnard@forge.franken.de)
Fix for z interpolation of single pixel height polygons in
flatPolygonZb().
Partially implemented 8Bpp colourIndex visual, with i386 assembly
inner loops.
Ongoing tuning in DitherVisual.C. Slight (5%) improvement on v0.1.2.
Fix to object space culling which eliminates most of the above performance gain (sigh).
First hints of documentation (see doc/*)
Version 0.1.2:
40-50% speed improvement on version 0.1.1. (138k poly/sec on a P100)
A reader for TAGL-style .geom files.
Some bug fixes.
Current Status
lib3d is currently implemented in a conservative subset of C++,
allowing scope for an easy C api or even a future port back to C.
Most of the compulsory optimizations are present, including:
Bounding box culling and clip plane selection.
Backface culling in object space.
Lighting calculations in object space.
Model optimization including shared vertex, shared normal and shared
material detection.
Culling and lighting per normal and per light rather than per polygon.
8+24bit Zbuffer which need only be cleared once every 256 frames.
Dirty region support for swapBuffer(), clearBuffer() and clearZBuffer().
All maths is floating point (except for rasterization), and there is no assembly (yet).
Technical Overview
Lib3d is a high level, retained-mode API with a similar flavor to the
commercial renderers which have appeared recently. Retained-mode
describes a system dictated by the requirements of efficient software
implementation, and describes a system where the full geometry of the
rendered environment is retained by the renderer from scene to scene.
The scene geometry is described by a hierarchy of fixed-geometry nodes
with arcs at the points of potentially free movement.
The nodes in this tree include the models (objects), lights and
cameras. The top of the tree is just a placeholder, called World in
lib3d. The tree must contain a camera and at least one model in order
for meaningful rendering to proceed.
The three dimensional space of each node is transformed to the space
of the parent node by the child's transformation matrix. Because the
transformations accumulate, when a node's transformation matrix is
changed, the change affects all of that node's children. As an
example, consider the following tree:
World
|
+-----Model: racetrack.nff
|
+-----Model: car.nff
|
+-----Light: headlight
|
+-----Camera: driver
The car is positioned on the track with the driver inside the car and
the lights at the head of the car, both pointing forwards. By
changing the car's transformation matrix, the car, the camera and
headlights all move together as a single unit. The camera gives a
view of the track as if from inside a moving car.
As well as being convenient for the programmer, this is a good
structure for software implementation of a 3d renderer. The largely
static nature of the tree allows large scale optimization of the model
structure (recognition of shared vertices, normals, materials etc),
the application of techniques such as bounding-box culling as well as
caching of tranformation information from scene to scene.
Device Handling
Framebuffer handling is split into Devices, which handle the
allocation of a back buffer for drawing and for performing the
swapBuffer() method, and Visuals, which draw the actual polygons to
the back buffer and must be aware of the pixel layout.
Thus there are devices to handle X, DGA and DOS, which all interact with
the 8bpp dithered visual.
The following have been implemented:
Blitting Dga Device. (fastest of the X devices)
XShmImage Device.
Pageflipping Dga Device.
XImage Device.
DOS/Allegro Device.
8bpp visual with 2x2 ordered dithering.
16bpp visual for rgb:565 pixels.
32bpp visual for rgb:0888 pixels.
Pipelines
There is now support for multiple pipelines. Three are implemented;
wireframe, flat and smooth (gouraud) shading, all with an
ambient+directional lighting model.
The smooth pipeline has the restriction of a single diffuse colour
over all active lights. If there is more than one diffuse colour,
white is used instead. This is due to use of the 'ramp' lighting
technique, the advantage of which is that only a single value,
intensity, needs to be calculated at each vertex. Thus,
theoretically, smooth shading requires only a single additional add
per pixel.
Maths
All maths is done in floating point so far. And I seem to have used
the opposite matrix formation to everyone else.
Utilities
The program testworld.C demonstrates a near finished NFF reader.
The API is a little short on functionality to manipulate the hierarchy
once it has been built. This is a reflection of the limited use the
library has had so far.
Future Work, Request for Contributions
The following would be much appreciated:
An svgalib device.
Ports to Windows and other Unixes.
Assembly implementations of the polygon rasterization functions.
Visuals for other pixel layouts.
Texture mapping.
Programmers documentation.
Platform-independent mouse and keyboard API's.