1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: LightingMicrofacet.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
33 #include "demo.h"
34
35 #include "Util.h"
36 #include "Loader.h"
37
38 #include <string.h>
39 #include <math.h>
40
41 #include "Memory.h"
42
43 #define APP_NAME "LightingMicrofacet"
44
45 #define STATE_SETTINGS 0 /* 0 - simple Blinn-Phong, 1 - generalized Blinn-Phong, 2 - Cook-Torrance */
46
47 static void State0(void);
48
49 static void State1(void);
50
51 static void State2(void);
52
53 void (*render_state_func[])(void) =
54 {
55 State0, State1, State2,
56 };
57
58 /* obj file loader class object */
59 dat_t robot;
60
61 /* program id */
62 GLuint s_ProgramID;
63
64 /* shader id */
65 GLuint s_ShaderID;
66
67 /* ExpHeap for app. */
68 nn::fnd::ExpHeap s_AppHeap;
69 uptr s_HeapForGx;
70 uptr s_HeapForMalloc;
71 const u32 s_GxHeapSize = 0x400000;
72 const u32 s_HeapSize = 0x200000;
73
74 demo::RenderSystem s_RenderSystem;
75
State0(void)76 static void State0(void)
77 {
78 GLfloat ls0[] = {1.f, 1.f, 0.f, 1.f};
79 GLfloat ms[] = {1.f, 1.f, 1.f, 1.f};
80 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].specular0"), 1, ls0);
81 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.specular0"), 1, ms);
82
83 /* to ignore 2nd specular term, set 0 to ms2.
84 use of const reflection allows material specular2(ms2). */
85 GLfloat ms2[] = {0.f, 0.f, 0.f, 1.f};
86 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.specular1"), 1, ms2);
87 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledRefl"), GL_FALSE);
88
89 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputD0"), GL_LIGHT_ENV_NH_DMP);
90 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputD0"), GL_TRUE);
91
92 /* Because the 2nd specular term is not used, only the D0 table is used
93 in configuration 0. */
94 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.config"), GL_LIGHT_ENV_LAYER_CONFIG0_DMP);
95
96 /* geometry factor is not considered. */
97 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].geomFactor1"), GL_FALSE);
98
99 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledD0"), GL_TRUE);
100 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.clampHighlights"), GL_FALSE);
101
102 /* bind lookup table */
103 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerD0"), 0);
104
105 /* setup lookup table */
106 GLuint lutids[2];
107 glGenTextures(2, lutids);
108 glBindTexture(GL_TEXTURE_COLLECTION_DMP, lutids[0]);
109
110 GLfloat lut[512];
111 int j;
112 memset(lut, 0, sizeof(lut));
113
114 for (j = 0; j < 256; j++)
115 /* shininess is 10.0 */
116 lut[j] = powf((float)j/255.9375f, 10.f);
117 /* shininess is 1.0 */
118 /* lut[j] = powf((float)j/255.9375f, 1.f); */
119 for (j = 0; j < 255; j++)
120 lut[j + 256] = lut[j + 1] - lut[j];
121 lut[255 + 256] = 1.f - lut[255];
122
123 glBindTexture(GL_LUT_TEXTURE0_DMP, lutids[1]);
124 glTexImage1D(GL_LUT_TEXTURE0_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
125
126 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineRgb"), GL_REPLACE);
127 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
128 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
129 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
130 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcRgb"), GL_FRAGMENT_SECONDARY_COLOR_DMP, GL_CONSTANT, GL_CONSTANT);
131 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcAlpha"), GL_CONSTANT, GL_CONSTANT, GL_CONSTANT);
132 }
133
134 /* Generalized Blinn-Phong reflection */
State1(void)135 static void State1(void)
136 {
137 GLfloat ls0[] = {0.f, 1.f, 0.f, 1.f};
138 GLfloat ms[] = {1.f, 1.f, 1.f, 1.f};
139 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].specular0"), 1, ls0);
140 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.specular0"), 1, ms);
141
142 GLfloat ls20[] = {1.f, 0.01f, 0.25f, 1.f};
143 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].specular1"), 1, ls20);
144 /* use of const reflection allows material specular2(ms2). */
145 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledRefl"), GL_FALSE);
146 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.specular1"), 1, ms);
147
148 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputD1"), GL_LIGHT_ENV_NH_DMP);
149 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputD0"), GL_LIGHT_ENV_NH_DMP);
150 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputD1"), GL_TRUE);
151 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputD0"), GL_TRUE);
152
153 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.config"), GL_LIGHT_ENV_LAYER_CONFIG2_DMP);
154
155 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].geomFactor0"), GL_FALSE);
156 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].geomFactor1"), GL_FALSE);
157 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledD0"), GL_TRUE);
158 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledD1"), GL_TRUE);
159 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.clampHighlights"), GL_FALSE);
160
161 /* bind lookup table */
162 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerD1"), 0);
163 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerD0"), 1);
164
165 /* setup lookup table */
166 GLuint lutids[3];
167 glGenTextures(3, lutids);
168 glBindTexture(GL_TEXTURE_COLLECTION_DMP, lutids[0]);
169
170 GLfloat lut[512];
171 int j;
172 memset(lut, 0, sizeof(lut));
173
174 /* set layer1 distribution function */
175 for (j = 0; j < 256; j++)
176 /* when s is equal to 2.0/m^2, highlight specular is similar between
177 power function and gaussian function.
178 when s is 90.0, m is 0.149, and when s is 2.0,
179 m is 1.0. */
180 /* lut[j] = powf((float)j/255.9375f, 90.f); */
181 lut[j] = gaussian((float)j/255.9375f, 0.149f);
182 for (j = 0; j < 255; j++)
183 lut[j + 256] = lut[j + 1] - lut[j];
184 lut[255 + 256] = 1.f - lut[255];
185
186 glBindTexture(GL_LUT_TEXTURE0_DMP, lutids[1]);
187 glTexImage1D(GL_LUT_TEXTURE0_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
188
189 /* set layer2 distribution function */
190 memset(lut, 0, sizeof(lut));
191
192 for (j = 0; j < 256; j++)
193 /* lut[j] = powf((float)j/255.9375f, 2.f); */
194 lut[j] = gaussian((float)j/255.9375f, 1.f);
195 for (j = 0; j < 255; j++)
196 lut[j + 256] = lut[j + 1] - lut[j];
197 lut[255 + 256] = 1.f - lut[255];
198
199 glBindTexture(GL_LUT_TEXTURE1_DMP, lutids[2]);
200 glTexImage1D(GL_LUT_TEXTURE1_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
201
202 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineRgb"), GL_REPLACE);
203 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
204 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
205 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
206 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcRgb"), GL_FRAGMENT_SECONDARY_COLOR_DMP, GL_CONSTANT, GL_CONSTANT);
207 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcAlpha"), GL_CONSTANT, GL_CONSTANT, GL_CONSTANT);
208 }
209
210
211 /* Full-scope Cook-Torrance reflection */
State2(void)212 static void State2(void)
213 {
214 GLfloat ls0[] = {1.f, 1.f, 1.f, 1.f};
215 GLfloat disable[] = {0.f, 0.f, 0.f, 0.f};
216
217 /* to ignore specular 1st term, set 0. */
218 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.specular0"), 1, disable);
219 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].specular1"), 1, ls0);
220
221 /* to use Rr, Rg, Rb table */
222 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledRefl"), GL_TRUE);
223
224 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputRR"), GL_LIGHT_ENV_VH_DMP);
225 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputRG"), GL_LIGHT_ENV_VH_DMP);
226 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputRB"), GL_LIGHT_ENV_VH_DMP);
227 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputD0"), GL_LIGHT_ENV_NH_DMP);
228 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputD1"), GL_LIGHT_ENV_NH_DMP);
229
230 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputRR"), GL_FALSE);
231 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputRG"), GL_FALSE);
232 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputRB"), GL_FALSE);
233 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputD0"), GL_FALSE);
234 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputD1"), GL_FALSE);
235
236 /* below we make bit shift after sampling table of Fresnel reflection
237 we have to do this because we do not have HDR(sky has high intensity) */
238 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleRR"), 2.f);
239 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleRG"), 2.f);
240 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleRB"), 2.f);
241 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleD0"), 2.f);
242 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleD1"), 2.f);
243
244 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.config"), GL_LIGHT_ENV_LAYER_CONFIG4_DMP);
245
246 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledD0"), GL_TRUE);
247 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledD1"), GL_TRUE);
248 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.clampHighlights"), GL_FALSE);
249
250 /* geometory factor is considered in Cook-Torrance model */
251 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].geomFactor0"), GL_TRUE);
252 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].geomFactor1"), GL_TRUE);
253
254 /* bind lookup table */
255 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerRR"), 0);
256 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerRG"), 1);
257 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerRB"), 2);
258 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerD1"), 3);
259 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerD0"), 4);
260
261 /* setup lookup table */
262 GLuint lutids[6];
263 glGenTextures(6, lutids);
264 glBindTexture(GL_TEXTURE_COLLECTION_DMP, lutids[0]);
265
266 GLfloat lut[512];
267 int j;
268 memset(lut, 0, sizeof(lut));
269 glBindTexture(GL_LUT_TEXTURE4_DMP, lutids[5]);
270 glTexImage1D(GL_LUT_TEXTURE4_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
271
272 /* in this sample, gold is used as fresnel factor,
273 and real and imaginary part of refractive index of gold
274 is following.
275 n k
276 ---------------------------------
277 0.183521, 2.959155 at 630 nm
278 0.516924, 2.276178 at 525 nm
279 1.464924, 1.860113 at 455 nm */
280 /* setup Rr table */
281 for (j = 0; j < 128; j++)
282 lut[j] = nk_fresnel((float)j/128.f, 0.183521f, 2.959155f);
283
284 for (j = 0; j < 127; j++)
285 lut[j + 256] = lut[j+1] - lut[j];
286
287 lut[127 + 256] = nk_fresnel(1.f, 0.183521f, 2.959155f) - lut[127];
288
289 glBindTexture(GL_LUT_TEXTURE0_DMP, lutids[1]);
290 glTexImage1D(GL_LUT_TEXTURE0_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
291
292 /* setup Rg table */
293 memset(lut, 0, sizeof(lut));
294 for (j = 0; j < 128; j++)
295 lut[j] = nk_fresnel((float)j/128.f, 0.516924f, 2.276178f);
296
297 for (j = 0; j < 127; j++)
298 lut[j + 256] = lut[j+1] - lut[j];
299
300 lut[127 + 256] = nk_fresnel(1.f, 0.516924f, 2.276178f) - lut[127];
301
302 glBindTexture(GL_LUT_TEXTURE1_DMP, lutids[2]);
303 glTexImage1D(GL_LUT_TEXTURE1_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
304
305 /* setup Rb table */
306 memset(lut, 0, sizeof(lut));
307 for (j = 0; j < 128; j++)
308 lut[j] = nk_fresnel((float)j/128.f, 1.464924f, 1.860113f);
309
310 for (j = 0; j < 127; j++)
311 lut[j + 256] = lut[j+1] - lut[j];
312
313 lut[127 + 256] = nk_fresnel(1.f, 1.464924f, 1.860113f) - lut[127];
314
315 glBindTexture(GL_LUT_TEXTURE2_DMP, lutids[3]);
316 glTexImage1D(GL_LUT_TEXTURE2_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
317
318 /* don't use D0 table, so setup D1 table only */
319 memset(lut, 0, sizeof(lut));
320 /* Beckmann function is used in m=1.0 and m=0.5 */
321 for (j = 1; j < 128; j++)
322 lut[j] = beckmann((float)j/128.f, 1.f); /* m=1.0 */
323 /* lut[j] = beckmann((float)j/128.f, 0.5f); */ /* m=0.5 */
324
325 for (j = 0; j < 127; j++)
326 lut[j + 256] = lut[j+1] - lut[j];
327 lut[127 + 256] = 1.f - lut[127];
328
329 glBindTexture(GL_LUT_TEXTURE3_DMP, lutids[4]);
330 glTexImage1D(GL_LUT_TEXTURE3_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
331
332 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineRgb"), GL_REPLACE);
333 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
334 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
335 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
336 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcRgb"), GL_FRAGMENT_SECONDARY_COLOR_DMP, GL_CONSTANT, GL_CONSTANT);
337 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcAlpha"), GL_CONSTANT, GL_CONSTANT, GL_CONSTANT);
338 }
339
340 /* generate simple object */
LoadObjects(void)341 static void LoadObjects(void)
342 {
343 /* load obj file geometory and diffuse texture */
344 loadDAT( "rom:/resources/robot1.dat", &robot);
345 }
346
UnloadObjects(void)347 static void UnloadObjects(void)
348 {
349 unloadDAT(&robot);
350
351 return;
352 }
353
DrawFrame(void)354 int DrawFrame(void)
355 {
356 static int f = 0;
357
358 nn::math::Matrix44 proj;
359 nn::math::Matrix34 mv, rot;
360
361 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
362 s_RenderSystem.Clear();
363
364 /* setup projection matrix */
365 nn::math::MTX44Frustum(&proj, -0.06f, 0.06f, -0.06f * nn::gx::DISPLAY0_HEIGHT / nn::gx::DISPLAY0_WIDTH,
366 0.06f * nn::gx::DISPLAY0_HEIGHT / nn::gx::DISPLAY0_WIDTH, 0.2f, 200.f);
367 glUniformMatrix4fv(glGetUniformLocation(s_ProgramID, "uProjection"), 1, GL_TRUE, static_cast<f32*>(proj));
368
369 nn::math::Vector3 camPos(0.f, 0.f, 6.f);
370 nn::math::Vector3 camUp(0.f, 1.f, 0.f);
371 nn::math::Vector3 target(0.f, 0.f, 0.f);
372 nn::math::MTX34RotXYZDeg(&rot, 0.f, 0.f, -90.0f);
373 nn::math::MTX34LookAt(&mv, &camPos, &camUp, &target);
374 nn::math::MTX34Mult(&mv, &rot, &mv);
375
376 /* setup light direction */
377 nn::math::Vector4 lpos0(0.f, 1.f, 1.f, 0.f);
378 nn::math::Vector4 mv0(mv.m[0][0], mv.m[0][1], mv.m[0][2], mv.m[0][3]);
379 nn::math::Vector4 mv1(mv.m[1][0], mv.m[1][1], mv.m[1][2], mv.m[1][3]);
380 nn::math::Vector4 mv2(mv.m[2][0], mv.m[2][1], mv.m[2][2], mv.m[2][3]);
381 nn::math::Vector4 lpos(nn::math::VEC4Dot(&mv0, &lpos0), nn::math::VEC4Dot(&mv1, &lpos0), nn::math::VEC4Dot(&mv2, &lpos0), lpos0.w);
382 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].position"), 1, static_cast<f32*>(lpos));
383
384 /* setup modelview matrix */
385 nn::math::MTX34RotXYZDeg(&rot, 0.f, static_cast<f32>(-f), 0.f);
386 nn::math::MTX34Mult(&mv, &mv, &rot);
387 nn::math::Matrix44 m(mv);
388 glUniformMatrix4fv(glGetUniformLocation(s_ProgramID, "uModelView"), 1, GL_TRUE, static_cast<f32*>(m));
389
390 glEnableVertexAttribArray(0);
391 glEnableVertexAttribArray(1);
392
393 /* draw objects */
394 for (int i = 0; i < robot.obj_num; i++)
395 {
396 glBindBuffer(GL_ARRAY_BUFFER, robot.posVB);
397 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)robot.obj[i].vtx_offset);
398 glBindBuffer(GL_ARRAY_BUFFER, robot.normVB);
399 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)robot.obj[i].nrm_offset);
400
401 for (unsigned j = robot.obj[i].patch_offset; j < robot.obj[i].patch_size + robot.obj[i].patch_offset; j++)
402 {
403 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, robot.idxVB);
404 glDrawElements(GL_TRIANGLES, robot.patch[j].elm_size,
405 GL_UNSIGNED_SHORT, (GLvoid*)(robot.patch[j].elm_offset + robot.obj[i].elm_offset));
406 }
407 }
408
409 glFinish();
410
411 s_RenderSystem.SwapBuffers();
412
413 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
414 s_RenderSystem.Clear();
415 s_RenderSystem.SwapBuffers();
416
417 s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
418
419 f++;
420
421 return !glGetError();
422 }
423
424 /* initialization */
Initialize(void)425 static int Initialize(void)
426 {
427 s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize() );
428 s_HeapForGx = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_GxHeapSize));
429 /* Initialize display */
430 s_RenderSystem.Initialize(s_HeapForGx, s_GxHeapSize);
431
432 /* Create heap for malloc*/
433 s_HeapForMalloc = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_HeapSize));
434 setMemoryHeap(s_HeapForMalloc, s_GxHeapSize);
435
436 s_ProgramID = glCreateProgram();
437 s_ShaderID = glCreateShader(GL_VERTEX_SHADER);
438
439 nn::fs::FileReader file(L"rom:/shader.shbin");
440 size_t fileSize = file.GetSize();
441 void* buf = s_AppHeap.Allocate(fileSize);
442
443 s32 read = file.Read(buf, fileSize);
444 glShaderBinary(1, &s_ShaderID, GL_PLATFORM_BINARY_DMP, buf, read);
445 file.Finalize();
446 s_AppHeap.Free(buf);
447
448 glAttachShader(s_ProgramID, s_ShaderID);
449 glAttachShader(s_ProgramID, GL_DMP_FRAGMENT_SHADER_DMP);
450
451 glBindAttribLocation(s_ProgramID, 0, "aPosition");
452 glBindAttribLocation(s_ProgramID, 1, "aNormal");
453
454 glLinkProgram(s_ProgramID);
455 glValidateProgram(s_ProgramID);
456 glUseProgram(s_ProgramID);
457
458 glClearColor(0.36f, 0.42f, 0.5f, 1.0f);
459 glClearDepthf(1.f);
460
461 glEnable(GL_DEPTH_TEST);
462 glDepthFunc(GL_LESS);
463 glEnable(GL_CULL_FACE);
464 glFrontFace(GL_CCW);
465 glCullFace(GL_BACK);
466
467 LoadObjects();
468
469 /* set another render state */
470 (*render_state_func[STATE_SETTINGS])();
471
472 /* enable DMP fragment lighting */
473 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLighting.enabled"), GL_TRUE);
474 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].enabled"), GL_TRUE);
475
476 return 0;
477 }
478
nnMain(void)479 void nnMain(void)
480 {
481 // Call only nn::applet::Enable to also allow execution from the HOME Menu
482 // HOME Menu transitions, POWER Button presses, and sleep are all unsupported
483 nn::applet::Enable();
484
485 // fs initialization
486 nn::fs::Initialize();
487
488 const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
489 static char buffer[ROMFS_BUFFER_SIZE];
490 NN_UTIL_PANIC_IF_FAILED(
491 nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
492
493 /* initialization */
494 if (Initialize() >= 0)
495 {
496 /* Enter loop */
497 while (1)
498 {
499 (void)DrawFrame();
500 }
501 }
502
503 UnloadObjects();
504 /* shutdown_display */
505 s_RenderSystem.Finalize();
506 s_AppHeap.Free(reinterpret_cast<void*>(s_HeapForMalloc));
507 s_AppHeap.Free(reinterpret_cast<void*>(s_HeapForGx));
508 s_AppHeap.Finalize();
509 }
510