1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tg-spheremap.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 tg-spheremap
15 An example of environment mapping by sphere map (made from cube map)
16 *---------------------------------------------------------------------------*/
17
18
19 /*---------------------------------------------------------------------------*
20 Header files
21 *---------------------------------------------------------------------------*/
22 #include <demo.h>
23 #include <math.h>
24
25 /*---------------------------------------------------------------------------*
26 Macro definitions
27 *---------------------------------------------------------------------------*/
28 #define SPHERE_MAP_SIZE 256
29 #define SPHERE_MAP_FMT GX_TF_RGB565
30 #define SPHERE_MAP_TESS 30
31
32 /*---------------------------------------------------------------------------*
33 Global variables
34 *---------------------------------------------------------------------------*/
35 // defined in spheremap.c so we can look at individual maps and alpha
36 extern u8 CubeFaceStart;
37 extern u8 CubeFaceEnd;
38 extern u8 CubeTevMode;
39
40 // static
41 static Mtx ViewMtx;
42 static Mtx ModelMtx;
43 static u8 CubeFaceDisp;
44
45 static Vec CamLoc = {0.0F, 0.0F, 4.0F};
46 static Vec UP = {0.0F, 1.0F, 0.0F};
47 static Vec ObjPt = {0.0F, 0.0F, 0.0F};
48
49 static u8 CurrentTexture;
50
51 static void *mySphere; // sphere geometry display list
52 static u32 mySphereSz; // sphere geometry display list size
53
54 static TPLPalettePtr tpl0 = 0; // cube map files
55 static TPLPalettePtr tpl1 = 0;
56
57 static GXTexObj CubeMap0[6]; // a couple of pre-made cube maps
58 static GXTexObj CubeMap1[6];
59 static GXTexObj SphereMap; // sphere map that is generated from cube map
60
61 /*---------------------------------------------------------------------------*
62 External function references
63 *---------------------------------------------------------------------------*/
64 // from spheremap.c
65 extern void genMapSphere ( void** display_list,
66 u32* size,
67 u16 tess,
68 GXVtxFmt fmt );
69
70 extern void drawSphereMap ( GXTexObj* cubemap,
71 GXTexObj* spheremap,
72 void* dl,
73 u32 dlsz );
74
75 /*---------------------------------------------------------------------------*
76 Forward references
77 *---------------------------------------------------------------------------*/
78 void main ( void );
79 static void DrawInit ( void );
80 static void DrawTick ( void );
81 static void InitTexGenMethod ( void );
82 static void AnimTick ( void );
83 static void SetTexGenForSphereMap ( Mtx nMtx );
84 static void SetCamera ( void );
85 static void PrintIntro ( void );
86
87 /*---------------------------------------------------------------------------*
88 Application main loop
89 *---------------------------------------------------------------------------*/
main(void)90 void main ( void )
91 {
92 DEMOInit(NULL);
93
94 DrawInit();
95 PrintIntro();
96
97 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
98 {
99 DEMOPadRead();
100
101 AnimTick();
102 DEMOBeforeRender();
103 DrawTick();
104
105 DEMODoneRender();
106 }
107
108 OSHalt("End of demo");
109 }
110
111 /*---------------------------------------------------------------------------*
112 Name: DrawInit
113
114 Description: Initializes textures, some permanent GX settings and
115 all scene parameters.
116
117 Arguments: none
118 Returns: none
119 *---------------------------------------------------------------------------*/
DrawInit(void)120 static void DrawInit ( void )
121 {
122 u32 i;
123 TPLDescriptorPtr tdp;
124 void* tex_buffer;
125
126 GXSetCullMode(GX_CULL_BACK);
127
128 // sphere map geometry is using format 7
129 // this is for textured quad geometry
130 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
131 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
132
133 //
134 // Initialize texture object for sphere map
135 // - the data will be filled in each time drawSphereMap is called
136 //
137 tex_buffer = (void*)MEMAllocFromAllocator(&DemoAllocator1,
138 GXGetTexBufferSize(SPHERE_MAP_SIZE, SPHERE_MAP_SIZE,
139 (u32)SPHERE_MAP_FMT, GX_FALSE, 0));
140
141 OSReport("tex %08x\n", tex_buffer);
142
143 GXInitTexObj(
144 &SphereMap,
145 tex_buffer,
146 SPHERE_MAP_SIZE,
147 SPHERE_MAP_SIZE,
148 SPHERE_MAP_FMT,
149 GX_CLAMP,
150 GX_CLAMP,
151 GX_FALSE);
152
153 // read textures
154 // order of loading: right, front, left, back, top, bottom
155 OSReport("Opening gxTests/tg-cube.tpl\n");
156 TPLGetPalette(&tpl0, "gxTests/tg-cube.tpl");
157
158 for (i = 0; i < 6; i++)
159 {
160 tdp = TPLGet(tpl0, i);
161 GXInitTexObj(&CubeMap0[i],
162 tdp->textureHeader->data,
163 tdp->textureHeader->width,
164 tdp->textureHeader->height,
165 (GXTexFmt)tdp->textureHeader->format,
166 GX_CLAMP,
167 GX_CLAMP,
168 GX_FALSE);
169
170 // alpha should be zero on edges, clamp so sphere outside
171 // projected texture is not overwritten
172 GXInitTexObjLOD(&CubeMap0[i],
173 tdp->textureHeader->minFilter,
174 tdp->textureHeader->magFilter,
175 tdp->textureHeader->minLOD,
176 tdp->textureHeader->maxLOD,
177 tdp->textureHeader->LODBias,
178 GX_FALSE,
179 tdp->textureHeader->edgeLODEnable,
180 GX_ANISO_1);
181 }
182
183 // read pre-made cube map textures
184 // order of loading: right, front, left, back, top, bottom
185 OSReport("Opening gxTests/tg-cube1.tpl\n");
186 TPLGetPalette(&tpl1, "gxTests/tg-cube1.tpl");
187
188 for (i = 0; i < 6; i++)
189 {
190 tdp = TPLGet(tpl1, i);
191 GXInitTexObj(&CubeMap1[i],
192 tdp->textureHeader->data,
193 tdp->textureHeader->width,
194 tdp->textureHeader->height,
195 (GXTexFmt)tdp->textureHeader->format,
196 GX_CLAMP,
197 GX_CLAMP,
198 GX_FALSE);
199
200 // alpha should be zero on edges, clamp so sphere outside
201 // projected texture is not overwritten
202 GXInitTexObjLOD(&CubeMap1[i],
203 tdp->textureHeader->minFilter,
204 tdp->textureHeader->magFilter,
205 tdp->textureHeader->minLOD,
206 tdp->textureHeader->maxLOD,
207 tdp->textureHeader->LODBias,
208 GX_FALSE,
209 tdp->textureHeader->edgeLODEnable,
210 GX_ANISO_1);
211 }
212
213 // generate sphere geometry once
214 genMapSphere(&mySphere, &mySphereSz, SPHERE_MAP_TESS, GX_VTXFMT7);
215
216 // initialization for contourable parameters
217 CubeFaceDisp = 6;
218 CubeFaceStart = 0;
219 CubeFaceEnd = 6;
220
221 MTXIdentity(ModelMtx);
222 }
223
224 /*---------------------------------------------------------------------------*
225 Name: DrawTick
226
227 Description: Create sphere environment map from cube textures and
228 draw it on a quad. Displays an example 3D object (torus)
229 with texgen for sphere environment mapping.
230
231 Arguments: none
232 Returns: none
233 *---------------------------------------------------------------------------*/
DrawTick(void)234 static void DrawTick ( void )
235 {
236 Mtx mv;
237
238 SetCamera();
239
240 // create sphere map texture
241 if (CurrentTexture)
242 drawSphereMap(&CubeMap1[0], &SphereMap, mySphere, mySphereSz);
243 else
244 drawSphereMap(&CubeMap0[0], &SphereMap, mySphere, mySphereSz);
245
246 // fill screen by another background color
247 GXSetCopyClear((GXColor){ 0x60, 0x60, 0x60, 0xFF }, 0x00FFFFFF);
248 GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
249
250 // Texture/rendering path setting
251 GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_SET);
252 GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
253 GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
254 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
255 GXSetNumTevStages(1);
256 GXSetNumTexGens(1);
257 GXSetNumChans(0);
258
259 GXInvalidateTexAll();
260 GXLoadTexObj(&SphereMap, GX_TEXMAP0);
261
262 // Draw sphere map texture on a quad
263 // (no distortion)
264 GXSetViewport(16.0F, 16.0F, 256.0F, 256.0F, 0.0F, 1.0F);
265
266 GXLoadPosMtxImm(ViewMtx, GX_PNMTX0);
267 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
268
269 GXClearVtxDesc();
270 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
271 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
272
273 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
274 GXPosition3f32(-1.0F, 1.0F, 0.0F);
275 GXTexCoord2f32(0.0F, 0.0F);
276 GXPosition3f32(1.0F, 1.0F, 0.0F);
277 GXTexCoord2f32(1.0F, 0.0F);
278 GXPosition3f32(1.0F, -1.0F, 0.0F);
279 GXTexCoord2f32(1.0F, 1.0F);
280 GXPosition3f32(-1.0F, -1.0F, 0.0F);
281 GXTexCoord2f32(0.0F, 1.0F);
282 GXEnd();
283
284 // Draw environment mapped torus
285 // (uses normal-based spherical projection)
286 GXSetViewport(320.0F, 120.0F, 256.0F, 256.0F, 0.0F, 1.0F);
287
288 MTXConcat(ViewMtx, ModelMtx, mv);
289 GXLoadPosMtxImm(mv, GX_PNMTX0);
290 MTXInvXpose(mv, mv);
291 SetTexGenForSphereMap(mv);
292
293 GXDrawTorus(0.25F, 32, 24);
294
295 // Set background color for the first pass.
296 GXSetCopyClear((GXColor){ 0, 0, 0, 0 }, 0x00FFFFFF);
297 }
298
299 /*---------------------------------------------------------------------------*
300 Name: AnimTick
301
302 Description: Changes scene parameters according to the pad status.
303
304 Arguments: none
305 Returns: none
306 *---------------------------------------------------------------------------*/
AnimTick(void)307 static void AnimTick ( void )
308 {
309 Mtx mrx, mry;
310 u16 buttons = DEMOPadGetButtonDown(0);
311
312 MTXRotDeg(mry, 'x', -(f32)(DEMOPadGetStickY(0))/16.0F);
313 MTXRotDeg(mrx, 'y', (f32)(DEMOPadGetStickX(0))/16.0F);
314 MTXConcat(mry, ModelMtx, ModelMtx);
315 MTXConcat(mrx, ModelMtx, ModelMtx);
316
317 if (buttons & PAD_BUTTON_B)
318 {
319 CubeFaceDisp++;
320 CubeFaceDisp %= 7;
321
322 CubeFaceStart = CubeFaceDisp;
323 CubeFaceEnd = (u8)(CubeFaceStart + 1);
324
325 if ( CubeFaceDisp == 6 )
326 {
327 CubeFaceStart = 0;
328 CubeFaceEnd = 6;
329 }
330
331 switch ( CubeFaceDisp )
332 {
333 case 0: OSReport("right face\n"); break;
334 case 1: OSReport("front face\n"); break;
335 case 2: OSReport("left face\n"); break;
336 case 3: OSReport("back face\n"); break;
337 case 4: OSReport("top face\n"); break;
338 case 5: OSReport("bottom face\n"); break;
339 case 6: OSReport("all faces\n"); break;
340 }
341 }
342
343 if (buttons & PAD_BUTTON_Y)
344 {
345 CubeFaceDisp = 6;
346 CubeFaceStart = 0;
347 CubeFaceEnd = 6;
348 OSReport("all faces\n");
349 }
350
351 if (buttons & PAD_BUTTON_A)
352 {
353 CurrentTexture ^= 1;
354 OSReport("Texture %d\n", CurrentTexture);
355 }
356
357 if (buttons & PAD_TRIGGER_Z)
358 {
359 CubeTevMode++;
360 if (CubeTevMode > 4)
361 CubeTevMode = 0;
362
363 switch (CubeTevMode)
364 {
365 case 0: OSReport("Final result\n"); break;
366 case 1: OSReport("Unclipped texture\n"); break;
367 case 2: OSReport("texture alpha\n"); break;
368 case 3: OSReport("Q-clipping (raster) alpha\n"); break;
369 case 4: OSReport("raster*texture alpha\n"); break;
370 }
371 }
372 }
373
374 /*---------------------------------------------------------------------------*
375 Name: SetTexGenForSphereMap
376
377 Description: Set up texgen for doing spherical environment mapping
378
379 Arguments: nMtx : view normal transformation matrix
380
381 Returns: none
382 *---------------------------------------------------------------------------*/
SetTexGenForSphereMap(Mtx nMtx)383 static void SetTexGenForSphereMap( Mtx nMtx )
384 {
385 Mtx m0, m1, m2;
386
387 MTXScale(m1, 0.50F, -0.50F, 0.0F);
388 MTXTrans(m0, 0.50F, 0.50F, 1.0F);
389 MTXConcat(m0, m1, m2);
390 GXLoadTexMtxImm(nMtx, GX_TEXMTX0, GX_MTX3x4);
391 GXLoadTexMtxImm(m2, GX_PTTEXMTX0, GX_MTX3x4);
392 GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_NRM,
393 GX_TEXMTX0, GX_TRUE, GX_PTTEXMTX0);
394 }
395
396 /*---------------------------------------------------------------------------*
397 Name: SetCamera
398
399 Description: Set projection and view matrix
400
401 Arguments: none
402
403 Returns: none
404 *---------------------------------------------------------------------------*/
SetCamera(void)405 static void SetCamera ( void )
406 {
407 Mtx44 p;
408
409 MTXOrtho(p, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 100.0f);
410 GXSetProjection(p, GX_ORTHOGRAPHIC);
411
412 MTXLookAt(ViewMtx, &CamLoc, &UP, &ObjPt);
413 }
414
415 /*---------------------------------------------------------------------------*
416 Name: PrintIntro
417
418 Description: Prints the directions on how to use this demo.
419
420 Arguments: none
421
422 Returns: none
423 *---------------------------------------------------------------------------*/
PrintIntro(void)424 static void PrintIntro( void )
425 {
426 OSReport("\n\n");
427 OSReport("******************************************************\n");
428 OSReport("tg-spheremap: create a sphere map from a cube map\n");
429 OSReport("******************************************************\n");
430 OSReport("to quit hit the start button\n");
431 OSReport("\n");
432 OSReport("Main Stick : rotate the torus\n");
433 OSReport("A button : select the environment cube map texture\n");
434 OSReport("B button : display individual cube faces\n");
435 OSReport("Y button : display all cube faces in the sphere map\n");
436 OSReport("Z button : select alpha/color channel to display\n");
437 OSReport("******************************************************\n");
438 OSReport("\n\n");
439 }
440
441 /*===========================================================================*/
442