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