1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: lit-unclamp.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-unclamp
15 Clamped/Unclamped diffuse function test
16 *---------------------------------------------------------------------------*/
17
18
19 /*---------------------------------------------------------------------------*
20 Header files
21 *---------------------------------------------------------------------------*/
22 #include <demo.h>
23 #include <math.h>
24
25 /*---------------------------------------------------------------------------*
26 Macro definitions
27 *---------------------------------------------------------------------------*/
28 #define PI 3.14159265358979323846F
29
30 #define Clamp(val,min,max) \
31 ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
32
33 /*---------------------------------------------------------------------------*
34 Structure definitions
35 *---------------------------------------------------------------------------*/
36 // for camera
37 typedef struct
38 {
39 Vec location;
40 Vec up;
41 Vec target;
42 f32 left;
43 f32 top;
44 f32 znear;
45 f32 zfar;
46 } CameraConfig;
47
48 typedef struct
49 {
50 CameraConfig cfg;
51 Mtx view;
52 Mtx44 proj;
53 } MyCameraObj;
54
55 // for lighting
56 typedef struct
57 {
58 GXLightObj lobj;
59 s32 theta;
60 s32 phi;
61 f32 brightCtrl[3];
62 GXDiffuseFn diffuseCtrl;
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 } MySceneCtrlObj;
73
74 /*---------------------------------------------------------------------------*
75 Forward references
76 *---------------------------------------------------------------------------*/
77 void main ( void );
78 static void DrawInit ( MySceneCtrlObj* sc );
79 static void DrawTick ( MySceneCtrlObj* sc );
80 static void AnimTick ( MySceneCtrlObj* sc );
81 static void DrawModel ( u32 model );
82 static void DrawLightMark ( void );
83 static void SetCamera ( MyCameraObj* cam );
84 static void SetLight ( MyLightEnvObj * le, Mtx view );
85 static void DisableLight ( void );
86 static void PrintIntro ( void );
87
88 /*---------------------------------------------------------------------------*
89 Model data and strings for message
90 *---------------------------------------------------------------------------*/
91 #define SPHERE 0
92 #define CYLINDER 1
93 #define TORUS 2
94 #define ICOSA 3
95 #define DODECA 4
96 #define OCTA 5
97 #define CUBE 6
98
99 #define MODELS 7
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
127 /*---------------------------------------------------------------------------*
128 Application main loop
129 *---------------------------------------------------------------------------*/
main(void)130 void main ( void )
131 {
132 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
133
134 DrawInit(&SceneCtrl); // Initialize vertex formats and scene parameters.
135
136 PrintIntro(); // Print demo directions
137
138 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
139 {
140 DEMOBeforeRender();
141 DrawTick(&SceneCtrl); // Draw the model.
142 DEMODoneRender();
143 DEMOPadRead(); // Update pad status.
144 AnimTick(&SceneCtrl); // Update animation.
145 }
146
147 OSHalt("End of demo");
148 }
149
150 /*---------------------------------------------------------------------------*
151 Functions
152 *---------------------------------------------------------------------------*/
153 /*---------------------------------------------------------------------------*
154 Name: DrawInit
155
156 Description: Initializes the vertex attribute format and
157 sets up default scene parameters.
158
159 Arguments: sc : pointer to the structure of scene control parameters
160
161 Returns: none
162 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)163 static void DrawInit( MySceneCtrlObj* sc )
164 {
165 // set up a vertex attribute
166 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
167 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
168 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
169
170
171 // Default scene parameter settings
172
173 // camera
174 sc->cam.cfg = DefaultCamera;
175 SetCamera(&sc->cam); // never changes in this test
176
177 // light parameters
178 sc->lightEnv.theta = 0;
179 sc->lightEnv.phi = 0;
180 sc->lightEnv.diffuseCtrl = GX_DF_SIGN;
181
182 // brightness of Ambient/Material/Light
183 sc->lightEnv.brightCtrl[0] = 0.5F;
184 sc->lightEnv.brightCtrl[1] = 1.0F;
185 sc->lightEnv.brightCtrl[2] = 0.5F;
186
187 // model control matrix
188 MTXScale(sc->modelCtrl, 250.0F, 250.0F, 250.0F);
189 sc->modelType = 0;
190 }
191
192 /*---------------------------------------------------------------------------*
193 Name: DrawTick
194
195 Description: Draws the model by using given scene parameters
196
197 Arguments: sc : pointer to the structure of scene control parameters
198
199 Returns: none
200 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)201 static void DrawTick( MySceneCtrlObj* sc )
202 {
203 Mtx mv; // Modelview matrix.
204 Mtx mr; // Rotate matrix
205 Mtx mvi; // Modelview matrix.
206
207 // render mode = one color / no texture
208 GXSetNumTexGens(0);
209 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
210 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
211
212 // enable lighting
213 SetLight(&sc->lightEnv, sc->cam.view);
214
215 // draw the model
216 MTXConcat(sc->cam.view, sc->modelCtrl, mv);
217 GXLoadPosMtxImm(mv, GX_PNMTX0);
218 MTXInverse(mv, mvi);
219 MTXTranspose(mvi, mv);
220 GXLoadNrmMtxImm(mv, GX_PNMTX0);
221 DrawModel(sc->modelType);
222
223
224 // disable lights
225 DisableLight();
226
227 // draw a light mark
228 MTXRotDeg(mr, 'y', sc->lightEnv.theta);
229 MTXConcat(sc->cam.view, mr, mv);
230 MTXRotDeg(mr, 'x', - sc->lightEnv.phi);
231 MTXConcat(mv, mr, mv);
232 GXLoadPosMtxImm(mv, GX_PNMTX0);
233 DrawLightMark();
234 }
235
236 /*---------------------------------------------------------------------------*
237 Name: AnimTick
238
239 Description: Changes scene parameters according to the pad status.
240
241 Arguments: sc : pointer to the structure of scene control parameters
242
243 Returns: none
244 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)245 static void AnimTick( MySceneCtrlObj* sc )
246 {
247 static u32 cursor = 0;
248 Mtx mrx, mry;
249 u16 down;
250 u32 pr = 0;
251
252 // PAD
253 down = DEMOPadGetButtonDown(0);
254
255 // Light Position Calculation
256 sc->lightEnv.theta += (DEMOPadGetStickX(0) / 32);
257 sc->lightEnv.theta %= 360;
258 sc->lightEnv.phi += (DEMOPadGetStickY(0) / 32);
259 Clamp(sc->lightEnv.phi, -90, 90);
260
261
262 // Model Rotation Calculation
263 MTXRotDeg(mry, 'x', -(DEMOPadGetSubStickY(0) / 32));
264 MTXRotDeg(mrx, 'y', (DEMOPadGetSubStickX(0) / 32));
265 MTXConcat(mry, sc->modelCtrl, sc->modelCtrl);
266 MTXConcat(mrx, sc->modelCtrl, sc->modelCtrl);
267
268
269 // Select Ambient/Material/Light
270 if ( down & PAD_BUTTON_Y )
271 {
272 cursor = ( cursor + 1 ) % 3;
273 pr = 1;
274 }
275 if ( down & PAD_BUTTON_X )
276 {
277 cursor = ( cursor + 2 ) % 3;
278 pr = 1;
279 }
280 // Ambient/Material/Light brightness tuning
281 if ( down & PAD_TRIGGER_L )
282 {
283 sc->lightEnv.brightCtrl[cursor] -= 0.05F;
284 if ( sc->lightEnv.brightCtrl[cursor] < 0.0F )
285 {
286 sc->lightEnv.brightCtrl[cursor] = 0.0F;
287 }
288 pr = 1;
289 }
290 if ( down & PAD_TRIGGER_R )
291 {
292 sc->lightEnv.brightCtrl[cursor] += 0.05F;
293 if ( sc->lightEnv.brightCtrl[cursor] > 1.0F )
294 {
295 sc->lightEnv.brightCtrl[cursor] = 1.0F;
296 }
297 pr = 1;
298 }
299
300 // prints selected/changed parameter
301 if ( pr )
302 {
303 OSReport(
304 "%s = %f\n",
305 ParamTitle[cursor],
306 sc->lightEnv.brightCtrl[cursor] );
307 }
308
309 // change diffuse function
310 if ( down & PAD_BUTTON_B )
311 {
312 sc->lightEnv.diffuseCtrl =
313 ( sc->lightEnv.diffuseCtrl == GX_DF_SIGN ) ?
314 GX_DF_CLAMP : GX_DF_SIGN;
315
316 if ( sc->lightEnv.diffuseCtrl == GX_DF_SIGN )
317 {
318 OSReport("GX_DF_SIGN\n");
319 }
320 else
321 {
322 OSReport("GX_DF_CLAMP\n");
323 }
324 }
325
326 // Model Select
327 if ( down & PAD_BUTTON_A )
328 {
329 sc->modelType = ( sc->modelType + 1 ) % MODELS;
330 }
331
332 }
333
334 /*---------------------------------------------------------------------------*
335 Name: DrawModel
336
337 Description: Draws specified model
338
339 Arguments: model : specifies which model is to be displayed
340
341 Returns: none
342 *---------------------------------------------------------------------------*/
DrawModel(u32 model)343 static void DrawModel( u32 model )
344 {
345 // sets up vertex descriptors
346 GXClearVtxDesc();
347 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
348 GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
349
350 // draws a GXDraw model
351 switch(model)
352 {
353 case CYLINDER :
354 GXDrawCylinder(48);
355 break;
356 case TORUS :
357 GXDrawTorus(0.25F, 16, 24);
358 break;
359 case SPHERE :
360 GXDrawSphere(16, 24);
361 break;
362 case CUBE :
363 GXDrawCube();
364 break;
365 case OCTA :
366 GXDrawOctahedron();
367 break;
368 case ICOSA :
369 GXDrawIcosahedron();
370 break;
371 case DODECA :
372 GXDrawDodeca();
373 break;
374 }
375 }
376
377 /*---------------------------------------------------------------------------*
378 Name: DrawLightMark
379
380 Description: Draws a mark which shows position of the light.
381
382 Arguments: none
383
384 Returns: none
385 *---------------------------------------------------------------------------*/
DrawLightMark(void)386 static void DrawLightMark( void )
387 {
388 // sets up vertex descriptors
389 GXClearVtxDesc();
390 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
391 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
392
393 GXBegin(GX_LINES, GX_VTXFMT0, 8);
394 GXPosition3f32(500.0F, 500.0F, -500.0F);
395 GXColor4u8(0, 255, 255, 255);
396 GXPosition3f32(0.0F, 0.0F, 500.0F);
397 GXColor4u8(0, 255, 255, 255);
398
399 GXPosition3f32(500.0F, -500.0F, -500.0F);
400 GXColor4u8(0, 255, 255, 255);
401 GXPosition3f32(0.0F, 0.0F, 500.0F);
402 GXColor4u8(0, 255, 255, 255);
403
404 GXPosition3f32(-500.0F, 500.0F, -500.0F);
405 GXColor4u8(0, 255, 255, 255);
406 GXPosition3f32(0.0F, 0.0F, 500.0F);
407 GXColor4u8(0, 255, 255, 255);
408
409 GXPosition3f32(-500.0F, -500.0F, -500.0F);
410 GXColor4u8(0, 255, 255, 255);
411 GXPosition3f32(0.0F, 0.0F, 500.0F);
412 GXColor4u8(0, 255, 255, 255);
413 GXEnd();
414 }
415
416 /*---------------------------------------------------------------------------*
417 Name: SetCamera
418
419 Description: Sets view matrix and loads projection matrix into hardware
420
421 Arguments: cam : pointer to the MyCameraObj structure
422
423 Returns: none
424 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)425 static void SetCamera( MyCameraObj* cam )
426 {
427 MTXLookAt(
428 cam->view,
429 &cam->cfg.location,
430 &cam->cfg.up,
431 &cam->cfg.target );
432
433 MTXFrustum(
434 cam->proj,
435 cam->cfg.top,
436 - (cam->cfg.top),
437 cam->cfg.left,
438 - (cam->cfg.left),
439 cam->cfg.znear,
440 cam->cfg.zfar );
441 GXSetProjection(cam->proj, GX_PERSPECTIVE);
442 }
443
444 /*---------------------------------------------------------------------------*
445 Name: SetLight
446
447 Description: Sets up lights and lighting channel parameters
448
449 Arguments: le : pointer to a MyLightEnvObj structure
450 view : view matrix
451
452 Returns: none
453 *---------------------------------------------------------------------------*/
SetLight(MyLightEnvObj * le,Mtx view)454 static void SetLight( MyLightEnvObj* le, Mtx view )
455 {
456 GXColor colorBuf[3];
457 Vec lpos;
458 f32 theta, phi;
459 u32 i;
460
461 // Light position
462 theta = (f32)le->theta * PI / 180.0F;
463 phi = (f32)le->phi * PI / 180.0F;
464 lpos.x = 500.0F * cosf(phi) * sinf(theta);
465 lpos.y = 500.0F * sinf(phi);
466 lpos.z = 500.0F * cosf(phi) * cosf(theta);
467
468 // Convert light position into view space
469 MTXMultVec(view, &lpos, &lpos);
470
471 // Ambient/Material/Light color
472 for ( i = 0 ; i < 3 ; ++i )
473 {
474 colorBuf[i].r =
475 colorBuf[i].g =
476 colorBuf[i].b = (u8)(le->brightCtrl[i] * 255.0F);
477 colorBuf[i].a = 255;
478 }
479
480 GXInitLightPos(&le->lobj, lpos.x, lpos.y, lpos.z);
481 GXInitLightColor(&le->lobj, colorBuf[2]);
482 GXLoadLightObjImm(&le->lobj, GX_LIGHT0);
483
484 // Lighting channel
485 GXSetNumChans(1); // number of active color channels
486 GXSetChanCtrl(
487 GX_COLOR0,
488 GX_ENABLE, // enable channel
489 GX_SRC_REG, // amb source
490 GX_SRC_REG, // mat source
491 GX_LIGHT0, // light mask
492 le->diffuseCtrl, // diffuse function
493 GX_AF_NONE);
494 GXSetChanCtrl(
495 GX_ALPHA0,
496 GX_DISABLE, // disable channel
497 GX_SRC_REG, // amb source
498 GX_SRC_REG, // mat source
499 GX_LIGHT0, // light mask
500 GX_DF_NONE, // diffuse function
501 GX_AF_NONE);
502 // set up ambient color
503 GXSetChanAmbColor(GX_COLOR0A0, colorBuf[0]);
504 // set up material color
505 GXSetChanMatColor(GX_COLOR0A0, colorBuf[1]);
506
507 }
508
509 /*---------------------------------------------------------------------------*
510 Name: DisableLight
511
512 Description: Disables lighting
513
514 Arguments: none
515
516 Returns: none
517 *---------------------------------------------------------------------------*/
DisableLight(void)518 static void DisableLight( void )
519 {
520 GXSetNumChans(1);
521 GXSetChanCtrl(
522 GX_COLOR0A0,
523 GX_DISABLE, // disable channel
524 GX_SRC_VTX, // amb source
525 GX_SRC_VTX, // mat source
526 GX_LIGHT0, // light mask
527 GX_DF_NONE, // diffuse function
528 GX_AF_NONE);
529 }
530
531 /*---------------------------------------------------------------------------*
532 Name: PrintIntro
533
534 Description: Prints the directions on how to use this demo.
535
536 Arguments: none
537
538 Returns: none
539 *---------------------------------------------------------------------------*/
PrintIntro(void)540 static void PrintIntro( void )
541 {
542 OSReport("\n\n");
543 OSReport("************************************************\n");
544 OSReport("lit-unclamp: clamped/unclamped diffuse func.test\n");
545 OSReport("************************************************\n");
546 OSReport("to quit hit the start button\n");
547 OSReport("\n");
548 OSReport("Main Stick : Move Light Position\n");
549 OSReport("Sub Stick : Rotate the Moddel\n");
550 OSReport("X/Y Buttons : Select control parameter\n");
551 OSReport("L/R Triggers : Change parameter value\n");
552 OSReport("A Button : Change Model\n");
553 OSReport("B Button : Change diffuse function\n");
554 OSReport("************************************************\n\n");
555 }
556
557 /*============================================================================*/
558