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