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