home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / SDKs / Third Party SDKs / ATI RAVE SDK / Samples / QD3D Tests / BackGround (Original) / BackGroundShell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-07  |  12.0 KB  |  467 lines  |  [TEXT/CWIE]

  1. // Quickdraw 3D sample code
  2. //
  3. // This file illustrates how to set up a pixmap based draw context.
  4. // A metafile is read into and imaged in the pixmap, this pixmap is combined
  5. // with a pixmap containing a background, so that the 3d data is drawn over 
  6. // the background
  7. //
  8. // Nick Thompson, AppleLink: DEVSUPPORT (devsupport@applelink.apple.com)
  9. //
  10. // ©1994-5 Apple Computer Inc., All Rights Reserved
  11.  
  12.  
  13. // system headers
  14. #include <Menus.h>
  15. #include <Devices.h>
  16. #include <Events.h>
  17. #include <Dialogs.h>
  18. #include <DiskInit.h>
  19. #include <Fonts.h>
  20. #include <Menus.h>
  21. #include <PictUtils.h>
  22. #include <QDOffScreen.h>
  23. #include <QuickDraw.h>
  24. #include <SegLoad.h>
  25. #include <StandardFile.h>
  26. #include <TextEdit.h>
  27. #include <ToolUtils.h>
  28. #include <Timer.h>
  29. #include <Processes.h>
  30. #include <string.h>
  31.  
  32. // for QuickDraw 3D
  33. #include "QD3D.h"
  34. #include "QD3DMath.h"
  35. #include "QD3DDrawContext.h"
  36. #include "QD3DShader.h"
  37. #include "QD3DTransform.h"
  38. #include "QD3DGroup.h"
  39. #include "QD3DCamera.h"
  40.  
  41.  
  42. #include "BackGroundShell.h"
  43. #include "BackGroundSupport.h"
  44.  
  45. // get the interface to my error handler routines
  46. #include "MyErrorHandler.h"
  47.  
  48. const RGBColor    kClearColor = { 0x0000, 0xffff, 0x0000 } ;
  49. const RGBColor    kWhiteColor = { 0xffff, 0xffff, 0xffff } ;
  50.  
  51. //-------------------------------------------------------------------------------------------
  52. // function prototypes
  53.  
  54. static void         InitToolbox( void ) ;
  55. static void         MainEventLoop( void ) ;
  56. static void         HandleKeyPress(EventRecord *event) ;
  57. static void         HandleOSEvent(EventRecord *event) ;
  58. void InitDocumentData( DocumentPtr theDocument ) ;
  59. TQ3Status DocumentDraw3DData( DocumentPtr theDocument ) ;
  60. void DisposeDocumentData( DocumentPtr theDocument) ;
  61. void DocumentDrawOnscreen(DocumentPtr theDocument, Rect *clipRect) ;
  62.  
  63. OSErr WritePict( PicHandle myPic, short  dstPictFRef ) ;
  64. OSErr GetOutputFileRef(short    *dstPictFRef ) ;
  65. PicHandle ImageToPict( DocumentPtr theDocument, WindowPtr theWindow ) ;
  66. void DoSaveAs(DocumentPtr theDocument)  ;
  67.  
  68. //-------------------------------------------------------------------------------------------
  69. //
  70.  
  71. Boolean         gQuitFlag         = false ;
  72. WindowPtr        gMainWindow        = nil ;
  73. DocumentRec        gDocument ;
  74.  
  75. //-------------------------------------------------------------------------------------------
  76. // main()
  77. // entry point for the application, initialize the toolbox, initialize QuickDraw 3D
  78. // and enter the main event loop.  On exit from the main event loop, we want to call
  79. // the QuickDraw 3D exit function to clean up QuickDraw 3d.
  80.  
  81. void main(void)
  82. {
  83.     TQ3Status    myStatus;
  84.     Rect        rBounds = { 50, 50, 350, 350 } ;
  85.     Str255        title = "\pSpinning Box" ;
  86.     FSSpec        theFileSpec ;                // the file we are opening
  87.  
  88.     InitToolbox() ;
  89.     
  90.  
  91.     if(MetafileFileSpecify( &theFileSpec )) {
  92.     
  93.         SetCursor(*(GetCursor(watchCursor)));
  94.         
  95.         //    Initialize QuickDraw 3D, open a connection to the QuickDraw 3D library
  96.         myStatus = Q3Initialize();
  97.         if ( myStatus == kQ3Failure )
  98.             DebugStr("\pErInitialize returned failure.");            
  99.     
  100.         // install the error & warning handler - these get called whenever
  101.         // errors or warnings occur, which means we don't have to check so 
  102.         // much
  103.         Q3Error_Register( MyErrorHandler, 0L );        
  104.         Q3Warning_Register( MyWarningHandler, 0L );        
  105.     
  106.         // set up our globals
  107.         gQuitFlag = false ;
  108.         gMainWindow = NewCWindow(nil,&rBounds,title,false,noGrowDocProc,(WindowPtr)-1,true,nil); ;
  109.  
  110.         // initialise our document structure
  111.         InitDocumentData( &gDocument ) ;
  112.         
  113.         // try to read the file into the main display group
  114.         if((gDocument.fModel = MyNewModelFromFile(&theFileSpec)) != NULL ) {        
  115.         
  116.             // get a bg picturre
  117.             if(PictureFileSpecify(&theFileSpec)) {
  118.                 PicHandle thePicture ;
  119.                 if((thePicture = OpenPICTFile( &theFileSpec )) != nil ) {
  120.                     
  121.                     CGrafPtr    savedPort ;
  122.                     GDHandle    gdh ;
  123.                     OSErr        theErr ;
  124.                     Rect        bounds = (**thePicture).picFrame ;
  125.                     
  126.                     GetGWorld( &savedPort, &gdh );
  127.                     
  128.                     // create the offscreen for the picture, this is faster than
  129.                     // calling DrawPicture each time through our update onscreen routine.
  130.                     theErr = NewGWorld(&gDocument.fBgPicture, 32, &bounds,nil,nil,0L);
  131.                     if(theErr != noErr )
  132.                         ExitToShell() ;
  133.                         
  134.                     SetGWorld( gDocument.fBgPicture, nil ) ;
  135.                     DrawPicture( thePicture, &bounds ) ;
  136.                     KillPicture( thePicture ) ;
  137.                     
  138.                     // clear our compositing buffer    
  139.                     theErr = NewGWorld(&gDocument.fCompositeBuffer, 32, &bounds,nil,nil,0L);
  140.                     if(theErr != noErr )
  141.                         ExitToShell() ;
  142.                         
  143.                     SetGWorld( gDocument.fCompositeBuffer, nil ) ;
  144.                     RGBBackColor( &kClearColor ) ;
  145.                     EraseRect(  &bounds ) ;
  146.                     
  147.                     // restore the environment                
  148.                     SetGWorld( savedPort, gdh );
  149.  
  150.                     AdjustCamera(    &gDocument,
  151.                                     (bounds.right - bounds.left),
  152.                                     (bounds.bottom - bounds.top) ) ;
  153.         
  154.                     SetWTitle( gMainWindow, theFileSpec.name );
  155.                     
  156.                     SizeWindow(    gMainWindow,
  157.                                 (bounds.right - bounds.left),
  158.                                 (bounds.bottom - bounds.top),
  159.                                 false );
  160.                                 
  161.                     ShowWindow( gMainWindow ) ;
  162.                     SetPort( gMainWindow ) ;
  163.             
  164.                     SetCursor(&qd.arrow) ;
  165.                     MainEventLoop();
  166.                 }
  167.             }
  168.             
  169.         }
  170.                         
  171.         //    Close our connection to the QuickDraw 3D library
  172.         myStatus = Q3Exit();
  173.         if ( myStatus == kQ3Failure )
  174.             DebugStr("\pErExit returned failure.");
  175.     }    
  176. }
  177.  
  178. //-------------------------------------------------------------------------------------------
  179. //
  180.  
  181. void InitDocumentData( DocumentPtr theDocument ) 
  182. {
  183.     GWorldPtr        theOffscreen ;
  184.     GDHandle        theDevice ;
  185.     TQ3Point3D        myOrigin = { 0, 0, 0 } ;
  186.     
  187.     // create a GWorld the size of the window area
  188.     OSErr myErr = NewGWorld(    &theDocument->fGWorld,
  189.                                 32,
  190.                                 &gMainWindow->portRect,
  191.                                 nil,
  192.                                 nil,
  193.                                 0L );
  194.     
  195.     if(myErr != noErr )
  196.         goto bail ;
  197.         
  198.     GetGWorld( &theOffscreen, &theDevice ) ;
  199.     SetGWorld( theDocument->fGWorld, nil ) ;
  200.     EraseRect( &gMainWindow->portRect ) ;
  201.     SetGWorld( theOffscreen, theDevice ) ;
  202.     
  203.     // sets up the 3d data for the scene
  204.     //    Create view for QuickDraw 3D.
  205.     theDocument->fView = MyNewView( theDocument->fGWorld );
  206.  
  207.     // the main display group:
  208.     theDocument->fModel = NULL ;
  209.     
  210.     // scale and group center
  211.     theDocument->fGroupScale = 1;                
  212.     theDocument->fGroupCenter = myOrigin ;    
  213.     
  214.     // the drawing styles:
  215.     theDocument->fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
  216.     theDocument->fBackFacing = Q3BackfacingStyle_New( kQ3BackfacingStyleBoth ) ;
  217.     theDocument->fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
  218.  
  219.     // set the rotation matrix the identity matrix
  220.     Q3Matrix4x4_SetIdentity(&theDocument->fRotation);    
  221.                     
  222.     return ;
  223.     
  224. bail:
  225.     // we failed setting up the GWorld
  226.     // so we want to quit here
  227.     ExitToShell() ;
  228.     
  229. }
  230.  
  231. void DisposeDocumentData( DocumentPtr theDocument)
  232. {
  233.     if(theDocument->fView)
  234.         Q3Object_Dispose(theDocument->fView) ;                // the view for the scene
  235.  
  236.     if(theDocument->fModel)
  237.         Q3Object_Dispose(theDocument->fModel) ;                // object in the scene being modelled
  238.  
  239.     if(theDocument->fInterpolation)
  240.         Q3Object_Dispose(theDocument->fInterpolation) ;        // interpolation style used when rendering
  241.  
  242.     if(theDocument->fBackFacing)
  243.         Q3Object_Dispose(theDocument->fBackFacing) ;        // whether to draw shapes that face away from the camera
  244.  
  245.     if(theDocument->fFillStyle)
  246.         Q3Object_Dispose(theDocument->fFillStyle) ;            // whether drawn as solid filled object or decomposed to components
  247. }
  248. //-----------------------------------------------------------------------------
  249. // assumes the port is set up before being called
  250.  
  251. TQ3Status DocumentDraw3DData( DocumentPtr theDocument )
  252. {    
  253.     TQ3Status theStatus ;    
  254.  
  255.     //    Start rendering.
  256.     Q3View_StartRendering(theDocument->fView) ;
  257.     do {
  258.         theStatus = SubmitScene( theDocument ) ;
  259.     } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );
  260.  
  261.     return theStatus ;    
  262. }
  263.  
  264. //-------------------------------------------------------------------------------------------
  265. //
  266.  
  267. void DocumentDrawOnscreen(DocumentPtr theDocument, Rect *clipRect)
  268. {
  269.     if (theDocument->fGWorld) {
  270.     
  271.         CGrafPtr            savedPort;
  272.         GDHandle            savedDevice;
  273.         RGBColor            savedColor ;
  274.  
  275.         GetGWorld( &savedPort, &savedDevice);
  276.         // composite the image in the offscreen
  277.         // first draw the BG Pict
  278.         SetGWorld( theDocument->fCompositeBuffer,  nil);
  279.         
  280.         GetBackColor(&savedColor);
  281.         RGBBackColor(&kWhiteColor) ;
  282.                 
  283.         CopyBits ((BitMapPtr) &theDocument->fBgPicture->portPixMap,
  284.                   (BitMapPtr) &theDocument->fCompositeBuffer->portPixMap,
  285.                   &theDocument->fBgPicture->portRect, 
  286.                   &theDocument->fCompositeBuffer->portRect, 
  287.                   srcCopy, 
  288.                   0L);
  289.         
  290.         RGBBackColor(&savedColor) ;
  291.         OpColor(&kClearColor);
  292.               
  293.         // next draw the 3d image over the bg pict using transparent copy
  294.         CopyBits ((BitMapPtr) &theDocument->fGWorld->portPixMap,
  295.                   (BitMapPtr) &theDocument->fCompositeBuffer->portPixMap,
  296.                   &theDocument->fGWorld->portRect, 
  297.                   &theDocument->fCompositeBuffer->portRect, 
  298.                   srcCopy | transparent, 
  299.                   0L);
  300.  
  301.         SetGWorld( (CGrafPtr)gMainWindow,  nil);
  302.         
  303.         ClipRect( clipRect ) ;
  304.         
  305.         
  306.         // don't need to lockPixels on the GWorld as the 
  307.         // offscreen remains locked (see IM: QD3D), the
  308.         // pixmap for a pixmap draw context must remain locked
  309.         
  310.         CopyBits ((BitMapPtr) &theDocument->fCompositeBuffer->portPixMap,
  311.                   &gMainWindow->portBits,
  312.                   &theDocument->fCompositeBuffer->portRect, 
  313.                   &gMainWindow->portRect,
  314.                   srcCopy, 
  315.                   0L);
  316.                   
  317.         SetGWorld( savedPort, savedDevice);
  318.       }
  319. }
  320.  
  321.  
  322. //-------------------------------------------------------------------------------------------
  323. //
  324.  
  325. short HiWrd(long aLong)
  326. {
  327.     return    (((aLong) >> 16) & 0xFFFF) ;
  328. }
  329.  
  330. //-------------------------------------------------------------------------------------------
  331. //
  332.  
  333. short LoWrd(long aLong)
  334. {
  335.     return    ((aLong) & 0xFFFF) ;
  336.  
  337. }
  338.  
  339. //-------------------------------------------------------------------------------------------
  340. //
  341.  
  342. void InitToolbox()
  343. {
  344.     Handle        menuBar = nil;
  345.  
  346.     MaxApplZone() ;
  347.     MoreMasters() ; MoreMasters() ; MoreMasters() ; 
  348.     
  349.     InitGraf( &qd.thePort );
  350.     InitFonts();
  351.     InitWindows();
  352.  
  353.     FlushEvents( everyEvent, 0 ) ;
  354.     // initialize application globals
  355.     
  356.     gQuitFlag = false;
  357.     InitCursor();
  358.     
  359. }
  360.  
  361. //-------------------------------------------------------------------------------------------
  362. //
  363. void MainEventLoop()
  364. {
  365.     EventRecord     event;
  366.     WindowPtr       window;
  367.     short           thePart;
  368.     Rect            screenRect, updateRect;
  369.     Point            aPoint = {100, 100};
  370.     
  371.  
  372.     while( !gQuitFlag )
  373.     {
  374.         if (WaitNextEvent( everyEvent, &event, 0, nil ))
  375.         {
  376.  
  377.             switch (event.what) {
  378.                 case mouseDown:
  379.                 
  380.                     thePart = FindWindow( event.where, &window );
  381.                     
  382.                     switch( thePart ) {
  383.                         case inMenuBar: 
  384.                             break;
  385.                         
  386.                         case inDrag:
  387.                     
  388.                             screenRect = (**GetGrayRgn()).rgnBBox;
  389.                             DragWindow( window, event.where, &screenRect );
  390.                             break ;
  391.                     
  392.                         case inContent:
  393.                     
  394.                             if (window != FrontWindow())
  395.                                 SelectWindow( window );
  396.                             break ;
  397.                     
  398.                         case inGoAway:
  399.                             if (TrackGoAway( window, event.where )) {
  400.                                 DisposeWindow ( window );
  401.                                 DisposeDocumentData( &gDocument ) ;
  402.                                 gQuitFlag = true;
  403.  
  404.                             }
  405.                             break ;
  406.                             
  407.                         default:
  408.                             break ;
  409.                     }
  410.                     break ;
  411.                             
  412.                         
  413.                 case updateEvt:
  414.                 
  415.                     window = (WindowPtr)event.message;
  416.                     updateRect = (**(window->visRgn)).rgnBBox;
  417.                     SetPort( window ) ;
  418.                     BeginUpdate( window );
  419.                     DocumentDraw3DData( &gDocument ) ;
  420.                     DocumentDrawOnscreen( &gDocument, &updateRect ) ;
  421.                     EndUpdate( window );
  422.  
  423.                     break ;
  424.                     
  425.                 case keyDown:
  426.                 case autoKey:
  427.                     HandleKeyPress(&event);
  428.                     break;
  429.                     
  430.                 case diskEvt:
  431.                     if ( HiWrd(event.message) != noErr ) 
  432.                         (void) DIBadMount(aPoint, event.message);
  433.                     break;
  434.                     
  435.                 case osEvt:
  436.                 case activateEvt:
  437.                     break;
  438.  
  439.  
  440.             }
  441.         }
  442.         else {
  443.             // we received a null event, rotate the cube
  444.             TQ3Matrix4x4    tmp;
  445.             Rect        theRect = ((GrafPtr)gMainWindow)->portRect ;
  446.             
  447.             SetPort((GrafPtr)gMainWindow) ;
  448.             Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.1, 0.12, 0.08);
  449.             Q3Matrix4x4_Multiply(&gDocument.fRotation, &tmp, &gDocument.fRotation);
  450.  
  451.             InvalRect( &theRect ) ;
  452.         }
  453.     }
  454. }
  455.  
  456.  
  457. //-------------------------------------------------------------------------------------------
  458. //
  459. void HandleKeyPress(EventRecord *event)
  460. {}
  461.  
  462. //-------------------------------------------------------------------------------------------
  463. //
  464.  
  465.  
  466.  
  467.