1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: frb-zcopy.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 frb-zcopy
15 Z texture copy test
16 *---------------------------------------------------------------------------*/
17
18
19 /*---------------------------------------------------------------------------*
20 Header files
21 *---------------------------------------------------------------------------*/
22 #include <demo.h>
23 #include <math.h>
24
25 /*---------------------------------------------------------------------------*
26 Macro definitions
27 *---------------------------------------------------------------------------*/
28
29 #define PI 3.14159265358979323846F
30 #define MAX_Z 0x00ffffff // max value of Z buffer
31 #define TEX_SIZE 128
32
33 #define Clamp(val,min,max) \
34 ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
35
36 /*---------------------------------------------------------------------------*
37 Structure definitions
38 *---------------------------------------------------------------------------*/
39 // for camera
40 typedef struct
41 {
42 Vec location;
43 Vec up;
44 Vec target;
45 f32 left;
46 f32 top;
47 f32 znear;
48 f32 zfar;
49 } CameraConfig;
50
51 typedef struct
52 {
53 CameraConfig cfg;
54 Mtx view;
55 Mtx44 proj;
56 s32 theta;
57 s32 phi;
58 } MyCameraObj;
59
60 // for entire scene control
61 typedef struct
62 {
63 MyCameraObj cam;
64 GXTexObj cTexObj;
65 u8* cTexData;
66 GXTexObj zTexObj;
67 u8* zTexData;
68 } MySceneCtrlObj;
69
70 /*---------------------------------------------------------------------------*
71 Forward references
72 *---------------------------------------------------------------------------*/
73 void main ( void );
74 static void DrawInit ( MySceneCtrlObj* sc );
75 static void DrawTick ( MySceneCtrlObj* sc );
76 static void AnimTick ( MySceneCtrlObj* sc );
77 static void DrawQuad ( void );
78 static void DrawUnitCell ( Mtx view );
79 static void DrawCells ( Mtx view );
80 static void SetCamera ( MyCameraObj* cam );
81 static void SetLight ( void );
82 static void DisableLight ( void );
83 static void PrintIntro ( void );
84
85 /*---------------------------------------------------------------------------*
86 Model and texture data
87 *---------------------------------------------------------------------------*/
88
89 #define REG_AMBIENT ColorArray[1]
90 #define LIGHT_COLOR ColorArray[2]
91 #define BG_COLOR ColorArray[3]
92 #define REG_MAT0 ColorArray[4]
93 #define REG_MAT1 ColorArray[5]
94 #define REG_MAT2 ColorArray[6]
95 #define REG_MAT3 ColorArray[7]
96 #define REG_MAT4 ColorArray[8]
97
98 static GXColor ColorArray[] ATTRIBUTE_ALIGN(32) =
99 {
100 { 0x00, 0x00, 0x00, 0x00 }, // Black
101 { 0x40, 0x40, 0x40, 0xFF }, // Gray (Ambient etc.)
102 { 0xFF, 0xFF, 0xFF, 0xFF }, // White (Light etc.)
103 { 0x20, 0x20, 0x20, 0x00 }, // Background
104 { 0xFF, 0xFF, 0xFF, 0xFF }, // Material 0
105 { 0xFF, 0x80, 0xFF, 0xFF }, // Material 1
106 { 0x80, 0xFF, 0xFF, 0xFF }, // Material 2
107 { 0xFF, 0xFF, 0x80, 0xFF }, // Material 3
108 { 0x40, 0x40, 0xFF, 0xFF }, // Material 4
109 };
110
111 #define NUM_CELLS 20
112 static Vec CellLocTbl[NUM_CELLS] =
113 {
114 { 2.5F, 1.5F, -1.5F },
115 { -0.5F, 1.5F, -1.5F },
116 { -3.5F, 1.5F, -1.5F },
117 { -6.5F, 1.5F, -1.5F },
118 { 2.5F, 1.5F, 1.5F },
119 { -0.5F, 1.5F, 1.5F },
120 { -3.5F, 1.5F, 1.5F },
121 { -6.5F, 1.5F, 1.5F },
122 { -2.0F, 0.0F, 0.0F },
123 { -5.0F, 0.0F, 0.0F },
124 { -8.0F, 0.0F, 0.0F },
125 { -2.0F, 3.0F, 0.0F },
126 { 1.0F, 3.0F, 0.0F },
127 { 4.0F, 0.0F, 0.0F },
128 { 5.5F, -1.5F, -1.5F },
129 { 5.5F, -1.5F, 1.5F },
130 { 7.0F, -3.0F, -3.0F },
131 { 7.0F, -3.0F, 3.0F },
132 { -2.0F, 0.0F, -3.0F },
133 { -2.0F, 0.0F, 3.0F }
134 };
135
136 /*---------------------------------------------------------------------------*
137 Camera configuration
138 *---------------------------------------------------------------------------*/
139 static CameraConfig UnitObjCamera =
140 {
141 { 0.0F, 0.0F, 2.0F }, // location (actually not used)
142 { 0.0F, 1.0F, 0.0F }, // up
143 { 0.0F, 0.0F, 0.0F }, // target
144 -2.0F, // left
145 2.0F, // top
146 0.0F, // near
147 128.0F // far
148 };
149
150 static CameraConfig SceneCamera =
151 {
152 { 0.0F, 0.0F, 16.0F }, // location (actually not used)
153 { 0.0F, 1.0F, 0.0F }, // up
154 { 0.0F, 0.0F, 0.0F }, // target
155 -2.0F, // left (actually not used)
156 2.0F, // top (actually not used)
157 0.0F, // near
158 128.0F // far
159 };
160
161 /*---------------------------------------------------------------------------*
162 Global variables
163 *---------------------------------------------------------------------------*/
164 static MySceneCtrlObj SceneCtrl; // scene control parameters
165
166 /*---------------------------------------------------------------------------*
167 Application main loop
168 *---------------------------------------------------------------------------*/
main(void)169 void main ( void )
170 {
171 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
172
173 DrawInit(&SceneCtrl); // Initialize vertex formats, array pointers
174 // and default scene settings.
175
176 PrintIntro(); // Print demo directions
177
178 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
179 {
180 DEMOBeforeRender();
181 DrawTick(&SceneCtrl); // Draw the model.
182 DEMODoneRender();
183 DEMOPadRead(); // Read controller
184 AnimTick(&SceneCtrl); // Do animation
185 }
186
187 OSHalt("End of test");
188 }
189
190 /*---------------------------------------------------------------------------*
191 Functions
192 *---------------------------------------------------------------------------*/
193 /*---------------------------------------------------------------------------*
194 Name: DrawInit
195
196 Description: Initializes the vertex attribute format and sets up
197 the array pointer for the indexed data.
198 This function also initializes scene control parameters.
199
200 Arguments: sc : pointer to the structure of scene control parameters
201
202 Returns: none
203 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)204 static void DrawInit( MySceneCtrlObj* sc )
205 {
206 u32 size;
207
208 // Vertex Attribute
209 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
210 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S8, 0);
211 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
212
213 // Pixel mode, Z compare, alpha compare and background color
214 GXSetPixelFmt(GX_PF_RGBA6_Z24, GX_ZC_LINEAR);
215 GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
216 GXSetZCompLoc(GX_FALSE);
217 GXSetAlphaCompare(GX_EQUAL, 255, GX_AOP_AND, GX_ALWAYS, 0);
218 GXSetCopyClear(BG_COLOR, MAX_Z);
219
220 // Clear background by specified color at first
221 // The operation can be done by dummy display copy.
222 GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
223
224
225 // Default scene control parameter settings
226
227 // camera
228 sc->cam.theta = 0;
229 sc->cam.phi = 0;
230
231 // Texture object for RGBA copy
232 size = GXGetTexBufferSize(TEX_SIZE, TEX_SIZE, GX_TF_RGBA8, GX_FALSE, 0);
233 sc->cTexData = MEMAllocFromAllocator(&DemoAllocator1, size);
234 GXInitTexObj(&sc->cTexObj, sc->cTexData, TEX_SIZE, TEX_SIZE,
235 GX_TF_RGBA8, GX_REPEAT, GX_REPEAT, GX_FALSE);
236 GXInitTexObjLOD(&sc->cTexObj, GX_NEAR, GX_NEAR, 0, 0, 0,
237 GX_FALSE, GX_FALSE, GX_ANISO_1);
238
239 // Texture object for Z copy
240 size = GXGetTexBufferSize(TEX_SIZE, TEX_SIZE, GX_TF_Z24X8, GX_FALSE, 0);
241 sc->zTexData = MEMAllocFromAllocator(&DemoAllocator1, size);
242 GXInitTexObj(&sc->zTexObj, sc->zTexData, TEX_SIZE, TEX_SIZE,
243 GX_TF_Z24X8, GX_REPEAT, GX_REPEAT, GX_FALSE);
244 GXInitTexObjLOD(&sc->zTexObj, GX_NEAR, GX_NEAR, 0, 0, 0,
245 GX_FALSE, GX_FALSE, GX_ANISO_1);
246 }
247
248 /*---------------------------------------------------------------------------*
249 Name: DrawTick
250
251 Description: Draw the scene by using given scene parameters
252
253 Arguments: sc : pointer to the structure of scene control parameters
254
255 Returns: none
256 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)257 static void DrawTick( MySceneCtrlObj* sc )
258 {
259 GXRenderModeObj *rmp;
260 Vec camPos;
261 u16 scrWd, scrHt;
262 f32 r_theta, r_phi;
263
264 // get current rendering mode structure
265 rmp = DEMOGetRenderModeObj();
266 scrWd = rmp->fbWidth;
267 scrHt = rmp->efbHeight;
268
269 // Texture data is changed every frame
270 GXInvalidateTexAll();
271 // turn off Z texture
272 GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z24X8, 0);
273
274 // pre-calculate camera orientation
275 r_theta = sc->cam.theta * PI / 180.0F;
276 r_phi = sc->cam.phi * PI / 180.0F;
277 camPos.x = cosf(r_phi) * sinf(r_theta);
278 camPos.y = sinf(r_phi);
279 camPos.z = cosf(r_phi) * cosf(r_theta);
280
281
282 //-------------------------------------------
283 // Make a image for texture
284 //-------------------------------------------
285
286 // Set up viewport and camera
287 GXSetViewport(0, 0, TEX_SIZE, TEX_SIZE, 0.0F, 1.0F);
288
289 sc->cam.cfg = UnitObjCamera;
290 VECScale(&camPos, &sc->cam.cfg.location, 2.0F);
291 SetCamera(&sc->cam);
292
293 // enable lighting
294 SetLight();
295
296 // Draw an unit model
297 DrawUnitCell(sc->cam.view);
298
299
300 //-------------------------------------------
301 // Copy RGBA / Z image into Texture
302 //-------------------------------------------
303
304 // Turn off vertical de-flicker filter temporary
305 // (to avoid filtering during framebuffer-to-texture copy)
306 GXSetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL);
307
308 // Copy Z image
309 GXSetTexCopySrc(0, 0, TEX_SIZE, TEX_SIZE);
310 GXSetTexCopyDst(TEX_SIZE, TEX_SIZE, GX_TF_Z24X8, GX_FALSE);
311 GXCopyTex(sc->zTexData, GX_FALSE);
312
313 // Copy RGBA image
314 GXSetTexCopySrc(0, 0, TEX_SIZE, TEX_SIZE);
315 GXSetTexCopyDst(TEX_SIZE, TEX_SIZE, GX_TF_RGBA8, GX_FALSE);
316 GXCopyTex(sc->cTexData, GX_TRUE);
317
318 // Wait for finishing all rendering task in the graphics pipeline
319 // while allowing CPU to continue
320 GXPixModeSync();
321
322 // Restore vertical de-flicker filter mode
323 GXSetCopyFilter(rmp->aa, rmp->sample_pattern, GX_TRUE, rmp->vfilter);
324
325 //-------------------------------------------
326 // Make Main Image
327 //-------------------------------------------
328 // Pixel mode for actual image
329 GXSetPixelFmt(GX_PF_RGBA6_Z24, GX_ZC_LINEAR);
330
331 // Set up viewport and camera
332 GXSetViewport(0, 0, scrWd, scrHt, 0.0F, 1.0F);
333 sc->cam.cfg = SceneCamera;
334 sc->cam.cfg.left = - (f32)scrWd * 2.0F / TEX_SIZE;
335 sc->cam.cfg.top = (f32)scrHt * 2.0F / TEX_SIZE;
336 VECScale(&camPos, &sc->cam.cfg.location, 16.0F);
337 SetCamera(&sc->cam);
338
339 // Disable lighting
340 DisableLight();
341
342 // Loads generated Z texture
343 GXLoadTexObj(&sc->cTexObj, GX_TEXMAP0);
344 GXLoadTexObj(&sc->zTexObj, GX_TEXMAP1);
345
346 // Draw billboards
347 DrawCells(sc->cam.view);
348 }
349
350 /*---------------------------------------------------------------------------*
351 Name: AnimTick
352
353 Description: Changes scene parameters according to the pad status.
354
355 Arguments: sc : pointer to the structure of scene control parameters
356
357 Returns: none
358 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)359 static void AnimTick( MySceneCtrlObj* sc )
360 {
361 // camera position
362 sc->cam.theta += ( DEMOPadGetStickX(0) / 24 );
363 sc->cam.theta = ( sc->cam.theta + 360 ) % 360;
364
365 sc->cam.phi += ( DEMOPadGetStickY(0) / 24 );
366 Clamp(sc->cam.phi, -80, 80);
367
368 }
369
370 /*---------------------------------------------------------------------------*
371 Name: DrawQuad
372
373 Description: Draw a textured quad
374
375 Arguments: none
376
377 Returns: none
378 *---------------------------------------------------------------------------*/
DrawQuad(void)379 static void DrawQuad( void )
380 {
381 // set vertex descriptor
382 GXClearVtxDesc();
383 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
384 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
385
386 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
387 GXPosition3s16( -2, 2, 0 );
388 GXTexCoord2s8( 0, 0 );
389 GXPosition3s16( 2, 2, 0 );
390 GXTexCoord2s8( 1, 0 );
391 GXPosition3s16( 2, -2, 0 );
392 GXTexCoord2s8( 1, 1 );
393 GXPosition3s16( -2, -2, 0 );
394 GXTexCoord2s8( 0, 1 );
395 GXEnd();
396 }
397
398 /*---------------------------------------------------------------------------*
399 Name: DrawUnitCell
400
401 Description: Draw an unit model
402
403 Arguments: view : view matrix
404
405 Returns: none
406 *---------------------------------------------------------------------------*/
DrawUnitCell(Mtx view)407 static void DrawUnitCell( Mtx view )
408 {
409 Mtx ms, mr, mt, mv, mvi;
410 s32 i, j, x, y, z;
411
412 // set shading mode to use lit vertex color only
413 GXSetNumTevStages(1);
414 GXSetNumTexGens(0);
415 GXSetNumChans(1);
416 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
417 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
418
419
420 // Eight corners
421 GXSetChanMatColor(GX_COLOR0A0, REG_MAT0);
422 MTXScale(ms, 0.25F, 0.25F, 0.25F);
423 for ( i = 0 ; i < 8 ; ++i )
424 {
425 x = ( i & 1 ) ? -1 : 1;
426 y = ( i & 2 ) ? -1 : 1;
427 z = ( i & 4 ) ? -1 : 1;
428
429 MTXTrans(mt, x, y, z);
430 MTXConcat(mt, ms, mv);
431 MTXConcat(view, mv, mv);
432
433 GXLoadPosMtxImm(mv, GX_PNMTX0);
434 MTXInverse(mv, mvi);
435 MTXTranspose(mvi, mv);
436 GXLoadNrmMtxImm(mv, GX_PNMTX0);
437
438 GXDrawSphere1(2);
439 }
440
441 // Twelve edges
442 MTXScale(ms, 0.15F, 0.15F, 1.0F);
443 for ( i = 0 ; i < 3 ; ++i )
444 {
445 switch(i)
446 {
447 case 0 :
448 GXSetChanMatColor(GX_COLOR0A0, REG_MAT1);
449 MTXIdentity(mr);
450 break;
451 case 1 :
452 GXSetChanMatColor(GX_COLOR0A0, REG_MAT2);
453 MTXRotDeg(mr, 'x', 90);
454 break;
455 case 2 :
456 GXSetChanMatColor(GX_COLOR0A0, REG_MAT3);
457 MTXRotDeg(mr, 'y', 90);
458 break;
459 }
460
461 for ( j = 0 ; j < 4 ; ++j )
462 {
463 x = ( j & 1 ) ? -1 : 1;
464 y = ( j & 2 ) ? -1 : 1;
465 z = 0;
466
467 MTXTrans(mt, x, y, z);
468 MTXConcat(mt, ms, mv);
469 MTXConcat(mr, mv, mt);
470 MTXConcat(view, mt, mv);
471
472 GXLoadPosMtxImm(mv, GX_PNMTX0);
473 MTXInverse(mv, mvi);
474 MTXTranspose(mvi, mv);
475 GXLoadNrmMtxImm(mv, GX_PNMTX0);
476
477 GXDrawCylinder(16);
478 }
479 }
480
481 // Center sphere
482 GXSetChanMatColor(GX_COLOR0A0, REG_MAT4);
483 MTXScale(ms, 0.40F, 0.40F, 0.40F);
484 MTXConcat(view, ms, mv);
485
486 GXLoadPosMtxImm(mv, GX_PNMTX0);
487 MTXInverse(mv, mvi);
488 MTXTranspose(mvi, mv);
489 GXLoadNrmMtxImm(mv, GX_PNMTX0);
490
491 GXDrawSphere1(2);
492 }
493
494 /*---------------------------------------------------------------------------*
495 Name: DrawCells
496
497 Description: Draw cells which position is defined in the table.
498 Each cell is drawn by using a billboard with run-time
499 rendered RGBA/Z texture.
500
501 Arguments: view : view matrix
502
503 Returns: none
504 *---------------------------------------------------------------------------*/
DrawCells(Mtx view)505 static void DrawCells( Mtx view )
506 {
507 Vec loc;
508 Mtx mt;
509 u32 i;
510
511 // set shading mode to use texture / Z texture
512 GXSetNumTevStages(2);
513 GXSetNumTexGens(1);
514 GXSetNumChans(0);
515
516 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
517
518 GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
519 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
520 // The second stage uses texture input only for Z texturing.
521 // So this stage simply passes previous stage output.
522 GXSetTevOp(GX_TEVSTAGE1, GX_PASSCLR);
523 GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR_NULL);
524
525 GXSetZTexture(GX_ZT_ADD, GX_TF_Z24X8, 0);
526
527 for ( i = 0 ; i < NUM_CELLS ; ++i )
528 {
529 // modelview matrix for billboards
530 // location of each cell is defined in the table.
531 MTXMultVec(view, &CellLocTbl[i], &loc);
532 MTXTrans(mt, loc.x, loc.y, loc.z);
533 GXLoadPosMtxImm(mt, GX_PNMTX0);
534
535 DrawQuad();
536 }
537
538 }
539
540 /*---------------------------------------------------------------------------*
541 Name: SetCamera
542
543 Description: set view matrix and load projection matrix into hardware
544
545 Arguments: cam : pointer to the MyCameraObj structure
546
547 Returns: none
548 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)549 static void SetCamera( MyCameraObj* cam )
550 {
551 MTXLookAt(
552 cam->view,
553 &cam->cfg.location,
554 &cam->cfg.up,
555 &cam->cfg.target );
556
557 MTXOrtho(
558 cam->proj,
559 cam->cfg.top,
560 - (cam->cfg.top),
561 cam->cfg.left,
562 - (cam->cfg.left),
563 cam->cfg.znear,
564 cam->cfg.zfar );
565 GXSetProjection(cam->proj, GX_ORTHOGRAPHIC);
566 }
567
568 /*---------------------------------------------------------------------------*
569 Name: SetLight
570
571 Description: Sets light objects and color channels
572
573 Arguments: le : pointer to a MyLightEnvObj structure
574 view : view matrix.
575
576 Returns: none
577 *---------------------------------------------------------------------------*/
SetLight(void)578 static void SetLight( void )
579 {
580 GXLightObj lobj;
581
582 // set up light position and color
583 GXInitLightPos(&lobj, 0.0F, 10000.0F, 10000.0F); // almost parallel
584 GXInitLightColor(&lobj, LIGHT_COLOR);
585 GXLoadLightObjImm(&lobj, GX_LIGHT0);
586
587 // channel setting
588 GXSetChanCtrl(
589 GX_COLOR0A0,
590 GX_ENABLE, // enable channel
591 GX_SRC_REG, // amb source
592 GX_SRC_REG, // mat source
593 GX_LIGHT0, // light mask
594 GX_DF_CLAMP, // diffuse function
595 GX_AF_NONE); // attenuation function
596 // channel ambient
597 GXSetChanAmbColor(GX_COLOR0A0, REG_AMBIENT);
598 }
599
600 /*---------------------------------------------------------------------------*
601 Name: DisableLight
602
603 Description: Disables lighting
604
605 Arguments: none
606
607 Returns: none
608 *---------------------------------------------------------------------------*/
DisableLight(void)609 static void DisableLight( void )
610 {
611 GXSetChanCtrl(
612 GX_COLOR0A0,
613 GX_DISABLE, // disable channel
614 GX_SRC_REG, // amb source
615 GX_SRC_VTX, // mat source
616 GX_LIGHT_NULL, // light mask
617 GX_DF_NONE, // diffuse function
618 GX_AF_NONE);
619 }
620
621 /*---------------------------------------------------------------------------*
622 Name: PrintIntro
623
624 Description: Prints the directions on how to use this demo.
625
626 Arguments: none
627
628 Returns: none
629 *---------------------------------------------------------------------------*/
PrintIntro(void)630 static void PrintIntro( void )
631 {
632 OSReport("\n\n");
633 OSReport("************************************************\n");
634 OSReport("frb-zcopy: Z texture copy from EFB\n");
635 OSReport("************************************************\n");
636 OSReport("to quit hit the start button\n");
637 OSReport("\n");
638 OSReport("Main Stick: move camera\n");
639 OSReport("************************************************\n\n");
640 }
641
642 /*============================================================================*/
643