1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     tf-reflect.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 #include <demo.h>
14 #include <math.h>
15 
16 /*---------------------------------------------------------------------------*
17    Macro definitions
18  *---------------------------------------------------------------------------*/
19 #define VP_ASPECT   ((float)4/(float)3)
20 
21 /*---------------------------------------------------------------------------*
22    Forward references
23  *---------------------------------------------------------------------------*/
24 void  DrawScene( void );
25 void  myDrawModel( void );
26 void  myAnimeModel( void );
27 
28 /*---------------------------------------------------------------------------*
29    Rendering parameters
30  *---------------------------------------------------------------------------*/
31 typedef struct
32 {
33     Point3d   position;
34     Point3d   target;
35     Vec       up;
36     f32       fovy;
37     f32       znear;
38     f32       zfar;
39     Mtx       viewMtx;
40 }   Camera;
41 
42 Camera  myCamera =
43 {
44     { 0.0f, -400.0f, 0.0f },   // position
45     { 0.0f,    0.0f, 0.0f },   // target
46     { 0.0f,    0.0f, 1.0f },   // upVec
47        33.3f,                   // fovy
48       128.0f,                   // near plane Z in camera coordinates
49      2048.0f,                   // far  plane Z in camera coordinates
50 };
51 
52 TPLPalettePtr   texPalette = 0;
53 GXTexObj        texObj;
54 
55 /*---------------------------------------------------------------------------*
56    Application main loop
57  *---------------------------------------------------------------------------*/
main(void)58 void  main ( void )
59 {
60     GXColor grey = {128,128,128,0};
61 
62     // initialize render settings and set clear color for first frame
63     DEMOInit( NULL );  // Defined in $(REVOLUTION_SDK_ROOT)/build/libraries/demo/src/DEMOInit.c
64 
65     OSReport("\n\n");
66     OSReport("**********************************************\n");
67     OSReport("tf-reflect: Reflection mapping demo\n");
68     OSReport("**********************************************\n");
69     OSReport("To quit hit the start button.\n");
70     OSReport("\n");
71     OSReport("Main stick rotates model.\n");
72     OSReport("A/B buttons control camera zoom.\n");
73     OSReport("L/R triggers control pipe bend.\n");
74     OSReport("**********************************************\n");
75     OSReport("\n\n");
76 
77     GXInvalidateTexAll( );
78     GXSetCopyClear( grey, GX_MAX_Z24 );
79 
80     // Image on fish eye camera view
81     TPLGetPalette( &texPalette, "gxTests/tf-02.tpl" );
82     TPLGetGXTexObjFromPalette( texPalette, &texObj, 1 );
83 
84     while ( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) )
85     {
86         // get pad status
87         DEMOPadRead( );
88         // General control & model animation
89         myAnimeModel( );
90 
91         // Draw scene
92         DEMOBeforeRender( );
93         DrawScene( );
94         DEMODoneRender( );
95     }
96 
97     OSHalt("End of test");
98 }
99 
100 //---------------------------------------------------------------------------
101 //  Model settings
102 //---------------------------------------------------------------------------
103 typedef  struct {
104    s8  x,  y;
105    s8  nx, ny, nz;
106    s8  pad;
107 }  MyVertex;
108 
109 static MyVertex ringVtx[] ATTRIBUTE_ALIGN(32) =
110 {
111     { 100,   0,    64,   0,  0 }, /*   0 */
112     {  87,  50,    55,  32,  0 }, /*  30 */
113     {  50,  87,    32,  55,  0 }, /*  60 */
114     {   0, 100,     0,  64,  0 }, /*  90 */
115     { -50,  87,   -32,  55,  0 }, /* 120 */
116     { -87,  50,   -55,  32,  0 }, /* 150 */
117     {-100,   0,   -64,   0,  0 }, /* 180 */
118     { -87, -50,   -55, -32,  0 }, /* 210 */
119     { -50, -87,   -32, -55,  0 }, /* 240 */
120     {   0,-100,     0, -64,  0 }, /* 270 */
121     {  50, -87,    32, -55,  0 }, /* 300 */
122     {  87, -50,    55, -32,  0 }, /* 330 */
123 };
124 
125 #define VTXINRING       ((s32)(sizeof(ringVtx)/sizeof(ringVtx[0])))
126 #define NUMPIPES        64
127 #define NUMRINGS        (NUMPIPES+1)
128 
129 f32  pipeAngle  = 10.0f;
130 f32  pipeLength = 50.0f;
131 
132 Mtx pipeLocalMtx =
133 {
134   { 0.0646906f, 0.0760343f, 0.0058220f, 0.0f },
135   {-0.0740718f, 0.0608390f, 0.0284950f, 0.0f },
136   { 0.0181239f,-0.0227461f, 0.0956772f, 0.0f }
137 };
138 
139 // For Pos/Tex Matrix Array
140 Mtx pipePosMtx[NUMRINGS] ATTRIBUTE_ALIGN(32);
141 Mtx pipeTexMtx[NUMRINGS] ATTRIBUTE_ALIGN(32);
142 
143 //---------------------------------------------------------------------------
144 //  Draw entire scene
145 //---------------------------------------------------------------------------
DrawScene(void)146 void    DrawScene( void )
147 {
148     Mtx44    projMtx;
149     Camera*  c = &myCamera;
150 
151     // Set projection matrix
152     MTXPerspective( projMtx, c->fovy, VP_ASPECT, c->znear, c->zfar );
153     GXSetProjection( projMtx, GX_PERSPECTIVE );
154 
155     // Set rendering mode
156     GXSetBlendMode( GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR );
157     GXSetZMode( GX_TRUE, GX_LESS, GX_TRUE );
158     GXSetZCompLoc( GX_TRUE );
159 
160     // Set rendering mode
161     GXSetCullMode( GX_CULL_BACK );
162 
163     // Draw objects
164     myDrawModel( );
165 
166     return;
167 }
168 
169 //---------------------------------------------------------------------------
170 //  Animate model
171 //---------------------------------------------------------------------------
172 #  define MOVE_SCALE    1.0f
173 
myAnimeModel(void)174 void  myAnimeModel( void )
175 {
176     Camera*  c = &myCamera;
177     Mtx      localMtx, tmpMtx;
178     Vec      axis;
179     s32      i, j;
180     f32      nfct;
181     f32      zoom;
182     Vec      rotAxis = { 0.0f, 1.0f, 0.2f };
183     u16      buttons, stickDirs;
184 
185     axis.x = axis.y = axis.z = 0.0f;
186     zoom   = 0.0f;
187 
188     stickDirs = DEMOPadGetDirs(0);
189     buttons   = DEMOPadGetButton(0);
190 
191     if ( stickDirs & DEMO_STICK_UP    ) axis.x -= 1.0f;
192     if ( stickDirs & DEMO_STICK_DOWN  ) axis.x += 1.0f;
193     if ( stickDirs & DEMO_STICK_LEFT  ) axis.y -= 1.0f;
194     if ( stickDirs & DEMO_STICK_RIGHT ) axis.y += 1.0f;
195     if ( buttons & PAD_BUTTON_A ) zoom =  2.0f * MOVE_SCALE;
196     if ( buttons & PAD_BUTTON_B ) zoom = -2.0f * MOVE_SCALE;
197     if ( buttons & PAD_TRIGGER_L ) pipeAngle += 0.1f;
198     if ( buttons & PAD_TRIGGER_R ) pipeAngle -= 0.1f;
199 
200     //--------- Get View matrix
201     c->position.y += zoom;
202     MTXLookAt( c->viewMtx, &c->position, &c->up, &c->target );
203 
204     //--------- Make local matrix
205     MTXInverse( c->viewMtx, tmpMtx );
206     MTXMultVecSR( tmpMtx, &axis, &axis );
207     if ( axis.x != 0.0f || axis.y != 0.0f || axis.z != 0.0f )
208     {
209         MTXRotAxisDeg( tmpMtx, &axis, 0.6f * MOVE_SCALE );
210         MTXConcat( tmpMtx, pipeLocalMtx, pipeLocalMtx );
211     }
212 
213     //--------- Get Position Matrix
214     MTXConcat    ( c->viewMtx, pipeLocalMtx, pipePosMtx[0] );
215     MTXTrans     ( localMtx, 0, 0, pipeLength );
216     MTXRotAxisDeg( tmpMtx, &rotAxis, pipeAngle  );
217     MTXConcat    ( tmpMtx, localMtx, localMtx );
218     for ( i = 1; i < NUMRINGS; i ++ )
219     {
220         MTXConcat( pipePosMtx[i-1], localMtx, pipePosMtx[i] );
221     }
222 
223     //--------- Get Texture Matrix for environment mapping
224     for ( i = 0; i < NUMRINGS; i ++ )
225     {
226         for ( j = 0; j < 2; j ++ )
227         {
228             nfct = 0.5f / VECMag( (VecPtr)pipePosMtx[i][0] );
229             if ( j == 1 ) nfct = -nfct;
230             pipeTexMtx[i][j][0] = pipePosMtx[i][j][0] * nfct;
231             pipeTexMtx[i][j][1] = pipePosMtx[i][j][1] * nfct;
232             pipeTexMtx[i][j][2] = pipePosMtx[i][j][2] * nfct;
233             pipeTexMtx[i][j][3] = 0.5f;
234         }
235     }
236     DCFlushRange( pipePosMtx, sizeof(pipePosMtx) );
237     DCFlushRange( pipeTexMtx, sizeof(pipeTexMtx) );
238 }
239 
240 //---------------------------------------------------------------------------
241 //  Draw model
242 //---------------------------------------------------------------------------
myDrawModel(void)243 void  myDrawModel( void )
244 {
245     s32          i, j, k;
246     GXPosNrmMtx  pm0, pm1;
247     GXTexMtx     tm0, tm1;
248     GXColor      black = {   0,   0,   0,   0 };
249     GXColor      color = { 255, 128,  64, 255 };
250 
251     //--------- Set rendering parameters
252     GXSetChanCtrl( GX_COLOR0,   GX_DISABLE,
253                    GX_SRC_REG,  GX_SRC_REG, GX_LIGHT_NULL,
254                    GX_DF_CLAMP, GX_AF_NONE  );
255 
256     GXSetChanCtrl( GX_ALPHA0,   GX_DISABLE,
257                    GX_SRC_REG,  GX_SRC_REG, GX_LIGHT_NULL,
258                    GX_DF_CLAMP, GX_AF_NONE  );
259 
260     GXSetChanAmbColor( GX_COLOR0A0, black );
261     GXSetChanMatColor( GX_COLOR0A0, color );
262 
263     GXSetNumTexGens  ( 1 );             // # of Texgen proc
264     GXSetNumChans    ( 1 );             // # of Color Channel
265     GXSetNumTevStages( 1 );             // # of Tev Stage
266 
267     GXSetTevOrder( GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0 );
268     GXSetTevOp( GX_TEVSTAGE0, GX_MODULATE );
269 
270     // Set texture
271     GXLoadTexObj( &texObj, GX_TEXMAP0 );
272 
273     //-------- Array base & stride setting
274     GXSetArray( GX_POS_MTX_ARRAY, &pipePosMtx[0], sizeof( pipePosMtx[0] ) );
275     GXSetArray( GX_TEX_MTX_ARRAY, &pipeTexMtx[0], sizeof( pipeTexMtx[0] ) );
276     GXSetArray( GX_VA_POS,        &ringVtx[0].x,  sizeof( ringVtx[0]    ) );
277     GXSetArray( GX_VA_NRM,        &ringVtx[0].nx, sizeof( ringVtx[0]    ) );
278 
279     //-------- Vertex descriptor settings
280     GXClearVtxDesc( );
281     GXSetVtxDesc( GX_VA_POS, GX_INDEX8 );
282     GXSetVtxDesc( GX_VA_NRM, GX_DIRECT );
283     GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XY,  GX_S8, 0 );
284     GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_S8, 6 );
285 
286     //-------- Pipe lid 0  (Triangle fan)
287     pm0 = GX_PNMTX0;
288     tm0 = GX_TEXMTX0;
289 
290     GXLoadPosMtxIndx( 0, pm0 );
291     GXLoadTexMtxIndx( 0, tm0, GX_MTX2x4 );
292     GXSetCurrentMtx ( pm0 );
293     GXSetTexCoordGen( GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_NRM, tm0 );
294 
295     GXBegin( GX_TRIANGLEFAN, GX_VTXFMT0, VTXINRING );
296     for ( i = 0; i < VTXINRING; i ++ )
297     {
298         GXPosition1x8( (u8)i );
299         GXNormal3s8  ( (s8)(ringVtx[i].nx/4), (s8)(ringVtx[i].ny/4), -60 );
300     }
301     GXEnd( );
302 
303     //-------- Pipe body (Triangle strip)
304     GXSetVtxDesc( GX_VA_PNMTXIDX,   GX_DIRECT );
305     GXSetVtxDesc( GX_VA_TEX0MTXIDX, GX_DIRECT );
306     GXSetVtxDesc( GX_VA_NRM,        GX_INDEX8 );
307     for ( j = 0; j < NUMRINGS-1; j ++ )
308     {
309         pm1 = ( pm0 == GX_PNMTX0  ) ? GX_PNMTX1  : GX_PNMTX0;
310         tm1 = ( tm0 == GX_TEXMTX0 ) ? GX_TEXMTX1 : GX_TEXMTX0;
311         GXLoadPosMtxIndx( (u16)(j+1), pm1 );
312         GXLoadTexMtxIndx( (u16)(j+1), tm1, GX_MTX2x4 );
313         GXBegin( GX_TRIANGLESTRIP, GX_VTXFMT0, (VTXINRING+1)*2 );
314         k = VTXINRING-1;
315         for ( i = -1; i < VTXINRING; i ++ )
316         {
317             GXMatrixIndex1x8( (u8)pm0 );
318             GXMatrixIndex1x8( (u8)tm0 );
319             GXPosition1x8   ( (u8)k   );
320             GXNormal1x8     ( (u8)k   );
321             GXMatrixIndex1x8( (u8)pm1 );
322             GXMatrixIndex1x8( (u8)tm1 );
323             GXPosition1x8   ( (u8)k   );
324             GXNormal1x8     ( (u8)k   );
325             k = i + 1;
326         }
327         GXEnd( );
328         pm0 = pm1;
329         tm0 = tm1;
330     }
331 
332     //-------- Pipe lid 1  (Triangle fan)
333     GXSetVtxDesc( GX_VA_PNMTXIDX,   GX_NONE   );
334     GXSetVtxDesc( GX_VA_TEX0MTXIDX, GX_NONE   );
335     GXSetVtxDesc( GX_VA_NRM,        GX_DIRECT );
336     GXSetCurrentMtx( pm0 );
337     GXSetTexCoordGen( GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_NRM, tm0 );
338 
339     GXBegin( GX_TRIANGLEFAN, GX_VTXFMT0, VTXINRING );
340     for ( i = 0; i < VTXINRING; i ++ )
341     {
342         GXPosition1x8( (u8)(VTXINRING-1-i) );
343         GXNormal3s8  ( (s8)(ringVtx[i].nx/4), (s8)(ringVtx[i].ny/4), +60 );
344     }
345     GXEnd( );
346 
347     return;
348 }
349 
350 /*======== End of tf-reflect.c ========*/
351