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 #include <demo.h>
15 #include <math.h>
16
17 #define SPHERE_MAP_SIZE 128
18 #define SPHERE_MAP_FMT GX_TF_RGB565
19 #define SPHERE_MAP_TESS 40
20
21 /*>*******************************(*)*******************************<*/
22 // defined in spheremap.c so we can look at individual maps and alpha
23 extern u8 CubeFaceStart;
24 extern u8 CubeFaceEnd;
25 extern u8 CubeTevMode;
26
27 /*>*******************************(*)*******************************<*/
28 static Mtx v, m, mv;
29 static Mtx44 proj;
30
31 static Vec CamLoc = {0.0F, 0.0F, 6.0F};
32 static Vec UP = {0.0F, 1.0F, 0.0F};
33 static Vec ObjPt = {0.0F, 0.0F, 0.0F};
34
35 static u8 CurrentTexture;
36
37 static void *mySphere; // sphere geometry display list
38 static u32 mySphereSz; // sphere geometry display list size
39
40 static TPLPalettePtr tpl0 = 0; // cube map files
41 static TPLPalettePtr tpl1 = 0;
42
43 static GXTexObj CubeMap0[6]; // a couple of pre-made cube maps
44 static GXTexObj CubeMap1[6];
45 static GXTexObj SphereMap[2]; // sphere map that is generated
46
47 /*>*******************************(*)*******************************<*/
48 void main ( void );
49 static void InitCamera ( void );
50 static void DrawInit ( void );
51 static void DrawTick ( void );
52 static void InitTexGenMethod ( void );
53 static void AnimTick ( void );
54 static void PrintIntro ( void );
55
56 /*>*******************************(*)*******************************<*/
57 //
58 // from spheremap.c
59 //
60 extern void genMapSphere ( void** display_list,
61 u32* size,
62 u16 tess,
63 GXVtxFmt fmt );
64
65 extern void drawParaboloidMap ( GXTexObj* cubemap,
66 GXTexObj* spheremap,
67 void* dl,
68 u32 dlsz,
69 GXBool front );
70 /*>*******************************(*)*******************************<*/
71
72
main(void)73 void main ( void )
74 {
75 DEMOInit(NULL);
76
77 InitCamera();
78
79 DrawInit();
80 PrintIntro();
81
82 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
83 {
84 DEMOPadRead();
85
86 AnimTick();
87 DEMOBeforeRender();
88
89 DrawTick();
90
91 DEMODoneRender();
92 }
93
94 OSHalt("End of demo");
95 }
96
97 /*>*******************************(*)*******************************<*/
InitCamera(void)98 static void InitCamera ( void )
99 {
100 Mtx44 p;
101
102 MTXOrtho(p, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 100.0f);
103 GXSetProjection(p, GX_ORTHOGRAPHIC);
104
105 MTXLookAt(v, &CamLoc, &UP, &ObjPt);
106 }
107
108 /*>*******************************(*)*******************************<*/
DrawInit(void)109 static void DrawInit ( void )
110 {
111 u32 i;
112 TPLDescriptorPtr tdp;
113 void* tex_buffer;
114
115 GXSetCullMode(GX_CULL_BACK);
116
117 // no zbuffer needed to create the sphere map
118 GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE);
119
120 // sphere map geometry is using format 7
121 // this is for textured quad geometry
122 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
123 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
124
125 //
126 // Initialize texture object for sphere map
127 // - the data will be filled in each time drawSphereMap is called
128 //
129 for (i = 0; i < 2; i++)
130 {
131 tex_buffer = (void*)MEMAllocFromAllocator(&DemoAllocator1,
132 GXGetTexBufferSize(SPHERE_MAP_SIZE, SPHERE_MAP_SIZE,
133 (u32)SPHERE_MAP_FMT, GX_FALSE, 0));
134
135 GXInitTexObj(
136 &SphereMap[i],
137 tex_buffer,
138 SPHERE_MAP_SIZE,
139 SPHERE_MAP_SIZE,
140 SPHERE_MAP_FMT,
141 GX_CLAMP,
142 GX_CLAMP,
143 GX_FALSE);
144 }
145
146 // read pre-made cube map textures
147 // order of loading: right, front, left, back, top, bottom
148 OSReport("Opening gxTests/tg-cube.tpl\n");
149 TPLGetPalette(&tpl0, "gxTests/tg-cube.tpl");
150
151 for (i = 0; i < 6; i++)
152 {
153 tdp = TPLGet(tpl0, i);
154 GXInitTexObj(&CubeMap0[i],
155 tdp->textureHeader->data,
156 tdp->textureHeader->width,
157 tdp->textureHeader->height,
158 (GXTexFmt)tdp->textureHeader->format,
159 GX_CLAMP,
160 GX_CLAMP,
161 GX_FALSE);
162
163 // alpha should be zero on edges, clamp so sphere outside
164 // projected texture is not overwritten
165 GXInitTexObjLOD(&CubeMap0[i],
166 tdp->textureHeader->minFilter,
167 tdp->textureHeader->magFilter,
168 tdp->textureHeader->minLOD,
169 tdp->textureHeader->maxLOD,
170 tdp->textureHeader->LODBias,
171 GX_FALSE,
172 tdp->textureHeader->edgeLODEnable,
173 GX_ANISO_1);
174 }
175
176 // read pre-made cube map textures
177 // order of loading: right, front, left, back, top, bottom
178 OSReport("Opening gxTests/tg-cube1.tpl\n");
179 TPLGetPalette(&tpl1, "gxTests/tg-cube1.tpl");
180
181 for (i = 0; i < 6; i++)
182 {
183 tdp = TPLGet(tpl1, i);
184 GXInitTexObj(&CubeMap1[i],
185 tdp->textureHeader->data,
186 tdp->textureHeader->width,
187 tdp->textureHeader->height,
188 (GXTexFmt)tdp->textureHeader->format,
189 GX_CLAMP,
190 GX_CLAMP,
191 GX_FALSE);
192
193 // alpha should be zero on edges, clamp so sphere outside
194 // projected texture is not overwritten
195 GXInitTexObjLOD(&CubeMap1[i],
196 tdp->textureHeader->minFilter,
197 tdp->textureHeader->magFilter,
198 tdp->textureHeader->minLOD,
199 tdp->textureHeader->maxLOD,
200 tdp->textureHeader->LODBias,
201 GX_FALSE,
202 tdp->textureHeader->edgeLODEnable,
203 GX_ANISO_1);
204 }
205
206 // generate sphere geometry once
207 genMapSphere(&mySphere, &mySphereSz, SPHERE_MAP_TESS, GX_VTXFMT7);
208 }
209
210 /*>*******************************(*)*******************************<*/
DrawTick(void)211 static void DrawTick ( void )
212 {
213 // create sphere map texture
214 if (CurrentTexture) {
215 drawParaboloidMap(&CubeMap1[0], &SphereMap[0], mySphere, mySphereSz, 0);
216 drawParaboloidMap(&CubeMap1[0], &SphereMap[1], mySphere, mySphereSz, 1);
217 }
218 else {
219 drawParaboloidMap(&CubeMap0[0], &SphereMap[0], mySphere, mySphereSz, 0);
220 drawParaboloidMap(&CubeMap0[0], &SphereMap[1], mySphere, mySphereSz, 1);
221 }
222
223 //
224 // Draw sphere map texture on a quad
225 //
226 GXSetViewport(16.0F, 16.0F,
227 400.0F, 400.0F,
228 0.0F, 1.0F);
229
230 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
231 GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
232 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
233 GXSetNumTevStages(1);
234 GXSetNumTexGens(1);
235 GXSetNumChans(0);
236 GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_SET);
237
238 GXClearVtxDesc();
239 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
240 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
241
242 GXInvalidateTexAll();
243 GXLoadTexObj(&SphereMap[0], GX_TEXMAP0);
244
245 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
246 GXPosition3f32(-1.0F, 1.0F, 0.0F);
247 GXTexCoord2f32( 0.0F, 0.0F);
248 GXPosition3f32( 0.0F, 1.0F, 0.0F);
249 GXTexCoord2f32( 1.0F, 0.0F);
250 GXPosition3f32( 0.0F, 0.0F, 0.0F);
251 GXTexCoord2f32( 1.0F, 1.0F);
252 GXPosition3f32(-1.0F, 0.0F, 0.0F);
253 GXTexCoord2f32( 0.0F, 1.0F);
254 GXEnd();
255
256 GXLoadTexObj(&SphereMap[1], GX_TEXMAP0);
257 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
258 GXPosition3f32(0.0F, 1.0F, 0.0F);
259 GXTexCoord2f32(0.0F, 0.0F);
260 GXPosition3f32(1.0F, 1.0F, 0.0F);
261 GXTexCoord2f32(1.0F, 0.0F);
262 GXPosition3f32(1.0F, 0.0F, 0.0F);
263 GXTexCoord2f32(1.0F, 1.0F);
264 GXPosition3f32(0.0F, 0.0F, 0.0F);
265 GXTexCoord2f32(0.0F, 1.0F);
266 GXEnd();
267 }
268
269 /*>*******************************(*)*******************************<*/
AnimTick(void)270 static void AnimTick ( void )
271 {
272 u16 buttons = DEMOPadGetButtonDown(0);
273
274 MTXIdentity(m);
275 MTXConcat(v, m, mv);
276 GXLoadPosMtxImm(mv, GX_PNMTX0);
277 MTXInverse(mv, m);
278 MTXTranspose(m, m);
279 GXLoadNrmMtxImm(m, GX_PNMTX0);
280
281 if (buttons & PAD_BUTTON_B) {
282 CubeFaceStart++;
283 CubeFaceEnd = (u8)(CubeFaceStart + 1);
284
285 if (CubeFaceStart == 5) {
286 CubeFaceStart = 0;
287 CubeFaceEnd = 1;
288 }
289
290 switch(CubeFaceStart)
291 {
292 case 0: OSReport("left/right face\n"); break;
293 case 1: OSReport("right/front face\n"); break;
294 case 2: OSReport("back/left face\n"); break;
295 case 3: OSReport("bottom/top face\n"); break;
296 case 4: OSReport("top/bottom face\n"); break;
297 }
298 }
299
300 if (buttons & PAD_BUTTON_A) {
301 CubeFaceStart = 0;
302 CubeFaceEnd = 5;
303 OSReport("all faces\n");
304 }
305
306 if (buttons & PAD_BUTTON_X) {
307 CurrentTexture ^= 1;
308 OSReport("Texture %d\n", CurrentTexture);
309 }
310
311 if (buttons & PAD_BUTTON_Y) {
312 CubeTevMode++;
313 if (CubeTevMode > 4)
314 CubeTevMode = 0;
315
316 switch (CubeTevMode)
317 {
318 case 0: OSReport("Final result\n"); break;
319 case 1: OSReport("Unclipped texture\n"); break;
320 case 2: OSReport("texture alpha\n"); break;
321 case 3: OSReport("Q-clipping (raster) alpha\n"); break;
322 case 4: OSReport("raster*texture alpha\n"); break;
323 }
324 }
325 }
326
327 /*---------------------------------------------------------------------------*
328 Name: PrintIntro
329
330 Description: Prints the directions on how to use this demo.
331
332 Arguments: none
333
334 Returns: none
335 *---------------------------------------------------------------------------*/
PrintIntro(void)336 static void PrintIntro( void )
337 {
338 OSReport("\n\n");
339 OSReport("*************************************************************\n");
340 OSReport("tg-parabolicmap: create a dual-paraboloid map from a cube map\n");
341 OSReport("*************************************************************\n");
342 OSReport("to quit hit the menu button\n");
343 OSReport("\n");
344 OSReport("A button : display all cube faces in the paraboloid map\n");
345 OSReport("B button : display individual cube faces\n");
346 OSReport("X button : select the cube map texture\n");
347 OSReport("Y button : select alpha/color channel to display\n");
348 OSReport("******************************************************\n");
349 OSReport("\n\n");
350 }
351
352 /*===========================================================================*/
353