1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tex-preload.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-preload
15 simple texture preloading test
16 *---------------------------------------------------------------------------*/
17
18
19 /*---------------------------------------------------------------------------*
20 Header files
21 *---------------------------------------------------------------------------*/
22 #include <demo.h>
23 #include <math.h>
24
25 /*---------------------------------------------------------------------------*
26 Macro definitions
27 *---------------------------------------------------------------------------*/
28 #define PI 3.1415926F
29
30 #define NUM_TEXTURES 16
31
32 /*---------------------------------------------------------------------------*
33 Structure definitions
34 *---------------------------------------------------------------------------*/
35 // for camera
36 typedef struct
37 {
38 Vec location;
39 Vec up;
40 Vec target;
41 f32 left;
42 f32 top;
43 f32 znear;
44 f32 zfar;
45 } CameraConfig;
46
47 typedef struct
48 {
49 CameraConfig cfg;
50 Mtx view;
51 Mtx44 proj;
52 } MyCameraObj;
53
54 // for texture
55 typedef struct
56 {
57 GXTexObj texObjs[NUM_TEXTURES];
58 GXTexRegion texRegions[NUM_TEXTURES];
59 } MyTexCtrlObj;
60
61 // for entire scene control
62 typedef struct
63 {
64 MyCameraObj cam;
65 s32 modelRot;
66 MyTexCtrlObj texCtrl;
67 } MySceneCtrlObj;
68
69 /*---------------------------------------------------------------------------*
70 Forward references
71 *---------------------------------------------------------------------------*/
72 void main ( void );
73 static void DrawInit ( MySceneCtrlObj* sc );
74 static void DrawTick ( MySceneCtrlObj* sc );
75 static void AnimTick ( MySceneCtrlObj* sc );
76 static void DrawCube ( void );
77 static void TexInit ( MyTexCtrlObj* tco );
78 static u32 GetTexBufferSizeEven ( u16 wd, u16 ht, u32 fmt, GXBool mm, u8 max );
79 static u32 GetTexBufferSizeOdd ( u16 wd, u16 ht, u32 fmt, GXBool mm, u8 max );
80 static void SetCamera ( MyCameraObj* cam );
81 static void PrintIntro ( void );
82
83 /*---------------------------------------------------------------------------*
84 Model Data
85 *---------------------------------------------------------------------------*/
86 static s16 CubeVertices[3*8] ATTRIBUTE_ALIGN(32) =
87 {
88 -32, -32, 32, // 0
89 32, -32, 32, // 1
90 32, 32, 32, // 2
91 -32, 32, 32, // 3
92 -32, -32, -32, // 4
93 32, -32, -32, // 5
94 32, 32, -32, // 6
95 -32, 32, -32 // 7
96 };
97
98 static s16 CubeTexCoords[2*4] ATTRIBUTE_ALIGN(32) =
99 {
100 0, 0,
101 1, 0,
102 1, 1,
103 0, 1
104 };
105
106 static u8 CubeFaces[6][4] =
107 {
108 { 3, 2, 1, 0 },
109 { 4, 5, 6, 7 },
110 { 4, 7, 3, 0 },
111 { 5, 4, 0, 1 },
112 { 6, 5, 1, 2 },
113 { 7, 6, 2, 3 }
114 };
115
116 /*---------------------------------------------------------------------------*
117 Camera configuration
118 *---------------------------------------------------------------------------*/
119 static CameraConfig DefaultCamera =
120 {
121 { 0.0F, 0.0F, 500.0F }, // location
122 { 0.0F, 1.0F, 0.0F }, // up
123 { 0.0F, 0.0F, 0.0F }, // target
124 -32.0F, // left
125 24.0F, // top
126 50.0F, // near
127 2000.0F // far
128 };
129
130 /*---------------------------------------------------------------------------*
131 Global variables
132 *---------------------------------------------------------------------------*/
133 static MySceneCtrlObj SceneCtrl; // scene control parameters
134 static TPLPalettePtr MyTplObj = NULL; // texture palette
135
136 /*---------------------------------------------------------------------------*
137 Application main loop
138 *---------------------------------------------------------------------------*/
main(void)139 void main ( void )
140 {
141 DEMOInit(NULL);
142
143 DrawInit(&SceneCtrl); // Initialize vertex formats, array pointers
144 // and default scene settings.
145
146 PrintIntro(); // Print demo directions
147
148 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
149 {
150 DEMOBeforeRender();
151 DrawTick(&SceneCtrl); // Draw the model.
152 DEMODoneRender();
153 DEMOPadRead(); // Read controller
154 AnimTick(&SceneCtrl); // Do animation
155 }
156
157 OSHalt("End of demo");
158 }
159
160 /*---------------------------------------------------------------------------*
161 Functions
162 *---------------------------------------------------------------------------*/
163 /*---------------------------------------------------------------------------*
164 Name: DrawInit
165
166 Description: Initializes the vertex attribute format and sets up
167 the array pointer for the indexed data.
168 This function also initializes scene control parameters.
169
170 Arguments: sc : pointer to the structure of scene control parameters
171
172 Returns: none
173 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)174 static void DrawInit( MySceneCtrlObj* sc )
175 {
176 // Vertex Attribute
177 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
178 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
179
180 // Array pointers
181 GXSetArray(GX_VA_POS, CubeVertices, 3 * sizeof(s16));
182 GXSetArray(GX_VA_TEX0, CubeTexCoords, 2 * sizeof(s16));
183
184 // Initialize texture objects / regions
185 TexInit(&sc->texCtrl);
186
187
188 // Default scene control parameter settings
189
190 // camera
191 sc->cam.cfg = DefaultCamera;
192 SetCamera(&sc->cam); // never changes in this test
193
194 // model rotation parameter
195 sc->modelRot = 0;
196 }
197
198 /*---------------------------------------------------------------------------*
199 Name: DrawTick
200
201 Description: Draw the model by using given scene parameters
202
203 Arguments: sc : pointer to the structure of scene control parameters
204
205 Returns: none
206 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)207 static void DrawTick( MySceneCtrlObj* sc )
208 {
209 s32 i, ti;
210 Mtx mt, mv, mr;
211 f32 px, py;
212
213 // use 2-textures
214 GXSetNumTevStages(2);
215 GXSetTevOp (GX_TEVSTAGE0, GX_REPLACE);
216 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
217 GXSetTevOp (GX_TEVSTAGE1, GX_DECAL);
218 GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR_NULL);
219 GXSetNumTexGens(2);
220 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
221 GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0);
222
223 // entire rotation matrix
224 MTXRotDeg(mv, 'x', (f32)sc->modelRot / 8.0F);
225 MTXRotDeg(mr, 'z', (f32)sc->modelRot);
226 MTXConcat(mv, mr, mr);
227
228 // texcoord matrix
229 MTXTrans(mv, -0.5F, -0.5F, 0.0F);
230 MTXRotDeg(mt, 'z', (f32)sc->modelRot);
231 MTXConcat(mt, mv, mv);
232 MTXTrans(mt, 0.5F, 0.5F, 0.0F);
233 MTXConcat(mt, mv, mv);
234 GXLoadTexMtxImm(mv, GX_TEXMTX0, GX_MTX2x4);
235
236 for ( i = 0 ; i < 8 ; ++i )
237 {
238 // Set modelview matrix
239 px = 220.0F * cosf(i * PI * 45 / 180);
240 py = 220.0F * sinf(i * PI * 45 / 180);
241 MTXTrans( mt, px, py, 0.0F );
242
243 MTXConcat(sc->cam.view, mr, mv);
244 MTXConcat(mv, mt, mv);
245 GXLoadPosMtxImm(mv, GX_PNMTX0);
246
247 // Load preloaded texture
248 ti = ( i * 2 ) % NUM_TEXTURES;
249
250 GXLoadTexObjPreLoaded(
251 &sc->texCtrl.texObjs[ti],
252 &sc->texCtrl.texRegions[ti],
253 GX_TEXMAP0 );
254 GXLoadTexObjPreLoaded(
255 &sc->texCtrl.texObjs[ti+1],
256 &sc->texCtrl.texRegions[ti+1],
257 GX_TEXMAP1 );
258
259 // Draw a textured cube
260 DrawCube();
261 }
262
263 }
264
265 /*---------------------------------------------------------------------------*
266 Name: AnimTick
267
268 Description: Changes scene parameters.
269
270 Arguments: sc : pointer to the structure of scene control parameters
271
272 Returns: none
273 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)274 static void AnimTick( MySceneCtrlObj* sc )
275 {
276 // Model rotation parameter
277 if (!(DEMOPadGetButton(0) & PAD_BUTTON_A ))
278 {
279 sc->modelRot = ( sc->modelRot + 1 ) % ( 360 * 16 );
280 }
281 }
282
283 /*---------------------------------------------------------------------------*
284 Name: DrawCube
285
286 Description: Draw a textured cube.
287
288 Arguments: none
289
290 Returns: none
291 *---------------------------------------------------------------------------*/
DrawCube(void)292 static void DrawCube( void )
293 {
294 u8 i, j;
295
296 // set vertex descriptor
297 GXClearVtxDesc();
298 GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
299 GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
300
301 // draw the box
302 GXBegin(GX_QUADS, GX_VTXFMT0, 4*6);
303 for ( i = 0 ; i < 6 ; ++i )
304 {
305 // Draw a face
306 for ( j = 0 ; j < 4 ; ++j )
307 {
308 GXPosition1x8(CubeFaces[i][j]);
309 GXTexCoord1x8(j);
310 }
311 }
312 GXEnd();
313 }
314
315 /*---------------------------------------------------------------------------*
316 Name: TexInit
317
318 Description: Initialize texture objects and regions for preloaded
319 texture. This function also does preloading.
320
321 Arguments: tco : pointer to a MyTexCtrlObj structure
322
323 Returns: none
324 *---------------------------------------------------------------------------*/
TexInit(MyTexCtrlObj * tco)325 static void TexInit( MyTexCtrlObj* tco )
326 {
327 TPLDescriptorPtr tdp;
328 GXTlutObj tlo;
329 GXBool mipMapFlag;
330 u32 fmt;
331 u16 wd, ht;
332 u8 max;
333 u32 tmemLow, tmemHigh;
334 u32 sizeEven, sizeOdd;
335 u32 i, tlutNum;
336
337 tmemLow = 0x00000;
338 tmemHigh = 0x80000;
339 tlutNum = 0;
340
341 TPLGetPalette(&MyTplObj, "gxTests/tex-08.tpl");
342 for ( i = 0 ; i < NUM_TEXTURES ; ++i )
343 {
344 tdp = TPLGet(MyTplObj, i);
345 mipMapFlag =
346 (GXBool)(( tdp->textureHeader->minLOD == tdp->textureHeader->maxLOD ) ?
347 GX_FALSE : GX_TRUE);
348
349 wd = tdp->textureHeader->width;
350 ht = tdp->textureHeader->height;
351 fmt = tdp->textureHeader->format;
352 max = (u8)tdp->textureHeader->maxLOD;
353
354 // Calculate region size
355 sizeEven = GetTexBufferSizeEven(wd, ht, fmt, mipMapFlag, max);
356 sizeOdd = GetTexBufferSizeOdd(wd, ht, fmt, mipMapFlag, max);
357
358 if (tdp->CLUTHeader)
359 {
360 // CI format
361 GXInitTexObjCI(
362 &tco->texObjs[i],
363 tdp->textureHeader->data,
364 wd,
365 ht,
366 (GXCITexFmt)fmt,
367 tdp->textureHeader->wrapS, // s
368 tdp->textureHeader->wrapT, // t
369 mipMapFlag, // Mipmap
370 tlutNum );
371
372 // Load Tlut data
373 GXInitTlutObj(
374 &tlo,
375 tdp->CLUTHeader->data,
376 (GXTlutFmt)tdp->CLUTHeader->format,
377 tdp->CLUTHeader->numEntries );
378 GXLoadTlut(&tlo, tlutNum);
379
380 // Create new region
381 GXInitTexPreLoadRegion(
382 &tco->texRegions[i],
383 tmemLow, // tmem_even
384 sizeEven, // size_even
385 tmemLow + sizeEven, // tmem_odd
386 sizeOdd ); // size_odd
387 // Both even/odd regions are placed on lower bank
388 // in the case of CI format.
389
390 tmemLow += sizeEven + sizeOdd;
391 ++tlutNum;
392 }
393 else
394 {
395 // Non-CI format
396 GXInitTexObj(
397 &tco->texObjs[i],
398 tdp->textureHeader->data,
399 wd,
400 ht,
401 (GXTexFmt)fmt,
402 tdp->textureHeader->wrapS, // s
403 tdp->textureHeader->wrapT, // t
404 mipMapFlag ); // Mipmap
405
406 // Create new region
407 GXInitTexPreLoadRegion(
408 &tco->texRegions[i],
409 tmemLow, // tmem_even
410 sizeEven, // size_even
411 tmemHigh, // tmem_odd
412 sizeOdd ); // size_odd
413
414 tmemLow += sizeEven;
415 tmemHigh += sizeOdd;
416 }
417
418 // LOD setting
419 GXInitTexObjLOD(
420 &tco->texObjs[i],
421 tdp->textureHeader->minFilter,
422 tdp->textureHeader->magFilter,
423 tdp->textureHeader->minLOD,
424 tdp->textureHeader->maxLOD,
425 tdp->textureHeader->LODBias,
426 GX_FALSE,
427 tdp->textureHeader->edgeLODEnable,
428 GX_ANISO_1 );
429
430 // Preload texture (texture i uses region i)
431 GXPreLoadEntireTexture(&tco->texObjs[i], &tco->texRegions[i]);
432 }
433
434 // In general case, we also have to re-configure
435 // cache regions and region callback in order to avoid
436 // redundant usage of same TMEM space. (Default TMEM
437 // configuration prepares no area for preloading.)
438 // As for this test, such procedure is dispensable
439 // because all textures are preloaded and so GXLoadTexObj
440 // is never called.
441 // (An example of mixture usage of cached/preloaded
442 // textures is shown in tex-mix-mode.c. See it also.)
443 }
444
445 /*---------------------------------------------------------------------------*
446 Name: GetTexBufferSizeEven
447
448 Description: returns memory size for preloading region
449 (for even LODs)
450
451 Arguments: wd : texture width
452 ht : texture height
453 fmt : texture format
454 mm : mipmap switch
455 max : max lod value
456
457 Returns: required region size
458 *---------------------------------------------------------------------------*/
GetTexBufferSizeEven(u16 wd,u16 ht,u32 fmt,GXBool mm,u8 max)459 static u32 GetTexBufferSizeEven( u16 wd, u16 ht, u32 fmt, GXBool mm, u8 max )
460 {
461 u32 i;
462 u32 size;
463
464 if ( fmt == GX_TF_RGBA8 )
465 {
466 // 32bit format (mipmap/non-mipmap)
467 size = GXGetTexBufferSize(wd, ht, fmt, mm, (u8)(max+1));
468 size /= 2;
469 }
470 else if ( mm == GX_FALSE )
471 {
472 // non-mipmap
473 size = GXGetTexBufferSize(wd, ht, fmt, GX_FALSE, 0);
474 }
475 else
476 {
477 // mipmap
478 size = 0;
479 for ( i = 0 ; i <= max ; i += 2 )
480 {
481 size += GXGetTexBufferSize(wd, ht, fmt, GX_FALSE, 1);
482 wd >>= 2;
483 ht >>= 2;
484 }
485 }
486
487 return size;
488 }
489
490 /*---------------------------------------------------------------------------*
491 Name: GetTexBufferSizeOdd
492
493 Description: returns memory size for preloading region
494 (for odd LODs)
495
496 Arguments: wd : texture width
497 ht : texture height
498 fmt : texture format
499 mm : mipmap switch
500 max : max lod value
501
502 Returns: required region size
503 *---------------------------------------------------------------------------*/
GetTexBufferSizeOdd(u16 wd,u16 ht,u32 fmt,GXBool mm,u8 max)504 static u32 GetTexBufferSizeOdd( u16 wd, u16 ht, u32 fmt, GXBool mm, u8 max )
505 {
506 u32 size;
507
508 size = GXGetTexBufferSize(wd, ht, fmt, mm, (u8)(max+1))
509 - GetTexBufferSizeEven(wd, ht, fmt, mm, max);
510
511 return size;
512 }
513
514 /*---------------------------------------------------------------------------*
515 Name: SetCamera
516
517 Description: set view matrix and load projection matrix into hardware
518
519 Arguments: cam : pointer to the MyCameraObj structure
520
521 Returns: none
522 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)523 static void SetCamera( MyCameraObj* cam )
524 {
525 MTXLookAt(
526 cam->view,
527 &cam->cfg.location,
528 &cam->cfg.up,
529 &cam->cfg.target );
530
531 MTXFrustum(
532 cam->proj,
533 cam->cfg.top,
534 - (cam->cfg.top),
535 cam->cfg.left,
536 - (cam->cfg.left),
537 cam->cfg.znear,
538 cam->cfg.zfar );
539 GXSetProjection(cam->proj, GX_PERSPECTIVE);
540 }
541
542 /*---------------------------------------------------------------------------*
543 Name: PrintIntro
544
545 Description: Prints the directions on how to use this demo.
546
547 Arguments: none
548
549 Returns: none
550 *---------------------------------------------------------------------------*/
PrintIntro(void)551 static void PrintIntro( void )
552 {
553 OSReport("\n\n");
554 OSReport("************************************************\n");
555 OSReport("tex-preload: texture preloading test\n");
556 OSReport("************************************************\n");
557 OSReport("to quit hit the start button\n");
558 OSReport("A Button : pause animation while pressed\n");
559 OSReport("\n");
560 OSReport("************************************************\n\n");
561 }
562
563 /*============================================================================*/
564