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