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