Introduction to Quesa
written by Dair Grant
Introduction to Quesa
Quesa is a high-level 3D graphics API, designed to complement lower-level 3D drawing APIs such as OpenGL. It provides a powerful set of building blocks for constructing 3D worlds, giving applications access to features which are not normally found in lower-level APIs. Quesa is also a cross-platform library, and runs natively on Mac OS X, Windows, Mac OS 8/9, and Linux. The Mac port can be built with either CodeWarrior or Project Builder, and can generate Carbon, Cocoa, or Classic libraries.
quesa01.gif
Quesa Platforms
History
Before adopting OpenGL, Apple developed their own 3D graphics API. Known as “QuickDraw 3D” (QD3D), this was moderately successful on the Mac but never really gained widespread support with cross-platform developers. Although eventually shipped for Windows as part of QuickTime, it was primarily a Mac-focused technology.
At their 1999 WWDC developer conference Apple announced that they no longer planned to support QD3D on Mac OS X. This caused some discussion on the QD3D mailing list, and I decided to investigate the feasibility of re-implementing the QD3D API as a 3rd party library. This library would have to be developed without reference to or use of any Apple source code, but retain binary and source level compatibility with the original. Luckily the QD3D API provided a very clean design, and a prototype followed fairly readily.
This prototype formed the basis for the Quesa (pronounced “kes-ah”) project, and at WWDC 2000 Quesa was successfully built as a native Carbon library on Mac OS X DP4.
Quesa vs. OpenGL
A common misconception, which stems from Apple adopting OpenGL over QD3D for Mac OS X, is that Quesa is intended to be a competitor to OpenGL or Direct3D. The reality is that these APIs tackle different problems, and that Quesa is designed to complement APIs like OpenGL rather than replace them. While OpenGL focuses on improving rendering performance, Quesa is intended to improve developer productivity—to provide the services which many 3D applications need, but that drawing APIs such as OpenGL do not provide.
quesa03.gif
Architecture
The structure is as illustrated, with Quesa sitting between the application and OpenGL. Since Quesa calls down to OpenGL to perform rendering, applications can also side-step Quesa at any point and invoke OpenGL directly. This process is completely transparent to OpenGL, as it has no way of knowing if it is being invoked directly by the application or via Quesa on the application’s behalf.
This flexibility gives applications the best of both worlds: direct access to a low-level rendering API for advanced features, and a powerful high-level API to tackle tasks such as picking or iterating over the objects in the world.
Overview
Advantages
One of the main strengths of Quesa is that it provides a powerful set of building blocks for constructing a 3D world. These features are not found in APIs such as OpenGL or Direct3D, and each application must typically provide their own implementation to manage their data.
Another unusual advantage is that it insulates your code from the underlying rendering engine. This allows Quesa to provide non-interactive rendering capabilities, such as a pen-and-ink rendering style or even a ray-tracer. It also serves as future proofing, in case OpenGL itself is superseded on the Mac at some point.
quesa04.gif
MacDopplerPRO
Quesa has around 1,300 API calls, exposed as an object-orientated C API. Every Quesa object is opaque, reference counted, and derived from a common base type. The overall style is quite similar to Mac OS X’s Core Foundation API. Every function name follows a standard naming convention, that of Q3Type_Action. This system makes it very easy to “predict” new API calls—once you know that the data for a triangle can be fetched with Q3Triangle_GetData, the obvious (and correct) way to fetch the data for a NURB patch object would be through Q3NURBPatch_GetData.
Since the API is quite large, we will examine four features which Quesa provides that OpenGL does not (or provides only in a rudimentary form).
Geometries
Quesa provides 21 different geometry objects, from the simple (e.g. points, lines, or triangles) to the complex (e.g. spheres, torii, or NURBS). It also provides an efficient triangle mesh object (the TriMesh) which maps directly to OpenGL vertex arrays, and a flexible mesh object composed of an unlimited number of arbitrary polygons.
quesa05.gif
Chess
Quesa converts all geometries to TriMeshes for rendering, and uses an automatic caching system to rebuild these TriMeshes on the fly. This allows applications to work with high-level geometries such as spheres or cones, yet still have them converted to an efficient form when rendering. The geometry system was designed to be extensible, and will be prompted to a public API in the future. This will allow applications to register their own geometry types, and to work with them as if they were built-in geometry objects.
For example, an application could register a new “dumbbell” geometry, defining it as a pair of spheres and a cylinder. Once this definition had been introduced to Quesa, it would be fully integrated into the caching system and would be decomposed automatically to produce TriMeshes for rendering.
Math Library
As well as a rich set of basic 3D types (e.g. points, vectors, matrices, quaternions, or bounding volumes), Quesa also includes an extensive math library. OpenGL does not provide these data types, and expects applications to provide their own definitions.
Quesa’s math library provides both basic manipulations such as addition, scaling, or dot products, and more complex operations such as manipulating matrices or quaternions. There are also batch-processing APIs for transforming arrays of points or vectors, which will be optimized for vector engines such as AltiVec in the future.
Quesa also extends the QD3D math library with new APIs such as ray-box/sphere/plane intersection tests, and allows most of the trivial math functions to be declared as inlines. This means that operations such as vector normalization or dot products can be performed directly in application code, without the overhead of a call to an external library.
Groups
One of the most powerful features in Quesa is the concept of groups. These come in several flavours, but are a type of Quesa object that can contain other Quesa objects. Given that a group object is itself a Quesa object, groups can contain other groups along with objects such as textures or geometries. This provides the basis for the hierarchical scene graph in Quesa, as an entire scene can be stored as a set of nested groups.
quesa06.gif
Setting Sun
Since groups can keep track of the bounding volume of their contents, this allows for automatic visibility culling. A group that contains 1,000 objects could test its cumulative bounds and cull every object within itself instantly if it found itself off-screen, rather than having to test each object individually.
Groups are also used to inherit state within the scene, allowing objects within a group to inherit their properties from their parent group (or from their parent group’s parent group, and so on up to the top level). For example, inserting a texture or a color into a group will affect any other objects placed in that group (including objects in sub-groups), and lets you chain together effects to be inherited through the scene.
Picking
OpenGL provides the ability to read back rendered values from the frame buffer. Picking can be implemented on top of this mechanism, one common method being to render each object with a unique color and to use the color under the mouse to identify the selected object.
Quesa provides a rich set of picking APIs, and allows objects to be selected in several ways. The most common is to query the scene under a window point, which will return the object(s) under the mouse. Picking can also be done over an area within the window (like a rubber-band selection in a 2D drawing application), or by firing an arbitrary 3D ray through the world.
The 3D ray form of picking is particularly powerful, as it allows simple collision detection simply by firing a ray from the front of an object and seeing what other objects in the world it hits.
Since Quesa picks mathematically rather than by rendering, it is able to return a great deal of information about the selection. This includes a sorted list of all the objects under the pick, and data such as the coordinates, normal, or UV of the intersection on those objects.
Future Goals
The primary goal of Quesa has always been to implement the existing QD3D API. This phase is now largely complete, and the next stage is to focus on performance improvements and new extensions. One obvious direction for extensions is to add features which were not feasible to add when QD3D used the RAVE rendering API, but which are now possible using OpenGL. This could include upcoming OpenGL extensions for more efficient geometry processing, or existing staples such as lens flare, light maps, bump mapping, or environment maps. Quesa uses Apple’s HeaderDoc system to generate API-level documentation, however we are in need of people able and willing to write general level docs. If you’d be interested in working on documentation, please sign up for the mailing list and let us know.
Learning More About Quesa
The primary source of information on Quesa is our web site, which can be found at http://www.quesa.org. Please sign up for the mailing list if you have any questions, and grab the latest source from the CVS server if you’d like to check it out. If you have any questions you’d like to ask me directly, feel free. The official Apple QD3D book is available online, which covers all of the main concepts in the API.
Useful Links
Quesa is the basis for the object-orientated 3D API in REAL Software’s REALbasic, and if you’re curious about 3D it’s a great environment for experimenting in. As well as being one of the developers working on Quesa, REAL’s Joe Strout maintains an RB3D FAQ, and has written several 3D articles for the RB Developer magazine.
There are a number of links to other 3D engines (several of which sit on top of OpenGL, as Quesa does) at the 3D Engines site. I would encourage you to check them out, and compare the feature sets of various APIs to what is available in Quesa.
introduction,to,quesa