1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: CommandBufferJump.cpp
4
5 Copyright (C)2009-2012 Nintendo Co., Ltd. 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 $Rev: 47228 $
14 *---------------------------------------------------------------------------*/
15
16 /*
17 *------------------------------------------------------------
18 * Copyright(c) 2009-2010 by Digital Media Professionals Inc.
19 * All rights reserved.
20 *------------------------------------------------------------
21 * This source code is the confidential and proprietary
22 * of Digital Media Professionals Inc.
23 *------------------------------------------------------------
24 */
25
26 #include <nn/gx.h>
27 #include <nn/fs.h>
28 #include <nn/math.h>
29 #include <nn/init.h>
30 #include <nn/os.h>
31 #include <nn/applet.h>
32 #include <nn/gx/CTR/gx_CommandAccess.h>
33
34 #include "demo.h"
35
36 #include "Util.h"
37 #include "Loader.h"
38
39 #include <string.h>
40 #include <math.h>
41
42 #include "Memory.h"
43
44 #define APP_NAME "CommandBufferJump"
45
46 #define STATE_SETTINGS 0 /* 0 - simple Blinn-Phong, 1 - generalized Blinn-Phong, 2 - Cook-Torrance */
47
48 static void State0(void);
49
50 static void State1(void);
51
52 static void State2(void);
53
54 void (*render_state_func[])(void) =
55 {
56 State0, State1, State2,
57 };
58
59 /* obj file loader class object */
60 dat_t robot;
61
62 /* program id */
63 GLuint s_ProgramID;
64
65 /* program ids */
66 GLuint s_ProgramIDs[3];
67
68 /* shader id */
69 GLuint s_ShaderID;
70
71 /* texture id */
72 GLuint s_TextureID[3];
73
74 /* command list id */
75 GLuint s_CmdlistID[4];
76
77 #define NUM_OBJ 18
78 unsigned* s_SubrCommand[NUM_OBJ];
79
80 struct CmdlistInfo
81 {
82 GLvoid* bufferaddr;
83 GLsizei buffersize;
84 } s_CmdlistInfo[4];
85
86 /* ExpHeap for app. */
87 nn::fnd::ExpHeap s_AppHeap;
88 uptr s_HeapForGx;
89 uptr s_HeapForMalloc;
90 const u32 s_GxHeapSize = 0x400000;
91 const u32 s_HeapSize = 0x200000;
92
93 demo::RenderSystem s_RenderSystem;
94
State0(void)95 static void State0(void)
96 {
97 GLfloat ls0[] = {1.f, 1.f, 0.f, 1.f};
98 GLfloat ms[] = {1.f, 1.f, 1.f, 1.f};
99 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].specular0"), 1, ls0);
100 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.specular0"), 1, ms);
101
102 /* to ignore 2nd specular term, set 0 to ms2.
103 use of const reflection allows material specular2(ms2). */
104 GLfloat ms2[] = {0.f, 0.f, 0.f, 1.f};
105 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.specular1"), 1, ms2);
106 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledRefl"), GL_FALSE);
107
108 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputD0"), GL_LIGHT_ENV_NH_DMP);
109 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputD0"), GL_TRUE);
110
111 /* Because the 2nd specular term is not used, only the D0 table is used
112 in configuration 0. */
113 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.config"), GL_LIGHT_ENV_LAYER_CONFIG0_DMP);
114
115 /* geometry factor is not considered. */
116 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].geomFactor1"), GL_FALSE);
117
118 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledD0"), GL_TRUE);
119 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.clampHighlights"), GL_FALSE);
120
121 /* bind lookup table */
122 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerD0"), 0);
123
124 /* setup lookup table */
125 GLuint lutids[2];
126 glGenTextures(2, lutids);
127 glBindTexture(GL_TEXTURE_COLLECTION_DMP, lutids[0]);
128
129 GLfloat lut[512];
130 int j;
131 memset(lut, 0, sizeof(lut));
132
133 for (j = 0; j < 256; j++)
134 /* shininess is 10.0 */
135 lut[j] = powf((float)j/255.9375f, 10.f);
136 /* shininess is 1.0 */
137 /* lut[j] = powf((float)j/255.9375f, 1.f); */
138 for (j = 0; j < 255; j++)
139 lut[j + 256] = lut[j + 1] - lut[j];
140 lut[255 + 256] = 1.f - lut[255];
141
142 glBindTexture(GL_LUT_TEXTURE0_DMP, lutids[1]);
143 glTexImage1D(GL_LUT_TEXTURE0_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
144
145 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineRgb"), GL_REPLACE);
146 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
147 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
148 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
149 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcRgb"), GL_FRAGMENT_SECONDARY_COLOR_DMP, GL_CONSTANT, GL_CONSTANT);
150 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcAlpha"), GL_CONSTANT, GL_CONSTANT, GL_CONSTANT);
151 }
152
153 /* Generalized Blinn-Phong reflection */
State1(void)154 static void State1(void)
155 {
156 GLfloat ls0[] = {0.f, 1.f, 0.f, 1.f};
157 GLfloat ms[] = {1.f, 1.f, 1.f, 1.f};
158 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].specular0"), 1, ls0);
159 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.specular0"), 1, ms);
160
161 GLfloat ls20[] = {1.f, 0.01f, 0.25f, 1.f};
162 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].specular1"), 1, ls20);
163 /* use of const reflection allows material specular2(ms2). */
164 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledRefl"), GL_FALSE);
165 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.specular1"), 1, ms);
166
167 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputD1"), GL_LIGHT_ENV_NH_DMP);
168 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputD0"), GL_LIGHT_ENV_NH_DMP);
169 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputD1"), GL_TRUE);
170 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputD0"), GL_TRUE);
171
172 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.config"), GL_LIGHT_ENV_LAYER_CONFIG2_DMP);
173
174 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].geomFactor0"), GL_FALSE);
175 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].geomFactor1"), GL_FALSE);
176 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledD0"), GL_TRUE);
177 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledD1"), GL_TRUE);
178 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.clampHighlights"), GL_FALSE);
179
180 /* bind lookup table */
181 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerD1"), 0);
182 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerD0"), 1);
183
184 /* setup lookup table */
185 GLuint lutids[3];
186 glGenTextures(3, lutids);
187 glBindTexture(GL_TEXTURE_COLLECTION_DMP, lutids[0]);
188
189 GLfloat lut[512];
190 int j;
191 memset(lut, 0, sizeof(lut));
192
193 /* set layer1 distribution function */
194 for (j = 0; j < 256; j++)
195 /* when s is equal to 2.0/m^2, highlight specular is similar between
196 power function and gaussian function.
197 when s is 90.0, m is 0.149, and when s is 2.0,
198 m is 1.0. */
199 /* lut[j] = powf((float)j/255.9375f, 90.f); */
200 lut[j] = gaussian((float)j/255.9375f, 0.149f);
201 for (j = 0; j < 255; j++)
202 lut[j + 256] = lut[j + 1] - lut[j];
203 lut[255 + 256] = 1.f - lut[255];
204
205 glBindTexture(GL_LUT_TEXTURE0_DMP, lutids[1]);
206 glTexImage1D(GL_LUT_TEXTURE0_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
207
208 /* set layer2 distribution function */
209 memset(lut, 0, sizeof(lut));
210
211 for (j = 0; j < 256; j++)
212 /* lut[j] = powf((float)j/255.9375f, 2.f); */
213 lut[j] = gaussian((float)j/255.9375f, 1.f);
214 for (j = 0; j < 255; j++)
215 lut[j + 256] = lut[j + 1] - lut[j];
216 lut[255 + 256] = 1.f - lut[255];
217
218 glBindTexture(GL_LUT_TEXTURE1_DMP, lutids[2]);
219 glTexImage1D(GL_LUT_TEXTURE1_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
220
221 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineRgb"), GL_REPLACE);
222 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
223 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
224 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
225 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcRgb"), GL_FRAGMENT_SECONDARY_COLOR_DMP, GL_CONSTANT, GL_CONSTANT);
226 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcAlpha"), GL_CONSTANT, GL_CONSTANT, GL_CONSTANT);
227 }
228
229
230 /* Full-scope Cook-Torrance reflection */
State2(void)231 static void State2(void)
232 {
233 GLfloat ls0[] = {1.f, 1.f, 1.f, 1.f};
234 GLfloat disable[] = {0.f, 0.f, 0.f, 0.f};
235
236 /* to ignore specular 1st term, set 0. */
237 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.specular0"), 1, disable);
238 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].specular1"), 1, ls0);
239
240 /* to use Rr, Rg, Rb table */
241 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledRefl"), GL_TRUE);
242
243 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputRR"), GL_LIGHT_ENV_VH_DMP);
244 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputRG"), GL_LIGHT_ENV_VH_DMP);
245 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputRB"), GL_LIGHT_ENV_VH_DMP);
246 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputD0"), GL_LIGHT_ENV_NH_DMP);
247 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputD1"), GL_LIGHT_ENV_NH_DMP);
248
249 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputRR"), GL_FALSE);
250 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputRG"), GL_FALSE);
251 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputRB"), GL_FALSE);
252 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputD0"), GL_FALSE);
253 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputD1"), GL_FALSE);
254
255 /* below we make bit shift after sampling table of Fresnel reflection
256 we have to do this because we do not have HDR(sky has high intensity) */
257 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleRR"), 2.f);
258 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleRG"), 2.f);
259 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleRB"), 2.f);
260 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleD0"), 2.f);
261 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleD1"), 2.f);
262
263 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.config"), GL_LIGHT_ENV_LAYER_CONFIG4_DMP);
264
265 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledD0"), GL_TRUE);
266 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledD1"), GL_TRUE);
267 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.clampHighlights"), GL_FALSE);
268
269 /* geometory factor is considered in Cook-Torrance model */
270 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].geomFactor0"), GL_TRUE);
271 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].geomFactor1"), GL_TRUE);
272
273 /* bind lookup table */
274 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerRR"), 0);
275 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerRG"), 1);
276 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerRB"), 2);
277 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerD1"), 3);
278 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerD0"), 4);
279
280 /* setup lookup table */
281 GLuint lutids[6];
282 glGenTextures(6, lutids);
283 glBindTexture(GL_TEXTURE_COLLECTION_DMP, lutids[0]);
284
285 GLfloat lut[512];
286 int j;
287 memset(lut, 0, sizeof(lut));
288 glBindTexture(GL_LUT_TEXTURE4_DMP, lutids[5]);
289 glTexImage1D(GL_LUT_TEXTURE4_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
290
291 /* in this sample, gold is used as fresnel factor,
292 and real and imaginary part of refractive index of gold
293 is following.
294 n k
295 ---------------------------------
296 0.183521, 2.959155 at 630 nm
297 0.516924, 2.276178 at 525 nm
298 1.464924, 1.860113 at 455 nm */
299 /* setup Rr table */
300 for (j = 0; j < 128; j++)
301 lut[j] = nk_fresnel((float)j/128.f, 0.183521f, 2.959155f);
302
303 for (j = 0; j < 127; j++)
304 lut[j + 256] = lut[j+1] - lut[j];
305
306 lut[127 + 256] = nk_fresnel(1.f, 0.183521f, 2.959155f) - lut[127];
307
308 glBindTexture(GL_LUT_TEXTURE0_DMP, lutids[1]);
309 glTexImage1D(GL_LUT_TEXTURE0_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
310
311 /* setup Rg table */
312 memset(lut, 0, sizeof(lut));
313 for (j = 0; j < 128; j++)
314 lut[j] = nk_fresnel((float)j/128.f, 0.516924f, 2.276178f);
315
316 for (j = 0; j < 127; j++)
317 lut[j + 256] = lut[j+1] - lut[j];
318
319 lut[127 + 256] = nk_fresnel(1.f, 0.516924f, 2.276178f) - lut[127];
320
321 glBindTexture(GL_LUT_TEXTURE1_DMP, lutids[2]);
322 glTexImage1D(GL_LUT_TEXTURE1_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
323
324 /* setup Rb table */
325 memset(lut, 0, sizeof(lut));
326 for (j = 0; j < 128; j++)
327 lut[j] = nk_fresnel((float)j/128.f, 1.464924f, 1.860113f);
328
329 for (j = 0; j < 127; j++)
330 lut[j + 256] = lut[j+1] - lut[j];
331
332 lut[127 + 256] = nk_fresnel(1.f, 1.464924f, 1.860113f) - lut[127];
333
334 glBindTexture(GL_LUT_TEXTURE2_DMP, lutids[3]);
335 glTexImage1D(GL_LUT_TEXTURE2_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
336
337 /* don't use D0 table, so setup D1 table only */
338 memset(lut, 0, sizeof(lut));
339 /* Beckmann function is used in m=1.0 and m=0.5 */
340 for (j = 1; j < 128; j++)
341 lut[j] = beckmann((float)j/128.f, 1.f); /* m=1.0 */
342 /* lut[j] = beckmann((float)j/128.f, 0.5f); */ /* m=0.5 */
343
344 for (j = 0; j < 127; j++)
345 lut[j + 256] = lut[j+1] - lut[j];
346 lut[127 + 256] = 1.f - lut[127];
347
348 glBindTexture(GL_LUT_TEXTURE3_DMP, lutids[4]);
349 glTexImage1D(GL_LUT_TEXTURE3_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
350
351 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineRgb"), GL_REPLACE);
352 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
353 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
354 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
355 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcRgb"), GL_FRAGMENT_SECONDARY_COLOR_DMP, GL_CONSTANT, GL_CONSTANT);
356 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcAlpha"), GL_CONSTANT, GL_CONSTANT, GL_CONSTANT);
357 }
358
359 /* generate simple object */
LoadObjects(void)360 static void LoadObjects(void)
361 {
362 /* load obj file geometry and diffuse texture */
363 loadDAT( "rom:/resources/robot1.dat", &robot);
364 }
365
UnloadObjects(void)366 static void UnloadObjects(void)
367 {
368 unloadDAT(&robot);
369
370 return;
371 }
372
CreateCommand()373 static void CreateCommand()
374 {
375 nn::math::Matrix44 proj;
376 nn::math::Matrix34 mv, rot;
377
378 // Different material setting commands each configured by State0(), State1(), and State2() are stored in s_CmdlistID[0], s_CmdlistID[1], and s_CmdlistID[2], respectively.
379 //
380 //
381
382 // A command for drawing is stored at the front in s_CmdlistID[3].
383 //
384
385 GLuint currentCmdlist;
386 nngxGetCmdlistParameteri(NN_GX_CMDLIST_BINDING, (GLint*)¤tCmdlist);
387
388 for (int prog = 0; prog < 3; prog++)
389 {
390 s_ProgramID = s_ProgramIDs[prog];
391 nngxBindCmdlist(s_CmdlistID[prog]);
392
393 glUseProgram(s_ProgramID);
394 glBindTexture(GL_TEXTURE_COLLECTION_DMP, s_TextureID[prog]);
395
396 /* setup projection matrix */
397 nn::math::MTX44Frustum(&proj, -0.06f, 0.06f, -0.06f * nn::gx::DISPLAY0_HEIGHT / nn::gx::DISPLAY0_WIDTH,
398 0.06f * nn::gx::DISPLAY0_HEIGHT / nn::gx::DISPLAY0_WIDTH, 0.2f, 200.f);
399 glUniformMatrix4fv(glGetUniformLocation(s_ProgramID, "uProjection"), 1, GL_TRUE, static_cast<f32*>(proj));
400
401 nn::math::Vector3 camPos(0.f, 0.f, 6.f);
402 nn::math::Vector3 camUp(0.f, 1.f, 0.f);
403 nn::math::Vector3 target(0.f, 0.f, 0.f);
404 nn::math::MTX34RotXYZDeg(&rot, 0.f, 0.f, -90.0f);
405 nn::math::MTX34LookAt(&mv, &camPos, &camUp, &target);
406 nn::math::MTX34Mult(&mv, &rot, &mv);
407
408 /* setup light direction */
409 nn::math::Vector4 lpos0(0.f, 1.f, 1.f, 0.f);
410 nn::math::Vector4 mv0(mv.m[0][0], mv.m[0][1], mv.m[0][2], mv.m[0][3]);
411 nn::math::Vector4 mv1(mv.m[1][0], mv.m[1][1], mv.m[1][2], mv.m[1][3]);
412 nn::math::Vector4 mv2(mv.m[2][0], mv.m[2][1], mv.m[2][2], mv.m[2][3]);
413 nn::math::Vector4 lpos(nn::math::VEC4Dot(&mv0, &lpos0), nn::math::VEC4Dot(&mv1, &lpos0), nn::math::VEC4Dot(&mv2, &lpos0), lpos0.w);
414 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].position"), 1, static_cast<f32*>(lpos));
415
416 // Create a material setting comment
417 nngxUpdateState(NN_GX_STATE_ALL);
418 nngxValidateState(NN_GX_STATE_ALL, GL_TRUE);
419
420 // Add a Channel 1 kick command
421 // Pad with dummy commands as necessary
422 unsigned retCmd[2] = {0x00000001, 0x000f023d};
423 unsigned emptyCmd[2] = {0x00000000, 0x00000200};
424 GLsizei buffersize;
425 nngxGetCmdlistParameteri(NN_GX_CMDLIST_USED_BUFSIZE, (GLint*)&buffersize);
426 if ((buffersize & 8) == 0)
427 nngxAdd3DCommand(emptyCmd, sizeof(emptyCmd), GL_TRUE);
428 nngxAdd3DCommand(retCmd, sizeof(retCmd), GL_TRUE);
429
430 // Save the sub-routine used for setting materials in s_CmdlistInfo[0-2].
431 nngxGetCmdlistParameteri(NN_GX_CMDLIST_USED_BUFSIZE, (GLint*)&s_CmdlistInfo[prog].buffersize);
432 nngxGetCmdlistParameteri(NN_GX_CMDLIST_TOP_BUFADDR, (GLint*)&s_CmdlistInfo[prog].bufferaddr);
433 nngxUpdateBuffer(s_CmdlistInfo[prog].bufferaddr, s_CmdlistInfo[prog].buffersize);
434
435 glEnableVertexAttribArray(0);
436 glEnableVertexAttribArray(1);
437
438 if (prog == 0)
439 {
440 // Create a command for drawing in s_CmdlistID[3].
441 nngxBindCmdlist(s_CmdlistID[3]);
442
443 /* draw objects */
444 for (int i = 0; i < robot.obj_num; i++)
445 {
446 glBindBuffer(GL_ARRAY_BUFFER, robot.posVB);
447 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)robot.obj[i].vtx_offset);
448 glBindBuffer(GL_ARRAY_BUFFER, robot.normVB);
449 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)robot.obj[i].nrm_offset);
450
451 for (unsigned j = robot.obj[i].patch_offset; j < robot.obj[i].patch_size + robot.obj[i].patch_offset; j++)
452 {
453 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, robot.idxVB);
454 glDrawElements(GL_TRIANGLES, robot.patch[j].elm_size,
455 GL_UNSIGNED_SHORT, (GLvoid*)(robot.patch[j].elm_offset + robot.obj[i].elm_offset));
456 }
457 }
458
459 // Add a Channel 1 kick command
460 // Pad with dummy commands as necessary
461 nngxGetCmdlistParameteri(NN_GX_CMDLIST_USED_BUFSIZE, (GLint*)&buffersize);
462 if ((buffersize & 8) == 0)
463 nngxAdd3DCommand(emptyCmd, sizeof(emptyCmd), GL_TRUE);
464 nngxAdd3DCommand(retCmd, sizeof(retCmd), GL_TRUE);
465
466 // Save a sub-routine for the drawing command in s_CmdlistInfo[3].
467 nngxGetCmdlistParameteri(NN_GX_CMDLIST_USED_BUFSIZE, (GLint*)&s_CmdlistInfo[3].buffersize);
468 nngxGetCmdlistParameteri(NN_GX_CMDLIST_TOP_BUFADDR, (GLint*)&s_CmdlistInfo[3].bufferaddr);
469 nngxUpdateBuffer(s_CmdlistInfo[3].bufferaddr, s_CmdlistInfo[3].buffersize);
470 }
471 }
472
473 nngxBindCmdlist(currentCmdlist);
474
475 }
476
DrawFrame(void)477 int DrawFrame(void)
478 {
479 static int f = 0;
480
481 nn::math::Matrix44 proj;
482 nn::math::Matrix34 mv, rot, trans, scale;
483
484 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
485 s_RenderSystem.Clear();
486
487 if (f == 0)
488 CreateCommand();
489
490 int num_obj = (f / 60) % NUM_OBJ + 1;
491
492 // Draw the number of models given by num_obj.
493 for (int obj = 0; obj < num_obj; obj++)
494 {
495 unsigned* modelViewCommand = s_SubrCommand[obj];
496
497 // Create model view command
498 nn::math::Vector3 camPos(0.f, 0.f, 6.f);
499 nn::math::Vector3 camUp(0.f, 1.f, 0.f);
500 nn::math::Vector3 target(0.f, 0.f, 0.f);
501 nn::math::MTX34RotXYZDeg(&rot, 0.f, 0.f, -90.0f);
502 nn::math::MTX34LookAt(&mv, &camPos, &camUp, &target);
503 nn::math::MTX34Mult(&mv, &rot, &mv);
504 nn::math::MTX34RotXYZDeg(&rot, 0.f, static_cast<f32>((float)(360.f / NUM_OBJ * obj) - f), 0.f);
505 nn::math::MTX34Mult(&mv, &mv, &rot);
506 nn::math::Vector3 Trans(2.0f, 0.f, 0.f);
507 nn::math::MTX34Translate(&trans, &Trans);
508 nn::math::MTX34Mult(&mv, &mv, &trans);
509 nn::math::Vector3 Scale(0.25f, 0.25f, 0.25f);
510 nn::math::MTX34Scale(&scale, &Scale);
511 nn::math::MTX34Mult(&mv, &mv, &scale);
512
513 nn::math::Matrix44 m(mv);
514
515 // Create a sub-routine for configuring the model view
516 int index = 0;
517 modelViewCommand[index++] = 0x80000004;
518 modelViewCommand[index++] = 0x000f02c0;
519
520 for (int i = 0; i < 4; i++)
521 for (int j = 0; j < 4; j++)
522 {
523 float v = m.m[i][3 - j];
524 modelViewCommand[index++] = *(unsigned*)&v;
525 if (i == 0 && j == 0)
526 modelViewCommand[index++] = 0x00ff02c1;
527 }
528 modelViewCommand[index++] = 0x00000000; // Pad the last four bytes of the burst.
529 if ((index & 2) == 0)
530 {
531 // Padding for 16-byte alignment
532 modelViewCommand[index++] = 0x00000000;
533 modelViewCommand[index++] = 0x00000200;
534 }
535 // Channel 1 kick command
536 modelViewCommand[index++] = 0x00000001;
537 modelViewCommand[index++] = 0x000f023d;
538
539 // Clear the cache
540 nngxUpdateBuffer(modelViewCommand, sizeof(unsigned) * index);
541
542
543
544 // Apply the sub-routine for configuring materials
545 nngxAddSubroutineCommand(s_CmdlistInfo[obj % 3].bufferaddr, s_CmdlistInfo[obj % 3].buffersize);
546
547 // Apply the sub-routine for configuring the model view
548 nngxAddSubroutineCommand(modelViewCommand, sizeof(unsigned) * index);
549
550 // Apply the sub-routine for the draw command
551 nngxAddSubroutineCommand(s_CmdlistInfo[3].bufferaddr, s_CmdlistInfo[3].buffersize);
552 }
553
554 s_RenderSystem.SwapBuffers();
555
556 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
557 s_RenderSystem.Clear();
558 s_RenderSystem.SwapBuffers();
559
560 s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
561
562 f++;
563
564 return !glGetError();
565 }
566
567 /* initialization */
Initialize(void)568 static int Initialize(void)
569 {
570 s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize() );
571 s_HeapForGx = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_GxHeapSize));
572 /* Initialize display */
573 s_RenderSystem.Initialize(s_HeapForGx, s_GxHeapSize);
574
575 /* Create heap for malloc*/
576 s_HeapForMalloc = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_HeapSize));
577 setMemoryHeap(s_HeapForMalloc, s_GxHeapSize);
578
579 for (int i = 0; i < 3; i++)
580 s_ProgramIDs[i] = glCreateProgram();
581 s_ShaderID = glCreateShader(GL_VERTEX_SHADER);
582
583 nn::fs::FileReader file(L"rom:/shader.shbin");
584 size_t fileSize = file.GetSize();
585 void* buf = s_AppHeap.Allocate(fileSize);
586
587 s32 read = file.Read(buf, fileSize);
588 glShaderBinary(1, &s_ShaderID, GL_PLATFORM_BINARY_DMP, buf, read);
589 file.Finalize();
590 s_AppHeap.Free(buf);
591
592 GLuint currentCmdlist;
593 nngxGetCmdlistParameteri(NN_GX_CMDLIST_BINDING, (GLint*)¤tCmdlist);
594
595 for (int i = 0; i < 3; i++)
596 {
597 s_ProgramID = s_ProgramIDs[i];
598
599 nngxGenCmdlists(1, &s_CmdlistID[i]);
600 nngxBindCmdlist(s_CmdlistID[i]);
601 nngxCmdlistStorage(0x8000, 16);
602
603 glAttachShader(s_ProgramID, s_ShaderID);
604 glAttachShader(s_ProgramID, GL_DMP_FRAGMENT_SHADER_DMP);
605
606 glBindAttribLocation(s_ProgramID, 0, "aPosition");
607 glBindAttribLocation(s_ProgramID, 1, "aNormal");
608
609 glLinkProgram(s_ProgramID);
610 glValidateProgram(s_ProgramID);
611 glUseProgram(s_ProgramID);
612 }
613
614 nngxGenCmdlists(1, &s_CmdlistID[3]);
615 nngxBindCmdlist(s_CmdlistID[3]);
616 nngxCmdlistStorage(0x10000, 16);
617 GLint SubrCommandStart;
618 nngxGetCmdlistParameteri(NN_GX_CMDLIST_TOP_BUFADDR, (GLint*)&SubrCommandStart);
619
620 // s_SubrCommand stores a subroutine for configuring the model view for each object.
621 for (int i = 0; i < NUM_OBJ; i++)
622 s_SubrCommand[i] = (unsigned*)(SubrCommandStart + 0x2000 + 0x100 * i);
623
624 nngxBindCmdlist(currentCmdlist);
625
626 glClearColor(0.36f, 0.42f, 0.5f, 1.0f);
627 glClearDepthf(1.f);
628
629 glEnable(GL_DEPTH_TEST);
630 glDepthFunc(GL_LESS);
631 glEnable(GL_CULL_FACE);
632 glFrontFace(GL_CCW);
633 glCullFace(GL_BACK);
634
635 LoadObjects();
636
637 /* set another render state */
638 for (int i = 0; i < 3; i++)
639 {
640 s_ProgramID = s_ProgramIDs[i];
641
642 glUseProgram(s_ProgramID);
643
644 (*render_state_func[i])();
645
646 /* enable DMP fragment lighting */
647 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLighting.enabled"), GL_TRUE);
648 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].enabled"), GL_TRUE);
649
650 glGetIntegerv(GL_TEXTURE_COLLECTION_BINDING_DMP, (GLint*)&s_TextureID[i]);
651 }
652
653 return 0;
654 }
655
nnMain(void)656 void nnMain(void)
657 {
658 // Call only the nn::applet::Enable function to also allow execution from the HOME Menu
659 // HOME Menu transitions, POWER Button presses, and sleep are all unsupported
660 nn::applet::Enable();
661
662 // fs initialization
663 nn::fs::Initialize();
664
665 const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
666 static char buffer[ROMFS_BUFFER_SIZE];
667 NN_UTIL_PANIC_IF_FAILED(
668 nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
669
670 /* initialization */
671 if (Initialize() >= 0)
672 {
673 /* Enter loop */
674 while (1)
675 {
676 (void)DrawFrame();
677 }
678 }
679
680 UnloadObjects();
681 /* shutdown_display */
682 s_RenderSystem.Finalize();
683 s_AppHeap.Free(reinterpret_cast<void*>(s_HeapForMalloc));
684 s_AppHeap.Free(reinterpret_cast<void*>(s_HeapForGx));
685 s_AppHeap.Finalize();
686 }
687