home *** CD-ROM | disk | FTP | other *** search
- //
- // This is box, the QuickDraw 3D starter program. Written for the
- // Quickdraw 3D sample code
- //
- // This file contains utility routines for QuickDraw 3d sample code.
- // This app shows how to apply a texture shader to an object. Bear in
- // mind that any object that you wish to texture map needs to have
- // UV parameters applied.
- //
- // Nick Thompson, AppleLink: DEVSUPPORT (devsupport@applelink.apple.com)
- //
- // ©1994-5 Apple Computer Inc., All Rights Reserved
-
- // system headers
- #include <Menus.h>
- #include <Devices.h>
- #include <Events.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>
-
- // for QuickDraw 3D
- #include "QD3D.h"
- #include "QD3DMath.h"
- #include "QD3DDrawContext.h"
- #include "QD3DShader.h"
- #include "QD3DTransform.h"
- #include "QD3DGroup.h"
-
-
- #include "BoxTexShell.h"
- #include "BoxTex3DSupport.h"
- #include "Textures.h"
-
- #define ATI_ACCESS_RAVE_CONTEXT 1
- #if ATI_ACCESS_RAVE_CONTEXT
- /*
- * headers
- */
- #include <Timer.h>
- #include <string.h>
- #include "ATIRave.h"
-
- /*
- * defines
- */
- #define MILLIONTHS 0.000001F
- #define MAX( a, b ) ( ((a) > (b)) ? (a) : (b) )
-
- /*
- * prototypes
- */
- void ATI_SetRaveState( GDHandle GDevice, TQ3ViewObject viewObject );
- TQAEngine *ATI_FindRaveEngine( TQADevice *device );
- GDHandle ATI_FindWindowDevice( WindowPtr pWin );
- unsigned long MicrosecondCount( void );
- void DisplayString( int x, int y, char *str );
- void callBack( const TQADrawContext *, const TQADevice *, const TQARect *, void *);
-
- /*
- * global variables
- */
- unsigned long start, end;
- float seconds;
- unsigned long count = 0;
- char str[100];
- RGBColor BLACK = { 0, 0, 0 };
- Boolean filter = false;
-
- TQANoticeMethod gNotice;
- #endif
-
- //-------------------------------------------------------------------------------------------
- // function prototypes
-
- static void InitToolbox( void ) ;
- static void MainEventLoop( void ) ;
- static void HandleKeyPress(EventRecord *event) ;
- static void HandleOSEvent(EventRecord *event) ;
- void InitDocumentData( DocumentPtr theDocument ) ;
- TQ3Status DocumentDraw3DData( DocumentPtr theDocument ) ;
- void DisposeDocumentData( DocumentPtr theDocument) ;
-
- //-------------------------------------------------------------------------------------------
- //
-
- 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 = "\pSpinning Box - click to toggle filtering" ;
-
- InitToolbox() ;
-
- // Initialize QuickDraw 3D, open a connection to the QuickDraw 3D library
- myStatus = Q3Initialize();
- if ( myStatus == kQ3Failure )
- DebugStr("\pErInitialize returned failure.");
-
- // set up our globals
- gQuitFlag = false ;
- gMainWindow = NewCWindow(nil,&rBounds,title,true,noGrowDocProc,(WindowPtr)-1,true,nil); ;
-
- InitDocumentData( &gDocument ) ;
-
- MainEventLoop();
-
- DisposeDocumentData( &gDocument ) ;
-
- // Close our connection to the QuickDraw 3D library
- myStatus = Q3Exit();
- if( myStatus == kQ3Failure )
- {
- //DebugStr("\pErExit returned failure.");
- }
- }
-
- //-------------------------------------------------------------------------------------------
- //
-
- void InitDocumentData( DocumentPtr theDocument )
- {
- TQ3Point3D myOrigin = { 0, 0, 0 } ;
-
- theDocument->fGroupScale = 1;
- theDocument->fGroupCenter = myOrigin ;
-
- // 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(kQ3BackfacingStyleRemove ) ;
- theDocument->fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
-
- // set the rotation matrix the identity matrix
- Q3Matrix4x4_SetIdentity(&theDocument->fRotation);
-
- AdjustCamera( &gDocument,
- (gMainWindow->portRect.right - gMainWindow->portRect.left),
- (gMainWindow->portRect.bottom - gMainWindow->portRect.top) ) ;
-
- #if ATI_ACCESS_RAVE_CONTEXT
- ATI_SetRaveState( ATI_FindWindowDevice(gMainWindow), theDocument->fView );
- #endif
- }
-
- 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
-
- }
-
- //-----------------------------------------------------------------------------
- //
-
- TQ3Status DocumentDraw3DData( DocumentPtr theDocument )
- {
- Q3View_StartRendering(theDocument->fView );
- do {
- SubmitScene( theDocument ) ;
- } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );
- 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 MainEventLoop()
- {
- EventRecord event;
- WindowPtr window;
- short thePart;
- Rect screenRect, updateRect;
- Point aPoint = {100, 100};
-
- #if ATI_ACCESS_RAVE_CONTEXT
- count = 0;
- start = MicrosecondCount();
- #endif
-
- while( !gQuitFlag )
- {
- if (WaitNextEvent( everyEvent, &event, 0, 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 );
-
- #if ATI_ACCESS_RAVE_CONTEXT
- ATI_SetRaveState( ATI_FindWindowDevice(window), gDocument.fView );
- count = 0;
- start = MicrosecondCount();
- #endif
- break ;
-
- case inContent:
-
- if (window != FrontWindow())
- SelectWindow( window );
-
- #if ATI_ACCESS_RAVE_CONTEXT
- ATI_SetRaveState( ATI_FindWindowDevice(window), gDocument.fView );
- #endif
-
- 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 );
-
- #if ATI_ACCESS_RAVE_CONTEXT
- /*
- * display frame rate
- */
- end = MicrosecondCount();
- seconds = (float)(MAX((end-start),1))*MILLIONTHS;
- sprintf( str, "fps = %5.2f", ++count/seconds);
- DisplayString( 2, 10, str );
- DisplayString( 100, 10, (filter) ? "Filtering ON" : "Filtering Off" );
- #endif
- 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_SetRotate_XYZ(&tmp, 0.0, 0.001, 0.001);
- Q3Matrix4x4_Multiply(&gDocument.fRotation, &tmp, &gDocument.fRotation);
-
- InvalRect( &theRect ) ;
- }
- }
- }
-
-
- //-------------------------------------------------------------------------------------------
- //
- void HandleKeyPress(EventRecord *event)
- {}
-
- //-------------------------------------------------------------------------------------------
- //
-
- #if ATI_ACCESS_RAVE_CONTEXT
-
- /*
- * Function: MicrosecondCount()
- *
- */
- unsigned long MicrosecondCount( void )
- {
- UnsignedWide currentCount;
-
- Microseconds(¤tCount);
-
- return( currentCount.lo );
- }
-
- /*
- * Function: DisplayString()
- *
- */
- void DisplayString( int x, int y, char *str )
- {
- char buf[256];
-
- RGBForeColor( &BLACK );
- MoveTo( x, y );
-
- strcpy( buf+1, str );
- buf[0] = strlen( buf+1 );
- DrawString( (const unsigned char *)buf );
- }
-
- /*
- * Function: ATI_SetRaveState()
- *
- */
- void ATI_SetRaveState( GDHandle GDevice, TQ3ViewObject viewObject )
- {
- OSErr iErr;
- TQADevice RaveDevice;
- TQADrawContext *raveDrawContext = NULL;
- TQAEngine *ATIRaveEngine;
- long response = (long)&RaveDevice;
-
- /*
- * get handle to desired GDevice
- */
- if( GDevice == NULL )
- return;
-
- /*
- * fill TQADevice struct + use this to find
- * if there is an ATI Engine on this device
- */
- RaveDevice.deviceType = kQADeviceGDevice;
- RaveDevice.device.gDevice = GDevice;
-
- if( (ATIRaveEngine = ATI_FindRaveEngine( &RaveDevice )) == NULL )
- return;
-
- /*
- * now we know we have an ATI Engine, so use
- * Gestalt call to query for pointer to current
- * RAVE draw context. The parameter "response"
- * is used both as input and output. On input
- * it holds the address of the TQADevice we're
- * interested in. If successful, on output it
- * holds the current RAVE draw context pointer
- */
- Q3View_StartRendering( viewObject );
-
- iErr = QAEngineGestalt( ATIRaveEngine,
- (TQAGestaltSelector)kQATIGestalt_CurrentContext,
- &response );
-
- Q3View_Cancel( viewObject );
-
- if( iErr != kQANoErr || response == NULL || response == (long)&RaveDevice )
- return;
-
- raveDrawContext = (TQADrawContext *)response;
-
- /*
- * toggle filtering mode
- */
- filter = !filter;
- QASetInt( raveDrawContext, kQATag_TextureFilter,
- (filter) ? kQATextureFilter_Best : kQATextureFilter_Fast );
-
- /*
- * Set standard Rave context state variables - these
- * are not required, but are just here to show the
- * kinds of things you can do
- */
- QASetInt( raveDrawContext, kQATag_TextureOp, kQATextureOp_Modulate );
- QASetInt( raveDrawContext, kQATag_Blend, kQABlend_Interpolate );
- QASetInt( raveDrawContext, kQATag_ZFunction, kQAZFunction_LE );
- QASetInt( raveDrawContext, kQATag_Antialias, kQAAntiAlias_Off );
- QASetInt( raveDrawContext, kQATag_PerspectiveZ, kQAPerspectiveZ_Off );
- QASetInt( raveDrawContext, kQATagGL_BlendSrc, GL_SRC_ALPHA );
- QASetInt( raveDrawContext, kQATagGL_BlendDst, GL_ONE_MINUS_DST_ALPHA );
-
- gNotice.bufferNoticeMethod = callBack;
- QASetNoticeMethod( raveDrawContext, kQAMethod_BufferComposite, gNotice, NULL );
-
- /*
- * Set ATI specific Rave context state variables
- *
- QASetInt( raveDrawContext, (TQATagInt)kATIFogMode, kQATIFogLinear );
- QASetFloat( raveDrawContext, (TQATagFloat)kATIFogColor_r, 0.0 );
- QASetFloat( raveDrawContext, (TQATagFloat)kATIFogColor_g, 0.2 );
- QASetFloat( raveDrawContext, (TQATagFloat)kATIFogColor_b, 0.0 );
- QASetFloat( raveDrawContext, (TQATagFloat)kATIFogStart, 0.0 );
- QASetFloat( raveDrawContext, (TQATagFloat)kATIFogEnd, 1.0 );
- QASetFloat( raveDrawContext, (TQATagFloat)kATIFogDensity, 1.0 );
- */
- }
-
- /*
- * Function: ATI_FindRaveEngine()
- *
- */
- TQAEngine *ATI_FindRaveEngine( TQADevice *device )
- {
- TQAEngine *tmpEngine;
- unsigned long vendorID;
-
- /*
- * try to find ATI RAVE engine
- */
- for( tmpEngine = QADeviceGetFirstEngine(device);
- tmpEngine;
- tmpEngine = QADeviceGetNextEngine(device, tmpEngine) )
- {
- QAEngineGestalt( tmpEngine, kQAGestalt_VendorID, &vendorID );
- if( vendorID == 1 )
- return( QAEngineCheckDevice(tmpEngine, device) ? NULL : tmpEngine );
- }
-
- /*
- * if no ATI RAVE engine, return NULL
- */
- return( NULL );
- }
-
- /*
- * Function: ATI_FindWindowDevice()
- *
- */
- GDHandle ATI_FindWindowDevice( WindowPtr pWin )
- {
- GDHandle hDevice;
- Rect rWin;
- Rect intersect;
-
- if( pWin == NULL )
- return( NULL );
-
- rWin = ((*(((WindowPeek)pWin)->strucRgn))->rgnBBox);
-
- for( hDevice = GetDeviceList();
- hDevice;
- hDevice = GetNextDevice(hDevice) )
- {
- /*
- * test for active monitors that entirely contain rect
- */
- if( TestDeviceAttribute(hDevice, screenDevice) &&
- TestDeviceAttribute(hDevice, screenActive) &&
- SectRect(&rWin, &((*hDevice)->gdRect), &intersect) &&
- EqualRect(&rWin, &intersect) )
- {
- return( hDevice );
- }
- }
-
- return( NULL );
- }
-
- /*
- * Function: callBack()
- *
- */
- void callBack( const TQADrawContext *drawContext, /* Draw context */
- const TQADevice *buffer, /* TQADevice describing back buffer */
- const TQARect *dirtyRect, /* Minimum area to process; NULL means whole buffer */
- void *refCon )
- {
- long rowBytes = buffer->device.memoryDevice.rowBytes;
- TQAImagePixelType pixelType = buffer->device.memoryDevice.pixelType;
- long width = buffer->device.memoryDevice.width;
- long height = buffer->device.memoryDevice.height;
- void *baseAddr = buffer->device.memoryDevice.baseAddr;
- int pixSize = (pixelType == kQAPixel_ARGB32) ? 32 : 16;
- int starty = height/2 - 50;
- int startx = width/2 - 50;
- unsigned char *rowPtr = (unsigned char *)baseAddr + starty*rowBytes;
- int x, y;
-
- /*
- * mess with the pixMap memory
- */
- if( pixSize == 16 )
- {
- unsigned short *pixPtr;
-
- for( y = 0; y < 100; y++ )
- {
- pixPtr = (unsigned short *)rowPtr + startx;
-
- for( x = 0; x < 100; x++ )
- *pixPtr++ ^= 0xFFFF;
-
- rowPtr += rowBytes;
- }
- }
- else
- {
- unsigned long *pixPtr;
-
- for( y = 0; y < 100; y++ )
- {
- pixPtr = (unsigned long *)rowPtr + startx;
-
- for( x = 0; x < 100; x++ )
- *pixPtr++ ^= 0xFFFFFFFF;
-
- rowPtr += rowBytes;
- }
- }
- }
- #endif
-
-
-