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