1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - GX - demos - UnitTours/3D_Pol_Light
3 File: main.c
4
5 Copyright 2003-2008 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 $Date:: 2008-09-17#$
14 $Rev: 8556 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 //---------------------------------------------------------------------------
19 // A sample for lighting:
20 //
21 // Draw two cubes with a light changing in colors and direction.
22 // The left one has a normal vector for each plane,
23 // and the right one has a normal vector for each vertex.
24 //
25 // HOWTO:
26 // 1. Specify the direction of light by G3_LightVector.
27 // 2. Specify the color of light by G3_LightColor.
28 // 3. Specify the light to be enabled by G3_PolygonAttr.
29 //
30 // Note that there are four lights available.
31 //---------------------------------------------------------------------------
32
33 #ifdef SDK_TWL
34 #include <twl.h>
35 #else
36 #include <nitro.h>
37 #endif
38 #include "DEMO.h"
39
40 s16 gCubeGeometry[3 * 8] = {
41 FX16_ONE, FX16_ONE, FX16_ONE,
42 FX16_ONE, FX16_ONE, -FX16_ONE,
43 FX16_ONE, -FX16_ONE, FX16_ONE,
44 FX16_ONE, -FX16_ONE, -FX16_ONE,
45 -FX16_ONE, FX16_ONE, FX16_ONE,
46 -FX16_ONE, FX16_ONE, -FX16_ONE,
47 -FX16_ONE, -FX16_ONE, FX16_ONE,
48 -FX16_ONE, -FX16_ONE, -FX16_ONE
49 };
50
51 VecFx10 gCubeNormal1[8] = {
52 GX_VECFX10(0, 0, FX32_ONE - 1),
53 GX_VECFX10(0, FX32_ONE - 1, 0),
54 GX_VECFX10(FX32_ONE - 1, 0, 0),
55 GX_VECFX10(0, 0, -FX32_ONE + 1),
56 GX_VECFX10(0, -FX32_ONE + 1, 0),
57 GX_VECFX10(-FX32_ONE + 1, 0, 0)
58 };
59
60 VecFx10 gCubeNormal2[8] = {
61 GX_VECFX10(FX32_SQRT1_3, FX32_SQRT1_3, FX32_SQRT1_3),
62 GX_VECFX10(FX32_SQRT1_3, FX32_SQRT1_3, -FX32_SQRT1_3),
63 GX_VECFX10(FX32_SQRT1_3, -FX32_SQRT1_3, FX32_SQRT1_3),
64 GX_VECFX10(FX32_SQRT1_3, -FX32_SQRT1_3, -FX32_SQRT1_3),
65 GX_VECFX10(-FX32_SQRT1_3, FX32_SQRT1_3, FX32_SQRT1_3),
66 GX_VECFX10(-FX32_SQRT1_3, FX32_SQRT1_3, -FX32_SQRT1_3),
67 GX_VECFX10(-FX32_SQRT1_3, -FX32_SQRT1_3, FX32_SQRT1_3),
68 GX_VECFX10(-FX32_SQRT1_3, -FX32_SQRT1_3, -FX32_SQRT1_3)
69 };
70
71 s16 *gVertexArray = NULL;
72 VecFx10 *gNormalArray = NULL;
73
setVtxArray(s16 * array)74 inline void setVtxArray(s16 *array)
75 {
76 gVertexArray = array;
77 }
78
setNormalArray(VecFx10 * array)79 inline void setNormalArray(VecFx10 *array)
80 {
81 gNormalArray = array;
82 }
83
vtx(int idx)84 inline void vtx(int idx)
85 {
86 G3_Vtx(gVertexArray[idx * 3], gVertexArray[idx * 3 + 1], gVertexArray[idx * 3 + 2]);
87 }
88
normal(int idx)89 inline void normal(int idx)
90 {
91 G3_Direct1(G3OP_NORMAL, gNormalArray[idx]);
92 // use G3_Normal(x, y, z) if not packed
93 }
94
95
NrmVtxQuad(int idx0,int idx1,int idx2,int idx3)96 static void NrmVtxQuad(int idx0, int idx1, int idx2, int idx3)
97 {
98 normal(idx0);
99 vtx(idx0);
100 normal(idx1);
101 vtx(idx1);
102 normal(idx2);
103 vtx(idx2);
104 normal(idx3);
105 vtx(idx3);
106 }
107
NrmQuad(int nrm,int idx0,int idx1,int idx2,int idx3)108 static void NrmQuad(int nrm, int idx0, int idx1, int idx2, int idx3)
109 {
110 normal(nrm);
111 vtx(idx0);
112 vtx(idx1);
113 vtx(idx2);
114 vtx(idx3);
115 }
116
drawLeftCube(u16 Rotate,u8 count)117 static void drawLeftCube(u16 Rotate, u8 count)
118 {
119 G3_PushMtx();
120
121 // Rotate and translate the cube
122 {
123 fx16 s = FX_SinIdx(Rotate);
124 fx16 c = FX_CosIdx(Rotate);
125
126 G3_Translate(-3 << (FX32_SHIFT - 1), 0, 0);
127
128 G3_RotX(s, c);
129 G3_RotY(s, c);
130 G3_RotZ(s, c);
131 }
132
133 // Set the material color( diffuse, ambient , specular ) as basic white
134 DEMO_Set3DDefaultMaterial(FALSE, TRUE);
135 DEMO_Set3DDefaultShininessTable();
136
137 G3_PolygonAttr((GXLightMask)(count >> 4), // lighting is varying
138 GX_POLYGONMODE_MODULATE, // modulation mode
139 GX_CULL_BACK, // cull back
140 0, // polygon ID(0 - 63)
141 31, // alpha(0 - 31)
142 0 // OR of GXPolygonAttrMisc's value
143 );
144
145 setVtxArray(gCubeGeometry);
146 setNormalArray(gCubeNormal1);
147
148 G3_Begin(GX_BEGIN_QUADS);
149
150 {
151 NrmQuad(0, 2, 0, 4, 6);
152 NrmQuad(3, 7, 5, 1, 3);
153 NrmQuad(5, 6, 4, 5, 7);
154 NrmQuad(2, 3, 1, 0, 2);
155 NrmQuad(1, 5, 4, 0, 1);
156 NrmQuad(4, 6, 7, 3, 2);
157 }
158
159 G3_End();
160
161 G3_PopMtx(1);
162 }
163
drawRightCube(u16 Rotate,u8 count)164 static void drawRightCube(u16 Rotate, u8 count)
165 {
166 G3_PushMtx();
167
168 // Rotate and translate the cube
169 {
170 fx16 s = FX_SinIdx(Rotate);
171 fx16 c = FX_CosIdx(Rotate);
172
173 G3_Translate(3 << (FX32_SHIFT - 1), 0, 0);
174
175 G3_RotX(s, c);
176 G3_RotY(s, c);
177 G3_RotZ(s, c);
178 }
179
180 // Set the material color( diffuse, ambient , specular ) as basic white
181 DEMO_Set3DDefaultMaterial(FALSE, TRUE);
182 DEMO_Set3DDefaultShininessTable();
183
184 G3_PolygonAttr((GXLightMask)(count >> 4), // lighting is varying
185 GX_POLYGONMODE_MODULATE, // modulation mode
186 GX_CULL_BACK, // cull back
187 0, // polygon ID(0 - 63)
188 31, // alpha(0 - 31)
189 0 // OR of GXPolygonAttrMisc's value
190 );
191
192 setVtxArray(gCubeGeometry);
193 setNormalArray(gCubeNormal2);
194
195 G3_Begin(GX_BEGIN_QUADS);
196
197 {
198 NrmVtxQuad(2, 0, 4, 6);
199 NrmVtxQuad(7, 5, 1, 3);
200 NrmVtxQuad(6, 4, 5, 7);
201 NrmVtxQuad(3, 1, 0, 2);
202 NrmVtxQuad(5, 4, 0, 1);
203 NrmVtxQuad(6, 7, 3, 2);
204 }
205 G3_End();
206
207 G3_PopMtx(1);
208 }
209
210 #ifdef SDK_TWL
TwlMain(void)211 void TwlMain(void)
212 #else
213 void NitroMain(void)
214 #endif
215 {
216 u8 count = 0;
217 u16 Rotate = 0; // for rotating cubes(0-65535)
218
219 //---------------------------------------------------------------------------
220 // Initialize:
221 // They enable IRQ interrupts, initialize VRAM, and set BG #0 for 3D mode.
222 //---------------------------------------------------------------------------
223 DEMOInitCommon();
224 DEMOInitVRAM();
225 DEMOInitDisplay3D();
226
227 DEMOStartDisplay();
228 while (1)
229 {
230 G3X_Reset();
231 count++;
232 Rotate += 256;
233
234 //---------------------------------------------------------------------------
235 // Set up camera matrix
236 //---------------------------------------------------------------------------
237 {
238 VecFx32 Eye = { 0, 0, FX32_ONE * 5 }; // Eye position
239 VecFx32 at = { 0, 0, 0 }; // Viewpoint
240 VecFx32 vUp = { 0, FX32_ONE, 0 }; // Up
241
242 G3_LookAt(&Eye, &vUp, &at, NULL);
243 }
244
245 //---------------------------------------------------------------------------
246 // Set up light colors and direction.
247 // Notice that light vector is transformed by the current vector matrix
248 // immediately after LightVector command is issued.
249 //
250 // GX_LIGHTID_0: white, downward
251 // GX_LIGHTID_1: red, leftward
252 // GX_LIGHTID_2: green, upward
253 // GX_LIGHTID_3: blue, rightward
254 //---------------------------------------------------------------------------
255 G3_LightVector(GX_LIGHTID_0, 0, -FX16_ONE + 1, 0);
256 G3_LightColor(GX_LIGHTID_0, GX_RGB(31, 31, 31));
257
258 G3_LightVector(GX_LIGHTID_1, -FX16_ONE + 1, 0, 0);
259 G3_LightColor(GX_LIGHTID_1, GX_RGB(31, 0, 0));
260
261 G3_LightVector(GX_LIGHTID_2, 0, FX16_ONE - 1, 0);
262 G3_LightColor(GX_LIGHTID_2, GX_RGB(0, 31, 0));
263
264 G3_LightVector(GX_LIGHTID_3, FX16_ONE - 1, 0, 0);
265 G3_LightColor(GX_LIGHTID_3, GX_RGB(0, 0, 31));
266
267 G3_PushMtx();
268
269 drawLeftCube(Rotate, count);
270 drawRightCube(Rotate, count);
271
272 G3_PopMtx(1);
273
274 // swapping the polygon list RAM, the vertex RAM, etc.
275 G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
276
277 #ifdef SDK_AUTOTEST
278 GX_SetBankForLCDC(GX_VRAM_LCDC_C);
279 EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
280 EXT_TestScreenShot(100, 0xEF41160C);
281 EXT_TestTickCounter();
282 #endif //SDK_AUTOTEST
283
284 OS_WaitVBlankIntr(); // Waiting the end of VBlank interrupt
285 }
286 }
287
288 //---------------------------------------------------------------------------
289 // VBlank interrupt function:
290 //
291 // Interrupt handlers are registered on the interrupt table by OS_SetIRQFunction.
292 // OS_EnableIrqMask selects IRQ interrupts to enable, and
293 // OS_EnableIrq enables IRQ interrupts.
294 // Notice that you have to call 'OS_SetIrqCheckFlag' to check a VBlank interrupt.
295 //---------------------------------------------------------------------------
VBlankIntr(void)296 void VBlankIntr(void)
297 {
298 OS_SetIrqCheckFlag(OS_IE_V_BLANK); // checking VBlank interrupt
299 }
300