1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/3D_Shadow_Pol
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 //---------------------------------------------------------------------------
20 // A sample that uses shadow polygons
21 //
22 // This sample displays a sphere and the ground.
23 // The sphere's shadow is drawn on the ground.
24 //
25 //---------------------------------------------------------------------------
26 
27 
28 #ifdef SDK_TWL
29 #include <twl.h>
30 #else
31 #include <nitro.h>
32 #endif
33 #include "DEMO.h"
34 #include "data.h"
35 
36 //---------------------------------------------------------------------------
37 //  Summary:
38 //        V-Blank interrupt process
39 //  Description:
40 //        Enables a flag that confirms that a V-Blank interrupt has been performed
41 //
42 //        The following steps will be performed during common initialization (DEMOInitCommon), causing this function to be called during V-Blanks
43 //        * Select IRQ interrupt (OS_SetIrqMask)
44 //        * Register this function, which performs IRQ interrupts (OS_SetIRQFunction)
45 //        * Enable IRQ interrupts (OS_EnableIrq)
46 //
47 //---------------------------------------------------------------------------
VBlankIntr(void)48 void VBlankIntr(void)
49 {
50     OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Sets a V-Blank interrupt confirmation flag
51 }
52 
53 //---------------------------------------------------------------------------
54 //  Summary:
55 //        Uses shadow polygons to display shadows
56 //  Description:
57 //        1. Prepare two identical cylinders that will be used to make the shadow cast on the ground by the sphere.
58 //
59 //        2. Prepare a cylinder whose PolygonAttr polygon attributes are shadow polygons for the mask; only rear surfaces are to be rendered.
60 //
61 //        3. Next, at the same coordinates as in the preceding step, prepare a cylinder whose PolygonAttr polygon attributes are shadow polygons for rendering; only front surfaces are to be rendered.
62 //
63 //           Assign vertex color to the rendered cylinder.
64 //        4. If this cylinder is made to intersect with the polygons that will become the ground, the part where the cylinder and the ground intersect will be displayed as a shadow.
65 //
66 //           The color of the shadow displayed will be the shadow polygon's color for rendering.
67 //
68 //---------------------------------------------------------------------------
69 #ifdef SDK_TWL
TwlMain(void)70 void TwlMain(void)
71 #else
72 void NitroMain(void)
73 #endif
74 {
75     u16     Rotate = 0;                // For rotating sphere (0-65535)
76 
77     //---------------------
78     // Initialize (enable IRQ, initialize VRAM, use BG0 in 3D mode)
79     //---------------------
80     DEMOInitCommon();
81     DEMOInitVRAM();
82     DEMOInitDisplay3D();
83 
84     G3X_AlphaBlend(TRUE);              // Enable alpha blending
85 
86     DEMOStartDisplay();
87 
88     //---------------------
89     //  Main loop
90     //---------------------
91     while (1)
92     {
93         G3X_Reset();
94         Rotate += 256;
95 
96         /* Camera configuration */
97         {
98             VecFx32 Eye = { 0, 15 * FX32_ONE, -15 * FX32_ONE }; // Eye point position
99             VecFx32 at = { 0, 0, 0 };  // Viewpoint
100             VecFx32 vUp = { 0, FX32_ONE, 0 };   // Up
101 
102             G3_LookAt(&Eye, &vUp, &at, NULL);   // Eye point settings
103         }
104 
105         /* Light configuration (configures light color and direction) */
106         {
107             G3_LightVector(GX_LIGHTID_0, 0, -FX32_ONE + 1, 0);
108             G3_LightColor(GX_LIGHTID_0, GX_RGB(31, 31, 31));
109         }
110 
111         G3_MtxMode(GX_MTXMODE_TEXTURE); // Set matrix to texture mode
112         G3_Identity();                 // Initialize current matrix to a unit matrix
113         // The matrix is set to Position-Vector simultaneous set mode
114         G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
115 
116         /* Terrain rendering settings */
117         G3_PushMtx();
118         // Set material's diffuse reflection color and ambient reflection color
119         G3_MaterialColorDiffAmb(GX_RGB(31, 31, 31),     // Diffuse reflection color
120                                 GX_RGB(16, 16, 16),     // Ambient reflection color
121                                 FALSE); // Do not use vertex color
122 
123         // Configure the specular color and the emission color of the material
124         G3_MaterialColorSpecEmi(GX_RGB(16, 16, 16),     // Specular reflection color
125                                 GX_RGB(0, 0, 0),        // The emission color
126                                 FALSE); // Specular reflection not used
127         // Specify texture parameters
128         G3_TexImageParam(GX_TEXFMT_NONE,        // Do not use texture
129                          GX_TEXGEN_NONE,
130                          GX_TEXSIZE_S8,
131                          GX_TEXSIZE_T8,
132                          GX_TEXREPEAT_NONE, GX_TEXFLIP_NONE, GX_TEXPLTTCOLOR0_USE, 0);
133         // Polygon attribute settings
134         G3_PolygonAttr(GX_LIGHTMASK_0, // Light 0 ON
135                        GX_POLYGONMODE_MODULATE, // Modulation mode
136                        GX_CULL_NONE,   // Do not perform backface culling
137                        2,              // Polygon ID 2
138                        31,             // Alpha value
139                        GX_POLYGON_ATTR_MISC_NONE);
140 
141         G3_Scale(10 * FX32_ONE, 0, 10 * FX32_ONE);
142 
143         G3_Begin(GX_BEGIN_QUADS);      // Start vertex list (draw with quadrilateral polygons)
144         G3_Normal(0, 1 << 9, 0);
145         G3_Vtx(FX16_ONE, 0, FX16_ONE);
146         G3_Vtx(FX16_ONE, 0, -FX16_ONE);
147         G3_Vtx(-FX16_ONE, 0, -FX16_ONE);
148         G3_Vtx(-FX16_ONE, 0, FX16_ONE);
149         G3_End();                      // End vertex list
150 
151         G3_PopMtx(1);
152 
153 
154         G3_PushMtx();
155         /* Sphere rotation calculation and position configuration */
156         {
157             fx16    s = FX_SinIdx(Rotate);
158             fx16    c = FX_CosIdx(Rotate);
159 
160             G3_RotY(s, c);
161             G3_Translate(0, 5 * FX32_ONE, -5 * FX32_ONE);
162             G3_RotX(s, c);
163             G3_RotY(s, c);
164             G3_RotZ(s, c);
165         }
166 
167         /* Sphere render settings */
168         // Set material's diffuse reflection color and ambient reflection color
169         G3_MaterialColorDiffAmb(GX_RGB(31, 31, 31),     // Diffuse reflection color
170                                 GX_RGB(16, 16, 16),     // Ambient reflection color
171                                 FALSE); // Do not use vertex color
172 
173         // Configure the specular color and the emission color of the material
174         G3_MaterialColorSpecEmi(GX_RGB(16, 16, 16),     // Specular reflection color
175                                 GX_RGB(0, 0, 0),        // The emission color
176                                 FALSE); // Specular reflection not used
177         // Specify texture parameters
178         G3_TexImageParam(GX_TEXFMT_NONE,        // Do not use texture
179                          GX_TEXGEN_NONE,
180                          GX_TEXSIZE_S8,
181                          GX_TEXSIZE_T8,
182                          GX_TEXREPEAT_NONE, GX_TEXFLIP_NONE, GX_TEXPLTTCOLOR0_USE, 0);
183         // Polygon attribute settings
184         G3_PolygonAttr(GX_LIGHTMASK_0, // Light 0 ON
185                        GX_POLYGONMODE_MODULATE, // Modulation mode
186                        GX_CULL_BACK,   // Perform backface culling
187                        1,              // Polygon ID 1
188                        31,             // Alpha value
189                        GX_POLYGON_ATTR_MISC_NONE);
190 
191         G3_Begin(GX_BEGIN_TRIANGLES);  // Begin vertex list (use triangular polygons)
192         {
193             MI_SendGXCommand(3, sphere1, sphere_size);
194         }
195         G3_End();                      // End vertex list
196 
197         G3_PopMtx(1);
198 
199         /* Shadow polygon position configuration for mask */
200         G3_PushMtx();
201         {
202             fx16    s = FX_SinIdx(Rotate);
203             fx16    c = FX_CosIdx(Rotate);
204 
205             G3_RotY(s, c);
206             G3_Translate(0, 0, -5 * FX32_ONE);
207         }
208 
209         /* Shadow polygon render configuration for mask */
210         // Set material's diffuse reflection color and ambient reflection color.
211         G3_MaterialColorDiffAmb(GX_RGB(0, 0, 0),        // Diffuse reflection color
212                                 GX_RGB(0, 0, 0),        // Ambient reflection color
213                                 FALSE); // Do not use vertex color
214         // Configure the specular color and the emission color of the material
215         G3_MaterialColorSpecEmi(GX_RGB(0, 0, 0),        // Specular reflection color
216                                 GX_RGB(0, 0, 0),        // The emission color
217                                 FALSE); // Specular reflection not used
218         // Specify texture parameters
219         G3_TexImageParam(GX_TEXFMT_NONE,        // Do not use texture
220                          GX_TEXGEN_NONE,
221                          GX_TEXSIZE_S8,
222                          GX_TEXSIZE_T8,
223                          GX_TEXREPEAT_NONE, GX_TEXFLIP_NONE, GX_TEXPLTTCOLOR0_USE, 0);
224         // Polygon attribute settings
225         G3_PolygonAttr(GX_LIGHTMASK_0, // Do not reflect light
226                        GX_POLYGONMODE_SHADOW,   // Shadow polygon mode
227                        GX_CULL_FRONT,  // Perform frontface culling
228                        0,              // Polygon ID �O
229                        0x08,           // Alpha value
230                        GX_POLYGON_ATTR_MISC_NONE);
231 
232         // Draw mask (cylinder)
233         G3_Begin(GX_BEGIN_TRIANGLES);  // Begin vertex list (use triangular polygons)
234         {
235             MI_SendGXCommand(3, cylinder1, cylinder_size);
236         }
237         G3_End();                      // End vertex list
238 
239         /* Shadow polygon render configuration for rendering */
240         // Set material's diffuse reflection color and ambient reflection color
241         G3_MaterialColorDiffAmb(GX_RGB(0, 0, 0),        // Diffuse reflection color
242                                 GX_RGB(0, 0, 0),        // Ambient reflection color
243                                 TRUE); // Use vertex color
244         // Configure the specular color and the emission color of the material
245         G3_MaterialColorSpecEmi(GX_RGB(0, 0, 0),        // Specular reflection color
246                                 GX_RGB(0, 0, 0),        // The emission color
247                                 FALSE); // Specular reflection not used
248         // Specify texture parameters
249         G3_TexImageParam(GX_TEXFMT_NONE,        // Do not use texture
250                          GX_TEXGEN_NONE,
251                          GX_TEXSIZE_S8,
252                          GX_TEXSIZE_T8,
253                          GX_TEXREPEAT_NONE, GX_TEXFLIP_NONE, GX_TEXPLTTCOLOR0_USE, 0);
254         // Polygon attribute settings
255         G3_PolygonAttr(GX_LIGHTMASK_0, // Do not reflect light
256                        GX_POLYGONMODE_SHADOW,   // Shadow polygon mode
257                        GX_CULL_BACK,   // Perform backface culling
258                        1,              // Polygon ID 1
259                        0x08,           // Alpha value
260                        GX_POLYGON_ATTR_MISC_NONE);      //
261 
262         // Draw shadow (cylinder)
263         G3_Begin(GX_BEGIN_TRIANGLES);  // Begin vertex list (use triangular polygons)
264         {
265             MI_SendGXCommand(3, cylinder1, cylinder_size);
266         }
267         G3_End();                      // End vertex list
268 
269         G3_PopMtx(1);
270 
271         // Swapping the polygon list RAM, the vertex RAM, etc.
272         G3_SwapBuffers(GX_SORTMODE_MANUAL, GX_BUFFERMODE_W);
273 
274         /* Waiting for the V-Blank */
275         OS_WaitVBlankIntr();
276 
277 #ifdef SDK_AUTOTEST                    // Code for auto-test
278         GX_SetBankForLCDC(GX_VRAM_LCDC_C);
279         EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
280         EXT_TestScreenShot(100, 0x213FA661);
281         EXT_TestTickCounter();
282 #endif //SDK_AUTOTEST
283     }
284 }
285