1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tf-tg-mtx.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 ( void );
24 static void DrawInit ( void );
25 static void DrawTick ( void );
26
27 static void AnimTick ( void );
28
29 static void DrawSmoothCube ( float tx, float ty );
30 static void SendVertex ( u16 posIndex, u16 texCoordIndex );
31
32 static void SetTexGenMethod ( GXTexMtx mtxIdx );
33
34 static void SetNoTexGenMtx ( void );
35 static void SetProjectionTexGenMtx ( void );
36 static void SetTexCoordTexGenMtx ( void );
37 static void SetReflectionTexGenMtx ( void );
38
39 #define SIDE 35
40 #define NORM (sqrt(3.0))/3.0
41
42 /*---------------------------------------------------------------------------*
43 Global variables
44 *---------------------------------------------------------------------------*/
45 Mtx v;
46 u32 rot;
47 u32 rot2;
48 float trans;
49
50 u8 CurrentControl;
51 u8 DoRotation = 1;
52
53 GXTexObj to1, to2;
54
55 float FloatVert[] ATTRIBUTE_ALIGN(32) =
56 { -SIDE, SIDE, -SIDE,
57 -SIDE, SIDE, SIDE,
58 -SIDE, -SIDE, SIDE,
59 -SIDE, -SIDE, -SIDE,
60 SIDE, SIDE, -SIDE,
61 SIDE, -SIDE, -SIDE,
62 SIDE, -SIDE, SIDE,
63 SIDE, SIDE, SIDE
64 };
65
66 float FloatNorm[] ATTRIBUTE_ALIGN(32) =
67 { -1, 1, -1,
68 -1, 1, 1,
69 -1, -1, 1,
70 -1, -1, -1,
71 1, 1, -1,
72 1, -1, -1,
73 1, -1, 1,
74 1, 1, 1
75 };
76
77 float FloatTex[] ATTRIBUTE_ALIGN(32) =
78 { 0.0F, 0.0F,
79 1.0F, 0.0F,
80 1.0F, 1.0F,
81 0.0F, 1.0F
82 };
83 /*---------------------------------------------------------------------------*
84 Application main loop
85 *---------------------------------------------------------------------------*/
main(void)86 void main ( void )
87 {
88 DEMOInit(NULL);
89
90 DrawInit(); // Define my vertex formats and set array pointers.
91
92 DEMOPadRead(); // Read the joystick for this frame
93
94 // While the quit button is not pressed
95 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
96 {
97 DEMOPadRead(); // Read the joystick for this frame
98
99 // Do animation based on input
100 AnimTick();
101 DEMOBeforeRender();
102
103 DrawTick(); // Draw the model.
104
105 DEMODoneRender();
106 }
107
108 OSHalt("End of test");
109 }
110
111 /*---------------------------------------------------------------------------*
112 Functions
113 *---------------------------------------------------------------------------*/
114
115
116 /*---------------------------------------------------------------------------*
117 Name: CameraInit
118
119 Description: Initialize the projection matrix and load into hardware.
120
121 Arguments: v view matrix to be passed to ViewInit
122 cameraLocScale scale for the camera's distance from the
123 object - to be passed to ViewInit
124
125 Returns: none
126 *---------------------------------------------------------------------------*/
CameraInit(void)127 static void CameraInit ( void )
128 {
129 Mtx44 p;
130 Vec camPt = {0.0F, 0.0F, 650.0F};
131 Vec up = {0.0F, 1.0F, 0.0F};
132 Vec origin = {0.0F, 0.0F, 0.0F};
133
134 MTXFrustum(p, 240, -240, -320, 320, 500, 2000);
135
136 GXSetProjection(p, GX_PERSPECTIVE);
137
138 MTXLookAt(v, &camPt, &up, &origin);
139 }
140
141 /*---------------------------------------------------------------------------*
142 Name: DrawInit
143
144 Description: Calls the correct initialization function for the current
145 model.
146
147 Arguments: none
148
149 Returns: none
150 *---------------------------------------------------------------------------*/
DrawInit(void)151 static void DrawInit( void )
152 {
153 TPLPalettePtr tpl = 0;
154 u32 i;
155
156 CameraInit(); // Initialize the camera.
157
158 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
159 GXSetVtxDesc(GX_VA_TEX0, GX_INDEX16);
160 GXSetArray(GX_VA_TEX0, FloatTex, 8);
161
162 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
163 GXSetVtxDesc(GX_VA_NRM, GX_INDEX16);
164 GXSetArray(GX_VA_NRM, FloatNorm, 12);
165
166 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
167 GXSetVtxDesc (GX_VA_POS, GX_INDEX16);
168 GXSetArray(GX_VA_POS, FloatVert, 12);
169
170 TPLGetPalette(&tpl, "gxTests/tf-02.tpl");
171
172 TPLGetGXTexObjFromPalette(tpl, &to1, 0);
173 TPLGetGXTexObjFromPalette(tpl, &to2, 1);
174
175 GXLoadTexObj(&to1, GX_TEXMAP0);
176
177 GXSetNumChans(0);
178 GXSetNumTexGens(1);
179 GXSetNumTevStages(1);
180 GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
181 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
182
183 for(i = 0; i < 24; i++)
184 {
185 FloatNorm[i] *= NORM;
186 }
187
188 OSReport("\n\nNo TexGen\n\n");
189 }
190
191 /*---------------------------------------------------------------------------*
192 Name: DrawTick
193
194 Description: Draw the current model once.
195
196 Arguments: v view matrix
197 m model matrix
198
199 Returns: none
200 *---------------------------------------------------------------------------*/
DrawTick(void)201 static void DrawTick( void )
202 {
203
204 switch(CurrentControl)
205 {
206 case 0:
207 SetNoTexGenMtx();
208 break;
209 case 1:
210 SetProjectionTexGenMtx();
211 break;
212 case 2:
213 SetTexCoordTexGenMtx();
214 break;
215 case 3:
216 SetReflectionTexGenMtx();
217 break;
218 }
219
220 SetTexGenMethod(GX_TEXMTX0);
221 DrawSmoothCube(-240, 150);
222
223 SetTexGenMethod(GX_TEXMTX1);
224 DrawSmoothCube(-80, 150);
225
226 SetTexGenMethod(GX_TEXMTX2);
227 DrawSmoothCube(80, 150);
228
229 SetTexGenMethod(GX_TEXMTX3);
230 DrawSmoothCube(240, 150);
231
232 SetTexGenMethod(GX_TEXMTX4);
233 DrawSmoothCube(-240, -150);
234
235 SetTexGenMethod(GX_TEXMTX5);
236 DrawSmoothCube(-80, -150);
237
238 SetTexGenMethod(GX_TEXMTX6);
239 DrawSmoothCube(80, -150);
240
241 SetTexGenMethod(GX_TEXMTX7);
242 DrawSmoothCube(240, -150);
243
244 SetTexGenMethod(GX_TEXMTX8);
245 DrawSmoothCube(-160, 0);
246
247 SetTexGenMethod(GX_TEXMTX9);
248 DrawSmoothCube(160, 0);
249
250 // Don't draw cube with identity matrix for projected or
251 // normal texcoords since this results in Q=0 on 4 cube faces
252 if (CurrentControl != 1 && CurrentControl != 3)
253 {
254 SetTexGenMethod(GX_IDENTITY);
255 DrawSmoothCube(0, 0);
256 }
257 }
258
259 /*---------------------------------------------------------------------------*
260 Name: AnimTick
261
262 Description: Animates the camera and object based on the joystick's
263 state.
264
265 Arguments: none
266
267 Returns: none
268 *---------------------------------------------------------------------------*/
AnimTick(void)269 static void AnimTick ( void )
270 {
271 u16 buttons = DEMOPadGetButtonDown(0);
272
273 if(buttons & PAD_BUTTON_X)
274 {
275 CurrentControl ++;
276 if(CurrentControl > 3)
277 CurrentControl = 0;
278
279 switch(CurrentControl)
280 {
281 case 0:
282 GXLoadTexObj(&to1, GX_TEXMAP0);
283 OSReport("\n\nNo TexGen\n\n");
284 break;
285
286 case 1:
287 OSReport("\n\nTexture Projection (position * 3x4 matrix)\n\n");
288 break;
289
290 case 2:
291 OSReport("\n\nTexture rotation and translation (TexCoord * 2x4 matrix)\n\n");
292 break;
293
294 case 3:
295 GXLoadTexObj(&to2, GX_TEXMAP0);
296 OSReport("\n\nReflection mapping (normal * 3x4 matrix)\n\n");
297 break;
298 }
299 }
300
301 if(buttons & PAD_BUTTON_B)
302 {
303 if(DoRotation)
304 DoRotation = 0;
305 else
306 DoRotation = 1;
307 }
308
309 if(DoRotation)
310 {
311 rot ++;
312 if(rot > 1439)
313 rot = 0;
314 }
315
316 rot2 ++;
317 if(rot2 > 1439)
318 rot2 = 0;
319
320 trans += .01F;
321 if(trans > 2.0F)
322 trans = 0.0F;
323 }
324
325 /*---------------------------------------------------------------------------*/
DrawSmoothCube(float tx,float ty)326 static void DrawSmoothCube ( float tx, float ty )
327 {
328 Mtx ry, rz, mv, t;
329
330 MTXRotDeg(ry, 'Y', (float)rot);
331 MTXRotDeg(rz, 'Z', (float)rot);
332 MTXTrans(t, tx, ty, 0);
333
334 MTXConcat(rz, ry, mv);
335 MTXConcat(t, mv, mv);
336 MTXConcat(v, mv, mv);
337 GXLoadPosMtxImm(mv, GX_PNMTX0);
338 MTXInverse(mv, mv);
339 MTXTranspose(mv, mv);
340 GXLoadNrmMtxImm(mv, GX_PNMTX0);
341
342 GXBegin(GX_QUADS, GX_VTXFMT0, 4*6);
343
344 SendVertex(0, 0);
345 SendVertex(1, 1);
346 SendVertex(2, 2);
347 SendVertex(3, 3);
348
349 SendVertex(4, 0);
350 SendVertex(5, 1);
351 SendVertex(6, 2);
352 SendVertex(7, 3);
353
354 SendVertex(2, 0);
355 SendVertex(6, 1);
356 SendVertex(5, 2);
357 SendVertex(3, 3);
358
359 SendVertex(1, 0);
360 SendVertex(0, 1);
361 SendVertex(4, 2);
362 SendVertex(7, 3);
363
364 SendVertex(5, 0);
365 SendVertex(4, 1);
366 SendVertex(0, 2);
367 SendVertex(3, 3);
368
369 SendVertex(6, 0);
370 SendVertex(2, 1);
371 SendVertex(1, 2);
372 SendVertex(7, 3);
373
374 GXEnd();
375 }
376
377 /*---------------------------------------------------------------------------*/
SendVertex(u16 posIndex,u16 texCoordIndex)378 static void SendVertex ( u16 posIndex, u16 texCoordIndex )
379 {
380 GXPosition1x16(posIndex);
381 GXNormal1x16(posIndex);
382 GXTexCoord1x16(texCoordIndex);
383 }
384
385 /*---------------------------------------------------------------------------*/
SetTexGenMethod(GXTexMtx mtxIdx)386 static void SetTexGenMethod ( GXTexMtx mtxIdx )
387 {
388 switch(CurrentControl)
389 {
390 case 0:
391 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, mtxIdx);
392 break;
393
394 case 1:
395 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_POS, mtxIdx);
396 break;
397
398 case 2:
399 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, mtxIdx);
400 break;
401
402 case 3:
403 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_NRM, mtxIdx);
404 break;
405
406 }
407 }
408
409 /*---------------------------------------------------------------------------*/
SetNoTexGenMtx(void)410 static void SetNoTexGenMtx ( void )
411 {
412 Mtx m;
413
414 MTXIdentity(m);
415
416 GXLoadTexMtxImm(m, GX_TEXMTX0, GX_MTX2x4);
417 GXLoadTexMtxImm(m, GX_TEXMTX1, GX_MTX2x4);
418 GXLoadTexMtxImm(m, GX_TEXMTX2, GX_MTX2x4);
419 GXLoadTexMtxImm(m, GX_TEXMTX3, GX_MTX2x4);
420 GXLoadTexMtxImm(m, GX_TEXMTX4, GX_MTX2x4);
421 GXLoadTexMtxImm(m, GX_TEXMTX5, GX_MTX2x4);
422 GXLoadTexMtxImm(m, GX_TEXMTX6, GX_MTX2x4);
423 GXLoadTexMtxImm(m, GX_TEXMTX7, GX_MTX2x4);
424 GXLoadTexMtxImm(m, GX_TEXMTX8, GX_MTX2x4);
425 GXLoadTexMtxImm(m, GX_TEXMTX9, GX_MTX2x4);
426 }
427
428 /*---------------------------------------------------------------------------*/
SetProjectionTexGenMtx(void)429 static void SetProjectionTexGenMtx ( void )
430 {
431 //assume all lights are at the origin pointing down the -z axis
432
433 Mtx proj;
434 Mtx ry, rz, mv;//, t;
435
436 MTXRotDeg(ry, 'Y', (float)rot);
437 MTXRotDeg(rz, 'Z', (float)rot);
438
439 MTXConcat(rz, ry, mv);
440 MTXConcat(v, mv, mv);
441
442 MTXLightFrustum(proj, -5, 5, -5, 5, 50, 0.5F, 0.5F, 0.5F, 0.5F);
443 MTXConcat(proj, mv, proj);
444 GXLoadTexMtxImm(proj, GX_TEXMTX0, GX_MTX3x4);
445
446 MTXLightFrustum(proj, -5, 5, -5, 5, 20, 0.5F, 0.5F, 0.5F, 0.5F);
447 MTXConcat(proj, mv, proj);
448 GXLoadTexMtxImm(proj, GX_TEXMTX1, GX_MTX3x4);
449
450 MTXLightFrustum(proj, -5, 5, -5, 5, 30, 0.5F, 0.5F, 0.7F, 0.3F);
451 MTXConcat(proj, mv, proj);
452 GXLoadTexMtxImm(proj, GX_TEXMTX2, GX_MTX3x4);
453
454 MTXLightFrustum(proj, -5, 5, -5, 5, 25, 1.0F, 1.0F, 0.5F, 0.5F);
455 MTXConcat(proj, mv, proj);
456 GXLoadTexMtxImm(proj, GX_TEXMTX3, GX_MTX3x4);
457
458 MTXLightFrustum(proj, -10, 10, -5, 5, 5, 0.5F, 0.5F, 0.5F, 0.5F);
459 MTXConcat(proj, mv, proj);
460 GXLoadTexMtxImm(proj, GX_TEXMTX4, GX_MTX3x4);
461
462 MTXLightFrustum(proj, -5, 5, -20, 20, 5, 0.5F, 0.5F, 0.5F, 0.5F);
463 MTXConcat(proj, mv, proj);
464 GXLoadTexMtxImm(proj, GX_TEXMTX5, GX_MTX3x4);
465
466 MTXLightFrustum(proj, -5, 5, -20, 20, 25, 0.5F, 0.5F, 0.5F, 0.5F);
467 MTXConcat(proj, mv, proj);
468 GXLoadTexMtxImm(proj, GX_TEXMTX6, GX_MTX3x4);
469
470 MTXLightFrustum(proj, -5, 5, -20, 20, 8, 0.5F, 0.5F, 0.5F, 0.5F);
471 MTXConcat(proj, mv, proj);
472 GXLoadTexMtxImm(proj, GX_TEXMTX7, GX_MTX3x4);
473
474 MTXLightFrustum(proj, -5, 5, -20, 20, 27, 1.5F, 1.5F, 0.5F, 0.5F);
475 MTXConcat(proj, mv, proj);
476 GXLoadTexMtxImm(proj, GX_TEXMTX8, GX_MTX3x4);
477
478 MTXLightFrustum(proj, -20, 20, -20, 20, 29, 0.5F, 0.5F, 0.75F, 0.75F);
479 MTXConcat(proj, mv, proj);
480 GXLoadTexMtxImm(proj, GX_TEXMTX9, GX_MTX3x4);
481
482
483 }
484
485 /*---------------------------------------------------------------------------*/
SetTexCoordTexGenMtx(void)486 static void SetTexCoordTexGenMtx ( void )
487 {
488 Mtx rz, tx, ty, mt;
489
490 MTXRotDeg(rz, 'Z', ((float)rot2) / 4.0F);
491 MTXTrans(tx, trans, 0.0F, 0.0F);
492 MTXTrans(ty, 0.0F, trans, 0.0F);
493
494 GXLoadTexMtxImm(rz, GX_TEXMTX0, GX_MTX2x4);
495 GXLoadTexMtxImm(tx, GX_TEXMTX1, GX_MTX2x4);
496 GXLoadTexMtxImm(ty, GX_TEXMTX2, GX_MTX2x4);
497
498 MTXConcat(ty, rz, mt);
499 GXLoadTexMtxImm(mt, GX_TEXMTX3, GX_MTX2x4);
500 MTXConcat(tx, rz, mt);
501 GXLoadTexMtxImm(mt, GX_TEXMTX4, GX_MTX2x4);
502 MTXConcat(ty, tx, mt);
503 GXLoadTexMtxImm(mt, GX_TEXMTX5, GX_MTX2x4);
504 MTXConcat(tx, rz, mt);
505 MTXConcat(ty, mt, mt);
506 GXLoadTexMtxImm(mt, GX_TEXMTX6, GX_MTX2x4);
507
508 MTXTrans(tx, trans/2.0F, 0.0F, 0.0F);
509 MTXTrans(ty, 0.0F, trans * 2.0F, 0.0F);
510
511 GXLoadTexMtxImm(tx, GX_TEXMTX7, GX_MTX2x4);
512 GXLoadTexMtxImm(ty, GX_TEXMTX8, GX_MTX2x4);
513 MTXConcat(tx, ty, mt);
514 GXLoadTexMtxImm(mt, GX_TEXMTX9, GX_MTX2x4);
515 }
516
517 /*---------------------------------------------------------------------------*/
SetReflectionTexGenMtx(void)518 static void SetReflectionTexGenMtx ( void )
519 {
520 Mtx ry, rz, mv, t, s;
521
522 MTXRotDeg(ry, 'Y', (float)rot);
523 MTXRotDeg(rz, 'Z', (float)rot);
524 MTXScale(s, -0.5F, -0.5F, 0.0F);
525 MTXTrans(t, 0.5F, 0.5F, 1.0F);
526
527 MTXConcat(rz, ry, mv);
528 MTXInverse(mv, mv);
529 MTXTranspose(mv, mv);
530 MTXConcat(s, mv, mv);
531 MTXConcat(t, mv, mv);
532
533 GXLoadTexMtxImm(mv, GX_TEXMTX0, GX_MTX3x4);
534 GXLoadTexMtxImm(mv, GX_TEXMTX1, GX_MTX3x4);
535 GXLoadTexMtxImm(mv, GX_TEXMTX2, GX_MTX3x4);
536 GXLoadTexMtxImm(mv, GX_TEXMTX3, GX_MTX3x4);
537 GXLoadTexMtxImm(mv, GX_TEXMTX4, GX_MTX3x4);
538 GXLoadTexMtxImm(mv, GX_TEXMTX5, GX_MTX3x4);
539 GXLoadTexMtxImm(mv, GX_TEXMTX6, GX_MTX3x4);
540 GXLoadTexMtxImm(mv, GX_TEXMTX7, GX_MTX3x4);
541 GXLoadTexMtxImm(mv, GX_TEXMTX8, GX_MTX3x4);
542 GXLoadTexMtxImm(mv, GX_TEXMTX9, GX_MTX3x4);
543 }
544
545 /*===========================================================================*/
546