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.
Source/Process.c
/****************************/ |
/* PROCESS.C */ |
/* By Brian Greenstone */ |
/****************************/ |
/****************************/ |
/* EXTERNALS */ |
/****************************/ |
#include <Resources.h> |
#include <NumberFormatting.h> |
#include <QuickTimeComponents.h> |
#include <QD3D.h> |
#include <QD3DGeometry.h> |
#include <QD3DMath.h> |
#include <QD3DView.h> |
#include <QD3DGroup.h> |
#include <QD3DTransform.h> |
#include <QD3DStorage.h> |
#include "myglobals.h" |
#include "misc.h" |
#include "process.h" |
#include "qd3d_support.h" |
extern float gFramesPerSecond; |
/****************************/ |
/* PROTOTYPES */ |
/****************************/ |
static void InitModelWindow(void); |
static void BuildTestModel(void); |
static TQ3SurfaceShaderObject QD3D_GetTextureMap(long textureRezID); |
static TQ3SurfaceShaderObject QD3D_PICTToTexture(PicHandle picture); |
/****************************/ |
/* CONSTANTS */ |
/****************************/ |
#define MODEL_WIND_ID 400 |
#define TEXTURE_ORIGINAL_DEPTH 32 |
/*********************/ |
/* VARIABLES */ |
/*********************/ |
WindowPtr gModelWindow = nil; |
QD3DSetupOutputType gModelViewInfo; |
TQ3Object gModelGroup = nil; |
TQ3GroupObject gBaseGroup = nil; |
CodecQ gCodecQuality = codecNormalQuality; |
CodecType gCodecType = kRawCodecType; |
CodecComponent gCodecComponent = anyCodec; |
short gCodecDepth = TEXTURE_ORIGINAL_DEPTH; |
short gCodecDepth2 = TEXTURE_ORIGINAL_DEPTH; |
TQ3AttributeSet gTextureAttr; |
TQ3Matrix4x4 gTransformMatrix; |
TQ3Object gTransformObject = nil; |
Str255 gCompressionRatio,gCompressionSize; |
#pragma mark ========INITIALIZATION STUFF========= |
/******************** INIT TEST ************************/ |
void InitTest(void) |
{ |
/* INIT THE WINDOW */ |
InitModelWindow(); |
/* CREATE THE TEST MODEL */ |
BuildTestModel(); |
/* CREATE DISPLAY GROUP */ |
gBaseGroup = Q3DisplayGroup_New(); // make display group |
Q3Matrix4x4_SetIdentity(&gTransformMatrix); |
gTransformObject = Q3MatrixTransform_New(&gTransformMatrix); // make transform object |
Q3Group_AddObject(gBaseGroup, gTransformObject); // add to group |
Q3Group_AddObject(gBaseGroup, gModelGroup); // add geometry to group |
/* DRAW THE WINDOW */ |
DrawModelWindow(); |
} |
/************** INIT MODEL WINDOW *******************/ |
static void InitModelWindow(void) |
{ |
QD3DSetupInputType viewDef; |
TQ3Point3D cameraFrom = { 0,0, 100 }; |
TQ3Point3D cameraTo = { 0, 0, 0 }; |
TQ3Vector3D cameraUp = { 0.0, 1.0, 0 }; |
TQ3ColorARGB clearColor = {1,0,0,.5}; |
TQ3ColorRGB ambientColor = { 1.0, 1.0, 1.0 }; |
TQ3Vector3D fillDirection1 = {1, -.3, -.8 }; |
TQ3Vector3D fillDirection2 = { -1, -.1, -.2 }; |
/* CREATE THE WINDOW */ |
gModelWindow = GetNewCWindow(MODEL_WIND_ID, nil,MOVE_TO_FRONT); |
if (gModelWindow == nil) |
DoFatalAlert("\pWhere did the GameWindow window go?"); |
SetPort((GrafPtr)gModelWindow); |
/***********************/ |
/* SET QD3D PARAMETERS */ |
/***********************/ |
viewDef.view.displayWindow = gModelWindow; |
viewDef.view.rendererType = kQ3RendererTypeInteractive; |
viewDef.view.clearColor = clearColor; |
viewDef.view.paneClip.left = 0; |
viewDef.view.paneClip.right = 0; |
viewDef.view.paneClip.top = 16; |
viewDef.view.paneClip.bottom = 0; |
viewDef.styles.interpolation = kQ3InterpolationStyleVertex; |
viewDef.styles.backfacing = kQ3BackfacingStyleBoth; |
viewDef.styles.fill = kQ3FillStyleFilled; |
viewDef.styles.illuminationType = kQ3IlluminationTypePhong; |
viewDef.camera.from = cameraFrom; |
viewDef.camera.to = cameraTo; |
viewDef.camera.up = cameraUp; |
viewDef.camera.hither = 5; |
viewDef.camera.yon = 3000; |
viewDef.camera.fov = 1.0; |
viewDef.lights.ambientBrightness = 1.0; |
viewDef.lights.ambientColor = ambientColor; |
viewDef.lights.numFillLights = 2; |
viewDef.lights.fillDirection[0] = fillDirection1; |
viewDef.lights.fillDirection[1] = fillDirection2; |
viewDef.lights.fillColor[0] = ambientColor; |
viewDef.lights.fillColor[1] = ambientColor; |
viewDef.lights.fillBrightness[0] = 1.1; |
viewDef.lights.fillBrightness[1] = 0.4; |
QD3D_SetupWindow(&viewDef, &gModelViewInfo); |
} |
/********************* BUILD TEST MODEL **************************/ |
static void BuildTestModel(void) |
{ |
TQ3TriMeshData myTriMeshData; |
TQ3TriMeshAttributeData vertexAttribs[3],faceAttribs; |
TQ3Point3D points[3] = |
{ |
0,35,0, |
-35,-35,0, |
35,-35,0 |
}; |
TQ3Vector3D vertexNormals[3] = |
{ |
0,0,1, |
0,0,1, |
0,0,1 |
}; |
TQ3Vector3D faceNormals[1] = |
{ |
0,0,1 |
}; |
TQ3Param2D uvArray[3] = |
{ |
.5,1, |
0,0, |
1,0 |
}; |
TQ3TriMeshTriangleData triangles[1] = |
{ |
0,1,2 |
}; |
TQ3SurfaceShaderObject texture; |
/* FIRST LOAD THE TEXTUREMAP */ |
texture = QD3D_GetTextureMap(128); |
gTextureAttr = Q3AttributeSet_New(); |
Q3AttributeSet_Add(gTextureAttr, kQ3AttributeTypeSurfaceShader, &texture); |
/* BUILD MAIN TRIMESH DATA STRUCTURE */ |
myTriMeshData.triMeshAttributeSet = gTextureAttr; |
myTriMeshData.numTriangles = 1; |
myTriMeshData.triangles = &triangles[0]; |
myTriMeshData.numTriangleAttributeTypes = 1; |
myTriMeshData.triangleAttributeTypes = &faceAttribs; |
myTriMeshData.numEdges = 0; |
myTriMeshData.edges = nil; |
myTriMeshData.numEdgeAttributeTypes = 0; |
myTriMeshData.edgeAttributeTypes = nil; |
myTriMeshData.numPoints = 3; |
myTriMeshData.points = &points[0]; |
myTriMeshData.numVertexAttributeTypes = 1; |
myTriMeshData.vertexAttributeTypes = &vertexAttribs[0]; |
/* CALCULATE BOUNDING BOX */ |
Q3BoundingBox_SetFromPoints3D(&myTriMeshData.bBox, &points[0], 3, sizeof(TQ3Point3D)); |
/* CREATE FACE ATTRIBUTES */ |
faceAttribs.attributeType = kQ3AttributeTypeNormal; |
faceAttribs.data = &faceNormals[0]; |
faceAttribs.attributeUseArray = nil; |
/* CREATE VERTEX ATTRIBUTES */ |
vertexAttribs[0].attributeType = kQ3AttributeTypeSurfaceUV; |
vertexAttribs[0].data = &uvArray[0]; |
vertexAttribs[0].attributeUseArray = nil; |
/* MAKE THE TRIMESH GEOMETRY OBJECT */ |
gModelGroup = Q3TriMesh_New(&myTriMeshData); |
if (gModelGroup == nil) |
DoFatalAlert("\pQ3TriMesh_New failed!"); |
} |
#pragma mark =========UPDATING============ |
/*************** DO MODEL WINDOW NULL EVENT **********************/ |
void DoModelWindowNullEvent(void) |
{ |
TQ3Matrix4x4 m; |
/* ROTATE THE GEOMETRY */ |
QD3D_CalcFramesPerSecond(); |
Q3Matrix4x4_SetRotate_XYZ(&m,0.4/gFramesPerSecond,0.5/gFramesPerSecond,0); |
Q3Matrix4x4_Multiply(&m,&gTransformMatrix,&gTransformMatrix); |
/* UPDATE THE MATRIX */ |
Q3MatrixTransform_Set(gTransformObject,&gTransformMatrix); |
/* REDRAW IT */ |
DrawModelWindow(); |
} |
/******************* DRAW MODEL WINDOW *********************/ |
// |
// Calls the support function QD3D_DrawScene. |
// It passes the view info and a pointer to the game draw callback. |
// |
void DrawModelWindow(void) |
{ |
QD3D_DrawScene(&gModelViewInfo,(void *)DrawTheGeometry); |
} |
/*************** DRAW THE GEOMETRY ******************/ |
void DrawTheGeometry(QD3DSetupOutputType *viewInfo) |
{ |
Q3Object_Submit(gBaseGroup,viewInfo->viewObject); |
} |
#pragma mark ======= COMPRESSION STUFF ======== |
/****************** SELECT COMPRESSOR ************************/ |
void SelectCompressor(void) |
{ |
ComponentInstance aComponent; |
OSErr iErr; |
PicHandle picture; |
ComponentResult aCompRes; |
Boolean cancel = false; |
SCSpatialSettings spatialInfo; |
TQ3Object texture; |
/* CREATE COMPONENT */ |
aComponent = OpenDefaultComponent('scdi', 'imag'); |
if (aComponent == nil) |
DoFatalAlert("\pSelectCompressor: OpenDefaultComponent failed!"); |
/* SET TEST PICT */ |
picture = GetPicture(128); |
aCompRes = SCSetTestImagePictHandle(aComponent, picture, nil, 0); |
/* DO THE DIALOG */ |
aCompRes = SCRequestImageSettings(aComponent); |
if (aCompRes == scUserCancelled) |
{ |
cancel = true; |
goto cleanup; |
} |
if (aCompRes < 0) |
DoFatalAlert("\pSelectCompressor: SCRequestSequenceSettings failed!"); |
/* EXTRACT INFO */ |
aCompRes = SCGetInfo(aComponent, scSpatialSettingsType, &spatialInfo); |
if (aCompRes < 0) |
DoFatalAlert("\pSelectCompressor: SCGetInfo failed!"); |
gCodecType = spatialInfo.codecType; // get codec type |
gCodecComponent = spatialInfo.codec; // get codec component |
gCodecQuality = spatialInfo.spatialQuality; // get quality |
gCodecDepth = spatialInfo.depth; // get depth |
if (gCodecDepth & (1<<5)) // see if using greyscale |
gCodecDepth2 = gCodecDepth & 0x1f; // mask out bit depth from encoded value |
else |
gCodecDepth2 = gCodecDepth; |
/* CHANGE TEXTURE */ |
Q3AttributeSet_Clear(gTextureAttr, kQ3AttributeTypeSurfaceShader); |
texture = QD3D_GetTextureMap(128); // get original texture (and knock to gCodecDepth) |
Q3AttributeSet_Add(gTextureAttr, kQ3AttributeTypeSurfaceShader, &texture); |
Q3Object_Dispose(texture); |
/* CLEANUP */ |
cleanup: |
ReleaseResource((Handle)picture); // nuke pict |
iErr = CloseComponent(aComponent); // nuke component |
if (iErr) |
DoFatalAlert("\pSelectCompressor: CloseComponent failed!"); |
} |
/**************** QD3D GET TEXTURE MAP ***********************/ |
// |
// Loads a PICT resource and returns a shader object which is |
// based on the PICT converted to a texture map. |
// |
// INPUT: textureRezID = resource ID of texture PICT to get. |
// myFSSpec != nil if want to load PICT from file instead |
// |
// OUTPUT: TQ3ShaderObject = shader object for texture map. |
// |
static TQ3SurfaceShaderObject QD3D_GetTextureMap(long textureRezID) |
{ |
PicHandle picture; |
TQ3SurfaceShaderObject shader; |
/* LOAD PICT REZ */ |
picture = GetPicture (textureRezID); |
if (picture == nil) |
DoFatalAlert("\pUnable to load texture PICT resource"); |
/* CONVERT PICT TO TEXTURE OBJECT */ |
shader = QD3D_PICTToTexture(picture); |
ReleaseResource ((Handle) picture); |
return(shader); |
} |
/**************** QD3D PICT TO TEXTURE ***********************/ |
// |
// |
// INPUT: picture = handle to PICT. |
// |
// OUTPUT: TQ3ShaderObject = shader object for texture map. |
// |
static TQ3SurfaceShaderObject QD3D_PICTToTexture(PicHandle picture) |
{ |
TQ3CompressedPixmap pixmap; |
TQ3TextureObject texture; |
TQ3SurfaceShaderObject shader; |
long width, height,numBytesPerPixel; |
Rect rectGW; |
GWorldPtr pGWorld; |
PixMapHandle hPixMap; |
OSErr myErr; |
GDHandle oldGD; |
GWorldPtr oldGW; |
unsigned long pictMapAddr; |
unsigned long pictRowBytes; |
TQ3Status status; |
/* CALC DIMENSIONS OF TEXTURE */ |
width = (**picture).picFrame.right - (**picture).picFrame.left; |
height = (**picture).picFrame.bottom - (**picture).picFrame.top; |
/* CREATE A GWORLD TO DRAW PICT INTO */ |
GetGWorld(&oldGW, &oldGD); // save current port |
SetRect(&rectGW, 0, 0, width, height); // set dimensions |
myErr = NewGWorld(&pGWorld, gCodecDepth2, &rectGW, 0, 0, 0L); // make gworld |
if (myErr) |
DoFatalAlert("\pQD3D_PICTToTexture: NewGWorld failed!"); |
/* DRAW PICTURE INTO GWORLD */ |
hPixMap = GetGWorldPixMap(pGWorld); // get gworld's pixmap |
numBytesPerPixel = ((int)(**hPixMap).pixelSize/8); // need this for ratio calculation below |
SetGWorld(pGWorld, nil); |
LockPixels(hPixMap); |
EraseRect(&rectGW); |
DrawPicture(picture, &rectGW); |
/****************************************/ |
/* MAKE A COMPRESSED PIXMAP FROM GWORLD */ |
/****************************************/ |
/* GET TEXTURE ADDR & ROWBYTES */ |
pictMapAddr = (unsigned long )GetPixBaseAddr(hPixMap); |
pictRowBytes = (unsigned long)(**hPixMap).rowBytes & 0x3fff; |
/* FILL OUT COMPRESSED PIXMAP STRUCTURE */ |
pixmap.compressedImage = nil; |
pixmap.imageDesc = nil; |
pixmap.makeMipmaps = kQ3True; |
pixmap.width = width; |
pixmap.height = height; |
if (gCodecDepth == 32) |
{ |
pixmap.pixelSize = 32; |
pixmap.pixelType = kQ3PixelTypeRGB32; |
} |
else |
{ |
pixmap.pixelSize = 16; |
pixmap.pixelType = kQ3PixelTypeRGB16; |
} |
/* COMPRESS IMAGE AND FILL OUT REMAINING RECORDS IN STRUCTURE */ |
// |
// pass in compression quality, codec type, etc. |
// |
status = Q3CompressedPixmapTexture_CompressImage(&pixmap, hPixMap, gCodecType, gCodecComponent, |
gCodecDepth, gCodecQuality); |
SetGWorld (oldGW, oldGD); |
DisposeGWorld (pGWorld); |
if (status == kQ3Failure) |
DoFatalAlert("\pQ3CompressedPixmapTexture_CompressImage Failed!"); |
/* CALC COMPRESSION RATIO FOR DISPLAYING */ |
{ |
unsigned char *buffer; |
unsigned long compSize; |
float unCompSize; |
Q3MemoryStorage_GetBuffer(pixmap.compressedImage, &buffer, &compSize, &compSize); // get compressed size |
// unCompSize = width * height * numBytesPerPixel; // calc uncompressed size |
unCompSize = width * height * (TEXTURE_ORIGINAL_DEPTH/8); // calc uncompressed size (based on original depth) |
FloatToString((float)compSize/unCompSize,gCompressionRatio); // calc compression ratio and convert to string |
NumToString(compSize, gCompressionSize); // also calc string for compressed size |
} |
/***************************/ |
/* MAKE NEW PIXMAP TEXTURE */ |
/***************************/ |
/* MAKE NEW COMPRESSED PIXMAP TEXTUE OBJECT */ |
texture = Q3CompressedPixmapTexture_New (&pixmap); |
if (texture == nil) |
DoFatalAlert("\pError calling Q3CompressedPixmapTexture_New!"); |
/* MAKE NEW SHADER FROM TEXTURE */ |
shader = Q3TextureShader_New (texture); |
if (shader == nil) |
DoFatalAlert("\pError calling Q3TextureShader_New!"); |
Q3Object_Dispose(texture); |
Q3Object_Dispose(pixmap.compressedImage); // disposes of extra reference to storage objs |
Q3Object_Dispose(pixmap.imageDesc); |
return(shader); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14