1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tg-project.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 #include <demo.h>
15 #include <math.h>
16
17 /*---------------------------------------------------------------------------*
18 Forward references
19 *---------------------------------------------------------------------------*/
20
21 void main ( void );
22
23 static void CameraInit ( Mtx v );
24 static void ViewInit ( Mtx v );
25 static void DrawInit ( void );
26 static void DrawTick ( void );
27 static void VertexLightInit ( void );
28
29 static void MakeModelMtx ( Vec xAxis, Vec yAxis, Vec zAxis, Mtx m );
30 static void AnimTick ( Mtx v );
31
32 static void DrawFrust ( void );
33
34 static void TextureLightInit( Mtx rot );
35
36 /*---------------------------------------------------------------------------*
37 Global variables
38 *---------------------------------------------------------------------------*/
39 // Vectors to keep track of the camera's coordinate system orientation
40 Vec CamX = {1.0F, 0.0F, 0.0F};
41 Vec CamY = {0.0F, 1.0F, 0.0F};
42 Vec CamZ = {0.0F, 0.0F, 1.0F};
43
44 Vec LightY = {0.0F, 1.0F, 0.0F};
45 Vec LightX = {1.0F, 0.0F, 0.0F};
46 Vec LightZ = {0.0F, 0.0F, 1.0F};
47
48 Mtx v, m;
49
50 // Scale for the camera's distance from the object
51 float CameraLocScale = 10;
52
53 Mtx lv;
54
55 float xmin = -.5F, xmax = .5F;
56 float ymin = -.5F, ymax = .5F;
57 float nnear = 5.0F;
58 float ffar = 100.0F;
59 float distance = -45.0F;
60
61 u8 CurrentControl = 0;
62 u8 CurrentModel = 0;
63 u8 CurrentTexture = 0;
64 GXTevMode CurrentTevMode = GX_DECAL;
65
66 TPLPalettePtr tpl = 0;
67
68 /*---------------------------------------------------------------------------*
69 Application main loop
70 *---------------------------------------------------------------------------*/
main(void)71 void main ( void )
72 {
73 DEMOInit(NULL);
74
75 DrawInit(); // Define my vertex formats and set array pointers.
76
77 VertexLightInit();
78
79 DEMOPadRead(); // Read the joystick for this frame
80
81 // While the quit button is not pressed
82 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
83 {
84 DEMOPadRead(); // Read the joystick for this frame
85
86 // Do animation based on input
87 AnimTick(v);
88 DEMOBeforeRender();
89
90 DrawTick(); // Draw the model.
91
92 DEMODoneRender();
93 }
94
95 OSHalt("End of demo");
96 }
97
98 /*---------------------------------------------------------------------------*
99 Functions
100 *---------------------------------------------------------------------------*/
101
102
103 /*---------------------------------------------------------------------------*
104 Name: CameraInit
105
106 Description: Initialize the projection matrix and load into hardware.
107
108 Arguments: v view matrix to be passed to ViewInit
109 cameraLocScale scale for the camera's distance from the
110 object - to be passed to ViewInit
111
112 Returns: none
113 *---------------------------------------------------------------------------*/
CameraInit(Mtx v)114 static void CameraInit ( Mtx v )
115 {
116 Mtx44 p;
117
118 MTXFrustum(p, .24F * CameraLocScale,-.24F * CameraLocScale,
119 -.32F * CameraLocScale, .32F * CameraLocScale,
120 .5F * CameraLocScale, 20.0F * CameraLocScale);
121
122 GXSetProjection(p, GX_PERSPECTIVE);
123
124 ViewInit(v);
125 }
126
127 /*---------------------------------------------------------------------------*
128 Name: ViewInit
129
130 Description: Initialize the view matrix.
131
132 Arguments: v view matrix
133 cameraLocScale value used to determine camera's distance
134 from the object
135
136 Returns: none
137 *---------------------------------------------------------------------------*/
ViewInit(Mtx v)138 static void ViewInit ( Mtx v )
139 {
140 Vec camPt = {0.0F, 0.0F, 8.0F};
141 Vec up = {0.0F, 1.0F, 0.0F};
142 Vec origin = {0.0F, 0.0F, 0.0F};
143
144 camPt.x *= CameraLocScale; // Scale camPt by cameraLocScale
145 camPt.y *= CameraLocScale;
146 camPt.z *= CameraLocScale;
147
148 MTXLookAt(v, &camPt, &up, &origin);
149 }
150
151
152 /*---------------------------------------------------------------------------*
153 Name: DrawInit
154
155 Description: Calls the correct initialization function for the current
156 model.
157
158 Arguments: none
159
160 Returns: none
161 *---------------------------------------------------------------------------*/
DrawInit(void)162 static void DrawInit( void )
163 {
164 GXTexObj to;
165 TPLDescriptorPtr tdp;
166
167 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
168 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
169
170 GXClearVtxDesc();
171 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
172 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
173
174 CameraInit(v); // Re-Initialize the camera.
175
176 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_POS, GX_TEXMTX0);
177 GXSetNumChans(1);
178
179 TPLGetPalette(&tpl, "gxTests/tg-01.tpl");
180 tdp = TPLGet(tpl, 0);
181
182 GXInitTexObj(&to,
183 tdp->textureHeader->data,
184 tdp->textureHeader->width,
185 tdp->textureHeader->height,
186 (GXTexFmt)tdp->textureHeader->format,
187 GX_CLAMP,
188 GX_CLAMP,
189 GX_FALSE);
190
191 GXInitTexObjLOD(&to,
192 tdp->textureHeader->minFilter,
193 tdp->textureHeader->magFilter,
194 tdp->textureHeader->minLOD,
195 tdp->textureHeader->maxLOD,
196 tdp->textureHeader->LODBias,
197 GX_FALSE,
198 tdp->textureHeader->edgeLODEnable,
199 GX_ANISO_1);
200
201 GXLoadTexObj(&to, GX_TEXMAP0);
202
203 MTXScale(m, 20.0F, 20.0F, 20.0F);
204 }
205
206 /*---------------------------------------------------------------------------*
207 Name: DrawTick
208
209 Description: Draw the current model once.
210
211 Arguments: v view matrix
212 m model matrix
213
214 Returns: none
215 *---------------------------------------------------------------------------*/
DrawTick(void)216 static void DrawTick( void )
217 {
218 Mtx mv;
219
220 GXSetTevOp(GX_TEVSTAGE0, CurrentTevMode);
221 GXSetNumTexGens(1);
222 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
223
224 GXSetChanCtrl(
225 GX_COLOR0,
226 TRUE, // enable channel
227 GX_SRC_REG, // amb source
228 GX_SRC_REG, // mat source
229 GX_LIGHT0, // light mask
230 GX_DF_CLAMP, // diffuse function
231 GX_AF_NONE);
232
233 MTXConcat(v, m, mv);
234 GXLoadPosMtxImm(mv, GX_PNMTX0);
235 MTXInverse(mv, mv);
236 MTXTranspose(mv, mv);
237 GXLoadNrmMtxImm(mv, GX_PNMTX0);
238 switch(CurrentModel)
239 {
240 case 0:
241 GXDrawCube();
242 break;
243 case 1:
244 GXDrawDodeca();
245 break;
246 case 2:
247 GXDrawCylinder(20);
248 break;
249 case 3:
250 GXDrawSphere1(3);
251 break;
252 case 4:
253 GXDrawOctahedron();
254 break;
255 case 5:
256 GXDrawIcosahedron();
257 break;
258 case 6:
259 GXDrawTorus(.3F, 10, 50);
260 break;
261 }
262
263 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
264 GXSetNumTexGens(0);
265 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
266 GXSetChanCtrl(
267 GX_COLOR0,
268 FALSE, // disable channel
269 GX_SRC_VTX, // amb source
270 GX_SRC_VTX, // mat source
271 GX_LIGHT0, // light mask
272 GX_DF_CLAMP, // diffuse function
273 GX_AF_NONE);
274 DrawFrust();
275 }
276
VertexLightInit(void)277 static void VertexLightInit ( void )
278 {
279 GXLightObj MyLight;
280 GXColor color = {255, 255, 255, 255};
281
282 GXInitLightPos(&MyLight, 0.0F, 0.0F, 0.0F);
283 GXInitLightColor(&MyLight, color);
284 GXLoadLightObjImm(&MyLight, GX_LIGHT0);
285
286 color.g = color.b = 0;
287 GXSetChanMatColor(GX_COLOR0, color);
288 }
289
290 /*---------------------------------------------------------------------------*
291 Name: MakeModelMtx
292
293 Description: computes a model matrix from 3 vectors representing an
294 object's coordinate system.
295
296 Arguments: xAxis vector for the object's X axis
297 yAxis vector for the object's Y axis
298 zAxis vector for the object's Z axis
299
300 Returns: none
301 *---------------------------------------------------------------------------*/
MakeModelMtx(Vec xAxis,Vec yAxis,Vec zAxis,Mtx m)302 static void MakeModelMtx ( Vec xAxis, Vec yAxis, Vec zAxis, Mtx m )
303 {
304 VECNormalize(&xAxis,&xAxis);
305 VECNormalize(&yAxis,&yAxis);
306 VECNormalize(&zAxis, &zAxis);
307
308 m[0][0] = xAxis.x;
309 m[1][0] = xAxis.y;
310 m[2][0] = xAxis.z;
311
312 m[0][1] = yAxis.x;
313 m[1][1] = yAxis.y;
314 m[2][1] = yAxis.z;
315
316 m[0][2] = zAxis.x;
317 m[1][2] = zAxis.y;
318 m[2][2] = zAxis.z;
319
320 m[0][3] = 0.0F;
321 m[1][3] = 0.0F;
322 m[2][3] = 0.0F;
323 }
324
325 /*---------------------------------------------------------------------------*
326 Name: AnimTick
327
328 Description: Animates the camera and object based on the joystick's
329 state.
330
331 Arguments: m model matrix
332 v view matrix
333 cameraLocScale scale value for the camera's distance
334 to the object.
335
336 Returns: none
337 *---------------------------------------------------------------------------*/
AnimTick(Mtx v)338 static void AnimTick ( Mtx v )
339 {
340 Mtx rot;
341 GXTexObj to;
342 TPLDescriptorPtr tdp;
343
344 u16 buttons = DEMOPadGetButton(0);
345 u16 downs = DEMOPadGetButtonDown(0);
346 s8 stickX = DEMOPadGetStickX(0);
347 s8 stickY = DEMOPadGetStickY(0);
348
349 if(downs & PAD_BUTTON_X)
350 {
351 CurrentControl ++;
352 if(CurrentControl > 4)
353 CurrentControl = 0;
354
355 switch(CurrentControl)
356 {
357 case 0:
358 OSReport("\n\nCamera Control\n\n");
359 break;
360 case 1:
361 OSReport("\n\nLight Position Control\n\n");
362 break;
363 case 2:
364 OSReport("\n\nLight Parameter Control\n\n");
365 break;
366 case 3:
367 OSReport("\n\nModel Select Control\n\n");
368 break;
369 case 4:
370 OSReport("\n\nTexture Select Control\n\n");
371 break;
372 }
373 }
374 if(CurrentControl == 0)
375 {
376 // Move camera
377 if(buttons & PAD_BUTTON_Y)
378 {
379 CameraLocScale *= .95F;
380 if(CameraLocScale < 0.001F)
381 CameraLocScale = 0.001F;
382 }
383 if(buttons & PAD_BUTTON_A)
384 CameraLocScale *= 1.05F;
385
386 // Rotate camera
387 if(stickX || stickY)
388 {
389 if(stickX)
390 {
391 if(stickX > 0)
392 MTXRotAxisDeg(rot, &CamY, 3.0F);
393 else
394 MTXRotAxisDeg(rot, &CamY, -3.0F);
395
396 MTXMultVec(rot, &CamX, &CamX);
397 MTXMultVec(rot, &CamZ, &CamZ);
398 }
399
400 if(stickY)
401 {
402 if(stickY > 0)
403 MTXRotAxisDeg(rot, &CamX, 3.0F);
404 else
405 MTXRotAxisDeg(rot, &CamX, -3.0F);
406
407 MTXMultVec(rot, &CamY, &CamY);
408 MTXMultVec(rot, &CamZ, &CamZ);
409 }
410 }
411 }
412 else if(CurrentControl == 1)
413 {
414 // Rotate light
415 if(stickX || stickY)
416 {
417 if(stickX)
418 {
419 if(stickX > 0)
420 MTXRotAxisDeg(rot, &CamY, 3.0F);
421 else
422 MTXRotAxisDeg(rot, &CamY, -3.0F);
423
424 MTXMultVec(rot, &LightX, &LightX);
425 MTXMultVec(rot, &LightY, &LightY);
426 MTXMultVec(rot, &LightZ, &LightZ);
427 }
428
429 if(stickY)
430 {
431 if(stickY > 0)
432 MTXRotAxisDeg(rot, &CamX, 3.0F);
433 else
434 MTXRotAxisDeg(rot, &CamX, -3.0F);
435
436 MTXMultVec(rot, &LightX, &LightX);
437 MTXMultVec(rot, &LightY, &LightY);
438 MTXMultVec(rot, &LightZ, &LightZ);
439 }
440 }
441 if(buttons & PAD_BUTTON_Y)
442 {
443 distance *= .95F;
444 if(distance > -0.001F)
445 distance = -0.001F;
446 }
447 if(buttons & PAD_BUTTON_A)
448 distance *= 1.05F;
449 }
450 else if(CurrentControl == 2)
451 {
452 if(stickY > 0)
453 {
454 xmax *= .95F;
455 if(xmax < 0.0001F)
456 xmax = 0.0001F;
457 ymin = -xmax;
458 ymax = xmax;
459 xmin = -xmax;
460 }
461 if(stickY < 0)
462 {
463 xmax *= 1.05F;
464 ymin = -xmax;
465 ymax = xmax;
466 xmin = -xmax;
467 }
468 }
469 else if(CurrentControl == 3)
470 {
471 if(downs & PAD_BUTTON_B)
472 {
473 CurrentModel ++;
474 if(CurrentModel > 6)
475 CurrentModel = 0;
476 }
477 }
478 else if(CurrentControl == 4)
479 {
480 if(downs & PAD_BUTTON_B)
481 {
482 CurrentTexture ++;
483 if(CurrentTexture > 1)
484 CurrentTexture = 0;
485 switch(CurrentTexture)
486 {
487 case 1:
488 CurrentTevMode = GX_MODULATE;
489 break;
490 case 0:
491 CurrentTevMode = GX_DECAL;
492 break;
493 }
494 tdp = TPLGet(tpl, CurrentTexture);
495
496 GXInitTexObj(&to,
497 tdp->textureHeader->data,
498 tdp->textureHeader->width,
499 tdp->textureHeader->height,
500 (GXTexFmt)tdp->textureHeader->format,
501 GX_CLAMP,
502 GX_CLAMP,
503 GX_FALSE);
504
505 GXInitTexObjLOD(&to,
506 tdp->textureHeader->minFilter,
507 tdp->textureHeader->magFilter,
508 tdp->textureHeader->minLOD,
509 tdp->textureHeader->maxLOD,
510 tdp->textureHeader->LODBias,
511 GX_FALSE,
512 tdp->textureHeader->edgeLODEnable,
513 GX_ANISO_1);
514
515 GXLoadTexObj(&to, GX_TEXMAP0);
516 }
517 }
518
519 MakeModelMtx(CamX, CamY, CamZ, v); // Make a new model matrix
520 MTXTranspose(v, v);
521 MTXTrans(rot, 0.0F, 0.0F, -8.0F * CameraLocScale);
522 MTXConcat(rot, v, v);
523
524 MakeModelMtx(LightX, LightY, LightZ, lv); // Make a new model matrix
525 MTXTranspose(lv, lv);
526 MTXTrans(rot, 0.0F, 0.0F, distance);
527 MTXConcat(rot, lv, lv);
528 TextureLightInit(lv);
529 MTXInverse(lv, lv);
530
531 }
532
DrawFrust(void)533 static void DrawFrust ( void )
534 {
535 float t = ffar / nnear;
536 Mtx mv;
537
538 MTXConcat(v, lv, mv);
539 GXLoadPosMtxImm(mv, GX_PNMTX0);
540
541 GXBegin(GX_LINESTRIP, GX_VTXFMT0, 17);
542
543 GXPosition3f32(xmin, ymin, -nnear); //n0
544 GXColor4u8(255, 255, 0, 255);
545
546 GXPosition3f32(xmax, ymin, -nnear); //n1
547 GXColor4u8(255, 255, 0, 255);
548
549 GXPosition3f32(xmax, ymax, -nnear); //n2
550 GXColor4u8(255, 255, 0, 255);
551
552 GXPosition3f32(xmin, ymax, -nnear); //n3
553 GXColor4u8(255, 255, 0, 255);
554
555 GXPosition3f32(xmin * t, ymax * t, -ffar); //f3
556 GXColor4u8(255, 255, 0, 255);
557
558 GXPosition3f32(xmax * t, ymax * t, -ffar); //f2
559 GXColor4u8(255, 255, 0, 255);
560
561 GXPosition3f32(xmax * t, ymin * t, -ffar); //f1
562 GXColor4u8(255, 255, 0, 255);
563
564 GXPosition3f32(xmin * t, ymin * t, -ffar); //f0
565 GXColor4u8(255, 255, 0, 255);
566
567 GXPosition3f32(xmin, ymin, -nnear); //n0
568 GXColor4u8(255, 255, 0, 255);
569
570 GXPosition3f32(xmax, ymin, -nnear); //n1
571 GXColor4u8(255, 255, 0, 255);
572
573 GXPosition3f32(xmax * t, ymin * t, -ffar); //f1
574 GXColor4u8(255, 255, 0, 255);
575
576 GXPosition3f32(xmin * t, ymin * t, -ffar); //f0
577 GXColor4u8(255, 255, 0, 255);
578
579 GXPosition3f32(xmin * t, ymax * t, -ffar); //f3
580 GXColor4u8(255, 255, 0, 255);
581
582 GXPosition3f32(xmax * t, ymax * t, -ffar); //f2
583 GXColor4u8(255, 255, 0, 255);
584
585 GXPosition3f32(xmax, ymax, -nnear); //n2
586 GXColor4u8(255, 255, 0, 255);
587
588 GXPosition3f32(xmin, ymax, -nnear); //n3
589 GXColor4u8(255, 255, 0, 255);
590
591 GXPosition3f32(xmin, ymin, -nnear); //n0
592 GXColor4u8(255, 255, 0, 255);
593
594 GXEnd();
595 }
596
TextureLightInit(Mtx rot)597 static void TextureLightInit ( Mtx rot )
598 {
599 Mtx proj;
600 Mtx mv;
601
602 MTXLightFrustum(proj, ymin, ymax, xmin, xmax, nnear,
603 0.5F, 0.5F, 0.5F, 0.5F);
604
605 MTXConcat(rot, m, mv);
606
607 MTXConcat(proj, mv, proj);
608
609 GXLoadTexMtxImm(proj, GX_TEXMTX0, GX_MTX3x4);
610 }
611
612 /*===========================================================================*/
613