1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     pix-sub.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 /*---------------------------------------------------------------------------*
14    pix-sub
15      Shadow volume algorithm by pixel subtract mode
16  *---------------------------------------------------------------------------*/
17 
18 
19 /*---------------------------------------------------------------------------*
20    Header files
21  *---------------------------------------------------------------------------*/
22 #include <demo.h>
23 #include <math.h>
24 
25 /*---------------------------------------------------------------------------*
26    Macro definitions
27  *---------------------------------------------------------------------------*/
28 
29 #define PI              3.14159265358979323846F
30 #define MAX_Z           0x00ffffff // max value of Z buffer
31 
32 #define NUM_GRIDS       2
33 #define NUM_BALLS       8
34 #define BALL_RD         150.0F
35 #define BALL_ORBIT      450.0F
36 
37 #define SCREEN_WD       640
38 #define SCREEN_HT       480
39 
40 #define Clamp(val,min,max) \
41     ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
42 
43 /*---------------------------------------------------------------------------*
44   Structure definitions
45  *---------------------------------------------------------------------------*/
46 // for camera
47 typedef struct
48 {
49     Vec    location;
50     Vec    up;
51     Vec    target;
52     f32    left;
53     f32    top;
54     f32    znear;
55     f32    zfar;
56 } CameraConfig;
57 
58 typedef struct
59 {
60     CameraConfig  cfg;
61     Mtx           view;
62     Mtx44         proj;
63     s32           theta;
64     s32           phi;
65     f32           distance;
66 } MyCameraObj;
67 
68 // for light
69 typedef struct
70 {
71     GXLightObj    lobj;
72     MyCameraObj   cam;
73 } MyLightObj;
74 
75 // for entire scene control
76 typedef struct
77 {
78     MyCameraObj   cam;
79     MyLightObj    light;
80     GXTexObj      shadowTex;
81     u8*           shadowTexData;
82     s32           modelRotZ;
83     s32           modelRotY;
84     Vec           ballPos[NUM_BALLS];
85     u32           anim;
86 } MySceneCtrlObj;
87 
88 /*---------------------------------------------------------------------------*
89    Forward references
90  *---------------------------------------------------------------------------*/
91 void        main            ( void );
92 static void DrawInit        ( MySceneCtrlObj* sc );
93 static void DrawShutDown    ( MySceneCtrlObj* sc );
94 static void DrawTick        ( MySceneCtrlObj* sc );
95 static void AnimTick        ( MySceneCtrlObj* sc );
96 static void DrawBalls       ( MySceneCtrlObj* sc );
97 static void DrawShadowVol   ( MySceneCtrlObj* sc );
98 static void DrawFloor       ( void );
99 static void DrawScrSizeQuad ( void );
100 static void SetCamera       ( MyCameraObj* cam );
101 static void SetLight        ( MyLightObj* light, Mtx v );
102 static void DisableLight    ( void );
103 static void PrintIntro      ( void );
104 
105 /*---------------------------------------------------------------------------*
106    Lighting parameters
107  *---------------------------------------------------------------------------*/
108 #define COL_WHITE   MyColors[0]
109 #define COL_BG      MyColors[1]
110 #define COL_AMBIENT MyColors[2]
111 #define COL_LIGHT   MyColors[3]
112 #define COL_SHADOW  MyColors[4]
113 #define COL_BALLS   MyColors[5]
114 #define COL_FLOOR   MyColors[6]
115 
116 static GXColor MyColors[] ATTRIBUTE_ALIGN(32) =
117 {
118     {0xff, 0xff, 0xff, 0xff},  // white
119     {0x20, 0x20, 0x20, 0x00},  // background
120     {0x40, 0x40, 0x40, 0xff},  // ambient
121     {0xc0, 0xc0, 0xc0, 0xff},  // light color
122     {0xa0, 0xa0, 0xa0, 0xff},  // shadow strength
123     {0x80, 0xff, 0x60, 0xff},  // balls
124     {0xf0, 0xf0, 0xf0, 0xff}   // floor
125 };
126 
127 // fixed normal vector
128 static f32 FixedNormal[] ATTRIBUTE_ALIGN(32) =
129 {
130     1.0F, 0.0F, 0.0F,  // X
131     0.0F, 1.0F, 0.0F,  // Y
132     0.0F, 0.0F, 1.0F   // Z
133 };
134 
135 /*---------------------------------------------------------------------------*
136    Camera configuration
137  *---------------------------------------------------------------------------*/
138 static CameraConfig DefaultCamera =
139 {
140     { 1500.0F, 1500.0F, 400.0F }, // location
141     { 0.0F, 0.0F, 1.0F }, // up
142     { 0.0F, 0.0F, 0.0F }, // target
143     -160.0F,  // left
144     120.0F,   // top
145     300.0F,   // near
146     5000.0F   // far
147 };
148 
149 static CameraConfig DefaultLightCamera =
150 {
151     { 1500.0F, 1500.0F, 2000.0F }, // location
152     { 0.0F, 0.0F, 1.0F }, // up
153     { 0.0F, 0.0F, 400.0F }, // target
154     -32.0F,   // left
155      32.0F,   // top
156     150.0F,   // near
157     10000.0F   // far
158 };
159 
160 /*---------------------------------------------------------------------------*
161    Global Variables
162  *---------------------------------------------------------------------------*/
163 static MySceneCtrlObj   SceneCtrl;    // scene control parameters
164 static Vec              DefaultBallPos[NUM_BALLS];
165 static TPLPalettePtr    MyTplObj = NULL;
166 static GXTexObj         MyFloorTexObj;
167 
168 /*---------------------------------------------------------------------------*
169    Application main loop
170  *---------------------------------------------------------------------------*/
main(void)171 void main ( void )
172 {
173     DEMOInit(&GXNtsc480IntDf);     // Init the OS, game pad, graphics and video.
174 
175     DrawInit(&SceneCtrl); // Initialize vertex formats and scene parameters etc.
176 
177     PrintIntro();  // Print demo directions
178 
179     while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
180     {
181         DEMOBeforeRender();
182         DrawTick(&SceneCtrl);    // Draw the model.
183         DEMODoneRender();
184         DEMOPadRead();
185         AnimTick(&SceneCtrl);    // Update animation.
186     }
187 
188     DrawShutDown(&SceneCtrl);
189     OSHalt("End of demo");
190 }
191 
192 /*---------------------------------------------------------------------------*
193    Functions
194  *---------------------------------------------------------------------------*/
195 /*---------------------------------------------------------------------------*
196     Name:           DrawInit
197 
198     Description:    Initializes the vertex attribute format, texture and
199                     default scene parameters.
200 
201     Arguments:      sc : pointer to the structure of scene control parameters
202 
203     Returns:        none
204  *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)205 static void DrawInit( MySceneCtrlObj* sc )
206 {
207     u32    size, i, deg;
208 
209     // set up a vertex attribute
210     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S8, 0);
211     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
212     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S8, 4);
213     GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
214     GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_S8, 4);
215 
216     // Set pixel format with alpha
217     GXSetPixelFmt(GX_PF_RGBA6_Z24, GX_ZC_LINEAR);
218     GXSetCopyClear(COL_BG, MAX_Z);
219     GXSetCullMode(GX_CULL_NONE);
220 
221     // Need to clear background by specified color
222     // since pixelfmt is different than DEMOInit default.
223     // The clear operation can be done by dummy copy.
224     GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
225 
226     // Texture object for the floor
227     TPLGetPalette(&MyTplObj, "gxTextrs.tpl");
228     TPLGetGXTexObjFromPalette(MyTplObj, &MyFloorTexObj, 6);
229 
230     // Default scene parameter settings
231 
232     // camera
233     sc->cam.cfg      = DefaultCamera;
234     sc->cam.theta    = 45;
235     sc->cam.phi      = 25;
236     sc->cam.distance = 2500.0F;
237 
238     // light projection camera
239     sc->light.cam.cfg      = DefaultLightCamera;
240     sc->light.cam.theta    = 0;
241     sc->light.cam.phi      = 85;
242     sc->light.cam.distance = 8000.0F;
243 
244     // model control parameters
245     sc->modelRotZ = 0;
246     sc->modelRotY = 0;
247     sc->anim     = 1;
248 
249     for ( i = 0 ; i < NUM_BALLS ; ++i )
250     {
251         deg = 360 * i / NUM_BALLS;
252 
253         DefaultBallPos[i].x = cosf(MTXDegToRad(deg)) * BALL_ORBIT;
254         DefaultBallPos[i].y = sinf(MTXDegToRad(deg)) * BALL_ORBIT;
255         DefaultBallPos[i].z = 0.0F;
256     }
257 
258 
259     // Texture object for shadow
260     size = GXGetTexBufferSize(SCREEN_WD, SCREEN_HT, GX_TF_I8, GX_FALSE, 0);
261     sc->shadowTexData = MEMAllocFromAllocator(&DemoAllocator1, size);
262 
263     GXInitTexObj(
264         &sc->shadowTex,
265         sc->shadowTexData,
266         SCREEN_WD,
267         SCREEN_HT,
268         GX_TF_I8,
269         GX_CLAMP,
270         GX_CLAMP,
271         GX_FALSE );
272     GXInitTexObjLOD(
273         &sc->shadowTex,
274         GX_NEAR,
275         GX_NEAR,
276         0.0F,
277         0.0F,
278         0.0F,
279         GX_FALSE,
280         GX_FALSE,
281         GX_ANISO_1 );
282 
283 }
284 
285 // Function for shutdown
DrawShutDown(MySceneCtrlObj * sc)286 static void DrawShutDown( MySceneCtrlObj* sc )
287 {
288     if ( sc->shadowTexData )
289     {
290         MEMFreeToAllocator(&DemoAllocator1, sc->shadowTexData);
291         sc->shadowTexData = NULL;
292     }
293 }
294 
295 /*---------------------------------------------------------------------------*
296     Name:           DrawTick
297 
298     Description:    Draw the model by using given scene parameters
299 
300     Arguments:      sc : pointer to the structure of scene control parameters
301 
302     Returns:        none
303  *---------------------------------------------------------------------------*/
304 // Set Color/Alpha/Z update control
SetCAZUpdate(GXBool cu,GXBool au,GXBool zc,GXBool zu)305 inline void SetCAZUpdate( GXBool cu, GXBool au, GXBool zc, GXBool zu )
306 {
307     GXSetColorUpdate(cu);
308     GXSetAlphaUpdate(au);
309     GXSetZMode(zc, GX_LEQUAL, zu);
310 }
311 
312 /*---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)313 static void DrawTick( MySceneCtrlObj* sc )
314 {
315     Mtx  ms, mt, mv, mvi;
316     f32  tr;
317 
318     GXInvalidateTexAll();
319     GXSetViewport(0, 0, SCREEN_WD, SCREEN_HT, 0.0F, 1.0F);
320 
321     //-------------------------------------------
322     //    Background
323     //-------------------------------------------
324 
325     // culling/blending off
326     GXSetCullMode(GX_CULL_BACK);
327     GXSetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_NOOP);
328     // Color update ON, Alpha update OFF, Z update ON
329     SetCAZUpdate(GX_ENABLE, GX_DISABLE, GX_ENABLE, GX_ENABLE);
330 
331     // Set camera for the main image
332     SetCamera(&sc->cam);
333 
334 
335     // Background floor
336     GXSetNumTevStages(1);
337     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
338     GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE);
339     GXSetNumTexGens(1);
340     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
341     SetLight(&sc->light, sc->cam.view);
342 
343     // Textures for floor panels
344     GXLoadTexObj(&MyFloorTexObj, GX_TEXMAP0);
345     GXSetChanMatColor(GX_COLOR0A0, COL_FLOOR);
346 
347     // Modelview matrix for floor panels
348     tr = -(f32)NUM_GRIDS / 2.0F;
349     MTXScale(ms, 800.0F, 800.0F, 100.0F);
350     MTXTrans(mt, tr, tr, -3.5F);
351     MTXConcat(ms, mt, ms);
352     MTXConcat(sc->cam.view, ms, mv);
353     GXLoadPosMtxImm(mv, GX_PNMTX0);
354     MTXInvXpose(mv, mvi);
355     GXLoadNrmMtxImm(mvi, GX_PNMTX0);
356 
357     // Draw floor panels
358     DrawFloor();
359 
360 
361     //-------------------------------------------
362     //    Shadow volume #1 (front faces)
363     //-------------------------------------------
364 
365     // Back-face culling, additive blend mode
366     GXSetCullMode(GX_CULL_BACK);
367     GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_NOOP);
368     // Color update OFF, Alpha update ON, Z compare only
369     SetCAZUpdate(GX_DISABLE, GX_ENABLE, GX_ENABLE, GX_DISABLE);
370 
371     // Set tev to use only one vertex color
372     GXSetNumChans(1);
373     GXSetNumTevStages(1);
374     GXSetNumTexGens(0);
375     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
376     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
377     DisableLight();
378 
379     // shadow volume value (minimum unit for 6bit alpha plane)
380     GXSetChanMatColor(GX_COLOR0A0, (GXColor){ 0x04, 0x04, 0x04, 0x04 });
381 
382     DrawShadowVol(sc);
383 
384     //-------------------------------------------
385     //    Shadow volume #2 (back faces)
386     //-------------------------------------------
387 
388     // Front-face culling, subtractive blend mode
389     GXSetCullMode(GX_CULL_FRONT);
390     GXSetBlendMode(GX_BM_SUBTRACT, GX_BL_ONE, GX_BL_ONE, GX_LO_NOOP);
391     // Color update OFF, Alpha update ON, Z compare only
392     SetCAZUpdate(GX_DISABLE, GX_ENABLE, GX_ENABLE, GX_DISABLE);
393 
394     // Set tev to use only one vertex color
395     GXSetNumChans(1);
396     GXSetNumTevStages(1);
397     GXSetNumTexGens(0);
398     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
399     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
400     DisableLight();
401 
402     // shadow volume value (minimum unit for 6bit alpha plane)
403     GXSetChanMatColor(GX_COLOR0A0, (GXColor){ 0x04, 0x04, 0x04, 0x04 });
404 
405     DrawShadowVol(sc);
406 
407     //-------------------------------------------
408     //    Copy alpha plane image into Texture
409     //-------------------------------------------
410 
411     // Copy shadow image into texture
412     GXSetTexCopySrc(0, 0, SCREEN_WD, SCREEN_HT);
413     GXSetTexCopyDst(SCREEN_WD, SCREEN_HT, GX_CTF_A8, GX_FALSE);
414 
415     // Clear alpha plane only
416     // Color update OFF, Alpha update ON, Z update OFF
417     SetCAZUpdate(GX_DISABLE, GX_ENABLE, GX_DISABLE, GX_DISABLE);
418 
419     GXCopyTex(sc->shadowTexData, GX_TRUE);
420 
421     // Wait for finishing the copy task in the graphics pipeline
422     GXPixModeSync();
423 
424     //-------------------------------------------
425     //    Draw shadows by using alpha texture
426     //-------------------------------------------
427 
428     GXSetCullMode(GX_CULL_NONE);
429     // Perform source color * destination color
430     GXSetBlendMode(GX_BM_BLEND, GX_BL_ZERO, GX_BL_SRCCLR, GX_LO_NOOP);
431     // Color update ON, Alpha update OFF, Z compare/update OFF
432     SetCAZUpdate(GX_ENABLE, GX_DISABLE, GX_DISABLE, GX_DISABLE);
433 
434     GXSetNumTevStages(1);
435     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
436     GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_COMP_RGB8_EQ, GX_TB_ZERO,
437                     GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
438     GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_TEXC, GX_CC_ZERO, GX_CC_ONE, GX_CC_C0);
439     GXSetTevColor(GX_TEVREG0, COL_SHADOW); // shadow strength
440     GXSetNumTexGens(1);
441     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
442     DisableLight();
443 
444     GXLoadTexObj(&sc->shadowTex, GX_TEXMAP0);
445 
446     DrawScrSizeQuad();
447 
448     //-------------------------------------------
449     //    Foreground
450     //-------------------------------------------
451     // Shadows don't affect objects drawn below
452 
453     // culling/blending off
454     GXSetCullMode(GX_CULL_BACK);
455     GXSetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_NOOP);
456     // Color update ON, Alpha update OFF, Z compare/update ON
457     SetCAZUpdate(GX_ENABLE, GX_DISABLE, GX_ENABLE, GX_ENABLE);
458 
459     // Set camera for the main image
460     SetCamera(&sc->cam);
461 
462     // Balls
463     GXSetNumChans(1);
464     GXSetNumTevStages(1);
465     GXSetNumTexGens(0);
466     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
467     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
468 
469     SetLight(&sc->light, sc->cam.view);
470     GXSetChanMatColor(GX_COLOR0A0, COL_BALLS);
471 
472     DrawBalls(sc);
473 }
474 
475 /*---------------------------------------------------------------------------*
476     Name:           AnimTick
477 
478     Description:    Changes scene parameters according to the pad status.
479 
480     Arguments:      sc : pointer to the structure of scene control parameters
481 
482     Returns:        none
483  *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)484 static void AnimTick( MySceneCtrlObj* sc )
485 {
486     f32     dy;
487     Mtx     mrz, mry, mt;
488 
489     // Camera position
490     sc->cam.theta += ( DEMOPadGetStickX(0) / 24 );
491     Clamp(sc->cam.theta, 0, 90);
492     sc->cam.phi   += ( DEMOPadGetStickY(0) / 24 );
493     Clamp(sc->cam.phi, 5, 75);
494 
495     // Moves models automatically
496     if (sc->anim)
497     {
498         sc->modelRotZ += 4;
499         if ( sc->modelRotZ > 360 )
500         {
501             sc->modelRotZ -= 360;
502         }
503 
504         ++sc->modelRotY;
505         if ( sc->modelRotY > 1400 )
506         {
507             sc->modelRotY -= 1400;
508         }
509     }
510 
511     if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_A )
512     {
513         sc->anim = 1 - sc->anim;
514     }
515 
516     // Ball animation
517     dy = fabsf((f32)(sc->modelRotY - 700) / 10.0F);
518     MTXRotDeg(mrz, 'Z', sc->modelRotZ);
519     MTXRotDeg(mry, 'Y', dy);
520     MTXConcat(mrz, mry, mt);
521     MTXTransApply(mt, mt, 0.0F, 0.0F, 450.0F);
522     MTXMultVecArray(mt, &DefaultBallPos[0], &sc->ballPos[0], NUM_BALLS);
523 }
524 
525 /*---------------------------------------------------------------------------*
526     Name:           DrawBalls
527 
528     Description:    Draws ball objects
529 
530     Arguments:      sc : pointer to the structure of scene control parameters
531 
532     Returns:        none
533  *---------------------------------------------------------------------------*/
DrawBalls(MySceneCtrlObj * sc)534 static void DrawBalls( MySceneCtrlObj* sc )
535 {
536     u32     i;
537     Mtx     ms, mt, mv, mvi;
538 
539     GXClearVtxDesc();
540     GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
541     GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
542 
543     MTXScale(ms, BALL_RD, BALL_RD, BALL_RD);
544 
545     for ( i = 0 ; i < NUM_BALLS ; ++i )
546     {
547         MTXTransApply(ms, mt, sc->ballPos[i].x, sc->ballPos[i].y, sc->ballPos[i].z);
548         MTXConcat(sc->cam.view, mt, mv);
549         GXLoadPosMtxImm(mv, GX_PNMTX0);
550         MTXInvXpose(mv, mvi);
551         GXLoadNrmMtxImm(mvi, GX_PNMTX0);
552 
553         GXDrawSphere(12,16);
554     }
555 }
556 
557 /*---------------------------------------------------------------------------*
558     Name:           DrawShadowVol
559 
560     Description:    Draws objects for shadow volumes
561 
562     Arguments:      sc : pointer to the structure of scene control parameters
563 
564     Returns:        none
565  *---------------------------------------------------------------------------*/
DrawShadowVol(MySceneCtrlObj * sc)566 static void DrawShadowVol( MySceneCtrlObj* sc )
567 {
568     u32     i;
569     Mtx     ms, mt, mv;
570     f32     zscale, zcenter;
571 
572     GXClearVtxDesc();
573     GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
574     GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
575 
576     for ( i = 0 ; i < NUM_BALLS ; ++i )
577     {
578         zscale  = (sc->ballPos[i].z + 400.0F) / 2.0F;
579         zcenter = (sc->ballPos[i].z - 400.0F) / 2.0F;
580 
581         MTXScale(ms, BALL_RD, BALL_RD, zscale);
582         MTXTransApply(ms, mt, sc->ballPos[i].x, sc->ballPos[i].y, zcenter);
583         MTXConcat(sc->cam.view, mt, mv);
584         GXLoadPosMtxImm(mv, GX_PNMTX0);
585 
586         GXDrawCylinder(16);
587     }
588 }
589 
590 /*---------------------------------------------------------------------------*
591     Name:           DrawFloor
592 
593     Description:    Draws the floor which contains some steps
594 
595     Arguments:      none
596 
597     Returns:        none
598  *---------------------------------------------------------------------------*/
DrawFloor(void)599 static void DrawFloor( void )
600 {
601     s8    x, y, z;
602 
603     // set up vertex descriptors
604     GXClearVtxDesc();
605     GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
606     GXSetVtxDesc(GX_VA_NRM, GX_INDEX8);
607     GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
608 
609     // normal array
610     GXSetArray(GX_VA_NRM, FixedNormal, 3 * sizeof(f32));
611 
612     z = 0;
613     for ( y = 0 ; y < NUM_GRIDS ; ++y )
614     {
615         GXBegin(GX_QUADS, GX_VTXFMT0, NUM_GRIDS * 12);
616             for ( x = 0 ; x < NUM_GRIDS ; ++x )
617             {
618                 z = (s8)(NUM_GRIDS - x - y);
619 
620                 // Z side
621                 GXPosition3s8(x, y, z);
622                 GXNormal1x8(2);
623                 GXTexCoord2s8(0, 0);
624                 GXPosition3s8(x, (s8)(y+1), z);
625                 GXNormal1x8(2);
626                 GXTexCoord2s8(0, 0x10);
627                 GXPosition3s8((s8)(x+1), (s8)(y+1), z);
628                 GXNormal1x8(2);
629                 GXTexCoord2s8(0x10, 0x10);
630                 GXPosition3s8((s8)(x+1), y, z);
631                 GXNormal1x8(2);
632                 GXTexCoord2s8(0x10, 0);
633 
634                 // X side
635                 GXPosition3s8((s8)(x+1), y, z);
636                 GXNormal1x8(0);
637                 GXTexCoord2s8(0, 0);
638                 GXPosition3s8((s8)(x+1), (s8)(y+1), z);
639                 GXNormal1x8(0);
640                 GXTexCoord2s8(0x10, 0);
641                 GXPosition3s8((s8)(x+1), (s8)(y+1), (s8)(z-1));
642                 GXNormal1x8(0);
643                 GXTexCoord2s8(0x10, 0x8);
644                 GXPosition3s8((s8)(x+1), y, (s8)(z-1));
645                 GXNormal1x8(0);
646                 GXTexCoord2s8(0, 0x8);
647 
648                 // Y side
649                 GXPosition3s8((s8)(x+1), (s8)(y+1), z);
650                 GXNormal1x8(1);
651                 GXTexCoord2s8(0, 0);
652                 GXPosition3s8(x, (s8)(y+1), z);
653                 GXNormal1x8(1);
654                 GXTexCoord2s8(0x10, 0);
655                 GXPosition3s8(x, (s8)(y+1), (s8)(z-1));
656                 GXNormal1x8(1);
657                 GXTexCoord2s8(0x10, 0x8);
658                 GXPosition3s8((s8)(x+1), (s8)(y+1), (s8)(z-1));
659                 GXNormal1x8(1);
660                 GXTexCoord2s8(0, 0x8);
661             }
662         GXEnd();
663     }
664 }
665 
666 /*---------------------------------------------------------------------------*
667     Name:           DrawScrSizeQuad
668 
669     Description:    Draws a full-screen size quad
670 
671     Arguments:      none
672 
673     Returns:        none
674  *---------------------------------------------------------------------------*/
DrawScrSizeQuad(void)675 static void DrawScrSizeQuad( void )
676 {
677     Mtx44   proj;
678     Mtx     mv;
679 
680     MTXOrtho(proj, 0, 480, 0, 640, 0.0F, 10000.0F);
681     GXSetProjection(proj, GX_ORTHOGRAPHIC);
682 
683     MTXIdentity(mv);
684     GXLoadPosMtxImm(mv, GX_PNMTX0);
685 
686     // set up vertex descriptors
687     GXClearVtxDesc();
688     GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
689     GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
690 
691     GXBegin(GX_QUADS, GX_VTXFMT1, 4);
692         GXPosition3s16(  0,   0, 0);
693         GXTexCoord2s8(0x00, 0x00);
694         GXPosition3s16(640,   0, 0);
695         GXTexCoord2s8(0x10, 0x00);
696         GXPosition3s16(640, 480, 0);
697         GXTexCoord2s8(0x10, 0x10);
698         GXPosition3s16(  0, 480, 0);
699         GXTexCoord2s8(0x00, 0x10);
700     GXEnd();
701 }
702 
703 /*---------------------------------------------------------------------------*
704     Name:           SetCamera
705 
706     Description:    set view matrix and load projection matrix into hardware
707 
708     Arguments:      cam : pointer to the MyCameraObj structure
709 
710     Returns:        none
711  *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)712 static void SetCamera( MyCameraObj* cam )
713 {
714     f32  r_theta, r_phi;
715 
716     r_theta = (f32)cam->theta * PI / 180.0F;
717     r_phi   = (f32)cam->phi   * PI / 180.0F;
718 
719     cam->cfg.location.x =
720         cam->distance * cosf(r_theta) * cosf(r_phi);
721     cam->cfg.location.y =
722         cam->distance * sinf(r_theta) * cosf(r_phi);
723     cam->cfg.location.z =
724         cam->distance * sinf(r_phi);
725 
726     MTXLookAt(
727         cam->view,
728         &cam->cfg.location,
729         &cam->cfg.up,
730         &cam->cfg.target );
731 
732     MTXFrustum(
733         cam->proj,
734         cam->cfg.top,
735         - (cam->cfg.top),
736         cam->cfg.left,
737         - (cam->cfg.left),
738         cam->cfg.znear,
739         cam->cfg.zfar );
740     GXSetProjection(cam->proj, GX_PERSPECTIVE);
741 }
742 
743 /*---------------------------------------------------------------------------*
744     Name:           SetLight
745 
746     Description:    Set up lights and lighting channel parameters
747 
748     Arguments:      light : pointer to a MyLightObj structure
749                     v     : view matrix
750 
751     Returns:        none
752  *---------------------------------------------------------------------------*/
SetLight(MyLightObj * light,Mtx v)753 void SetLight( MyLightObj* light, Mtx v )
754 {
755     Vec lpos = light->cam.cfg.location;
756 
757     // Multiplied by view matrix
758     MTXMultVec(v, &lpos, &lpos);
759 
760     GXInitLightPos(&light->lobj, lpos.x, lpos.y, lpos.z);
761     GXInitLightColor(&light->lobj, COL_LIGHT);
762     GXLoadLightObjImm(&light->lobj, GX_LIGHT0);
763 
764     GXSetChanCtrl(
765         GX_COLOR0A0,
766         GX_ENABLE,   // enable channel
767         GX_SRC_REG,  // amb source
768         GX_SRC_REG,  // mat source
769         GX_LIGHT0,   // light mask
770         GX_DF_CLAMP, // diffuse function
771         GX_AF_NONE );
772     // set up material color
773     GXSetChanAmbColor(GX_COLOR0A0, COL_AMBIENT);
774 }
775 
776 /*---------------------------------------------------------------------------*
777     Name:           DisableLight
778 
779     Description:    Disables lighting
780 
781     Arguments:      none
782 
783     Returns:        none
784  *---------------------------------------------------------------------------*/
DisableLight(void)785 void DisableLight( void )
786 {
787     GXSetChanCtrl(
788         GX_COLOR0A0,
789         GX_DISABLE,  // disable channel
790         GX_SRC_REG,  // amb source
791         GX_SRC_REG,  // mat source
792         GX_LIGHT0,   // light mask
793         GX_DF_NONE,  // diffuse function
794         GX_AF_NONE);
795 }
796 
797 /*---------------------------------------------------------------------------*
798     Name:           PrintIntro
799 
800     Description:    Prints the directions on how to use this demo.
801 
802     Arguments:      none
803 
804     Returns:        none
805  *---------------------------------------------------------------------------*/
PrintIntro(void)806 static void PrintIntro( void )
807 {
808     OSReport("\n\n");
809     OSReport("******************************************************\n");
810     OSReport("pix-sub: shadow volume demo by pixel subtract mode\n");
811     OSReport("******************************************************\n");
812     OSReport("to quit hit the start button\n");
813     OSReport("\n");
814     OSReport("Main stick : Move the camera\n");
815     OSReport("A Button   : Stop/Start animation\n");
816     OSReport("******************************************************\n");
817     OSReport("\n\n");
818 }
819 
820 /*============================================================================*/
821