1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/3D_PolAttr_DpthUpdate
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-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 //---------------------------------------------------------------------------
19 // A sample that sets GX_POLYGON_ATTR_MISC_XLU_DEPTH_UPDATE in G3_PolygonAttr.
20 // The depth buffer is updated when the transparent polygon is drawn.
21 //
22 // This sample displays a transparent cube and cylinder. If the switch is ON,
23 // the cube is drawn with GX_POLYGON_ATTR_MISC_XLU_DEPTH_UPDATE parameter.
24 //
25 // USAGE:
26 //   UP, DOWN   : Change alpha blend parameter
27 //   START      : Switch ON/OFF GX_POLYGON_ATTR_MISC_XLU_DEPTH_UPDATE
28 //
29 //---------------------------------------------------------------------------
30 
31 #ifdef SDK_TWL
32 #include <twl.h>
33 #else
34 #include <nitro.h>
35 #endif
36 #include "DEMO.h"
37 
38 //---------------------------------------------------------------------------
39 //  Summary:
40 //        Cube model data
41 //---------------------------------------------------------------------------
42 /* Vertex data */
43 static const s16 s_Vertex[3 * 8] = {
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     -FX16_ONE, FX16_ONE, -FX16_ONE,
50     -FX16_ONE, -FX16_ONE, FX16_ONE,
51     -FX16_ONE, -FX16_ONE, -FX16_ONE
52 };
53 
54 //---------------------------------------------------------------------------
55 //        Set vertex coordinates
56 //  Description:
57 //        Use specified vertex data to set vertex coordinates
58 //  Input:
59 //        i_idx: Vertex data ID
60 //---------------------------------------------------------------------------
Vertex(int i_idx)61 static void Vertex(int i_idx)
62 {
63     G3_Vtx(s_Vertex[i_idx * 3], s_Vertex[i_idx * 3 + 1], s_Vertex[i_idx * 3 + 2]);
64 }
65 
66 //---------------------------------------------------------------------------
67 //  Summary:
68 //        Generate a cube surface
69 //  Description:
70 //        Generate one cube surface
71 //  Input:
72 //        i_idx0 - i_id3 : Structural vertex data ID
73 //---------------------------------------------------------------------------
Quad(int i_idx0,int i_idx1,int i_idx2,int i_idx3)74 inline void Quad(int i_idx0, int i_idx1, int i_idx2, int i_idx3)
75 {
76     Vertex(i_idx0);
77     Vertex(i_idx1);
78     Vertex(i_idx2);
79     Vertex(i_idx3);
80 }
81 
82 
83 //---------------------------------------------------------------------------
84 //  Summary:
85 //        Cube rendering (w/o normals)
86 //  Description:
87 //
88 //---------------------------------------------------------------------------
DrawCube(void)89 static void DrawCube(void)
90 {
91     G3_Begin(GX_BEGIN_QUADS);          // Beginning of vertex list (draw with quadrilateral polygons)
92     {
93         Quad(2, 0, 4, 6);
94         Quad(7, 5, 1, 3);
95         Quad(6, 4, 5, 7);
96         Quad(3, 1, 0, 2);
97         Quad(5, 4, 0, 1);
98         Quad(6, 7, 3, 2);
99     }
100     G3_End();                          // End vertex list
101 }
102 
103 
104 //---------------------------------------------------------------------------
105 //  Summary:
106 //        V-Blank interrupt process
107 //  Description:
108 //        Enables a flag that confirms that a V-Blank interrupt has been performed
109 //
110 //        The following steps will be performed during common initialization (DEMOInitCommon), causing this function to be called during V-Blanks
111 //        * Select IRQ interrupt (OS_SetIrqMask)
112 //        * Register this function, which performs IRQ interrupts (OS_SetIRQFunction)
113 //        * Enable IRQ interrupts (OS_EnableIrq)
114 //
115 //---------------------------------------------------------------------------
VBlankIntr(void)116 void VBlankIntr(void)
117 {
118     OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Sets a V-Blank interrupt confirmation flag
119 }
120 
121 //---------------------------------------------------------------------------
122 //  Summary:
123 //       Sets TR_MISC_XLU_DEPTH_UPDATE in G3_PolygonAttr
124 //       (Updates the depth buffer when drawing translucent polygons)
125 //  Description:
126 //        The semi-transparent cube with fog applied that is the target of the depth test orbits the periphery of the normal display rectangle
127 //
128 //        If depth value updating is OFF, the influence of the fog on the depth value will not be shown on the semi-transparent cube.
129 //      When the depth value update is ON, the effect of fog will be reflected.
130 //  Controls:
131 //       START: Switch depth value update ON/OFF
132 //       UP, DOWN: Increase and decrease the object's alpha value
133 //---------------------------------------------------------------------------
134 #ifdef SDK_TWL
TwlMain(void)135 void TwlMain(void)
136 #else
137 void NitroMain(void)
138 #endif
139 {
140     unsigned int count = 0;
141     int     alpha = 0x0a;
142     BOOL    trg = 1;
143     u16     Rotate = 0;
144 
145     //---------------------
146     // Initialize (enable IRQ, initialize VRAM, use BG0 in 3D mode)
147     //---------------------
148     DEMOInitCommon();
149     DEMOInitVRAM();
150     DEMOInitDisplay3D();
151 
152     /* Fog configuration */
153     {
154         u32     fog_table[8];
155         int     i;
156 
157         // Clear color settings
158         G3X_SetClearColor(GX_RGB(0, 0, 0),      // Clear color
159                           0,           // Clear alpha value
160                           0x7fff,      // Clear depth value
161                           63,          // Clear polygon ID
162                           TRUE);       // Use fog
163         // Fog attribute settings
164         G3X_SetFog(TRUE,               // Enable fog
165                    GX_FOGBLEND_COLOR_ALPHA,     // Apply fog to color and alpha
166                    GX_FOGSLOPE_0x2000, // Fog gradient settings
167                    0x5800);            // Fog calculation depth value
168         G3X_SetFogColor(GX_RGB(31, 31, 31), 0); // Fog color settings
169 
170         // Fog table settings (increasing the values thickens the fog)
171         for (i = 0; i < 8; i++)
172         {
173             fog_table[i] = (u32)(((i * 16) << 0) |
174                                  ((i * 16 + 4) << 8) |
175                                  ((i * 16 + 8) << 16) | ((i * 16 + 12) << 24));
176         }
177         G3X_SetFogTable(&fog_table[0]);
178     }
179 
180     G3X_AlphaBlend(TRUE);              // Enable alpha blending
181 
182     /* Swap rendering engine reference data groups
183        (Notice that in Z buffer mode and W buffer mode depth values are different)
184         */
185     G3_SwapBuffers(GX_SORTMODE_AUTO,   // Auto sort mode
186                    GX_BUFFERMODE_Z);   // Buffering mode using Z values
187 
188     DEMOStartDisplay();
189 
190     OS_Printf("mssg%d:PolygonAttr_DepthUpdate=%s\n", count++, (trg ? "ON" : "OFF"));
191 
192     //---------------------
193     //  Main loop
194     //---------------------
195     while (1)
196     {
197         G3X_Reset();
198         Rotate += 256;
199 
200         /* Obtain pad information and configure operations */
201         DEMOReadKey();
202 #ifdef SDK_AUTOTEST                    // Code for auto-test
203         {
204             const EXTKeys keys[8] = { {PAD_KEY_UP, 10}, {0, 1}, {PAD_KEY_UP, 10}, {0, 1},
205             {PAD_KEY_UP, 10}, {0, 1}, {PAD_KEY_UP, 10}, {0, 0}
206             };
207             EXT_AutoKeys(keys, &gKeyWork.press, &gKeyWork.trigger);
208         }
209 #endif
210 
211         if (DEMO_IS_TRIG(PAD_KEY_UP))
212         {
213             if (++alpha > 31)
214             {
215                 alpha = 31;
216             }
217             OS_Printf("mssg%d:alpha=%d\n", count++, alpha);
218         }
219         else if (DEMO_IS_TRIG(PAD_KEY_DOWN))
220         {
221             if (--alpha < 0)
222             {
223                 alpha = 0;
224             }
225             OS_Printf("mssg%d:alpha=%d\n", count++, alpha);
226         }
227         if (DEMO_IS_TRIG(PAD_BUTTON_START))
228         {
229             trg = (trg + 1) & 0x01;
230             OS_Printf("mssg%d:PolygonAttr_DepthUpdate=%s\n", count++, (trg ? "ON" : "OFF"));
231         }
232 
233         /* Camera configuration */
234         {
235             VecFx32 Eye = { 0, 0, FX32_ONE * 8 };       // Eye point position
236             VecFx32 at = { 0, 0, 0 };  // Viewpoint
237             VecFx32 vUp = { 0, FX32_ONE, 0 };   // Up
238 
239             G3_LookAt(&Eye, &vUp, &at, NULL);   // Eye point settings
240         }
241 
242         G3_MtxMode(GX_MTXMODE_TEXTURE); // Set matrix to texture mode
243         G3_Identity();                 // Initialize current matrix to a unit matrix
244         // The matrix is set to Position-Vector simultaneous set mode
245         G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
246 
247         G3_PushMtx();                  // Add matrix to the stack
248 
249         /* Calculate the cube rotation and set its position */
250         {
251             fx16    s = FX_SinIdx(Rotate);
252             fx16    c = FX_CosIdx(Rotate);
253 
254             G3_RotY(s, c);
255             G3_Translate(0, 0, 5 * FX32_ONE);
256             G3_RotX(s, c);
257             G3_RotZ(s, c);
258         }
259 
260         /* Cube render configuration (perform fog blending) */
261         // Set a diffuse color and an ambient color of texture
262         G3_MaterialColorDiffAmb(GX_RGB(31, 0, 0),       // Diffuse reflection color
263                                 GX_RGB(16, 16, 16),     // Ambient reflection color
264                                 TRUE); // Set vertex color
265         // Set a specular color and an emission color of texture
266         G3_MaterialColorSpecEmi(GX_RGB(16, 16, 16),     // Specular reflection color
267                                 GX_RGB(0, 0, 0),        // The emission color
268                                 FALSE); // Specular reflection not used
269 
270         // Cube polygon attribute (alpha and depth) settings
271         {
272             int     attr;
273 
274             if (trg)
275             {
276                 attr = GX_POLYGON_ATTR_MISC_XLU_DEPTH_UPDATE;
277             }
278             else
279             {
280                 attr = GX_POLYGON_ATTR_MISC_NONE;
281             }
282             attr |= GX_POLYGON_ATTR_MISC_FOG;
283             // Polygon attribute settings
284             G3_PolygonAttr(GX_LIGHTMASK_NONE,   // No light influence
285                            GX_POLYGONMODE_MODULATE,     // Modulation mode
286                            GX_CULL_BACK,        // Perform backface culling
287                            0,          // Polygon ID 0
288                            alpha,      // Alpha value setting
289                            attr);
290         }
291 
292         DrawCube();                    // Draw cube
293 
294         G3_PopMtx(1);
295 
296         /* Rectangle render configuration (do not perform fog blending) */
297         G3_PushMtx();
298         // Set a diffuse color and an ambient color of texture
299         G3_MaterialColorDiffAmb(GX_RGB(0, 0, 31),       // Diffuse reflection color
300                                 GX_RGB(16, 16, 16),     // Ambient reflection color
301                                 TRUE); // Set vertex color
302         // Set a specular color and an emission color of texture
303         G3_MaterialColorSpecEmi(GX_RGB(16, 16, 16),     // Specular reflection color
304                                 GX_RGB(0, 0, 0),        // The emission color
305                                 FALSE); // Specular reflection not used
306         // Polygon attribute settings
307         G3_PolygonAttr(GX_LIGHTMASK_NONE,       // No light influence
308                        GX_POLYGONMODE_MODULATE, // Modulation mode
309                        GX_CULL_BACK,   // Perform backface culling
310                        0,              // Polygon ID 0
311                        31,             // Alpha value
312                        0);
313 
314         G3_Begin(GX_BEGIN_QUADS);      // Begin vertex list (draw with quadrilateral polygons)
315         {
316             G3_Vtx(FX32_ONE << 2, -FX32_ONE << 2, 0);
317             G3_Vtx(FX32_ONE << 2, FX32_ONE << 2, 0);
318             G3_Vtx(-FX32_ONE, FX32_ONE << 2, 0);
319             G3_Vtx(-FX32_ONE, -FX32_ONE << 2, 0);
320         }
321         G3_End();                      // End vertex list
322 
323         G3_PopMtx(1);
324 
325         // Swapping the polygon list RAM, the vertex RAM, etc.
326         G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_Z);
327 
328         /* Waiting for the V-Blank */
329         OS_WaitVBlankIntr();
330 
331 #ifdef SDK_AUTOTEST                    // Code for auto-test
332         GX_SetBankForLCDC(GX_VRAM_LCDC_C);
333         EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
334         EXT_TestScreenShot(100, 0x2A787000);
335         EXT_TestTickCounter();
336 #endif //SDK_AUTOTEST
337     }
338 }
339