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