1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: pix-blend.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 #include <demo.h>
14 #include "cmn-model.h"
15
16 #define SCREEN_WD 1 // Dummy - actual value filled at runtime
17 #define SCREEN_HT 1 // Dummy - actual value filled at runtime
18 #define SCREEN_ZFAR 1.0f // far plane Z in screen coordinates
19 #define SCREEN_ZNEAR 0.0f // near plane Z in screen coordinates
20 #define ZBUFFER_MAX 0x00ffffff
21
22
23 /*---------------------------------------------------------------------------*
24 Typedefs
25 *---------------------------------------------------------------------------*/
26 typedef struct
27 {
28 char* title;
29 GXBlendMode type;
30 GXBlendFactor sfactor;
31 GXBlendFactor dfactor;
32 GXLogicOp logic;
33 } Blend;
34
35 typedef struct
36 {
37 Model* model;
38 Camera* camera;
39 ViewPort* viewport;
40 Blend* blend;
41 u32 flag;
42 } Scene;
43
44 #define SCENE_DRAWN (1<<0)
45 #define SCENE_CURSOR (1<<1)
46 #define SCENE_LCURSOR0 (1<<2)
47 #define SCENE_LCURSOR1 (1<<3)
48
49 /*---------------------------------------------------------------------------*
50 Forward references
51 *---------------------------------------------------------------------------*/
52 void SceneDraw( Scene* );
53 void SceneDrawInfo( Scene* );
54 void SceneControl( DEMOPadStatus* );
55 static void PrintIntro( void );
56
57 /*---------------------------------------------------------------------------*
58 Rendering parameters
59 *---------------------------------------------------------------------------*/
60 Camera myCamera =
61 {
62 { 0.0f, 0.0f, 30.0f }, // position
63 { 0.0f,1000.0f, 0.0f }, // target
64 { 0.0f, 0.0f, 1.0f }, // upVec
65 33.3f, // fovy
66 16.0f, // near plane Z in camera coordinates
67 1024.0f, // far plane Z in camera coordinates
68 };
69
70 ViewPort myViewPort[] =
71 {
72 // full size (these are adjusted in main)
73 { 0, 0, SCREEN_WD*2, SCREEN_HT*2 },
74 // half size
75 { 0, 0, SCREEN_WD, SCREEN_HT },
76 { 0, SCREEN_HT, SCREEN_WD, SCREEN_HT },
77 { SCREEN_WD, 0, SCREEN_WD, SCREEN_HT },
78 { SCREEN_WD, SCREEN_HT, SCREEN_WD, SCREEN_HT },
79 };
80
81 Blend myBlend[] =
82 {
83 { "BLEND1", GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR },
84 { "BLEND2", GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR },
85 { "BLEND3", GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR },
86 { "BLEND4", GX_BM_BLEND, GX_BL_DSTCLR, GX_BL_ZERO, GX_LO_CLEAR },
87 };
88
89 GXColor sceneBgColor = { 32, 32, 128,255};
90
91 Scene myScene[] =
92 {
93 { &cmModel[3], &myCamera, &myViewPort[0], &myBlend[0], 0 },
94 { &cmModel[3], &myCamera, &myViewPort[1], &myBlend[0], 0 },
95 { &cmModel[3], &myCamera, &myViewPort[2], &myBlend[1], 0 },
96 { &cmModel[3], &myCamera, &myViewPort[3], &myBlend[2], 0 },
97 { &cmModel[3], &myCamera, &myViewPort[4], &myBlend[3], 0 },
98 };
99
100 #define NUMSCENE (sizeof(myScene)/sizeof(Scene))
101
102 /*---------------------------------------------------------------------------*
103 Application main loop
104 *---------------------------------------------------------------------------*/
main(void)105 void main ( void )
106 {
107 GXRenderModeObj *rmp;
108 u32 i;
109
110 // initialize render settings and set clear color for first frame
111 DEMOInit( NULL ); // Defined in $(REVOLUTION_SDK_ROOT)/build/libraries/demo/src/DEMOInit.c
112 GXInvalidateTexAll( );
113 GXSetCopyClear( sceneBgColor, ZBUFFER_MAX );
114
115 // Perform dummy copy operation to clear eFB by specified color
116 GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
117
118 rmp = DEMOGetRenderModeObj();
119
120 for(i = 0; i < 5; i++)
121 {
122 myViewPort[i].xorg *= rmp->fbWidth/2;
123 myViewPort[i].yorg *= rmp->efbHeight/2;
124 myViewPort[i].width *= rmp->fbWidth/2;
125 myViewPort[i].height *= rmp->efbHeight/2;
126 }
127
128 PrintIntro();
129
130 while( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) )
131 {
132 // get pad status
133 DEMOPadRead( );
134 // General control & model animation
135 SceneControl( &DemoPad[0] );
136 cmModelAnime( &DemoPad[0], &myCamera );
137
138 // Draw scene
139 DEMOBeforeRender( );
140 for ( i = 0; i < NUMSCENE; i ++ )
141 {
142 SceneDraw( &myScene[i] );
143 }
144 DEMODoneRender( );
145 }
146
147 OSHalt("End of test");
148 }
149
150 /*---------------------------------------------------------------------------*
151 Functions
152 *---------------------------------------------------------------------------*/
153
154 //============================================================================
155 // Scene
156 //============================================================================
157 static char* factorName[] =
158 {
159 "0", "1",
160 "Cs", "(1-Cs)",
161 "Cd", "(1-Cd)",
162 "As", "(1-As)",
163 "Ad", "(1-Ad)",
164 };
165
166 /*---------------------------------------------------------------------------*
167 Name: SceneDrawBegin
168 Description: Update the perspective and view matrices.
169 Arguments: Scene* s
170 Returns: none
171 *---------------------------------------------------------------------------*/
SceneDraw(Scene * s)172 void SceneDraw( Scene* s )
173 {
174 Camera* c = s->camera;
175 ViewPort* v = s->viewport;
176 Blend* b = s->blend;
177 float aspect = (float) (4.0 / 3.0);
178 GXColor black = {0, 0, 0, 0};
179
180 // Check if drawn flag
181 if ( !(s->flag & SCENE_DRAWN) ) return;
182
183 // Set Perspective Viewing frustum
184 MTXPerspective( c->projMtx, c->fovy, aspect, c->znear, c->zfar );
185 GXSetProjection( c->projMtx, GX_PERSPECTIVE );
186
187 // Set CameraView matrix
188 MTXLookAt( c->viewMtx, &c->position, &c->up, &c->target );
189
190 // Set Viewport
191 GXSetViewport( v->xorg, v->yorg, v->width, v->height,
192 SCREEN_ZNEAR, SCREEN_ZFAR );
193 GXSetScissor( (u32)v->xorg, (u32)v->yorg, (u32)v->width, (u32)v->height );
194
195 // Set pixel processing mode
196 GXSetFog( GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, black );
197 GXSetZMode( GX_TRUE, GX_LESS, GX_TRUE );
198
199 // Set blend
200 GXSetBlendMode( b->type, b->sfactor, b->dfactor, b->logic );
201
202 // Draw model
203 if ( s->model->draw ) (*s->model->draw)( c );
204
205 // draw information
206 SceneDrawInfo( s );
207 return;
208 }
209
210 /*---------------------------------------------------------------------------*
211 Name: SceneDrawInfo
212 Description: Draw scene information
213 Arguments:
214 Returns: none
215 *---------------------------------------------------------------------------*/
SceneDrawInfo(Scene * s)216 void SceneDrawInfo( Scene* s )
217 {
218 Camera* c = s->camera;
219 ViewPort* v = s->viewport;
220 Blend* b = s->blend;
221 char* title;
222
223 // Get title name
224 title = b->title;
225 if ( GX_BL_ONE == b->sfactor )
226 {
227 if ( GX_BL_ZERO == b->dfactor ) title = "OPAQUE";
228 if ( GX_BL_ONE == b->dfactor ) title = "ADD";
229 }
230 if ( GX_BL_SRCALPHA == b->sfactor &&
231 GX_BL_INVSRCALPHA == b->dfactor ) title = "MODULATE";
232 if ( GX_BL_DSTCLR == b->sfactor &&
233 GX_BL_ZERO == b->dfactor ) title = "MULTIPLY";
234
235 // Draw parameters to the window
236 DEMOInitCaption( DM_FT_OPQ, v->width, v->height );
237 DEMOPuts ( 10, 12, 0, title );
238 DEMOPrintf( 96, 12, 0, "Cs * %s\nCd * %s",
239 factorName[b->sfactor-GX_BL_ZERO],
240 factorName[b->dfactor-GX_BL_ZERO] );
241
242 // Draw cursor
243 if ( s->flag & SCENE_CURSOR ) DEMOPuts( 2,12,0, "\x7f" );
244 if ( s->flag & SCENE_LCURSOR0 ) DEMOPuts(88,12,0, "\x7f" );
245 if ( s->flag & SCENE_LCURSOR1 ) DEMOPuts(88,20,0, "\x7f" );
246
247 return;
248 }
249
250 /*---------------------------------------------------------------------------*
251 Name: SceneControl
252 Description: user interface for parameter control
253 Arguments:
254 Returns: none
255 *---------------------------------------------------------------------------*/
SceneControl(DEMOPadStatus * pad)256 void SceneControl( DEMOPadStatus* pad )
257 {
258 static s32 zoomMode = 0;
259 static s32 cursor = 0;
260 static s32 cursorL = 0;
261 static u32 modelId = 3;
262 s32 i;
263 Scene* s;
264 Blend* b;
265
266 // Validate animation
267 cmModel[modelId].flag = MODEL_REFERRED;
268
269 // zoom mode
270 if ( pad->buttonDown & PAD_BUTTON_A ) zoomMode ^= 1;
271
272 if ( zoomMode )
273 {
274 //
275 // *** zoom mode
276 //
277
278 // show specified scene in full screen
279 s = &myScene[cursor+1];
280 b = s->blend;
281 myScene[0].blend = b;
282 myScene[0].flag = SCENE_DRAWN;
283
284 // turn off another window
285 for ( i = 1; i < NUMSCENE; i ++ )
286 {
287 myScene[i].flag = 0;
288 }
289
290 // choose a parameter
291 if ( pad->dirsNew & DEMO_STICK_UP ) cursorL = 0; // cursor up
292 if ( pad->dirsNew & DEMO_STICK_DOWN ) cursorL = 1; // cursor down
293
294 // set cursor position
295 myScene[0].flag |= (SCENE_LCURSOR0 << cursorL);
296
297 // change blend parameter
298 if ( pad->dirsNew & DEMO_STICK_LEFT ){
299 if ( cursorL == 0 ){
300 // Change sfactor, sfactor skips SRCCLR and INVSRCCLR
301 if ( b->sfactor == GX_BL_INVSRCCLR+1 ) b->sfactor -= 3;
302 else if ( b->sfactor > GX_BL_ZERO ) b->sfactor --;
303 }
304 else {
305 // Change dfactor, dfactor skips DSTCLR and INVDSTCLR
306 if ( b->dfactor == GX_BL_INVDSTCLR+1 ) b->dfactor -= 3;
307 else if ( b->dfactor > GX_BL_ZERO ) b->dfactor --;
308 }
309 }
310 if ( pad->dirsNew & DEMO_STICK_RIGHT )
311 {
312 if ( cursorL == 0 )
313 {
314 // Change sfactor, sfactor skips SRCCLR and INVSRCCLR
315 if ( b->sfactor == GX_BL_SRCCLR-1 ) b->sfactor += 3;
316 else if ( b->sfactor < GX_BL_INVDSTALPHA ) b->sfactor ++;
317 }
318 else
319 {
320 // Change dfactor, dfactor skips DSTCLR,INVDSTCLR and SRCASAT
321 if ( b->dfactor == GX_BL_DSTCLR-1 ) b->dfactor += 3;
322 else if ( b->dfactor < GX_BL_INVDSTALPHA ) b->dfactor ++;
323 }
324 }
325 }
326 else
327 {
328 //
329 // *** catalog mode
330 //
331
332 // choose a scene.
333 if ( pad->dirsNew & DEMO_STICK_LEFT ) cursor &= ~2; // left
334 if ( pad->dirsNew & DEMO_STICK_RIGHT ) cursor |= 2; // right
335 if ( pad->dirsNew & DEMO_STICK_UP ) cursor &= ~1; // up
336 if ( pad->dirsNew & DEMO_STICK_DOWN ) cursor |= 1; // down
337
338 // show 4 small windows
339 for ( i = 1; i < 5; i ++ )
340 {
341 myScene[i].flag = SCENE_DRAWN;
342 }
343
344 // turn off large window
345 myScene[0].flag = 0;
346
347 // set cursor
348 s = &myScene[cursor+1];
349 s->flag |= SCENE_CURSOR;
350 }
351
352 return;
353 }
354
355 /*---------------------------------------------------------------------------*
356 Name: PrintIntro
357
358 Description: Prints the directions on how to use this demo.
359
360 Arguments: none
361
362 Returns: none
363 *---------------------------------------------------------------------------*/
PrintIntro(void)364 static void PrintIntro( void )
365 {
366 OSReport("\n\n");
367 OSReport("************************************************\n");
368 OSReport("pix-blend: blend mode test\n");
369 OSReport("************************************************\n");
370 OSReport("to quit hit the menu button\n");
371 OSReport("\n");
372 OSReport(" Stick X/Y : move the cursor, change options\n");
373 OSReport(" A button : toggle zoom mode\n");
374 OSReport("************************************************\n\n");
375 }
376
377
378 /*======== End of pix-blend.c ========*/
379