1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: pix-z-comp.c
4
5 Copyright 1998-2006 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12 *---------------------------------------------------------------------------*/
13 #include <demo.h>
14 #include "cmn-model.h"
15
16 #define SCREEN_WD 1 // Dummy - actual value filled at runtime
17 #define SCREEN_HT 1 // Dummy - actual value filled at runtime
18 #define SCREEN_DEPTH 128.0f
19 #define SCREEN_ZNEAR 0.0f // near plane Z in screen coordinates
20 #define SCREEN_ZFAR 1.0f // far plane Z in screen coordinates
21 #define ZBUFFER_MAX 0x00ffffff
22
23 /*---------------------------------------------------------------------------*
24 Typedefs
25 *---------------------------------------------------------------------------*/
26 typedef struct
27 {
28 char* title;
29 // GXSetZMode
30 GXBool compare_enable;
31 GXCompare func;
32 GXBool update_enable;
33 // GXSetZCompLoc
34 GXBool before_tex;
35 } ZMode;
36
37 typedef struct
38 {
39 Model* model;
40 Camera* camera;
41 ViewPort* viewport;
42 ZMode* zmode;
43 u32 flag;
44 } Scene;
45
46 #define SCENE_DRAWN (1<<0)
47 #define SCENE_CURSOR (1<<1)
48
49 /*---------------------------------------------------------------------------*
50 Forward references
51 *---------------------------------------------------------------------------*/
52 void SceneDraw( Scene* );
53 void SceneDrawInfo( Scene* );
54 void SceneControl( void );
55 void myDrawModel( s32, s32, ZMode* );
56 static void PrintIntro( void );
57
58 /*---------------------------------------------------------------------------*
59 Rendering parameters
60 *---------------------------------------------------------------------------*/
61 Camera myCamera =
62 {
63 { 0.0f, 0.0f, 30.0f }, // position (ignored in this demo)
64 { 0.0f,1000.0f, 0.0f }, // target (ignored in this demo)
65 { 0.0f, 0.0f, 1.0f }, // upVec (ignored in this demo)
66 33.3f, // fovy (ignored in this demo)
67 16.0f, // near plane Z in camera coordinates
68 1024.0f, // far plane Z in camera coordinates
69 };
70
71 ViewPort myViewPort[] =
72 {
73 // full size (these are adjusted in main)
74 { 0, 0, SCREEN_WD*2, SCREEN_HT*2 },
75 // half size
76 { 0, 0, SCREEN_WD, SCREEN_HT },
77 { 0, SCREEN_HT, SCREEN_WD, SCREEN_HT },
78 { SCREEN_WD, 0, SCREEN_WD, SCREEN_HT },
79 { SCREEN_WD, SCREEN_HT, SCREEN_WD, SCREEN_HT },
80 };
81
82 ZMode myZMode[] =
83 {
84 { NULL, GX_TRUE, GX_EQUAL, GX_TRUE, GX_TRUE },
85 { NULL, GX_TRUE, GX_LESS, GX_TRUE, GX_TRUE },
86 { NULL, GX_TRUE, GX_GREATER, GX_TRUE, GX_TRUE },
87 { NULL, GX_TRUE, GX_ALWAYS, GX_TRUE, GX_TRUE },
88 };
89
90 // ZScale for test
91 float sceneZScale = 1.0f;
92
93 GXColor sceneBgColor = { 32, 32, 128,255};
94
95 Scene myScene[] =
96 {
97 { &cmModel[1], &myCamera, &myViewPort[0], &myZMode[0], 0 },
98 { &cmModel[1], &myCamera, &myViewPort[1], &myZMode[0], 0 },
99 { &cmModel[1], &myCamera, &myViewPort[2], &myZMode[1], 0 },
100 { &cmModel[1], &myCamera, &myViewPort[3], &myZMode[2], 0 },
101 { &cmModel[1], &myCamera, &myViewPort[4], &myZMode[3], 0 },
102 };
103
104 #define NUMSCENE (sizeof(myScene)/sizeof(Scene))
105
106 /*---------------------------------------------------------------------------*
107 Application main loop
108 *---------------------------------------------------------------------------*/
main(void)109 void main ( void )
110 {
111 GXRenderModeObj *rmp;
112 u32 i;
113
114 // initialize render settings and set clear color for first frame
115 DEMOInit( NULL ); // Defined in $(REVOLUTION_SDK_ROOT)/build/libraries/demo/src/DEMOInit.c
116 GXInvalidateTexAll( );
117 GXSetCopyClear( sceneBgColor, GX_MAX_Z24 );
118
119 // Perform dummy copy operation to clear eFB by specified color
120 GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
121
122 rmp = DEMOGetRenderModeObj();
123
124 for(i = 0; i < 5; i++)
125 {
126 myViewPort[i].xorg *= rmp->fbWidth/2;
127 myViewPort[i].yorg *= rmp->efbHeight/2;
128 myViewPort[i].width *= rmp->fbWidth/2;
129 myViewPort[i].height *= rmp->efbHeight/2;
130 }
131
132 PrintIntro();
133
134 while ( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) )
135 {
136 // get pad status
137 DEMOPadRead( );
138 // General control & model animation
139 SceneControl( );
140 // No animation for this model.
141
142 // Draw scene
143 DEMOBeforeRender( );
144 for ( i = 0; i < NUMSCENE; i ++ )
145 {
146 SceneDraw( &myScene[i] );
147 }
148 DEMODoneRender( );
149 }
150
151 OSHalt("End of test");
152 }
153
154 /*---------------------------------------------------------------------------*
155 Functions
156 *---------------------------------------------------------------------------*/
157
158 //============================================================================
159 // Scene
160 //============================================================================
161 typedef struct
162 {
163 GXCompare func;
164 char* name;
165 } ZComp;
166
167 ZComp myZComp[] =
168 {
169 { GX_NEVER, "NEVER" },
170 { GX_LESS, "LESS" },
171 { GX_LEQUAL, "LESS OR EQUAL" },
172 { GX_EQUAL, "EQUAL" },
173 { GX_NEQUAL, "NOT EQUAL" },
174 { GX_GEQUAL, "GREATER OR EQUAL" },
175 { GX_GREATER, "GREATER" },
176 { GX_ALWAYS, "ALWAYS" },
177 };
178
179 #define NUMZCOMPS (sizeof(myZComp)/sizeof(ZComp))
180
181 /*---------------------------------------------------------------------------*
182 Name: SceneDraw
183 Description: Draw model
184 Arguments: Scene* s
185 Returns: none
186 *---------------------------------------------------------------------------*/
SceneDraw(Scene * s)187 void SceneDraw( Scene* s )
188 {
189 ViewPort* v = s->viewport;
190 ZMode* z = s->zmode;
191
192 // Check if drawn flag
193 if ( !(s->flag & SCENE_DRAWN) ) return;
194
195 // Set Viewport
196 GXSetViewport( v->xorg, v->yorg, v->width, v->height,
197 SCREEN_ZNEAR, SCREEN_ZFAR );
198 GXSetScissor( (u32)v->xorg, (u32)v->yorg, (u32)v->width, (u32)v->height );
199
200 // Draw objects
201 myDrawModel( (s32)v->width, (s32)v->height, z );
202
203 // draw information
204 SceneDrawInfo( s );
205
206 // Z mode should be enabled if you want to clear Z buffer
207 // at the timing of copy to XFB
208 GXSetZMode( GX_TRUE, GX_ALWAYS, GX_TRUE );
209
210 return;
211 }
212
213 /*---------------------------------------------------------------------------*
214 Name: SceneDrawInfo
215 Description: Draw scene information
216 Arguments:
217 Returns: none
218 *---------------------------------------------------------------------------*/
SceneDrawInfo(Scene * s)219 void SceneDrawInfo( Scene* s )
220 {
221 Camera* c = s->camera;
222 ViewPort* v = s->viewport;
223 ZMode* z = s->zmode;
224 s32 lid;
225 s8 log2;
226 union
227 {
228 f32 fval;
229 struct
230 {
231 s32 sgn:1;
232 u32 exp:8;
233 u32 mts:23;
234 } field;
235 } zfactor;
236
237 // Draw parameters to the window
238 DEMOInitCaption( DM_FT_XLU, v->width, v->height );
239 if ( z->title )
240 {
241 DEMOPuts( 15, 12, 0, z->title );
242 }
243 else
244 {
245 // get zcomp id
246 for ( lid = NUMZCOMPS-1; lid > 0; lid -- )
247 {
248 if ( z->func == myZComp[lid].func ) break;
249 }
250 DEMOPuts( 15, 12, 0, myZComp[lid].name );
251 }
252
253 // Draw precision of zscale
254 zfactor.fval = sceneZScale / SCREEN_DEPTH;
255 log2 = (s8)(zfactor.field.exp - 127);
256 DEMOPrintf( 160, 12, 0, "ZSCALE 2^%d", log2 );
257
258 // Draw cursor
259 if ( s->flag & SCENE_CURSOR ) DEMOPuts( 7, 12, 0, "\x7f" );
260
261 return;
262 }
263
264 /*---------------------------------------------------------------------------*
265 Name: SceneControl
266 Description: user interface for parameter control
267 Arguments:
268 Returns: none
269 *---------------------------------------------------------------------------*/
SceneControl(void)270 void SceneControl( void )
271 {
272 static s32 zoomMode = 0;
273 static s32 cursor = 0;
274 s32 i, lid;
275 u16 button, stickDirs;
276 Scene* s;
277 ZMode* z;
278
279 button = DEMOPadGetButtonDown(0);
280 stickDirs = DEMOPadGetDirsNew(0);
281
282 // zoom mode
283 if ( button & PAD_BUTTON_A ) zoomMode ^= 1;
284
285 // change zscale
286 if ( button & PAD_BUTTON_Y )
287 {
288 if ( sceneZScale < 1.0f ) sceneZScale *= 2.0f;
289 }
290 if ( button & PAD_BUTTON_X )
291 {
292 sceneZScale *= 0.5f;
293 }
294
295 if ( zoomMode )
296 {
297 //
298 // *** zoom mode
299 //
300
301 // show specified scene in full screen and put cursor
302 s = &myScene[cursor+1];
303 z = s->zmode;
304 myScene[0].zmode = z;
305 myScene[0].flag = SCENE_DRAWN | SCENE_CURSOR;
306
307 // turn off another window
308 for ( i = 1; i < NUMSCENE; i ++ )
309 {
310 myScene[i].flag = 0;
311 }
312
313 // get zmode id
314 for ( lid = NUMZCOMPS-1; lid > 0; lid -- )
315 {
316 if ( z->func == myZComp[lid].func ) break;
317 }
318
319 // change zfunc parameter
320 if ( stickDirs & DEMO_STICK_LEFT )
321 {
322 if ( lid > 0 ) lid --;
323 }
324 if ( stickDirs & DEMO_STICK_RIGHT )
325 {
326 if ( lid < NUMZCOMPS-1 ) lid ++;
327 }
328
329 // set parameter
330 z->func = myZComp[lid].func;
331 }
332 else
333 {
334 //
335 // *** catalog mode
336 //
337
338 // choose a scene.
339 if ( stickDirs & DEMO_STICK_LEFT ) cursor &= ~2; // left
340 if ( stickDirs & DEMO_STICK_RIGHT ) cursor |= 2; // right
341 if ( stickDirs & DEMO_STICK_UP ) cursor &= ~1; // up
342 if ( stickDirs & DEMO_STICK_DOWN ) cursor |= 1; // down
343
344 // show 4 small windows
345 for ( i = 1; i < 5; i ++ )
346 {
347 myScene[i].flag = SCENE_DRAWN;
348 }
349
350 // turn off large window
351 myScene[0].flag = 0;
352
353 // set cursor
354 s = &myScene[cursor+1];
355 s->flag |= SCENE_CURSOR;
356 }
357 return;
358 }
359
360 //============================================================================
361 // Model
362 // Rectangles
363 //============================================================================
364 typedef struct
365 {
366 f32 x0, y0, x1, y1, z;
367 GXColor color;
368 } myModel;
369
370 myModel rect[] =
371 {
372 // x0 y0 x1 y1 z color
373 { 30, 20,170,180, 50, { 64, 64,255,255 } },
374 { 10, 40,120, 90, 51, { 255, 64, 64,255 } },
375 { 80,110,190,160, 25, { 64,255, 64,255 } },
376 { 110, 10,160,120, 75, { 255,255, 64,255 } },
377 { 40, 80, 90,190, 49, { 64,255,255,255 } },
378 { 70, 70,130,130, 50, { 255,255,255,255 } },
379 };
380
381 #define NUMRECTS (sizeof(rect)/sizeof(myModel))
382
383 /*---------------------------------------------------------------------------*
384 Name: myDrawModel
385 Description: draw model
386 Arguments: f32 width : width of viewport
387 f32 height: height of viewport
388 Returns: none
389 *---------------------------------------------------------------------------*/
myDrawModel(s32 width,s32 height,ZMode * z)390 void myDrawModel( s32 width, s32 height, ZMode *z )
391 {
392 Mtx mtx;
393 s32 i;
394
395 // use constant material color
396 GXSetChanCtrl( GX_COLOR0,
397 GX_FALSE, // enable Channel
398 GX_SRC_REG, // amb source (Don't care)
399 GX_SRC_REG, // mat source
400 GX_LIGHT0, // light mask (Don't care)
401 GX_DF_NONE, // diffuse function (Don't care)
402 GX_AF_NONE ); // atten function (Don't care)
403 GXSetChanCtrl( GX_ALPHA0,
404 GX_FALSE, // enable Channel
405 GX_SRC_REG, // amb source (Don't care)
406 GX_SRC_REG, // mat source
407 GX_LIGHT0, // light mask (Don't care)
408 GX_DF_NONE, // diffuse function (Don't care)
409 GX_AF_NONE ); // atten function (Don't care)
410
411 // set cull mode
412 GXSetCullMode( GX_CULL_BACK );
413
414 // Load tags in point sample mode
415 DEMOLoadFont( GX_TEXMAP0, GX_TEXMTX0, DMTF_POINTSAMPLE );
416
417 // Here, use orthographic screen coordinates.
418 // Set normalized 0-200 screen coordinates and reduce z range in MTX0
419 // Set vertex descriptor on VTXFMT1
420 DEMOSetupScrnSpc( width, height, SCREEN_DEPTH );
421 MTXScale( mtx, ((float)width)/200.0f, ((float)height)/200.f, sceneZScale );
422 GXLoadPosMtxImm( mtx, GX_PNMTX0 );
423 GXSetVtxAttrFmt( GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_F32, 0 );
424
425 // Force to draw a first rectangle
426 GXSetZMode( GX_TRUE, GX_ALWAYS, GX_TRUE );
427
428 for ( i = 0; i < NUMRECTS; i ++ )
429 {
430 // Set material color to go through PE stage.
431 GXSetNumChans(1); // # of light channels
432 GXSetNumTexGens( 0 ); // # of Tex Gens
433 GXSetNumTevStages( 1 ); // # of Tev Stage
434 GXSetChanMatColor( GX_COLOR0A0, rect[i].color );
435 GXSetTevOrder( GX_TEVSTAGE0,
436 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0 );
437 GXSetTevOp( GX_TEVSTAGE0, GX_PASSCLR );
438 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR );
439
440 // Fill rectangle
441 GXClearVtxDesc( );
442 GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
443 GXBegin( GX_QUADS, GX_VTXFMT1, 4 );
444 GXPosition3f32( rect[i].x0, rect[i].y0, rect[i].z );
445 GXPosition3f32( rect[i].x1, rect[i].y0, rect[i].z );
446 GXPosition3f32( rect[i].x1, rect[i].y1, rect[i].z );
447 GXPosition3f32( rect[i].x0, rect[i].y1, rect[i].z );
448 GXEnd( );
449
450 // Set texture color to go through PE stage and XOR'ed by blender.
451 GXSetNumTexGens( 1 ); // # of Tex Gens
452 GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0 );
453 GXSetTevOp( GX_TEVSTAGE0, GX_REPLACE );
454 GXSetBlendMode( GX_BM_LOGIC, GX_BL_ONE, GX_BL_ZERO, GX_LO_XOR );
455
456 // Draw tag to show z value as coplanar surface
457 GXSetCoPlanar( GX_TRUE );
458 GXSetZMode( GX_TRUE, GX_EQUAL, GX_TRUE );
459 DEMOPrintf( (s16)rect[i].x0, (s16)rect[i].y0,
460 (s16)rect[i].z, "%d", (s32)rect[i].z );
461 GXSetCoPlanar( GX_FALSE );
462
463 // Reset ZMode
464 GXSetZMode( z->compare_enable, z->func, z->update_enable );
465 }
466
467 return;
468 }
469
470 /*---------------------------------------------------------------------------*
471 Name: PrintIntro
472
473 Description: Prints the directions on how to use this demo.
474
475 Arguments: none
476
477 Returns: none
478 *---------------------------------------------------------------------------*/
PrintIntro(void)479 static void PrintIntro( void )
480 {
481 OSReport("\n\n");
482 OSReport("************************************************\n");
483 OSReport("pix-z-comp: test z compare modes\n");
484 OSReport("************************************************\n");
485 OSReport("to quit hit the menu button\n");
486 OSReport("\n");
487 OSReport(" Stick X/Y : move the cursor, select options\n");
488 OSReport(" A button : zoom mode control\n");
489 OSReport("X/Y button : change z scale\n");
490 OSReport("************************************************\n\n");
491 }
492
493
494 /*======== End of pix-z-comp.c ========*/
495