1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tg-emboss.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 <math.h>
15 #include "cmn-model.h"
16
17 #define SCREEN_DEPTH 128.0f
18 #define SCREEN_ZNEAR 0.0f // near plane Z in screen coordinates
19 #define SCREEN_ZFAR 1.0f // far plane Z in screen coordinates
20 #define ZBUFFER_MAX 0x00ffffff
21
22 /*---------------------------------------------------------------------------*
23 Typedefs
24 *---------------------------------------------------------------------------*/
25 typedef struct
26 {
27 Camera* camera;
28 ViewPort* viewport;
29 GXColor* bgcolor;
30 } Scene;
31
32 /*---------------------------------------------------------------------------*
33 Forward references
34 *---------------------------------------------------------------------------*/
35 void SceneDraw ( Scene* );
36 void SceneControl ( Scene*, DEMOPadStatus* );
37 void myInitModel ( void );
38 void myAnimeModel ( Scene*, DEMOPadStatus* );
39 void myDrawModel ( Scene* );
40 void myInfoModel ( Scene* );
41 static void PrintIntro( void );
42
43 /*---------------------------------------------------------------------------*
44 Rendering parameters
45 *---------------------------------------------------------------------------*/
46 Camera myCamera =
47 {
48 { 0.0f,-300.0f, 0.0f }, // position
49 { 0.0f, 0.0f, 0.0f }, // target
50 { 0.0f, 0.0f, 1.0f }, // upVec
51 33.3f, // fovy
52 16.0f, // near plane Z in camera coordinates
53 1024.0f, // far plane Z in camera coordinates
54 };
55
56 ViewPort myViewPort = { 0, 0, 0, 0 };
57 GXColor myBgColor = { 32, 32, 255, 255};
58 Scene myScene = { &myCamera, &myViewPort, &myBgColor };
59
60 /*---------------------------------------------------------------------------*
61 Application main loop
62 *---------------------------------------------------------------------------*/
main(void)63 void main ( void )
64 {
65 GXRenderModeObj *rmp;
66
67 // initialize render settings and set clear color for first frame
68 DEMOInit(NULL);
69 GXInvalidateTexAll( );
70 GXSetCopyClear( *(myScene.bgcolor), GX_MAX_Z24 );
71
72 // Dummy copy operation to clear the eFB by specified color
73 GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE );
74
75 rmp = DEMOGetRenderModeObj();
76 myViewPort.width = (s16) rmp->fbWidth;
77 myViewPort.height = (s16) rmp->efbHeight;
78
79 myInitModel( );
80
81 while ( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) )
82 {
83 // get pad status
84 DEMOPadRead( );
85
86 // General control & model animation
87 SceneControl( &myScene, &DemoPad[0] );
88 myAnimeModel( &myScene, &DemoPad[0] );
89
90 // Draw scene
91 DEMOBeforeRender( );
92 SceneDraw( &myScene );
93 DEMODoneRender( );
94 }
95
96 OSHalt("End of demo");
97 }
98
99 /*---------------------------------------------------------------------------*
100 Functions
101 *---------------------------------------------------------------------------*/
102
103 //============================================================================
104 // Scene
105 //============================================================================
106
107 /*---------------------------------------------------------------------------*
108 Name: SceneControl
109 Description: user interface for parameter control
110 Arguments:
111 Returns: none
112 *---------------------------------------------------------------------------*/
SceneControl(Scene * s,DEMOPadStatus * pad)113 void SceneControl( Scene* s, DEMOPadStatus* pad )
114 {
115 #pragma unused( s, pad )
116 return;
117 }
118
119 /*---------------------------------------------------------------------------*
120 Name: SceneDraw
121 Description: Draw model
122 Arguments: Scene* s
123 Returns: none
124 *---------------------------------------------------------------------------*/
SceneDraw(Scene * s)125 void SceneDraw( Scene* s )
126 {
127 Camera* c = s->camera;
128 ViewPort* v = s->viewport;
129 float aspect = (float) (4.0 / 3.0);
130
131 // Set projection matrix
132 MTXPerspective ( c->projMtx, c->fovy, aspect, c->znear, c->zfar );
133 GXSetProjection( c->projMtx, GX_PERSPECTIVE );
134
135 // Set CameraView matrix
136 MTXLookAt( c->viewMtx, &c->position, &c->up, &c->target );
137
138 // Set Viewport
139 GXSetViewport( v->xorg, v->yorg, v->width, v->height,
140 SCREEN_ZNEAR, SCREEN_ZFAR );
141 GXSetScissor ( v->xorg, v->yorg, v->width, v->height );
142
143 // Set rendering mode
144 GXSetCullMode ( GX_CULL_BACK );
145
146 // Draw objects
147 myDrawModel( s );
148
149 // draw information
150 myInfoModel( s );
151 return;
152 }
153
154 //============================================================================
155 // Model
156 // Rectangles
157 //============================================================================
158 typedef struct
159 {
160 GXColor color;
161 Point3d pos; // in world space
162 f32 dist;
163 GXLightObj obj;
164 } MyLight;
165
166 typedef struct
167 {
168 Mtx modelMtx;
169 u8 bumpScale; // 0-128 on Emulator, 0-255 on HW
170 s32 invNrmScale;
171 s32 blendSteps;
172 u32 texNo;
173 GXTexObj texObj;
174 } MyModel;
175
176 typedef struct
177 {
178 s32 cursor;
179 s32 animation;
180 GXTexCoordID coord, coord1; // to show all tex coord pairs work
181 } MyControl;
182
183 MyLight myLight;
184 MyModel myModel;
185 MyControl myControl;
186 TPLPalettePtr texPalette = 0;
187
188 #ifndef M_SQRT3
189 #define M_SQRT3 1.732050808f
190 #endif
191
192 /*---------------------------------------------------------------------------*
193 Name: myDrawModel
194 Description: draw model
195 Arguments: Camera *c
196 Returns: none
197 *---------------------------------------------------------------------------*/
myInitModel(void)198 void myInitModel( void )
199 {
200 Vec axis = { 1.0f, 0.0f, 1.0f };
201
202 //------------------------------------------------------------------------
203 // MODEL
204 //------------------------------------------------------------------------
205
206 // Matrix
207 MTXRotAxisDeg( myModel.modelMtx, &axis, -150.0f );
208
209 // Texture
210 myModel.texNo = 1;
211 TPLGetPalette( &texPalette, "gxTests/tg-02.tpl" );
212 TPLGetGXTexObjFromPalette( texPalette, &myModel.texObj, myModel.texNo-1 );
213
214 // Bump Mapping
215 myModel.bumpScale = 128;
216 myModel.blendSteps = 3;
217 myModel.invNrmScale = 48;
218
219 //------------------------------------------------------------------------
220 // LIGHT
221 //------------------------------------------------------------------------
222
223 // Light color
224 myLight.color.r = 32;
225 myLight.color.g = 64;
226 myLight.color.b = 96;
227
228 // Light position in world space
229 myLight.dist = 100.0f;
230 myLight.pos.x = - myLight.dist * 1.0f / M_SQRT3;
231 myLight.pos.y = - myLight.dist * 1.0f / M_SQRT3;
232 myLight.pos.z = + myLight.dist * 1.0f / M_SQRT3;
233
234 // Set white light with no attenuation
235 GXInitLightSpot ( &myLight.obj, 0.0f, GX_SP_OFF );
236 GXInitLightDistAttn( &myLight.obj, 0.0f, 0.0f, GX_DA_OFF );
237
238 //------------------------------------------------------------------------
239 // CONTROL
240 //------------------------------------------------------------------------
241 myControl.cursor = 0;
242 myControl.animation = 1;
243 myControl.coord = GX_TEXCOORD0;
244 myControl.coord1 = GX_TEXCOORD1;
245 }
246
247 /*---------------------------------------------------------------------------*
248 Name: myAnimeModel
249 Description: animate model
250 Arguments: Scene* s
251 Returns: none
252 *---------------------------------------------------------------------------*/
myAnimeModel(Scene * s,DEMOPadStatus * pad)253 void myAnimeModel( Scene* s, DEMOPadStatus* pad )
254 {
255 # pragma unused(s)
256 f32 r2, y2, scale;
257 Mtx tmp;
258 Vec axis;
259
260 //---------------------------------------------------------------------
261 // Move cursor
262 //---------------------------------------------------------------------
263 if ( pad->buttonDown & PAD_BUTTON_X )
264 {
265 myControl.cursor ++;
266 }
267 if ( pad->buttonDown & PAD_BUTTON_B )
268 {
269 myControl.cursor += 4;
270 }
271 myControl.cursor %= 5;
272
273 //---------------------------------------------------------------------
274 // Cycle though all texture coordinates
275 //---------------------------------------------------------------------
276 if ( pad->buttonDown & PAD_BUTTON_Y )
277 {
278 myControl.coord++;
279 if (myControl.coord > GX_TEXCOORD6)
280 myControl.coord = GX_TEXCOORD0;
281 myControl.coord1 = (GXTexCoordID)(myControl.coord + 1);
282 OSReport("Using texture coord %d and %d\n",
283 myControl.coord, myControl.coord1);
284 }
285 //---------------------------------------------------------------------
286 // Change item
287 //---------------------------------------------------------------------
288 if ( pad->buttonDown & PAD_BUTTON_A )
289 {
290 switch ( myControl.cursor )
291 {
292 case 0:
293 // Texture
294 myModel.texNo %= 3;
295 myModel.texNo ++;
296 TPLGetGXTexObjFromPalette( texPalette,
297 &myModel.texObj, myModel.texNo-1 );
298 break;
299
300 case 1:
301 // Animation
302 myControl.animation ^= 1;
303 break;
304
305 case 2:
306 // Bump scale
307 myModel.bumpScale = (u8)( ( myModel.bumpScale < 128 )
308 ? myModel.bumpScale + 32 : 0 );
309 break;
310
311 case 3:
312 // Normal scale ( 8 - 96 )
313 myModel.invNrmScale %= 96;
314 myModel.invNrmScale += 8;
315 break;
316
317 case 4:
318 // Show step of blending
319 myModel.blendSteps %= 3;
320 myModel.blendSteps ++;
321 break;
322 }
323 }
324
325 //---------------------------------------------------------------------
326 // Animation
327 //---------------------------------------------------------------------
328 if ( myControl.animation )
329 {
330 axis.x = 1.0f;
331 axis.y = 2.0f;
332 axis.z = 0.5f;
333 MTXRotAxisDeg( tmp, &axis, 1.0f );
334 MTXConcat( myModel.modelMtx, tmp, myModel.modelMtx );
335 }
336
337 //---------------------------------------------------------------------
338 // Change light position
339 //---------------------------------------------------------------------
340 if ( pad->dirs & DEMO_STICK_LEFT ) myLight.pos.x -= 2.0f;
341 if ( pad->dirs & DEMO_STICK_RIGHT ) myLight.pos.x += 2.0f;
342 if ( pad->dirs & DEMO_STICK_UP ) myLight.pos.z += 2.0f;
343 if ( pad->dirs & DEMO_STICK_DOWN ) myLight.pos.z -= 2.0f;
344
345 r2 = myLight.pos.x * myLight.pos.x + myLight.pos.z * myLight.pos.z;
346 y2 = myLight.dist * myLight.dist - r2;
347
348 if ( y2 < 0 )
349 {
350 scale = myLight.dist / sqrtf(r2);
351 myLight.pos.x *= scale;
352 myLight.pos.z *= scale;
353 myLight.pos.y = 0.0f;
354 }
355 else
356 {
357 myLight.pos.y = - sqrtf(y2);
358 }
359 }
360
361 /*---------------------------------------------------------------------------*
362 Name: myDrawModel
363 Description: draw model
364 Arguments: Scene *c
365 Returns: none
366 *---------------------------------------------------------------------------*/
367
myDrawModel(Scene * s)368 void myDrawModel( Scene* s )
369 {
370 Camera* c = s->camera;
371 Mtx mvmtx, posMtx, nrmMtx;
372 Point3d lpos;
373 f32 nrmScale = 1.0f / (f32)myModel.invNrmScale;
374 GXColor color1 = {255,64,64,255};
375
376 // set a light object
377 MTXMultVec( c->viewMtx, &myLight.pos, &lpos );
378 GXInitLightPos ( &myLight.obj, lpos.x, lpos.y, lpos.z );
379 GXInitLightColor ( &myLight.obj, myLight.color );
380 GXLoadLightObjImm( &myLight.obj, GX_LIGHT0 );
381
382 // set modelview matrix
383 GXSetCurrentMtx( GX_PNMTX0 );
384
385 // Load ModelView matrix for pos/nrm into view space
386 // Note: mvmtx is uniform transformation here, then (mvmtx)^(-T) = mvmtx
387 // With bump mapping, normal must be scaled to match texel size in
388 // texture space.
389 MTXConcat ( c->viewMtx, myModel.modelMtx, mvmtx );
390 MTXScale ( posMtx, 75.0f, 75.0f, 75.0f );
391 MTXConcat ( mvmtx, posMtx, posMtx );
392 GXLoadPosMtxImm( posMtx, GX_PNMTX0 );
393 MTXScale ( nrmMtx, nrmScale, nrmScale, nrmScale );
394 MTXConcat ( mvmtx, nrmMtx, nrmMtx );
395 GXLoadNrmMtxImm( nrmMtx, GX_PNMTX0 );
396
397 // Set texture
398 GXLoadTexObj( &myModel.texObj, GX_TEXMAP0 );
399
400 // Render mode for Box
401 GXClearVtxDesc( );
402
403 // z update for 1st stage
404 GXSetZMode ( GX_TRUE, GX_LESS, GX_TRUE );
405
406 //------------------------------------------------------------------------
407 // Actual code for bump mapping on dolphin HW.
408 //------------------------------------------------------------------------
409 {
410 GXColor bumpScale;
411 u32 i;
412 GXColor white = {255,255,255,255};
413 GXColor grey = {128,128,128,128};
414
415 // Vertex component
416 GXClearVtxDesc();
417 GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
418 GXSetVtxDesc( GX_VA_NBT, GX_DIRECT );
419 GXSetVtxDesc( GX_VA_TEX0, GX_DIRECT );
420
421 // Light 0 for bump mapping
422 GXSetNumChans(1); // GX_COLOR0A0
423 GXSetChanCtrl( GX_COLOR0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG,
424 GX_LIGHT0, GX_DF_CLAMP, GX_AF_NONE );
425 GXSetChanCtrl( GX_ALPHA0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG,
426 GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE );
427 GXSetChanMatColor( GX_COLOR0A0, white );
428 GXSetChanAmbColor( GX_COLOR0A0, grey );
429
430 // clear out unused tex gens
431 for (i = 0; i < myControl.coord; i++)
432 GXSetTexCoordGen( (GXTexCoordID)i, GX_TG_MTX2x4,
433 GX_TG_POS, GX_IDENTITY );
434
435 // Tex Gen
436 // GX_TEXCOORD0: Base texcoord of bump mapping
437 // GX_TEXCOORD1: Tex gen by bump mapping
438 GXSetNumTexGens((u8)(myControl.coord1+1)); // coord1 is always the max coord
439 GXSetTexCoordGen( myControl.coord, GX_TG_MTX2x4,
440 GX_TG_TEX0, GX_IDENTITY );
441 GXSetTexCoordGen( myControl.coord1, GX_TG_BUMP0,
442 (GXTexGenSrc)((u32)myControl.coord + GX_TG_TEXCOORD0),
443 GX_IDENTITY );
444
445 // Tev Order
446 // GX_TEVSTAGE0: send base texture + diffuse color
447 // GX_TEVSTAGE1: send shifted texture
448 GXSetTevOrder( GX_TEVSTAGE0,
449 myControl.coord, GX_TEXMAP0, GX_COLOR0A0 );
450 GXSetTevOrder( GX_TEVSTAGE1,
451 myControl.coord1, GX_TEXMAP0, GX_COLOR_NULL );
452
453 // Tev Register
454 // GX_TEVREG0: ( X, X, X, bumpScale )
455 bumpScale.a = myModel.bumpScale;
456 GXSetTevColor( GX_TEVREG0, bumpScale );
457
458 //
459 // In many case, bump mapping needs 3 tev stage, but here,
460 // use only 2 tev stages, since no material texture map
461 //
462 GXSetNumTevStages( 2 );
463
464 //
465 // Tev stage0
466 // Color: BumpTexture * bumpScale + DiffuseColor => R
467 // Alpha: Not used
468 //
469 GXSetTevColorIn( GX_TEVSTAGE0, GX_CC_ZERO,
470 GX_CC_TEXC, /* Bump Texture */
471 GX_CC_A0, /* BumpScale */
472 GX_CC_RASC /* Diffuse color */ );
473 GXSetTevColorOp( GX_TEVSTAGE0, GX_TEV_ADD,
474 GX_TB_ZERO,
475 GX_CS_SCALE_1,
476 GX_DISABLE,
477 GX_TEVPREV /* To next stage */ );
478
479 GXSetTevAlphaIn( GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO,
480 GX_CA_ZERO, GX_CA_ZERO );
481 GXSetTevAlphaOp( GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO,
482 GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV );
483
484 //
485 // Tev stage1
486 // Color: ShiftTexture * bumpScale * (-1) + R => R
487 // Alpha: Not used
488 //
489 GXSetTevColorIn( GX_TEVSTAGE1, GX_CC_ZERO,
490 GX_CC_TEXC, /* Shift Texture */
491 GX_CC_A0, /* BumpScale */
492 GX_CC_CPREV /* Last stage out */ );
493 GXSetTevColorOp( GX_TEVSTAGE1, GX_TEV_SUB, /* mult (-1) */
494 GX_TB_ZERO,
495 GX_CS_SCALE_1,
496 GX_ENABLE,
497 GX_TEVPREV );
498
499 GXSetTevAlphaIn( GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO,
500 GX_CA_ZERO, GX_CA_ZERO );
501 GXSetTevAlphaOp( GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO,
502 GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV );
503
504 //-------------------------------------------------
505 // Draw objects
506 //-------------------------------------------------
507 GXDrawCube( );
508 }
509
510 //-------------------------------------------------
511 // Draw light direction
512 //-------------------------------------------------
513
514 // Shade mode
515 GXSetChanCtrl ( GX_COLOR0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG,
516 GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE );
517 GXSetChanMatColor( GX_COLOR0, color1 );
518
519 GXSetNumTexGens ( 0 );
520
521 // Tev mode
522 GXSetNumTevStages( 1 );
523 GXSetTevOrder ( GX_TEVSTAGE0,
524 GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0 );
525 GXSetTevOp ( GX_TEVSTAGE0, GX_PASSCLR );
526
527 // Render mode
528 GXSetBlendMode ( GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR );
529 GXSetZMode ( GX_TRUE, GX_LESS, GX_TRUE );
530
531 // Draw lines
532 GXClearVtxDesc ( );
533 GXSetVtxDesc ( GX_VA_POS, GX_DIRECT );
534 GXSetVtxAttrFmt ( GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_F32, 0 );
535 GXLoadPosMtxImm ( c->viewMtx, GX_PNMTX0 );
536 GXBegin( GX_LINES, GX_VTXFMT1, 2 );
537 GXPosition3f32( 0.0f, 0.0f, 0.0f );
538 GXPosition3f32( myLight.pos.x, myLight.pos.y, myLight.pos.z );
539 GXEnd( );
540 GXBegin( GX_LINESTRIP, GX_VTXFMT1, 5 );
541 GXPosition3f32( myLight.pos.x+2.0f, myLight.pos.y, myLight.pos.z+2.0f );
542 GXPosition3f32( myLight.pos.x+2.0f, myLight.pos.y, myLight.pos.z-2.0f );
543 GXPosition3f32( myLight.pos.x-2.0f, myLight.pos.y, myLight.pos.z-2.0f );
544 GXPosition3f32( myLight.pos.x-2.0f, myLight.pos.y, myLight.pos.z+2.0f );
545 GXPosition3f32( myLight.pos.x+2.0f, myLight.pos.y, myLight.pos.z+2.0f );
546 GXEnd( );
547
548 return;
549 }
550
551 /*---------------------------------------------------------------------------*
552 Name: ModelDrawInfo
553 Description: Draw scene information
554 Arguments:
555 Returns: none
556 *---------------------------------------------------------------------------*/
myInfoModel(Scene * s)557 void myInfoModel( Scene* s )
558 {
559 ViewPort* v = s->viewport;
560
561 // Z mode for drawing captions
562 GXSetZMode( GX_TRUE, GX_ALWAYS, GX_TRUE );
563
564 // Draw parameters to the window
565 DEMOInitCaption( DM_FT_XLU, v->width, v->height );
566 DEMOPuts ( 10, (s16)(myControl.cursor*8+10), 0, "\x7f" );
567 DEMOPrintf( 18, 10, 0, "Texture %d", myModel.texNo );
568 DEMOPrintf( 18, 18, 0,
569 "Animation %s", myControl.animation ? "ON" : "OFF" );
570 DEMOPrintf( 18, 26, 0, "Bump scale %d", myModel.bumpScale );
571 DEMOPrintf( 18, 34, 0, "Normal scale 1/%d", myModel.invNrmScale );
572 DEMOPrintf( 18, 42, 0, "Blend steps %d", myModel.blendSteps );
573
574 return;
575 }
576
577 /*---------------------------------------------------------------------------*
578 Name: PrintIntro
579
580 Description: Prints the directions on how to use this demo.
581
582 Arguments: none
583
584 Returns: none
585 *---------------------------------------------------------------------------*/
PrintIntro(void)586 static void PrintIntro( void )
587 {
588 OSReport("\n\n");
589 OSReport("**********************************************\n");
590 OSReport("tg-emboss: demonstrate bump mapping using the \n");
591 OSReport(" embossing technique. \n");
592 OSReport("**********************************************\n");
593 OSReport("to quit hit the start button\n");
594 OSReport("\n");
595 OSReport("Main Stick : Move Light Position\n");
596 OSReport("Sub Stick : Rotate the Model\n");
597 OSReport("X/B Buttons : Select parameter\n");
598 OSReport("A Button : Change selected parameter\n");
599 OSReport("Y Button : Change texture coordinate\n");
600 OSReport("**********************************************\n");
601 }
602
603
604
605 /*======== End of tg-emboss.c ========*/
606