1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     tex-filter.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-filter
15         texture bilinear/trilinear filter 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 
29 #define MAX_SCOORD         0x4000  // for 16b, 2.14 fixed point format
30 #define MAX_TCOORD         0x4000  // for 16b, 2.14 fixed point format
31 
32 #define Clamp(val,min,max) \
33     ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
34 
35 /*---------------------------------------------------------------------------*
36    Structure definitions
37  *---------------------------------------------------------------------------*/
38 // for camera
39 typedef struct
40 {
41     Vec    location;
42     Vec    up;
43     Vec    target;
44     f32    left;
45     f32    top;
46     f32    znear;
47     f32    zfar;
48 } CameraConfig;
49 
50 typedef struct
51 {
52     CameraConfig  cfg;
53     Mtx           view;
54     Mtx44         proj;
55 } MyCameraObj;
56 
57 // for viewports
58 typedef struct
59 {
60     s32    xorig;
61     s32    yorig;
62     s32    width;
63     s32    height;
64 } MyViewPortObj;
65 
66 // for entire scene control
67 typedef struct
68 {
69     MyCameraObj       cam;
70     u32               texNumber;
71     GXBool            mipMapSw;
72     Mtx               modelCtrl;
73     f32               modelScale;
74     MyViewPortObj     viewPorts[NUM_VIEWS];
75 } MySceneCtrlObj;
76 
77 /*---------------------------------------------------------------------------*
78    Forward references
79  *---------------------------------------------------------------------------*/
80 void        main           ( void );
81 static void DrawInit       ( MySceneCtrlObj* sc );
82 static void DrawTick       ( MySceneCtrlObj* sc );
83 static void AnimTick       ( MySceneCtrlObj* sc );
84 static void DrawCube       ( void );
85 static void SetCamera      ( MyCameraObj* cam );
86 static void SetViewPort    ( MyViewPortObj* vp );
87 static void PrintIntro     ( void );
88 
89 /*---------------------------------------------------------------------------*
90   Model Data
91  *---------------------------------------------------------------------------*/
92 /*---------------------------------------------------------------------------*
93    Data arrays for indexed primitives must be 32B aligned.  Normally, memory
94    for the arrays would be OSAlloc'd (which returns 32B aligned pointers) and
95    the data would be loaded from ROM.  The pragma variable_align provides a
96    convenient way to align initialized arrays.
97  *---------------------------------------------------------------------------*/
98 static s16 CubeVertices[] ATTRIBUTE_ALIGN(32) =
99 {
100     -40, -40,  40, // 0
101      40, -40,  40, // 1
102      40,  40,  40, // 2
103     -40,  40,  40, // 3
104     -40, -40, -40, // 4
105      40, -40, -40, // 5
106      40,  40, -40, // 6
107     -40,  40, -40  // 7
108 };
109 
110 static u16 CubeTexCoords[4][2] = // This is not used as array.
111 {
112     { 0x0000,     0x0000 },
113     { MAX_SCOORD, 0x0000 },
114     { MAX_SCOORD, MAX_TCOORD },
115     { 0x0000,     MAX_TCOORD }
116 };
117 
118 static s16 CubeTexSpeed[6][2] =
119 {
120     { 2,  3 },
121     { 3,  2 },
122     { 0,  0 },
123     { 2,  0 },
124     { 1,  1 },
125     { 0,  3 }
126 };
127 
128 static u8 CubeFaces[6][4] =
129 {
130     { 3, 2, 1, 0 },
131     { 4, 5, 6, 7 },
132     { 4, 7, 3, 0 },
133     { 5, 4, 0, 1 },
134     { 6, 5, 1, 2 },
135     { 7, 6, 2, 3 }
136 };
137 
138 /*---------------------------------------------------------------------------*
139    Settings for each view
140  *---------------------------------------------------------------------------*/
141 // Viewport origin for each view
142 static u32 ViewOrigX[NUM_VIEWS] = { 0, 1, 0, 1 };
143 static u32 ViewOrigY[NUM_VIEWS] = { 0, 0, 1, 1 };
144 
145 // Mipmap filter for each cube
146 static GXTexFilter Filters[NUM_VIEWS][2] =
147 {
148     { GX_NEAR_MIP_NEAR, GX_NEAR },
149     { GX_NEAR_MIP_LIN,  GX_NEAR },
150     { GX_LIN_MIP_NEAR,  GX_LINEAR },
151     { GX_LIN_MIP_LIN,   GX_LINEAR }
152 };
153 
154 /*---------------------------------------------------------------------------*
155    Camera configuration
156  *---------------------------------------------------------------------------*/
157 static CameraConfig DefaultCamera =
158 {
159     {   0.0F, -500.0F, 0.0F }, // location
160     {   0.0F,    0.0F, 1.0F }, // up
161     {   0.0F,    0.0F, 0.0F }, // target
162     -160.0F,  // left
163     120.0F,   // top
164     50.0F,    // near
165     2000.0F   // far
166 };
167 
168 /*---------------------------------------------------------------------------*
169    Global variables
170  *---------------------------------------------------------------------------*/
171 static MySceneCtrlObj   SceneCtrl;                // scene control parameters
172 static TPLPalettePtr    MyTplObj = NULL;          // texture palette
173 static u32              TexNumMax;                // number of textures
174 
175 /*---------------------------------------------------------------------------*
176    Application main loop
177  *---------------------------------------------------------------------------*/
main(void)178 void main ( void )
179 {
180     DEMOInit(NULL);  // Init the OS, game pad, graphics and video.
181 
182     DrawInit(&SceneCtrl); // Initialize vertex formats, array pointers
183                           // and default scene settings.
184 
185     PrintIntro();    // Print demo directions
186 
187     while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
188     {
189 		DEMOBeforeRender();
190         DrawTick(&SceneCtrl);        // Draw the model.
191         DEMODoneRender();
192         DEMOPadRead();               // Read controller
193         AnimTick(&SceneCtrl);   // Do animation
194     }
195 
196     OSHalt("End of demo");
197 }
198 
199 /*---------------------------------------------------------------------------*
200    Functions
201  *---------------------------------------------------------------------------*/
202 /*---------------------------------------------------------------------------*
203     Name:           DrawInit
204 
205     Description:    Initializes the vertex attribute format and sets up
206                     the array pointer for the indexed data.
207                     This function also initializes scene control parameters.
208 
209     Arguments:      sc : pointer to the structure of scene control parameters
210 
211     Returns:        none
212  *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)213 static void DrawInit( MySceneCtrlObj* sc )
214 {
215     GXRenderModeObj* rmode;
216     u32    swd, sht;
217     u32    i;
218 
219     //  Vertex Attribute
220     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
221     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U16, 14);
222 
223     //  Array Pointers and Strides
224     GXInvalidateVtxCache();
225     GXSetArray(GX_VA_POS, CubeVertices, 3 * sizeof(s16));
226 
227     //  Load TPL file
228     TPLGetPalette(&MyTplObj, "gxTests/tex-01.tpl");
229     TexNumMax = MyTplObj->numDescriptors;
230 
231     // Set texture coordinate generation.
232     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
233     GXSetNumTexGens(1);
234 
235 
236     // Default scene control parameter settings
237 
238     // camera
239     sc->cam.cfg = DefaultCamera;
240     SetCamera(&sc->cam);   // never changes in this test
241 
242     // viewports
243     rmode = DEMOGetRenderModeObj();
244     swd   = rmode->fbWidth;    // Screen Width
245     sht   = rmode->efbHeight;  // Screen Height
246     for ( i = 0 ; i < NUM_VIEWS ; ++i )
247     {
248         sc->viewPorts[i].xorig  = (s32)(ViewOrigX[i] * (swd / 2));
249         sc->viewPorts[i].yorig  = (s32)(ViewOrigY[i] * (sht / 2));
250         sc->viewPorts[i].width  = (s32)(swd / 2);
251         sc->viewPorts[i].height = (s32)(sht / 2);
252     }
253 
254     // texture number
255     sc->texNumber = 0;
256 
257     // mipmap switch
258     sc->mipMapSw = GX_TRUE;
259 
260     // model rotation and scale
261     sc->modelScale = 1.0F;
262     MTXIdentity(sc->modelCtrl);
263 }
264 
265 /*---------------------------------------------------------------------------*
266     Name:           DrawTick
267 
268     Description:    Draw the model by using given scene parameters
269 
270     Arguments:      sc : pointer to the structure of scene control parameters
271 
272     Returns:        none
273  *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)274 static void DrawTick( MySceneCtrlObj* sc )
275 {
276     u32              i;
277     TPLDescriptorPtr tdp;
278     GXTexObj         texObj;
279     GXBool           mipMapFlag;
280     Mtx              ms, mv;
281     f32              minLOD, maxLOD;
282 
283     // set tev mode to use texture
284     GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
285     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
286 
287 
288     // get texture descriptor from texture palette
289     tdp = TPLGet(MyTplObj, sc->texNumber);
290 
291     mipMapFlag =
292         (GXBool)(( tdp->textureHeader->minLOD == tdp->textureHeader->maxLOD ) ?
293                  GX_FALSE : GX_TRUE);
294 
295     minLOD = tdp->textureHeader->minLOD;
296     maxLOD = tdp->textureHeader->maxLOD;
297 
298     if ( sc->mipMapSw == GX_FALSE )
299     {
300         mipMapFlag = GX_FALSE;
301         maxLOD     = minLOD;
302     }
303 
304     GXInitTexObj(
305         &texObj,
306         tdp->textureHeader->data,
307         tdp->textureHeader->width,
308         tdp->textureHeader->height,
309         (GXTexFmt)tdp->textureHeader->format,
310         tdp->textureHeader->wrapS, // s
311         tdp->textureHeader->wrapT, // t
312         mipMapFlag );     // Mipmap
313 
314     // Set modelview matrix
315     MTXConcat(sc->cam.view, sc->modelCtrl, mv);
316     MTXScale(ms, sc->modelScale, sc->modelScale, sc->modelScale);
317     MTXConcat(mv, ms, mv);
318     GXLoadPosMtxImm(mv, GX_PNMTX0);
319 
320 
321     // Draw each view
322     for ( i = 0 ; i < NUM_VIEWS ; ++i )
323     {
324         // Viewport
325         SetViewPort(&sc->viewPorts[i]);
326 
327         // Filter setting
328         GXInitTexObjLOD(
329             &texObj,
330             mipMapFlag ? Filters[i][0] : Filters[i][1],
331             Filters[i][1],
332             minLOD,
333             maxLOD,
334             tdp->textureHeader->LODBias,
335             GX_FALSE,
336             tdp->textureHeader->edgeLODEnable,
337             GX_ANISO_1 );
338 
339         // Draw a textured cube
340         GXLoadTexObj(&texObj, GX_TEXMAP0);
341         DrawCube();
342     }
343 }
344 
345 /*---------------------------------------------------------------------------*
346     Name:           AnimTick
347 
348     Description:    Changes scene parameters according to the pad status.
349 
350     Arguments:      sc  : pointer to the structure of scene control parameters
351 
352     Returns:        none
353  *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)354 static void AnimTick( MySceneCtrlObj* sc )
355 {
356     u16  down;
357     f32  dscale;
358     Mtx  mrx, mry;
359 
360     down = DEMOPadGetButtonDown(0);
361 
362     // Model Rotation Calculation
363     MTXRotDeg(mry, 'x', -(f32)(DEMOPadGetStickY(0))/32.0F);
364     MTXRotDeg(mrx, 'z',  (f32)(DEMOPadGetStickX(0))/32.0F);
365     MTXConcat(mry, sc->modelCtrl, sc->modelCtrl);
366     MTXConcat(mrx, sc->modelCtrl, sc->modelCtrl);
367 
368     // Model scale control
369     dscale = 1.0F + (DEMOPadGetSubStickY(0) / 32 ) * 0.0125F;
370     sc->modelScale *= dscale;
371     Clamp(sc->modelScale, 0.05F, 4.0F);
372 
373     // Change the texture
374     if ( down & PAD_BUTTON_A )
375     {
376         sc->texNumber = ( sc->texNumber + 1 ) % TexNumMax;
377     }
378 
379     // Turn on/off mipmap switch
380     if ( down & PAD_BUTTON_B )
381     {
382         if ( sc->mipMapSw == GX_TRUE )
383         {
384             sc->mipMapSw = GX_FALSE;
385             OSReport("Mipmap off\n");
386         }
387         else
388         {
389             sc->mipMapSw = GX_TRUE;
390             OSReport("Mipmap on\n");
391         }
392     }
393 }
394 
395 /*---------------------------------------------------------------------------*
396     Name:           DrawCube
397 
398     Description:    Draw a textured cube.
399 
400     Arguments:      none
401 
402     Returns:        none
403  *---------------------------------------------------------------------------*/
DrawCube(void)404 static void DrawCube( void )
405 {
406     static u32 s = 0;
407     static u32 t = 0;
408     u16  cs, ct;
409     u8   i, j;
410 
411     // set vertex descriptor
412     GXClearVtxDesc();
413     GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
414     GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
415 
416     // draw a cube
417     GXBegin(GX_QUADS, GX_VTXFMT0, 24);
418     for ( i = 0 ; i < 6 ; ++i )
419     {
420         // Draw a face
421         for ( j = 0 ; j < 4 ; ++j )
422         {
423             cs = (u16)(CubeTexCoords[j][0] + s * CubeTexSpeed[i][0]);
424             ct = (u16)(CubeTexCoords[j][1] + t * CubeTexSpeed[i][1]);
425             GXPosition1x8(CubeFaces[i][j]);
426             GXTexCoord2u16(cs, ct);
427         }
428     }
429     GXEnd();
430 
431     // translate s, t coordinates
432     ++s;
433     ++t;
434     if (s  > MAX_SCOORD) s = 0;
435     if (t  > MAX_TCOORD) t = 0;
436 }
437 
438 /*---------------------------------------------------------------------------*
439     Name:           SetCamera
440 
441     Description:    set view matrix and load projection matrix into hardware
442 
443     Arguments:      cam : pointer to the MyCameraObj structure
444 
445     Returns:        none
446  *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)447 static void SetCamera( MyCameraObj* cam )
448 {
449     MTXLookAt(
450         cam->view,
451         &cam->cfg.location,
452         &cam->cfg.up,
453         &cam->cfg.target );
454 
455     MTXOrtho(
456         cam->proj,
457         cam->cfg.top,
458         - (cam->cfg.top),
459         cam->cfg.left,
460         - (cam->cfg.left),
461         cam->cfg.znear,
462         cam->cfg.zfar );
463     GXSetProjection(cam->proj, GX_ORTHOGRAPHIC);
464 }
465 
466 /*---------------------------------------------------------------------------*
467     Name:           SetViewPort
468 
469     Description:    set viewports
470 
471     Arguments:      vp : pointer to the MyViewPortObj structure
472 
473     Returns:        none
474  *---------------------------------------------------------------------------*/
SetViewPort(MyViewPortObj * vp)475 static void SetViewPort( MyViewPortObj* vp )
476 {
477     GXSetViewport(
478         (f32)vp->xorig,
479         (f32)vp->yorig,
480         (f32)vp->width,
481         (f32)vp->height,
482         0.0F,
483         1.0F );
484     GXSetScissor(
485         (u32)vp->xorig,
486         (u32)vp->yorig,
487         (u32)vp->width,
488         (u32)vp->height );
489 }
490 
491 /*---------------------------------------------------------------------------*
492     Name:           PrintIntro
493 
494     Description:    Prints the directions on how to use this demo.
495 
496     Arguments:      none
497 
498     Returns:        none
499  *---------------------------------------------------------------------------*/
PrintIntro(void)500 static void PrintIntro( void )
501 {
502     OSReport("\n\n");
503     OSReport("************************************************\n");
504     OSReport("tex-filter: texture filter mode test\n");
505     OSReport("************************************************\n");
506     OSReport("to quit hit the start button\n");
507     OSReport("\n");
508     OSReport("  Main Stick   : rotate the box\n");
509     OSReport("  Sub Stick Y  : change scale of the box\n");
510     OSReport("  A button     : change the texture\n");
511     OSReport("  B button     : mipmap on/off\n");
512     OSReport("Descriptions:\n");
513     OSReport("  Upper Left   : Near/Near Filter\n");
514     OSReport("  Upper Right  : Near/Linear Filter\n");
515     OSReport("  Lower Left   : Linear/Near Filter\n");
516     OSReport("  Lower Right  : Linear/Linear Filter\n");
517     OSReport("************************************************\n\n");
518 }
519 
520 /*============================================================================*/
521