1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: lit-texture.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 lit-texture
15 Texture with lighting test
16 *---------------------------------------------------------------------------*/
17
18 /*---------------------------------------------------------------------------*
19 Header files
20 *---------------------------------------------------------------------------*/
21 #include <demo.h>
22 #include <math.h>
23
24 /*---------------------------------------------------------------------------*
25 Macro definitions
26 *---------------------------------------------------------------------------*/
27 #define PI 3.14159265358979323846F
28
29 #define NUM_TEVMODES 5
30
31 #define Clamp(val,min,max) \
32 ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
33
34 /*---------------------------------------------------------------------------*
35 Structure definitions
36 *---------------------------------------------------------------------------*/
37 // for camera
38 typedef struct
39 {
40 Vec location;
41 Vec up;
42 Vec target;
43 f32 left;
44 f32 top;
45 f32 znear;
46 f32 zfar;
47 } CameraConfig;
48
49 typedef struct
50 {
51 CameraConfig cfg;
52 Mtx view;
53 Mtx44 proj;
54 } MyCameraObj;
55
56 // for lighting
57 typedef struct
58 {
59 GXLightObj lobj;
60 s32 theta;
61 s32 phi;
62 f32 colorCtrl[3][3];
63 } MyLightEnvObj;
64
65 // for entire scene control
66 typedef struct
67 {
68 MyCameraObj cam;
69 MyLightEnvObj lightEnv;
70 Mtx modelCtrl;
71 u32 modelType;
72 GXTexObj texture;
73 u32 tevMode;
74 } MySceneCtrlObj;
75
76 /*---------------------------------------------------------------------------*
77 Forward references
78 *---------------------------------------------------------------------------*/
79 void main ( void );
80 static void DrawInit ( MySceneCtrlObj* sc );
81 static void DrawTick ( MySceneCtrlObj* sc );
82 static void AnimTick ( MySceneCtrlObj* sc );
83 static void DrawModel ( u32 model );
84 static void DrawLightMark ( void );
85 static void SetCamera ( MyCameraObj* cam );
86 static void SetLight ( MyLightEnvObj * le, Mtx view );
87 static void DisableLight ( void );
88 static void PrintIntro ( void );
89 static void PrintParam ( u32 cur, f32 param );
90
91 /*---------------------------------------------------------------------------*
92 Model data and strings for message
93 *---------------------------------------------------------------------------*/
94 #define SPHERE 0
95 #define CYLINDER 1
96 #define TORUS 2
97 #define ICOSA 3
98 #define DODECA 4
99 #define OCTA 5
100 #define CUBE 6
101
102 #define MODELS 7
103
104 static GXTevMode TevModeTable[] =
105 {
106 GX_MODULATE,
107 GX_DECAL,
108 GX_PASSCLR,
109 GX_REPLACE,
110 GX_BLEND // not supported on the MAC emulator
111 };
112
113 static char* TevModeStr[] =
114 {
115 "GX_MODULATE",
116 "GX_DECAL",
117 "GX_PASSCLR",
118 "GX_REPLACE",
119 "GX_BLEND"
120 };
121
122 static char* ParamTitle[] =
123 {
124 "Ambient",
125 "Material",
126 "Light"
127 };
128
129 /*---------------------------------------------------------------------------*
130 Test texture data
131 *---------------------------------------------------------------------------*/
132 #define TEST_TEXTURE_WIDTH 8
133 #define TEST_TEXTURE_HEIGHT 8
134 #define TEST_TEXTURE_FORMAT GX_TF_RGB5A3
135
136 static u16 TestTextureData[] ATTRIBUTE_ALIGN(32) =
137 {
138 // RGB5A3 format 8x8
139 0x7FFF, 0x7F00, 0x7F88, 0x70FF,
140 0x78FF, 0x700F, 0x78F8, 0x7888,
141 0x7CCC, 0x7FF8, 0x7F8F, 0x7FF0,
142 0x7F0F, 0x788F, 0x70F0, 0x7000,
143
144 0x1FFF, 0x1F00, 0x1F88, 0x10FF,
145 0x18FF, 0x100F, 0x18F8, 0x1888,
146 0x1CCC, 0x1FF8, 0x1F8F, 0x1FF0,
147 0x1F0F, 0x188F, 0x10F0, 0x1000,
148
149 0x0FFF, 0x0F00, 0x0F88, 0x00FF,
150 0x08FF, 0x000F, 0x08F8, 0x0888,
151 0x0CCC, 0x0FF8, 0x0F8F, 0x0FF0,
152 0x0F0F, 0x088F, 0x00F0, 0x0000,
153
154 0x6FFF, 0x6F00, 0x6F88, 0x60FF,
155 0x68FF, 0x600F, 0x68F8, 0x6888,
156 0x6CCC, 0x6FF8, 0x6F8F, 0x6FF0,
157 0x6F0F, 0x688F, 0x60F0, 0x6000,
158 };
159
160 /*---------------------------------------------------------------------------*
161 Camera configuration
162 *---------------------------------------------------------------------------*/
163 static CameraConfig DefaultCamera =
164 {
165 { 0.0F, 0.0F, 900.0F }, // location
166 { 0.0F, 1.0F, 0.0F }, // up
167 { 0.0F, 0.0F, 0.0F }, // target
168 -320.0F, // left
169 240.0F, // top
170 400.0F, // near
171 2000.0F // far
172 };
173
174 /*---------------------------------------------------------------------------*
175 Global variables
176 *---------------------------------------------------------------------------*/
177 static MySceneCtrlObj SceneCtrl; // scene control parameters
178
179 /*---------------------------------------------------------------------------*
180 Application main loop
181 *---------------------------------------------------------------------------*/
main(void)182 void main ( void )
183 {
184 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
185
186 DrawInit(&SceneCtrl); // Initialize vertex formats and scene parameters.
187
188 PrintIntro(); // Print demo directions
189
190 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
191 {
192 DEMOBeforeRender();
193 DrawTick(&SceneCtrl); // Draw the model.
194 DEMODoneRender();
195 DEMOPadRead(); // Update pad status.
196 AnimTick(&SceneCtrl); // Update animation.
197 }
198
199 OSHalt("End of demo");
200 }
201
202 /*---------------------------------------------------------------------------*
203 Functions
204 *---------------------------------------------------------------------------*/
205 /*---------------------------------------------------------------------------*
206 Name: DrawInit
207
208 Description: Initializes the vertex attribute format, texture and
209 default scene parameters.
210
211 Arguments: sc : pointer to the structure of scene control parameters
212
213 Returns: none
214 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)215 static void DrawInit( MySceneCtrlObj* sc )
216 {
217 u32 i;
218 Mtx mv,mr;
219
220 // set up a vertex attribute
221 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
222 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
223 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
224
225 // set up texture coord generation matrix
226 // because GXDraw Objects have no texture coords.
227 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_POS, GX_TEXMTX0);
228 MTXLightFrustum(mv, -1.0F, 1.0F, -1.0F, 1.0F, 8.0F, 1.0F, 1.0F, 0.5F, 0.5F);
229 MTXTrans(mr, 0.0F, 0.0F, -5.0F);
230 MTXConcat(mv, mr, mv);
231 GXLoadTexMtxImm(mv, GX_TEXMTX0, GX_MTX3x4);
232
233 GXInvalidateTexAll();
234
235
236 // Default scene parameter settings
237
238 // camera
239 sc->cam.cfg = DefaultCamera;
240 SetCamera(&sc->cam); // never changes in this test
241
242 // texture
243 GXInitTexObj(
244 &sc->texture,
245 TestTextureData,
246 TEST_TEXTURE_WIDTH,
247 TEST_TEXTURE_HEIGHT,
248 TEST_TEXTURE_FORMAT,
249 GX_REPEAT, // s
250 GX_REPEAT, // t
251 GX_FALSE );
252 GXInitTexObjLOD(
253 &sc->texture,
254 GX_NEAR,
255 GX_NEAR,
256 0,
257 0,
258 0,
259 GX_FALSE,
260 GX_FALSE,
261 GX_ANISO_1 );
262
263 // light parameters
264 sc->lightEnv.theta = 0;
265 sc->lightEnv.phi = 0;
266
267 // color of Ambient/Material/Light
268 for ( i = 0 ; i < 3 ; ++i )
269 {
270 sc->lightEnv.colorCtrl[0][i] = 0.1F;
271 sc->lightEnv.colorCtrl[1][i] = 1.0F;
272 sc->lightEnv.colorCtrl[2][i] = 0.9F;
273 }
274
275 // initialize model control matrix
276 MTXScale(sc->modelCtrl, 250.0F, 250.0F, 250.0F);
277 sc->modelType = 0;
278
279 // tev mode
280 sc->tevMode = 0;
281 }
282
283 /*---------------------------------------------------------------------------*
284 Name: DrawTick
285
286 Description: Draws the model by using given scene parameters
287
288 Arguments: sc : pointer to the structure of scene control parameters
289
290 Returns: none
291 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)292 static void DrawTick( MySceneCtrlObj* sc )
293 {
294 Mtx mv; // Modelview matrix.
295 Mtx mr; // Rotate matrix
296 Mtx mvi; // Modelview matrix.
297
298 // Tev mode = one color / one texture
299 GXSetNumTexGens(1); // use one texture coord
300 GXSetTevOp(GX_TEVSTAGE0, TevModeTable[sc->tevMode]);
301 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
302
303 // texture and lights
304 GXLoadTexObj(&sc->texture, GX_TEXMAP0);
305 SetLight(&sc->lightEnv, sc->cam.view);
306
307 // Draw a model
308 MTXConcat(sc->cam.view, sc->modelCtrl, mv);
309 GXLoadPosMtxImm(mv, GX_PNMTX0);
310 MTXInverse(mv, mvi);
311 MTXTranspose(mvi, mv);
312 GXLoadNrmMtxImm(mv, GX_PNMTX0);
313 DrawModel(sc->modelType);
314
315
316 // Tev mode = one color / no texture
317 GXSetNumTexGens(0);
318 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
319 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
320 // disable lighting
321 DisableLight();
322
323 // draw a light mark
324 MTXRotDeg(mr, 'y', sc->lightEnv.theta);
325 MTXConcat(sc->cam.view, mr, mv);
326 MTXRotDeg(mr, 'x', - sc->lightEnv.phi);
327 MTXConcat(mv, mr, mv);
328 GXLoadPosMtxImm(mv, GX_PNMTX0);
329 DrawLightMark();
330 }
331
332 /*---------------------------------------------------------------------------*
333 Name: AnimTick
334
335 Description: Changes scene parameters according to the pad status.
336
337 Arguments: sc : pointer to the structure of scene control parameters
338
339 Returns: none
340 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)341 static void AnimTick( MySceneCtrlObj* sc )
342 {
343 static u32 cursor = 0;
344 u16 down;
345 Mtx mrx, mry;
346
347 // PAD
348 down = DEMOPadGetButtonDown(0);
349
350 // Light Position Calculation
351 sc->lightEnv.theta += (DEMOPadGetStickX(0) / 24);
352 sc->lightEnv.theta %= 360;
353 sc->lightEnv.phi += (DEMOPadGetStickY(0) / 24);
354 Clamp(sc->lightEnv.phi, -90, 90);
355
356
357 // Model Rotation Calculation
358 MTXRotDeg(mry, 'x', -(DEMOPadGetSubStickY(0) / 24));
359 MTXRotDeg(mrx, 'y', (DEMOPadGetSubStickX(0) / 24));
360 MTXConcat(mry, sc->modelCtrl, sc->modelCtrl);
361 MTXConcat(mrx, sc->modelCtrl, sc->modelCtrl);
362
363
364 // Select Ambient/Material/Light (also R/G/B)
365 if ( down & PAD_BUTTON_Y )
366 {
367 cursor = ( cursor + 1 ) % 9;
368 PrintParam(cursor, sc->lightEnv.colorCtrl[cursor/3][cursor%3]);
369 }
370 if ( down & PAD_BUTTON_X )
371 {
372 cursor = ( cursor + 8 ) % 9;
373 PrintParam(cursor, sc->lightEnv.colorCtrl[cursor/3][cursor%3]);
374 }
375 // Color Parameter Tuning
376 if ( down & PAD_TRIGGER_L )
377 {
378 sc->lightEnv.colorCtrl[cursor/3][cursor%3] -= 0.05F;
379 if ( sc->lightEnv.colorCtrl[cursor/3][cursor%3] < 0.0F )
380 {
381 sc->lightEnv.colorCtrl[cursor/3][cursor%3] = 0.0F;
382 }
383 PrintParam(cursor, sc->lightEnv.colorCtrl[cursor/3][cursor%3]);
384 }
385 if ( down & PAD_TRIGGER_R )
386 {
387 sc->lightEnv.colorCtrl[cursor/3][cursor%3] += 0.05F;
388 if ( sc->lightEnv.colorCtrl[cursor/3][cursor%3] > 1.0F )
389 {
390 sc->lightEnv.colorCtrl[cursor/3][cursor%3] = 1.0F;
391 }
392 PrintParam(cursor, sc->lightEnv.colorCtrl[cursor/3][cursor%3]);
393 }
394
395 // Change tev mode
396 if ( down & PAD_BUTTON_B )
397 {
398 sc->tevMode = ( sc->tevMode + 1 ) % NUM_TEVMODES;
399 OSReport("TevMode : %s\n", TevModeStr[sc->tevMode]);
400 }
401
402 // Model Select
403 if ( down & PAD_BUTTON_A )
404 {
405 sc->modelType = ( sc->modelType + 1 ) % MODELS;
406 }
407 }
408
409 /*---------------------------------------------------------------------------*
410 Name: DrawModel
411
412 Description: Draws specified model
413
414 Arguments: model : specifies which model is to be displayed
415
416 Returns: none
417 *---------------------------------------------------------------------------*/
DrawModel(u32 model)418 static void DrawModel(u32 model)
419 {
420 // sets up vertex descriptors
421 GXClearVtxDesc();
422 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
423 GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
424
425 // draws a GXDraw model
426 switch(model)
427 {
428 case CYLINDER :
429 GXDrawCylinder(32);
430 break;
431 case TORUS :
432 GXDrawTorus(0.25F, 12, 16);
433 break;
434 case SPHERE :
435 GXDrawSphere(12, 24);
436 break;
437 case CUBE :
438 GXDrawCube();
439 break;
440 case OCTA :
441 GXDrawOctahedron();
442 break;
443 case ICOSA :
444 GXDrawIcosahedron();
445 break;
446 case DODECA :
447 GXDrawDodeca();
448 break;
449 }
450 }
451
452 /*---------------------------------------------------------------------------*
453 Name: DrawLightMark
454
455 Description: Draws a mark which shows position of the light.
456
457 Arguments: none
458
459 Returns: none
460 *---------------------------------------------------------------------------*/
DrawLightMark(void)461 static void DrawLightMark( void )
462 {
463 // sets up vertex descriptors
464 GXClearVtxDesc();
465 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
466 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
467
468 GXBegin(GX_LINES, GX_VTXFMT0, 8);
469 GXPosition3f32(500.0F, 500.0F, -500.0F);
470 GXColor4u8(0, 255, 255, 255);
471 GXPosition3f32(0.0F, 0.0F, 500.0F);
472 GXColor4u8(0, 255, 255, 255);
473
474 GXPosition3f32(500.0F, -500.0F, -500.0F);
475 GXColor4u8(0, 255, 255, 255);
476 GXPosition3f32(0.0F, 0.0F, 500.0F);
477 GXColor4u8(0, 255, 255, 255);
478
479 GXPosition3f32(-500.0F, 500.0F, -500.0F);
480 GXColor4u8(0, 255, 255, 255);
481 GXPosition3f32(0.0F, 0.0F, 500.0F);
482 GXColor4u8(0, 255, 255, 255);
483
484 GXPosition3f32(-500.0F, -500.0F, -500.0F);
485 GXColor4u8(0, 255, 255, 255);
486 GXPosition3f32(0.0F, 0.0F, 500.0F);
487 GXColor4u8(0, 255, 255, 255);
488 GXEnd();
489 }
490
491 /*---------------------------------------------------------------------------*
492 Name: SetCamera
493
494 Description: Sets view matrix and loads projection matrix into hardware
495
496 Arguments: cam : pointer to the MyCameraObj structure
497
498 Returns: none
499 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)500 static void SetCamera( MyCameraObj* cam )
501 {
502 MTXLookAt(
503 cam->view,
504 &cam->cfg.location,
505 &cam->cfg.up,
506 &cam->cfg.target );
507
508 MTXFrustum(
509 cam->proj,
510 cam->cfg.top,
511 - (cam->cfg.top),
512 cam->cfg.left,
513 - (cam->cfg.left),
514 cam->cfg.znear,
515 cam->cfg.zfar );
516 GXSetProjection(cam->proj, GX_PERSPECTIVE);
517 }
518
519 /*---------------------------------------------------------------------------*
520 Name: SetLight
521
522 Description: Sets up lights and lighting channel parameters
523
524 Arguments: le : pointer to a MyLightEnvObj structure
525 view : view matrix
526
527 Returns: none
528 *---------------------------------------------------------------------------*/
SetLight(MyLightEnvObj * le,Mtx view)529 static void SetLight( MyLightEnvObj* le, Mtx view )
530 {
531 GXColor colorBuf[3];
532 Vec lpos;
533 f32 theta, phi;
534 u32 i;
535
536 // Light Position
537 theta = (f32)le->theta * PI / 180.0F;
538 phi = (f32)le->phi * PI / 180.0F;
539 lpos.x = 500.0F * cosf(phi) * sinf(theta);
540 lpos.y = 500.0F * sinf(phi);
541 lpos.z = 500.0F * cosf(phi) * cosf(theta);
542
543 // Convert light position into view space
544 MTXMultVec(view, &lpos, &lpos);
545
546 // Light/Material Color
547 for ( i = 0 ; i < 3 ; ++i )
548 {
549 colorBuf[i].r = (u8)(le->colorCtrl[i][0] * 255.0F);
550 colorBuf[i].g = (u8)(le->colorCtrl[i][1] * 255.0F);
551 colorBuf[i].b = (u8)(le->colorCtrl[i][2] * 255.0F);
552 colorBuf[i].a = 255;
553 }
554
555 GXInitLightPos(&le->lobj, lpos.x, lpos.y, lpos.z);
556 GXInitLightColor(&le->lobj, colorBuf[2]);
557 GXLoadLightObjImm(&le->lobj, GX_LIGHT0);
558
559 // Lighting channel
560 GXSetNumChans(1); // number of active color channels
561 GXSetChanCtrl(
562 GX_COLOR0A0,
563 GX_ENABLE, // enable channel
564 GX_SRC_REG, // amb source
565 GX_SRC_REG, // mat source
566 GX_LIGHT0, // light mask
567 GX_DF_CLAMP, // diffuse function
568 GX_AF_NONE);
569 // set up ambient color
570 GXSetChanAmbColor(GX_COLOR0A0, colorBuf[0]);
571 // set up material color
572 GXSetChanMatColor(GX_COLOR0A0, colorBuf[1]);
573
574 }
575
576 /*---------------------------------------------------------------------------*
577 Name: DisableLight
578
579 Description: Disables lighting
580
581 Arguments: none
582
583 Returns: none
584 *---------------------------------------------------------------------------*/
DisableLight(void)585 static void DisableLight( void )
586 {
587 GXSetNumChans(1);
588 GXSetChanCtrl(
589 GX_COLOR0A0,
590 GX_DISABLE, // disable channel
591 GX_SRC_VTX, // amb source
592 GX_SRC_VTX, // mat source
593 GX_LIGHT0, // light mask
594 GX_DF_NONE, // diffuse function
595 GX_AF_NONE);
596 }
597
598 /*---------------------------------------------------------------------------*
599 Name: PrintIntro
600
601 Description: Prints the directions on how to use this demo.
602
603 Arguments: none
604
605 Returns: none
606 *---------------------------------------------------------------------------*/
PrintIntro(void)607 static void PrintIntro( void )
608 {
609 OSReport("\n\n");
610 OSReport("************************************************\n");
611 OSReport("lit-texture: texture with lighting test\n");
612 OSReport("************************************************\n");
613 OSReport("to quit hit the start button\n");
614 OSReport("\n");
615 OSReport("Main Stick : Move Light Position\n");
616 OSReport("Sub Stick : Rotate the Moddel\n");
617 OSReport("X/Y Buttons : Select control parameter\n");
618 OSReport("L/R Triggers : Change parameter value\n");
619 OSReport("A Button : Change Model\n");
620 OSReport("B Button : Change tev mode\n");
621 OSReport("************************************************\n\n");
622 }
623
624 /*---------------------------------------------------------------------------*
625 Name: PrintParam
626
627 Description: Prints specified parameter.
628 *---------------------------------------------------------------------------*/
PrintParam(u32 cur,f32 param)629 static void PrintParam( u32 cur, f32 param )
630 {
631 char rgb_chars[] = {'R','G','B'};
632
633 OSReport("%s", ParamTitle[cur/3]);
634 OSReport("[%c]", rgb_chars[cur%3]);
635 OSReport(" = %f\n", param);
636 }
637
638 /*============================================================================*/
639