1 /*---------------------------------------------------------------------------*
2 Project: Dolphin/Revolution gx demo
3 File: tev-complex.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 tev-complex
15 complex multi-texture example
16 *---------------------------------------------------------------------------*/
17
18
19 /*---------------------------------------------------------------------------*
20 Header files
21 *---------------------------------------------------------------------------*/
22 #include <demo.h>
23 #include <math.h>
24
25 /*---------------------------------------------------------------------------*
26 Macro definitions
27 *---------------------------------------------------------------------------*/
28 #define MAX_TEXMAPS 8
29 #define MAX_TEVSTAGES 8
30 #define MAX_TEXCOORDS 8
31 #define MAX_CHANNELS 2
32
33 #define MODEL_DIV0 32
34 #define MODEL_DIV1 16
35
36 #define BUMP_SCALE 0x50
37 #define REFLEX_SCALE 0x70
38 #define DIFFUSE_BASE 0xB0
39 #define SPECULAR_BASE 0x90
40
41 #define PI 3.14159265F
42 #define PI_2 6.28318531F
43
44 #define Clamp(val,min,max) \
45 ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
46
47 /*---------------------------------------------------------------------------*
48 Structure definitions
49 *---------------------------------------------------------------------------*/
50 // for camera
51 typedef struct
52 {
53 Vec location;
54 Vec up;
55 Vec target;
56 f32 left;
57 f32 top;
58 f32 znear;
59 f32 zfar;
60 } CameraConfig;
61
62 typedef struct
63 {
64 CameraConfig cfg;
65 Mtx view;
66 Mtx44 proj;
67 } MyCameraObj;
68
69 // for lighting
70 typedef struct
71 {
72 GXLightObj lobj;
73 s32 theta;
74 s32 phi;
75 } MyLightCtrlObj;
76
77 // for TEV stage control
78 typedef struct
79 {
80 GXTexMapID texMap;
81 GXTexCoordID texCoord;
82 GXChannelID channel;
83 GXTevColorArg colArgs[4];
84 GXTevOp colOp;
85 GXTevBias colBias;
86 GXTevScale colScale;
87 GXBool colClamp;
88 GXTevRegID colOut;
89 GXTevAlphaArg alpArgs[4];
90 GXTevOp alpOp;
91 GXTevBias alpBias;
92 GXTevScale alpScale;
93 GXBool alpClamp;
94 GXTevRegID alpOut;
95 } MyTevStgObj;
96
97 // for Texture coord generation
98 typedef struct
99 {
100 GXTexGenType func;
101 GXTexGenSrc src;
102 GXTexMtx mt;
103 } MyTexGenObj;
104
105 // for multi-texture shading configuration
106 typedef struct
107 {
108 u8 numTevStages;
109 u8 numTexMaps;
110 u8 numTexCoords;
111 u8 numChannels;
112 GXTexObj* texMapArray;
113 MyTexGenObj* texGenArray;
114 MyTevStgObj* tevStgArray;
115 GXColor tevRegColor[3];
116 } MyMTConfig;
117
118 // for model
119 typedef struct
120 {
121 Mtx rot;
122 f32 scale;
123 u32 numDiv0;
124 u32 numDiv1;
125 s16* posArray;
126 s16* nrmArray;
127 s16* tcdArray;
128 } MyModelObj;
129
130 // for entire scene control
131 typedef struct
132 {
133 MyCameraObj cam;
134 MyLightCtrlObj lightCtrl;
135 MyMTConfig* mtConfig;
136 MyModelObj model;
137 u16 viewWidth;
138 u16 viewHeight;
139 } MySceneCtrlObj;
140
141 /*---------------------------------------------------------------------------*
142 Forward references
143 *---------------------------------------------------------------------------*/
144 void main ( void );
145 static void DrawInit ( MySceneCtrlObj* sc );
146 static void DrawTick ( MySceneCtrlObj* sc );
147 static void AnimTick ( MySceneCtrlObj* sc );
148 static void DrawModel ( MyModelObj* mo );
149 static void CreateModel ( MyModelObj* mo );
150 static void SetCamera ( MyCameraObj* cam );
151 static void SetLight ( MyLightCtrlObj* le, Mtx view );
152 static void SetMultiTex ( MyMTConfig* mtc );
153 static void PrintIntro ( void );
154
155 /*---------------------------------------------------------------------------*
156 Camera configuration
157 *---------------------------------------------------------------------------*/
158 static CameraConfig DefaultCamera =
159 {
160 { 0.0F, 0.0F, 900.0F }, // location
161 { 0.0F, 1.0F, 0.0F }, // up
162 { 0.0F, 0.0F, 0.0F }, // target
163 -320.0F, // left
164 240.0F, // top
165 400.0F, // near
166 2000.0F // far
167 };
168
169 /*---------------------------------------------------------------------------*
170 Multi-texture configuration data
171 *---------------------------------------------------------------------------*/
172 static MyTexGenObj TexGenConfig0[] =
173 {
174 // TEXCOORD0
175 { GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0 },
176 // TEXCOORD1
177 { GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX1 },
178 // TEXCOORD2
179 { GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX2 },
180 // TEXCOORD3 (for reflection map)
181 { GX_TG_MTX2x4, GX_TG_NRM, GX_TEXMTX9 },
182 // TEXCOORD4 (for emboss bump)
183 { GX_TG_BUMP0, GX_TG_TEXCOORD1, GX_IDENTITY }
184 };
185
186 static MyTevStgObj TevStgConfig0[] =
187 {
188 // ------------------------ TEVSTAGE 0 ------------------------
189 // REGPREV(C) = diffuse lit color(COLOR0A0)
190 // + bump texture(TEXMAP0/TEXCOORD1) * bump scale(REG0(A))
191 {
192 GX_TEXMAP0, // texture map ID (emboss bump texture)
193 GX_TEXCOORD1, // texcoord ID
194 GX_COLOR0A0, // channel ID
195 // Color operation
196 { GX_CC_ZERO, GX_CC_TEXC, GX_CC_A0, GX_CC_RASC },
197 GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV,
198 // Alpha operation
199 { GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO },
200 GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV
201 },
202 // ------------------------ TEVSTAGE 1 ------------------------
203 // REGPREV(C) = REGPREV(C)
204 // - bump texture(TEXMAP0/TEXCOORD4) * bump scale(REG0(A))
205 {
206 GX_TEXMAP0, // texture map ID (emboss bump texture)
207 GX_TEXCOORD4, // texcoord ID (perturbed coordinate)
208 GX_COLOR0A0, // channel ID
209 // Color operation
210 { GX_CC_ZERO, GX_CC_TEXC, GX_CC_A0, GX_CC_CPREV },
211 GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
212 // Alpha operation
213 { GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO },
214 GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV
215 },
216 // ------------------------ TEVSTAGE 2 ------------------------
217 // REG2(C) = REGPREV(C) * base texture(TEXMAP1/TEXCOORD2)
218 {
219 GX_TEXMAP1, // texture map ID
220 GX_TEXCOORD2, // texcoord ID
221 GX_COLOR0A0, // channel ID
222 // Color operation
223 { GX_CC_ZERO, GX_CC_CPREV, GX_CC_TEXC, GX_CC_ZERO },
224 GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVREG2,
225 // Alpha operation
226 { GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO },
227 GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVREG2
228 },
229 // ------------------------ TEVSTAGE 3 ------------------------
230 // REGPREV(C) = specular lit color(COLOR1A1)
231 // + reflection map(TEXMAP2/TEXCOORD3) * reflection scale(REG1(A))
232 {
233 GX_TEXMAP2, // texture map ID
234 GX_TEXCOORD3, // texcoord ID
235 GX_COLOR1A1, // channel ID
236 // Color operation
237 { GX_CC_ZERO, GX_CC_A1, GX_CC_TEXC, GX_CC_RASC },
238 GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
239 // Alpha operation
240 { GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO },
241 GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV
242 },
243 // ------------------------ TEVSTAGE 4 ------------------------
244 // REGPREV(C) = diffusion map texture(TEXMAP3/TEXCOORD0) * REG2(C)
245 // + (1 - diffusion map texture) * REGPREV(C)
246 {
247 GX_TEXMAP3, // texture map ID
248 GX_TEXCOORD0, // texcoord ID
249 GX_COLOR0A0, // channel ID
250 // Color operation
251 { GX_CC_CPREV, GX_CC_C2, GX_CC_TEXC, GX_CC_ZERO },
252 GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV,
253 // Alpha operation
254 { GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO },
255 GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_DISABLE, GX_TEVPREV
256 }
257 };
258
259 static MyMTConfig MultiTexConfig0 =
260 {
261 5, // number of TEV stages
262 4, // number of texture maps
263 5, // number of texture coordinate generators
264 2, // number of channels
265 NULL, // texmap array (set in run-time)
266 TexGenConfig0, // texgen array
267 TevStgConfig0, // tevstage array
268 {
269 { 0, 0, 0, BUMP_SCALE }, // TEVREG0 preset value
270 { 0, 0, 0, REFLEX_SCALE }, // TEVREG1 preset value
271 { 0, 0, 0, 0 } // TEVREG2 preset value
272 }
273 };
274
275 /*---------------------------------------------------------------------------*
276 Other data tables
277 *---------------------------------------------------------------------------*/
278 static GXTevStageID StageIDTbl[MAX_TEVSTAGES] =
279 {
280 GX_TEVSTAGE0, GX_TEVSTAGE1, GX_TEVSTAGE2, GX_TEVSTAGE3,
281 GX_TEVSTAGE4, GX_TEVSTAGE5, GX_TEVSTAGE6, GX_TEVSTAGE7
282 };
283
284 static GXTexCoordID CoordIDTbl[MAX_TEXCOORDS] =
285 {
286 GX_TEXCOORD0, GX_TEXCOORD1, GX_TEXCOORD2, GX_TEXCOORD3,
287 GX_TEXCOORD4, GX_TEXCOORD5, GX_TEXCOORD6, GX_TEXCOORD7
288 };
289
290 static GXTexMtx TexMtxIDTbl[MAX_TEXCOORDS] =
291 {
292 GX_TEXMTX0, GX_TEXMTX1, GX_TEXMTX2, GX_TEXMTX3,
293 GX_TEXMTX4, GX_TEXMTX5, GX_TEXMTX6, GX_TEXMTX7
294 };
295
296 static GXTexMapID MapIDTbl[MAX_TEXMAPS] =
297 {
298 GX_TEXMAP0, GX_TEXMAP1, GX_TEXMAP2, GX_TEXMAP3,
299 GX_TEXMAP4, GX_TEXMAP5, GX_TEXMAP6, GX_TEXMAP7
300 };
301
302 static GXChannelID ChannelIDTbl[MAX_CHANNELS] =
303 {
304 GX_COLOR0A0, GX_COLOR1A1
305 };
306
307 /*---------------------------------------------------------------------------*
308 Global variables
309 *---------------------------------------------------------------------------*/
310 static MySceneCtrlObj SceneCtrl; // scene control parameters
311 static TPLPalettePtr MyTplObj = NULL; // texture palette
312
313 /*---------------------------------------------------------------------------*
314 Application main loop
315 *---------------------------------------------------------------------------*/
main(void)316 void main ( void )
317 {
318 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
319
320 DrawInit(&SceneCtrl); // Initialize vertex formats and scene parameters.
321
322 PrintIntro(); // Print demo directions
323
324 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
325 {
326 DEMOBeforeRender();
327 DrawTick(&SceneCtrl); // Draw the model.
328 DEMODoneRender();
329 DEMOPadRead(); // Update pad status.
330 AnimTick(&SceneCtrl); // Update animation.
331 }
332
333 OSHalt("End of demo");
334 }
335
336 /*---------------------------------------------------------------------------*
337 Functions
338 *---------------------------------------------------------------------------*/
339 /*---------------------------------------------------------------------------*
340 Name: DrawInit
341
342 Description: Initializes the vertex attribute format and
343 sets up default scene parameters.
344
345 Arguments: sc : pointer to the structure of scene control parameters
346
347 Returns: none
348 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)349 static void DrawInit( MySceneCtrlObj* sc )
350 {
351 GXRenderModeObj* rmode;
352 u32 i, nt, nd;
353
354 // set up a vertex attribute
355 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 13);
356 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NBT, GX_NRM_NBT, GX_S16, 13);
357 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 13);
358
359 // Load TPL file
360 TPLGetPalette(&MyTplObj, "gxTests/tev-03.tpl");
361 nd = MyTplObj->numDescriptors;
362
363 // Get screen information
364 rmode = DEMOGetRenderModeObj();
365 sc->viewWidth = rmode->fbWidth; // Screen Width
366 sc->viewHeight = rmode->efbHeight; // Screen Height
367
368
369 // Default scene parameter settings
370
371 // camera
372 sc->cam.cfg = DefaultCamera;
373 SetCamera(&sc->cam); // never changes in this test
374
375 // light parameters
376 sc->lightCtrl.theta = 30;
377 sc->lightCtrl.phi = 0;
378
379 // multi-texturing configuration
380 sc->mtConfig = &MultiTexConfig0;
381
382 // get texture maps from a texture palette
383 nt = sc->mtConfig->numTexMaps;
384 sc->mtConfig->texMapArray = (GXTexObj*)MEMAllocFromAllocator(&DemoAllocator1, nt * sizeof(GXTexObj));
385 for ( i = 0 ; i < nt ; ++i )
386 {
387 TPLGetGXTexObjFromPalette(
388 MyTplObj,
389 &sc->mtConfig->texMapArray[i],
390 i % nd );
391 }
392
393 // model
394 MTXRotDeg(sc->model.rot, 'x', 30);
395 sc->model.scale = 300.0F;
396 sc->model.numDiv0 = MODEL_DIV0;
397 sc->model.numDiv1 = MODEL_DIV1;
398 sc->model.posArray = NULL;
399 sc->model.nrmArray = NULL;
400 sc->model.tcdArray = NULL;
401 CreateModel(&sc->model);
402 }
403
404 /*---------------------------------------------------------------------------*
405 Name: DrawTick
406
407 Description: Draws the model by using given scene parameters
408
409 Arguments: sc : pointer to the structure of scene control parameters
410
411 Returns: none
412 *---------------------------------------------------------------------------*/
DrawTick(MySceneCtrlObj * sc)413 static void DrawTick( MySceneCtrlObj* sc )
414 {
415 Mtx mn = { { 0.5F, 0.0F, 0.0F, -0.5F }, // Fixed matrix
416 { 0.0F, 0.5F, 0.0F, -0.5F }, // to regularize normal
417 { 0.0F, 0.0F, 0.5F, -0.5F } }; // texgen
418 Mtx ms; // Scaling matrix.
419 Mtx mr; // Rotation matrix.
420 Mtx mv; // Modelview matrix.
421
422 // viewport
423 GXSetViewport(0, 0, sc->viewWidth, sc->viewHeight, 0.0F, 1.0F);
424
425 // modelview matrix
426 //
427 // Binormal and tangent will not be normalized.
428 // So we should consider scale factor of matrix for normal transformation matrix.
429 MTXScale(ms, sc->model.scale, sc->model.scale, sc->model.scale);
430 MTXConcat(sc->cam.view, sc->model.rot, mr);
431 MTXConcat(mr, ms, mv);
432 GXLoadPosMtxImm(mv, GX_PNMTX0);
433
434 MTXScale(ms, 0.03F, 0.03F, 0.03F);
435 MTXConcat(mr, ms, mv);
436 GXLoadNrmMtxImm(mv, GX_PNMTX0);
437
438 // texgen matrix
439 MTXConcat(mn, sc->model.rot, mv);
440 GXLoadTexMtxImm(mv, GX_TEXMTX9, GX_MTX2x4);
441 MTXScale(ms, 1.0F, 2.0F, 1.0F);
442 GXLoadTexMtxImm(ms, GX_TEXMTX0, GX_MTX2x4);
443 MTXScale(ms, 5.0F, 5.0F, 5.0F);
444 GXLoadTexMtxImm(ms, GX_TEXMTX1, GX_MTX2x4);
445 MTXScale(ms, 4.0F, 6.0F, 4.0F);
446 GXLoadTexMtxImm(ms, GX_TEXMTX2, GX_MTX2x4);
447
448 // enable lighting
449 SetLight(&sc->lightCtrl, sc->cam.view);
450
451 // set multi-texture environment
452 SetMultiTex(sc->mtConfig);
453
454 // draw the model
455 DrawModel(&sc->model);
456 }
457
458 /*---------------------------------------------------------------------------*
459 Name: AnimTick
460
461 Description: Changes scene parameters according to the pad status.
462
463 Arguments: sc : pointer to the structure of scene control parameters
464
465 Returns: none
466 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)467 static void AnimTick( MySceneCtrlObj* sc )
468 {
469 Mtx mrx, mry;
470
471 // Model Rotation Calculation
472 MTXRotDeg(mry, 'x', -(DEMOPadGetStickY(0) / 24));
473 MTXRotDeg(mrx, 'y', (DEMOPadGetStickX(0) / 24));
474 MTXConcat(mry, sc->model.rot, sc->model.rot);
475 MTXConcat(mrx, sc->model.rot, sc->model.rot);
476
477 // Light Position Calculation
478 sc->lightCtrl.theta += (DEMOPadGetSubStickX(0) / 24);
479 sc->lightCtrl.theta %= 360;
480 sc->lightCtrl.phi += (DEMOPadGetSubStickY(0) / 24);
481 Clamp(sc->lightCtrl.phi, -90, 90);
482 }
483
484 /*---------------------------------------------------------------------------*
485 Name: CreateModel
486
487 Description: Create indexed data array for the model
488 (a torus with NBT, texcoord)
489
490 Arguments: mo : pointer to model object
491
492 Returns: none
493 *---------------------------------------------------------------------------*/
CreateModel(MyModelObj * mo)494 static void CreateModel( MyModelObj* mo )
495 {
496 #define MODEL_R 0.35F
497 #define SCALE_Q 0x2000
498 u32 size_p, size_n, size_t;
499 u32 cnt_p, cnt_n, cnt_t;
500 s32 i, j;
501 f32 fs, ft, fr;
502
503 // allocate necessary array memories
504 if ( mo->posArray != NULL )
505 MEMFreeToAllocator(&DemoAllocator1, mo->posArray);
506 if ( mo->nrmArray != NULL )
507 MEMFreeToAllocator(&DemoAllocator1, mo->nrmArray);
508 if ( mo->tcdArray != NULL )
509 MEMFreeToAllocator(&DemoAllocator1, mo->tcdArray);
510
511 size_p = mo->numDiv0 * mo->numDiv1 * 3;
512 size_n = mo->numDiv0 * mo->numDiv1 * 9;
513 size_t = ( mo->numDiv0 + 1 ) * ( mo->numDiv1 + 1 ) * 2;
514
515 mo->posArray = (s16*)MEMAllocFromAllocator(&DemoAllocator1, size_p * sizeof(s16));
516 mo->nrmArray = (s16*)MEMAllocFromAllocator(&DemoAllocator1, size_n * sizeof(s16));
517 mo->tcdArray = (s16*)MEMAllocFromAllocator(&DemoAllocator1, size_t * sizeof(s16));
518
519 // make array data
520 cnt_p = cnt_n = cnt_t = 0;
521 for ( i = 0 ; i <= mo->numDiv0 ; ++i )
522 {
523 for ( j = 0 ; j <= mo->numDiv1 ; ++j )
524 {
525 // Tex coord
526 mo->tcdArray[cnt_t++] = (s16)(i * SCALE_Q / mo->numDiv0);
527 mo->tcdArray[cnt_t++] = (s16)(j * SCALE_Q / mo->numDiv1);
528
529 if ( i == mo->numDiv0 || j == mo->numDiv1 )
530 continue;
531
532 // Position
533 fs = i * PI_2 / mo->numDiv0;
534 ft = j * PI_2 / mo->numDiv1;
535 fr = 1.0F + MODEL_R * cosf(fs);
536
537 mo->posArray[cnt_p++] = (s16)(fr * cosf(ft) * SCALE_Q);
538 mo->posArray[cnt_p++] = (s16)(fr * sinf(ft) * SCALE_Q);
539 mo->posArray[cnt_p++] = (s16)(MODEL_R * sinf(fs) * SCALE_Q);
540
541 // Normal
542 mo->nrmArray[cnt_n++] = (s16)(cosf(ft) * cosf(fs) * SCALE_Q);
543 mo->nrmArray[cnt_n++] = (s16)(sinf(ft) * cosf(fs) * SCALE_Q);
544 mo->nrmArray[cnt_n++] = (s16)(sinf(fs) * SCALE_Q);
545
546 // Bi-normal
547 mo->nrmArray[cnt_n++] = (s16)(-cosf(ft) * sinf(fs) * SCALE_Q);
548 mo->nrmArray[cnt_n++] = (s16)(-sinf(ft) * sinf(fs) * SCALE_Q);
549 mo->nrmArray[cnt_n++] = (s16)( cosf(fs) * SCALE_Q);
550
551 // Tangent
552 mo->nrmArray[cnt_n++] = (s16)(-sinf(ft) * SCALE_Q);
553 mo->nrmArray[cnt_n++] = (s16)( cosf(ft) * SCALE_Q);
554 mo->nrmArray[cnt_n++] = 0;
555 }
556 }
557
558 // make sure data is written to main memory
559 DCFlushRange(mo->posArray, size_p * sizeof(s16));
560 DCFlushRange(mo->nrmArray, size_n * sizeof(s16));
561 DCFlushRange(mo->tcdArray, size_t * sizeof(s16));
562
563 }
564
565 /*---------------------------------------------------------------------------*
566 Name: DrawModel
567
568 Description: Draws a model by using prepared array data
569
570 Arguments: mo : pointer to model object
571
572 Returns: none
573 *---------------------------------------------------------------------------*/
DrawModel(MyModelObj * mo)574 static void DrawModel( MyModelObj* mo )
575 {
576 u32 i, j, k, s, t;
577 u16 idx;
578
579 // set up array pointer
580 GXSetArray(GX_VA_POS, mo->posArray, sizeof(s16) * 3);
581 GXSetArray(GX_VA_NRM, mo->nrmArray, sizeof(s16) * 9);
582 GXSetArray(GX_VA_TEX0, mo->tcdArray, sizeof(s16) * 2);
583
584 // set up vertex descriptors
585 GXClearVtxDesc();
586 GXSetVtxDesc(GX_VA_POS, GX_INDEX16);
587 GXSetVtxDesc(GX_VA_NBT, GX_INDEX16);
588 GXSetVtxDesc(GX_VA_TEX0, GX_INDEX16);
589
590 for ( i = 0 ; i < mo->numDiv0 ; i++ )
591 {
592 GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, (u16)((mo->numDiv1+1)*2));
593 for ( j = 0 ; j <= mo->numDiv1 ; j++ )
594 {
595 for ( k = 0 ; k <= 1 ; k++ )
596 {
597 s = (i + k) % mo->numDiv0;
598 t = j % mo->numDiv1;
599
600 // Position
601 idx = (u16)(s * mo->numDiv1 + t);
602 GXPosition1x16(idx);
603
604 // Normal-Binormal-Tangent
605 GXNormal1x16(idx);
606
607 // Tex coord
608 idx = (u16)((i+k) * (mo->numDiv1+1) + j);
609 GXTexCoord1x16(idx);
610 }
611 }
612 GXEnd();
613 }
614 }
615
616 /*---------------------------------------------------------------------------*
617 Name: SetCamera
618
619 Description: Sets view matrix and loads projection matrix into hardware
620
621 Arguments: cam : pointer to the MyCameraObj structure
622
623 Returns: none
624 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)625 static void SetCamera( MyCameraObj* cam )
626 {
627 MTXLookAt(
628 cam->view,
629 &cam->cfg.location,
630 &cam->cfg.up,
631 &cam->cfg.target );
632
633 MTXFrustum(
634 cam->proj,
635 cam->cfg.top,
636 - (cam->cfg.top),
637 cam->cfg.left,
638 - (cam->cfg.left),
639 cam->cfg.znear,
640 cam->cfg.zfar );
641 GXSetProjection(cam->proj, GX_PERSPECTIVE);
642 }
643
644 /*---------------------------------------------------------------------------*
645 Name: SetLight
646
647 Description: Sets up lights and lighting channel parameters
648
649 Arguments: le : pointer to a MyLightCtrlObj structure
650 view : view matrix
651
652 Returns: none
653 *---------------------------------------------------------------------------*/
SetLight(MyLightCtrlObj * le,Mtx view)654 static void SetLight( MyLightCtrlObj* le, Mtx view )
655 {
656 GXColor litc0 = { 0xC0, 0xC0, 0xC0, 0xC0 };
657 GXColor ambc0 = { 0x40, 0x40, 0x40, 0x40 };
658 GXColor matc0 = { DIFFUSE_BASE, DIFFUSE_BASE, DIFFUSE_BASE, DIFFUSE_BASE };
659 GXColor litc1 = { 0xE0, 0xE0, 0xE0, 0xE0 };
660 GXColor ambc1 = { 0x00, 0x00, 0x00, 0x00 };
661 GXColor matc1 = { SPECULAR_BASE, SPECULAR_BASE, SPECULAR_BASE, SPECULAR_BASE };
662 GXLightObj lo0, lo1;
663 Vec lpos, ldir;
664 f32 theta, phi;
665
666 // Light position/direction
667 theta = (f32)le->theta * PI / 180.0F;
668 phi = (f32)le->phi * PI / 180.0F;
669 // Direction of specular light
670 ldir.x = - cosf(phi) * sinf(theta);
671 ldir.y = - sinf(phi);
672 ldir.z = - cosf(phi) * cosf(theta);
673 // Position of diffuse light
674 VECScale(&ldir, &lpos, -1000.0F);
675
676 // Set a diffuse light
677 MTXMultVec(view, &lpos, &lpos);
678 GXInitLightPosv(&lo0, &lpos);
679 GXInitLightColor(&lo0, litc0);
680 GXLoadLightObjImm(&lo0, GX_LIGHT0);
681
682 // Set a specular light
683 MTXMultVecSR(view, &ldir, &ldir);
684 GXInitSpecularDirv(&lo1, &ldir);
685 GXInitLightShininess(&lo1, 16.0F);
686 GXInitLightColor(&lo1, litc1);
687 GXLoadLightObjImm(&lo1, GX_LIGHT1);
688
689 // Lighting channel
690 GXSetChanCtrl(
691 GX_COLOR0A0,
692 GX_ENABLE, // enable channel
693 GX_SRC_REG, // amb source
694 GX_SRC_REG, // mat source
695 GX_LIGHT0, // light mask
696 GX_DF_CLAMP, //
697 GX_AF_NONE ); // used as diffuse light
698 GXSetChanCtrl(
699 GX_COLOR1A1,
700 GX_ENABLE, // enable channel
701 GX_SRC_REG, // amb source
702 GX_SRC_REG, // mat source
703 GX_LIGHT1, // light mask
704 GX_DF_NONE, //
705 GX_AF_SPEC ); // used as specular light
706
707 // set up ambient/material color
708 GXSetChanAmbColor(GX_COLOR0A0, ambc0);
709 GXSetChanAmbColor(GX_COLOR1A1, ambc1);
710 GXSetChanMatColor(GX_COLOR0A0, matc0);
711 GXSetChanMatColor(GX_COLOR1A1, matc1);
712 }
713
714 /*---------------------------------------------------------------------------*
715 Name: SetMultiTex
716
717 Description: Set up texture maps, texcoord generators and TEV
718 for complex multi-texturing.
719
720 Arguments: mtc : pointer to a multi-texture configuration structure
721
722 Returns: none
723 *---------------------------------------------------------------------------*/
SetMultiTex(MyMTConfig * mtc)724 static void SetMultiTex( MyMTConfig* mtc )
725 {
726 u32 i;
727
728 ASSERTMSG(mtc->numChannels <= MAX_CHANNELS, "Too much channels\n");
729 ASSERTMSG(mtc->numTexCoords <= MAX_TEXCOORDS, "Too much texcoords\n");
730 ASSERTMSG(mtc->numTexMaps <= MAX_TEXMAPS, "Too much texmaps\n");
731 ASSERTMSG(mtc->numTevStages <= MAX_TEVSTAGES, "Too much tevstages\n");
732
733 // Number of color channels
734 GXSetNumChans(mtc->numChannels);
735
736 // Texmaps
737 for ( i = 0 ; i < mtc->numTexMaps ; ++i )
738 {
739 GXLoadTexObj(&mtc->texMapArray[i], MapIDTbl[i]);
740 }
741
742 // Texcoord generators
743 GXSetNumTexGens(mtc->numTexCoords);
744 for ( i = 0 ; i < mtc->numTexCoords ; ++i )
745 {
746 GXSetTexCoordGen(
747 CoordIDTbl[i],
748 mtc->texGenArray[i].func,
749 mtc->texGenArray[i].src,
750 mtc->texGenArray[i].mt );
751 }
752
753 // TEV
754 GXSetNumTevStages(mtc->numTevStages);
755 GXSetTevColor(GX_TEVREG0, mtc->tevRegColor[0]);
756 GXSetTevColor(GX_TEVREG1, mtc->tevRegColor[1]);
757 GXSetTevColor(GX_TEVREG2, mtc->tevRegColor[2]);
758
759 // each TEV stage
760 for ( i = 0 ; i < mtc->numTevStages ; ++i )
761 {
762 // color operations
763 GXSetTevColorIn(
764 StageIDTbl[i],
765 mtc->tevStgArray[i].colArgs[0],
766 mtc->tevStgArray[i].colArgs[1],
767 mtc->tevStgArray[i].colArgs[2],
768 mtc->tevStgArray[i].colArgs[3] );
769 GXSetTevColorOp(
770 StageIDTbl[i],
771 mtc->tevStgArray[i].colOp,
772 mtc->tevStgArray[i].colBias,
773 mtc->tevStgArray[i].colScale,
774 mtc->tevStgArray[i].colClamp,
775 mtc->tevStgArray[i].colOut );
776 GXSetTevAlphaIn(
777 StageIDTbl[i],
778 mtc->tevStgArray[i].alpArgs[0],
779 mtc->tevStgArray[i].alpArgs[1],
780 mtc->tevStgArray[i].alpArgs[2],
781 mtc->tevStgArray[i].alpArgs[3] );
782 GXSetTevAlphaOp(
783 StageIDTbl[i],
784 mtc->tevStgArray[i].alpOp,
785 mtc->tevStgArray[i].alpBias,
786 mtc->tevStgArray[i].alpScale,
787 mtc->tevStgArray[i].alpClamp,
788 mtc->tevStgArray[i].alpOut );
789
790 // TEV order
791 GXSetTevOrder(
792 StageIDTbl[i],
793 mtc->tevStgArray[i].texCoord,
794 mtc->tevStgArray[i].texMap,
795 mtc->tevStgArray[i].channel );
796 }
797 }
798
799 /*---------------------------------------------------------------------------*
800 Name: PrintIntro
801
802 Description: Prints the directions on how to use this demo.
803
804 Arguments: none
805
806 Returns: none
807 *---------------------------------------------------------------------------*/
PrintIntro(void)808 static void PrintIntro( void )
809 {
810 OSReport("\n\n");
811 OSReport("************************************************\n");
812 OSReport("tev-complex: complex multitexture\n");
813 OSReport("************************************************\n");
814 OSReport("to quit hit the menu button\n");
815 OSReport("\n");
816 OSReport("Main Stick : Rotate the model\n");
817 OSReport("Sub Stick : Move Light Position\n");
818 OSReport("************************************************\n\n");
819 }
820
821 /*============================================================================*/
822