1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tg-light-fix.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 tg-light-fx
15 Some applications by texgen from the normal
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 #define NUM_MODES 3
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 GXColor lightColor;
60 GXColor ambColor;
61 GXColor matColor;
62 } MyColorEnvObj;
63
64 typedef struct
65 {
66 GXLightObj lobj;
67 s32 theta;
68 s32 phi;
69 GXBool mark;
70 MyColorEnvObj colorEnv;
71 } MyLightObj;
72
73 // for entire scene control
74 typedef struct
75 {
76 MyCameraObj cam;
77 MyLightObj light;
78 GXTexObj texture[NUM_MODES];
79 f32 tune[NUM_MODES];
80 Mtx modelCtrl;
81 u32 mode;
82 } MySceneCtrlObj;
83
84 /*---------------------------------------------------------------------------*
85 Forward references
86 *---------------------------------------------------------------------------*/
87 void main ( void );
88 static void DrawInit ( MySceneCtrlObj* sc );
89 static void DrawTick ( MySceneCtrlObj* sc );
90 static void AnimTick ( MySceneCtrlObj* sc );
91 static void DrawLightMark ( void );
92 static void SetCamera ( MyCameraObj* cam );
93 static void SetLight ( MyLightObj* light, Mtx view );
94 static void DisableLight ( void );
95 static void SetTexGenMtx0 ( MySceneCtrlObj* sc );
96 static void SetTexGenMtx1 ( MySceneCtrlObj* sc );
97 static void SetTexGenMtx2 ( MySceneCtrlObj* sc );
98 static void PrintIntro ( void );
99
100 /*---------------------------------------------------------------------------*
101 Lighting parameters
102 *---------------------------------------------------------------------------*/
103 MyColorEnvObj MyColors[] ATTRIBUTE_ALIGN(32) =
104 {
105 {
106 { 0xFF, 0xFF, 0xFF, 0xFF }, // Light color 0
107 { 0x80, 0x80, 0x80, 0xFF }, // Ambient 0
108 { 0xFF, 0xFF, 0x00, 0xFF } // Material 0
109 },
110 {
111 { 0xFF, 0xFF, 0xFF, 0xFF }, // Light color 1
112 { 0x40, 0x40, 0x40, 0xFF }, // Ambient 1
113 { 0x00, 0x00, 0xFF, 0xFF } // Material 1
114 },
115 {
116 { 0xFF, 0xFF, 0xFF, 0xFF }, // Light color 2
117 { 0x40, 0x40, 0x40, 0xFF }, // Ambient 2
118 { 0xFF, 0x00, 0x20, 0xFF } // Material 2
119 }
120 };
121
122 /*---------------------------------------------------------------------------*
123 Test texture data
124 *---------------------------------------------------------------------------*/
125 static u8 TestTexMap0[] ATTRIBUTE_ALIGN(32) =
126 {
127 // IA4 format 16x4
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF0, 0xF0,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF0, 0xF0,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF0, 0xF0,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF0, 0xF0,
132
133 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
134 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
135 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
136 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00
137 };
138
139 static u8 TestTexMap1[] ATTRIBUTE_ALIGN(32) =
140 {
141 // IA8 format 16x4
142 0x00, 0xFF, 0x00, 0xFF, 0x08, 0xFF, 0x20, 0xFF,
143 0x00, 0xFF, 0x00, 0xFF, 0x08, 0xFF, 0x20, 0xFF,
144 0x00, 0xFF, 0x00, 0xFF, 0x08, 0xFF, 0x20, 0xFF,
145 0x00, 0xFF, 0x00, 0xFF, 0x08, 0xFF, 0x20, 0xFF,
146
147 0x38, 0xFF, 0x50, 0xFF, 0x68, 0xFF, 0x80, 0xFF,
148 0x38, 0xFF, 0x50, 0xFF, 0x68, 0xFF, 0x80, 0xFF,
149 0x38, 0xFF, 0x50, 0xFF, 0x68, 0xFF, 0x80, 0xFF,
150 0x38, 0xFF, 0x50, 0xFF, 0x68, 0xFF, 0x80, 0xFF,
151
152 0x98, 0xFF, 0xB0, 0xFF, 0xC8, 0xFF, 0xE0, 0xFF,
153 0x98, 0xFF, 0xB0, 0xFF, 0xC8, 0xFF, 0xE0, 0xFF,
154 0x98, 0xFF, 0xB0, 0xFF, 0xC8, 0xFF, 0xE0, 0xFF,
155 0x98, 0xFF, 0xB0, 0xFF, 0xC8, 0xFF, 0xE0, 0xFF,
156
157 0xF0, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
158 0xF0, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159 0xF0, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
160 0xF0, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
161 };
162
163 static u8 TestTexMap2[] ATTRIBUTE_ALIGN(32) =
164 {
165 // IA4 format 16x16
166 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
167 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1F,
168 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1F, 0x2F,
169 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x2F, 0x5F,
170
171 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
172 0x1F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
173 0x2F, 0x1F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
174 0x5F, 0x2F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
175
176
177 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x3F, 0x8F,
178 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x3F, 0x6F, 0xBF,
179 0x0F, 0x0F, 0x1F, 0x2F, 0x3F, 0x6F, 0xAF, 0xDF,
180 0x0F, 0x1F, 0x2F, 0x5F, 0x8F, 0xBF, 0xDF, 0xFF,
181
182 0x8F, 0x3F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
183 0xBF, 0x6F, 0x3F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
184 0xDF, 0xAF, 0x6F, 0x3F, 0x2F, 0x1F, 0x0F, 0x0F,
185 0xFF, 0xDF, 0xBF, 0x8F, 0x5F, 0x2F, 0x1F, 0x0F,
186
187
188 0x0F, 0x1F, 0x2F, 0x5F, 0x8F, 0xBF, 0xDF, 0xFF,
189 0x0F, 0x0F, 0x1F, 0x2F, 0x3F, 0x6F, 0xAF, 0xDF,
190 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x3F, 0x6F, 0xBF,
191 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x3F, 0x8F,
192
193 0xFF, 0xDF, 0xBF, 0x8F, 0x5F, 0x2F, 0x1F, 0x0F,
194 0xDF, 0xAF, 0x6F, 0x3F, 0x2F, 0x1F, 0x0F, 0x0F,
195 0xBF, 0x6F, 0x3F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
196 0x8F, 0x3F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
197
198
199 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x2F, 0x5F,
200 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1F, 0x2F,
201 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1F,
202 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
203
204 0x5F, 0x2F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
205 0x2F, 0x1F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
206 0x1F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
207 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
208 };
209
210 static u16 TestTexWidth[NUM_MODES] =
211 {
212 16, 16, 16
213 };
214
215 static u16 TestTexHeight[NUM_MODES] =
216 {
217 4, 4, 16
218 };
219
220 static GXTexFmt TestTexFormat[NUM_MODES] =
221 {
222 GX_TF_IA4, GX_TF_IA8, GX_TF_IA4
223 };
224
225 static u8* TestTexData[NUM_MODES] =
226 {
227 TestTexMap0,
228 TestTexMap1,
229 TestTexMap2
230 };
231
232 /*---------------------------------------------------------------------------*
233 Camera configuration
234 *---------------------------------------------------------------------------*/
235 static CameraConfig DefaultCamera =
236 {
237 { 0.0F, 0.0F, 2500.0F }, // location
238 { 0.0F, 1.0F, 0.0F }, // up
239 { 0.0F, 0.0F, 0.0F }, // target
240 -320.0F, // left
241 240.0F, // top
242 1000.0F, // near
243 5000.0F // far
244 };
245
246 /*---------------------------------------------------------------------------*
247 Global variables
248 *---------------------------------------------------------------------------*/
249 static MySceneCtrlObj SceneCtrl; // scene control parameters
250
251 /*---------------------------------------------------------------------------*
252 Application main loop
253 *---------------------------------------------------------------------------*/
main(void)254 void main ( void )
255 {
256 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
257
258 DrawInit(&SceneCtrl); // Initialize vertex formats and scene parameters.
259
260 PrintIntro(); // Print demo directions
261
262 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
263 {
264 DEMOBeforeRender();
265 DrawTick(&SceneCtrl); // Draw the model.
266 DEMODoneRender();
267 DEMOPadRead(); // Update pad status.
268 AnimTick(&SceneCtrl); // Update animation.
269 }
270
271 OSHalt("End of demo");
272 }
273
274 /*---------------------------------------------------------------------------*
275 Functions
276 *---------------------------------------------------------------------------*/
277 /*---------------------------------------------------------------------------*
278 Name: DrawInit
279
280 Description: Initializes the vertex attribute format, texture and
281 default scene parameters.
282
283 Arguments: sc : pointer to the structure of scene control parameters
284
285 Returns: none
286 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)287 static void DrawInit( MySceneCtrlObj* sc )
288 {
289 GXColor bgColor = { 0x40, 0x40, 0x40, 0xFF };
290 u32 i;
291
292 GXSetCopyClear(bgColor, 0xFFFFFF);
293
294 // set up a vertex attribute
295 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
296 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
297 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
298
299 // textures
300 for ( i = 0 ; i < NUM_MODES ; ++i )
301 {
302 GXInitTexObj(
303 &sc->texture[i],
304 TestTexData[i],
305 TestTexWidth[i],
306 TestTexHeight[i],
307 TestTexFormat[i],
308 GX_CLAMP, // s
309 GX_CLAMP, // t
310 GX_FALSE );
311 GXInitTexObjLOD(
312 &sc->texture[i],
313 GX_LINEAR,
314 GX_LINEAR,
315 0,
316 0,
317 0,
318 GX_FALSE,
319 GX_FALSE,
320 GX_ANISO_1 );
321 }
322
323
324 // Default scene parameter settings
325
326 // camera
327 sc->cam.cfg = DefaultCamera;
328 SetCamera(&sc->cam); // never changes in this test
329
330 // light parameters
331 sc->light.theta = 0;
332 sc->light.phi = 0;
333 sc->light.mark = GX_FALSE;
334
335 // tuning parameters
336 for ( i = 0 ; i < NUM_MODES ; ++i )
337 {
338 sc->tune[i] = 0.5F;
339 }
340
341 // mode
342 sc->mode = 0;
343
344 // model control matrix
345 MTXIdentity(sc->modelCtrl);
346 }
347
348 /*---------------------------------------------------------------------------*
349 Name: DrawTick
350
351 Description: Draws the model by using given scene parameters
352
353 Arguments: sc : pointer to the structure of scene control parameters
354
355 Returns: none
356 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)357 static void DrawTick( MySceneCtrlObj* sc )
358 {
359 Mtx mv, mvi, mr, ms, mm;
360
361 // enable lighting
362 sc->light.colorEnv = MyColors[sc->mode];
363 SetLight(&sc->light, sc->cam.view);
364 // set texture environments
365 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
366 GXSetTevOp(GX_TEVSTAGE0, GX_DECAL);
367 GXSetNumTexGens(1);
368 GXSetNumChans(1);
369 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_NRM, GX_TEXMTX0);
370 GXLoadTexObj(&sc->texture[sc->mode], GX_TEXMAP0);
371
372 // set texture coord generation matrix
373 switch ( sc->mode )
374 {
375 case 0:
376 SetTexGenMtx0(sc);
377 break;
378 case 1:
379 SetTexGenMtx1(sc);
380 break;
381 case 2:
382 SetTexGenMtx2(sc);
383 break;
384 }
385
386 // draw a model
387 MTXConcat(sc->cam.view, sc->modelCtrl, mm);
388 MTXInverse(mm, mvi);
389 MTXTranspose(mvi, mv);
390 GXLoadNrmMtxImm(mv, GX_PNMTX0);
391
392 MTXScale(ms, 400.0F, 400.0F, 400.0F);
393 MTXConcat(mm, ms, mv);
394 GXLoadPosMtxImm(mv, GX_PNMTX0);
395 GXDrawTorus(0.20F, 16, 32);
396
397 MTXScale(ms, 200.0F, 200.0F, 200.0F);
398 MTXConcat(mm, ms, mv);
399 GXLoadPosMtxImm(mv, GX_PNMTX0);
400 GXDrawSphere1(3);
401
402
403 if ( sc->light.mark )
404 {
405 // disable lighting
406 DisableLight();
407 // set texture environments
408 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
409 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
410 GXSetNumTexGens(0);
411
412 // draw a light mark
413 MTXRotDeg(mr, 'y', sc->light.theta);
414 MTXConcat(sc->cam.view, mr, mv);
415 MTXRotDeg(mr, 'x', - sc->light.phi);
416 MTXConcat(mv, mr, mv);
417 GXLoadPosMtxImm(mv, GX_PNMTX0);
418 DrawLightMark();
419 }
420 }
421
422 /*---------------------------------------------------------------------------*
423 Name: AnimTick
424
425 Description: Changes scene parameters according to the pad status.
426
427 Arguments: sc : pointer to the structure of scene control parameters
428
429 Returns: none
430 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)431 static void AnimTick( MySceneCtrlObj* sc )
432 {
433 Mtx mrx, mry;
434 u16 button, down;
435 u32 pr = 0;
436
437 // PAD
438 button = DEMOPadGetButton(0);
439 down = DEMOPadGetButtonDown(0);
440
441 // Light Position Calculation
442 sc->light.theta += ( DEMOPadGetStickX(0) / 24 );
443 sc->light.theta = sc->light.theta % 360;
444
445 sc->light.phi += ( DEMOPadGetStickY(0) / 24 );
446 Clamp(sc->light.phi, -90, 90);
447
448
449 // Model Rotation Calculation
450 MTXRotDeg(mry, 'x', -(f32)DEMOPadGetSubStickY(0) / 24.0F);
451 MTXRotDeg(mrx, 'y', (f32)DEMOPadGetSubStickX(0) / 24.0F);
452 MTXConcat(mry, sc->modelCtrl, sc->modelCtrl);
453 MTXConcat(mrx, sc->modelCtrl, sc->modelCtrl);
454
455
456 // Hide light direction mark
457 if ( button & PAD_BUTTON_B )
458 {
459 sc->light.mark = GX_FALSE;
460 }
461 else
462 {
463 sc->light.mark = GX_TRUE;
464 }
465
466 // Tuning parameters
467 if ( down & PAD_TRIGGER_L )
468 {
469 sc->tune[sc->mode] -= 0.1F;
470 }
471 if ( down & PAD_TRIGGER_R )
472 {
473 sc->tune[sc->mode] += 0.1F;
474 }
475 Clamp(sc->tune[sc->mode], 0.0F, 1.0F);
476
477 // change mode
478 if ( down & PAD_BUTTON_A )
479 {
480 sc->mode = ( sc->mode + 1 ) % NUM_MODES;
481 }
482
483 }
484
485 /*---------------------------------------------------------------------------*
486 Name: DrawLightMark
487
488 Description: Draws a mark which shows position of the light.
489
490 Arguments: none
491
492 Returns: none
493 *---------------------------------------------------------------------------*/
DrawLightMark(void)494 static void DrawLightMark( void )
495 {
496 // sets up vertex descriptors
497 GXClearVtxDesc();
498 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
499 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
500
501 GXBegin(GX_LINES, GX_VTXFMT0, 8);
502 GXPosition3f32(500.0F, 500.0F, -500.0F);
503 GXColor4u8(0, 255, 255, 255);
504 GXPosition3f32(0.0F, 0.0F, 1000.0F);
505 GXColor4u8(0, 255, 255, 255);
506
507 GXPosition3f32(500.0F, -500.0F, -500.0F);
508 GXColor4u8(0, 255, 255, 255);
509 GXPosition3f32(0.0F, 0.0F, 1000.0F);
510 GXColor4u8(0, 255, 255, 255);
511
512 GXPosition3f32(-500.0F, 500.0F, -500.0F);
513 GXColor4u8(0, 255, 255, 255);
514 GXPosition3f32(0.0F, 0.0F, 1000.0F);
515 GXColor4u8(0, 255, 255, 255);
516
517 GXPosition3f32(-500.0F, -500.0F, -500.0F);
518 GXColor4u8(0, 255, 255, 255);
519 GXPosition3f32(0.0F, 0.0F, 1000.0F);
520 GXColor4u8(0, 255, 255, 255);
521 GXEnd();
522 }
523
524 /*---------------------------------------------------------------------------*
525 Name: SetCamera
526
527 Description: Sets view matrix and loads projection matrix into hardware
528
529 Arguments: cam : pointer to the MyCameraObj structure
530
531 Returns: none
532 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)533 static void SetCamera( MyCameraObj* cam )
534 {
535 MTXLookAt(
536 cam->view,
537 &cam->cfg.location,
538 &cam->cfg.up,
539 &cam->cfg.target );
540
541 MTXFrustum(
542 cam->proj,
543 cam->cfg.top,
544 - (cam->cfg.top),
545 cam->cfg.left,
546 - (cam->cfg.left),
547 cam->cfg.znear,
548 cam->cfg.zfar );
549 GXSetProjection(cam->proj, GX_PERSPECTIVE);
550 }
551
552 /*---------------------------------------------------------------------------*
553 Name: SetLight
554
555 Description: Sets up lights and lighting channel parameters
556
557 Arguments: light : pointer to a MyLightObj structure
558 view : view matrix
559
560 Returns: none
561 *---------------------------------------------------------------------------*/
SetLight(MyLightObj * light,Mtx view)562 static void SetLight( MyLightObj* light, Mtx view )
563 {
564 Vec lpos;
565 f32 theta, phi;
566
567 // Light Position
568 theta = (f32)light->theta * PI / 180.0F;
569 phi = (f32)light->phi * PI / 180.0F;
570 lpos.x = 1000.0F * cosf(phi) * sinf(theta);
571 lpos.y = 1000.0F * sinf(phi);
572 lpos.z = 1000.0F * cosf(phi) * cosf(theta);
573
574 // Convert light position into view space
575 MTXMultVec(view, &lpos, &lpos);
576
577 GXInitLightPos(&light->lobj, lpos.x, lpos.y, lpos.z);
578 GXInitLightColor(&light->lobj, light->colorEnv.lightColor);
579 GXLoadLightObjImm(&light->lobj, GX_LIGHT0);
580
581 // Lighting channel
582 GXSetChanCtrl(
583 GX_COLOR0A0,
584 GX_ENABLE, // enable channel
585 GX_SRC_REG, // amb source
586 GX_SRC_REG, // mat source
587 GX_LIGHT0, // light mask
588 GX_DF_CLAMP, // diffuse function
589 GX_AF_NONE);
590 // set up ambient color
591 GXSetChanAmbColor(GX_COLOR0A0, light->colorEnv.ambColor);
592 // set up material color
593 GXSetChanMatColor(GX_COLOR0A0, light->colorEnv.matColor);
594
595 }
596
597 /*---------------------------------------------------------------------------*
598 Name: DisableLight
599
600 Description: Disables lighting
601
602 Arguments: none
603
604 Returns: none
605 *---------------------------------------------------------------------------*/
DisableLight(void)606 static void DisableLight( void )
607 {
608 GXSetChanCtrl(
609 GX_COLOR0A0,
610 GX_DISABLE, // disable channel
611 GX_SRC_VTX, // amb source
612 GX_SRC_VTX, // mat source
613 GX_LIGHT0, // light mask
614 GX_DF_NONE, // diffuse function
615 GX_AF_NONE);
616 }
617
618 /*---------------------------------------------------------------------------*
619 Name: SetTexGenMtx0
620
621 Description: Calculate and set texture coord generation matrix
622 for drawing pseudo outline.
623
624 Arguments: sc : a pointer to MySceneCtrlObj structure
625
626 Returns: none
627 *---------------------------------------------------------------------------*/
SetTexGenMtx0(MySceneCtrlObj * sc)628 static void SetTexGenMtx0( MySceneCtrlObj* sc )
629 {
630 Mtx mt, ms;
631 f32 scale;
632
633 // Project object normals from side view
634 MTXRotDeg(mt, 'Y', -90);
635 MTXConcat(mt, sc->cam.view, mt);
636 MTXConcat(mt, sc->modelCtrl, mt);
637 MTXInverse(mt, ms);
638 MTXTranspose(ms, mt);
639
640 // Scaling and bias
641 scale = 0.5F - 0.25F * sc->tune[sc->mode];
642 MTXScale(ms, scale, 0.5F, 1.0F);
643 MTXConcat(ms, mt, mt);
644 MTXTrans(ms, 0.5F, 0.5F, 0.0F);
645 MTXConcat(ms, mt, mt);
646
647 // Load into the hardware
648 GXLoadTexMtxImm(mt, GX_TEXMTX0, GX_MTX2x4);
649 }
650
651 /*---------------------------------------------------------------------------*
652 Name: SetTexGenMtx1
653
654 Description: Calculate and set texture coord generation matrix
655 for specular highlight (1D lookup version).
656
657 Arguments: sc : a pointer to MySceneCtrlObj structure
658
659 Returns: none
660 *---------------------------------------------------------------------------*/
SetTexGenMtx1(MySceneCtrlObj * sc)661 static void SetTexGenMtx1( MySceneCtrlObj* sc )
662 {
663 Mtx mt, ms;
664 f32 theta, phi, scale;
665 Vec vview = { 0.0F, 0.0F, -1.0F };
666 Vec vlight, vhalf;
667
668 // Calculate light direction
669 theta = sc->light.theta * PI / 180.0F;
670 phi = sc->light.phi * PI / 180.0F;
671 vlight.x = - cosf(phi) * sinf(theta);
672 vlight.y = - sinf(phi);
673 vlight.z = - cosf(phi) * cosf(theta);
674
675 // Convert light direction into view space
676 MTXMultVecSR(sc->cam.view, &vlight, &vlight);
677
678 // Calculate the half angle
679 VECHalfAngle(&vlight, &vview, &vhalf);
680
681 // Modelview translation
682 MTXConcat(sc->cam.view, sc->modelCtrl, mt);
683 MTXInverse(mt, ms);
684 MTXTranspose(ms, mt);
685
686 // Make a matrix which generates s-coord by half angle.
687 // actually generated coord is 1D
688 MTXIdentity(ms);
689 MTXRowCol(ms, 0, 0) = vhalf.x;
690 MTXRowCol(ms, 0, 1) = vhalf.y;
691 MTXRowCol(ms, 0, 2) = vhalf.z;
692 MTXConcat(ms, mt, mt);
693
694 // Scaling and bias
695 scale = 14.0F + 20.0F * sc->tune[sc->mode];
696 MTXScale(ms, scale, 1.0F, 1.0F);
697 MTXConcat(ms, mt, mt);
698 MTXTrans(ms, 1.0F - scale, 0.0F, 0.0F);
699 MTXConcat(ms, mt, mt);
700
701 // Load into the hardware
702 GXLoadTexMtxImm(mt, GX_TEXMTX0, GX_MTX2x4);
703 }
704
705 /*---------------------------------------------------------------------------*
706 Name: SetTexGenMtx2
707
708 Description: Calculate and set texture coord generation matrix
709 for specular highlight (2D lookup version).
710
711 Arguments: sc : a pointer to MySceneCtrlObj structure
712
713 Returns: none
714 *---------------------------------------------------------------------------*/
SetTexGenMtx2(MySceneCtrlObj * sc)715 static void SetTexGenMtx2( MySceneCtrlObj* sc )
716 {
717 Mtx mt, mv, ms;
718 f32 theta, phi, scale, dotp, r;
719 Vec vlight, vhalf, vaxis;
720 Vec vview = { 0.0F, 0.0F, 1.0F };
721
722 // Calculate light direction
723 theta = sc->light.theta * PI / 180.0F;
724 phi = sc->light.phi * PI / 180.0F;
725 vlight.x = cosf(phi) * sinf(theta);
726 vlight.y = sinf(phi);
727 vlight.z = cosf(phi) * cosf(theta);
728
729 // Convert light direction into view space
730 MTXMultVecSR(sc->cam.view, &vlight, &vlight);
731
732 // Calculate the half angle
733 dotp = VECDotProduct(&vlight, &vview);
734 if ( dotp == -1.0F )
735 {
736 // Singular point ( vview + vlight = 0 )
737 MTXScale(mt, 0.0F, 0.0F, 0.0F); // zero matrix
738
739 GXLoadTexMtxImm(mt, GX_TEXMTX0, GX_MTX2x4);
740 return;
741 }
742 VECHalfAngle(&vlight, &vview, &vhalf);
743 // The obtained half-angle vector directs an opposite side
744 vhalf.x = -vhalf.x;
745 vhalf.y = -vhalf.y;
746 vhalf.z = -vhalf.z;
747
748 // Modelview translation
749 MTXConcat(sc->cam.view, sc->modelCtrl, mv);
750 MTXInverse(mv, ms);
751 MTXTranspose(ms, mv);
752
753 // Rotation
754 if ( dotp == 1.0F )
755 {
756 MTXIdentity(ms);
757 }
758 else
759 {
760 VECCrossProduct(&vhalf, &vview, &vaxis); // rotation axis
761 r = acosf(VECDotProduct(&vview, &vhalf)); // rotation amounts
762 MTXRotAxisRad(ms, &vaxis, r);
763 }
764 MTXConcat(ms, mv, mt);
765
766 // Scaling and bias
767 scale = 2.0F * sc->tune[sc->mode] + 1.5F;
768 MTXScale(ms, scale, scale, 1.0F);
769 MTXConcat(ms, mt, mt);
770 MTXTrans(ms, 0.5F, 0.5F, 0.0F);
771 MTXConcat(ms, mt, mt);
772
773 // Load into the hardware
774 GXLoadTexMtxImm(mt, GX_TEXMTX0, GX_MTX2x4);
775 }
776
777 /*---------------------------------------------------------------------------*
778 Name: PrintIntro
779
780 Description: Prints the directions on how to use this demo.
781
782 Arguments: none
783
784 Returns: none
785 *---------------------------------------------------------------------------*/
PrintIntro(void)786 static void PrintIntro( void )
787 {
788 OSReport("\n\n");
789 OSReport("**********************************************\n");
790 OSReport("tg-light-fx: some applications using texgen\n");
791 OSReport(" from normals\n");
792 OSReport("**********************************************\n");
793 OSReport("to quit hit the start button\n");
794 OSReport("\n");
795 OSReport("Main stick : Move Light Position\n");
796 OSReport("Sub stick : Rotate the Moddel\n");
797 OSReport("L/R Triggers : Tune parameter\n");
798 OSReport("A Button : Change texgen mode\n");
799 OSReport("B Button : Hide light direction mark\n");
800 OSReport("**********************************************\n");
801 }
802
803 /*============================================================================*/
804