3D Graphics Programming with QuickDraw 3D
Q3LightGroup_New
function. If there is sufficient memory to create the group, Q3LightGroup_New
returns to your application a reference to a group object, which you pass to other group routines. The new group is initially empty, and you add objects to the group by calling QuickDraw3D routines (such as Q3Group_AddObject
). When an object is added to a group, its reference count is incremented. (QuickDraw3D uses the reference count to ensure that an object is not prematurely disposed.) If you don't want to maintain references to all the objects inside a group, you can use the technique illustrated in Listing 10-1.Listing 10-1 Creating a group
myGroup = Q3LightGroup_New
();
myLight = Q3SpotLight_New(mySpotLightData);
Q3Group_AddObject(myGroup, myLight);
Q3Object_Dispose(myLight);
By calling Q3Object_Dispose
, you decrement the light's reference count once it's been added to the light group. When the group itself is later disposed of, QuickDraw3D decrements the light's reference count, which may cause it also to be disposed of.
Listing 10-2 shows how to access all the lights in a light group. The MyTurnOnOrOffAllLights
function takes a view parameter and an on/off state value. It turns all the lights in the view's light group on or off, as specified by the state value.
Listing 10-2 Accessing all the lights in a light group
TQ3Status MyTurnOnOrOffViewLights (TQ3ViewObject myView, TQ3Boolean myState) { TQ3GroupObject myGroup; /*the view's light group*/ TQ3GroupPosition myPos; /*a group position*/ TQ3Object myLight; /*a light*/ TQ3Status myResult; /*a result code*/ myResult = Q3View_GetLightGroup(myView, &myGroup); if (myResult == kQ3Failure) goto bail; for (Q3Group_GetFirstPosition(myGroup, &myPos); myPos != NULL; Q3Group_GetNextPosition(myGroup, &myPos)) { myResult = Q3Group_GetPositionObject(myGroup, myPos, myLight); if (myResult == kQ3Failure) goto bail; myResult = Q3Light_SetState(myLight, myState); Q3Object_Dispose(myLight); /*balance reference count of light*/ } return(kQ3Success); bail: return(kQ3Failure); }You can use the looping technique illustrated in Listing 10-2 to traverse ordered display groups as well, as shown in Listing 10-3. The function
MyToggleOrderedGroupLights
traverses an ordered display group and toggles any lights it finds. Notice that MyToggleOrderedGroupLights
calls the Q3Group_GetFirstPositionOfType
function to find the position of the first light in the group.Listing 10-3 Accessing all the lights in an ordered display group
TQ3Status MyToggleOrderedGroupLights (TQ3GroupObject myGroup) { TQ3GroupPosition myPos; /*a group position*/ TQ3Object myLight; /*a light*/ TQ3Boolean myState; /*a light state*/ TQ3Status myResult; /*a result code*/ for (Q3Group_GetFirstPositionOfType(myGroup, kQ3ShapeTypeLight, &myPos); myPos != NULL; Q3Group_GetNextPositionOfType(myGroup, kQ3ShapeTypeLight, &myPos)) { myResult = Q3Group_GetPositionObject(myGroup, myPos, myLight); if (myResult == kQ3Failure) goto bail; myResult = Q3Light_GetState(myLight, &myState); myState = !myState; /*toggle the light state*/ myResult = Q3Light_SetState(myLight, myState); Q3Object_Dispose(myLight); /*balance reference count of light*/ } return(kQ3Success); bail: return(kQ3Failure); }It's also possible to find the position of the next object in an ordered display group by calling the
Q3Group_GetNextPosition
function. Q3Group_GetNextPosition
is not, however, guaranteed to return a position of an object that is of the same type as the object immediately before it. If you use Q3Group_GetNextPosition
to iterate through an ordered display group, you must therefore make sure not to step past the part of the list that contains objects of the type you're interested in. Listing 10-4 shows, in outline, how to call Q3Group_GetNextPosition
to iterate safely through an object type in an ordered display group.
Listing 10-4 Accessing all the lights in an ordered display group using Q3Group_GetNextPosition
TQ3GroupPosition myFirst; /*group position of first light*/ TQ3GroupPosition myLast; /*group position of last light*/ TQ3Object myLight; /*a light*/ TQ3Status myResult; /*a result code*/ Q3Group_GetFirstPositionOfType(myGroup, kQ3ShapeTypeLight, &myFirst); if (myFirst) { Q3Group_GetLastPositionOfType(myGroup, kQ3ShapeTypeLight, &myLast); do { myResult = Q3Group_GetPositionObject(myGroup, myFirst, myLight); if (myResult == kQ3Failure) goto bail; myResult = Q3Light_GetState(myLight, &myState); myState = !myState; /*toggle the light state*/ myResult = Q3Light_SetState(myLight, myState); Q3Object_Dispose(myLight); /*balance reference count of light*/ Q3Group_GetNextPosition(myGroup, &myFirst); } while (myFirst != myLast); }
Let us know what you think of these prototype pages.
Generated with Harlequin WebMaker