1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: lit-dist-atn.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 lit-dist-atn
15 Distance attenuation test
16 *---------------------------------------------------------------------------*/
17
18 /*---------------------------------------------------------------------------*
19 Header files
20 *---------------------------------------------------------------------------*/
21 #include <demo.h>
22 #include <math.h>
23
24 /*---------------------------------------------------------------------------*
25 Macro definitions
26 *---------------------------------------------------------------------------*/
27 #define PI 3.14159265358979323846F
28
29 /*---------------------------------------------------------------------------*
30 Structure definitions
31 *---------------------------------------------------------------------------*/
32 typedef struct
33 {
34 Vec location;
35 Vec up;
36 Vec target;
37 f32 left;
38 f32 top;
39 f32 znear;
40 f32 zfar;
41 } CameraConfig;
42
43 typedef struct
44 {
45 CameraConfig cfg;
46 Mtx view;
47 Mtx44 proj;
48 s32 theta;
49 s32 zoom;
50 } MyCameraObj;
51
52 typedef struct
53 {
54 f32 k0;
55 f32 k1;
56 f32 k2;
57 } DistAttn;
58
59 typedef struct
60 {
61 GXLightObj lobj;
62 u32 attnType;
63 } MyLightObj;
64
65 typedef struct
66 {
67 MyCameraObj cam;
68 MyLightObj light;
69 } MySceneCtrlObj;
70
71 /*---------------------------------------------------------------------------*
72 Forward references
73 *---------------------------------------------------------------------------*/
74 void main ( void );
75 static void DrawInit ( MySceneCtrlObj* sc );
76 static void DrawTick ( MySceneCtrlObj* sc );
77 static void AnimTick ( MySceneCtrlObj* sc );
78 static void DrawTessPanel ( void );
79 static void SetCamera ( MyCameraObj* cam );
80 static void SetLight ( MyLightObj* light, Mtx v );
81 static void DisableLight ( void );
82 static void PrintIntro ( void );
83 static void StatusMessage ( u32 index );
84
85 /*---------------------------------------------------------------------------*
86 Lighting parameters
87 *---------------------------------------------------------------------------*/
88 #define BLACK MyColors[2]
89 #define WHITE MyColors[3]
90
91 static GXColor MyColors[] ATTRIBUTE_ALIGN(32) =
92 {
93 {0x00, 0x00, 0x40, 0xff}, // blue
94 {0x40, 0x00, 0x00, 0xff}, // red
95 {0x00, 0x00, 0x00, 0xff}, // black
96 {0xff, 0xff, 0xff, 0xff}, // white
97 };
98
99 // fixed normal vector
100 static f32 FixedNormal[] ATTRIBUTE_ALIGN(32) =
101 {
102 0.0F, 0.0F, 1.0F
103 };
104
105 #define NUM_OF_ATTNS 14
106 static DistAttn LightAttnSamples[NUM_OF_ATTNS] =
107 {
108 { 1.0F, 0.1F, 0.0F },
109 { 1.0F, 0.02F, 0.0F },
110 { 1.0F, 0.01F, 0.0F },
111 { 1.0F, 0.005F, 0.0F },
112 { 1.0F, 0.002F, 0.0F },
113 { 1.0F, 0.001F, 0.0F },
114 { 1.0F, 0.0F, 0.0F },
115 { 2.0F, 0.0F, 0.0F },
116 { 2.0F, 0.001F, 0.0F },
117 { 1.0F, 0.0F, 0.0001F },
118 { 1.0F, -0.01F, 0.0001F },
119 { 1.0F, -0.05F, 0.0005F },
120 { 1.0F, -0.005F, 0.000025F },
121 { 4.0F, -0.002F, 0.0F }
122 };
123
124 /*---------------------------------------------------------------------------*
125 Camera configuration
126 *---------------------------------------------------------------------------*/
127 static CameraConfig DefaultCamera =
128 {
129 { 0.0F, 0.0F, 0.1F }, // location
130 { 0.0F, 1.0F, 0.0F }, // up
131 { 0.0F, 0.0F, 0.0F }, // target
132 -320.0F, // left
133 240.0F, // top
134 400.0F, // near
135 1800.0F // far
136 };
137
138 /*---------------------------------------------------------------------------*
139 Global Variables
140 *---------------------------------------------------------------------------*/
141 static MySceneCtrlObj SceneCtrl; // scene control parameters
142
143 /*---------------------------------------------------------------------------*
144 Application main loop
145 *---------------------------------------------------------------------------*/
main(void)146 void main ( void )
147 {
148 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
149
150 DrawInit(&SceneCtrl); // Initialize vertex formats and scene parameters etc.
151
152 PrintIntro(); // Print demo directions
153
154 StatusMessage(SceneCtrl.light.attnType);
155 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
156 {
157 DEMOBeforeRender();
158 DrawTick(&SceneCtrl); // Draw the model.
159 DEMODoneRender();
160 DEMOPadRead(); // Update pad status.
161 AnimTick(&SceneCtrl); // Update animation.
162 }
163
164 OSHalt("End of demo");
165 }
166
167 /*---------------------------------------------------------------------------*
168 Functions
169 *---------------------------------------------------------------------------*/
170 /*---------------------------------------------------------------------------*
171 Name: DrawInit
172
173 Description: Initializes the vertex attribute format, texture and
174 default scene parameters.
175
176 Arguments: sc : pointer to the structure of scene control parameters
177
178 Returns: none
179 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)180 static void DrawInit( MySceneCtrlObj* sc )
181 {
182 // set up a vertex attribute
183 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S8, 0);
184 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
185
186 // culling off
187 GXSetCullMode(GX_CULL_NONE);
188
189
190 // Default scene parameter settings
191
192 // camera
193 sc->cam.cfg = DefaultCamera;
194 sc->cam.theta = 45;
195 sc->cam.zoom = 1000;
196
197 // light parameters
198 sc->light.attnType = 0;
199 }
200
201 /*---------------------------------------------------------------------------*
202 Name: DrawTick
203
204 Description: Draw the model by using given scene parameters
205
206 Arguments: sc : pointer to the structure of scene control parameters
207
208 Returns: none
209 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)210 static void DrawTick( MySceneCtrlObj* sc )
211 {
212 Mtx ms; // Scale matrix.
213 Mtx mt; // Translation matrix
214 Mtx mv; // Modelview matrix.
215 Mtx mvi; // Modelview matrix.
216 s32 iz;
217
218 // render mode = one color / no texture
219 GXSetNumTexGens(0);
220 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
221 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
222
223 // Set camera
224 SetCamera(&sc->cam);
225
226 // Set light
227 SetLight(&sc->light, sc->cam.view);
228
229 // Draw panels
230 for ( iz = 0 ; iz < 10 ; ++iz )
231 {
232 f32 width = 10.0F - iz * 0.6F;
233 MTXScale(ms, width * 2.0F, width * 2.0F, 1.0F);
234 MTXTrans(mt, -7.5F, -7.5F, iz * 100.0F - 500.0F );
235 MTXConcat(sc->cam.view, ms, mv);
236 MTXConcat(mv, mt, mv);
237
238 GXLoadPosMtxImm(mv, GX_PNMTX0);
239 MTXInverse(mv, mvi);
240 MTXTranspose(mvi, mv);
241 GXLoadNrmMtxImm(mv, GX_PNMTX0);
242
243 GXSetChanAmbColor(GX_COLOR0A0, MyColors[iz%2]);
244 DrawTessPanel();
245 }
246
247 // Disable light
248 DisableLight();
249 // use ambient color for drawing
250 GXSetChanAmbColor(GX_COLOR0A0, WHITE);
251
252 // Draw ball light object
253 MTXTrans(mt, 0.0F, 0.0F, 500.0F);
254 MTXConcat(sc->cam.view, mt, mv);
255 MTXScale(ms, 20.0F, 20.0F, 20.0F);
256 MTXConcat(mv, ms, mv);
257 GXLoadPosMtxImm(mv, GX_PNMTX0);
258 MTXInverse(mv, mvi);
259 MTXTranspose(mvi, mv);
260 GXLoadNrmMtxImm(mv, GX_PNMTX0);
261 GXSetChanMatColor(GX_COLOR0A0, WHITE);
262 GXDrawSphere(12, 24);
263
264 }
265
266 /*---------------------------------------------------------------------------*
267 Name: AnimTick
268
269 Description: Changes scene parameters according to the pad status.
270
271 Arguments: sc : pointer to the structure of scene control parameters
272
273 Returns: none
274 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)275 static void AnimTick( MySceneCtrlObj* sc )
276 {
277 u16 down = DEMOPadGetButtonDown(0);
278
279 // Camera Position Calculation
280 sc->cam.theta -= ( DEMOPadGetStickX(0) / 24 );
281 if ( sc->cam.theta < 0 )
282 sc->cam.theta = 0;
283 if ( sc->cam.theta > 180 )
284 sc->cam.theta = 180;
285
286 sc->cam.zoom -= DEMOPadGetStickY(0);
287 if ( sc->cam.zoom < 600 )
288 sc->cam.zoom = 600;
289 if ( sc->cam.zoom > 1200 )
290 sc->cam.zoom = 1200;
291
292 // Light Attenuation change
293 if ( down & PAD_TRIGGER_R )
294 {
295 sc->light.attnType = ( sc->light.attnType + 1 ) % NUM_OF_ATTNS;
296 StatusMessage(sc->light.attnType);
297 }
298 if ( down & PAD_TRIGGER_L )
299 {
300 sc->light.attnType = ( sc->light.attnType + NUM_OF_ATTNS - 1 ) % NUM_OF_ATTNS;
301 StatusMessage(sc->light.attnType);
302 }
303 }
304
305 /*---------------------------------------------------------------------------*
306 Name: DrawTessPanel
307
308 Description: Draws 16x16 vertices panel
309
310 Arguments: none
311
312 Returns: none
313 *---------------------------------------------------------------------------*/
DrawTessPanel(void)314 static void DrawTessPanel( void )
315 {
316 s8 x, y;
317
318 // set up vertex descriptors
319 GXClearVtxDesc();
320 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
321 GXSetVtxDesc(GX_VA_NRM, GX_INDEX8);
322
323 // normal array (actually contains only one item)
324 GXSetArray(GX_VA_NRM, FixedNormal, 3 * sizeof(f32));
325
326 for ( y = 0 ; y < 15 ; ++y )
327 {
328 GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, 32);
329 for ( x = 0 ; x < 16 ; ++x )
330 {
331 GXPosition3s8(x, y, 0);
332 GXNormal1x8(0);
333 GXPosition3s8(x, (s8)(y+1), 0);
334 GXNormal1x8(0);
335 }
336 GXEnd();
337 }
338 }
339
340 /*---------------------------------------------------------------------------*
341 Name: SetCamera
342
343 Description: set view matrix and load projection matrix into hardware
344
345 Arguments: cam : pointer to the MyCameraObj structure
346
347 Returns: none
348 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)349 static void SetCamera( MyCameraObj* cam )
350 {
351 cam->cfg.location.x =
352 (f32)cam->zoom * cosf((f32)cam->theta * PI / 180.0F);
353 cam->cfg.location.y =
354 (f32)cam->zoom * 0.2F;
355 cam->cfg.location.z =
356 (f32)cam->zoom * sinf((f32)cam->theta * PI / 180.0F);
357
358 MTXLookAt(
359 cam->view,
360 &cam->cfg.location,
361 &cam->cfg.up,
362 &cam->cfg.target );
363
364 MTXFrustum(
365 cam->proj,
366 cam->cfg.top,
367 - (cam->cfg.top),
368 cam->cfg.left,
369 - (cam->cfg.left),
370 cam->cfg.znear,
371 cam->cfg.zfar );
372 GXSetProjection(cam->proj, GX_PERSPECTIVE);
373 }
374
375 /*---------------------------------------------------------------------------*
376 Name: SetLight
377
378 Description: Set up lights and lighting channel parameters
379
380 Arguments: light : pointer to a MyLightObj structure
381 v : view matrix
382
383 Returns: none
384 *---------------------------------------------------------------------------*/
SetLight(MyLightObj * light,Mtx v)385 void SetLight( MyLightObj* light, Mtx v )
386 {
387 Vec lpos = { 0.0F, 0.0F, 500.0F };
388
389 DistAttn attn = LightAttnSamples[light->attnType];
390
391 // Multiplied by view matrix
392 MTXMultVec(v, &lpos, &lpos);
393
394 GXInitLightPos(&light->lobj, lpos.x, lpos.y, lpos.z);
395 GXInitLightAttn(
396 &light->lobj,
397 1.0F,
398 0.0F,
399 0.0F,
400 attn.k0,
401 attn.k1,
402 attn.k2 );
403 GXInitLightColor(&light->lobj, WHITE);
404 GXLoadLightObjImm(&light->lobj, GX_LIGHT0);
405
406 GXSetNumChans(1); // number of active color channels
407 GXSetChanCtrl(
408 GX_COLOR0A0,
409 GX_ENABLE, // enable channel
410 GX_SRC_REG, // amb source
411 GX_SRC_REG, // mat source
412 GX_LIGHT0, // light mask
413 GX_DF_CLAMP, // diffuse function
414 GX_AF_SPOT);
415 // set up material color
416 GXSetChanMatColor(GX_COLOR0A0, WHITE);
417 }
418
419 /*---------------------------------------------------------------------------*
420 Name: DisableLight
421
422 Description: Disables lighting
423
424 Arguments: none
425
426 Returns: none
427 *---------------------------------------------------------------------------*/
DisableLight(void)428 void DisableLight( void )
429 {
430 GXSetNumChans(1);
431 GXSetChanCtrl(
432 GX_COLOR0A0,
433 GX_DISABLE, // disable channel
434 GX_SRC_REG, // amb source
435 GX_SRC_REG, // mat source
436 0, // light mask
437 GX_DF_NONE, // diffuse function
438 GX_AF_NONE);
439 }
440
441 /*---------------------------------------------------------------------------*
442 Name: PrintIntro
443
444 Description: Prints the directions on how to use this demo.
445
446 Arguments: none
447
448 Returns: none
449 *---------------------------------------------------------------------------*/
PrintIntro(void)450 static void PrintIntro( void )
451 {
452 OSReport("\n\n");
453 OSReport("******************************************************\n");
454 OSReport("lit-dist-atn: distance attenuation test\n");
455 OSReport("******************************************************\n");
456 OSReport("to quit hit the start button\n");
457 OSReport("\n");
458 OSReport("Stick : Move camera position\n");
459 OSReport("L/R Triggers : Change the distance attenuation value set\n");
460 OSReport("******************************************************\n");
461 OSReport("\n\n");
462 }
463
464 /*---------------------------------------------------------------------------*
465 Name: StatusMessage
466
467 Description: Prints the current status.
468 *---------------------------------------------------------------------------*/
StatusMessage(u32 index)469 static void StatusMessage( u32 index )
470 {
471 OSReport(" k0 = %f ", LightAttnSamples[index].k0);
472 OSReport(" k1 = %f ", LightAttnSamples[index].k1);
473 OSReport(" k2 = %f ", LightAttnSamples[index].k2);
474
475 OSReport("\n");
476 }
477
478 /*============================================================================*/
479