1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: lit-cartoon.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-cartoon
15 Unclamped diffuse function with texture coord generation
16 (Cartoon rendering)
17 *---------------------------------------------------------------------------*/
18
19
20 /*---------------------------------------------------------------------------*
21 Header files
22 *---------------------------------------------------------------------------*/
23 #include <demo.h>
24 #include <math.h>
25
26 /*---------------------------------------------------------------------------*
27 Macro definitions
28 *---------------------------------------------------------------------------*/
29 #define PI 3.14159265358979323846F
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 brightCtrl[3];
63 u32 cartoonType;
64 } MyLightEnvObj;
65
66 // for entire scene control
67 typedef struct
68 {
69 MyCameraObj cam;
70 MyLightEnvObj lightEnv;
71 Mtx modelCtrl;
72 u32 modelType;
73 GXTexObj texture;
74 GXTevMode tevMode;
75 } MySceneCtrlObj;
76
77 /*---------------------------------------------------------------------------*
78 Forward references
79 *---------------------------------------------------------------------------*/
80 void main ( void );
81 static void DrawInit ( MySceneCtrlObj* sc );
82 static void DrawTick ( MySceneCtrlObj* sc );
83 static void AnimTick ( MySceneCtrlObj* sc );
84 static void DrawModel ( u32 model );
85 static void DrawLightMark ( void );
86 static void SetCamera ( MyCameraObj* cam );
87 static void SetLight ( MyLightEnvObj* le, Mtx view );
88 static void DisableLight ( void );
89 static void PrintIntro ( void );
90
91 /*---------------------------------------------------------------------------*
92 Model data and strings for message
93 *---------------------------------------------------------------------------*/
94 #define TORUS 0
95 #define SPHERE 1
96 #define CUBE 2
97 #define ICOSA 3
98
99 #define MODELS 4
100
101 static char* ParamTitle[] =
102 {
103 "Ambient",
104 "Material",
105 "Light"
106 };
107
108 /*---------------------------------------------------------------------------*
109 Camera configuration
110 *---------------------------------------------------------------------------*/
111 static CameraConfig DefaultCamera =
112 {
113 { 0.0F, 0.0F, 900.0F }, // location
114 { 0.0F, 1.0F, 0.0F }, // up
115 { 0.0F, 0.0F, 0.0F }, // target
116 -320.0F, // left
117 240.0F, // top
118 400.0F, // near
119 2000.0F // far
120 };
121
122 /*---------------------------------------------------------------------------*
123 Global variables
124 *---------------------------------------------------------------------------*/
125 static MySceneCtrlObj SceneCtrl; // scene control parameters
126 static TPLPalettePtr MyTplObj = 0; // texture palette file
127 static GXTexCoordID CoordCtrl = GX_TEXCOORD0; // select one of 7 tex coords
128
129 /*---------------------------------------------------------------------------*
130 Application main loop
131 *---------------------------------------------------------------------------*/
main(void)132 void main ( void )
133 {
134 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
135
136 DrawInit(&SceneCtrl); // Initialize vertex formats and scene parameters.
137
138 PrintIntro(); // Print demo directions
139
140 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
141 {
142 DEMOBeforeRender();
143 DrawTick(&SceneCtrl); // Draw the model.
144 DEMODoneRender();
145 DEMOPadRead(); // Update pad status.
146 AnimTick(&SceneCtrl); // Update animation.
147 }
148
149 OSHalt("End of demo");
150 }
151
152 /*---------------------------------------------------------------------------*
153 Functions
154 *---------------------------------------------------------------------------*/
155 /*---------------------------------------------------------------------------*
156 Name: DrawInit
157
158 Description: Initializes the vertex attribute format, texture and
159 default scene parameters.
160
161 Arguments: sc : pointer to the structure of scene control parameters
162
163 Returns: none
164 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)165 static void DrawInit( MySceneCtrlObj* sc )
166 {
167 TPLDescriptorPtr tdp;
168
169 // set up a vertex attribute
170 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
171 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
172 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
173
174 // texture from Tpl file
175 TPLGetPalette(&MyTplObj, "gxTests/lit-06.tpl");
176 tdp = TPLGet(MyTplObj, 0);
177 GXInitTexObj(
178 &sc->texture,
179 tdp->textureHeader->data,
180 tdp->textureHeader->width,
181 tdp->textureHeader->height,
182 (GXTexFmt)tdp->textureHeader->format,
183 GX_CLAMP, // s
184 GX_CLAMP, // t
185 GX_FALSE ); // Mipmap
186 GXInitTexObjLOD(
187 &sc->texture,
188 tdp->textureHeader->minFilter,
189 tdp->textureHeader->magFilter,
190 tdp->textureHeader->minLOD,
191 tdp->textureHeader->maxLOD,
192 tdp->textureHeader->LODBias,
193 GX_FALSE,
194 tdp->textureHeader->edgeLODEnable,
195 GX_ANISO_1);
196 GXInvalidateTexAll();
197
198
199 // Default scene parameter settings
200
201 // camera
202 sc->cam.cfg = DefaultCamera;
203 SetCamera(&sc->cam); // never changes in this test
204
205 // light parameters
206 sc->lightEnv.theta = 0;
207 sc->lightEnv.phi = 0;
208
209 // brightness of Ambient/Material/Light
210 sc->lightEnv.brightCtrl[0] = 0.5F;
211 sc->lightEnv.brightCtrl[1] = 1.0F;
212 sc->lightEnv.brightCtrl[2] = 0.5F;
213
214 // type of cartoon lighting (1D texture lookup index)
215 sc->lightEnv.cartoonType = 0;
216
217 // model control matrix
218 MTXScale(sc->modelCtrl, 250.0F, 250.0F, 250.0F);
219 sc->modelType = 0;
220
221 // tev mode
222 sc->tevMode = GX_REPLACE;
223 }
224
225 /*---------------------------------------------------------------------------*
226 Name: DrawTick
227
228 Description: Draws the model by using given scene parameters
229
230 Arguments: sc : pointer to the structure of scene control parameters
231
232 Returns: none
233 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)234 static void DrawTick( MySceneCtrlObj* sc )
235 {
236 Mtx mv; // Modelview matrix.
237 Mtx mr; // Rotate matrix.
238 Mtx mvi; // Modelview matrix.
239 u32 i;
240
241 // enable lighting
242 SetLight(&sc->lightEnv, sc->cam.view);
243
244 // set texture
245 GXLoadTexObj(&sc->texture, GX_TEXMAP0);
246
247 // texture coord generation mode for cartoon lighting
248 for (i = 0; i < CoordCtrl; i++)
249 GXSetTexCoordGen((GXTexCoordID)i, GX_TG_MTX2x4, GX_TG_POS, GX_IDENTITY);
250
251 GXSetTexCoordGen(CoordCtrl, GX_TG_SRTG, GX_TG_COLOR0, GX_IDENTITY);
252
253 // set Tev mode = one color / one texture
254 GXSetTevOp(GX_TEVSTAGE0, sc->tevMode);
255 GXSetTevOrder(GX_TEVSTAGE0, CoordCtrl, GX_TEXMAP0, GX_COLOR0A0);
256 GXSetNumTexGens((u8)(CoordCtrl+1));
257
258 // draw a model
259 MTXConcat(sc->cam.view, sc->modelCtrl, mv);
260 GXLoadPosMtxImm(mv, GX_PNMTX0);
261 MTXInverse(mv, mvi);
262 MTXTranspose(mvi, mv);
263 GXLoadNrmMtxImm(mv, GX_PNMTX0);
264 DrawModel(sc->modelType);
265
266
267 // disable lights
268 DisableLight();
269
270 // set Tev mode = one color / no texture
271 GXSetNumTexGens(0);
272 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
273 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
274
275 // draw a light mark
276 MTXRotDeg(mr, 'y', sc->lightEnv.theta);
277 MTXConcat(sc->cam.view, mr, mv);
278 MTXRotDeg(mr, 'x', - sc->lightEnv.phi);
279 MTXConcat(mv, mr, mv);
280 GXLoadPosMtxImm(mv, GX_PNMTX0);
281 DrawLightMark();
282 }
283
284 /*---------------------------------------------------------------------------*
285 Name: AnimTick
286
287 Description: Changes scene parameters according to the pad status.
288
289 Arguments: sc : pointer to the structure of scene control parameters
290
291 Returns: none
292 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)293 static void AnimTick( MySceneCtrlObj* sc )
294 {
295 static u32 cursor = 0;
296 u16 down;
297 Mtx mrx, mry;
298 u32 pr = 0;
299
300 // PAD
301 down = DEMOPadGetButtonDown(0);
302
303 // Light Position Calculation
304 sc->lightEnv.theta += (DEMOPadGetStickX(0) / 32);
305 sc->lightEnv.theta %= 360;
306 sc->lightEnv.phi += (DEMOPadGetStickY(0) / 32);
307 Clamp(sc->lightEnv.phi, -90, 90);
308
309
310 // Model Rotation Calculation
311 MTXRotDeg(mry, 'x', -(DEMOPadGetSubStickY(0) / 32));
312 MTXRotDeg(mrx, 'y', (DEMOPadGetSubStickX(0) / 32));
313 MTXConcat(mry, sc->modelCtrl, sc->modelCtrl);
314 MTXConcat(mrx, sc->modelCtrl, sc->modelCtrl);
315
316
317 // Select Ambient/Material/Light
318 if ( down & PAD_BUTTON_Y )
319 {
320 cursor = ( cursor + 1 ) % 3;
321 pr = 1;
322 }
323 if ( down & PAD_BUTTON_X )
324 {
325 CoordCtrl = (GXTexCoordID) (CoordCtrl + 1);
326 if (CoordCtrl == GX_MAX_TEXCOORD)
327 CoordCtrl = GX_TEXCOORD0;
328 OSReport("Tex Coord %d being tested\n", CoordCtrl);
329 }
330 // Ambient/Material/Light brightness tuning
331 if ( down & PAD_TRIGGER_L )
332 {
333 sc->lightEnv.brightCtrl[cursor] -= 0.05F;
334 if ( sc->lightEnv.brightCtrl[cursor] < 0.0F )
335 {
336 sc->lightEnv.brightCtrl[cursor] = 0.0F;
337 }
338 pr = 1;
339 }
340 if ( down & PAD_TRIGGER_R )
341 {
342 sc->lightEnv.brightCtrl[cursor] += 0.05F;
343 if ( sc->lightEnv.brightCtrl[cursor] > 1.0F )
344 {
345 sc->lightEnv.brightCtrl[cursor] = 1.0F;
346 }
347 pr = 1;
348 }
349
350 // print selected/changed parameter
351 if ( pr )
352 {
353 OSReport(
354 "%s = %f\n",
355 ParamTitle[cursor],
356 sc->lightEnv.brightCtrl[cursor] );
357 }
358
359 // change cartoon texture type
360 if ( down & PAD_BUTTON_B )
361 {
362 sc->lightEnv.cartoonType = ( sc->lightEnv.cartoonType + 1 ) % 8;
363 }
364
365 // model select
366 if ( down & PAD_BUTTON_A )
367 {
368 sc->modelType = ( sc->modelType + 1 ) % MODELS;
369 }
370
371 }
372
373 /*---------------------------------------------------------------------------*
374 Name: DrawModel
375
376 Description: Draws specified model
377
378 Arguments: model : specifies which model is to be displayed
379
380 Returns: none
381 *---------------------------------------------------------------------------*/
DrawModel(u32 model)382 static void DrawModel( u32 model )
383 {
384 // sets up vertex descriptors
385 GXClearVtxDesc();
386 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
387 GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
388
389 // draws a GXDraw model
390 switch(model)
391 {
392 case TORUS :
393 GXDrawTorus(0.25F, 16, 24);
394 break;
395 case SPHERE :
396 GXDrawSphere(16, 24);
397 break;
398 case CUBE :
399 GXDrawCube();
400 break;
401 case ICOSA :
402 GXDrawIcosahedron();
403 break;
404 }
405 }
406
407 /*---------------------------------------------------------------------------*
408 Name: DrawLightMark
409
410 Description: Draws a mark which shows position of the light.
411
412 Arguments: none
413
414 Returns: none
415 *---------------------------------------------------------------------------*/
DrawLightMark(void)416 static void DrawLightMark( void )
417 {
418 // sets up vertex descriptors
419 GXClearVtxDesc();
420 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
421 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
422
423 GXBegin(GX_LINES, GX_VTXFMT0, 8);
424 GXPosition3f32(500.0F, 500.0F, -500.0F);
425 GXColor4u8(0, 255, 255, 255);
426 GXPosition3f32(0.0F, 0.0F, 500.0F);
427 GXColor4u8(0, 255, 255, 255);
428
429 GXPosition3f32(500.0F, -500.0F, -500.0F);
430 GXColor4u8(0, 255, 255, 255);
431 GXPosition3f32(0.0F, 0.0F, 500.0F);
432 GXColor4u8(0, 255, 255, 255);
433
434 GXPosition3f32(-500.0F, 500.0F, -500.0F);
435 GXColor4u8(0, 255, 255, 255);
436 GXPosition3f32(0.0F, 0.0F, 500.0F);
437 GXColor4u8(0, 255, 255, 255);
438
439 GXPosition3f32(-500.0F, -500.0F, -500.0F);
440 GXColor4u8(0, 255, 255, 255);
441 GXPosition3f32(0.0F, 0.0F, 500.0F);
442 GXColor4u8(0, 255, 255, 255);
443 GXEnd();
444 }
445
446 /*---------------------------------------------------------------------------*
447 Name: SetCamera
448
449 Description: Sets view matrix and loads projection matrix into hardware
450
451 Arguments: cam : pointer to the MyCameraObj structure
452
453 Returns: none
454 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)455 static void SetCamera( MyCameraObj* cam )
456 {
457 MTXLookAt(
458 cam->view,
459 &cam->cfg.location,
460 &cam->cfg.up,
461 &cam->cfg.target );
462
463 MTXFrustum(
464 cam->proj,
465 cam->cfg.top,
466 - (cam->cfg.top),
467 cam->cfg.left,
468 - (cam->cfg.left),
469 cam->cfg.znear,
470 cam->cfg.zfar );
471 GXSetProjection(cam->proj, GX_PERSPECTIVE);
472 }
473
474 /*---------------------------------------------------------------------------*
475 Name: SetLight
476
477 Description: Sets up lights and lighting channel parameters
478
479 Arguments: le : pointer to a MyLightEnvObj structure
480 view : view matrix
481
482 Returns: none
483 *---------------------------------------------------------------------------*/
SetLight(MyLightEnvObj * le,Mtx view)484 static void SetLight( MyLightEnvObj* le, Mtx view )
485 {
486 GXColor colorBuf[3];
487 Vec lpos;
488 f32 theta, phi;
489 u32 i;
490
491 // Light Position
492 theta = (f32)le->theta * PI / 180.0F;
493 phi = (f32)le->phi * PI / 180.0F;
494 lpos.x = 500.0F * cosf(phi) * sinf(theta);
495 lpos.y = 500.0F * sinf(phi);
496 lpos.z = 500.0F * cosf(phi) * cosf(theta);
497
498 // Convert light position into view space
499 MTXMultVec(view, &lpos, &lpos);
500
501 // Ambient/Material/Light color (red value only)
502 for ( i = 0 ; i < 3 ; ++i )
503 {
504 colorBuf[i].r = (u8)(le->brightCtrl[i] * 255.0F);
505 colorBuf[i].b = 0;
506 colorBuf[i].g = 0;
507 colorBuf[i].a = 255;
508 }
509 // The green component of ambient color is used to lookup
510 // 1D cartoon texture from 2D texture map.
511 colorBuf[0].g = (u8)(le->cartoonType * 0x20 + 0x10);
512 colorBuf[1].g = 255;
513
514 GXInitLightPos(&le->lobj, lpos.x, lpos.y, lpos.z);
515 GXInitLightColor(&le->lobj, colorBuf[2]);
516 GXLoadLightObjImm(&le->lobj, GX_LIGHT0);
517
518 // Lighting channel
519 GXSetNumChans(1); // number of active color channels
520 GXSetChanCtrl(
521 GX_COLOR0A0,
522 GX_ENABLE, // enable channel
523 GX_SRC_REG, // amb source
524 GX_SRC_REG, // mat source
525 GX_LIGHT0, // light mask
526 GX_DF_SIGN, // diffuse function
527 GX_AF_NONE);
528 // set up ambient color
529 GXSetChanAmbColor(GX_COLOR0A0, colorBuf[0]);
530 // set up material color
531 GXSetChanMatColor(GX_COLOR0A0, colorBuf[1]);
532
533 }
534
535 /*---------------------------------------------------------------------------*
536 Name: DisableLight
537
538 Description: Disables lighting
539
540 Arguments: none
541
542 Returns: none
543 *---------------------------------------------------------------------------*/
DisableLight(void)544 static void DisableLight( void )
545 {
546 GXSetNumChans(1);
547 GXSetChanCtrl(
548 GX_COLOR0A0,
549 GX_DISABLE, // disable channel
550 GX_SRC_VTX, // amb source
551 GX_SRC_VTX, // mat source
552 GX_LIGHT0, // light mask
553 GX_DF_NONE, // diffuse function
554 GX_AF_NONE);
555 }
556
557 /*---------------------------------------------------------------------------*
558 Name: PrintIntro
559
560 Description: Prints the directions on how to use this demo.
561
562 Arguments: none
563
564 Returns: none
565 *---------------------------------------------------------------------------*/
PrintIntro(void)566 static void PrintIntro( void )
567 {
568 OSReport("\n\n");
569 OSReport("**********************************************\n");
570 OSReport("lit-cartoon: unclamped diffuse function with\n");
571 OSReport(" texture lookup (cartoon rendering)\n");
572 OSReport("**********************************************\n");
573 OSReport("to quit hit the start button\n");
574 OSReport("\n");
575 OSReport("Main Stick : Move Light Position\n");
576 OSReport("Sub Stick : Rotate the Model\n");
577 OSReport("Y Button : Select control parameter\n");
578 OSReport("X Buttons : Select texture coordinate\n");
579 OSReport("L/R Triggers : Change parameter value\n");
580 OSReport("A Button : Change Model\n");
581 OSReport("B Button : Change 1D texture\n");
582 OSReport("**********************************************\n");
583 }
584
585 /*============================================================================*/
586