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