1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     smp-light.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    smp-light
15      A simple example of lighting
16  *---------------------------------------------------------------------------*/
17 
18 
19 /*---------------------------------------------------------------------------*
20    Header files
21  *---------------------------------------------------------------------------*/
22 #include <demo.h>
23 #include <math.h>
24 
25 /*---------------------------------------------------------------------------*
26    Macro definitions
27  *---------------------------------------------------------------------------*/
28 #define PI    3.14159265358979323846F
29 
30 /*---------------------------------------------------------------------------*
31    Forward references
32  *---------------------------------------------------------------------------*/
33 void        main            ( void );
34 static void CameraInit      ( Mtx v );
35 static void DrawInit        ( void );
36 static void DrawTick        ( Mtx v );
37 static void DrawModel       ( void );
38 static void PrintIntro      ( void );
39 
40 /*---------------------------------------------------------------------------*
41    Model data (octahedron)
42  *---------------------------------------------------------------------------*/
43 /*---------------------------------------------------------------------------*
44    The macro ATTRIBUTE_ALIGN provides a convenient way to align initialized
45    arrays.  Alignment of vertex arrays to 32B IS NOT required, but may result
46    in a slight performance improvement.
47  *---------------------------------------------------------------------------*/
48 f32 PosArray[] ATTRIBUTE_ALIGN(32) =
49 {
50 //      x,     y,     z
51      0.0f,  0.0f,  1.0f,    // face 0:0
52      0.0f,  1.0f,  0.0f,    // face 0:1
53      1.0f,  0.0f,  0.0f,    // face 0:2
54      0.0f,  0.0f,  1.0f,    // face 1:0
55     -1.0f,  0.0f,  0.0f,    // face 1:1
56      0.0f,  1.0f,  0.0f,    // face 1:2
57      0.0f,  0.0f,  1.0f,    // face 2:0
58      0.0f, -1.0f,  0.0f,    // face 2:1
59     -1.0f,  0.0f,  0.0f,    // face 2:2
60      0.0f,  0.0f,  1.0f,    // face 3:0
61      1.0f,  0.0f,  0.0f,    // face 3:1
62      0.0f, -1.0f,  0.0f,    // face 3:2
63      0.0f,  0.0f, -1.0f,    // face 4:0
64      1.0f,  0.0f,  0.0f,    // face 4:1
65      0.0f,  1.0f,  0.0f,    // face 4:2
66      0.0f,  0.0f, -1.0f,    // face 5:0
67      0.0f,  1.0f,  0.0f,    // face 5:1
68     -1.0f,  0.0f,  0.0f,    // face 5:2
69      0.0f,  0.0f, -1.0f,    // face 6:0
70     -1.0f,  0.0f,  0.0f,    // face 6:1
71      0.0f, -1.0f,  0.0f,    // face 6:2
72      0.0f,  0.0f, -1.0f,    // face 7:0
73      0.0f, -1.0f,  0.0f,    // face 7:1
74      1.0f,  0.0f,  0.0f     // face 7:2
75 };
76 
77 f32 NrmArray[] ATTRIBUTE_ALIGN(32) =
78 {
79 // For lighting, the vector doesn't have to be normalized.
80 
81 //     nx,    ny,    nz
82      1.0f,  1.0f,  1.0f,    // face 0
83     -1.0f,  1.0f,  1.0f,    // face 1
84     -1.0f, -1.0f,  1.0f,    // face 2
85      1.0f, -1.0f,  1.0f,    // face 3
86      1.0f,  1.0f, -1.0f,    // face 4
87     -1.0f,  1.0f, -1.0f,    // face 5
88     -1.0f, -1.0f, -1.0f,    // face 6
89      1.0f, -1.0f, -1.0f,    // face 7
90 };
91 
92 /*---------------------------------------------------------------------------*
93    Global variables
94  *---------------------------------------------------------------------------*/
95 
96 // Color data for lighting
97 static GXColor AmbientColor  = { 0x40, 0x40, 0x40, 0x00 };
98 static GXColor MaterialColor = { 0x80, 0xD8, 0xFF, 0x00 };
99 static GXColor LightColor    = { 0xC0, 0xC0, 0xC0, 0x00 };
100 
101 // Light position
102 static Vec LightPos = { 10.0F, 10.0F, 2.0F };
103 
104 // Time counter
105 static u32  Ticks = 0;
106 
107 
108 /*---------------------------------------------------------------------------*
109    Application main loop
110  *---------------------------------------------------------------------------*/
main(void)111 void main ( void )
112 {
113     Mtx         v;  // view matrix
114     PADStatus   pad[PAD_MAX_CONTROLLERS]; // game pad state
115 
116     DEMOInit(NULL); // Init the OS, game pad, graphics and video.
117 
118     pad[0].button = 0;
119     CameraInit(v);  // Initialize the camera.
120     DrawInit();     // Initialize vertex formats and array pointers.
121 
122     PrintIntro();   // Print demo directions
123 
124     while(!(pad[0].button & PAD_BUTTON_MENU))
125     {
126         DEMOBeforeRender();
127         DrawTick(v);       // Draw the model.
128         DEMODoneRender();
129         PADRead(pad);
130         ++Ticks;           // Update time counter.
131     }
132 
133     OSHalt("End of demo");
134 }
135 
136 /*---------------------------------------------------------------------------*
137    Functions
138  *---------------------------------------------------------------------------*/
139 /*---------------------------------------------------------------------------*
140     Name:           CameraInit
141 
142     Description:    Initialize the projection matrix and load into hardware.
143                     Initialize the view matrix.
144 
145     Arguments:      v      view matrix
146 
147     Returns:        none
148  *---------------------------------------------------------------------------*/
CameraInit(Mtx v)149 static void CameraInit ( Mtx v )
150 {
151     Mtx44   p;      // projection matrix
152     Vec     up      = { 0.0F, 0.0F, 1.0F };
153     Vec     camLoc  = { 2.0F, 3.0F, 1.0F };
154     Vec     objPt   = { 0.0F, 0.0F, 0.0F };
155     f32     left    = -0.050F;
156     f32     top     = 0.0375F;
157     f32     znear   = 0.1F;
158     f32     zfar    = 10.0F;
159 
160     MTXFrustum(p, top, -top, left, -left, znear, zfar);
161     GXSetProjection(p, GX_PERSPECTIVE);
162 
163     MTXLookAt(v, &camLoc, &up, &objPt);
164 }
165 
166 /*---------------------------------------------------------------------------*
167     Name:           DrawInit
168 
169     Description:    Initializes the vertex attribute format and
170                     array pointers.
171 
172     Arguments:      none
173 
174     Returns:        none
175  *---------------------------------------------------------------------------*/
DrawInit(void)176 static void DrawInit( void )
177 {
178     // set up vertex attributes
179 
180     // Position has 3 elements (x,y,z), each of type f32
181     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
182     // Normal has 3 elements (x,y,z), each of type f32
183     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
184 
185     // set up array pointers for indexed lookup
186 
187     // stride = 3 elements (x,y,z) each of type f32
188     GXSetArray(GX_VA_POS, PosArray, 3*sizeof(f32));
189     GXSetArray(GX_VA_NRM, NrmArray, 3*sizeof(f32));
190 }
191 
192 /*---------------------------------------------------------------------------*
193     Name:           DrawTick
194 
195     Description:    Draws the lit model
196 
197     Arguments:      v        view matrix
198 
199     Returns:        none
200  *---------------------------------------------------------------------------*/
DrawTick(Mtx v)201 static void DrawTick( Mtx v )
202 {
203     Mtx         mv;         // Modelview matrix.
204     Mtx         mvi;        // Modelview matrix.
205     Mtx         mr;         // Rotate matrix
206     Vec         lpos;       // Light position.
207     GXLightObj  myLight;    // Light object.
208 
209     //--------------------------------------------------
210     //  Setting for using one color / no texture
211     //--------------------------------------------------
212 
213     // it doesn't require any texture coord
214     GXSetNumTexGens(0);
215     // only require one TEV stage
216     GXSetNumTevStages(1);
217     // TEV should simply pass through color channel output
218     GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
219     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
220 
221 
222     //--------------------------------------------------
223     //  Lighting parameters
224     //--------------------------------------------------
225 
226     // Light position
227     lpos = LightPos;
228 
229     // If the light position is defined in the world space,
230     // you should convert the coordinate because the lighting
231     // HW is assuming view space coordinates.
232     MTXMultVec(v, &lpos, &lpos);
233 
234     // Basical diffuse light requires position and color information.
235     GXInitLightPos(&myLight, lpos.x, lpos.y, lpos.z);
236     GXInitLightColor(&myLight, LightColor);
237 
238     // Once parameter initialization is done, you should load the
239     // light object into hardware to make it working.
240     // In this case, the object data is loaded into GX_LIGHT0.
241     GXLoadLightObjImm(&myLight, GX_LIGHT0);
242 
243     // Lighting channel control
244     GXSetNumChans(1);    // number of active color channels
245     GXSetChanCtrl(
246         GX_COLOR0,       // color channel 0
247         GX_ENABLE,       // enable channel (use lighting)
248         GX_SRC_REG,      // use the register as ambient color source
249         GX_SRC_REG,      // use the register as material color source
250         GX_LIGHT0,       // use GX_LIGHT0
251         GX_DF_CLAMP,     // diffuse function (CLAMP = normal setting)
252         GX_AF_NONE );    // attenuation function (this case doesn't use)
253     GXSetChanCtrl(
254         GX_ALPHA0,       // alpha channel 0
255         GX_DISABLE,      // not used in this program
256         GX_SRC_REG,      // ambient source (N/A in this case)
257         GX_SRC_REG,      // material source (N/A)
258         GX_LIGHT0,       // light mask (N/A)
259         GX_DF_NONE,      // diffuse function (N/A)
260         GX_AF_NONE );    // attenuation function (N/A)
261 
262     // ambient color register
263     GXSetChanAmbColor(GX_COLOR0A0, AmbientColor);
264     // material color register
265     GXSetChanMatColor(GX_COLOR0A0, MaterialColor);
266 
267 
268     //--------------------------------------------------
269     //  Geometry transformation
270     //--------------------------------------------------
271 
272     // Calculate position transformation
273 
274     // model has a rotation about z axis
275     MTXRotDeg(mr, 'z', Ticks);
276     MTXConcat(v, mr, mv);
277     GXLoadPosMtxImm(mv, GX_PNMTX0);
278 
279     // If you want to perform lighting, you must also set
280     // normal transformation matrix. In general case, such
281     // matrix can be obtained as inverse-transpose of the
282     // position transform matrix.
283     MTXInverse(mv, mvi);
284     MTXTranspose(mvi, mv);
285     GXLoadNrmMtxImm(mv, GX_PNMTX0);
286 
287 
288     //--------------------------------------------------
289     //  Draw the model
290     //--------------------------------------------------
291 
292     DrawModel();
293 }
294 
295 /*---------------------------------------------------------------------------*
296     Name:           DrawModel
297 
298     Description:    Draws the model (octahedron)
299 
300     Arguments:      none
301 
302     Returns:        none
303  *---------------------------------------------------------------------------*/
DrawModel(void)304 static void DrawModel( void )
305 {
306     u8    it;   // index of triangle
307     u8    iv;   // index of vertex
308 
309     // sets up vertex descriptors
310     GXClearVtxDesc();
311     GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
312     GXSetVtxDesc(GX_VA_NRM, GX_INDEX8);
313 
314     // send vertex data
315     // normal is necessary for performing lighting.
316     GXBegin(GX_TRIANGLES, GX_VTXFMT0, 24);
317 
318     for ( it = 0 ; it < 8 ; ++it )
319     {
320         for ( iv = 0 ; iv < 3 ; ++iv )
321         {
322             GXPosition1x8((u8)( 3 * it + iv ));
323             GXNormal1x8(it);   // same normal for each vertex on a triangle
324         }
325     }
326 
327     GXEnd();
328 }
329 
330 /*---------------------------------------------------------------------------*
331     Name:           PrintIntro
332 
333     Description:    Prints the directions on how to use this demo.
334 
335     Arguments:      none
336 
337     Returns:        none
338  *---------------------------------------------------------------------------*/
PrintIntro(void)339 static void PrintIntro( void )
340 {
341     OSReport("\n\n");
342     OSReport("********************************\n");
343     OSReport("to quit:\n");
344     OSReport("     hit the start button\n");
345     OSReport("********************************\n");
346 }
347 
348 /*============================================================================*/
349