1 /*---------------------------------------------------------------------------*
2 Project: Dolphin GD demo
3 File: gd-tev-gc.c
4
5 Copyright 2001-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 $Log: gd-tev-gc.c,v $
14 Revision 1.3 2006/03/06 09:59:06 kawaset
15 Eliminated warnings.
16
17 Revision 1.2 02/09/2006 01:17:37 hirose
18 Replaced TEX library calls by TPL library.
19
20 Revision 1.1 02/08/2006 11:19:43 mitu
21 1st version.
22
23
24 3 02/09/06 11:26 Hirose
25 Resolved future time stamp problem.
26
27 3 10/19/02 6:53p Hirose
28 Changed location of data file.
29
30 2 10/13/01 2:29a Hirose
31 Fixes due to GDSetTexCoordGen API change.
32
33 1 10/04/01 2:48p Hirose
34 Initial check in.
35
36 $NoKeywords: $
37 *---------------------------------------------------------------------------*/
38 /*---------------------------------------------------------------------------*
39 gd-tev
40 Displaylist demo with multi-texture shader commands
41 [Main source code for GAMECUBE executable]
42 *---------------------------------------------------------------------------*/
43
44
45 /*---------------------------------------------------------------------------*
46 Header files
47 *---------------------------------------------------------------------------*/
48 #include <demo.h>
49 #include <math.h>
50
51 #include "gd-tev.h"
52
53 /*---------------------------------------------------------------------------*
54 Macro definitions
55 *---------------------------------------------------------------------------*/
56 #define PI 3.14159265F
57 #define PI_2 6.28318531F
58
59 #define Clamp(val,min,max) \
60 ((val) = (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)))
61
62 /*---------------------------------------------------------------------------*
63 Structure definitions
64 *---------------------------------------------------------------------------*/
65 // for camera
66 typedef struct
67 {
68 Vec location;
69 Vec up;
70 Vec target;
71 f32 left;
72 f32 top;
73 f32 znear;
74 f32 zfar;
75 } CameraConfig;
76
77 typedef struct
78 {
79 CameraConfig cfg;
80 Mtx view;
81 Mtx44 proj;
82 } MyCameraObj;
83
84 // for lighting
85 typedef struct
86 {
87 GXLightObj lobj;
88 s32 theta;
89 s32 phi;
90 } MyLightCtrlObj;
91
92 typedef struct
93 {
94 void* dlPtr;
95 u32 dlSize;
96 u32* plPtr;
97 u32 plSize;
98 } MyDLObj;
99
100 // for model object
101 typedef struct
102 {
103 s16* posArray;
104 s16* nrmArray;
105 s16* tcdArray;
106 MyDLObj dl;
107 } MyModelObj;
108
109 // for entire scene control
110 typedef struct
111 {
112 MyCameraObj cam;
113 MyLightCtrlObj lightCtrl;
114 Mtx modelRot;
115 f32 modelScale;
116 u16 viewWidth;
117 u16 viewHeight;
118 } MySceneCtrlObj;
119
120 /*---------------------------------------------------------------------------*
121 Forward references
122 *---------------------------------------------------------------------------*/
123 void main ( void );
124
125 static void DrawInit ( MySceneCtrlObj* sc );
126 static void DrawTick ( MySceneCtrlObj* sc );
127 static void AnimTick ( MySceneCtrlObj* sc );
128 static void SetCamera ( MyCameraObj* cam );
129 static void SetLight ( MyLightCtrlObj* le, Mtx view );
130 static void PrintIntro ( void );
131
132 static void PrepareDL ( void );
133 static void CreateModelVtxArray ( void );
134 static void PatchShaderDLTCScale( MyDLObj* mdl );
135
136
137 /*---------------------------------------------------------------------------*
138 Camera configuration
139 *---------------------------------------------------------------------------*/
140 static CameraConfig DefaultCamera =
141 {
142 { 0.0F, 0.0F, 900.0F }, // location
143 { 0.0F, 1.0F, 0.0F }, // up
144 { 0.0F, 0.0F, 0.0F }, // target
145 -320.0F, // left
146 240.0F, // top
147 400.0F, // near
148 2000.0F // far
149 };
150
151 /*---------------------------------------------------------------------------*
152 Global variables
153 *---------------------------------------------------------------------------*/
154 static MySceneCtrlObj SceneCtrl; // scene control parameters
155 static TPLPalettePtr MyTplObj = NULL; // texture palette
156
157 static GXTexObj MyTexObjs[NUM_TEXTURES];
158 static MyDLObj ShaderDLs[NUM_SHADERDLS];
159 static MyModelObj ModelObj;
160
161 /*---------------------------------------------------------------------------*
162 Application main loop
163 *---------------------------------------------------------------------------*/
main(void)164 void main ( void )
165 {
166 DEMOInit(NULL); // Init the OS, game pad, graphics and video.
167
168 DrawInit(&SceneCtrl); // Initialize vertex formats and scene parameters.
169
170 PrintIntro(); // Print demo directions
171
172 while(!(DEMOPadGetButton(0) & PAD_BUTTON_MENU))
173 {
174 DEMOBeforeRender();
175 DrawTick(&SceneCtrl); // Draw the model.
176 DEMODoneRender();
177 DEMOPadRead(); // Update pad status.
178 AnimTick(&SceneCtrl); // Update animation.
179 }
180
181 OSHalt("End of demo");
182 }
183
184 /*---------------------------------------------------------------------------*
185 Functions
186 *---------------------------------------------------------------------------*/
187 /*---------------------------------------------------------------------------*
188 Name: DrawInit
189
190 Description: Initializes the vertex attribute format and
191 sets up default scene parameters.
192
193 Arguments: sc : pointer to the structure of scene control parameters
194
195 Returns: none
196 *---------------------------------------------------------------------------*/
DrawInit(MySceneCtrlObj * sc)197 static void DrawInit( MySceneCtrlObj* sc )
198 {
199 GXRenderModeObj* rmode;
200 u32 i, nd;
201
202 // set up a vertex attribute
203 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, QUANTIZE_SHIFT);
204 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NBT, GX_NRM_NBT, GX_S16, QUANTIZE_SHIFT);
205 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, QUANTIZE_SHIFT);
206
207 // Disable all automatic texcoord scaling settings that
208 // cannot work well with GD display lists.
209 GXSetTexCoordScaleManually(GX_TEXCOORD0, GX_ENABLE, 1, 1);
210 GXSetTexCoordScaleManually(GX_TEXCOORD1, GX_ENABLE, 1, 1);
211 GXSetTexCoordScaleManually(GX_TEXCOORD2, GX_ENABLE, 1, 1);
212 GXSetTexCoordScaleManually(GX_TEXCOORD3, GX_ENABLE, 1, 1);
213 GXSetTexCoordScaleManually(GX_TEXCOORD4, GX_ENABLE, 1, 1);
214 GXSetTexCoordScaleManually(GX_TEXCOORD5, GX_ENABLE, 1, 1);
215 GXSetTexCoordScaleManually(GX_TEXCOORD6, GX_ENABLE, 1, 1);
216 GXSetTexCoordScaleManually(GX_TEXCOORD7, GX_ENABLE, 1, 1);
217
218
219 // Get screen information
220 rmode = DEMOGetRenderModeObj();
221 sc->viewWidth = rmode->fbWidth; // Screen Width
222 sc->viewHeight = rmode->efbHeight; // Screen Height
223
224
225 // Load TPL file
226 TPLGetPalette(&MyTplObj, "gxTests/tev-03.tpl");
227 nd = MyTplObj->numDescriptors;
228 // get texture maps from a texture palette
229 for ( i = 0 ; i < NUM_TEXTURES ; ++i )
230 {
231 TPLGetGXTexObjFromPalette(MyTplObj, &MyTexObjs[i], i % nd);
232 }
233
234
235 // Prepare model display list and shader display lists
236 PrepareDL();
237 CreateModelVtxArray();
238
239
240 // Default scene parameter settings
241
242 // camera
243 sc->cam.cfg = DefaultCamera;
244 SetCamera(&sc->cam); // never changes in this test
245
246 // light parameters
247 sc->lightCtrl.theta = 30;
248 sc->lightCtrl.phi = 0;
249
250 // model control
251 MTXRotDeg(sc->modelRot, 'x', -30);
252 sc->modelScale = 750.0F;
253
254 }
255
256 /*---------------------------------------------------------------------------*
257 Name: DrawTick
258
259 Description: Draws the model by using given scene parameters
260
261 Arguments: sc : pointer to the structure of scene control parameters
262
263 Returns: none
264 *---------------------------------------------------------------------------*/
265 // Viewport setup
SetWindow(u32 num,u32 wd,u32 ht)266 inline void SetWindow( u32 num, u32 wd, u32 ht )
267 {
268 u32 xorg, yorg;
269 xorg = (num&1) * wd;
270 yorg = ((num>>1)&1) * ht;
271 GXSetScissor(xorg, yorg, wd, ht);
272 GXSetViewport(xorg, yorg, wd, ht, 0.0F, 1.0F);
273 }
274
DrawTick(MySceneCtrlObj * sc)275 static void DrawTick( MySceneCtrlObj* sc )
276 {
277 Mtx mn = { { 0.5F, 0.0F, 0.0F, -0.5F }, // Fixed matrix
278 { 0.0F, 0.5F, 0.0F, -0.5F }, // to regularize normal
279 { 0.0F, 0.0F, 0.0F, 1.0F } }; // texgen
280 Mtx ms; // Scaling matrix.
281 Mtx mr; // Rotation matrix.
282 Mtx mv; // Modelview matrix.
283 u32 i, vw, vh;
284
285 // modelview matrix
286 //
287 // Binormal and tangent will not be normalized.
288 // So we should consider scale factor of matrix for normal transformation matrix.
289 MTXScale(ms, sc->modelScale, sc->modelScale, sc->modelScale);
290 MTXConcat(sc->cam.view, sc->modelRot, mr);
291 MTXConcat(mr, ms, mv);
292 GXLoadPosMtxImm(mv, GX_PNMTX0);
293
294 MTXScale(ms, 0.03F, 0.03F, 0.03F);
295 MTXConcat(mr, ms, mv);
296 GXLoadNrmMtxImm(mv, GX_PNMTX0);
297
298 // texgen matrices
299 GXLoadTexMtxImm(sc->modelRot, GX_TEXMTX2, GX_MTX3x4); // for reflection map
300 GXLoadTexMtxImm(mn, GX_PTTEXMTX0, GX_MTX3x4); //
301 MTXScale(ms, 6.0F, 6.0F, 0.0F);
302 GXLoadTexMtxImm(ms, GX_TEXMTX0, GX_MTX2x4); // for bump map
303 MTXScale(ms, 3.5F, 5.0F, 0.0F);
304 GXLoadTexMtxImm(ms, GX_TEXMTX1, GX_MTX2x4); // for base map
305 MTXScale(ms, 1.0F, 2.0F, 0.0F);
306 GXLoadTexMtxImm(ms, GX_TEXMTX3, GX_MTX2x4); // for gloss map
307
308 // Lighting
309 SetLight(&sc->lightCtrl, sc->cam.view);
310
311 // Texmaps
312 for ( i = 0 ; i < NUM_TEXTURES ; ++i )
313 {
314 GXLoadTexObj(&MyTexObjs[i], (GXTexMapID)i);
315 }
316
317 // Viewport size
318 vw = (u32)(sc->viewWidth / 2);
319 vh = (u32)(sc->viewHeight / 2);
320
321 // Call display list (shader + model)
322 for ( i = 0 ; i < 4 ; ++i )
323 {
324 SetWindow(i, vw, vh);
325 GXCallDisplayList(ShaderDLs[i].dlPtr, ShaderDLs[i].dlSize);
326 GXCallDisplayList(ModelObj.dl.dlPtr, ModelObj.dl.dlSize);
327 }
328 }
329
330 /*---------------------------------------------------------------------------*
331 Name: AnimTick
332
333 Description: Changes scene parameters according to the pad status.
334
335 Arguments: sc : pointer to the structure of scene control parameters
336
337 Returns: none
338 *---------------------------------------------------------------------------*/
AnimTick(MySceneCtrlObj * sc)339 static void AnimTick( MySceneCtrlObj* sc )
340 {
341 Mtx mrx, mry;
342
343 // Model Rotation Calculation
344 MTXRotDeg(mry, 'x', -(DEMOPadGetStickY(0) / 24));
345 MTXRotDeg(mrx, 'y', (DEMOPadGetStickX(0) / 24));
346 MTXConcat(mry, sc->modelRot, sc->modelRot);
347 MTXConcat(mrx, sc->modelRot, sc->modelRot);
348
349 // Light Position Calculation
350 sc->lightCtrl.theta += (DEMOPadGetSubStickX(0) / 24);
351 sc->lightCtrl.theta %= 360;
352 sc->lightCtrl.phi += (DEMOPadGetSubStickY(0) / 24);
353 Clamp(sc->lightCtrl.phi, -90, 90);
354 }
355
356 /*---------------------------------------------------------------------------*
357 Name: SetCamera
358
359 Description: Sets view matrix and loads projection matrix into hardware
360
361 Arguments: cam : pointer to the MyCameraObj structure
362
363 Returns: none
364 *---------------------------------------------------------------------------*/
SetCamera(MyCameraObj * cam)365 static void SetCamera( MyCameraObj* cam )
366 {
367 MTXLookAt(
368 cam->view,
369 &cam->cfg.location,
370 &cam->cfg.up,
371 &cam->cfg.target );
372
373 MTXFrustum(
374 cam->proj,
375 cam->cfg.top,
376 - (cam->cfg.top),
377 cam->cfg.left,
378 - (cam->cfg.left),
379 cam->cfg.znear,
380 cam->cfg.zfar );
381 GXSetProjection(cam->proj, GX_PERSPECTIVE);
382 }
383
384 /*---------------------------------------------------------------------------*
385 Name: SetLight
386
387 Description: Sets up lights and lighting channel parameters
388
389 Arguments: le : pointer to a MyLightCtrlObj structure
390 view : view matrix
391
392 Returns: none
393 *---------------------------------------------------------------------------*/
SetLight(MyLightCtrlObj * le,Mtx view)394 static void SetLight( MyLightCtrlObj* le, Mtx view )
395 {
396 GXColor litc0 = { 0xC0, 0xC0, 0xC0, 0xC0 };
397 GXColor ambc0 = { 0x40, 0x40, 0x40, 0x40 };
398 GXColor matc0 = { DIFFUSE_BASE, DIFFUSE_BASE, DIFFUSE_BASE, DIFFUSE_BASE };
399 GXColor litc1 = { 0xE0, 0xE0, 0xE0, 0xE0 };
400 GXColor ambc1 = { 0x00, 0x00, 0x00, 0x00 };
401 GXColor matc1 = { SPECULAR_BASE, SPECULAR_BASE, SPECULAR_BASE, SPECULAR_BASE };
402 GXLightObj lo0, lo1;
403 Vec lpos, ldir;
404 f32 theta, phi;
405
406 // Light position/direction
407 theta = (f32)le->theta * PI / 180.0F;
408 phi = (f32)le->phi * PI / 180.0F;
409 // Direction of specular light
410 ldir.x = - cosf(phi) * sinf(theta);
411 ldir.y = - sinf(phi);
412 ldir.z = - cosf(phi) * cosf(theta);
413 // Position of diffuse light
414 VECScale(&ldir, &lpos, -1000.0F);
415
416 // Set a diffuse light
417 MTXMultVec(view, &lpos, &lpos);
418 GXInitLightPosv(&lo0, &lpos);
419 GXInitLightColor(&lo0, litc0);
420 GXLoadLightObjImm(&lo0, GX_LIGHT0);
421
422 // Set a specular light
423 MTXMultVecSR(view, &ldir, &ldir);
424 GXInitSpecularDirv(&lo1, &ldir);
425 GXInitLightShininess(&lo1, 48.0F);
426 GXInitLightColor(&lo1, litc1);
427 GXLoadLightObjImm(&lo1, GX_LIGHT1);
428
429 // Lighting channel
430 GXSetChanCtrl(GX_COLOR0, GX_ENABLE, // Diffuse
431 GX_SRC_REG, GX_SRC_REG,
432 GX_LIGHT0, GX_DF_CLAMP, GX_AF_NONE);
433 GXSetChanCtrl(GX_COLOR1, GX_ENABLE, // Specular
434 GX_SRC_REG, GX_SRC_REG,
435 GX_LIGHT1, GX_DF_NONE, GX_AF_SPEC);
436 GXSetChanCtrl(GX_ALPHA0, GX_DISABLE, // Unused
437 GX_SRC_REG, GX_SRC_REG,
438 GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
439 GXSetChanCtrl(GX_ALPHA1, GX_DISABLE, // Unused
440 GX_SRC_REG, GX_SRC_REG,
441 GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
442
443 // set up ambient/material color
444 GXSetChanAmbColor(GX_COLOR0A0, ambc0);
445 GXSetChanAmbColor(GX_COLOR1A1, ambc1);
446 GXSetChanMatColor(GX_COLOR0A0, matc0);
447 GXSetChanMatColor(GX_COLOR1A1, matc1);
448 }
449
450 /*---------------------------------------------------------------------------*
451 Name: PrepareDL
452
453 Description: [create mode] Allocate memory for display list and call
454 the function CreateModelDL to create the display list.
455 [load mode] Load GDL file from the disc.
456
457 Arguments: none
458
459 Returns: none
460 *---------------------------------------------------------------------------*/
461 #ifndef LOAD_DL_FROM_FILE
462 static void(*CreateShdDLFunc[NUM_SHADERDLS])() =
463 {
464 CreateShader0DL, CreateShader1DL, CreateShader2DL, CreateShader3DL
465 };
466 #endif
467
PrepareDL(void)468 static void PrepareDL( void )
469 {
470 u32 i;
471
472 #ifdef LOAD_DL_FROM_FILE
473 //---------------------------------------------------------
474 // File mode : Read pre-generated GDL file from file
475 //---------------------------------------------------------
476 s32 err;
477 GDGList* dlArray;
478 GDGList* plArray;
479 u32 nDls, nPls;
480
481 err = GDReadDLFile("gddemo/gdTev.gdl", &nDls, &nPls, &dlArray, &plArray);
482
483 ASSERTMSG( err == 0, "GD file read error.\n" );
484
485 // Check number of lists.
486 ASSERTMSG( ( nDls == NUM_DLS && nPls == NUM_PLS ),
487 "This data doesn't match requirement of this demo.\n" );
488
489
490 OSReport("\nGD file read completed.\n");
491
492 // Obtain shader display lists.
493 for ( i = 0 ; i < NUM_SHADERDLS ; ++i )
494 {
495 ShaderDLs[i].dlPtr = dlArray[i].ptr;
496 ShaderDLs[i].dlSize = dlArray[i].byteLength;
497 ShaderDLs[i].plPtr = plArray[i].ptr;
498 ShaderDLs[i].plSize = plArray[i].byteLength;
499 }
500
501 // Obtain model display list.
502 ModelObj.dl.dlPtr = dlArray[i].ptr;
503 ModelObj.dl.dlSize = dlArray[i].byteLength;
504 ModelObj.dl.plPtr = NULL;
505 ModelObj.dl.plSize = 0;
506
507 #else
508 //---------------------------------------------------------
509 // Create mode : Create display list in this application
510 //---------------------------------------------------------
511
512 // Create shader display lists
513 for ( i = 0 ; i < NUM_SHADERDLS ; ++i )
514 {
515 ShaderDLs[i].dlPtr = OSAlloc(SDL_SIZE_MAX);
516 ShaderDLs[i].plPtr = OSAlloc(PL_SIZE_MAX);
517 (*CreateShdDLFunc[i])(ShaderDLs[i].dlPtr, &ShaderDLs[i].dlSize,
518 ShaderDLs[i].plPtr, &ShaderDLs[i].plSize);
519 OSReport("ShaderDL %d size = %d\n", i, ShaderDLs[i].dlSize);
520 }
521
522 // Create model display list
523 ModelObj.dl.dlPtr = OSAlloc(MDL_SIZE_MAX);
524 ModelObj.dl.plPtr = NULL;
525 ModelObj.dl.plSize = 0;
526 CreateModelDL(ModelObj.dl.dlPtr, &ModelObj.dl.dlSize);
527 OSReport("ModelDL size = %d\n", ModelObj.dl.dlSize);
528 #endif
529
530
531 // Patch texcoord scale data of all shader display lists
532 for ( i = 0 ; i < NUM_SHADERDLS ; ++i )
533 {
534 PatchShaderDLTCScale(&ShaderDLs[i]);
535 }
536 }
537
538 /*---------------------------------------------------------------------------*
539 Name: PatchShaderDLTCScale
540
541 Description: Patch given shader display list and overwrite texcoord
542 scale information that was not determinable during
543 creation time.
544
545 Arguments: mdl : MyDLObj which holds a display list to be patched.
546
547 Returns: none
548 *---------------------------------------------------------------------------*/
PatchShaderDLTCScale(MyDLObj * mdl)549 static void PatchShaderDLTCScale( MyDLObj* mdl )
550 {
551 GDLObj gdlObj;
552 u32 plIndex = 0;
553
554 // Set up a GDL object and make it current.
555 GDInitGDLObj(&gdlObj, mdl->dlPtr, mdl->dlSize);
556 GDSetCurrent(&gdlObj);
557
558 while( plIndex < mdl->plSize / sizeof(u32) )
559 {
560 u16 scaleS, scaleT;
561 GXBool biasS, biasT;
562 u32 tmid;
563 GXTexCoordID tcid;
564
565 // Patch list contains following entries per patch:
566 // [0] : patch location offset
567 // [1] : target texcoord ID
568 // [2] : texture which scales the texcoord
569
570 // Move pointer to the patch location.
571 GDSetCurrOffset(mdl->plPtr[plIndex++]);
572
573 // Get texcoord target
574 tcid = (GXTexCoordID)(mdl->plPtr[plIndex++]);
575
576 // Get texture size which scales the texcoord
577 tmid = mdl->plPtr[plIndex++];
578 scaleS = GXGetTexObjWidth(&MyTexObjs[tmid]);
579 scaleT = GXGetTexObjHeight(&MyTexObjs[tmid]);
580 // Bias should be turned on if repeat mode
581 biasS = (GXBool)((GXGetTexObjWrapS(&MyTexObjs[tmid]) == GX_REPEAT)
582 ? GX_ENABLE : GX_DISABLE);
583 biasT = (GXBool)((GXGetTexObjWrapT(&MyTexObjs[tmid]) == GX_REPEAT)
584 ? GX_ENABLE : GX_DISABLE);
585
586 // Patch command
587 GDSetTexCoordScale2(tcid, scaleS, biasS, GX_DISABLE,
588 scaleT, biasT, GX_DISABLE);
589 }
590
591 GDFlushCurrToMem();
592
593 GDSetCurrent(NULL);
594 }
595
596 /*---------------------------------------------------------------------------*
597 Name: CreateModelVtxArray
598
599 Description: Create indexed data array for the model
600
601 Arguments: mo : pointer to model object
602
603 Returns: none
604 *---------------------------------------------------------------------------*/
CreateModelVtxArray(void)605 static void CreateModelVtxArray( void )
606 {
607 MyModelObj* mo = &ModelObj;
608 u32 size_p, size_n, size_t;
609 u32 cnt_p, cnt_n, cnt_t;
610 s32 i, j;
611 f32 theta, phi;
612 f32 ct, cp, dzdt, dzdp, nt, np, nn;
613
614 size_p = MODEL_MESHX * MODEL_MESHY * 3;
615 size_n = MODEL_MESHX * MODEL_MESHY * 9;
616 size_t = MODEL_MESHX * MODEL_MESHY * 2;
617
618 mo->posArray = (s16*)OSAlloc(size_p * sizeof(s16));
619 mo->nrmArray = (s16*)OSAlloc(size_n * sizeof(s16));
620 mo->tcdArray = (s16*)OSAlloc(size_t * sizeof(s16));
621
622 // make array data
623 cnt_p = cnt_n = cnt_t = 0;
624 for ( i = 0 ; i < MODEL_MESHY ; ++i )
625 {
626 for ( j = 0 ; j < MODEL_MESHX ; ++j )
627 {
628 theta = (f32)j * PI_2 / MODEL_MESHX;
629 phi = (f32)i * PI_2 / MODEL_MESHX;
630
631 ct = cosf(theta);
632 cp = cosf(phi);
633
634 dzdt = MODEL_ZSCALE * PI * -sinf(theta) * cp;
635 dzdp = MODEL_ZSCALE * PI * -sinf(phi) * ct;
636
637 nt = 1.0F / sqrtf( 1.0F + dzdt*dzdt );
638 np = 1.0F / sqrtf( 1.0F + dzdp*dzdp );
639 nn = nt * np;
640
641 // Position
642 mo->posArray[cnt_p++] = (s16)(((f32)j*2 / MODEL_MESHX - 1.0F) * QSCALE);
643 mo->posArray[cnt_p++] = (s16)(((f32)i*2 / MODEL_MESHY - 1.0F) * QSCALE);
644 mo->posArray[cnt_p++] = (s16)(MODEL_ZSCALE * ct * cp * QSCALE);
645
646 // Normal
647 mo->nrmArray[cnt_n++] = (s16)(nn * -dzdt * QSCALE);
648 mo->nrmArray[cnt_n++] = (s16)(nn * -dzdp * QSCALE);
649 mo->nrmArray[cnt_n++] = (s16)(nn * QSCALE);
650
651 // Binormal
652 mo->nrmArray[cnt_n++] = (s16)(nt * QSCALE);
653 mo->nrmArray[cnt_n++] = (s16)0;
654 mo->nrmArray[cnt_n++] = (s16)(nt * dzdt * QSCALE);
655
656 // Tangent
657 mo->nrmArray[cnt_n++] = (s16)0;
658 mo->nrmArray[cnt_n++] = (s16)(np * QSCALE);
659 mo->nrmArray[cnt_n++] = (s16)(np * dzdp * QSCALE);
660
661 // Texcoord
662 mo->tcdArray[cnt_t++] = (s16)(j * QSCALE / MODEL_MESHX);
663 mo->tcdArray[cnt_t++] = (s16)(i * QSCALE / MODEL_MESHY);
664 }
665 }
666
667 // make sure data is written to main memory
668 DCFlushRange(mo->posArray, size_p * sizeof(s16));
669 DCFlushRange(mo->nrmArray, size_n * sizeof(s16));
670 DCFlushRange(mo->tcdArray, size_t * sizeof(s16));
671
672 // set up array pointers
673 GXSetArray(GX_VA_POS, mo->posArray, sizeof(s16) * 3);
674 GXSetArray(GX_VA_NRM, mo->nrmArray, sizeof(s16) * 9);
675 GXSetArray(GX_VA_TEX0, mo->tcdArray, sizeof(s16) * 2);
676 }
677
678 /*---------------------------------------------------------------------------*
679 Name: PrintIntro
680
681 Description: Prints the directions on how to use this demo.
682
683 Arguments: none
684
685 Returns: none
686 *---------------------------------------------------------------------------*/
PrintIntro(void)687 static void PrintIntro( void )
688 {
689 OSReport("\n\n");
690 OSReport("************************************************\n");
691 OSReport(" GD Multitexturing (TEV) demo\n");
692 OSReport("************************************************\n");
693 OSReport("to quit hit the menu button\n");
694 OSReport("\n");
695 OSReport("Main Stick : Rotate the model\n");
696 OSReport("Sub Stick : Move Light Position\n");
697 OSReport("************************************************\n\n");
698 }
699
700 /*============================================================================*/
701