1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: cul-faces.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 <math.h>
15 #include "cmn-model.h"
16
17 #define SCREEN_WD 1 // Dummy - actual value filled at runtime
18 #define SCREEN_HT 1 // Dummy - actual value filled at runtime
19 #define SCREEN_DEPTH 128.0f
20 #define SCREEN_ZNEAR 0.0f // near plane Z in screen coordinates
21 #define SCREEN_ZFAR 1.0f // far plane Z in screen coordinates
22 #define ZBUFFER_MAX 0x00ffffff
23
24 /*---------------------------------------------------------------------------*
25 Typedefs
26 *---------------------------------------------------------------------------*/
27 typedef struct
28 {
29 Camera* camera;
30 ViewPort* viewport;
31 GXCullMode cullmode;
32 u32 flag;
33 } Scene;
34
35 #define SCENE_DRAWN (1<<0)
36
37 typedef struct
38 {
39 u32 modelId;
40 u32 numScene;
41 Scene* scene;
42 u32 screen_wd;
43 u32 screen_ht;
44 } GlobalScene;
45
46 /*---------------------------------------------------------------------------*
47 Forward references
48 *---------------------------------------------------------------------------*/
49 static void GlobalSceneDraw( GlobalScene* );
50 static void SceneDraw ( GlobalScene*, Scene* );
51 static void SceneDrawInfo ( Scene* );
52 static void SceneControl ( GlobalScene* );
53 static void myDrawModel ( GlobalScene*, Camera* );
54 static void PrintIntro ( void );
55
56 /*---------------------------------------------------------------------------*
57 Rendering parameters
58 *---------------------------------------------------------------------------*/
59 Camera myCamera =
60 {
61 { 0.0f, 0.0f, 0.0f }, // position
62 { 0.0f,1000.0f, 0.0f }, // target
63 { 0.0f, 0.0f, 1.0f }, // upVec
64 33.3f, // fovy
65 16.0f, // near plane Z in camera coordinates
66 1024.0f, // far plane Z in camera coordinates
67 };
68
69 ViewPort myViewPort[] =
70 {
71 // quarter size (these are adjusted in main)
72 { 0, 0, SCREEN_WD, SCREEN_HT },
73 { 0, SCREEN_HT, SCREEN_WD, SCREEN_HT },
74 { SCREEN_WD, 0, SCREEN_WD, SCREEN_HT },
75 { SCREEN_WD, SCREEN_HT, SCREEN_WD, SCREEN_HT },
76 };
77
78 GXColor myBgColor = { 32, 32, 128,255};
79
80 Scene myScene[] =
81 {
82 { &myCamera, &myViewPort[0], GX_CULL_NONE, SCENE_DRAWN },
83 { &myCamera, &myViewPort[1], GX_CULL_BACK, SCENE_DRAWN },
84 { &myCamera, &myViewPort[2], GX_CULL_FRONT, SCENE_DRAWN },
85 { &myCamera, &myViewPort[3], GX_CULL_ALL, SCENE_DRAWN },
86 };
87
88 GlobalScene myGlobal =
89 {
90 0,
91 (sizeof(myScene)/sizeof(Scene)),
92 myScene,
93 SCREEN_WD,
94 SCREEN_HT,
95 };
96
97 /*---------------------------------------------------------------------------*
98 Application main loop
99 *---------------------------------------------------------------------------*/
main(void)100 void main ( void )
101 {
102 GXRenderModeObj *rmp;
103 int i;
104
105 // initialize render settings and set clear color for first frame
106 DEMOInit(NULL);
107
108 PrintIntro();
109
110 // Perform dummy copy to clear EFB by specified color
111 GXSetCopyClear( myBgColor, GX_MAX_Z24 );
112 GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
113
114 rmp = DEMOGetRenderModeObj();
115 myGlobal.screen_wd = rmp->fbWidth;
116 myGlobal.screen_ht = rmp->efbHeight;
117
118 for(i = 0; i < 4; i++)
119 {
120 myViewPort[i].xorg *= myGlobal.screen_wd/2;
121 myViewPort[i].yorg *= myGlobal.screen_ht/2;
122 myViewPort[i].width *= myGlobal.screen_wd/2;
123 myViewPort[i].height *= myGlobal.screen_ht/2;
124 }
125
126 while ( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) )
127 {
128 // get pad status
129 DEMOPadRead( );
130
131 // General control & model animation
132 SceneControl( &myGlobal );
133 // No animation for this model.
134
135 // Draw scene
136 DEMOBeforeRender( );
137 GlobalSceneDraw( &myGlobal );
138 DEMODoneRender( );
139 }
140
141 OSHalt("End of demo");
142 }
143
144 /*---------------------------------------------------------------------------*
145 Functions
146 *---------------------------------------------------------------------------*/
147
148 //============================================================================
149 // Global Scene
150 //============================================================================
151 static void myDrawTriangles ( s32 );
152 static void myDrawQuads ( s32 );
153 static void myDrawTriangleStrip ( s32 );
154 static void myDrawTriangleFan ( s32 );
155
156 typedef struct
157 {
158 void (*draw)();
159 char* name;
160 } MyModel;
161
162 MyModel myModel[] =
163 {
164 { myDrawTriangles, "Triangles" },
165 { myDrawTriangleStrip, "Triangle Strip" },
166 { myDrawTriangleFan, "Triangle Fan" },
167 { myDrawQuads, "Quads" },
168 };
169
170 #define NUMMODELS (sizeof(myModel)/sizeof(MyModel))
171
172 static
GlobalSceneDraw(GlobalScene * g)173 void GlobalSceneDraw( GlobalScene* g )
174 {
175 u32 i;
176
177 for ( i = 0; i < g->numScene; i ++ )
178 {
179 SceneDraw( g, &g->scene[i] );
180 }
181
182 // Draw primitive name onto the window
183 GXSetViewport( 0, 0, (f32) g->screen_wd, (f32) g->screen_ht,
184 SCREEN_ZNEAR, SCREEN_ZFAR );
185 GXSetScissor( 0, 0, g->screen_wd, g->screen_ht );
186 DEMOInitCaption( DM_FT_XLU, (s32) g->screen_wd, (s32) g->screen_ht );
187 DEMOPrintf( 10, 12, 0, myModel[g->modelId].name );
188
189 return;
190 }
191
192 //============================================================================
193 // Scene
194 //============================================================================
195 typedef struct
196 {
197 GXCullMode mode;
198 char* name;
199 } CullMode;
200
201 CullMode myCullMode[] =
202 {
203 { GX_CULL_NONE, "CULL NONE" },
204 { GX_CULL_FRONT, "CULL FRONT" },
205 { GX_CULL_BACK, "CULL BACK" },
206 { GX_CULL_ALL, "CULL ALL" },
207 };
208
209 #define NUMCULLMODES (sizeof(myCullMode)/sizeof(CullMode))
210
211 /*---------------------------------------------------------------------------*
212 Name: SceneDraw
213 Description: Draw model
214 Arguments: Scene* s
215 Returns: none
216 *---------------------------------------------------------------------------*/
217 static
SceneDraw(GlobalScene * g,Scene * s)218 void SceneDraw( GlobalScene* g, Scene* s )
219 {
220 Camera* c = s->camera;
221 ViewPort* v = s->viewport;
222 float aspect = (float) (10.0 / 7.0);
223
224 // Check if drawn flag
225 if ( !(s->flag & SCENE_DRAWN) ) return;
226
227 // Set Perspective Viewing frustum
228 MTXPerspective( c->projMtx, c->fovy, aspect, c->znear, c->zfar );
229 GXSetProjection( c->projMtx, GX_PERSPECTIVE );
230
231 // Set CameraView matrix
232 MTXLookAt( c->viewMtx, &c->position, &c->up, &c->target );
233
234 // Set Viewport
235 GXSetViewport( v->xorg, v->yorg, v->width, v->height,
236 SCREEN_ZNEAR, SCREEN_ZFAR );
237 GXSetScissor( (u32)v->xorg, (u32)v->yorg, (u32)v->width, (u32)v->height );
238
239 // Pixel processing mode
240 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR );
241 GXSetZMode( GX_TRUE, GX_ALWAYS, GX_TRUE );
242
243 // Culling mode
244 GXSetCullMode( s->cullmode );
245
246 // Draw objects
247 myDrawModel( g, c );
248
249 // draw information
250 SceneDrawInfo( s );
251 return;
252 }
253
254 /*---------------------------------------------------------------------------*
255 Name: SceneDrawInfo
256 Description: Draw scene information
257 Arguments:
258 Returns: none
259 *---------------------------------------------------------------------------*/
260 static
SceneDrawInfo(Scene * s)261 void SceneDrawInfo( Scene* s )
262 {
263 ViewPort* v = s->viewport;
264 u32 lid;
265 s16 sx, sy;
266
267 // Draw parameters to the window
268 DEMOInitCaption( DM_FT_XLU, v->width, v->height );
269
270 // Temporary cullmode for displaying captions
271 GXSetCullMode( GX_CULL_NONE );
272
273 // get cullmode id
274 for ( lid = NUMCULLMODES-1; lid > 0; lid -- )
275 {
276 if ( s->cullmode == myCullMode[lid].mode ) break;
277 }
278 sx = (s16)( v->width / 2 - 36 );
279 sy = (s16)( v->height * 0.9 );
280 DEMOPrintf( sx, sy, 0, myCullMode[lid].name );
281
282 return;
283 }
284
285 /*---------------------------------------------------------------------------*
286 Name: SceneControl
287 Description: user interface for parameter control
288 Arguments:
289 Returns: none
290 *---------------------------------------------------------------------------*/
291 static
SceneControl(GlobalScene * g)292 void SceneControl( GlobalScene* g )
293 {
294 // Change model by Button A
295 if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_A )
296 {
297 g->modelId = ( g->modelId + 1 ) % NUMMODELS;
298 }
299 return;
300 }
301
302 //============================================================================
303 // Model
304 // Rectangles
305 //============================================================================
306 typedef struct
307 {
308 s16 x, z;
309 u8 r, g, b;
310 } MyVtx;
311
312 #define RSIZE 50
313 #define RPOSX 70
314 #define RPOSY 500 // direction for depth constant
315 #define RPOSZ 0
316
317 static void myDrawArrow( MyVtx *v, s32, s32 );
318 static void mySendVtx( MyVtx*, s32, s32 );
319
320 /*---------------------------------------------------------------------------*
321 Name: myDrawModel
322 Description: draw model
323 Arguments: Camera *c
324 Returns: none
325 *---------------------------------------------------------------------------*/
326 static
myDrawModel(GlobalScene * g,Camera * c)327 void myDrawModel( GlobalScene* g, Camera *c )
328 {
329 // set modelview matrix
330 GXSetCurrentMtx( GX_PNMTX0 );
331 GXLoadPosMtxImm( c->viewMtx, GX_PNMTX0 );
332
333 // use constant material color
334 GXSetNumChans( 1 ); // # of color channels
335 GXSetChanCtrl( GX_COLOR0,
336 GX_FALSE, // enable Channel
337 GX_SRC_REG, // amb source (Don't care)
338 GX_SRC_VTX, // mat source
339 GX_LIGHT0, // light mask (Don't care)
340 GX_DF_NONE, // diffuse function (Don't care)
341 GX_AF_NONE ); // atten function (Don't care)
342
343 // Set material color to go through PE stage.
344 GXSetNumTexGens( 0 ); // # of Tex gen
345 GXSetNumTevStages( 1 ); // # of Tev Stage
346 GXSetTevOrder( GX_TEVSTAGE0,
347 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0 );
348 GXSetTevOp( GX_TEVSTAGE0, GX_PASSCLR );
349
350 // Set vtx desc
351 GXClearVtxDesc( );
352 GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
353 GXSetVtxDesc( GX_VA_CLR0, GX_DIRECT );
354 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0 );
355 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGB, GX_RGB8, 0 );
356
357 // Draw primitives
358 myModel[g->modelId].draw( 1 );
359 myModel[g->modelId].draw( -1 );
360
361 return;
362 }
363
364 /*---------------------------------------------------------------------------*
365 Name: myDrawTriangles
366 Description: draw triangles
367 Arguments: s32 xflip
368 Returns: none
369 *---------------------------------------------------------------------------*/
370 static
371 MyVtx myTri[] =
372 {
373 { 1, 2, 255, 0, 0 },
374 { -1, 2, 0,255, 0 },
375 { 1, 0, 0, 0,255 },
376 { -1, 0, 255,255, 0 },
377 { -1, -2, 0,255,255 },
378 { 1, -2, 255, 0,255 },
379 };
380
381 static
myDrawTriangles(s32 xflip)382 void myDrawTriangles( s32 xflip )
383 {
384 // Draw rectangle
385 GXBegin( GX_TRIANGLES, GX_VTXFMT0, 6 );
386 mySendVtx( myTri, 6, xflip );
387 GXEnd( );
388
389 // Draw arrow
390 myDrawArrow( myTri+0, 3, xflip );
391 myDrawArrow( myTri+3, 3, xflip );
392
393 return;
394 }
395
396 /*---------------------------------------------------------------------------*
397 Name: myDrawQuads
398 Description: draw quad
399 Arguments: s32 xflip
400 Returns: none
401 *---------------------------------------------------------------------------*/
402 static
403 MyVtx myQuad[] =
404 {
405 { 1, 2, 255, 0, 0 },
406 { -1, 2, 0,255, 0 },
407 { -1, 0, 255, 0,255 },
408 { 1, 0, 0, 0,255 },
409 { 0, -2, 255,255, 0 },
410 { 1, -1, 0,255,255 },
411 { 0, 0, 128, 0,255 },
412 { -1, -1, 0,128,255 },
413 };
414
415 static
myDrawQuads(s32 xflip)416 void myDrawQuads( s32 xflip )
417 {
418 // Draw rectangle
419 GXBegin( GX_QUADS, GX_VTXFMT0, 8 );
420 mySendVtx( myQuad, 8, xflip );
421 GXEnd( );
422
423 // Draw arrow
424 myDrawArrow( myQuad+0, 4, xflip );
425 myDrawArrow( myQuad+4, 4, xflip );
426
427 return;
428 }
429
430 /*---------------------------------------------------------------------------*
431 Name: myDrawTriangleStrip
432 Description: draw triangle strip
433 Arguments: s32 xflip
434 Returns: none
435 *---------------------------------------------------------------------------*/
436 static
437 MyVtx myTriStrip[] =
438 {
439 { 1, 2, 255, 0, 0 },
440 { -1, 2, 0,255, 0 },
441 { 1, 0, 0, 0,255 },
442 { -1, 0, 255,255, 0 },
443 { -1, -2, 0,255,255 },
444 { 1, -2, 255, 0,255 },
445 };
446
447 static
myDrawTriangleStrip(s32 xflip)448 void myDrawTriangleStrip( s32 xflip )
449 {
450 // Draw rectangle
451 GXBegin( GX_TRIANGLESTRIP, GX_VTXFMT0, 6 );
452 mySendVtx( myTriStrip, 6, xflip );
453 GXEnd( );
454
455 // Draw arrow
456 myDrawArrow( myTriStrip, 6, xflip );
457
458 return;
459 }
460
461 /*---------------------------------------------------------------------------*
462 Name: myDrawTriangleFan
463 Description: draw triangle fan
464 Arguments: s32 xflip
465 Returns: none
466 *---------------------------------------------------------------------------*/
467 static
468 MyVtx myTriFan[] =
469 {
470 { 1, 0, 255, 0, 0 },
471 { 1, 2, 0,255, 0 },
472 { -1, 2, 0, 0,255 },
473 { -1, 0, 255,255, 0 },
474 { 1, -2, 0,255,255 },
475 { -1, -2, 255, 0,255 },
476 };
477
478 static
myDrawTriangleFan(s32 xflip)479 void myDrawTriangleFan( s32 xflip )
480 {
481 // Draw rectangle
482 GXBegin( GX_TRIANGLEFAN, GX_VTXFMT0, 6 );
483 mySendVtx( myTriFan, 6, xflip );
484 GXEnd( );
485
486 // Draw arrow
487 myDrawArrow( myTriFan, 6, xflip );
488
489 return;
490 }
491
492 /*---------------------------------------------------------------------------*
493 Name: myDrawArrow
494 Description: draw arrow
495 Arguments: MyVtx *v, s32 nvtx, s32 xflip
496 Returns: none
497 *---------------------------------------------------------------------------*/
498 #define ARROWSIZE 10
499 #define COS30 (1.7320508f/2.0f)
500 #define SIN30 (1.0000000f/2.0f)
501
502 static
myDrawArrow(MyVtx * v,s32 nvtx,s32 xflip)503 void myDrawArrow( MyVtx *v, s32 nvtx, s32 xflip )
504 {
505 u32 i;
506 s32 xs, zs, x0, z0, x1, z1;
507 f32 d, c, s;
508
509 // Draw arrow
510 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR );
511 GXBegin( GX_LINESTRIP, GX_VTXFMT0, (u8)(nvtx + 3) );
512 for ( i = 0; i < nvtx; i ++ )
513 {
514 xs = ( RPOSX + v[i].x * RSIZE ) * xflip;
515 zs = RPOSZ + v[i].z * RSIZE;
516 GXPosition3s16( (s16)xs, RPOSY, (s16)zs );
517 GXColor3u8( 255, 255, 255 );
518 }
519 c = (float)( ( v[i-2].x - v[i-1].x ) * xflip );
520 s = (float) ( v[i-2].z - v[i-1].z );
521 d = (float)ARROWSIZE / sqrtf( c * c + s * s );
522 c *= d;
523 s *= d;
524 x0 = (s32)( c * COS30 - s * SIN30 + 0.5f );
525 z0 = (s32)( c * SIN30 + s * COS30 + 0.5f );
526 x1 = (s32)( c * COS30 + s * SIN30 + 0.5f );
527 z1 = (s32)(- c * SIN30 + s * COS30 + 0.5f );
528 GXPosition3s16( (s16)( xs + x0 ), RPOSY, (s16)( zs + z0 ) );
529 GXColor3u8( 255, 255, 255 );
530 GXPosition3s16( (s16)xs, RPOSY, (s16)zs );
531 GXColor3u8( 255, 255, 255 );
532 GXPosition3s16( (s16)( xs + x1 ), RPOSY, (s16)( zs + z1 ) );
533 GXColor3u8( 255, 255, 255 );
534 GXEnd( );
535 GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR );
536
537 return;
538 }
539
540 /*---------------------------------------------------------------------------*
541 Name: mySendVtx
542 Description: send vertex into pipeline
543 Arguments: MyVtx* v, s32 nvtx, s32 xflip
544 Returns: none
545 *---------------------------------------------------------------------------*/
546 static
mySendVtx(MyVtx * v,s32 nvtx,s32 xflip)547 void mySendVtx( MyVtx* v, s32 nvtx, s32 xflip )
548 {
549 u32 i;
550 s32 xs, zs;
551
552 for ( i = 0; i < nvtx; i ++ )
553 {
554 xs = ( RPOSX + v[i].x * RSIZE ) * xflip;
555 zs = RPOSZ + v[i].z * RSIZE;
556 GXPosition3s16( (s16)xs, RPOSY, (s16)zs );
557 GXColor3u8( v[i].r, v[i].g, v[i].b );
558 }
559
560 return;
561 }
562
563
564 /*---------------------------------------------------------------------------*
565 Name: PrintIntro
566 Description: Print directions on how to use this demo
567 Arguments: none
568 Returns: none
569 *---------------------------------------------------------------------------*/
PrintIntro(void)570 static void PrintIntro( void )
571 {
572 OSReport("\n\n");
573 OSReport("************************************************\n");
574 OSReport("cul-faces: show different culling modes\n");
575 OSReport("************************************************\n");
576 OSReport("to quit hit the start button\n");
577 OSReport("\n");
578 OSReport("Button A : change model\n");
579 }
580
581 /*======== End of cul-faces.c ========*/
582