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