1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tex-mix-mode.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-mix-mode
15 mixture of cached / preloaded textures test
16 *---------------------------------------------------------------------------*/
17
18
19 /*---------------------------------------------------------------------------*
20 Header files
21 *---------------------------------------------------------------------------*/
22 #include <demo.h>
23
24 /*---------------------------------------------------------------------------*
25 Macro definitions
26 *---------------------------------------------------------------------------*/
27 #define NUM_TEXTURES 16
28 #define NUM_REGIONS 8
29
30 /*---------------------------------------------------------------------------*
31 Structure definitions
32 *---------------------------------------------------------------------------*/
33 // for camera
34 typedef struct
35 {
36 Vec location;
37 Vec up;
38 Vec target;
39 f32 left;
40 f32 top;
41 f32 znear;
42 f32 zfar;
43 } CameraConfig;
44
45 typedef struct
46 {
47 CameraConfig cfg;
48 Mtx view;
49 Mtx44 proj;
50 } MyCameraObj;
51
52 // for texture (includes region control)
53 typedef struct
54 {
55 u32 numPreload;
56 u32 numGen0;
57 u32 numGen1;
58 GXTexObj texObjs[NUM_TEXTURES];
59 GXTexRegion texRegions[NUM_REGIONS];
60 } MyTexCtrlObj;
61
62 // for entire scene control
63 typedef struct
64 {
65 MyCameraObj cam;
66 s32 modelRot;
67 s32 duplication;
68 MyTexCtrlObj texCtrl;
69 } MySceneCtrlObj;
70
71 /*---------------------------------------------------------------------------*
72 Forward references
73 *---------------------------------------------------------------------------*/
74 void main ( void );
75 static void DrawInit ( MySceneCtrlObj* sc );
76 static void DrawTick ( MySceneCtrlObj* sc );
77 static void AnimTick ( MySceneCtrlObj* sc );
78 static void DrawCube ( MyTexCtrlObj* tco );
79 static void LoadOneTexture ( MyTexCtrlObj* tco );
80 static void InitTexNumGen ( MyTexCtrlObj* tco );
81 static void ConfigureTmemMap ( MyTexCtrlObj* tco );
82 static void SetCamera ( MyCameraObj* cam );
83 static void StatusMessage ( u32 numPreload );
84 static void PrintIntro ( void );
85 static GXTexRegion*
86 MyTexRegionCallback( const GXTexObj* texObj, GXTexMapID mapID );
87
88 /*---------------------------------------------------------------------------*
89 Model Data
90 *---------------------------------------------------------------------------*/
91 static s16 CubeVertices[3*8] ATTRIBUTE_ALIGN(32) =
92 {
93 -32, -32, 32, // 0
94 32, -32, 32, // 1
95 32, 32, 32, // 2
96 -32, 32, 32, // 3
97 -32, -32, -32, // 4
98 32, -32, -32, // 5
99 32, 32, -32, // 6
100 -32, 32, -32 // 7
101 };
102
103 static s16 CubeTexCoords[2*4] ATTRIBUTE_ALIGN(32) =
104 {
105 0, 0,
106 1, 0,
107 1, 1,
108 0, 1
109 };
110
111 static u8 CubeFaces[6][4] =
112 {
113 { 3, 2, 1, 0 },
114 { 4, 5, 6, 7 },
115 { 4, 7, 3, 0 },
116 { 5, 4, 0, 1 },
117 { 6, 5, 1, 2 },
118 { 7, 6, 2, 3 }
119 };
120
121 /*---------------------------------------------------------------------------*
122 Camera configuration
123 *---------------------------------------------------------------------------*/
124 static CameraConfig DefaultCamera =
125 {
126 { 0.0F, 0.0F, 500.0F }, // location
127 { 0.0F, 1.0F, 0.0F }, // up
128 { 0.0F, 0.0F, 0.0F }, // target
129 -320.0F, // left
130 240.0F, // top
131 50.0F, // near
132 2000.0F // far
133 };
134
135 /*---------------------------------------------------------------------------*
136 Global variables
137 *---------------------------------------------------------------------------*/
138 static MySceneCtrlObj SceneCtrl; // scene control parameters
139 static TPLPalettePtr MyTplObj = NULL; // texture palette
140
141 /*---------------------------------------------------------------------------*
142 Application main loop
143 *---------------------------------------------------------------------------*/
main(void)144 void main ( void )
145 {
146 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
147
148 DrawInit(&SceneCtrl); // Initialize vertex formats, array pointers
149 // and default scene settings.
150
151 PrintIntro(); // Print demo directions
152
153 StatusMessage(SceneCtrl.texCtrl.numPreload);
154 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
155 {
156 DEMOBeforeRender();
157 DrawTick(&SceneCtrl); // Draw the model.
158 DEMODoneRender();
159 DEMOPadRead(); // Read controller
160 AnimTick(&SceneCtrl); // Do animation
161 }
162
163 OSHalt("End of demo");
164 }
165
166 /*---------------------------------------------------------------------------*
167 Functions
168 *---------------------------------------------------------------------------*/
169 /*---------------------------------------------------------------------------*
170 Name: DrawInit
171
172 Description: Initializes the vertex attribute format and sets up
173 the array pointer for the indexed data.
174 This function also initializes scene control parameters.
175
176 Arguments: sc : pointer to the structure of scene control parameters
177
178 Returns: none
179 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)180 static void DrawInit( MySceneCtrlObj* sc )
181 {
182 TPLDescriptorPtr tdp;
183 GXBool mipMapFlag;
184 u32 i;
185
186 // Vertex Attribute
187 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
188 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
189
190 // Array pointers
191 GXSetArray(GX_VA_POS, CubeVertices, 3 * sizeof(s16));
192 GXSetArray(GX_VA_TEX0, CubeTexCoords, 2 * sizeof(s16));
193
194 // Texture coords
195 GXSetNumTexGens(1);
196 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
197
198 // Color channels
199 GXSetNumChans(0);
200
201 // Use user-defined tex region Callback
202 GXSetTexRegionCallback(MyTexRegionCallback);
203
204 // Load TPL file and initialize texture objects
205 TPLGetPalette(&MyTplObj, "gxTests/tex-07.tpl");
206 for ( i = 0 ; i < NUM_TEXTURES ; ++i )
207 {
208 tdp = TPLGet(MyTplObj, i);
209 mipMapFlag =
210 (GXBool)(( tdp->textureHeader->minLOD == tdp->textureHeader->maxLOD ) ?
211 GX_FALSE : GX_TRUE);
212
213 GXInitTexObj(
214 &sc->texCtrl.texObjs[i],
215 tdp->textureHeader->data,
216 tdp->textureHeader->width,
217 tdp->textureHeader->height,
218 (GXTexFmt)tdp->textureHeader->format,
219 tdp->textureHeader->wrapS, // s
220 tdp->textureHeader->wrapT, // t
221 mipMapFlag ); // Mipmap
222
223 GXInitTexObjLOD(
224 &sc->texCtrl.texObjs[i],
225 tdp->textureHeader->minFilter,
226 tdp->textureHeader->magFilter,
227 tdp->textureHeader->minLOD,
228 tdp->textureHeader->maxLOD,
229 tdp->textureHeader->LODBias,
230 GX_FALSE,
231 tdp->textureHeader->edgeLODEnable,
232 GX_ANISO_1 );
233 }
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 // number of preload textures
243 sc->texCtrl.numPreload = 0;
244
245 // number of drawing duplications
246 sc->duplication = 1;
247
248 // model rotation parameter
249 sc->modelRot = 0;
250 }
251
252 /*---------------------------------------------------------------------------*
253 Name: DrawTick
254
255 Description: Draw the model by using given scene parameters
256
257 Arguments: sc : pointer to the structure of scene control parameters
258
259 Returns: none
260 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)261 static void DrawTick( MySceneCtrlObj* sc )
262 {
263 Mtx mt, mv, mr;
264 s32 x, y, z;
265
266 // configure tmem map
267 ConfigureTmemMap(&sc->texCtrl);
268
269 // use texture in Tev
270 GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
271 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
272
273 // common rotation matrix
274 MTXRotDeg(mv, 'y', sc->modelRot);
275 MTXRotDeg(mr, 'x', sc->modelRot * 2);
276 MTXConcat(mv, mr, mr);
277
278 // initialize tex number generator
279 InitTexNumGen(&sc->texCtrl);
280
281 for ( z = sc->duplication ; z > 0 ; --z )
282 {
283 // display 8x6 cubes
284 for ( y = 0 ; y < 6 ; ++y )
285 {
286 for ( x = 0 ; x < 8 ; ++x )
287 {
288 // Set modelview matrix
289 MTXTrans( mt,
290 (f32)(x * 80 + z * 5 - 280),
291 (f32)(y * 80 + z * 5 - 200),
292 (f32)(z * -100) );
293 MTXConcat(sc->cam.view, mt, mv);
294 MTXConcat(mv, mr, mv);
295 GXLoadPosMtxImm(mv, GX_PNMTX0);
296
297 // Draw a textured cube
298 DrawCube(&sc->texCtrl);
299
300 } // x
301 } // y
302 } // z
303
304 }
305
306 /*---------------------------------------------------------------------------*
307 Name: AnimTick
308
309 Description: Changes scene parameters according to the pad status.
310
311 Arguments: sc : pointer to the structure of scene control parameters
312
313 Returns: none
314 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)315 static void AnimTick( MySceneCtrlObj* sc )
316 {
317 u16 down = DEMOPadGetButtonDown(0);
318
319
320 // Model rotation parameter
321 sc->modelRot = ( sc->modelRot + 1 ) % 360;
322
323
324 // Change number of preloaded textures
325 if ( ( down & PAD_TRIGGER_L ) && sc->texCtrl.numPreload > 0 )
326 {
327 sc->texCtrl.numPreload -= 1;
328 StatusMessage(sc->texCtrl.numPreload);
329 }
330
331 if ( ( down & PAD_TRIGGER_R ) && sc->texCtrl.numPreload < NUM_REGIONS - 1 )
332 {
333 sc->texCtrl.numPreload += 1;
334 StatusMessage(sc->texCtrl.numPreload);
335 }
336
337 // Change number of drawing duplications
338 if ( ( down & PAD_BUTTON_Y ) && sc->duplication > 1 )
339 {
340 sc->duplication -= 1;
341 OSReport("Drawing %d layers\n", sc->duplication);
342 }
343
344 if ( ( down & PAD_BUTTON_X ) && sc->duplication < 8 )
345 {
346 sc->duplication += 1;
347 OSReport("Drawing %d layers\n", sc->duplication);
348 }
349 }
350
351 /*---------------------------------------------------------------------------*
352 Name: DrawCube
353
354 Description: Draw a textured cube. Each face can have different texture
355 which is automatically set by LoadOneTexture function.
356
357 Arguments: tco : texture control object which includes
358 texture map set mapped on faces
359
360 Returns: none
361 *---------------------------------------------------------------------------*/
DrawCube(MyTexCtrlObj * tco)362 static void DrawCube( MyTexCtrlObj* tco )
363 {
364 u8 i, j;
365
366 // set vertex descriptor
367 GXClearVtxDesc();
368 GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
369 GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
370
371 // draw the box
372 for ( i = 0 ; i < 6 ; ++i )
373 {
374 LoadOneTexture(tco);
375
376 // Draw a face
377 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
378 for ( j = 0 ; j < 4 ; ++j )
379 {
380 GXPosition1x8(CubeFaces[i][j]);
381 GXTexCoord1x8(j);
382 }
383 GXEnd();
384 }
385 }
386
387 /*---------------------------------------------------------------------------*
388 Name: LoadOneTexture
389
390 Description: Load an appropriate texture (which number is
391 generated automatically)
392 If the texture is preloaded, this function calls
393 GXLoadTexObjPreLoaded and use preloaded region.
394
395 Arguments: tco : texture control object which includes
396 texture map set to be mapped on
397
398 Returns: none
399 *---------------------------------------------------------------------------*/
LoadOneTexture(MyTexCtrlObj * tco)400 static void LoadOneTexture( MyTexCtrlObj* tco )
401 {
402 u32 texNo;
403
404 // Generate an appropriate number
405 texNo = tco->numGen0;
406 if ( ++(tco->numGen0) > tco->numGen1 )
407 {
408 tco->numGen0 = 0;
409 tco->numGen1 = ( tco->numGen1 + 1 ) % NUM_TEXTURES;
410 }
411
412 // Load texture object
413 if ( texNo < tco->numPreload )
414 {
415 GXLoadTexObjPreLoaded(
416 &tco->texObjs[texNo],
417 (GXTexRegion*)(GXGetTexObjUserData(&tco->texObjs[texNo])),
418 GX_TEXMAP0 );
419 }
420 else
421 {
422 GXLoadTexObj(&tco->texObjs[texNo], GX_TEXMAP0);
423 }
424 }
425
426 /*---------------------------------------------------------------------------*
427 Name: InitTexNumGen
428
429 Description: Initialize parameters for generating texture number
430 which is used in LoadOneTexture function.
431
432 Arguments: tco : texture control object in which parameters
433 should be initialized
434
435 Returns: none
436 *---------------------------------------------------------------------------*/
InitTexNumGen(MyTexCtrlObj * tco)437 static void InitTexNumGen( MyTexCtrlObj* tco )
438 {
439 tco->numGen0 = 0;
440 tco->numGen1 = 0;
441 }
442
443 /*---------------------------------------------------------------------------*
444 Name: ConfigureTmemMap
445
446 Description: Initialize TMEM configuration. Set up cache regions
447 and preloading regions. This function also preloads
448 specified textures.
449 Texture #0 - #(numPreload - 1) are preloaded.
450
451 Arguments: tco : a pointer to MyTexCtrlObj structure which
452 includes number of preloaded texture, texture
453 object array and region array.
454
455 Returns: none
456 *---------------------------------------------------------------------------*/
ConfigureTmemMap(MyTexCtrlObj * tco)457 static void ConfigureTmemMap( MyTexCtrlObj* tco )
458 {
459 u32 i, r;
460 u32 numPreload, numCaches;
461
462 // Synchronization for new TMEM cache configuration
463 GXTexModeSync();
464
465 numPreload = tco->numPreload;
466 numCaches = NUM_REGIONS - numPreload;
467
468 for ( i = 0 ; i < NUM_REGIONS ; ++i )
469 {
470 if ( i < numPreload )
471 {
472 // The region is used for preloading.
473 // Though this test is using only 32K region, it is possible
474 // to use any 32byte-aligned region for preloading.
475 GXInitTexPreLoadRegion(
476 &tco->texRegions[i],
477 0x00000 + i * 0x08000, // tmem_even
478 0x08000, // size_even
479 0x80000 + i * 0x08000, // tmem_odd
480 0x08000 ); // size_odd
481
482 // Preload texture (tex No.i uses region No.i respectively)
483 GXPreLoadEntireTexture(&tco->texObjs[i], &tco->texRegions[i]);
484 // The userdata field keeps the pointer to region object.
485 GXInitTexObjUserData(
486 &tco->texObjs[i],
487 (void*)(&tco->texRegions[i]) );
488 }
489 else
490 {
491 // The region is used as a cache.
492 GXInitTexCacheRegion(
493 &tco->texRegions[i],
494 GX_FALSE, // 32b mipmap
495 0x00000 + i * 0x08000, // tmem_even
496 GX_TEXCACHE_32K, // size_even
497 0x80000 + i * 0x08000, // tmem_odd
498 GX_TEXCACHE_32K ); // size_odd
499 }
500 }
501
502 // Decide which cache region should be used beforehand.
503 for ( i = numPreload ; i < NUM_TEXTURES ; ++i )
504 {
505 // Get appropriate cache region number.
506 r = numPreload + ( i % numCaches );
507 // The userdata field keeps the pointer to region object directly.
508 GXInitTexObjUserData(
509 &tco->texObjs[i],
510 (void*)(&tco->texRegions[r]) );
511 }
512
513 // Invalidate all new caches.
514 GXInvalidateTexAll();
515 }
516
517 /*---------------------------------------------------------------------------*
518 Name: MyTexRegionCallback
519
520 Description: User-defined Callback function for texture cache
521 region allocation
522
523 Arguments: texObj : a pointer to texture object to be loaded
524 mapID : destination texmap ID (just same as GXLoadTexObj)
525
526 Returns: appropriate tex cache region for loading texture.
527 *---------------------------------------------------------------------------*/
MyTexRegionCallback(const GXTexObj * texObj,GXTexMapID mapID)528 static GXTexRegion* MyTexRegionCallback(const GXTexObj* texObj, GXTexMapID mapID)
529 {
530 #pragma unused(mapID)
531
532 // In this test, userdata field already has a pointer
533 // to cache region to be used.
534 return (GXTexRegion*)(GXGetTexObjUserData(texObj));
535 }
536
537 /*---------------------------------------------------------------------------*
538 Name: SetCamera
539
540 Description: set view matrix and load projection matrix into hardware
541
542 Arguments: cam : pointer to the MyCameraObj structure
543
544 Returns: none
545 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)546 static void SetCamera( MyCameraObj* cam )
547 {
548 MTXLookAt(
549 cam->view,
550 &cam->cfg.location,
551 &cam->cfg.up,
552 &cam->cfg.target );
553
554 MTXOrtho(
555 cam->proj,
556 cam->cfg.top,
557 - (cam->cfg.top),
558 cam->cfg.left,
559 - (cam->cfg.left),
560 cam->cfg.znear,
561 cam->cfg.zfar );
562 GXSetProjection(cam->proj, GX_ORTHOGRAPHIC);
563 }
564
565 /*---------------------------------------------------------------------------*
566 Name: StatusMessage
567
568 Description: Prints current status (number of preloaded textures.)
569
570 Arguments: numPreload : number of preloaded textures
571
572 Returns: none
573 *---------------------------------------------------------------------------*/
StatusMessage(u32 numPreload)574 static void StatusMessage( u32 numPreload )
575 {
576 if ( numPreload == 0 )
577 {
578 OSReport("No preloaded texture\n");
579 }
580 else if ( numPreload == 1 )
581 {
582 OSReport("0 : preloaded / 1-15 : cached\n");
583 }
584 else
585 {
586 OSReport("0-%d : preloaded / %d-15 : cached\n",
587 numPreload-1, numPreload);
588 }
589 }
590
591 /*---------------------------------------------------------------------------*
592 Name: PrintIntro
593
594 Description: Prints the directions on how to use this demo.
595
596 Arguments: none
597
598 Returns: none
599 *---------------------------------------------------------------------------*/
PrintIntro(void)600 static void PrintIntro( void )
601 {
602 OSReport("\n\n");
603 OSReport("************************************************\n");
604 OSReport("tex-mix-mode: mixture of preloaded/cached tex test\n");
605 OSReport("************************************************\n");
606 OSReport("to quit hit the start button\n");
607 OSReport("\n");
608 OSReport("L/R Triggers : Change number of preloaded texture.\n");
609 OSReport("X/Y Buttons : Change number of layers to be drawn.\n");
610 OSReport("************************************************\n\n");
611 }
612
613 /*============================================================================*/
614