-
Notifications
You must be signed in to change notification settings - Fork 3
/
listing17.html
executable file
·1382 lines (1124 loc) · 42.6 KB
/
listing17.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<!-- BEGIN META TAG INFO -->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="home" href="http://developer.apple.com/">
<link rel="find" href="http://developer.apple.com/search/">
<link rel="stylesheet" type="text/css" href="../../documentation/css/adcstyle.css" title="fonts">
<script language="JavaScript" src="../../documentation/js/adc.js" type="text/javascript"></script>
<!-- END META TAG INFO -->
<!-- BEGIN TITLE -->
<title>vrmovies - /VRMovies.c</title>
<!-- END TITLE -->
<script language="JavaScript">
function JumpToNewPage() {
window.location=document.scpopupmenu.gotop.value;
return true;
}
</script>
</head>
<!-- BEGIN BODY OPEN -->
<body>
<!--END BODY OPEN -->
<!-- START CENTER OPEN -->
<center>
<!-- END CENTER OPEN -->
<!-- BEGIN LOGO AND SEARCH -->
<!--#include virtual="/includes/adcnavbar"-->
<!-- END LOGO AND SEARCH -->
<!-- START BREADCRUMB -->
<div id="breadcrumb">
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td scope="row"><img width="340" height="10" src="images/1dot.gif" alt=""></td>
<td><img width="340" height="10" src="images/1dot.gif" alt=""></td>
</tr>
<tr valign="middle">
<td align="left" colspan="2">
<a href="http://developer.apple.com/">ADC Home</a> > <a href="../../referencelibrary/index.html">Reference Library</a> > <a href="../../samplecode/index.html">Sample Code</a> > <a href="../../samplecode/QuickTime/index.html">QuickTime</a> > <a href="../../samplecode/QuickTime/idxVirtualReality-date.html">Virtual Reality</a> > <A HREF="javascript:location.replace('index.html');">vrmovies</A> >
</td>
</tr>
<tr>
<td colspan="2" scope="row"><img width="680" height="35" src="images/1dot.gif" alt=""></td>
</tr>
</table>
</div>
<!-- END BREADCRUMB -->
<!-- START MAIN CONTENT -->
<!-- START TITLE GRAPHIC AND INTRO-->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td><h1><div id="pagehead">vrmovies</div></h1></td>
</tr>
</table>
<!-- END TITLE GRAPHIC AND INTRO -->
<!-- START WIDE COLUMN -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td id="scdetails">
<h2>/VRMovies.c</h2>
<form name="scpopupmenu" onSubmit="return false;" method=post>
<p><strong>View Source Code:</strong>
<select name="gotop" onChange="JumpToNewPage();" style="width:340px"><option selected value="ingnore">Select File</option>
<option value="listing1.html">/Application Files/ComApplication.c</option>
<option value="listing2.html">/Application Files/ComApplication.h</option>
<option value="listing3.html">/Application Files/ComResource.h</option>
<option value="listing4.html">/Common Files/ComFramework.c</option>
<option value="listing5.html">/Common Files/ComFramework.h</option>
<option value="listing6.html">/Common Files/MacFramework.c</option>
<option value="listing7.html">/Common Files/MacFramework.h</option>
<option value="listing8.html">/Common Files/MacPrefix.h</option>
<option value="listing9.html">/Common Files/QTUtilities.c</option>
<option value="listing10.html">/Common Files/QTUtilities.h</option>
<option value="listing11.html">/Common Files/QTVRUtilities.c</option>
<option value="listing12.html">/Common Files/QTVRUtilities.h</option>
<option value="listing13.html">/Common Files/WinFramework.c</option>
<option value="listing14.html">/Common Files/WinFramework.h</option>
<option value="listing15.html">/Common Files/WinPrefix.h</option>
<option value="listing16.html">/README.txt</option>
<option value="listing17.html">/VRMovies.c</option>
<option value="listing18.html">/VRMovies.h</option></select>
</p>
</form>
<p><strong><a href="vrmovies.zip">Download Sample</a></strong> (“vrmovies.zip”, 1.00M)<BR>
<strong><a href="vrmovies.dmg">Download Sample</a></strong> (“vrmovies.dmg”, 1.46M)</p>
<!--
<p><strong><a href="#">Download Sample</a></strong> (“filename.sit”, 500K)</p>
-->
</td>
</tr>
<tr>
<td scope="row"><img width="680" height="10" src="images/1dot.gif" alt=""><br>
<img height="1" width="680" src="images/1dot_919699.gif" alt=""><br>
<img width="680" height="20" src="images/1dot.gif" alt=""></td>
</tr>
<tr>
<td scope="row">
<!--googleon: index -->
<pre class="sourcecodebox">////////////// File: VRMovies.c//// Contains: Support for QuickTime movie playback in VR nodes.//// Written by: Tim Monroe// Some code borrowed from QTVRSamplePlayer by Bryce Wolfson.//// Copyright: © 1996-1998 by Apple Computer, Inc., all rights reserved.//// Change History (most recent first)://// <16> 03/20/00 rtm made changes to get things running under CarbonLib// <15> 06/23/99 rtm added VRMoov_MacRGBToWinRGB and VRMoov_WinRGBToMacRGB// <14> 06/22/99 rtm more work on matrices; now everything works okay (AFAICT)// <13> 06/21/99 rtm added call to UpdateMovie to back buffer imaging procedure// <12> 06/18/99 rtm got movie matrices working correctly; added color picking to Windows// <11> 06/17/99 rtm reworked geometry of back buffer yet again; now we copy from the// offscreen GWorld to back buffer using use DecompressSequenceFrameS// <10> 05/16/99 rtm added VRMoov_DumpWindowData; further work on geometry of back buffer// <9> 05/15/99 rtm reworked geometry handling to support horizontal back buffer in QT 4.0// <8> 05/04/98 rtm added automatic rotation of movie// <7> 03/06/97 rtm started to implement video masking// <6> 03/05/97 rtm added VRMoov_SetChromaColor; added fChromaColor to app data record// <5> 03/04/97 rtm fixed compositing problems at back buffer edges// <4> 03/03/97 rtm added VRMoov_SetVideoGraphicsMode to handle compositing// without using an offscreen GWorld// <3> 02/27/97 rtm further development: borrowed some ideas from QTVRSamplePlayer;// added VRMoov_SetEmbeddedMovieWidth etc.// <2> 12/12/96 rtm further development: borrowed some ideas from BoxMoov demo // <1> 12/11/96 rtm first file // // This code draws the QuickTime movie frames into the back buffer, either directly// or indirectly (via an offscreen GWorld). Direct drawing gives the best performance,// but indirect drawing is necessary for some visual effects. ////////////// TO DO:// + finish video masking by custom 'hide' hot spots (so video goes *behind* such hot spots)// + verify that everything works okay if *images* are used instead of movies (scaling seems to be a problem)//////////// // header files// //////////#include "VRMovies.h"//////////// // constants// //////////const RGBColor kClearColor = {0x0000, 0xffff, 0x0000}; // the default chroma key colorconst RGBColor kBlackColor = {0x0000, 0x0000, 0x0000};const RGBColor kWhiteColor = {0xffff, 0xffff, 0xffff};//////////// // global variables// //////////#if TARGET_OS_MACUserEventUPP gColorFilterUPP = NULL; // UPP to our custom color picker dialog event filter#endif////////////// VRMoov_InitWindowData// Initialize any window-specific data.////////////ApplicationDataHdl VRMoov_InitWindowData (WindowObject theWindowObject){#pragma unused(theWindowObject) ApplicationDataHdl myAppData; myAppData = (ApplicationDataHdl)NewHandleClear(sizeof(ApplicationDataRecord)); if (myAppData != NULL) { (**myAppData).fMovie = NULL; (**myAppData).fOffscreenGWorld = NULL; (**myAppData).fOffscreenPixMap = NULL; (**myAppData).fPrevBBufGWorld = NULL; (**myAppData).fMovieCenter.x = 0.0; (**myAppData).fMovieCenter.y = 0.0; (**myAppData).fMovieScale = 1.0; (**myAppData).fMovieWidth = kDefaultEmbMovieWidth; (**myAppData).fUseOffscreenGWorld = false; (**myAppData).fUseMovieCenter = true; (**myAppData).fQTMovieHasSound = false; (**myAppData).fCompositeMovie = false; (**myAppData).fUseHideRegion = false; (**myAppData).fChromaColor = kClearColor; (**myAppData).fHideRegion = NULL; (**myAppData).fBackBufferIsHoriz = false; (**myAppData).fImageDesc = NULL; (**myAppData).fImageSequence = 0; SetIdentityMatrix(&(**myAppData).fMovieMatrix); SetIdentityMatrix(&(**myAppData).fOrigMovieMatrix); // create a new routine descriptor (**myAppData).fBackBufferProc = NewQTVRBackBufferImagingUPP(VRMoov_BackBufferImagingProc); }#if TARGET_OS_MAC if (gColorFilterUPP == NULL) gColorFilterUPP = NewUserEventUPP(VRMoov_ColorDialogEventFilter);#endif return(myAppData);}////////////// VRMoov_DumpWindowData// Dispose of any window-specific data.////////////void VRMoov_DumpWindowData (WindowObject theWindowObject){ ApplicationDataHdl myAppData = NULL; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) return; VRMoov_DumpEmbeddedMovie(theWindowObject); DisposeQTVRBackBufferImagingUPP((**myAppData).fBackBufferProc);}/////////////// VRMoov_GetEmbeddedMovie// Get the QuickTime movie to be embedded in a panorama.// Returns a Boolean to indicate success (true) or failure (false).////////////Boolean VRMoov_GetEmbeddedMovie (WindowObject theWindowObject){ FSSpec myFSSpec; OSType myTypeList = kQTFileTypeMovie; OSErr myErr = paramErr; // do some preliminary parameter checking if (theWindowObject == NULL) return(false); if (!QTFrame_IsWindowObjectOurs(theWindowObject)) return(false); // elicit the movie file from user myErr = QTFrame_GetOneFileWithPreview(1, (QTFrameTypeListPtr)&myTypeList, &myFSSpec, NULL); if (myErr != noErr) { VRMoov_DumpEmbeddedMovie(theWindowObject); // clean up any existing embedded movie return(false); } return(VRMoov_LoadEmbeddedMovie(&myFSSpec, theWindowObject));}////////////// VRMoov_LoadEmbeddedMovie// Load the QuickTime movie in the specified file.// Returns a Boolean to indicate success (true) or failure (false).////////////Boolean VRMoov_LoadEmbeddedMovie (FSSpec *theMovieFile, WindowObject theWindowObject){ short myMovieFileRef; Movie myMovie; GWorldPtr myGWorld = NULL; Rect myRect; ApplicationDataHdl myAppData = NULL; OSErr myErr = paramErr; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) goto bail; HLock((Handle)myAppData); ////////// // // open the movie file and the movie // ////////// myErr = OpenMovieFile(theMovieFile, &myMovieFileRef, fsRdPerm); if (myErr != noErr) goto bail; myErr = NewMovieFromFile(&myMovie, myMovieFileRef, NULL, (StringPtr)NULL, newMovieActive, NULL); if (myErr != noErr) goto bail; ////////// // // get the movie geometry // ////////// GetMovieBox(myMovie, &myRect); GetMovieMatrix(myMovie, &(**myAppData).fOrigMovieMatrix); MacOffsetRect(&myRect, -myRect.left, -myRect.top); SetMovieBox(myMovie, &myRect); // keep track of the movie and movie rectangle (in our app-specific data structure) (**myAppData).fMovie = myMovie; (**myAppData).fMovieBox = myRect; // determine the orientation of the back buffer (**myAppData).fBackBufferIsHoriz = QTVRUtils_IsBackBufferHorizontal((**theWindowObject).fInstance); // get rid of any existing offscreen graphics world if ((**myAppData).fOffscreenGWorld != NULL) { DisposeGWorld((**myAppData).fOffscreenGWorld); (**myAppData).fOffscreenGWorld = NULL; } // clear out any existing custom cover/uncover functions and reset the video media graphics mode // (these may have been modified for direct-screen drawing) SetMovieCoverProcs(myMovie, NULL, NULL, 0L); VRMoov_SetVideoGraphicsMode(myMovie, myAppData, false); ////////// // // if necessary, create an offscreen graphics world // // this is where we'll image the movie before copying it into the back buffer // when we want to do special effects // ////////// if ((**myAppData).fUseOffscreenGWorld) { myErr = NewGWorld(&myGWorld, 0, &myRect, NULL, NULL, 0); (**myAppData).fOffscreenGWorld = myGWorld; (**myAppData).fOffscreenPixMap = GetGWorldPixMap(myGWorld); // make an image description, which is needed by DecompressSequenceBegin LockPixels((**myAppData).fOffscreenPixMap); MakeImageDescriptionForPixMap((**myAppData).fOffscreenPixMap, &((**myAppData).fImageDesc)); UnlockPixels((**myAppData).fOffscreenPixMap); } else { // set the video media graphics mode to drop out the chroma key color in a movie; // we also need to install an uncover function that doesn't erase the uncovered region if ((**myAppData).fCompositeMovie) { VRMoov_SetVideoGraphicsMode(myMovie, myAppData, true); SetMovieCoverProcs(myMovie, NewMovieRgnCoverUPP(VRMoov_UncoverProc), NULL, (long)theWindowObject); } } ////////// // // install the back-buffer imaging procedure // ////////// if ((**theWindowObject).fInstance != NULL) myErr = VRMoov_InstallBackBufferImagingProc((**theWindowObject).fInstance, theWindowObject); // start the movie playing in a loop VRMoov_LoopEmbeddedMovie(myMovie);bail: // we don't want to edit the embedded movie, so we can close the movie file if (myMovieFileRef != 0) CloseMovieFile(myMovieFileRef); HUnlock((Handle)myAppData); return(myErr == noErr);} ////////////// VRMoov_LoopEmbeddedMovie// Start the QuickTime movie playing in a loop.////////////void VRMoov_LoopEmbeddedMovie (Movie theMovie){ TimeBase myTimeBase; // throw the movie into loop mode myTimeBase = GetMovieTimeBase(theMovie); SetTimeBaseFlags(myTimeBase, GetTimeBaseFlags(myTimeBase) | loopTimeBase); // start playing the movie StartMovie(theMovie);} ////////////// VRMoov_DumpEmbeddedMovie// Stop any existing embedded movie from playing and then clean up.////////////void VRMoov_DumpEmbeddedMovie (WindowObject theWindowObject){ ApplicationDataHdl myAppData; if (theWindowObject == NULL) goto bail; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) goto bail; // if we have an embedded movie, stop it from playing and dispose of it if ((**myAppData).fMovie != NULL) { StopMovie((**myAppData).fMovie); DisposeMovie((**myAppData).fMovie); (**myAppData).fMovie = NULL; } // get rid of any existing offscreen graphics world if ((**myAppData).fOffscreenGWorld != NULL) { DisposeGWorld((**myAppData).fOffscreenGWorld); (**myAppData).fOffscreenGWorld = NULL; } // clear the existing back buffer imaging proc QTVRSetBackBufferImagingProc((**theWindowObject).fInstance, NULL, 0, NULL, 0); // clear out any other movie-specific data (**myAppData).fPrevBBufGWorld = NULL; MacSetRect(&(**myAppData).fPrevBBufRect, 0, 0, 0, 0); MacSetRect(&(**myAppData).fMovieBox, 0, 0, 0, 0); SetIdentityMatrix(&(**myAppData).fMovieMatrix); SetIdentityMatrix(&(**myAppData).fOrigMovieMatrix); if ((**myAppData).fImageDesc != NULL) { DisposeHandle((Handle)(**myAppData).fImageDesc); (**myAppData).fImageDesc = NULL; } VRMoov_RemoveDecompSeq(theWindowObject); // make sure the back buffer is clean QTVRRefreshBackBuffer((**theWindowObject).fInstance, 0);bail: return;} ////////////// VRMoov_InstallBackBufferImagingProc// Install a back buffer imaging procedure.// (This routine might sometimes be called to move or resize the area of interest within the panorama.)////////////OSErr VRMoov_InstallBackBufferImagingProc (QTVRInstance theInstance, WindowObject theWindowObject){ ApplicationDataHdl myAppData; QTVRAreaOfInterest myArea; float myWidth, myHeight; OSErr myErr = noErr; ////////// // // initialize; clean up any existing back buffer procedure // ////////// if ((theInstance == NULL) || (theWindowObject == NULL)) return(paramErr); myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) return(paramErr); HLock((Handle)myAppData); // remove any existing back buffer imaging procedure if ((**myAppData).fBackBufferProc != NULL) QTVRSetBackBufferImagingProc(theInstance, NULL, 0, NULL, 0); ////////// // // set the area of interest // // the panAngle and tiltAngle fields define the top-left corner, in panorama space, of the area of interest; // so here we do not have to worry about whether the back buffer is oriented vertically or horizontally // ////////// // the application data structure holds the desired width, center, size, and scale of the movie myWidth = (**myAppData).fMovieWidth * (**myAppData).fMovieScale; myHeight = myWidth * (((float)(**myAppData).fMovieBox.bottom) / ((float)(**myAppData).fMovieBox.right)); if ((**myAppData).fUseMovieCenter) { // use the stored movie center myArea.panAngle = (**myAppData).fMovieCenter.x + (myWidth/2); myArea.tiltAngle = (**myAppData).fMovieCenter.y + (myHeight/2); } else { // center the movie on the current pan and tilt angles myArea.panAngle = QTVRGetPanAngle(theInstance) + (myWidth/2); myArea.tiltAngle = QTVRGetTiltAngle(theInstance) + (myHeight/2); } myArea.width = myWidth; myArea.height = myHeight; ////////// // // set the back buffer flags and install the back buffer procedure // ////////// // make sure we get called on every idle event, so we can keep playing the embedded movie; // also make sure we get called on every back buffer update if ((**myAppData).fCompositeMovie) myArea.flags = kQTVRBackBufferEveryIdle | kQTVRBackBufferEveryUpdate | kQTVRBackBufferAlwaysRefresh; else myArea.flags = kQTVRBackBufferEveryIdle | kQTVRBackBufferEveryUpdate; // if the back buffer is oriented horizontally, set the appropriate flag if ((**myAppData).fBackBufferIsHoriz) myArea.flags |= kQTVRBackBufferHorizontal; // install our procedure myErr = QTVRSetBackBufferImagingProc(theInstance, (**myAppData).fBackBufferProc, 1, &myArea, (SInt32)theWindowObject); HUnlock((Handle)myAppData); return(myErr);} ////////////// VRMoov_CalcImagingMatrix// Calculate the movie matrix required to draw the embedded movie into the specified rectangle.////////////OSErr VRMoov_CalcImagingMatrix (WindowObject theWindowObject, Rect *theBBufRect){ ApplicationDataHdl myAppData = NULL; Rect myDestRect = *theBBufRect; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) return(paramErr); // reset the current movie matrix with the original movie matrix of the embedded movie; // we need to preserve that matrix in our calculations below if we are not drawing the // movie into an offscreen GWorld (**myAppData).fMovieMatrix = (**myAppData).fOrigMovieMatrix; // in general, it's easiest to construct the desired matrix by first doing the scaling // and then doing the rotation and translation (if necessary); so we need to swap the // right and bottom edges of the back buffer rectangle before doing the scaling, if a // rotation will also be necessary if (!(**myAppData).fBackBufferIsHoriz) { myDestRect.bottom = theBBufRect->right; myDestRect.right = theBBufRect->bottom; } // set up the scaling matrix // (MapMatrix concatenates the new matrix to the existing matrix, whereas RectMatrix first // sets the existing matrix to the identity matrix) if ((**myAppData).fUseOffscreenGWorld) RectMatrix(&(**myAppData).fMovieMatrix, &(**myAppData).fMovieBox, &myDestRect); else MapMatrix(&(**myAppData).fMovieMatrix, &(**myAppData).fMovieBox, &myDestRect); // add a rotation and translation, if necessary if (!(**myAppData).fBackBufferIsHoriz) { RotateMatrix(&(**myAppData).fMovieMatrix, Long2Fix(-90), 0, 0); TranslateMatrix(&(**myAppData).fMovieMatrix, 0, Long2Fix(RECT_HEIGHT(*theBBufRect))); } return(noErr);}////////////// VRMoov_SetupDecompSeq// Set up the decompression sequence for DecompressionSequenceFrameS.//// This needs to be called whenever either the rectangle or the GWorld of the back buffer changes.////////////OSErr VRMoov_SetupDecompSeq (WindowObject theWindowObject, GWorldPtr theDestGWorld){ ApplicationDataHdl myAppData = NULL; short myMode = srcCopy; OSErr myErr = noErr; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) return(paramErr); // make sure we don't have a decompression sequence already open VRMoov_RemoveDecompSeq(theWindowObject); // set up the transfer mode if ((**myAppData).fCompositeMovie) myMode = srcCopy | transparent; // set up the image decompression sequence myErr = DecompressSequenceBegin( &(**myAppData).fImageSequence, (**myAppData).fImageDesc, (CGrafPtr)theDestGWorld, NULL, NULL, // entire source image &(**myAppData).fMovieMatrix, myMode, NULL, // no mask 0, (**(**myAppData).fImageDesc).spatialQuality, NULL); return(myErr);}////////////// VRMoov_RemoveDecompSeq// Remove the decompression sequence for DecompressionSequenceFrameS.////////////OSErr VRMoov_RemoveDecompSeq (WindowObject theWindowObject){ ApplicationDataHdl myAppData = NULL; OSErr myErr = paramErr; if (theWindowObject != NULL) { myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData != NULL) if ((**myAppData).fImageSequence != 0) { myErr = CDSequenceEnd((**myAppData).fImageSequence); (**myAppData).fImageSequence = 0; } } return(myErr);}////////////// VRMoov_BackBufferImagingProc// The back buffer imaging procedure: get a frame of movie and image it into the back buffer.// Also, do any additional compositing that might be desired.////////////PASCAL_RTN OSErr VRMoov_BackBufferImagingProc (QTVRInstance theInstance, Rect *theRect, UInt16 theAreaIndex, UInt32 theFlagsIn, UInt32 *theFlagsOut, long theRefCon){#pragma unused(theAreaIndex) WindowObject myWindowObject = (WindowObject)theRefCon; ApplicationDataHdl myAppData = NULL; Movie myMovie = NULL; Boolean myIsDrawing = theFlagsIn & kQTVRBackBufferRectVisible; GWorldPtr myBBufGWorld, myMovGWorld; GDHandle myBBufGDevice, myMovGDevice; Rect myRect; OSErr myErr = paramErr; ////////// // // initialize; make sure that we've got the data we need to continue // ////////// // assume we're not going to draw anything *theFlagsOut = 0; if ((theInstance == NULL) || (myWindowObject == NULL)) goto bail; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(myWindowObject); if (myAppData == NULL) goto bail; HLock((Handle)myAppData); myMovie = (**myAppData).fMovie; if (myMovie == NULL) { // we don't have an embedded movie, so remove this back-buffer imaging procedure VRMoov_DumpEmbeddedMovie(myWindowObject); goto bail; } ////////// // // make sure that the movie GWorld is set correctly; // note that we call SetMovieGWorld only if we have to (for performance reasons) // ////////// // get the current graphics world // (on entry, the current graphics world is [usually] set to the back buffer) GetGWorld(&myBBufGWorld, &myBBufGDevice); // get the embedded movie's graphics world GetMovieGWorld(myMovie, &myMovGWorld, &myMovGDevice); if ((**myAppData).fUseOffscreenGWorld) { // we're using an offscreen graphics world, so set movie's GWorld to be that offscreen graphics world if (myMovGWorld != (**myAppData).fOffscreenGWorld) SetMovieGWorld(myMovie, (**myAppData).fOffscreenGWorld, GetGWorldDevice((**myAppData).fOffscreenGWorld)); } else { // we're not using an offscreen graphics world, so set movie GWorld to be the back buffer; if ((myMovGWorld != myBBufGWorld) || (myMovGDevice != myBBufGDevice)) SetMovieGWorld(myMovie, myBBufGWorld, myBBufGDevice); } ////////// // // make sure the movie rectangle and movie matrix are set correctly // ////////// if (myIsDrawing) { // if we weren't previously visible, make sure we are now GetMovieBox(myMovie, &myRect); if (EmptyRect(&myRect)) SetMovieBox(myMovie, &(**myAppData).fMovieBox); // when no offscreen GWorld is being used... if (!(**myAppData).fUseOffscreenGWorld) { // ...make sure the movie matrix is set correctly... if (!MacEqualRect(theRect, &(**myAppData).fPrevBBufRect)) { VRMoov_CalcImagingMatrix(myWindowObject, theRect); SetMovieMatrix(myMovie, &(**myAppData).fMovieMatrix); } // ...and, if we are compositing, force QuickTime to draw a movie frame when MoviesTask is called // (since the previous frame was automatically erased from the back buffer by QuickTime VR) if ((**myAppData).fCompositeMovie) UpdateMovie(myMovie); } } else { // if we're not visible, set the movie rectangle to an empty rectangle // so we're not wasting time trying to draw a movie frame MacSetRect(&myRect, 0, 0, 0, 0); SetMovieBox(myMovie, &myRect); } ////////// // // draw a new movie frame into the movie's graphics world (and play movie sound) // ////////// MoviesTask(myMovie, 1L);// MoviesTask(myMovie, 0); // if we got here, everything is okay so far myErr = noErr; ////////// // // perform any additional compositing // ////////// // that is, draw, using the current chroma key color, anything to be dropped out of the image; // note that this technique works *only* if we're using an offscreen graphics world if ((**myAppData).fUseOffscreenGWorld && (**myAppData).fCompositeMovie && myIsDrawing) { RGBColor myColor; // since we're using an offscreen graphics world, make sure we draw there SetGWorld((**myAppData).fOffscreenGWorld, GetGWorldDevice((**myAppData).fOffscreenGWorld)); // set up compositing environment GetForeColor(&myColor); RGBForeColor(&(**myAppData).fChromaColor); // do the drawing if ((**myAppData).fHideRegion != NULL) MacPaintRgn((**myAppData).fHideRegion); // restore original drawing environment RGBForeColor(&myColor); // restore original graphics world SetGWorld(myBBufGWorld, myBBufGDevice); } ////////// // // if we're using an offscreen graphics world, copy it into the back buffer // ////////// if (myIsDrawing) { if ((**myAppData).fUseOffscreenGWorld) { PixMapHandle myPixMap; // if anything relevant to DecompressSequenceFrameS has changed, reset the decompression sequence if ((myBBufGWorld != (**myAppData).fPrevBBufGWorld) || !(MacEqualRect(theRect, &(**myAppData).fPrevBBufRect))) { VRMoov_CalcImagingMatrix(myWindowObject, theRect); VRMoov_SetupDecompSeq(myWindowObject, myBBufGWorld); } myPixMap = GetGWorldPixMap((**myAppData).fOffscreenGWorld); LockPixels(myPixMap); // set the chroma key color, if necessary if ((**myAppData).fCompositeMovie) RGBBackColor(&(**myAppData).fChromaColor); // copy the image from the offscreen graphics world into the back buffer myErr = DecompressSequenceFrameS( (**myAppData).fImageSequence,#if TARGET_CPU_68K StripAddress(GetPixBaseAddr(myPixMap)),#else GetPixBaseAddr(myPixMap),#endif (**(**myAppData).fImageDesc).dataSize, 0, NULL, NULL); // reset the chroma key color; // we need to do this because the buffer we just drew into might NOT actually // be the real back buffer (see Virtual Reality Programming With QuickTime VR, p. 1-154); // the copy between the intermediate buffer and the back buffer respects the current back color. if ((**myAppData).fCompositeMovie) RGBBackColor(&kWhiteColor); UnlockPixels(myPixMap); } } ////////// // // finish up // ////////// // keep track of the GWorld and rectangle passed to us this time (**myAppData).fPrevBBufGWorld = myBBufGWorld; (**myAppData).fPrevBBufRect = *theRect; // if we drew something, tell QuickTime VR if (myIsDrawing) *theFlagsOut = kQTVRBackBufferFlagDidDraw; bail: HUnlock((Handle)myAppData); return(myErr);}////////////// VRMoov_GetEmbeddedMovieWidth// Get the width of the embedded movie.////////////float VRMoov_GetEmbeddedMovieWidth (WindowObject theWindowObject){ ApplicationDataHdl myAppData; float myWidth; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) myWidth = 0; else myWidth = (**myAppData).fMovieWidth; return(myWidth);}////////////// VRMoov_SetEmbeddedMovieWidth// Set the width of the embedded movie.////////////void VRMoov_SetEmbeddedMovieWidth (WindowObject theWindowObject, float theWidth){ ApplicationDataHdl myAppData; QTVRInstance myInstance; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) return; myInstance = (**theWindowObject).fInstance; if (myInstance == NULL) return; // install the desired width in our application data structure (**myAppData).fMovieWidth = theWidth; // clear out the existing area of interest QTVRRefreshBackBuffer(myInstance, 0); // reinstall the back buffer imaging procedure VRMoov_InstallBackBufferImagingProc(myInstance, theWindowObject);}////////////// VRMoov_GetEmbeddedMovieCenter// Get the center of the embedded movie.////////////void VRMoov_GetEmbeddedMovieCenter (WindowObject theWindowObject, QTVRFloatPoint *theCenter){ ApplicationDataHdl myAppData; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) { theCenter->x = 0.0; theCenter->y = 0.0; } else { theCenter->x = (**myAppData).fMovieCenter.x; theCenter->y = (**myAppData).fMovieCenter.y; } }////////////// VRMoov_SetEmbeddedMovieCenter// Set the center of the embedded movie.////////////void VRMoov_SetEmbeddedMovieCenter (WindowObject theWindowObject, const QTVRFloatPoint *theCenter){ ApplicationDataHdl myAppData; QTVRInstance myInstance; float myX, myY; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) return; myInstance = (**theWindowObject).fInstance; if (myInstance == NULL) return; myX = theCenter->x; myY = theCenter->y; // subject the values passed in to the current view constraints QTVRWrapAndConstrain(myInstance, kQTVRPan, myX, &myX); QTVRWrapAndConstrain(myInstance, kQTVRTilt, myY, &myY); // install the desired center in our application data structure (**myAppData).fMovieCenter.x = myX; (**myAppData).fMovieCenter.y = myY; // clear out the existing area of interest QTVRRefreshBackBuffer(myInstance, 0); // reinstall the back buffer imaging procedure VRMoov_InstallBackBufferImagingProc(myInstance, theWindowObject);}////////////// VRMoov_GetEmbeddedMovieScale// Get the scale of the embedded movie.////////////float VRMoov_GetEmbeddedMovieScale (WindowObject theWindowObject){ ApplicationDataHdl myAppData; float myScale; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) myScale = 0; else myScale = (**myAppData).fMovieScale; return(myScale);}////////////// VRMoov_SetEmbeddedMovieScale// Set the scale factor of the embedded movie.////////////void VRMoov_SetEmbeddedMovieScale (WindowObject theWindowObject, float theScale){ ApplicationDataHdl myAppData; QTVRInstance myInstance; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) return; myInstance = (**theWindowObject).fInstance; if (myInstance == NULL) return; // install the desired scale factor in our application data structure (**myAppData).fMovieScale = theScale; // clear out the existing area of interest QTVRRefreshBackBuffer(myInstance, 0); // reinstall the back buffer imaging procedure VRMoov_InstallBackBufferImagingProc(myInstance, theWindowObject);}////////////// VRMoov_SetChromaColor// Set the chroma key color for a window object:// display color picker dialog and remember the newly-selected color.////////////void VRMoov_SetChromaColor (WindowObject theWindowObject){#if TARGET_OS_MAC ColorPickerInfo myColorInfo;#endif #if TARGET_OS_WIN32 static CHOOSECOLOR myColorRec; static COLORREF myColorRef[16];#endif ApplicationDataHdl myAppData; myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindowObject(theWindowObject); if (myAppData == NULL) return;#if TARGET_OS_MAC // pass in existing color myColorInfo.theColor.color.rgb.red = (**myAppData).fChromaColor.red; myColorInfo.theColor.color.rgb.green = (**myAppData).fChromaColor.green; myColorInfo.theColor.color.rgb.blue = (**myAppData).fChromaColor.blue; // not much here... myColorInfo.theColor.profile = 0L; myColorInfo.dstProfile = 0L; myColorInfo.flags = 0L; myColorInfo.placeWhere = kCenterOnMainScreen; myColorInfo.pickerType = 0L; myColorInfo.eventProc = gColorFilterUPP; myColorInfo.colorProc = NULL; myColorInfo.colorProcData = 0L; GetIndString(myColorInfo.prompt, kColorPickerTextStringID, 1); // set Edit menu info myColorInfo.mInfo.editMenuID = kEditMenuResID; myColorInfo.mInfo.undoItem = MENU_ITEM(IDM_EDITUNDO); myColorInfo.mInfo.cutItem = MENU_ITEM(IDM_EDITCUT); myColorInfo.mInfo.copyItem = MENU_ITEM(IDM_EDITCOPY); myColorInfo.mInfo.pasteItem = MENU_ITEM(IDM_EDITPASTE); myColorInfo.mInfo.clearItem = MENU_ITEM(IDM_EDITCLEAR); // call Color Picker if ((PickColor(&myColorInfo) == noErr) && (myColorInfo.newColorChosen)) { // install the newly chosen color in the palette (**myAppData).fChromaColor.red = myColorInfo.theColor.color.rgb.red; (**myAppData).fChromaColor.green = myColorInfo.theColor.color.rgb.green; (**myAppData).fChromaColor.blue = myColorInfo.theColor.color.rgb.blue; }#endif#if TARGET_OS_WIN32 myColorRec.lStructSize = sizeof(CHOOSECOLOR); myColorRec.hwndOwner = NULL; myColorRec.hInstance = NULL; VRMoov_MacRGBToWinRGB(&(**myAppData).fChromaColor, &(myColorRec.rgbResult)); myColorRec.lpCustColors = myColorRef; myColorRec.Flags = CC_RGBINIT | CC_FULLOPEN; myColorRec.lCustData = 0; myColorRec.lpfnHook = NULL; myColorRec.lpTemplateName = NULL; // call Common Color dialog if (ChooseColor(&myColorRec)) { // install the newly chosen color in the palette VRMoov_WinRGBToMacRGB(&(**myAppData).fChromaColor, myColorRec.rgbResult); }#endif} ////////////// VRMoov_ColorDialogEventFilter// Handle events before they get passed to the Color Picker dialog box.////////////PASCAL_RTN Boolean VRMoov_ColorDialogEventFilter (EventRecord *theEvent){#if TARGET_OS_WIN32#pragma unused(theEvent)#endif Boolean myEventHandled = false; OSErr myErr = noErr;#if TARGET_OS_MAC switch (theEvent->what) { case updateEvt: { if ((WindowPtr)theEvent->message != FrontWindow()) { QTFrame_HandleEvent(theEvent); myEventHandled = true; } break; } case nullEvent: { // do idle-time processing for all open windows in our window list WindowObject myWindowObject = NULL; ApplicationDataHdl myAppData = NULL; WindowReference myWindow = NULL; myWindow = QTFrame_GetFrontMovieWindow(); while (myWindow != NULL) { myWindowObject = (WindowObject)QTFrame_GetWindowObjectFromWindow(myWindow); myAppData = (ApplicationDataHdl)QTFrame_GetAppDataFromWindow(myWindow); if ((myWindowObject != NULL) && (myAppData != NULL)) if ((**myAppData).fMovie != NULL) QTVRUpdate((**myWindowObject).fInstance, kQTVRCurrentMode); myWindow = QTFrame_GetNextMovieWindow(myWindow); } myEventHandled = false; break; } case kHighLevelEvent: myErr = AEProcessAppleEvent(theEvent); if (myErr != noErr) myEventHandled = true; break; default: myEventHandled = false; break; } #endif return(myEventHandled);}////////////// VRMoov_UncoverProc// The uncover function of the embedded movie.////////////PASCAL_RTN OSErr VRMoov_UncoverProc (Movie theMovie, RgnHandle theRegion, long theRefCon){#pragma unused(theMovie, theRegion, theRefCon) return(noErr);}////////////// VRMoov_SetVideoGraphicsMode// Set the video media graphics mode of the embedded movie.////////////void VRMoov_SetVideoGraphicsMode (Movie theMovie, ApplicationDataHdl theAppData, Boolean theSetVGM){ long myTrackCount; short myIndex; Track myTrack = NULL; Media myMedia = NULL; OSType myMediaType; if ((theMovie == NULL) || (theAppData == NULL)) return; myTrackCount = GetMovieTrackCount(theMovie); for (myIndex = 1; myIndex <= myTrackCount; myIndex++) { myTrack = GetMovieIndTrack(theMovie, myIndex); myMedia = GetTrackMedia(myTrack); GetMediaHandlerDescription(myMedia, &myMediaType, NULL, NULL); if (myMediaType == VideoMediaType) { if (theSetVGM) MediaSetGraphicsMode(GetMediaHandler(myMedia), srcCopy | transparent, &(**theAppData).fChromaColor); else MediaSetGraphicsMode(GetMediaHandler(myMedia), srcCopy, &kWhiteColor); } } return;}////////////// VRMoov_GetVideoGraphicsPixelDepth// Return the highest pixel depth supported by a QuickTime movie.////////////short VRMoov_GetVideoGraphicsPixelDepth (Movie theMovie){ long myTrackCount; short myIndex; Track myMovieTrack = NULL; Media myMedia; OSType myMediaType; short myQuality; myTrackCount = GetMovieTrackCount(theMovie); for (myIndex = 1; myIndex <= myTrackCount; myIndex++) { myMovieTrack = GetMovieIndTrack(theMovie, myIndex); myMedia = GetTrackMedia(myMovieTrack); GetMediaHandlerDescription(myMedia, &myMediaType, NULL, NULL); if (myMediaType == VideoMediaType) { myQuality = GetMediaQuality(myMedia); if (myQuality >> 5) return(32); if (myQuality >> 4) return(16); if (myQuality >> 3) return(8); if (myQuality >> 2) return(4); if (myQuality >> 1) return(2); if (myQuality >> 0) return(1); } } return(0);}/////////////////////////////////////////////////////////////////////////////////////////////////////////////// Color conversion utilities.//// Macintosh usually represents colors using an RGBColor structure, where each color component is a 16-bit// unsigned integer. Windows represents colors using a 32-bit unsigned COLORREF, where each color component// occupies 8 bits. The following two functions allow us to convert from Mac to Windows colors and back. We// need to do this because we use Mac-style colors when doing compositing./////////////////////////////////////////////////////////////////////////////////////////////////////////////#if TARGET_OS_WIN32#define kMaxMacRGBValue 0xffff#define kMaxWinRGBValue 0x00ff#define MAC_TO_WIN_COMP(color) (color*((float)kMaxWinRGBValue/(float)kMaxMacRGBValue))#define WIN_TO_MAC_COMP(color) (color*((float)kMaxMacRGBValue/(float)kMaxWinRGBValue))////////////// VRMoov_MacRGBToWinRGB// Convert an RGBColor structure into a COLORREF value.////////////void VRMoov_MacRGBToWinRGB (RGBColorPtr theRGBColor, COLORREF *theColorRef){ *theColorRef = RGB( (BYTE)MAC_TO_WIN_COMP(theRGBColor->red), (BYTE)MAC_TO_WIN_COMP(theRGBColor->green), (BYTE)MAC_TO_WIN_COMP(theRGBColor->blue));}////////////// VRMoov_WinRGBToMacRGB// Convert a COLORREF value into an RGBColor structure.////////////void VRMoov_WinRGBToMacRGB (RGBColorPtr theRGBColor, COLORREF theColorRef){ theRGBColor->red = (unsigned long)WIN_TO_MAC_COMP(GetRValue(theColorRef)); theRGBColor->green = (unsigned long)WIN_TO_MAC_COMP(GetGValue(theColorRef)); theRGBColor->blue = (unsigned long)WIN_TO_MAC_COMP(GetBValue(theColorRef));}#endif // TARGET_OS_WIN32</pre>
<!--googleoff: index -->
</td>
</tr>
</table>
<!-- END WIDE COLUMN -->
<!-- END MAIN CONTENT -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td><div style="width: 100%; height: 1px; background-color: #919699; margin-top: 5px; margin-bottom: 15px"></div></td>
</tr>
<tr>
<td align="center"><br/>
<table border="0" cellpadding="0" cellspacing="0" class="graybox">
<tr>
<th>Did this document help you?</th>
</tr>
<tr>
<td>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=1&url=/samplecode/vrmovies/listing17.html%3Fid%3DDTS10001030-1.0&media=dvd" target=_new>Yes</a>: Tell us what works for you.</div>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=2&url=/samplecode/vrmovies/listing17.html%3Fid%3DDTS10001030-1.0&media=dvd" target=_new>It’s good, but:</a> Report typos, inaccuracies, and so forth.</div>
<div><a href="http://developer.apple.com/feedback/?v=3&url=/samplecode/vrmovies/listing17.html%3Fid%3DDTS10001030-1.0&media=dvd" target=_new>It wasn’t helpful</a>: Tell us what would have helped.</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!-- START BOTTOM APPLE NAVIGATION -->
<!--#include virtual="/includes/footer"-->
<!-- END BOTTOM APPLE NAVIGATION -->
<!-- START CENTER CLOSE -->
</center>
<!-- END CENTER CLOSE -->
</body>
</html>