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.
Test Code/TinselTest.c
/****************************************************************************** |
** ** |
** Module: TinselTest.c ** |
** ** |
** Purpose: Main file for Tinsel Town test app ** |
** ** |
** Author: Mike W. Kelley ** |
** ** |
** 2/3/95 Revised for 0.9 SDK release ** |
** ** |
** Copyright (C) 1994-95 Apple Computer, Inc. All rights reserved. ** |
** ** |
*****************************************************************************/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <math.h> |
/* Macintosh */ |
#include <Types.h> |
#include <QuickDraw.h> |
#include <Windows.h> |
/* Project */ |
#include "RAVE.h" |
#include "TinselTest.h" |
/******************************************************************************************* |
* |
* Defines that affect how the tests are run. |
* |
******************************************************************************************/ |
#define dWaitForButton /* If defined, wait for button click between tests */ |
/******************************************************************************************* |
* |
* Declare the registration function for the empty rasterizer. This allows us to call |
* it from our app, so we can link the rasterizer in instead of using a shared library. |
* |
******************************************************************************************/ |
extern OSErr TtRegister (void); |
/******************************************************************************************* |
* |
* Globals. |
* |
******************************************************************************************/ |
long gWindowWidth, gWindowHeight; |
TQAEngine *gEngine [kTinselWindows]; |
TQADrawContext *gDrawContext [kTinselWindows]; |
TQATexture *gTexture [kTinselWindows]; |
/******************************************************************************************* |
* |
* Static variables used by this file's functions only. |
* |
******************************************************************************************/ |
static float frand (void) |
{ |
return ((Random() + 32768) / 65536.0); |
} |
/******************************************************************************************* |
* |
* Main. This runs the tests, clearing the windows before each test and waiting for |
* a mouse click after each test. Each test is run four ways: Single and double buffered, |
* with and without 2D clipping. |
* |
******************************************************************************************/ |
int main() |
{ |
long tinselTest, tinselStyle; |
long i; |
TQAVGouraud vGouraud[3]; |
TQAVTexture vTexture[3]; |
long flushCount; |
/* |
* If we are running with a shared library, TdLinkEngine should not be defined! |
*/ |
#ifdef dLinkEngine |
(void) TtRegister(); |
#endif |
/* |
* Create the test window(s). |
*/ |
InitToolbox (); |
if ( ! CreateTestWindows (kTinselMaxWindowSize, kTinselMaxWindowSize)) |
{ |
return (-1); |
} |
if ( ! CreateWindowClip ()) |
{ |
return (-1); |
} |
if ( ! TestTextureNew()) |
{ |
return (-1); |
} |
/* |
* Run tests. |
*/ |
for (tinselStyle = 0; tinselStyle <= kMaxStyle; ++tinselStyle) |
{ |
switch (tinselStyle) |
{ |
case kStyleSingleBuffered: |
if ( ! TestDrawContextNew (kQAContext_DeepZ, false)) |
{ |
return (-1); |
} |
break; |
case kStyleDoubleBuffered: |
if ( ! TestDrawContextNew (kQAContext_DeepZ | kQAContext_DoubleBuffer, false)) |
{ |
return (-1); |
} |
break; |
case kStyleSingleBufferedClip: |
if ( ! TestDrawContextNew (kQAContext_DeepZ, true)) |
{ |
return (-1); |
} |
break; |
case kStyleDoubleBufferedClip: |
if ( ! TestDrawContextNew (kQAContext_DeepZ | kQAContext_DoubleBuffer, true)) |
{ |
return (-1); |
} |
break; |
} |
ClearWindows(); |
for (tinselTest = 0; tinselTest <= kMaxTest; ++tinselTest) |
{ |
switch (tinselTest) |
{ |
case kTestPoints: |
TestRenderStart(); |
for (i = 0, flushCount = kNPoints / kNFlushes; i++ < kNPoints; /* Nothing */) |
{ |
TestRandomVGouraud (&vGouraud[0]); |
TestDrawPoint (&vGouraud[0]); |
if ((i % flushCount) == 0) |
{ |
TestFlush(); |
} |
} |
TestRenderEnd(); |
break; |
case kTestLines: |
TestRenderStart(); |
for (i = 0, flushCount = kNLines / kNFlushes; i++ < kNLines; /* Nothing */) |
{ |
TestRandomVGouraud (&vGouraud[0]); |
TestRandomVGouraud (&vGouraud[1]); |
TestDrawLine (&vGouraud[0], &vGouraud[1]); |
if ((i % flushCount) == 0) |
{ |
TestFlush(); |
} |
} |
TestRenderEnd(); |
break; |
case kTestTriGouraud: |
TestRenderStart(); |
for (i = 0, flushCount = kNTris / kNFlushes; i++ < kNTris; /* Nothing */) |
{ |
TestRandomVGouraud (&vGouraud[0]); |
TestRandomVGouraud (&vGouraud[1]); |
TestRandomVGouraud (&vGouraud[2]); |
TestDrawTriGouraud (&vGouraud[0], |
&vGouraud[1], &vGouraud[2], kQATriFlags_None); |
if ((i % flushCount) == 0) |
{ |
TestFlush(); |
} |
} |
TestRenderEnd(); |
break; |
case kTestTriTexture: |
TestRenderStart(); |
TestSetStateTexture(); |
for (i = 0, flushCount = kNTris / kNFlushes; i++ < kNTris; /* Nothing */) |
{ |
/* |
* Setup the u,v values before calling TestRandomVTexture(), |
* as it references them. |
*/ |
vTexture[0].uOverW = 0.0; |
vTexture[0].vOverW = 0.0; |
vTexture[1].uOverW = 0.0; |
vTexture[1].vOverW = 1.0; |
vTexture[2].uOverW = 1.0; |
vTexture[2].vOverW = 1.0; |
TestRandomVTexture (&vTexture[0]); |
TestRandomVTexture (&vTexture[1]); |
TestRandomVTexture (&vTexture[2]); |
TestDrawTriTexture (&vTexture[0], |
&vTexture[1], &vTexture[2], kQATriFlags_None); |
if ((i % flushCount) == 0) |
{ |
TestFlush(); |
} |
} |
TestRenderEnd(); |
break; |
} |
#ifdef dWaitForButton |
/* |
* Wait for a mouse button click.. |
*/ |
while ( ! Button()) |
/* Do nothing */ ; |
FlushEvents (everyEvent, 0); |
#endif |
} |
TestDrawContextDelete(); |
} |
return (0); |
} |
/******************************************************************************************* |
* |
* Set xyzw fields of a TQAVGouraud randomly. All other fields get simple defaults. |
* |
******************************************************************************************/ |
void TestRandomVGouraud ( |
TQAVGouraud *v) |
{ |
v->x = frand() * gWindowWidth; |
v->y = frand() * gWindowHeight; |
v->z = frand(); |
v->invW = 1.0 / v->z; |
v->a = 1.0; |
v->r = frand(); |
v->g = frand(); |
v->b = frand(); |
} |
/******************************************************************************************* |
* |
* Set xyzw fields of a TQAVTexture randomly. The incoming u,v values are multiplied |
* by the random invW value; all other fields get simple defaults. |
* |
******************************************************************************************/ |
void TestRandomVTexture ( |
TQAVTexture *v) |
{ |
v->x = frand() * gWindowWidth; |
v->y = frand() * gWindowHeight; |
v->z = frand(); |
v->invW = 1.0 / v->z; |
v->uOverW *= v->invW; |
v->vOverW *= v->invW; |
v->a = 1.0; |
v->r = 0.0; |
v->g = 0.0; |
v->b = 0.0; |
v->kd_r = 1.0; |
v->kd_g = 1.0; |
v->kd_b = 1.0; |
v->ks_r = 0.0; |
v->ks_g = 0.0; |
v->ks_b = 0.0; |
} |
/******************************************************************************************* |
* |
* Miscellaneous test functions. |
* |
******************************************************************************************/ |
void TestRenderStart (void) |
{ |
long i; |
for (i = 0; i < kTinselWindows; ++i) |
{ |
if (gDrawContext [i]) |
{ |
QARenderStart (gDrawContext [i], NULL, NULL); |
} |
} |
} |
void TestRenderEnd (void) |
{ |
long i; |
TQAError status; |
for (i = 0; i < kTinselWindows; ++i) |
{ |
if (gDrawContext [i]) |
{ |
status = QARenderEnd (gDrawContext [i], NULL); |
} |
} |
} |
void TestSetStateTexture (void) |
{ |
long i; |
for (i = 0; i < kTinselWindows; ++i) |
{ |
if (gDrawContext [i]) |
{ |
QASetPtr (gDrawContext [i], kQATag_Texture, gTexture [i]); |
/* |
* NOTE: The current Apple software rasterizer always assumes these |
* kQATextureOp_Modulate | kQATextureOp_Highlight are set, as that's |
* the standard QuickDrawª 3D mode. So if you change this, you may |
* find that the software rasterizer isn't a good test case. |
* (This will be fixed soon...) |
*/ |
QASetInt (gDrawContext [i], kQATag_TextureOp, |
kQATextureOp_Modulate | kQATextureOp_Highlight); |
} |
} |
} |
void TestFlush (void) |
{ |
long i; |
for (i = 0; i < kTinselWindows; ++i) |
{ |
if (gDrawContext [i]) |
{ |
QAFlush (gDrawContext [i]); |
} |
} |
} |
void TestDrawPoint ( |
const TQAVGouraud *v) |
{ |
long i; |
for (i = 0; i < kTinselWindows; ++i) |
{ |
if (gDrawContext [i]) |
{ |
QADrawPoint (gDrawContext [i], v); |
} |
} |
} |
void TestDrawLine ( |
const TQAVGouraud *v0, |
const TQAVGouraud *v1) |
{ |
long i; |
for (i = 0; i < kTinselWindows; ++i) |
{ |
if (gDrawContext [i]) |
{ |
QADrawLine (gDrawContext [i], v0, v1); |
} |
} |
} |
void TestDrawTriGouraud ( |
const TQAVGouraud *v0, |
const TQAVGouraud *v1, |
const TQAVGouraud *v2, |
unsigned long flags) |
{ |
long i; |
for (i = 0; i < kTinselWindows; ++i) |
{ |
if (gDrawContext [i]) |
{ |
QADrawTriGouraud (gDrawContext [i], v0, v1, v2, flags); |
} |
} |
} |
void TestDrawTriTexture ( |
const TQAVTexture *v0, |
const TQAVTexture *v1, |
const TQAVTexture *v2, |
unsigned long flags) |
{ |
long i; |
for (i = 0; i < kTinselWindows; ++i) |
{ |
/* |
* Test both for a draw context, and that a texture was created. |
*/ |
if (gDrawContext [i] && gTexture [i]) |
{ |
QADrawTriTexture (gDrawContext [i], v0, v1, v2, flags); |
} |
} |
} |
Boolean TestTextureNew (void) |
{ |
TexturePixel *pixmap; |
long x, y; |
long i; |
/* |
* Create the source pixmap. Note that we can't free it (unless we |
* called QATextureDetach()). We just do a procedural map with some |
* checkerboard effect... |
*/ |
if ( ! (pixmap = malloc (sizeof (*pixmap) * kTextureSize * kTextureSize))) |
{ |
return (false); |
} |
for (x = 0; x < kTextureSize; ++x) |
{ |
for (y = 0; y < kTextureSize; ++y) |
{ |
pixmap [x + (y << kTextureSizeNBits)].a = 0xff; |
pixmap [x + (y << kTextureSizeNBits)].r = (x & 0x1f) << 3; |
pixmap [x + (y << kTextureSizeNBits)].g = (y & 0x1f) << 3; |
pixmap [x + (y << kTextureSizeNBits)].b = (((x + y) / 2) & 0x1f) << 3; |
} |
} |
for (i = 0; i < kTinselWindows; ++i) |
{ |
if (gEngine [i]) |
{ |
/* |
* Create the texture. If this fails, gTexture[i] will be NULL. |
* This is ok, as TestDrawTriTexture() always tests it before calling |
* QADrawTriTexture(). |
*/ |
gTexture [i] = CreateMipMapTexture ( |
gEngine [i], /* store context */ |
pixmap, /* high res pix map */ |
kTextureSize * sizeof (*pixmap), /* row bytes */ |
kTextureSizeNBits, /* widthNBits */ |
kTextureSizeNBits); /* heightNBits */ |
} |
} |
return (true); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14