No Title
At the most basic level, you can use the file format and file-access routines provided by QuickDraw3D to read and display 3D graphics created by some other application. For example, a word-processing application might want to import a picture created by a 3D modeling or image-capturing application. QuickDraw3D supports the 3D Viewer, which you can use to display 3D data and objects in a window and allow users limited interaction with that data, without having to learn any of the core QuickDraw3D application programming interfaces.
See the chapter "3D Viewer" for complete information about the 3D viewer, as well as complete source code samples illustrating how to create and manage a
viewer object.<8bat>u
You can also use QuickDraw3D for more sophisticated applications, such as interactive 3D modeling and rendering, animation, data visualization, or any of thousands of other ways of interpreting and displaying data in three (or more) dimensions. Figure 1-1 illustrates the kinds of images you can produce using QuickDraw3D. It shows a texture, a wireframe model, and the result of applying the texture to that model. See also Color Plate 3 at the beginning of this book.
Figure 1-1 A simple three-dimensional picture
In QuickDraw3D, modeling involves
In QuickDraw3D, interacting involves
Figure 1-2 A model rendered by the wireframe renderer
The interactive renderer uses a more complex rendering algorithm that allows illumination and shading effects to be produced. Figure 1-3 shows the same teapot model rendered by the interactive renderer.
Figure 1-3 A model rendered by the interactive renderer
QuickDraw3D is extensible:
Figure 1-4 shows the functional components of QuickDraw3D.
Figure 1-4 The parts of QuickDraw3D
kQ3
. Very simple constants consist solely of the kQ3
prefix and a specific value indicator. Here are some examples:
typedef enum TQ3Boolean { kQ3False, kQ3True } TQ3Boolean; typedef enum TQ3Status { kQ3Failure, kQ3Success } TQ3Status;Most other enumerated constants consist of the standard
kQ3
prefix, followed by a type, followed by a specific value. Here are some examples:
typedef enum TQ3Axis { kQ3AxisX, kQ3AxisY, kQ3AxisZ } TQ3Axis;Other constants are defined using the C preprocessor
#define
mechanism. Here are some examples:
#define kQ3ObjectTypeElement Q3_OBJECT_TYPE('e','l','m','n') #define kQ3ObjectTypePick Q3_OBJECT_TYPE('p','i','c','k') #define kQ3ObjectTypeShared Q3_OBJECT_TYPE('s','h','r','d') #define kQ3ObjectTypeView Q3_OBJECT_TYPE('v','i','e','w') #define kQ3ObjectTypeInvalid 0In general, these kinds of constants specify types of objects in the QuickDraw3D class hierarchy or methods defining the behaviors of those types. These constants use the macros
Q3_OBJECT_TYPE
or Q3_METHOD_TYPE
. See page 3-19 for a definition of these macros.TQ3
. Like constant names, data type names never contain the underscore character (_
). When emphasis is required, subwords of a data type name are capitalized and usually proceed from general to specific.There are four distinguishable classes in data type names.
TQ3
and end with the suffix Object
. Between the prefix and the suffix are one or more words indicating the type of the opaque object. Here are some examples:
TQ3GeometryObject TQ3ViewObject TQ3CameraObject TQ3StyleObject TQ3DrawContextObject
TQ3
and end with the suffix Data
. Between the prefix and the suffix are one or more words indicating the type of the object. Here are some examples:
TQ3TriangleData TQ3BoxData TQ3OrthographicCameraData
TQ3
. Following the prefix are one or more words indicating the type of the data the structure contains. Here are some examples:
TQ3Point3D TQ3Vector2D TQ3ColorRGB TQ3ColorARGB
TQ3Attribute
.
Q3
. The class of an identifier immediately follows its type prefix. Then the method occurs, separated from the class by an underscore. A method is almost always expressed as a verb-noun sequence. Here are some examples:
Q3Polygon_GetVertexPosition Q3NURBCurve_SetControlPoint Q3Light_SetBrightness Q3SpotLight_GetFallOff Q3View_GetLocalToWorldInverseTransposeMatrixState Q3Triangle_NewSome functions are so simple that they have no distinguishable class and method. Here are some examples:
Q3Initialize Q3IsInitialized Q3ExitAs much as possible, function parameters are ordered consistently throughout the application programming interfaces. In virtually all cases, the first parameter is a data type that corresponds to the object being operated on. When there are two or more additional parameters, they are placed in their natural or intuitive ordering.
Most QuickDraw3D functions return a status code, which is of type TQ3Status
. A status code is either kQ3Success
or kQ3Failure
, indicating that the function has succeeded or failed. When a function fails, you can call a further function to get a specific error code. Alternatively, you can install an error-reporting callback routine to handle failures. See the chapter "Error Manager" for complete details on handling errors.
Functions that create opaque objects usually return a function result whose type is a reference to the type of the newly created object (for instance, TQ3CameraObject
for a new camera object). An object reference is an opaque pointer to the object. When these kinds of routines fail, they return the
value NULL
.
By contrast, a graphics system operates in immediate mode if the application itself maintains the data that describe a model. For example, original QuickDraw is a two-dimensional graphics system that operates in immediate mode. You draw objects on the screen, using QuickDraw, by calling routines that completely specify the objects to be drawn. QuickDraw does not maintain any information about a picture internally; it simply takes the data provided by the application and immediately draws the appropriate objects.
OpenGL
QuickDraw3D supports both immediate and retained modes of specifying and drawing models. The principal advantage of immediate mode imaging is that the model data is immediately available to you and is not duplicated by the graphics system. The data is stored in whatever form you like, and you can change that data at any time. The main disadvantage of immediate mode imaging is that you need to maintain the sometimes quite lengthy object data, and you need to perform geometric operations on that data yourself. In addition, it can be difficult to accelerate immediate mode rendering, because you generally need to specify the entire model to draw a single frame, whether or not the entire model has changed since the previous frame. This can involve passing large amounts of data to the graphics system.
Retained mode imaging typically supports higher levels of abstraction than immediate mode imaging and is more amenable to hardware acceleration and caching. In addition, the hierarchical arrangement of the model data allows the graphics system to perform very quick updates whenever the data is altered. To avoid duplicating data between your application and the graphics system's database, your application should match the data types of the graphics system and use the extensive editing functions to change a model's data.
Another important advantage of retained mode imaging is that it's very easy to read and write retained objects.
To create a point, for example, in retained mode, you fill in a data structure
It's much simpler to draw a point in immediate mode. You do not need to
Immediate mode rendering does not require any memory permanently allocated to QuickDraw3D, but it might require QuickDraw3D to perform temporary allocations while rendering is occurring.<8bat>u
In general, if most of a model remains unchanged from frame to frame, you should use retained mode imaging to create and draw the model. If, however, many parts of the model do change from frame to frame, you should probably use immediate mode imaging, creating and rendering a model on a shape-by-
Let us know what you think of these prototype pages. Generated with Harlequin WebMaker
retained mode.<8bat>u
of type TQ3PointData
and pass it to the Q3Point_New
function. This
function copies the data in that structure and returns an object of type TQ3GeometryObject
, which you use for all subsequent operations on the point. For example, to draw the point in retained mode, you pass that geometric object returned by Q3Point_New
to the Q3Geometry_Submit
function inside
a rendering loop. To change the data associated with the point, you
call point-editing functions, such as Q3Point_GetPosition
and Q3Point_SetPosition
. Finally, when you have finished using the point, you must call Q3Object_Dispose
to have QuickDraw3D delete the point from its internal database.
call any QuickDraw3D routine to create a point in immediate mode; instead, you merely have to maintain the point data yourself, typically in a structure
of type TQ3PointData
. To draw a point in immediate mode, you call the Q3Point_Submit
function, passing it a pointer to that structure. Note,
however, that when using immediate mode, you need to know exactly
what types of objects you're drawing and hardcode the appropriate routines
in your source code.
shape basis. You can, of course, use a combination of retained and immediate mode imaging: you can create retained objects for the parts of a model that remain static and draw quickly changing objects in immediate mode.
3D Graphics Programming with QuickDraw 3D - 14 OCT 1995