Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
NameAttrTest.c
/* this is box, modified to be a test for the name plug-in attribute */ |
// NameAttrTest.c - QuickDraw 3d routines |
// |
// This is box, the QuickDraw 3D starter program. Written for the |
// Getting started with QuickDraw 3D Develop article. This app does not have |
// graceful error handling - it's purpose is to illustrate a very basic QuickDraw |
// 3D program. |
// |
// Nick Thompson, Robert Dierkes - April 24, 1997 |
// |
// ©1994-97 Apple computer Inc., All Rights Reserved |
// |
// system headers |
#include <Devices.h> |
#include <Dialogs.h> |
#include <DiskInit.h> |
#include <Fonts.h> |
#include <Menus.h> |
#include <PictUtils.h> |
#include <QDOffScreen.h> |
#include <QuickDraw.h> |
#include <SegLoad.h> |
#include <StandardFile.h> |
#include <TextEdit.h> |
#include <strings.h> |
#include <string.h> |
// for QuickDraw 3D |
#include "QD3D.h" |
#include "QD3DAcceleration.h" |
#include "QD3DCamera.h" |
#include "QD3DDrawContext.h" |
#include "QD3DGeometry.h" |
#include "QD3DGroup.h" |
#include "QD3DLight.h" |
#include "QD3DMath.h" |
#include "QD3DPick.h" |
#include "QD3DRenderer.h" |
#include "QD3DSet.h" |
#include "QD3DShader.h" |
#include "QD3DTransform.h" |
#include "NameAttribute.h" |
//------------------------------------------------------------------------------------------- |
struct _documentRecord { |
TQ3ViewObject fView ; // the view for the scene |
TQ3GroupObject fModel ; // object in the scene being modelled |
TQ3StyleObject fInterpolation ; // interpolation style used when rendering |
TQ3StyleObject fBackFacing ; // whether to draw shapes that face away from the camera |
TQ3StyleObject fFillStyle ; // whether drawn as solid filled object or decomposed to components |
TQ3Matrix4x4 fRotation; // the transform for the model |
}; |
typedef struct _documentRecord DocumentRec, *DocumentPtr, **DocumentHdl ; |
//------------------------------------------------------------------------------------------- |
// function prototypes |
void InitDocumentData( |
DocumentPtr theDocument ) ; |
void DisposeDocumentData( |
DocumentPtr theDocument ) ; |
void SubmitDocumentData( |
DocumentPtr theDocument ) ; |
TQ3Status DocumentDraw3DData( |
DocumentPtr theDocument ) ; |
short HiWrd( |
long aLong) ; |
short LoWrd( |
long aLong ) ; |
void InitToolbox( |
void ) ; |
void PickAndProcess( |
WindowPtr window, |
DocumentPtr theDocument, |
Point mouseLoc ) ; |
void ChangeObjectName( |
TQ3GeometryObject objectPicked, |
TQ3AttributeSet attribSet) ; |
void MainEventLoop( |
void ) ; |
void HandleKeyPress( |
EventRecord *event ) ; |
TQ3ViewObject MyNewView( |
WindowPtr theWindow ) ; |
TQ3DrawContextObject MyNewDrawContext( |
WindowPtr theWindow ) ; |
TQ3CameraObject MyNewCamera( |
WindowPtr theWindow) ; |
TQ3GroupObject MyNewLights( |
void ) ; |
void MyColorBoxFaces( |
TQ3BoxData *myBoxData ) ; |
TQ3GroupPosition MyAddTransformedObjectToGroup( |
TQ3GroupObject theGroup, |
TQ3Object theObject, |
TQ3Vector3D *translation ) ; |
TQ3GroupObject MyNewModel( |
void ) ; |
//------------------------------------------------------------------------------------------- |
// |
Boolean gQuitFlag = false ; |
WindowPtr gMainWindow = nil ; |
DocumentRec gDocument ; |
//------------------------------------------------------------------------------------------- |
// main() |
// entry point for the application, initialize the toolbox, initialize QuickDraw 3D |
// and enter the main event loop. On exit from the main event loop, we want to call |
// the QuickDraw 3D exit function to clean up QuickDraw 3d. |
void main(void) |
{ |
TQ3Status myStatus; |
Rect rBounds = { 50, 50, 450, 450 } ; |
Str255 title = "\pName Attributes on Geometries" ; |
InitToolbox() ; |
// Initialize QuickDraw 3D, open a connection to the QuickDraw 3D library |
myStatus = Q3Initialize(); |
if ( myStatus == kQ3Failure ) |
{ |
DebugStr("\pQ3Initialize returned failure. Use QD3D debug version to find out why."); |
ExitToShell() ; |
} |
// set up our globals |
gQuitFlag = false ; |
gMainWindow = NewCWindow(nil,&rBounds,title,true,noGrowDocProc,(WindowPtr)-1,true,0) ; |
InitDocumentData( &gDocument ) ; |
MainEventLoop(); |
DisposeDocumentData( &gDocument ) ; |
// Close our connection to the QuickDraw 3D library |
myStatus = Q3Exit(); |
if ( myStatus == kQ3Failure ) |
DebugStr("\pQ3Exit returned failure. Use debug version to find out why"); |
ExitToShell() ; |
} |
//------------------------------------------------------------------------------------------- |
// |
void InitDocumentData( DocumentPtr theDocument ) |
{ |
// sets up the 3d data for the scene |
// Create view for QuickDraw 3D. |
theDocument->fView = MyNewView( (WindowPtr)gMainWindow ) ; |
// the main display group: |
theDocument->fModel = MyNewModel() ; |
// the drawing styles: |
theDocument->fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ; |
theDocument->fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleBoth ) ; |
theDocument->fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ; |
// set the rotation matrix the identity matrix |
Q3Matrix4x4_SetIdentity(&theDocument->fRotation); |
} |
//----------------------------------------------------------------------------- |
// |
void DisposeDocumentData( DocumentPtr theDocument) |
{ |
Q3Object_Dispose(theDocument->fView) ; // the view for the scene |
Q3Object_Dispose(theDocument->fModel) ; // object in the scene being modelled |
Q3Object_Dispose(theDocument->fInterpolation) ; // interpolation style used when rendering |
Q3Object_Dispose(theDocument->fBackFacing) ; // whether to draw shapes that face away from the camera |
Q3Object_Dispose(theDocument->fFillStyle) ; // whether drawn as solid filled object or decomposed to components |
} |
//----------------------------------------------------------------------------- |
// |
void SubmitDocumentData( |
DocumentPtr theDocument ) |
{ |
Q3Style_Submit( theDocument->fInterpolation, theDocument->fView ); |
Q3Style_Submit( theDocument->fBackFacing, theDocument->fView ); |
Q3Style_Submit( theDocument->fFillStyle, theDocument->fView ); |
Q3MatrixTransform_Submit( &theDocument->fRotation, theDocument->fView ); |
Q3DisplayGroup_Submit( theDocument->fModel, theDocument->fView ); |
} |
//----------------------------------------------------------------------------- |
// |
TQ3Status DocumentDraw3DData( DocumentPtr theDocument ) |
{ |
Q3View_StartRendering(theDocument->fView ); |
do { |
SubmitDocumentData( theDocument ) ; |
} while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse ); |
Q3View_Sync( theDocument->fView ) ; |
return kQ3Success ; |
} |
//------------------------------------------------------------------------------------------- |
// |
short HiWrd(long aLong) |
{ |
return (((aLong) >> 16) & 0xFFFF) ; |
} |
//------------------------------------------------------------------------------------------- |
// |
short LoWrd(long aLong) |
{ |
return ((aLong) & 0xFFFF) ; |
} |
//------------------------------------------------------------------------------------------- |
// |
void InitToolbox() |
{ |
Handle menuBar = nil; |
MaxApplZone() ; |
MoreMasters() ; MoreMasters() ; MoreMasters() ; |
InitGraf( &qd.thePort ); |
InitFonts(); |
InitWindows(); |
InitCursor(); |
FlushEvents( everyEvent, 0 ) ; |
/* initialize application globals */ |
gQuitFlag = false; |
} |
//------------------------------------------------------------------------------------------- |
// |
void PickAndProcess( |
WindowPtr window, |
DocumentPtr theDocument, |
Point mouseLoc ) |
{ |
TQ3WindowPointPickData myWindowPointPickData; |
TQ3GeometryObject objectPicked; |
TQ3PickObject pickObject = NULL ; |
unsigned long numPicked; |
unsigned long i; |
TQ3AttributeSet attribSet; |
/* set up the picking data field */ |
myWindowPointPickData.data.sort = kQ3PickSortNearToFar; |
myWindowPointPickData.data.mask = kQ3PickDetailMaskObject; |
myWindowPointPickData.data.numHitsToReturn = kQ3ReturnAllHits; |
/* get the point of the click in local (window) co-ordinates */ |
GlobalToLocal( &mouseLoc ) ; |
myWindowPointPickData.point.x = mouseLoc.h ; |
myWindowPointPickData.point.y = mouseLoc.v ; |
myWindowPointPickData.vertexTolerance = 3.0 ; |
myWindowPointPickData.edgeTolerance = 3.0 ; |
if ((pickObject = Q3WindowPointPick_New( &myWindowPointPickData )) != NULL) { |
Q3View_StartPicking(theDocument->fView, pickObject); |
do { |
SubmitDocumentData(theDocument) ; |
} while (Q3View_EndPicking(theDocument->fView) == kQ3ViewStatusRetraverse ); |
} |
if (Q3Pick_GetNumHits(pickObject, &numPicked) == kQ3Success) { |
/* Get all geometries hit */ |
for (i = 0; i < numPicked; i++) { |
if (Q3Pick_GetPickDetailData( |
pickObject, |
i, |
kQ3PickDetailMaskObject, |
&objectPicked) == kQ3Failure) { |
break; |
} |
/* switch on/off highlighting for this object */ |
Q3Geometry_GetAttributeSet(objectPicked, &attribSet); |
if (!attribSet) { |
attribSet = Q3AttributeSet_New(); |
Q3Geometry_SetAttributeSet(objectPicked, attribSet); |
} |
/* Set or get the name of the geometry hit */ |
ChangeObjectName(objectPicked, attribSet); |
Q3Object_Dispose(attribSet); |
Q3Object_Dispose(objectPicked); |
} |
DocumentDraw3DData( theDocument ) ; |
} |
Q3Object_Dispose(pickObject); |
} |
//------------------------------------------------------------------------------------------- |
// |
void ChangeObjectName( |
TQ3GeometryObject objectPicked, |
TQ3AttributeSet attribSet) |
{ |
DialogPtr theDialog ; |
Handle itemHndl = nil; |
Rect itemRect ; |
short itemType ; |
short itemHit ; |
TQ3Switch highlightSwitch ; |
char nameString[255] ; |
if ( NameAttribute_GetName( objectPicked, nameString) == kQ3Success && |
*nameString != '\0') { |
c2pstr(nameString); |
ParamText((unsigned char *)nameString, (unsigned char *)"\0", (unsigned char *)"\0", (unsigned char *)"\0" ) ; |
Alert( 128, nil ) ; |
/* add the hightlight attribute it's off now */ |
highlightSwitch = kQ3Off ; |
Q3AttributeSet_Add(attribSet, |
kQ3AttributeTypeHighlightState, |
&highlightSwitch); |
} |
else { |
/* add the hightlight attribute it is on now*/ |
highlightSwitch = kQ3On ; |
Q3AttributeSet_Add(attribSet, |
kQ3AttributeTypeHighlightState, |
&highlightSwitch); |
theDialog = GetNewDialog(128, nil, (WindowPtr)-1) ; |
do { |
ModalDialog(nil, &itemHit); |
} while( itemHit != 1 ) ; |
GetDialogItem(theDialog, 4, &itemType, (Handle*)&itemHndl, &itemRect); |
GetDialogItemText(itemHndl, (StringPtr) nameString); |
DisposeDialog( theDialog ) ; |
if( itemHndl != nil && objectPicked != nil ) |
{ |
p2cstr((StringPtr) nameString) ; |
NameAttribute_SetName( objectPicked, (char *)nameString) ; |
} |
DisposeHandle( (Handle)itemHndl ) ; |
} |
} |
//------------------------------------------------------------------------------------------- |
// |
void MainEventLoop() |
{ |
EventRecord event; |
WindowPtr window; |
short thePart; |
Rect screenRect, updateRect; |
Point aPoint = {100, 100}; |
CGrafPtr savedPort ; |
while( !gQuitFlag ) |
{ |
if (WaitNextEvent( everyEvent, &event, 10, nil )) |
{ |
switch (event.what) { |
case mouseDown: |
thePart = FindWindow( event.where, &window ); |
switch( thePart ) { |
case inMenuBar: |
break; |
case inDrag: |
screenRect = (**GetGrayRgn()).rgnBBox; |
DragWindow( window, event.where, &screenRect ); |
break ; |
case inContent: |
if (window != FrontWindow()) |
SelectWindow( window ); |
else |
PickAndProcess( window, &gDocument, event.where ) ; |
break ; |
case inGoAway: |
if (TrackGoAway( window, event.where )) { |
DisposeWindow ( window ); |
gQuitFlag = true; |
} |
break ; |
default: |
break ; |
} |
break ; |
case updateEvt: |
window = (WindowPtr)event.message; |
updateRect = (**(window->visRgn)).rgnBBox; |
SetPort( window ) ; |
BeginUpdate( window ); |
DocumentDraw3DData( &gDocument ) ; |
EndUpdate( window ); |
break ; |
case keyDown: |
case autoKey: |
HandleKeyPress(&event); |
break; |
case diskEvt: |
if ( HiWrd(event.message) != noErr ) |
(void) DIBadMount(aPoint, event.message); |
break; |
case osEvt: |
case activateEvt: |
break; |
} |
} |
else { |
// we received a null event, rotate the cube |
TQ3Matrix4x4 tmp; |
Rect theRect = ((GrafPtr)gMainWindow)->portRect ; |
SetPort((GrafPtr)gMainWindow) ; |
Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.1, 0.12, 0.08); |
Q3Matrix4x4_Multiply(&gDocument.fRotation, &tmp, &gDocument.fRotation); |
InvalRect( &theRect ) ; |
} |
} |
} |
//------------------------------------------------------------------------------------------- |
// |
void HandleKeyPress( |
EventRecord *event) |
{} |
//------------------------------------------------------------------------------------------- |
// |
TQ3ViewObject MyNewView( |
WindowPtr theWindow) |
{ |
TQ3Status myStatus; |
TQ3ViewObject myView; |
TQ3DrawContextObject myDrawContext; |
TQ3RendererObject myRenderer; |
TQ3CameraObject myCamera; |
TQ3GroupObject myLights; |
myView = Q3View_New(); |
// Create and set draw context. |
if ((myDrawContext = MyNewDrawContext(theWindow)) == nil ) |
goto bail; |
if ((myStatus = Q3View_SetDrawContext(myView, myDrawContext)) == kQ3Failure ) |
goto bail; |
Q3Object_Dispose( myDrawContext ) ; |
// Create and set renderer. |
// this would use the wireframe renderer |
#if 0 |
myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeWireFrame); |
if ((myStatus = Q3View_SetRenderer(myView, myRenderer)) == kQ3Failure ) { |
goto bail; |
} |
#else |
// this would use the interactive software renderer |
if ((myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeInteractive)) != nil ) { |
if ((myStatus = Q3View_SetRenderer(myView, myRenderer)) == kQ3Failure ) { |
goto bail; |
} |
// these two lines set us up to use the best possible renderer, |
// including hardware if it is installed. |
Q3InteractiveRenderer_SetDoubleBufferBypass (myRenderer, kQ3True); |
Q3InteractiveRenderer_SetPreferences(myRenderer, kQAVendor_BestChoice, 0); |
} |
else { |
goto bail; |
} |
#endif |
Q3Object_Dispose( myRenderer ) ; |
// Create and set camera. |
if ( (myCamera = MyNewCamera(theWindow)) == nil ) |
goto bail; |
if ((myStatus = Q3View_SetCamera(myView, myCamera)) == kQ3Failure ) |
goto bail; |
Q3Object_Dispose( myCamera ) ; |
// Create and set lights. |
if ((myLights = MyNewLights()) == nil ) |
goto bail; |
if ((myStatus = Q3View_SetLightGroup(myView, myLights)) == kQ3Failure ) |
goto bail; |
Q3Object_Dispose(myLights); |
// Done!!! |
return ( myView ); |
bail: |
// If any of the above failed, then don't return a view. |
return ( nil ); |
} |
//---------------------------------------------------------------------------------- |
TQ3DrawContextObject MyNewDrawContext( |
WindowPtr theWindow ) |
{ |
TQ3DrawContextData myDrawContextData; |
TQ3MacDrawContextData myMacDrawContextData; |
TQ3ColorARGB ClearColor; |
TQ3DrawContextObject myDrawContext ; |
// Set the background color. |
ClearColor.a = 1.0; |
ClearColor.r = 1.0; |
ClearColor.g = 1.0; |
ClearColor.b = 1.0; |
// Fill in draw context data. |
myDrawContextData.clearImageMethod = kQ3ClearMethodWithColor; |
myDrawContextData.clearImageColor = ClearColor; |
myDrawContextData.paneState = kQ3False; |
myDrawContextData.maskState = kQ3False; |
myDrawContextData.doubleBufferState = kQ3True; |
myMacDrawContextData.drawContextData = myDrawContextData; |
myMacDrawContextData.window = (CGrafPtr) theWindow; // this is the window associated with the view |
myMacDrawContextData.library = kQ3Mac2DLibraryNone; |
myMacDrawContextData.viewPort = nil; |
myMacDrawContextData.grafPort = nil; |
// Create draw context and return it, if itÕs nil the caller must handle |
myDrawContext = Q3MacDrawContext_New(&myMacDrawContextData) ; |
return myDrawContext ; |
} |
//---------------------------------------------------------------------------------- |
TQ3CameraObject MyNewCamera( |
WindowPtr theWindow) |
{ |
TQ3ViewAngleAspectCameraData perspectiveData; |
TQ3CameraObject camera; |
TQ3Point3D from = { 0.0, 0.0, 7.25 }; |
TQ3Point3D to = { 0.0, 0.0, 0.0 }; |
TQ3Vector3D up = { 0.0, 1.0, 0.0 }; |
float fieldOfView = 1.0; |
float hither = 0.1; |
float yon = 10; |
TQ3Status returnVal = kQ3Failure ; |
perspectiveData.cameraData.placement.cameraLocation = from; |
perspectiveData.cameraData.placement.pointOfInterest = to; |
perspectiveData.cameraData.placement.upVector = up; |
perspectiveData.cameraData.range.hither = hither; |
perspectiveData.cameraData.range.yon = yon; |
perspectiveData.cameraData.viewPort.origin.x = -1.0; |
perspectiveData.cameraData.viewPort.origin.y = 1.0; |
perspectiveData.cameraData.viewPort.width = 2.0; |
perspectiveData.cameraData.viewPort.height = 2.0; |
perspectiveData.fov = fieldOfView; |
perspectiveData.aspectRatioXToY = |
(float) (theWindow->portRect.right - theWindow->portRect.left) / |
(float) (theWindow->portRect.bottom - theWindow->portRect.top); |
camera = Q3ViewAngleAspectCamera_New(&perspectiveData); |
return camera ; |
} |
//---------------------------------------------------------------------------------- |
TQ3GroupObject MyNewLights( |
void ) |
{ |
TQ3GroupPosition myGroupPosition; |
TQ3GroupObject myLightList; |
TQ3LightData myLightData; |
TQ3PointLightData myPointLightData; |
TQ3DirectionalLightData myDirectionalLightData; |
TQ3LightObject myAmbientLight, myPointLight, myFillLight; |
TQ3Point3D pointLocation = { -10.0, 0.0, 10.0 }; |
TQ3Vector3D fillDirection = { 10.0, 0.0, 10.0 }; |
TQ3ColorRGB WhiteLight = { 1.0, 1.0, 1.0 }; |
// Set up light data for ambient light. This light data will be used for point and fill |
// light also. |
myLightData.isOn = kQ3True; |
myLightData.color = WhiteLight; |
// Create ambient light. |
myLightData.brightness = .2; |
myAmbientLight = Q3AmbientLight_New(&myLightData); |
if ( myAmbientLight == nil ) |
goto bail; |
// Create point light. |
myLightData.brightness = 1.0; |
myPointLightData.lightData = myLightData; |
myPointLightData.castsShadows = kQ3False; |
myPointLightData.attenuation = kQ3AttenuationTypeNone; |
myPointLightData.location = pointLocation; |
myPointLight = Q3PointLight_New(&myPointLightData); |
if ( myPointLight == nil ) |
goto bail; |
// Create fill light. |
myLightData.brightness = .2; |
myDirectionalLightData.lightData = myLightData; |
myDirectionalLightData.castsShadows = kQ3False; |
myDirectionalLightData.direction = fillDirection; |
myFillLight = Q3DirectionalLight_New(&myDirectionalLightData); |
if ( myFillLight == nil ) |
goto bail; |
// Create light group and add each of the lights into the group. |
myLightList = Q3LightGroup_New(); |
if ( myLightList == nil ) |
goto bail; |
myGroupPosition = Q3Group_AddObject(myLightList, myAmbientLight); |
if ( myGroupPosition == 0 ) |
goto bail; |
myGroupPosition = Q3Group_AddObject(myLightList, myPointLight); |
if ( myGroupPosition == 0 ) |
goto bail; |
myGroupPosition = Q3Group_AddObject(myLightList, myFillLight); |
if ( myGroupPosition == 0 ) |
goto bail; |
Q3Object_Dispose( myAmbientLight ) ; |
Q3Object_Dispose( myPointLight ) ; |
Q3Object_Dispose( myFillLight ) ; |
// Done! |
return ( myLightList ); |
bail: |
// If any of the above failed, then return nothing! |
return ( nil ); |
} |
void MyColorBoxFaces( |
TQ3BoxData *myBoxData ) |
{ |
TQ3ColorRGB faceColor ; |
short face ; |
// sanity check - you need to have set up |
// the face attribute set for the box data |
// before calling this. |
if( myBoxData->faceAttributeSet == NULL ) |
return ; |
// make each face of a box a different color |
for( face = 0; face < 6; face++) { |
myBoxData->faceAttributeSet[face] = Q3AttributeSet_New(); |
switch( face ) { |
case 0: |
faceColor.r = 1.0; |
faceColor.g = 0.0; |
faceColor.b = 0.0; |
break; |
case 1: |
faceColor.r = 0.0; |
faceColor.g = 1.0; |
faceColor.b = 0.0; |
break; |
case 2: |
faceColor.r = 0.0; |
faceColor.g = 0.0; |
faceColor.b = 1.0; |
break; |
case 3: |
faceColor.r = 1.0; |
faceColor.g = 1.0; |
faceColor.b = 0.0; |
break; |
case 4: |
faceColor.r = 1.0; |
faceColor.g = 0.0; |
faceColor.b = 1.0; |
break; |
case 5: |
faceColor.r = 0.0; |
faceColor.g = 1.0; |
faceColor.b = 1.0; |
break; |
} |
Q3AttributeSet_Add(myBoxData->faceAttributeSet[face], kQ3AttributeTypeDiffuseColor, &faceColor); |
} |
} |
TQ3GroupPosition MyAddTransformedObjectToGroup( |
TQ3GroupObject theGroup, |
TQ3Object theObject, |
TQ3Vector3D *translation ) |
{ |
TQ3TransformObject transform; |
transform = Q3TranslateTransform_New(translation); |
Q3Group_AddObject(theGroup, transform); |
Q3Object_Dispose(transform); |
return Q3Group_AddObject(theGroup, theObject); |
} |
TQ3GroupObject MyNewModel( |
void ) |
{ |
TQ3GroupObject myGroup = NULL; |
TQ3GroupPosition myGroupPosition; |
TQ3ShaderObject myIlluminationShader ; |
TQ3BoxData boxData; |
TQ3ConeData coneData; |
TQ3CylinderData cylinderData; |
TQ3TorusData torusData; |
TQ3GeometryObject boxGeo, |
coneGeo, |
cylinderGeo, |
torusGeo; |
short face ; |
TQ3SetObject boxFaces[6] ; |
TQ3ColorRGB color; |
TQ3Vector3D translation; |
// Create a group for the complete model. |
// do not use Q3OrderedDisplayGroup_New since in this |
// type of group all of the translations are applied before |
// the objects in the group are drawn, in this instance we |
// dont want this. |
if ((myGroup = Q3DisplayGroup_New()) != NULL ) { |
// Define a shading type for the group |
// and add the shader to the group |
myIlluminationShader = Q3PhongIllumination_New(); |
if (myIlluminationShader != NULL ) { |
Q3Group_AddObject(myGroup, myIlluminationShader); |
Q3Object_Dispose(myIlluminationShader); |
} |
// create the box |
// set up the colored faces for the box data |
boxData.faceAttributeSet = boxFaces; |
boxData.boxAttributeSet = nil; |
MyColorBoxFaces( &boxData ) ; |
Q3Point3D_Set(&boxData.origin, 0, 0, 0); |
Q3Vector3D_Set(&boxData.orientation, 0, 1.25, 0); |
Q3Vector3D_Set(&boxData.majorAxis, 0, 0, 2); |
Q3Vector3D_Set(&boxData.minorAxis, 1.25, 0, 0); |
boxGeo = Q3Box_New(&boxData); |
// create the cone |
Q3Point3D_Set(&coneData.origin, 0, 0, 0); |
Q3Vector3D_Set(&coneData.orientation, 0, 1.75, 0); |
Q3Vector3D_Set(&coneData.majorRadius, 0, 0, 0.75); |
Q3Vector3D_Set(&coneData.minorRadius, 0.75, 0, 0); |
coneData.uMin = 0.0; |
coneData.uMax = 1.0; |
coneData.vMin = 0.0; |
coneData.vMax = 1.0; |
coneData.caps = kQ3EndCapMaskBottom; |
coneData.interiorAttributeSet = NULL; |
coneData.faceAttributeSet = NULL; |
coneData.bottomAttributeSet = NULL; |
coneData.coneAttributeSet = Q3AttributeSet_New(); |
if (coneData.coneAttributeSet != NULL ) { |
Q3ColorRGB_Set(&color, 0.3, 0.9, 0.9); |
Q3AttributeSet_Add(coneData.coneAttributeSet, kQ3AttributeTypeDiffuseColor, &color); |
} |
coneGeo = Q3Cone_New(&coneData); |
// create the cylinder |
Q3Point3D_Set(&cylinderData.origin, 0, 0, 0); |
Q3Vector3D_Set(&cylinderData.orientation, 0, 1.25, 0); |
Q3Vector3D_Set(&cylinderData.majorRadius, 0, 0, 0.75); |
Q3Vector3D_Set(&cylinderData.minorRadius, 0.75, 0, 0); |
cylinderData.uMin = 0.0; |
cylinderData.uMax = 1.0; |
cylinderData.vMin = 0.0; |
cylinderData.vMax = 1.0; |
cylinderData.caps = kQ3EndCapMaskTop | kQ3EndCapMaskBottom; |
cylinderData.interiorAttributeSet = NULL; |
cylinderData.topAttributeSet = NULL; |
cylinderData.faceAttributeSet = NULL; |
cylinderData.bottomAttributeSet = NULL; |
cylinderData.cylinderAttributeSet = Q3AttributeSet_New(); |
if (cylinderData.cylinderAttributeSet != NULL ) { |
Q3ColorRGB_Set(&color, 0.9, 0.3, 0.9); |
Q3AttributeSet_Add(cylinderData.cylinderAttributeSet, kQ3AttributeTypeDiffuseColor, &color); |
} |
cylinderGeo = Q3Cylinder_New(&cylinderData); |
// create the torus |
Q3Point3D_Set(&torusData.origin, 0, 0.8, 0); |
Q3Vector3D_Set(&torusData.orientation, 0, 0.4, 0); |
Q3Vector3D_Set(&torusData.majorRadius, 0, 0, 0.75); |
Q3Vector3D_Set(&torusData.minorRadius, 0.75, 0, 0); |
torusData.ratio = 1.0; |
torusData.uMin = 0.0; |
torusData.uMax = 1.0; |
torusData.vMin = 0.0; |
torusData.vMax = 1.0; |
torusData.caps = kQ3EndCapNone; |
torusData.interiorAttributeSet = NULL; |
torusData.torusAttributeSet = Q3AttributeSet_New(); |
if (torusData.torusAttributeSet != NULL ) { |
Q3ColorRGB_Set(&color, 1.0, 1.0, 0.0); |
Q3AttributeSet_Add(torusData.torusAttributeSet, kQ3AttributeTypeDiffuseColor, &color); |
} |
torusGeo = Q3Torus_New(&torusData); |
// add all geometries to group and translate them |
Q3Vector3D_Set(&translation, 0, 0, 0); |
MyAddTransformedObjectToGroup( myGroup, boxGeo, &translation ) ; |
Q3Object_Dispose( boxGeo ); |
for( face = 0; face < 6; face++) { |
if( boxData.faceAttributeSet[face] != NULL ) |
Q3Object_Dispose(boxData.faceAttributeSet[face]); |
} |
Q3Vector3D_Set(&translation, 2, 0, 0); |
MyAddTransformedObjectToGroup( myGroup, coneGeo, &translation ) ; |
Q3Object_Dispose(coneGeo); |
if (coneData.coneAttributeSet != NULL ) |
Q3Object_Dispose(coneData.coneAttributeSet); |
Q3Vector3D_Set(&translation, 0, 0, -2); |
MyAddTransformedObjectToGroup( myGroup, cylinderGeo, &translation ) ; |
Q3Object_Dispose(cylinderGeo); |
if (cylinderData.cylinderAttributeSet != NULL ) |
Q3Object_Dispose(cylinderData.cylinderAttributeSet); |
Q3Vector3D_Set(&translation, -2, 0, 0); |
MyAddTransformedObjectToGroup( myGroup, torusGeo, &translation ) ; |
Q3Object_Dispose(torusGeo); |
if (torusData.torusAttributeSet != NULL ) |
Q3Object_Dispose(torusData.torusAttributeSet); |
} |
return ( myGroup ); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14