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