1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: frb-fld-dbs-aa.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
18 #define OCT_DEPTH_MIN 1 // min octahedron recursion depth
19 #define OCT_DEPTH_MAX 6 // max octahedron recursion depth
20
21 // Octahedron vertices
22 static f32 vertNorth[] = { 0.0f, 0.0f, 1.0f };
23 static f32 vertSouth[] = { 0.0f, 0.0f, -1.0f };
24 static f32 vertEquator[] =
25 {
26 1.0f, 0.0f, 0.0f,
27 0.0f, 1.0f, 0.0f,
28 -1.0f, 0.0f, 0.0f,
29 0.0f, -1.0f, 0.0f
30 };
31
32 // An alternate sample pattern & filter to try out
33 static u8 mySamples[12][2] = {
34 3, 3, 10, 5, 5, 10,
35 7, 2, 2, 7, 9, 9,
36 7, 2, 2, 7, 9, 9,
37 3, 3, 10, 5, 5, 10,
38 };
39
40 static u8 myFilter[7] = {
41 0, 8, 16, 16, 16, 8, 0
42 };
43
44 static u32 Ticks = 0; // time counter
45 static u8 animMode = 1; // whether animation is going or stopped
46 static u8 drawMode = 0; // which pattern to draw
47 static u8 aaMode = 0; // which filters to use
48
49 static u32 octDepth = 3;
50
51 GXRenderModeObj *rMode;
52
53 /*---------------------------------------------------------------------------*
54 Forward references
55 *---------------------------------------------------------------------------*/
56
57 void main ( void );
58 static void CameraInit ( Mtx v );
59 static void DrawInit ( void );
60 static void DrawTick ( Mtx v );
61 static void AnimTick ( void );
62 static void PrintIntro ( void );
63 static void Tri (f32 *v0, f32 *v1, f32 *v2, u8 color, u32 depth);
64
65 /*---------------------------------------------------------------------------*
66 Application main loop
67 *---------------------------------------------------------------------------*/
68
main(void)69 void main ( void )
70 {
71 Mtx v; // view matrix
72
73 rMode = &GXNtsc240DsAa;
74
75 DEMOInit(rMode); // Init os, pad, gx, vi
76
77 CameraInit(v); // Initialize the camera.
78 DrawInit(); // Define my vertex formats and set array pointers.
79
80 PrintIntro(); // Print demo directions
81
82 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
83 {
84 DEMOBeforeRender();
85 DrawTick(v); // Draw the model.
86 DEMODoneRender();
87
88 DEMOPadRead();
89 AnimTick(); // Update animation.
90 }
91
92 OSHalt("End of test");
93 }
94
95
96 /*---------------------------------------------------------------------------*
97 Functions
98 *---------------------------------------------------------------------------*/
99
100 /*---------------------------------------------------------------------------*
101 Name: CameraInit
102
103 Description: Initialize the projection matrix and load into hardware.
104 Initialize the view matrix.
105
106 Arguments: v view matrix
107
108 Returns: none
109 *---------------------------------------------------------------------------*/
CameraInit(Mtx v)110 static void CameraInit ( Mtx v )
111 {
112 Mtx44 p; // projection matrix
113 Vec up = {0.0F, 0.0F, 1.0F};
114 Vec camLoc = {0.25F, 3.0F, 0.5F};
115 Vec objPt = {0.0F, 0.0F, 0.0F};
116 f32 left = 0.0375F;
117 f32 top = 0.050F;
118 f32 znear = 0.1F;
119 f32 zfar = 10.0F;
120
121 MTXFrustum(p, left, -left, -top, top, znear, zfar);
122 GXSetProjection(p, GX_PERSPECTIVE);
123
124 MTXLookAt(v, &camLoc, &up, &objPt);
125 }
126
127 /*---------------------------------------------------------------------------*
128 Name: DrawInit
129
130 Description: Initializes the vertex attribute format 0, and sets
131 the array pointers and strides for the indexed data.
132
133 Arguments: none
134
135 Returns: none
136 *---------------------------------------------------------------------------*/
DrawInit(void)137 static void DrawInit( void )
138 {
139 GXColor blue = {0, 0, 255, 0};
140
141 GXSetCopyClear(blue, 0x00ffffff);
142
143 // Need to clear background by specified color
144 // since the clear color is different than DEMOInit default
145 // The clear operation can be done by dummy display copy
146 GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
147
148 // Set current vertex descriptor to enable position and color0.
149 // Both use 8b index to access their data arrays.
150 GXClearVtxDesc();
151 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
152 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
153
154 // Position has 3 elements (x,y,z), each of type f32
155 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
156
157 // Color 0 has 4 components (r, g, b, a), each component is 8b.
158 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
159
160 // Initialize lighting, texgen, and tev parameters
161 GXSetNumChans(1); // default, color = vertex color
162 GXSetNumTexGens(0); // no texture in this demo
163 GXSetNumTevStages( 1 );
164 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
165 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
166 }
167
168 /*---------------------------------------------------------------------------*
169 Name: Tri
170
171 Description: Recursively draw a triangle while alternating colors.
172
173 Arguments: v0 vertex 0
174 v1 vertex 1
175 v2 vertex 2
176 color color of triangle
177 depth recursion depth
178
179 Returns: none
180 *---------------------------------------------------------------------------*/
Tri(f32 * v0,f32 * v1,f32 * v2,u8 color,u32 depth)181 static void Tri (f32 *v0, f32 *v1, f32 *v2, u8 color, u32 depth)
182 {
183 f32 vertMid01[3]; // midpoint between v0 and v1
184 f32 vertMid12[3]; // midpoint between v1 and v2
185 f32 vertMid20[3]; // midpoint between v2 and v0
186
187 // if more recursion depth to go, ...
188 if (depth > 0)
189 {
190 // compute triangle midpoints on unit spheres
191 VECAdd((VecPtr) v0, (VecPtr) v1, (VecPtr) vertMid01);
192 VECScale((VecPtr) vertMid01, (VecPtr) vertMid01, 0.5f);
193 VECNormalize((VecPtr) vertMid01, (VecPtr) vertMid01);
194
195 VECAdd((VecPtr) v1, (VecPtr) v2, (VecPtr) vertMid12);
196 VECScale((VecPtr) vertMid12, (VecPtr) vertMid12, 0.5f);
197 VECNormalize((VecPtr) vertMid12, (VecPtr) vertMid12);
198
199 VECAdd((VecPtr) v2, (VecPtr) v0, (VecPtr) vertMid20);
200 VECScale((VecPtr) vertMid20, (VecPtr) vertMid20, 0.5f);
201 VECNormalize((VecPtr) vertMid20, (VecPtr) vertMid20);
202
203 // draw three outer triangles in same color as parent
204 Tri(v0, vertMid01, vertMid20, color, depth - 1);
205 Tri(v1, vertMid12, vertMid01, color, depth - 1);
206 Tri(v2, vertMid20, vertMid12, color, depth - 1);
207
208 // draw inner triangle in complementary color
209 Tri(vertMid01, vertMid12, vertMid20, (u8) ~color, depth - 1);
210 }
211 else // at bottom of recursion
212 {
213 // draw the triangle
214 GXBegin(GX_TRIANGLES, GX_VTXFMT0, 3);
215 // vertex 0
216 GXPosition3f32( v0[0], v0[1], v0[2] );
217 GXColor4u8( color, color, color, 255 );
218
219 // vertex 1
220 GXPosition3f32( v1[0], v1[1], v1[2] );
221 GXColor4u8( color, color, color, 255 );
222
223 // vertex 2
224 GXPosition3f32( v2[0], v2[1], v2[2] );
225 GXColor4u8( color, color, color, 255 );
226 GXEnd();
227 }
228 }
229
230 /*---------------------------------------------------------------------------*
231 Name: DrawTick
232
233 Description: Draw the model once.
234
235 Arguments: v view matrix
236
237 Returns: none
238 *---------------------------------------------------------------------------*/
DrawTick(Mtx v)239 static void DrawTick( Mtx v )
240 {
241 Mtx m; // Model matrix.
242 Mtx mv; // Modelview matrix.
243
244 switch(aaMode)
245 {
246 case 0:
247 GXSetCopyFilter(GX_TRUE, rMode->sample_pattern,
248 GX_TRUE, rMode->vfilter);
249 break;
250 case 1:
251 GXSetCopyFilter(GX_TRUE, mySamples,
252 GX_TRUE, myFilter);
253 break;
254 case 2:
255 GXSetCopyFilter(GX_FALSE, NULL,
256 GX_TRUE, myFilter);
257 break;
258 case 3:
259 GXSetCopyFilter(GX_FALSE, NULL,
260 GX_FALSE, NULL);
261 break;
262 default:
263 OSHalt("bad aaMode case");
264 }
265
266 // model has a rotation about z axis
267 MTXRotDeg(m, 'z', Ticks);
268 MTXConcat(v, m, mv);
269 GXLoadPosMtxImm(mv, GX_PNMTX0);
270
271 if (drawMode == 0)
272 {
273 // draw octahedron to recursion depth of octDepth
274 // draw northern hemisphere
275 Tri(&vertEquator[3], &vertEquator[0], vertNorth, 0, octDepth);
276 Tri(&vertEquator[6], &vertEquator[3], vertNorth, 255, octDepth);
277 Tri(&vertEquator[9], &vertEquator[6], vertNorth, 0, octDepth);
278 Tri(&vertEquator[0], &vertEquator[9], vertNorth, 255, octDepth);
279
280 // draw southern hemisphere
281 Tri(&vertEquator[0], &vertEquator[3], vertSouth, 255, octDepth);
282 Tri(&vertEquator[3], &vertEquator[6], vertSouth, 0, octDepth);
283 Tri(&vertEquator[6], &vertEquator[9], vertSouth, 255, octDepth);
284 Tri(&vertEquator[9], &vertEquator[0], vertSouth, 0, octDepth);
285 }
286 if (drawMode == 1)
287 {
288 int i;
289 f32 x, y;
290
291 GXBegin(GX_LINES, GX_VTXFMT0, 30*2);
292 for(i=0; i<30; i++)
293 {
294 x = cosf(i/15.0F * 3.1415926535F);
295 y = sinf(i/15.0F * 3.1415926535F);
296
297 // vertex 0
298 GXPosition3f32( 0.0F, 0.0F, 0.0F );
299 GXColor4u8( 255, 255, 255, 255 );
300
301 // vertex 1
302 GXPosition3f32( x, y, 0.0F );
303 GXColor4u8( 255, 255, 255, 255 );
304 }
305 GXEnd();
306 }
307 }
308
309 /*---------------------------------------------------------------------------*
310 Name: AnimTick
311
312 Description: Computes next time step.
313
314 Arguments: none
315
316 Returns: none
317 *---------------------------------------------------------------------------*/
AnimTick(void)318 static void AnimTick( void )
319 {
320 u8 oldaaMode = aaMode;
321 u16 down = DEMOPadGetButtonDown(0);
322
323 if (down & PAD_BUTTON_X)
324 {
325 animMode = ! animMode;
326 }
327
328 if (down & PAD_BUTTON_Y)
329 {
330 drawMode = ! drawMode;
331 }
332
333 if (DEMOPadGetButton(0) & PAD_BUTTON_A)
334 {
335 aaMode |= 1;
336 }
337 else
338 {
339 aaMode &= ~1;
340 }
341
342 if (down & PAD_BUTTON_B)
343 {
344 aaMode+=2;
345 if (aaMode > 3)
346 aaMode = 0;
347 }
348
349 if (down & PAD_TRIGGER_R)
350 {
351 octDepth++;
352 if (octDepth > OCT_DEPTH_MAX)
353 octDepth = OCT_DEPTH_MAX;
354 }
355
356 if (down & PAD_TRIGGER_L)
357 {
358 octDepth--;
359 if (octDepth < OCT_DEPTH_MIN)
360 octDepth = OCT_DEPTH_MIN;
361 }
362
363 if (animMode)
364 {
365 Ticks++;
366 }
367
368 if (aaMode != oldaaMode)
369 {
370 switch(aaMode)
371 {
372 case 0: OSReport("Regular filter\n"); break;
373 case 1: OSReport("Modified filter\n"); break;
374 case 2: OSReport("AA off, deflicker on\n"); break;
375 case 3: OSReport("AA off, deflicker off\n"); break;
376 default: OSHalt("bad aaMode case\n");
377 }
378 }
379 }
380
381 /*---------------------------------------------------------------------------*
382 Name: PrintIntro
383
384 Description: Prints the directions on how to use this demo.
385
386 Arguments: none
387
388 Returns: none
389 *---------------------------------------------------------------------------*/
PrintIntro(void)390 static void PrintIntro( void )
391 {
392 OSReport("\n\n*************************************************\n");
393 OSReport("frb-fld-dbs-aa: demonstrate double-strike field antialiasing\n");
394 OSReport("Button A - hold to show alternate AA mode\n");
395 OSReport("Button B - press to toggle AA on/off\n\n");
396 OSReport("Button X - press to toggle animation on/off\n");
397 OSReport("Button Y - press to toggle drawing mode\n");
398 OSReport("Triggers - press to change levels of recursive subdivision\n");
399 OSReport("\nTo quit:\n");
400 OSReport(" press the start/pause button\n");
401 OSReport("***************************************************\n");
402 }
403