1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tex-lod.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 tex-lod
15 advanced LOD filters test
16 *---------------------------------------------------------------------------*/
17
18
19 /*---------------------------------------------------------------------------*
20 Header files
21 *---------------------------------------------------------------------------*/
22 #include <demo.h>
23
24 /*---------------------------------------------------------------------------*
25 Macro definitions
26 *---------------------------------------------------------------------------*/
27 #define NUM_VIEWS 4
28 #define NUM_PARAMETERS 4
29
30 #define Clamp(val,min,max) \
31 ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
32
33 /*---------------------------------------------------------------------------*
34 Structure definitions
35 *---------------------------------------------------------------------------*/
36 // for camera
37 typedef struct
38 {
39 Vec location;
40 Vec up;
41 Vec target;
42 f32 left;
43 f32 top;
44 f32 znear;
45 f32 zfar;
46 } CameraConfig;
47
48 typedef struct
49 {
50 CameraConfig cfg;
51 Mtx view;
52 Mtx44 proj;
53 } MyCameraObj;
54
55 // for viewports
56 typedef struct
57 {
58 s32 xorig;
59 s32 yorig;
60 s32 width;
61 s32 height;
62 } MyViewPortObj;
63
64 // for subscene in a view
65 typedef struct
66 {
67 s32 filterCtrl[NUM_PARAMETERS];
68 Mtx modelCtrl;
69 f32 modelScale;
70 MyViewPortObj viewPort;
71 } MySubSceneObj;
72
73 // for entire scene control
74 typedef struct
75 {
76 MyCameraObj cam;
77 u32 texNumber;
78 MySubSceneObj subScene[NUM_VIEWS];
79 u32 curV;
80 u32 curP;
81 } MySceneCtrlObj;
82
83 /*---------------------------------------------------------------------------*
84 Forward references
85 *---------------------------------------------------------------------------*/
86 void main ( void );
87 static void DrawInit ( MySceneCtrlObj* sc );
88 static void DrawTick ( MySceneCtrlObj* sc );
89 static void AnimTick ( MySceneCtrlObj* sc );
90 static void DrawCube ( void );
91 static void SetCamera ( MyCameraObj* cam );
92 static void PrintIntro ( void );
93
94 /*---------------------------------------------------------------------------*
95 Model Data
96 *---------------------------------------------------------------------------*/
97 static s16 CubeVertices[3*8] ATTRIBUTE_ALIGN(32) =
98 {
99 -64, -64, 64, // 0
100 64, -64, 64, // 1
101 64, 64, 64, // 2
102 -64, 64, 64, // 3
103 -64, -64, -64, // 4
104 64, -64, -64, // 5
105 64, 64, -64, // 6
106 -64, 64, -64 // 7
107 };
108
109 static s16 CubeTexCoords[2*4] ATTRIBUTE_ALIGN(32) =
110 {
111 0, 0,
112 1, 0,
113 1, 1,
114 0, 1
115 };
116
117 static u8 CubeFaces[6][4] =
118 {
119 { 1, 0, 3, 2 },
120 { 6, 7, 4, 5 },
121 { 3, 0, 4, 7 },
122 { 0, 1, 5, 4 },
123 { 1, 2, 6, 5 },
124 { 2, 3, 7, 6 }
125 };
126
127 /*---------------------------------------------------------------------------*
128 Data for views and parameters
129 *---------------------------------------------------------------------------*/
130 // Viewport origin for each view
131 static u32 ViewOrigX[NUM_VIEWS] = { 0, 1, 0, 1 };
132 static u32 ViewOrigY[NUM_VIEWS] = { 0, 0, 1, 1 };
133
134 // Max/Min value of parameters
135 static s32 ParamMax[NUM_PARAMETERS] = { 7, 1, 1, 2 };
136 static s32 ParamMin[NUM_PARAMETERS] = { -7, 0, 0, 0 };
137
138 // Anisotropic filter mode
139 static u32 AnisoNum[3] = { 1, 2, 4 };
140 static GXAnisotropy AnisoMode[3] =
141 {
142 GX_ANISO_1,
143 GX_ANISO_2,
144 GX_ANISO_4
145 };
146
147 // Strings for captions
148 static char* SwStr[2] = { "OFF", "ON" };
149
150 /*---------------------------------------------------------------------------*
151 Camera configuration
152 *---------------------------------------------------------------------------*/
153 static CameraConfig DefaultCamera =
154 {
155 { 0.0F, -500.0F, 0.0F }, // location
156 { 0.0F, 0.0F, 1.0F }, // up
157 { 0.0F, 0.0F, 0.0F }, // target
158 -160.0F, // left
159 120.0F, // top
160 50.0F, // near
161 2000.0F // far
162 };
163
164 /*---------------------------------------------------------------------------*
165 Global variables
166 *---------------------------------------------------------------------------*/
167 static MySceneCtrlObj SceneCtrl; // scene control parameters
168 static TPLPalettePtr MyTplObj = NULL; // texture palette
169 static u32 TexNumMax; // number of textures
170
171 /*---------------------------------------------------------------------------*
172 Application main loop
173 *---------------------------------------------------------------------------*/
main(void)174 void main ( void )
175 {
176 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
177
178 DrawInit(&SceneCtrl); // Initialize vertex formats, array pointers
179 // and default scene settings.
180
181 PrintIntro(); // Print demo directions
182
183 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
184 {
185 DEMOBeforeRender();
186 DrawTick(&SceneCtrl); // Draw the model.
187 DEMODoneRender();
188 DEMOPadRead(); // Read controller
189 AnimTick(&SceneCtrl); // Do animation
190 }
191
192 OSHalt("End of demo");
193 }
194
195 /*---------------------------------------------------------------------------*
196 Functions
197 *---------------------------------------------------------------------------*/
198 /*---------------------------------------------------------------------------*
199 Name: DrawInit
200
201 Description: Initializes the vertex attribute format and sets up
202 the array pointer for the indexed data.
203 This function also initializes scene control parameters.
204
205 Arguments: sc : pointer to the structure of scene control parameters
206
207 Returns: none
208 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)209 static void DrawInit( MySceneCtrlObj* sc )
210 {
211 GXRenderModeObj* rmode;
212 f32 swd, sht;
213 u32 i, j;
214
215 // Vertex Attribute ( VTXFMT0 is used by DEMOPuts lib.)
216 GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
217 GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
218
219 // Array Pointers and Strides
220 GXInvalidateVtxCache();
221 GXSetArray(GX_VA_POS, CubeVertices, 3 * sizeof(s16));
222 GXSetArray(GX_VA_TEX0, CubeTexCoords, 2 * sizeof(s16));
223
224 // Load TPL file
225 TPLGetPalette(&MyTplObj, "gxTests/tex-01.tpl");
226 TexNumMax = MyTplObj->numDescriptors;
227
228 // Get Screen Information
229 rmode = DEMOGetRenderModeObj();
230 swd = rmode->fbWidth; // Screen Width
231 sht = rmode->efbHeight; // Screen Height
232
233
234 // Default scene control parameter settings
235
236 // camera
237 sc->cam.cfg = DefaultCamera;
238 SetCamera(&sc->cam);
239
240 // texture number
241 sc->texNumber = 0;
242
243 // each subscene object
244 for ( i = 0 ; i < NUM_VIEWS ; ++i )
245 {
246 // viewport
247 sc->subScene[i].viewPort.xorig = (s32)(ViewOrigX[i] * (swd / 2));
248 sc->subScene[i].viewPort.yorig = (s32)(ViewOrigY[i] * (sht / 2));
249 sc->subScene[i].viewPort.width = (s32)(swd / 2);
250 sc->subScene[i].viewPort.height = (s32)(sht / 2);
251
252 // filters
253 for ( j = 0 ; j < NUM_PARAMETERS ; ++j )
254 {
255 sc->subScene[i].filterCtrl[j] = 0;
256 }
257
258 // model
259 sc->subScene[i].modelScale = 1.0F;
260 MTXIdentity(sc->subScene[i].modelCtrl);
261 }
262
263 // cursor position
264 sc->curV = 0;
265 sc->curP = 0;
266 }
267
268 /*---------------------------------------------------------------------------*
269 Name: DrawTick
270
271 Description: Draw the model by using given scene parameters
272
273 Arguments: sc : pointer to the structure of scene control parameters
274
275 Returns: none
276 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)277 static void DrawTick( MySceneCtrlObj* sc )
278 {
279 u32 i;
280 TPLDescriptorPtr tdp;
281 MySubSceneObj* ssc;
282 GXTexObj texObj;
283 f32 lodBias;
284 GXBool biasClamp, edgeLod;
285 GXAnisotropy aniso;
286 Mtx ms, mv;
287
288 // get texture descriptor from texture palette
289 tdp = TPLGet(MyTplObj, sc->texNumber);
290 GXInitTexObj(
291 &texObj,
292 tdp->textureHeader->data,
293 tdp->textureHeader->width,
294 tdp->textureHeader->height,
295 (GXTexFmt)tdp->textureHeader->format,
296 tdp->textureHeader->wrapS, // s
297 tdp->textureHeader->wrapT, // t
298 GX_TRUE ); // Mipmap always enabled
299
300 // Draw each view
301 for ( i = 0 ; i < NUM_VIEWS ; ++i )
302 {
303 ssc = &sc->subScene[i];
304
305 // Viewport/Scissor
306 GXSetViewport(
307 (f32)ssc->viewPort.xorig,
308 (f32)ssc->viewPort.yorig,
309 (f32)ssc->viewPort.width,
310 (f32)ssc->viewPort.height,
311 0.0F,
312 1.0F );
313 GXSetScissor(
314 (u32)ssc->viewPort.xorig,
315 (u32)ssc->viewPort.yorig,
316 (u32)ssc->viewPort.width,
317 (u32)ssc->viewPort.height );
318
319 // Camera
320 SetCamera(&sc->cam);
321
322 // Modelview matrix
323 MTXConcat(sc->cam.view, ssc->modelCtrl, mv);
324 MTXScale(ms, ssc->modelScale, ssc->modelScale, ssc->modelScale);
325 MTXConcat(mv, ms, mv);
326
327 // Tev, TexGen and Zmode
328 GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
329 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
330 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
331 GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE);
332
333 // LOD filter settings
334 lodBias = (f32)(ssc->filterCtrl[0]) / 2.0F;
335 biasClamp = (GXBool)(ssc->filterCtrl[1]);
336 edgeLod = (GXBool)(ssc->filterCtrl[2]);
337 aniso = AnisoMode[ssc->filterCtrl[3]];
338
339 GXInitTexObjLOD(
340 &texObj,
341 GX_LIN_MIP_LIN,
342 GX_LINEAR,
343 tdp->textureHeader->minLOD,
344 tdp->textureHeader->maxLOD,
345 lodBias, // LOD bias
346 biasClamp, // bias clamp
347 edgeLod, // edge LOD enable
348 aniso ); // anisotropy
349
350 // Draw a textured cube
351 GXLoadTexObj(&texObj, GX_TEXMAP0);
352 GXLoadPosMtxImm(mv, GX_PNMTX0);
353 DrawCube();
354
355 // Show parameters by caption
356 DEMOInitCaption(
357 DM_FT_OPQ,
358 (s32)ssc->viewPort.width,
359 (s32)ssc->viewPort.height );
360
361 DEMOPrintf(0, 0, 0, " LOD Bias :%1.1f", lodBias);
362 DEMOPrintf(0, 8, 0, " Bias Clamp:%s",
363 SwStr[ssc->filterCtrl[1]] );
364 DEMOPrintf(0, 16, 0, " Edge LOD :%s",
365 SwStr[ssc->filterCtrl[2]] );
366 DEMOPrintf(0, 24, 0, " Max Aniso.:%d",
367 AnisoNum[ssc->filterCtrl[3]] );
368
369 // Draw cursor
370 if ( i == sc->curV )
371 {
372 DEMOPrintf(0, (s16)(sc->curP * 8), 0, "%c", 0x7F);
373 }
374 }
375 }
376
377 /*---------------------------------------------------------------------------*
378 Name: AnimTick
379
380 Description: Changes scene parameters according to the pad status.
381
382 Arguments: sc : pointer to the structure of scene control parameters
383
384 Returns: none
385 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)386 static void AnimTick( MySceneCtrlObj* sc )
387 {
388 u16 button, down;
389 MySubSceneObj* ssc;
390 Mtx mrx, mry;
391 f32 dscale;
392 u32 i;
393
394 // PAD
395 down = DEMOPadGetButtonDown(0);
396 button = DEMOPadGetButton(0);
397
398 ssc = &sc->subScene[sc->curV];
399
400 // Model Rotation Calculation
401 MTXRotDeg(mry, 'x', -(DEMOPadGetStickY(0) / 24));
402 MTXRotDeg(mrx, 'z', (DEMOPadGetStickX(0) / 24));
403 MTXConcat(mry, ssc->modelCtrl, ssc->modelCtrl);
404 MTXConcat(mrx, ssc->modelCtrl, ssc->modelCtrl);
405
406 // Model scale control
407 dscale = 1.0F + ( DEMOPadGetSubStickY(0) / 16 ) * 0.025F;
408 ssc->modelScale *= dscale;
409 Clamp(ssc->modelScale, 0.05F, 3.0F);
410
411
412 // Synchronize scale and rotation
413 if ( button & PAD_BUTTON_A )
414 {
415 for ( i = 0 ; i < NUM_VIEWS ; ++i )
416 {
417 if ( i == sc->curV )
418 continue;
419
420 sc->subScene[i].modelScale = ssc->modelScale;
421 MTXCopy(ssc->modelCtrl, sc->subScene[i].modelCtrl);
422 }
423 }
424
425 // Change the texture
426 if ( down & PAD_BUTTON_B )
427 {
428 sc->texNumber = ( sc->texNumber + 1 ) % TexNumMax;
429 }
430
431 // Change parameter
432 if ( down & PAD_TRIGGER_L )
433 {
434 if ( ssc->filterCtrl[sc->curP] > ParamMin[sc->curP] )
435 {
436 ssc->filterCtrl[sc->curP] -= 1;
437 }
438 }
439 if ( down & PAD_TRIGGER_R )
440 {
441 if ( ssc->filterCtrl[sc->curP] < ParamMax[sc->curP] )
442 {
443 ssc->filterCtrl[sc->curP] += 1;
444 }
445 }
446
447 // Move cursor
448 if ( down & PAD_BUTTON_Y )
449 {
450 sc->curP = ( sc->curP + NUM_PARAMETERS - 1 ) % NUM_PARAMETERS;
451 if ( sc->curP == NUM_PARAMETERS - 1 )
452 {
453 sc->curV = ( sc->curV + NUM_VIEWS - 1 ) % NUM_VIEWS;
454 }
455 }
456 if ( down & PAD_BUTTON_X )
457 {
458 sc->curP = ( sc->curP + 1 ) % NUM_PARAMETERS;
459 if ( sc->curP == 0 )
460 {
461 sc->curV = ( sc->curV + 1 ) % NUM_VIEWS;
462 }
463 }
464 }
465
466 /*---------------------------------------------------------------------------*
467 Name: DrawCube
468
469 Description: Draw a textured cube.
470
471 Arguments: none
472
473 Returns: none
474 *---------------------------------------------------------------------------*/
DrawCube(void)475 static void DrawCube( void )
476 {
477 u8 i, j;
478
479 // set vertex descriptor
480 GXClearVtxDesc();
481 GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
482 GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
483
484 // draw a cube
485 GXBegin(GX_QUADS, GX_VTXFMT1, 24);
486 for ( i = 0 ; i < 6 ; ++i )
487 {
488 // Draw a face
489 for ( j = 0 ; j < 4 ; ++j )
490 {
491 GXPosition1x8(CubeFaces[i][j]);
492 GXTexCoord1x8(j);
493 }
494 }
495 GXEnd();
496 }
497
498 /*---------------------------------------------------------------------------*
499 Name: SetCamera
500
501 Description: set view matrix and load projection matrix into hardware
502
503 Arguments: cam : pointer to the MyCameraObj structure
504
505 Returns: none
506 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)507 static void SetCamera( MyCameraObj* cam )
508 {
509 MTXLookAt(
510 cam->view,
511 &cam->cfg.location,
512 &cam->cfg.up,
513 &cam->cfg.target );
514
515 MTXOrtho(
516 cam->proj,
517 cam->cfg.top,
518 - (cam->cfg.top),
519 cam->cfg.left,
520 - (cam->cfg.left),
521 cam->cfg.znear,
522 cam->cfg.zfar );
523 GXSetProjection(cam->proj, GX_ORTHOGRAPHIC);
524 }
525
526 /*---------------------------------------------------------------------------*
527 Name: PrintIntro
528
529 Description: Prints the directions on how to use this demo.
530
531 Arguments: none
532
533 Returns: none
534 *---------------------------------------------------------------------------*/
PrintIntro(void)535 static void PrintIntro( void )
536 {
537 OSReport("\n\n");
538 OSReport("************************************************\n");
539 OSReport("tex-lod: advanced LOD filter test\n");
540 OSReport("************************************************\n");
541 OSReport("to quit hit the start button\n");
542 OSReport("\n");
543 OSReport("Main Stick : rotate the box\n");
544 OSReport("Sub Stick Y : change scale of the box\n");
545 OSReport("X/Y Buttons : move cursor\n");
546 OSReport("L/R Triggers : change parameters\n");
547 OSReport("A button : synchronize scale and rotation\n");
548 OSReport("B button : change the texture\n");
549 OSReport("************************************************\n\n");
550 }
551
552 /*============================================================================*/
553