Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Sprite_Window.c
/* |
* Sprite_Window.c |
* Red Rocket |
* |
* Created by ggs on Fri May 11 2001. |
Copyright: Copyright © 2001 Apple Computer, Inc., All Rights Reserved |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
*/ |
#include <Carbon/Carbon.h> |
#include <QuickTime/ImageCompression.h> |
#include <OpenGL/gl.h> |
#include <OpenGL/glu.h> |
#include <OpenGL/glext.h> |
#include "aglString.h" |
#include "Carbon_SetupGL.h" |
#include "Carbon_Error_Handler.h" |
#include "OpenGL_Image_Utilities.h" |
#include "Data_File_Utilities.h" |
#include "Sprite_Utilities.h" |
#include "HID_Utilities_External.h" |
#include "Sprite_Window.h" |
// ================================== |
short gMaxTextureSize = 256; |
Boolean gRocketRotate = true; |
Boolean gMipmap = false; |
// ================================== |
static void DrawInfo (float worldX, float worldY, float worldRotation, float worldZoom, |
long width, long height, GLuint fontList); |
// ================================== |
// private |
static void DrawInfo (float worldX, float worldY, float worldRotation, float worldZoom, |
long width, long height, GLuint fontList) |
{ |
long y = 1; |
char cstr [256]; |
glLoadIdentity (); |
glTranslatef (-(width) / 2.0, -(height) / 2.0, 0.0); // translate center to upper left |
glDisable (GL_DEPTH_TEST); |
glEnable (GL_BLEND); |
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
// draw dimming box |
glColor4f (0.1, 0.1, 0.12, 0.52); |
glBegin (GL_QUADS); |
glVertex3f (0.0, 0.0,0.0); |
glVertex3f (250.0, 0.0, 0.0); |
glVertex3f (250.0, 55.0, 0.0); |
glVertex3f (0.0, 55.0, 0.0); |
glEnd (); |
glBegin (GL_QUADS); |
glVertex3f (0.0, height, 0.0); |
glVertex3f (250.0, height, 0.0); |
glVertex3f (250.0, height - 28.0, 0.0); |
glVertex3f (0.0, height - 28.0, 0.0); |
glEnd (); |
glColor3f (0.9, 0.0, 0.0); |
glRasterPos3d (10, y++ * 12, 0.0); |
sprintf (cstr, "Window: (%ld x %ld)", |
width, height); |
DrawCStringGL (cstr, fontList); |
glRasterPos3d (10, y++ * 12, 0.0); |
sprintf (cstr, "Position: (%0.1f, %0.1f) at %0.1f deg", |
worldX, worldY, worldRotation); |
DrawCStringGL (cstr, fontList); |
glRasterPos3d (10, y++ * 12, 0.0); |
sprintf (cstr, "Zoom: %0.2f", |
worldZoom); |
DrawCStringGL (cstr, fontList); |
glRasterPos3d (10, y++ * 12, 0.0); |
DrawFrameRate (fontList); |
glRasterPos3d (10, (height) - 15, 0.0); |
DrawCStringGL ((char*) glGetString (GL_VENDOR), fontList); |
glRasterPos3d (10, (height) - 3, 0.0); |
DrawCStringGL ((char*) glGetString (GL_RENDERER), fontList); |
} |
// ================================== |
// public |
long GetThrustValue (void) |
{ |
pRecWindow pWindowInfo = (pRecWindow) GetWRefCon (FrontWindow ()); |
if (pWindowInfo) |
return pWindowInfo->thrustValue; |
else |
return 0; |
} |
// --------------------------------- |
long GetTurnValue (void) |
{ |
pRecWindow pWindowInfo = (pRecWindow) GetWRefCon (FrontWindow ()); |
if (pWindowInfo) |
return pWindowInfo->turnValue; |
else |
return 0; |
} |
// --------------------------------- |
void IdleWindow (WindowRef window, long turn, long thrust, Boolean Zin, Boolean Zout) |
{ |
static AbsoluteTime time = {0,0}; |
AbsoluteTime currTime = UpTime (); |
double deltaTime = (float) AbsoluteDeltaToDuration (currTime, time); |
time = currTime; // reset for next time interval |
if (0 > deltaTime) // if negative microseconds |
deltaTime /= -1000000.0; |
else // else milliseconds |
deltaTime /= 1000.0; |
if (deltaTime > 10.0) // skip pauses |
return; |
else |
{ |
pRecWindow pWindowInfo = (pRecWindow) GetWRefCon (window); |
if (pWindowInfo) |
{ |
pWindowInfo->turnValue = turn; |
pWindowInfo->thrustValue = thrust; |
if (Zin) |
pWindowInfo->zoom += pWindowInfo->zoom * deltaTime; |
if (Zout) |
pWindowInfo->zoom -= pWindowInfo->zoom * deltaTime; |
if (pWindowInfo->zoom < 0.10) |
pWindowInfo->zoom = 0.10; |
IdleSprites (window, pWindowInfo->pSpriteArray, pWindowInfo->numSprites, deltaTime); |
} |
DrawGL (window); |
} |
} |
// --------------------------------- |
Boolean LoadDataFile (pRecWindow pWindowInfo) |
{ |
char * pFileBuffer; |
long i, index = 0, bufferSize; |
char cstr [256]; |
FSSpec fsspecData; |
pWindowInfo->zoom = 0.5; |
pWindowInfo->info = true; |
pWindowInfo->lines = false; |
pWindowInfo->grid = false; |
pFileBuffer = ReadDataFile (&bufferSize, &fsspecData); |
// load images |
pWindowInfo->numImages = GetLongFromData (pFileBuffer, &index, bufferSize); |
pWindowInfo->pImageArray = (pRecImage) NewPtrClear (sizeof (recImage) * pWindowInfo->numImages); // array of images |
for (i = 0; i < pWindowInfo->numImages; i++) |
{ |
long maskType = GetLongFromData (pFileBuffer, &index, bufferSize); |
GetCStrFromData (pFileBuffer, &index, bufferSize, cstr); |
CopyCStringToPascal (cstr, fsspecData.name); |
LoadImageFile (fsspecData, &(pWindowInfo->pImageArray [i]), maskType); |
} |
// load sprites |
pWindowInfo->numSprites = GetLongFromData (pFileBuffer, &index, bufferSize); |
pWindowInfo->pSpriteArray = (pRecSprite) NewPtrClear (sizeof (recSprite) * pWindowInfo->numSprites); // array of sprites |
for (i = 0; i < pWindowInfo->numSprites; i++) |
LoadSprite (&(pWindowInfo->pSpriteArray [i]), pFileBuffer, &index, bufferSize); |
DisposeDataBuffer (&pFileBuffer); |
return true; |
} |
// --------------------------------- |
OSStatus DisposeGLForWindow (WindowRef window) |
{ |
pRecWindow pWindowInfo = (pRecWindow) GetWRefCon (window); |
if ( pWindowInfo != NULL ) |
{ |
DestroyGLFromWindow (&pWindowInfo->aglContext, &pWindowInfo->glInfo); |
pWindowInfo->aglContext = NULL; |
DisposeImages (&(pWindowInfo->pImageArray), pWindowInfo->numImages); |
DisposeSprites (&(pWindowInfo->pSpriteArray), pWindowInfo->numSprites); |
pWindowInfo->numSprites = 0; |
pWindowInfo->numImages = 0; |
SetWRefCon( window, NULL ); |
} |
return noErr; |
} |
// --------------------------------- |
OSStatus BuildGLForWindow (WindowRef window) |
{ |
OSStatus err = noErr; |
GrafPtr portSave = NULL; |
pRecWindow pWindowInfo = (pRecWindow) GetWRefCon (window); |
pRecImage pImageInfo; |
short i; |
short fNum; |
if (NULL == pWindowInfo) |
return paramErr; |
if (!pWindowInfo->aglContext) |
{ |
GetPort (&portSave); |
SetPort ((GrafPtr) GetWindowPort (window)); |
pWindowInfo->glInfo.fAcceleratedMust = true; // must renderer be accelerated? |
pWindowInfo->glInfo.VRAM = 0 * 1048576; // minimum VRAM (if not zero this is always required) |
pWindowInfo->glInfo.textureRAM = 0 * 1048576; // minimum texture RAM (if not zero this is always required) |
pWindowInfo->glInfo.fDraggable = true; |
pWindowInfo->glInfo.fmt = 0; // output pixel format |
i = 0; |
pWindowInfo->glInfo.aglAttributes [i++] = AGL_RGBA; |
pWindowInfo->glInfo.aglAttributes [i++] = AGL_DOUBLEBUFFER; |
pWindowInfo->glInfo.aglAttributes [i++] = AGL_ACCELERATED; |
pWindowInfo->glInfo.aglAttributes [i++] = AGL_DEPTH_SIZE; |
pWindowInfo->glInfo.aglAttributes [i++] = 16; |
pWindowInfo->glInfo.aglAttributes [i++] = AGL_NONE; |
BuildGLFromWindow (window, &(pWindowInfo->aglContext), &(pWindowInfo->glInfo), NULL); |
if (!pWindowInfo->aglContext) |
DestroyGLFromWindow (&pWindowInfo->aglContext, &pWindowInfo->glInfo); |
else |
{ |
GLint swap = 1; |
Rect rectPort; |
// VBL SYNC |
aglSetInteger (pWindowInfo->aglContext, AGL_SWAP_INTERVAL, &swap); |
aglUpdateContext (pWindowInfo->aglContext); |
GetWindowPortBounds (window, &rectPort); |
// InvalWindowRect (window, &rectPort); |
glViewport (0, 0, rectPort.right - rectPort.left, rectPort.bottom - rectPort.top); |
// Set Texture mapping parameters |
glEnable(GL_TEXTURE_2D); |
glClearColor(0.2f, 0.2f, 0.2f, 1.0f); // Clear color buffer to black |
glClear (GL_COLOR_BUFFER_BIT); |
aglSwapBuffers (pWindowInfo->aglContext); |
GetFNum ("\pGeneva", &fNum); // build font |
pWindowInfo->fontList = BuildFontGL (pWindowInfo->aglContext, fNum, bold, 9); |
// load textures |
// get number of textures x and y |
for (i = 0; i < pWindowInfo->numImages; i++) |
{ |
pImageInfo = &(pWindowInfo->pImageArray[i]); |
pImageInfo->maxTextureSize = gMaxTextureSize; |
pImageInfo->textureX = GetTextureNumFromTextureDim (pImageInfo->textureWidth, pImageInfo->maxTextureSize); |
pImageInfo->textureY = GetTextureNumFromTextureDim (pImageInfo->textureHeight, pImageInfo->maxTextureSize); |
pImageInfo->pTextureName = (GLuint *) NewPtrClear (sizeof (GLuint) * pImageInfo->textureX * pImageInfo->textureY); |
glPixelStorei (GL_UNPACK_ROW_LENGTH, pImageInfo->textureWidth); // width in groups (pixels) |
glGenTextures (pImageInfo->textureX * pImageInfo->textureY, pImageInfo->pTextureName); |
{ |
long x, y, k = 0, offsetY = 0, offsetX = 0, currWidth, currHeight; |
for (x = 0; x < pImageInfo->textureX; x++) { |
currWidth = GetNextTextureSize (pImageInfo->textureWidth - offsetX, pImageInfo->maxTextureSize); // use remaining to determine next texture size |
offsetY = 0; |
for (y = 0; y < pImageInfo->textureY; y++) { |
// buffer pointer is at base + rows * row size + columns |
unsigned char * pBuffer = pImageInfo->pImageBuffer + (offsetY * pImageInfo->textureWidth * (pImageInfo->imageDepth >> 3)) + offsetX * (pImageInfo->imageDepth >> 3); |
currHeight = GetNextTextureSize (pImageInfo->textureHeight - offsetY, pImageInfo->maxTextureSize); // use remaining to determine next texture size |
glBindTexture(GL_TEXTURE_2D, pImageInfo->pTextureName[k++]); |
// note: these need to be set after the texture is bound, setting prior only results in the default texture's params being set |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
if (gMipmap) { |
glPixelStorei (GL_UNPACK_ALIGNMENT, 1); |
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); |
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
if (pImageInfo->imageDepth == 32) |
gluBuild2DMipmaps (GL_TEXTURE_2D, GL_RGBA8, currWidth, currHeight, |
GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, pBuffer); |
else if (pImageInfo->imageDepth == 16) |
gluBuild2DMipmaps (GL_TEXTURE_2D, GL_RGB5_A1, currWidth, currHeight, |
GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, pBuffer); |
else if (pImageInfo->imageDepth == 8) |
if (pImageInfo->maskType == 0) |
gluBuild2DMipmaps (GL_TEXTURE_2D, GL_LUMINANCE8, currWidth, currHeight, |
GL_LUMINANCE, GL_UNSIGNED_BYTE, pBuffer); |
else if (pImageInfo->maskType == 0) |
gluBuild2DMipmaps (GL_TEXTURE_2D, GL_ALPHA8, currWidth, currHeight, |
GL_ALPHA, GL_UNSIGNED_BYTE, pBuffer); |
} else { |
if (pImageInfo->imageDepth == 32) |
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, currWidth, currHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, pBuffer); |
else if (pImageInfo->imageDepth == 16) |
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB5_A1, currWidth, currHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, pBuffer); |
else if (pImageInfo->imageDepth == 8) |
if (pImageInfo->maskType == 0) |
glTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE8, currWidth, currHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pBuffer); |
else if (pImageInfo->maskType == 3) |
glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA8, currWidth, currHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pBuffer); |
} |
offsetY += currHeight; |
} |
offsetX += currWidth; |
} |
} |
err = glReportError (); // check for gl errors |
// done with gworld and image |
DisposeGWorld (pImageInfo->pGWorld); |
pImageInfo->pGWorld = NULL; |
DisposePtr ((Ptr) pImageInfo->pImageBuffer); |
pImageInfo->pImageBuffer = NULL; |
} |
} |
SetPort (portSave); |
} |
return err; |
} |
// --------------------------------- |
OSStatus ResizeGLWindow (WindowRef window) |
{ |
OSStatus err = noErr; |
Rect rectPort; |
pRecWindow pWindowInfo = (pRecWindow) GetWRefCon (window); |
GetWindowPortBounds (window, &rectPort); |
err = aglUpdateContext (pWindowInfo->aglContext); |
err = InvalWindowRect (window, &rectPort); |
return err; |
} |
// --------------------------------- |
void DrawGL (WindowRef window) |
{ |
Rect rectPort; |
pRecWindow pWindowInfo = (pRecWindow) GetWRefCon (window); |
pRecSprite pCenterSprite; |
long width, height, i; |
float worldX, worldY, worldZ, worldRotation, worldZoom; |
if (!pWindowInfo || !(pWindowInfo->aglContext)) |
return; |
aglSetCurrentContext (pWindowInfo->aglContext); |
GetWindowPortBounds (window, &rectPort); |
width = rectPort.right - rectPort.left; |
height = rectPort.bottom - rectPort.top; |
glViewport (0, 0, width, height); |
glEnable (GL_DEPTH_TEST); |
glMatrixMode (GL_PROJECTION); |
glLoadIdentity (); |
glOrtho (-width / 2.0, width / 2.0, -height / 2.0, height / 2.0, 0, 1000); // pixel coordinate othro projection |
glScalef (1.0, -1.0, 1.0); |
glMatrixMode (GL_MODELVIEW); |
glLoadIdentity (); |
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
// get center and rotation of rocket |
pCenterSprite = &(pWindowInfo->pSpriteArray[0]); // rocket is first sprite |
worldX = -pCenterSprite->centerX; |
worldY = -pCenterSprite->centerY; |
worldZ = -pCenterSprite->centerZ; |
if (!gRocketRotate) |
worldRotation = -pCenterSprite->rotation; |
else |
worldRotation = 0.0; |
worldZoom = pWindowInfo->zoom; |
for (i = 0; i < pWindowInfo->numSprites; i++) |
DrawGLSprite (&(pWindowInfo->pSpriteArray[i]), pWindowInfo->pImageArray, |
worldX, worldY, worldZ, worldRotation, worldZoom, width, height, |
pWindowInfo->grid, pWindowInfo->lines); |
if (pWindowInfo->info) |
DrawInfo (worldX, worldY, worldRotation, worldZoom, width, height, pWindowInfo->fontList); |
aglSwapBuffers (pWindowInfo->aglContext); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14