1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tev-outline.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 tev-outline
15 Cartoon outline effects by using alpha plane copy and TEV features
16 *---------------------------------------------------------------------------*
17
18 Overview of this method:
19
20 (1st. pass) Render the entire scene as usual. At this time,
21 paint each object part by its individual ID number which is
22 drawn into alpha plane. It doesn't affect the result image
23 in color buffer.
24
25 Then copy the entire alpha plane into a texture (ID map).
26 The framebuffer is not cleared by this operation.
27
28 (2nd. pass) Render a screen-sized quad with ID map. Then,
29 generate two texcoords to lookup this map. One exactly
30 matches screen-space coordinate, and another is perturbed
31 by just one pixel width horizontally (or vertically).
32 Then compare texel values from these two texcoords each
33 other. The comparison can be done by some TEV stages and
34 alpha compare feature. If two ID values are not similar,
35 it means the part is a border of two different objects,
36 hence should be outlined.
37
38 Since this demo sets the tolerance value of comparison
39 as more than 1, no outline will be generated between two
40 adjacent ID numbers. It will help outlining self-intersection
41 of soft objects.
42
43 This demo draws horizontal/vertical outlines separately.
44
45 *---------------------------------------------------------------------------*/
46
47 /*---------------------------------------------------------------------------*
48 Header files
49 *---------------------------------------------------------------------------*/
50 #include <demo.h>
51 #include <math.h>
52
53 /*---------------------------------------------------------------------------*
54 Macro definitions
55 *---------------------------------------------------------------------------*/
56 #define SCREEN_WD_MAX 640
57 #define SCREEN_HT_MAX 480
58
59 #define VP_ASPECT ((float)SCREEN_WD_MAX/(float)SCREEN_HT_MAX)
60 #define VP_FOVY 33.3f
61 #define VP_NEAR 16.0f // near plane Z in view coordinates
62 #define VP_FAR 1024.0f // far plane Z in view coordinates
63
64 #define SCREEN_ZNEAR 0.0f // near plane Z in screen coordinates
65 #define SCREEN_ZFAR 1.0f // far plane Z in screen coordinates
66 #define ZBUFFER_MAX 0x00ffffff
67
68 #define ASFT(x) ((x)<<2) // ID step size ( 6bit alpha )
69
70
71 #define Clamp(val,min,max) \
72 ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
73
74 /*---------------------------------------------------------------------------*
75 Forward references
76 *---------------------------------------------------------------------------*/
77 void DrawInit ( void );
78 void DrawScene( void );
79 void myCreateModel( void );
80 void myDrawModel( void );
81 void myAnimeModel( void );
82 void PrintIntro( void );
83
84 void DrawCartoonOutline( void );
85
86
87 /*---------------------------------------------------------------------------*
88 Global Variables
89 *---------------------------------------------------------------------------*/
90 u16 screen_wd;
91 u16 screen_ht;
92
93 /*---------------------------------------------------------------------------*
94 Rendering parameters
95 *---------------------------------------------------------------------------*/
96 typedef struct
97 {
98 Point3d position;
99 Point3d target;
100 Vec up;
101 f32 fovy;
102 f32 znear;
103 f32 zfar;
104 Mtx viewMtx;
105 } Camera;
106
107 Camera myCamera =
108 {
109 { 0.0f, -400.0f, 0.0f }, // position
110 { 0.0f, 0.0f, 0.0f }, // target
111 { 0.0f, 0.0f, 1.0f }, // upVec
112 33.3f, // fovy
113 128.0f, // near plane Z in camera coordinates
114 2048.0f, // far plane Z in camera coordinates
115 };
116
117 /*---------------------------------------------------------------------------*
118 Application main loop
119 *---------------------------------------------------------------------------*/
main(void)120 void main ( void )
121 {
122 GXRenderModeObj *rmp;
123
124 // initialize render settings and set clear color for first frame
125 DEMOInit( NULL ); // Defined in $(REVOLUTION_SDK_ROOT)/build/libraries/demo/src/DEMOInit.c
126
127 rmp = DEMOGetRenderModeObj();
128 screen_wd = rmp->fbWidth;
129 screen_ht = rmp->efbHeight;
130
131 PrintIntro( ); // Print demo directions
132
133 DrawInit( );
134
135 while ( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) )
136 {
137 // get pad status
138 DEMOPadRead( );
139
140 // General control & model animation
141 myAnimeModel( );
142
143 // Draw scene
144 DEMOBeforeRender( );
145
146 DrawScene( );
147 DrawCartoonOutline( );
148 DEMODoneRender( );
149 }
150
151 OSHalt("End of demo");
152 }
153
154 //---------------------------------------------------------------------------
155 // Cartoon outline settings
156 //---------------------------------------------------------------------------
157
158 /*---------------------------------------------------------------------------*/
159
160 /*---------------------------------------------------------------------------*
161 Draw Cartoon outline for real HW
162 *---------------------------------------------------------------------------*/
DrawCartoonOutline(void)163 void DrawCartoonOutline( void )
164 {
165 static u16 *alphaBuffer;
166 static GXTexObj eFBTexObj;
167 static Mtx texMtx1, texMtx2;
168 static Mtx mtxUnit;
169 static Mtx44 mtxProj;
170 static s32 initialized = 0;
171 f32 zMid;
172
173 if ( !initialized )
174 {
175 alphaBuffer = MEMAllocFromAllocator(&DemoAllocator1, screen_wd*screen_ht*sizeof(u16));
176 ASSERT( alphaBuffer != NULL );
177
178 MTXIdentity(mtxUnit);
179 MTXOrtho(mtxProj, 0.0f, (f32) screen_ht, 0.0f, (f32) screen_wd, SCREEN_ZNEAR, SCREEN_ZFAR);
180
181 // set up texture offset matrices
182 MTXIdentity(texMtx1);
183 MTXRowCol(texMtx1, 0, 3) = 1.0f / (f32)screen_wd;
184 MTXIdentity(texMtx2);
185 MTXRowCol(texMtx2, 1, 3) = 1.0f / (f32)screen_ht;
186
187 GXInitTexObj( &eFBTexObj, alphaBuffer, screen_wd, screen_ht,
188 GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_DISABLE );
189 GXInitTexObjLOD( &eFBTexObj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f,
190 GX_DISABLE, GX_DISABLE, GX_ANISO_1 );
191 initialized = 1;
192 }
193
194 // Copy out eFB alpha plane as I8 texture format
195 GXSetTexCopySrc( 0, 0, screen_wd, screen_ht );
196 GXSetTexCopyDst(screen_wd, screen_ht, GX_TF_A8, GX_DISABLE );
197 GXCopyTex( alphaBuffer, GX_DISABLE );
198
199 // Be sure texture is completely copied out
200 GXPixModeSync();
201
202 // flush texture cache
203 GXInvalidateTexAll();
204
205 // Load the bitmap into TMEM
206 GXLoadTexObj( &eFBTexObj, GX_TEXMAP0 );
207
208 // Setup for outline drawing
209 GXSetNumTexGens ( 2 );
210 GXSetNumChans ( 0 );
211 GXSetNumTevStages( 2 );
212
213 // first TEV stage just gets texture lookup value
214 GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL );
215 GXSetTevOp( GX_TEVSTAGE0, GX_REPLACE );
216
217 // second stage does the subtract (in alpha; colors gets zero)
218 // clamping turned off (in alpha) to allow wrapped "negative" values
219 GXSetTevOrder( GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP0, GX_COLOR_NULL );
220 GXSetTevColorIn( GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_ZERO,
221 GX_CC_ZERO, GX_CC_ZERO );
222 GXSetTevColorOp( GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1,
223 GX_ENABLE, GX_TEVPREV );
224 GXSetTevAlphaIn( GX_TEVSTAGE1, GX_CA_TEXA, GX_CA_ZERO,
225 GX_CA_ZERO, GX_CA_APREV );
226 GXSetTevAlphaOp( GX_TEVSTAGE1, GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_1,
227 GX_DISABLE, GX_TEVPREV );
228
229 // only write pixels that pass alpha test
230 GXSetAlphaCompare( GX_GREATER, ASFT(1), GX_AOP_AND, GX_LESS, 256-ASFT(1) );
231
232 // always draw regardless of Z
233 GXSetZMode( GX_TRUE, GX_ALWAYS, GX_TRUE );
234
235 // load matrices
236 GXSetCurrentMtx(GX_PNMTX0);
237 GXLoadPosMtxImm(mtxUnit, GX_PNMTX0);
238 GXSetProjection(mtxProj, GX_ORTHOGRAPHIC);
239
240 GXLoadTexMtxImm(mtxUnit, GX_TEXMTX0, GX_MTX2x4);
241 GXLoadTexMtxImm(texMtx1, GX_TEXMTX1, GX_MTX2x4);
242 GXLoadTexMtxImm(texMtx2, GX_TEXMTX2, GX_MTX2x4);
243
244 // vertex descriptor settings
245 GXClearVtxDesc( );
246 GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
247 GXSetVtxDesc( GX_VA_TEX0, GX_DIRECT );
248 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0 );
249 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0 );
250
251 zMid = -0.5f * (SCREEN_ZNEAR + SCREEN_ZFAR);
252
253 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0);
254 GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX1);
255
256 // draw with texture offset in S
257 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
258 GXPosition3f32(0.0F, 0.0F, zMid);
259 GXTexCoord2f32(0.0F, 0.0F);
260 GXPosition3f32((f32) screen_wd, 0.0F, zMid);
261 GXTexCoord2f32(1.0F, 0.0F);
262 GXPosition3f32((f32) screen_wd, (f32) screen_ht, zMid);
263 GXTexCoord2f32(1.0F, 1.0F);
264 GXPosition3f32(0.0F, (f32) screen_ht, zMid);
265 GXTexCoord2f32(0.0F, 1.0F);
266 GXEnd();
267
268 GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX2);
269
270 // draw with texture offset in T
271 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
272 GXPosition3f32(0.0F, 0.0F, zMid);
273 GXTexCoord2f32(0.0F, 0.0F);
274 GXPosition3f32((f32) screen_wd, 0.0F, zMid);
275 GXTexCoord2f32(1.0F, 0.0F);
276 GXPosition3f32((f32) screen_wd, (f32) screen_ht, zMid);
277 GXTexCoord2f32(1.0F, 1.0F);
278 GXPosition3f32(0.0F, (f32) screen_ht, zMid);
279 GXTexCoord2f32(0.0F, 1.0F);
280 GXEnd();
281
282 return;
283 }
284
285 //---------------------------------------------------------------------------
286 // Model settings
287 //---------------------------------------------------------------------------
288 #define MYDLBUFSIZE 1024
289
290 #define VTXINRING 12
291 #define NUMRINGS 6
292
293 #define PIPELID0_NRM 12
294 #define PIPELID1_NRM 13
295 #define PIPELID0_CLR (NUMRINGS-1)
296 #define PIPELID1_CLR (NUMRINGS)
297
298 typedef struct {
299 s8 x, y;
300 s8 nx, ny, nz, pad;
301 } MyVertex;
302
303 static MyVertex ringVtx[] ATTRIBUTE_ALIGN(32) =
304 {
305 // x, y, nx, ny, nz, pad
306 { 100, 0, 64, 0, 0, 0 }, /* 0 */
307 { 87, 50, 55, 32, 0, 0 }, /* 30 */
308 { 50, 87, 32, 55, 0, 0 }, /* 60 */
309 { 0, 100, 0, 60, 0, 0 }, /* 90 */
310 { -50, 87, -32, 55, 0, 0 }, /* 120 */
311 { -87, 50, -55, 32, 0, 0 }, /* 150 */
312 {-100, 0, -64, 0, 0, 0 }, /* 180 */
313 { -87, -50, -55, -32, 0, 0 }, /* 210 */
314 { -50, -87, -32, -55, 0, 0 }, /* 240 */
315 { 0,-100, 0, -64, 0, 0 }, /* 270 */
316 { 50, -87, 32, -55, 0, 0 }, /* 300 */
317 { 87, -50, 55, -32, 0, 0 }, /* 330 */
318
319 { 0, 0, 0, 0, -60, 0 }, /* center of lid */
320 { 0, 0, 0, 0, 60, 0 }, /* center of lid */
321 };
322
323 static GXColor pipeClr[] ATTRIBUTE_ALIGN(32) =
324 {
325 // R, G, B, A(ID)
326 { 64, 128, 255, ASFT(4) }, // for pipe
327 { 64, 128, 255, ASFT(5) },
328 { 64, 128, 255, ASFT(5) },
329 { 64, 128, 255, ASFT(5) },
330 { 64, 128, 255, ASFT(6) },
331 { 64, 128, 255, ASFT(2) }, // for lid0
332 { 64, 128, 255, ASFT(8) }, // for lid1
333 };
334
335 struct {
336 f32 rot;
337 f32 length;
338 }
339 pipe[NUMRINGS-1] =
340 {
341 { 0.0f, 400.0f },
342 { 20.0f, 50.0f },
343 { 20.0f, 50.0f },
344 { 20.0f, 50.0f },
345 { 0.0f, 400.0f },
346 };
347
348 Mtx pipeLocalMtx =
349 { { 0.0646906f, 0.0760343f, 0.0058220f, 0.0f },
350 {-0.0740718f, 0.0608390f, 0.0284950f, 0.0f },
351 { 0.0181239f,-0.0227461f, 0.0956772f, 0.0f } };
352
353 Mtx pipeMtx[NUMRINGS] ATTRIBUTE_ALIGN(32);
354
355 // display list
356 u8* myDisplayList = NULL;
357 u32 myDLSize;
358 GXVtxDescList myDLVcd[GX_MAX_VTXDESCLIST_SZ];
359
360 //---------------------------------------------------------------------------
361 // Init scene
362 //---------------------------------------------------------------------------
DrawInit(void)363 void DrawInit( void )
364 {
365 GXColor color = {160,160,160,0};
366 // need an alpha channel
367 GXSetPixelFmt(GX_PF_RGBA6_Z24, GX_ZC_LINEAR);
368 GXSetCopyClear( color , GX_MAX_Z24 );
369 // clear framebuffer because eFB format is changed
370 GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
371
372 // We're using alpha compare, so we must compare z AFTER texturing
373 GXSetZCompLoc( GX_DISABLE );
374
375 // update both color and alpha
376 GXSetAlphaUpdate(GX_TRUE);
377 GXSetColorUpdate(GX_TRUE);
378
379 // create the model data
380 myCreateModel();
381 }
382
383 //---------------------------------------------------------------------------
384 // Draw entire scene
385 //---------------------------------------------------------------------------
DrawScene(void)386 void DrawScene( void )
387 {
388 Mtx44 projMtx;
389 Camera* c = &myCamera;
390
391 // Set projection matrix
392 MTXPerspective( projMtx, c->fovy, VP_ASPECT, c->znear, c->zfar );
393 GXSetProjection( projMtx, GX_PERSPECTIVE );
394
395 // Set Viewport
396 GXSetViewport( 0, 0, screen_wd, screen_ht, SCREEN_ZNEAR, SCREEN_ZFAR );
397 GXSetScissor ( 0, 0, screen_wd, screen_ht );
398
399 // Set rendering mode
400 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR );
401 GXSetZMode( GX_TRUE, GX_LESS, GX_TRUE );
402
403 // Set rendering mode
404 GXSetCullMode( GX_CULL_BACK );
405
406 // Draw objects
407 myDrawModel( );
408
409 return;
410 }
411
412 //---------------------------------------------------------------------------
413 // Animate model
414 //---------------------------------------------------------------------------
415 # define MOVE_SCALE 1.0f
416
myAnimeModel(void)417 void myAnimeModel( void )
418 {
419 static f32 angle = 60.0f;
420 Camera* c = &myCamera;
421 Mtx localMtx, tmpMtx;
422 Vec axis;
423 s32 i;
424 u16 stickDirs;
425
426 axis.x = axis.y = axis.z = 0.0f;
427
428 stickDirs = DEMOPadGetDirs(0);
429
430 // Model rotation
431 stickDirs = DEMOPadGetDirs(0);
432 if ( stickDirs & DEMO_STICK_UP )
433 axis.x -= 1.0f;
434 if ( stickDirs & DEMO_STICK_DOWN )
435 axis.x += 1.0f;
436 if ( stickDirs & DEMO_STICK_LEFT )
437 axis.y -= 1.0f;
438 if ( stickDirs & DEMO_STICK_RIGHT )
439 axis.y += 1.0f;
440 if ( stickDirs & DEMO_SUBSTICK_LEFT )
441 axis.z -= 1.0f;
442 if ( stickDirs & DEMO_SUBSTICK_RIGHT )
443 axis.z += 1.0f;
444
445 // Camera zoom
446 c->position.y += (f32)DEMOPadGetSubStickY(0) / 30.0f * MOVE_SCALE;
447 Clamp(c->position.y, -600.0f, -200.0f);
448
449 // Joint angle
450 if ( DEMOPadGetButton(0) & PAD_TRIGGER_L )
451 angle += MOVE_SCALE * 3.0f;
452 if ( DEMOPadGetButton(0) & PAD_TRIGGER_R )
453 angle -= MOVE_SCALE * 3.0f;
454 Clamp(angle, 0.0f, 150.0f);
455
456
457 //--------- Get View matrix
458 MTXLookAt( c->viewMtx, &c->position, &c->up, &c->target );
459
460 //--------- Make local matrix
461 MTXInverse( c->viewMtx, tmpMtx );
462 MTXMultVecSR( tmpMtx, &axis, &axis );
463 if ( axis.x != 0.0f || axis.y != 0.0f || axis.z != 0.0f )
464 {
465 MTXRotAxisDeg( tmpMtx, &axis, MOVE_SCALE );
466 MTXConcat( tmpMtx, pipeLocalMtx, pipeLocalMtx );
467 }
468
469 //--------- Set pipe bend parameter
470 for ( i = 1; i < NUMRINGS-2; i ++ )
471 {
472 pipe[i].rot = angle / ((NUMRINGS-3) * 2);
473 }
474
475 //--------- Make ModelView matrix
476 MTXConcat( c->viewMtx, pipeLocalMtx, pipeMtx[0] );
477 for ( i = 0; i < NUMRINGS-1; i ++ )
478 {
479 MTXTrans( localMtx, 0, 0, pipe[i].length );
480 MTXRotDeg( tmpMtx, 'Y', pipe[i].rot );
481 MTXConcat( tmpMtx, localMtx, localMtx );
482 MTXConcat( localMtx, tmpMtx, localMtx );
483 MTXConcat( pipeMtx[i], localMtx, pipeMtx[i+1] );
484 }
485 DCFlushRange( pipeMtx, sizeof(pipeMtx) );
486 }
487
488 //---------------------------------------------------------------------------
489 // Create a model as display list
490 //---------------------------------------------------------------------------
myCreateModel(void)491 void myCreateModel( void )
492 {
493 s32 i, j, k;
494 u8 m0 = 0; // GX_PNMTX0;
495 u8 m1;
496
497 //--------- allocate buffer for the display list
498 if ( myDisplayList == NULL )
499 {
500 myDisplayList = MEMAllocFromAllocator(&DemoAllocator1, MYDLBUFSIZE);
501 DCInvalidateRange( myDisplayList, MYDLBUFSIZE);
502 }
503
504 //-------- Vertex attribute settings
505 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S8, 0 );
506 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_S8, 6 );
507 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0 );
508
509 //-------- Vertex descriptor settings
510 GXClearVtxDesc( );
511 GXSetVtxDesc( GX_VA_PNMTXIDX, GX_DIRECT );
512 GXSetVtxDesc( GX_VA_POS, GX_INDEX8 );
513 GXSetVtxDesc( GX_VA_NRM, GX_INDEX8 );
514 GXSetVtxDesc( GX_VA_CLR0, GX_INDEX8 );
515
516 GXGetVtxDescv(myDLVcd); // save vertex descriptor state
517
518 //-------- start generating display list
519 GXBeginDisplayList( myDisplayList, MYDLBUFSIZE );
520
521
522 //-------- Pipe lid 0 (Triangle fan)
523 GXBegin( GX_TRIANGLEFAN, GX_VTXFMT0, VTXINRING );
524 for ( i = 0; i < VTXINRING; i ++ )
525 {
526 GXMatrixIndex1x8( m0 );
527 GXPosition1x8 ( (u8)i );
528 GXNormal1x8 ( (u8)PIPELID0_NRM );
529 GXColor1x8 ( (u8)PIPELID0_CLR );
530 }
531 GXEnd( );
532
533
534 //-------- Pipe body (Triangle strip)
535 for ( j = 0; j < NUMRINGS-1; j ++ )
536 {
537 m0 = (u8)(j * 3); // GX_PNMTX0(=0), GX_PNMTX1(=3), ...
538 m1 = (u8)((j+1)*3); // GX_PNMTX1(=3), GX_PNMTX2(=6), ...
539
540 GXBegin( GX_TRIANGLESTRIP, GX_VTXFMT0, (VTXINRING+1)*2 );
541 k = VTXINRING-1;
542 for ( i = -1; i < VTXINRING; i ++, k = i )
543 {
544 GXMatrixIndex1x8( m0 );
545 GXPosition1x8 ( (u8)k );
546 GXNormal1x8 ( (u8)k );
547 GXColor1x8 ( (u8)j );
548 GXMatrixIndex1x8( m1 );
549 GXPosition1x8 ( (u8)k );
550 GXNormal1x8 ( (u8)k );
551 GXColor1x8 ( (u8)j );
552 }
553 GXEnd( );
554
555 }
556
557 //-------- Pipe lid 1 (Triangle fan)
558 GXBegin( GX_TRIANGLEFAN, GX_VTXFMT0, VTXINRING );
559 for ( i = 0; i < VTXINRING; i ++ )
560 {
561 GXMatrixIndex1x8( m1 );
562 GXPosition1x8 ( (u8)(VTXINRING-1-i) );
563 GXNormal1x8 ( (u8)PIPELID1_NRM );
564 GXColor1x8 ( (u8)PIPELID1_CLR );
565 }
566 GXEnd( );
567
568 //-------- end of the display list
569 myDLSize = GXEndDisplayList();
570
571 }
572
573 //---------------------------------------------------------------------------
574 // Draw model
575 //---------------------------------------------------------------------------
myDrawModel(void)576 void myDrawModel( void )
577 {
578 s32 i;
579 u32 m0;
580 GXColor matColor = { 0, 0, 0, 0 };
581 GXLightObj light;
582 GXColor color0 = { 160, 160, 160, 0 };
583 GXColor color1 = { 96, 96, 96, 0 };
584
585 //--------- Set rendering parameters
586 GXSetChanCtrl( GX_COLOR0, GX_ENABLE,
587 GX_SRC_REG, GX_SRC_VTX, GX_LIGHT0,
588 GX_DF_CLAMP, GX_AF_NONE );
589
590 GXSetChanCtrl( GX_ALPHA0, GX_DISABLE,
591 GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL,
592 GX_DF_CLAMP, GX_AF_NONE );
593
594 GXSetChanAmbColor( GX_COLOR0A0, color0 );
595
596 GXInitLightPos(&light, 1000.0f, 0.0f, 0.0f);
597 GXInitLightColor(&light, color1 );
598 GXLoadLightObjImm(&light, GX_LIGHT0);
599
600 GXSetNumTexGens ( 0 ); // # of Texgen proc
601 GXSetNumChans ( 1 ); // # of Color Channel
602 GXSetNumTevStages( 1 ); // # of Tev Stage
603
604 GXSetTevOrder( GX_TEVSTAGE0,
605 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0 );
606 GXSetTevOp( GX_TEVSTAGE0, GX_PASSCLR );
607
608 GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
609
610 //-------- Array base & stride setting
611 GXSetArray( GX_VA_POS, &ringVtx[0].x, sizeof( ringVtx[0] ) );
612 GXSetArray( GX_VA_NRM, &ringVtx[0].nx, sizeof( ringVtx[0] ) );
613 GXSetArray( GX_VA_CLR0, &pipeClr[0], sizeof( pipeClr[0] ) );
614 GXSetArray( GX_POS_MTX_ARRAY, &pipeMtx[0], sizeof( pipeMtx[0] ) );
615
616 //-------- Vertex attribute settings
617 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S8, 0 );
618 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_S8, 6 );
619 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0 );
620
621 //-------- Vertex descriptor settings
622 GXSetVtxDescv(myDLVcd);
623
624 //-------- Set transform matrices
625 for ( i = 0 ; i < NUMRINGS ; ++i )
626 {
627 m0 = (u32)(i * 3); // GX_PNMTX0(=0), GX_PNMTX1(=3), ...
628 GXLoadPosMtxIndx( (u16)i, m0 );
629 GXLoadNrmMtxImm( pipeMtx[i], m0 );
630 }
631
632 //-------- Draw the model
633 GXCallDisplayList( myDisplayList, myDLSize );
634
635 return;
636 }
637
638 //---------------------------------------------------------------------------
639 // Prints the directions on how to use this demo
640 //---------------------------------------------------------------------------
PrintIntro(void)641 void PrintIntro( void )
642 {
643 OSReport("\n\n");
644 OSReport("**********************************************\n");
645 OSReport("tev-outline: cartoon-outline demo\n");
646 OSReport("**********************************************\n");
647 OSReport("to quit hit the start button\n");
648 OSReport("\n");
649 OSReport("Main stick : Rotate the model\n");
650 OSReport("Sub stick : Control zoom\n");
651 OSReport("L/R triggers : Bend/Stretch the model\n");
652 OSReport("**********************************************\n");
653 OSReport("\n\n");
654 }
655
656 /*======== End of tev-outline.c ========*/
657