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