home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Archive / Graphics / QD3D / rollercoaster / Sources / QD3DSupport.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  24.1 KB  |  825 lines  |  [TEXT/dosa]

  1.  
  2.  
  3. /*
  4.     File:        QD3DSupport.c
  5.     
  6.     Contains:    QD3D support routines
  7.     
  8.     Written by:    Scott Kuechle, based on original Gerbils code by Brian Greenstone
  9.  
  10.     Copyright:    © 1998 by Apple Computer, Inc. All rights reserved
  11.     
  12.     Change History (most recent first)
  13.     
  14.         <2>        9/28/98        rtm        made changes for Metrowerks compiler
  15.         <1>        9/01/98        srk        first file
  16.  
  17.  
  18. */
  19.  
  20. /************************************************************
  21. *                                                           *
  22. *    INCLUDE FILES                                          *
  23. *                                                           *
  24. *************************************************************/
  25.  
  26. #include "QD3DSupport.h"
  27. #include "Utils.h"
  28.  
  29.  
  30. /************************************************************
  31. *                                                           *
  32. *    FUNCTION PROTOTYPES                                    *
  33. *                                                           *
  34. *************************************************************/
  35.  
  36. #if TARGET_OS_MAC
  37.     static TQ3ViewObject             QD3DSupport_NewView(WindowPtr theWindow);
  38.     static TQ3DrawContextObject     QD3DSupport_NewDrawContext(WindowPtr theWindow);
  39.     static TQ3ShaderObject             QD3DSupport_CreateShaderFromTexture(short grndTextureResourceID);
  40. #else if TARGET_OS_WIN32
  41.     static TQ3ViewObject             QD3DSupport_NewView(HWND theWindow);
  42.     static TQ3DrawContextObject     QD3DSupport_NewDrawContext(HWND theWindow);
  43.     static TQ3ShaderObject             QD3DSupport_CreateShaderFromTexture(LPTSTR    grndTextureFilePath);
  44. #endif
  45.  
  46. static TQ3GroupObject             QD3DSupport_GroundInit(TQ3ShaderObject    groundShaderObject);
  47. static TQ3CameraObject             QD3DSupport_NewCamera(float docWidth, float docHeight);
  48. static TQ3GroupObject            QD3DSupport_NewLights(void);
  49. static OSErr                     QD3DSupport_QuickTimeInit (void);
  50. static TQ3GroupObject             QD3DSupport_NewTrackGroup(TQ3ShaderObject    theShader);
  51.  
  52.  
  53.  
  54. /************************************************************
  55. *                                                           *
  56. *    FUNCTION:  QD3DSupport_NewView                         *
  57. *                                                           *
  58. *    PURPOSE:   Creates a new QD3D view object, along with  *
  59. *               the accompanying draw context, light and    *
  60. *               camera objects                              *
  61. *                                                           *
  62. *************************************************************/
  63.  
  64. #if TARGET_OS_MAC
  65.     static TQ3ViewObject QD3DSupport_NewView(WindowPtr theWindow)
  66. #else if TARGET_OS_WIN32
  67.     static TQ3ViewObject QD3DSupport_NewView(HWND theWindow)
  68. #endif
  69. {
  70.     TQ3Status                myStatus;
  71.     TQ3ViewObject            myView;
  72.     TQ3DrawContextObject    myDrawContext;
  73.     TQ3RendererObject        myRenderer;
  74.     TQ3GroupObject            myLights;
  75.     TQ3CameraObject            myCamera;
  76. #if TARGET_OS_WIN32
  77.     RECT                    clientRect;
  78.     BOOL                    success;
  79. #endif
  80.  
  81.  
  82.         myView = Q3View_New();
  83.         if (myView == nil)
  84.         {
  85.             goto bail;
  86.         }
  87.  
  88.         //    Create and set draw context.
  89.         if ((myDrawContext = QD3DSupport_NewDrawContext(theWindow)) == nil )
  90.         {
  91.             goto bail;
  92.         }
  93.             
  94.         if ((myStatus = Q3View_SetDrawContext(myView, myDrawContext)) == kQ3Failure )
  95.         {
  96.             goto bail;
  97.         }
  98.  
  99.         Q3Object_Dispose( myDrawContext ) ;
  100.         
  101.         //    Create and set renderer.
  102.         
  103.         // this would use the Z-Buffer renderer
  104.     #if 0
  105.  
  106.         myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeWireFrame);
  107.         if ((myStatus = Q3View_SetRenderer(myView, myRenderer)) == kQ3Failure ) {
  108.             goto bail;
  109.         }
  110.         
  111.     #else
  112.  
  113.         // this would use the interactive software renderer
  114.  
  115.         if ((myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeInteractive)) != nil )
  116.         {
  117.             if ((myStatus = Q3View_SetRenderer(myView, myRenderer)) == kQ3Failure )
  118.             {
  119.                 goto bail;
  120.             }
  121.             // these two lines set us up to use the best possible renderer,
  122.             // including  hardware if it is installed.
  123.             Q3InteractiveRenderer_SetDoubleBufferBypass (myRenderer, kQ3True);                        
  124.             Q3InteractiveRenderer_SetPreferences(myRenderer, kQAVendor_BestChoice, 0);
  125.  
  126.         }
  127.         else
  128.         {
  129.             goto bail;
  130.         }
  131.     #endif
  132.  
  133.         Q3Object_Dispose( myRenderer ) ;
  134.         
  135.         //    Create and set camera.
  136.         #if TARGET_OS_MAC
  137.             if ( (myCamera = QD3DSupport_NewCamera((float) (theWindow->portRect.right - theWindow->portRect.left),
  138.                                                     (float) (theWindow->portRect.bottom - theWindow->portRect.top))) == nil )
  139.             {
  140.                 goto bail;
  141.             }
  142.         #else if TARGET_OS_WIN32
  143.             success = GetClientRect(theWindow, &clientRect);
  144.             if (success)
  145.             {
  146.                 if ( (myCamera = QD3DSupport_NewCamera((float)RECT_WIDTH(clientRect), (float)RECT_HEIGHT(clientRect))) == nil )
  147.                 {
  148.                     goto bail;
  149.                 }
  150.             }
  151.             else
  152.             {
  153.                 goto bail;
  154.             }
  155.         #endif
  156.             
  157.         if ((myStatus = Q3View_SetCamera(myView, myCamera)) == kQ3Failure )
  158.         {
  159.             goto bail;
  160.         }
  161.         Q3Object_Dispose( myCamera ) ;
  162.         
  163.         //    Create and set lights.
  164.         if ((myLights = QD3DSupport_NewLights()) == nil )
  165.         {
  166.             goto bail;
  167.         }
  168.             
  169.         if ((myStatus = Q3View_SetLightGroup(myView, myLights)) == kQ3Failure )
  170.         {
  171.             goto bail;
  172.         }
  173.             
  174.         Q3Object_Dispose(myLights);
  175.  
  176.         //    Done!!!
  177.         return ( myView );
  178.         
  179.     bail:
  180.         //    If any of the above failed, then don't return a view.
  181.         return ( nil );
  182. }
  183.  
  184.  
  185. /************************************************************
  186. *                                                           *
  187. *    FUNCTION:  QD3DSupport_NewDrawContext                  *
  188. *                                                           *
  189. *    PURPOSE:   Creates a new QD3D draw context object      *
  190. *                                                           *
  191. *                                                           *
  192. *                                                           *
  193. *                                                           *
  194. *************************************************************/
  195.  
  196. #if TARGET_OS_MAC
  197.  
  198. static TQ3DrawContextObject QD3DSupport_NewDrawContext(WindowPtr theWindow)
  199. {
  200.     TQ3DrawContextData        myDrawContextData;
  201.     TQ3MacDrawContextData    myMacDrawContextData;
  202.     TQ3ColorARGB            ClearColor;
  203.     TQ3DrawContextObject    myDrawContext ;
  204.     
  205.         /*    Set the background color. */
  206.         ClearColor.a = 1.0F;
  207.         ClearColor.r = 0.0F;
  208.         ClearColor.g = 0.0F;
  209.         ClearColor.b = 1.0F;
  210.         
  211.         /*    Fill in draw context data. */
  212.         myDrawContextData.clearImageMethod    = kQ3ClearMethodWithColor;
  213.         myDrawContextData.clearImageColor    = ClearColor;
  214.         myDrawContextData.paneState            = kQ3False;
  215.         myDrawContextData.maskState            = kQ3False;
  216.         myDrawContextData.doubleBufferState = kQ3True;
  217.      
  218.         myMacDrawContextData.drawContextData = myDrawContextData;
  219.         
  220.         myMacDrawContextData.window = (CGrafPtr) theWindow;        // this is the window associated with the view
  221.         myMacDrawContextData.library = kQ3Mac2DLibraryNone;
  222.         myMacDrawContextData.viewPort = nil;
  223.         myMacDrawContextData.grafPort = (CGrafPtr) theWindow;
  224.         
  225.         /*    Create draw context and return it, if it’s nil the caller must handle */
  226.         myDrawContext = Q3MacDrawContext_New(&myMacDrawContextData) ;
  227.  
  228.         return myDrawContext ;
  229. }
  230.  
  231.  
  232. #else if TARGET_OS_WIN32
  233.  
  234. static TQ3DrawContextObject QD3DSupport_NewDrawContext(HWND theWindow)
  235. {
  236.  
  237.     TQ3DrawContextData            myDrawContextData;
  238.     TQ3Win32DCDrawContextData    myWin32DCDrawContextData;
  239.     TQ3DrawContextObject        myDrawContext ;
  240.     DWORD                        wndClassStyle;
  241.     TQ3ColorARGB                ClearColor;
  242.  
  243.  
  244.         /*    Set the background color. */
  245.  
  246.         ClearColor.a = 1.0;
  247.         ClearColor.r = 0.0;
  248.         ClearColor.g = 0.0;
  249.         ClearColor.b = 1.0;
  250.  
  251.         /*    Fill in draw context data. */
  252.  
  253.         myDrawContextData.clearImageMethod    = kQ3ClearMethodWithColor;
  254.         myDrawContextData.clearImageColor    = ClearColor;
  255.         myDrawContextData.paneState            = kQ3False;
  256.         myDrawContextData.maskState            = kQ3False;
  257.         myDrawContextData.doubleBufferState = kQ3True;
  258.  
  259.         myWin32DCDrawContextData.drawContextData = myDrawContextData;
  260.  
  261.         /* Assertion: window MUST be CS_OWNDC */
  262.  
  263.         wndClassStyle = GetClassLong( theWindow, GCL_STYLE );
  264.         if( CS_OWNDC != ( wndClassStyle & CS_OWNDC ) )
  265.         {
  266.             return NULL;
  267.         }
  268.  
  269.         /* set up the win32DCDrawContext */
  270.         myWin32DCDrawContextData.hdc = GetDC( theWindow );
  271.  
  272.         /*    Create draw context and return it, if it's NULL the caller must handle */
  273.         myDrawContext = Q3Win32DCDrawContext_New(&myWin32DCDrawContextData) ;
  274.  
  275.         ReleaseDC(theWindow, myWin32DCDrawContextData.hdc);
  276.  
  277.         return myDrawContext ;
  278.  
  279. }
  280.  
  281. #endif
  282.  
  283. /************************************************************
  284. *                                                           *
  285. *    FUNCTION:  QD3DSupport_NewCamera                       *
  286. *                                                           *
  287. *    PURPOSE:   Creates our camera                          *
  288. *                                                           *
  289. *                                                           *
  290. *************************************************************/
  291.  
  292. static TQ3CameraObject QD3DSupport_NewCamera(float             docWidth,
  293.                                             float             docHeight)
  294. {
  295.     TQ3ViewAngleAspectCameraData    perspectiveData;
  296.     TQ3CameraObject                    camera;
  297.     
  298.     TQ3Point3D                     from     = { 30.0F, 50.0F, -50.0F };
  299.     TQ3Point3D                     to         = { 30.0F, 0.0F, 0.0F };
  300.     TQ3Vector3D                 up         = { 0.0F, 1.0F, 0.0F };
  301.  
  302.     float                         fieldOfView = 1.2F;
  303.     float                         hither         = 0.2F;
  304.     float                         yon         = 200.0F;
  305.     
  306.  
  307.         perspectiveData.cameraData.placement.cameraLocation     = from;
  308.         perspectiveData.cameraData.placement.pointOfInterest     = to;
  309.         perspectiveData.cameraData.placement.upVector             = up;
  310.  
  311.         perspectiveData.cameraData.range.hither    = hither;
  312.         perspectiveData.cameraData.range.yon     = yon;
  313.  
  314.         perspectiveData.cameraData.viewPort.origin.x     =     -1.0F;
  315.         perspectiveData.cameraData.viewPort.origin.y     =     1.0F;
  316.         perspectiveData.cameraData.viewPort.width        =     2.0F;
  317.         perspectiveData.cameraData.viewPort.height         =     2.0F;
  318.         
  319.         perspectiveData.fov                = fieldOfView;
  320.         perspectiveData.aspectRatioXToY    = docWidth / docHeight;
  321.  
  322.         camera = Q3ViewAngleAspectCamera_New(&perspectiveData);
  323.  
  324.         return camera ;
  325. }
  326.  
  327.  
  328. /************************************************************
  329. *                                                           *
  330. *    FUNCTION:  QD3DSupport_NewLights                       *
  331. *                                                           *
  332. *    PURPOSE:   Create our lights                           *
  333. *                                                           *
  334. *                                                           *
  335. *************************************************************/
  336.  
  337. static TQ3GroupObject QD3DSupport_NewLights()
  338. {
  339.     TQ3GroupPosition        myGroupPosition;
  340.     TQ3GroupObject            myLightList;
  341.     TQ3LightData            myLightData;
  342.     TQ3LightObject            myAmbientLight = NULL;
  343.     TQ3ColorRGB                WhiteLight = { 1.0F, 1.0F, 1.0F };
  344.     
  345.         /*    Set up light data for ambient light.  This light data will be used for point and fill
  346.             light also. */
  347.  
  348.         myLightData.isOn = kQ3True;
  349.         myLightData.color = WhiteLight;
  350.         
  351.         /*    Create ambient light. */
  352.         myLightData.brightness = 0.8F;
  353.         myAmbientLight = Q3AmbientLight_New(&myLightData);
  354.         if ( myAmbientLight == nil )
  355.         {
  356.             goto bail;
  357.         }
  358.  
  359.         /*    Create light group and add each of the lights into the group. */
  360.         myLightList = Q3LightGroup_New();
  361.         if ( myLightList == nil )
  362.         {
  363.             goto bail;
  364.         }
  365.         myGroupPosition = Q3Group_AddObject(myLightList, myAmbientLight);
  366.         if ( myGroupPosition == 0 )
  367.         {
  368.             goto bail;
  369.         }
  370.  
  371.         Q3Object_Dispose( myAmbientLight ) ;
  372.  
  373.         /*    Done! */
  374.         return ( myLightList );
  375.         
  376.     bail:
  377.         /*    If any of the above failed, then return nothing! */
  378.         if (myAmbientLight != NULL)
  379.         {
  380.             Q3Object_Dispose( myAmbientLight ) ;
  381.         }
  382.         return ( nil );
  383. }
  384.  
  385.  
  386. /************************************************************
  387. *                                                           *
  388. *    FUNCTION:  QD3DSupport_NewTrackGroup                   *
  389. *                                                           *
  390. *    PURPOSE:   Creates a new group for our track & its     *
  391. *               associated shader object                    *
  392. *                                                           *
  393. *                                                           *
  394. *************************************************************/
  395.  
  396. static TQ3GroupObject QD3DSupport_NewTrackGroup(TQ3ShaderObject    theShader)
  397. {
  398.     TQ3GroupObject    myGroup = NULL;    
  399.             
  400.         if ((myGroup = Q3OrderedDisplayGroup_New()) != NULL )
  401.         {
  402.         TQ3GroupPosition myGroupPosition;
  403.         
  404.                 /* ADD TEXTURE SHADER OBJECT TO GROUP */
  405.             myGroupPosition = Q3Group_AddObject(myGroup, theShader);
  406.             if ( myGroupPosition == nil )
  407.             {
  408.                 Utils_DisplayErrorMsg("Group_AddObject failed!");
  409.             }
  410.         }
  411.                         
  412.         /*    Done! */
  413.         return ( myGroup );
  414. }
  415.  
  416.  
  417.  
  418. /************************************************************
  419. *                                                           *
  420. *    FUNCTION:  QD3DSupport_GroundInit                      *
  421. *                                                           *
  422. *    PURPOSE:   Creates a new ground object and group       *
  423. *                                                           *
  424. *                                                           *
  425. *************************************************************/
  426.  
  427. static TQ3GroupObject QD3DSupport_GroundInit(TQ3ShaderObject    groundShaderObject)
  428. {
  429.     long                i;
  430.     TQ3GeometryObject    polygonObj = NULL;
  431.     TQ3GroupPosition    myGroupPosition;
  432.     TQ3GroupObject        groundGroup;
  433.     TQ3PolygonData        polygonData;
  434.     TQ3Vertex3D            vertices[kNumGrndTextureVertices] = {0,-3,GROUND_SIZE,nil,
  435.                                                             GROUND_SIZE,-3,GROUND_SIZE,nil,
  436.                                                             GROUND_SIZE,-3,-GROUND_SIZE,nil,
  437.                                                             0,-3,-GROUND_SIZE,nil};
  438.     TQ3AttributeSet        attribs[kNumGrndTextureVertices] = {NULL, NULL, NULL, NULL};
  439.     float                ambient = 1.0F;
  440.     TQ3Param2D            uv[kNumGrndTextureVertices] = {0,0,1,0,1,1,0,1};
  441.  
  442.  
  443.  
  444.         if (groundShaderObject == NULL)
  445.  
  446.         {
  447.  
  448.             return NULL;
  449.  
  450.         }
  451.  
  452.  
  453.         groundGroup =  Q3OrderedDisplayGroup_New();
  454.         if (groundGroup == NULL)
  455.         {
  456.             return NULL;
  457.         }
  458.             
  459.                 /* ADD TEXTURE SHADER OBJECT TO GROUP */
  460.         myGroupPosition = Q3Group_AddObject(groundGroup, groundShaderObject);
  461.         if ( myGroupPosition == nil )
  462.         {
  463.             Utils_DisplayErrorMsg("Q3Group_AddObject failed!");
  464.             goto outOfMem;
  465.         }
  466.         Q3Object_Dispose(groundShaderObject);
  467.  
  468.  
  469.                 /* CREATE VERTICES */
  470.             
  471.         for (i=0; i < kNumGrndTextureVertices; i++)
  472.         {
  473.             attribs[i] = Q3AttributeSet_New();    
  474.             if( attribs[i] == NULL )
  475.             {
  476.                 Utils_DisplayErrorMsg("Attribute set creation failed!");    
  477.                 goto outOfMem;
  478.             }
  479.             Q3AttributeSet_Add(attribs[i], kQ3AttributeTypeShadingUV, &uv[i]);
  480.             vertices[i].attributeSet = attribs[i];
  481.         }
  482.  
  483.                 /* CREATE NEW POLYGON OBJECT */
  484.  
  485.         polygonData.numVertices = kNumGrndTextureVertices;
  486.         polygonData.vertices = vertices;
  487.         polygonData.polygonAttributeSet = nil;
  488.         polygonObj = Q3Polygon_New(&polygonData);            
  489.         
  490.         if( polygonObj == NULL )
  491.         {
  492.             Utils_DisplayErrorMsg("Polygon_New failed!");    
  493.             goto outOfMem;
  494.         }
  495.         
  496.         for (i=0; i < kNumGrndTextureVertices; i++)
  497.         {            
  498.             Q3Object_Dispose(attribs[i]);
  499.             attribs[i] = NULL;
  500.         }
  501.  
  502.         myGroupPosition = Q3Group_AddObject(groundGroup, polygonObj);
  503.         Q3Object_Dispose(polygonObj);
  504.         if ( myGroupPosition == nil )
  505.         {
  506.             Utils_DisplayErrorMsg("Q3Group_AddObject failed!");    
  507.             goto outOfMem;
  508.         }
  509.         
  510.             /* Success! */
  511.             
  512.         return groundGroup;
  513.         
  514.             /* Error handling */
  515.     outOfMem:
  516.         if (groundGroup)
  517.         {
  518.             Q3Object_Dispose(groundGroup);
  519.         }
  520.  
  521.         for (i=0; i < kNumGrndTextureVertices; i++)
  522.         {            
  523.             if( attribs[i] )
  524.             {
  525.                 Q3Object_Dispose(attribs[i]);
  526.             }
  527.         }
  528.         
  529.         return NULL;
  530. }
  531.  
  532.  
  533. /************************************************************
  534. *                                                           *
  535. *    FUNCTION:  QD3DSupport_InitDoc3DData                   *
  536. *                                                           *
  537. *    PURPOSE:   General initialization routine which        *
  538. *               creates our QD3D view and builds our track  *
  539. *               and ground objects                          *
  540. *                                                           *
  541. *                                                           *
  542. *************************************************************/
  543.  
  544. #if TARGET_OS_MAC
  545.     void QD3DSupport_InitDoc3DData( WindowPtr     window,
  546.                                     DocumentPtr theDocument )
  547. #else if TARGET_OS_WIN32
  548.     void QD3DSupport_InitDoc3DData( HWND         window,
  549.                                     DocumentPtr theDocument )
  550. #endif
  551. {
  552.     TQ3Status         status;
  553.     TQ3ShaderObject    groundShaderObject;
  554.     short            partCount;
  555.     
  556.     #if TARGET_OS_WIN32
  557.  
  558.         OSErr err;
  559.         DWORD error;
  560.  
  561.  
  562.     #endif
  563.  
  564.  
  565.             /* Initialize QuickDraw 3D, open a connection to the QuickDraw 3D library */
  566.  
  567.         status = Q3Initialize();
  568.         if ( status == kQ3Failure )
  569.         {
  570.             Utils_DisplayFatalErrorMsg("QD3D Initialization failure!");
  571.         }
  572.         
  573.         #if TARGET_OS_WIN32
  574.  
  575.             err = QD3DSupport_QuickTimeInit ();
  576.  
  577.             if ( err != noErr )
  578.             {
  579.                 Utils_DisplayFatalErrorMsg("QTML Initialization failure!");
  580.             }
  581.         #endif
  582.  
  583.         theDocument->fSplinePointsPtr     = NULL;
  584.         theDocument->fNumSplineNubs     = 0;
  585.         theDocument->fNumSplinePoints     = 0;
  586.         theDocument->fTrackIndex         = 0;
  587.         theDocument->fMainWindow         = window;
  588.  
  589.             /* sets up the 3d data for the scene */
  590.             /* Create view for QuickDraw 3D. */
  591.         theDocument->fView = QD3DSupport_NewView( theDocument->fMainWindow ) ;
  592.         if (theDocument->fView == NULL)
  593.         {
  594.             Utils_DisplayFatalErrorMsg("Failure creating a new view!");
  595.         }
  596.         
  597.             /* get the view's camera for use later */
  598.         Q3View_GetCamera(theDocument->fView, &theDocument->fCamera);
  599.         
  600.             /* the drawing styles: */
  601.         theDocument->fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleVertex) ;
  602.         theDocument->fBackFacing     = Q3BackfacingStyle_New(kQ3BackfacingStyleBoth ) ;
  603.         theDocument->fFillStyle     = Q3FillStyle_New(kQ3FillStyleFilled ) ;
  604.  
  605.  
  606.             /* get shaders for ground/track textures */
  607.         #if TARGET_OS_MAC
  608.         
  609.             groundShaderObject = QD3DSupport_CreateShaderFromTexture(kGrndTextureResID);
  610.             theDocument->fTrackShader = QD3DSupport_CreateShaderFromTexture(kTextureRezID);
  611.  
  612.         #else if TARGET_OS_WIN32
  613.         
  614.             error = Utils_Win32_BuildCurDirPath((Ptr)&theDocument->fGroundTextureFilePath, kGroundTextureFileName);
  615.             if (!Utils_Win32_DoesFileExist((char *)&theDocument->fGroundTextureFilePath))
  616.  
  617.             {
  618.  
  619.                 Utils_DisplayFatalErrorMsg("Failure loading ground texture file GroundTexture.pct!");
  620.  
  621.             }
  622.  
  623.             error = Utils_Win32_BuildCurDirPath((Ptr)&theDocument->fTrackTextureFilePath, kTrackTextureFileName);
  624.             if (!Utils_Win32_DoesFileExist((char *)&theDocument->fGroundTextureFilePath))
  625.  
  626.             {
  627.  
  628.                 Utils_DisplayFatalErrorMsg("Failure loading track texture file MetalTrack.pct!");
  629.  
  630.             }
  631.  
  632.             
  633.             groundShaderObject = QD3DSupport_CreateShaderFromTexture((Ptr)&theDocument->fGroundTextureFilePath);
  634.             theDocument->fTrackShader = QD3DSupport_CreateShaderFromTexture((Ptr)&theDocument->fTrackTextureFilePath);
  635.  
  636.         #endif
  637.         
  638.             /* create ground/track groups */
  639.             
  640.         theDocument->fGroundGroup = QD3DSupport_GroundInit(groundShaderObject);
  641.         theDocument->fTrackGroup = QD3DSupport_NewTrackGroup (theDocument->fTrackShader);
  642.         
  643.             /* load track parts */
  644.  
  645.         #if TARGET_OS_WIN32
  646.  
  647.             Track_LoadPartsFromFile((PartType *)&theDocument->fPartsList, &partCount);
  648.  
  649.         #elif TARGET_OS_MAC
  650.  
  651.             Track_LoadPartsFromRez((PartType *)&theDocument->fPartsList, &partCount);
  652.  
  653.         #endif
  654.  
  655.             /* build track from track parts */
  656.         if (partCount > 0)
  657.         {
  658.             Track_MakeRandomTrack((TrackSectionType *)&theDocument->fTrackSectionList, MAX_TRACK_SECTIONS);
  659.             Track_CreateMasterNubList((TrackSectionType *)&theDocument->fTrackSectionList,
  660.                                     partCount,
  661.                                     (PartType *)&theDocument->fPartsList,
  662.                                     (NubEntryType *)&theDocument->fNubArray,
  663.                                     &theDocument->fNumSplineNubs);    /* on output, new spline count */
  664.  
  665.             Track_CalcSplineCurve(&theDocument->fSplinePointsPtr,
  666.                                 MAX_SPLINE_POINTS,
  667.                                 (NubEntryType *)&theDocument->fNubArray,
  668.                                 theDocument->fNumSplineNubs,
  669.                                 &theDocument->fNumSplinePoints,
  670.                                 kTrackSubDivFactor);
  671.  
  672.             Track_BuildCoasterGeometry_Mesh(kSkipValue,
  673.                                             theDocument->fTrackGroup,
  674.                                             theDocument->fNumSplinePoints,
  675.                                             theDocument->fSplinePointsPtr);
  676.         }
  677.  
  678. }
  679. /************************************************************
  680. *                                                           *
  681. *    FUNCTION:  QD3DSupport_DisposeDoc3DData                *
  682. *                                                           *
  683. *    PURPOSE:   Dispose of our QD3D objects                 *
  684. *                                                           *
  685. *                                                           *
  686. *************************************************************/
  687.  
  688. void QD3DSupport_DisposeDoc3DData( DocumentPtr theDocument)
  689. {
  690.     TQ3Status status;
  691.  
  692.         Q3Object_Dispose(theDocument->fView) ;                /* the view for the scene */
  693.         Q3Object_Dispose(theDocument->fCamera) ;            /* the camera for the scene */
  694.         Q3Object_Dispose(theDocument->fTrackGroup) ;
  695.         Q3Object_Dispose(theDocument->fGroundGroup) ;
  696.         Q3Object_Dispose(theDocument->fInterpolation) ;        /* interpolation style used when rendering */
  697.         Q3Object_Dispose(theDocument->fBackFacing) ;        /* whether to draw shapes that face away from the camera */
  698.         Q3Object_Dispose(theDocument->fFillStyle) ;            /* whether drawn as solid filled object or decomposed to components */
  699.         Q3Object_Dispose(theDocument->fTrackShader) ;            /* whether drawn as solid filled object or decomposed to components */
  700.  
  701.         status = Q3Exit();
  702.         if ( status == kQ3Failure )
  703.         {
  704.             Utils_DisplayErrorMsg("QD3D Exit returned failure");
  705.         }
  706.  
  707. }
  708.  
  709. /************************************************************
  710. *                                                           *
  711. *    FUNCTION:  QD3DSupport_DocDraw3DData                   *
  712. *                                                           *
  713. *    PURPOSE:   Draws our track and ground group objects    *
  714. *                                                           *
  715. *                                                           *
  716. *************************************************************/
  717.  
  718. TQ3Status QD3DSupport_DocDraw3DData( DocumentPtr theDocument )
  719. {
  720.  
  721.     Q3View_StartRendering(theDocument->fView );
  722.     do
  723.     {        
  724.         Q3Style_Submit( theDocument->fInterpolation, theDocument->fView );
  725.         Q3Style_Submit( theDocument->fBackFacing, theDocument->fView );
  726.         Q3Style_Submit( theDocument->fFillStyle, theDocument->fView );
  727.         Q3DisplayGroup_Submit( theDocument->fTrackGroup, theDocument->fView );
  728.         Q3DisplayGroup_Submit( theDocument->fGroundGroup, theDocument->fView );
  729.  
  730.     } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );
  731.  
  732.     Track_MoveCamera(theDocument->fCamera,
  733.                     theDocument->fSplinePointsPtr,
  734.                     theDocument->fNumSplinePoints,
  735.                     &theDocument->fTrackIndex);
  736.  
  737.     return kQ3Success ;
  738. }
  739.  
  740.  
  741. /************************************************************
  742. *                                                           *
  743. *    FUNCTION:  QD3DSupport_QuickTimeInit                   *
  744. *                                                           *
  745. *    PURPOSE:   Initalize QuickTime                         *
  746. *                                                           *
  747. *                                                           *
  748. *************************************************************/
  749.  
  750. static OSErr QD3DSupport_QuickTimeInit (void)
  751. {
  752.     #if TARGET_OS_WIN32
  753.         OSErr err;
  754.  
  755.             err = InitializeQTML(0L);
  756.             if (err != noErr)
  757.             {
  758.  
  759.                 return err;
  760.  
  761.             }
  762.     #endif
  763.  
  764.     return ( EnterMovies () );
  765. }
  766.  
  767.  
  768.  
  769. /************************************************************
  770. *                                                           *
  771. *    FUNCTION:  QD3DSupport_CreateShaderFromTexture         *
  772. *                                                           *
  773. *    PURPOSE:   Create our shader object                    *
  774. *                                                           *
  775. *                                                           *
  776. *************************************************************/
  777.  
  778. #if TARGET_OS_MAC
  779.  
  780.     static TQ3ShaderObject QD3DSupport_CreateShaderFromTexture(short grndTextureResourceID)
  781.     {
  782.         TQ3ShaderObject     shaderObject = NULL;
  783.         PicHandle            picH;
  784.         Rect                picRect;
  785.  
  786.             Utils_Mac_GetPictForTexture(grndTextureResourceID, &picH, &picRect);
  787.             if (picH == NULL)
  788.             {
  789.                 Utils_DisplayFatalErrorMsg("Failure retrieving ground textures!");
  790.             }
  791.             
  792.             shaderObject = TextureMap_Get(picH, &picRect);
  793.             
  794.             ReleaseResource((Handle)picH);
  795.             
  796.             return shaderObject;
  797.     }
  798.     
  799. #else if TARGET_OS_WIN32
  800.  
  801.     static TQ3ShaderObject QD3DSupport_CreateShaderFromTexture(LPTSTR    grndTextureFilePath)
  802.     {
  803.         TQ3ShaderObject     shaderObject = NULL;
  804.         PicHandle            picH;
  805.         Rect                picRect;
  806.         ComponentResult        result;
  807.  
  808.         
  809.             result = Utils_Win32_GetPicFromFile(grndTextureFilePath, &picH, &picRect);
  810.             if (picH == NULL)
  811.             {
  812.                 Utils_DisplayFatalErrorMsg("Failure retrieving ground textures!");
  813.             }
  814.             
  815.             shaderObject = TextureMap_Get(picH, &picRect);
  816.             
  817.                 /* release memory occupied by picture */
  818.             KillPicture(picH);
  819.             
  820.             return shaderObject;
  821.     }
  822.     
  823. #endif
  824.  
  825.