1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: LightingAniso.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 /*
27 * Comments
28 * --------
29 *
30 * Light reflection in this sample consists of two parts - diffuse one
31 * (simulating reflection from inside of cloth) modulated by texture and
32 * anisotropic one (simulating reflection of the air-fiber interface).
33 *
34 * To render anisotropic appearance, we use Schlick's model described in
35 * the following paper
36 *
37 * Christophe Schlick, An Inexpensive BRDF Model for Physically-Based
38 * Rendering, Comput. Graph. Forum 13(3), 233-246 (1994).
39 *
40 * (c) DMP, Inc.
41 * konstantin.kolchin@dmprof.com
42 */
43
44 #include <nn/os.h>
45 #include <nn/gx.h>
46 #include <nn/fs.h>
47 #include <nn/math.h>
48 #include <nn/init.h>
49 #include <nn/os.h>
50 #include <nn/applet.h>
51
52 #include "demo.h"
53
54 #include "Util.h"
55 #include "Loader.h"
56
57 #include <string.h>
58
59 #include "Memory.h"
60
61 /* program id */
62 GLuint s_ProgramID;
63
64 /* shader id */
65 GLuint s_ShaderID;
66
67 /* diffuse texture ID */
68 GLuint s_DiffTexName;
69
70 /* bump texture ID */
71 GLuint s_BumpTexName;
72
73 /* obj file loader class object */
74 dat_t kimono;
75
76 /* texture collection name */
77 GLuint s_TexColl ;
78
79 /* ExpHeap for app. */
80 nn::fnd::ExpHeap s_AppHeap;
81 uptr s_HeapForGx;
82 uptr s_HeapForMalloc;
83 const u32 s_GxHeapSize = 0x400000;
84 const u32 s_HeapSize = 0x200000;
85
86 demo::RenderSystem s_RenderSystem;
87
SetLutTable()88 static void SetLutTable()
89 {
90 /* Schlick suggested that distribution function of anisotropic reflection
91 is composed of two functions, one dependent on dot product NH, and other dependent on
92 dot product of the angle between the projection of H on the tangent plane and the
93 tangent vector. in microfacets theory, distribution function is not
94 depended on wave length(R,G,B) essentially. but, this sample distribution term
95 looked up by NH is depended on wave length. therefore, specular has a little blue. */
96
97 GLuint lutids[5] ;
98
99 glGenTextures(5, lutids);
100
101 GLfloat lut[512];
102 int j;
103 memset(lut, 0, sizeof(lut));
104
105 /* to ignore 1st specular term, set 0. */
106 glBindTexture(GL_LUT_TEXTURE0_DMP, lutids[0]);
107 glTexImage1D(GL_LUT_TEXTURE0_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
108
109 /* set term depended on NH */
110 for (j = 0; j < 256; j++)
111 lut[j] = 0.7f * z_schlick(0.7f, (float)j/256.f, true);
112
113 for (j = 0; j < 255; j++)
114 lut[j + 256] = lut[j+1] - lut[j];
115
116 lut[255 + 256] = 0.7f * z_schlick(0.7f, 1.f, true) - lut[255];
117 glBindTexture(GL_LUT_TEXTURE1_DMP, lutids[1]);
118 glTexImage1D(GL_LUT_TEXTURE1_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
119
120 for (j = 0; j < 256; j++)
121 lut[j] = 0.7f * z_schlick(0.7f, (float)j/256.f, true);
122
123 for (j = 0; j < 255; j++)
124 lut[j + 256] = lut[j+1] - lut[j];
125
126 lut[255 + 256] = 0.7f * z_schlick(0.7f, 1.f, true) - lut[255];
127 glBindTexture(GL_LUT_TEXTURE2_DMP, lutids[2]);
128 glTexImage1D(GL_LUT_TEXTURE2_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
129
130 for (j = 0; j < 256; j++)
131 lut[j] = z_schlick(0.5f, (float)j/256.f, true);
132
133 for (j = 0; j < 255; j++)
134 lut[j + 256] = lut[j+1] - lut[j];
135
136 lut[255 + 256] = z_schlick(0.5f, 1.f, true) - lut[255];
137 glBindTexture(GL_LUT_TEXTURE3_DMP, lutids[3]);
138 glTexImage1D(GL_LUT_TEXTURE3_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
139
140 /* set term dependent on dot product between the projection of H on the tangent plane
141 and the tangent vector */
142 for (j = 0; j < 256; j++)
143 lut[j] = a_schlick(0.015f, (float)j/256.f, true);
144
145 for (j = 0; j < 255; j++)
146 lut[j + 256] = lut[j + 1] - lut[j];
147
148 lut[255 + 256] = a_schlick(0.015f, 1.f, true) - lut[255];
149 glBindTexture(GL_LUT_TEXTURE4_DMP, lutids[4]);
150 glTexImage1D(GL_LUT_TEXTURE4_DMP, 0, GL_LUMINANCEF_DMP, 512, 0, GL_LUMINANCEF_DMP, GL_FLOAT, lut);
151 }
152
153 /* set lighting render state */
SetRenderState(void)154 static void SetRenderState(void)
155 {
156 GLfloat ld0[] = {0.5f,0.5f,0.5f,1.f} ;
157 GLfloat ls0[] = {0.7f,0.7f,0.7f,1.f} ;
158 GLfloat ld1[] = {0.5f,0.5f,0.5f,1.f} ;
159 GLfloat ls1[] = {0.7f,0.7f,0.7f,1.f} ;
160
161 /* all light setting */
162 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLighting.enabled"), GL_TRUE);
163 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].enabled"), GL_TRUE);
164 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[1].enabled"), GL_TRUE);
165 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputD0"), GL_TRUE);
166 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputD1"), GL_TRUE);
167 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputSP"), GL_TRUE);
168 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputFR"), GL_TRUE);
169 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputRB"), GL_TRUE);
170 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputRG"), GL_TRUE);
171 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.absLutInputRR"), GL_TRUE);
172
173 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputD1"), GL_LIGHT_ENV_CP_DMP);
174 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputRB"), GL_LIGHT_ENV_NH_DMP);
175 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputRG"), GL_LIGHT_ENV_NH_DMP);
176 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutInputRR"), GL_LIGHT_ENV_NH_DMP);
177
178 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleD0"), 1.f);
179 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleD1"), 1.f);
180 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleSP"), 1.f);
181 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleFR"), 1.f);
182 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleRB"), 1.f);
183 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleRG"), 1.f);
184 glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutScaleRR"), 1.f);
185
186 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledRefl"), GL_TRUE);
187
188 /* when anisotropic lighting, distribution function is looked up by
189 dot product between projection of half-vector onto tangent plane and
190 tangent vector. HW specification require layer configuration setting7
191 in this case. another layer configuration setting can not be used. */
192 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.config"), GL_LIGHT_ENV_LAYER_CONFIG7_DMP);
193
194 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.bumpMode"), GL_LIGHT_ENV_BUMP_AS_BUMP_DMP);
195 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.bumpSelector"), GL_TEXTURE1);
196
197 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledD0"), GL_TRUE);
198 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.lutEnabledD1"), GL_TRUE);
199
200 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_LightEnv.clampHighlights"), GL_FALSE);
201
202 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].geomFactor0"), GL_FALSE);
203 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].geomFactor1"), GL_FALSE);
204
205 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].twoSideDiffuse"), GL_TRUE);
206
207 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[1].geomFactor0"), GL_FALSE);
208 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[1].geomFactor1"), GL_FALSE);
209
210 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[1].twoSideDiffuse"), GL_TRUE);
211
212 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerD0"), 0);
213 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerRR"), 1);
214 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerRG"), 2);
215 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerRB"), 3);
216 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.samplerD1"), 4);
217
218 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].diffuse"), 1, ld0);
219 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].specular0"), 1, ls0);
220 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].specular1"), 1, ls0);
221
222 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[1].diffuse"), 1, ld1);
223 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[1].specular0"), 1, ls1);
224 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[1].specular1"), 1, ls1);
225
226 /* light position settings */
227
228 nn::math::Matrix34 mv;
229 nn::math::Vector3 camPos(0.f, 0.f, 1.5f);
230 nn::math::Vector3 camUp(0.f, 1.f, 0.f);
231 nn::math::Vector3 target(0.f, 0.f, 0.f);
232
233 nn::math::MTX34LookAt(&mv, &camPos, &camUp, &target);
234
235 nn::math::Vector4 lpos0(-1.f, 0.5f, 1.f, 1.f);
236 nn::math::Vector4 lpos1(1.f, 0.5f,1.f,1.f);
237
238 nn::math::Vector4 mv0(mv.m[0][0], mv.m[0][1], mv.m[0][2], mv.m[0][3]);
239 nn::math::Vector4 mv1(mv.m[1][0], mv.m[1][1], mv.m[1][2], mv.m[1][3]);
240 nn::math::Vector4 mv2(mv.m[2][0], mv.m[2][1], mv.m[2][2], mv.m[2][3]);
241 nn::math::Vector4 lpos(nn::math::VEC4Dot(&mv0, &lpos0), nn::math::VEC4Dot(&mv1, &lpos0), nn::math::VEC4Dot(&mv2, &lpos0), lpos0.w);
242
243 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[0].position"), 1, static_cast<f32*>(lpos));
244
245 lpos = nn::math::Vector4(nn::math::VEC4Dot(&mv0, &lpos1), nn::math::VEC4Dot(&mv1, &lpos1), nn::math::VEC4Dot(&mv2, &lpos1), lpos1.w);
246 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentLightSource[1].position"), 1, static_cast<f32*>(lpos));
247
248 /* set projection matrix */
249 nn::math::Matrix44 proj;
250 nn::math::MTX44Frustum(&proj, -0.01f, 0.01f, -0.01f * nn::gx::DISPLAY0_HEIGHT / nn::gx::DISPLAY0_WIDTH,
251 0.01f * nn::gx::DISPLAY0_HEIGHT / nn::gx::DISPLAY0_WIDTH, 0.2f, 10.f);
252 glUniformMatrix4fv(glGetUniformLocation(s_ProgramID, "uProjection"), 1, GL_TRUE, static_cast<f32*>(proj));
253
254 /* texture and texture environment settings */
255 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_Texture[0].samplerType"), GL_TEXTURE_2D);
256 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_Texture[1].samplerType"), GL_TEXTURE_2D);
257
258 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineRgb"), GL_MULT_ADD_DMP);
259 glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
260 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
261 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
262 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcRgb"), GL_TEXTURE0, GL_FRAGMENT_PRIMARY_COLOR_DMP, GL_FRAGMENT_SECONDARY_COLOR_DMP);
263 glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcAlpha"), GL_CONSTANT, GL_CONSTANT, GL_CONSTANT);
264
265 /* lookup table settings */
266 SetLutTable();
267 }
268
269 /* load objects */
LoadObjects(void)270 static void LoadObjects(void)
271 {
272 bool use_alpha;
273
274 /* load obj file geometry and diffuse texture */
275 loadDAT( "rom:/resources/kimono.dat", &kimono);
276
277 /* load texture */
278 glGenTextures(1, &s_DiffTexName);
279 glActiveTexture(GL_TEXTURE0);
280 /* stored in the texture collection */
281 glBindTexture(GL_TEXTURE_2D, s_DiffTexName);
282 /* limit texture sampling to the top level only */
283 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
284 loadTexture( "rom:/resources/KIMONO01.tga", GL_TEXTURE_2D, 0, use_alpha, true);
285
286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
288
289 /* load bump texture */
290 glGenTextures(1, &s_BumpTexName);
291 glActiveTexture(GL_TEXTURE1) ;
292 /* stored in the texture collection */
293 glBindTexture(GL_TEXTURE_2D, s_BumpTexName);
294 /* limit texture sampling to the top level only */
295 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
296 loadTexture( "rom:/resources/KIMONOB0.tga", GL_TEXTURE_2D, 0, use_alpha, true);
297
298 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
299 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
300
301 /* restore active texture to unit 0 to enable loading of object's diffuse texture */
302 glActiveTexture(GL_TEXTURE0);
303 }
304
UnloadObjects(void)305 static void UnloadObjects(void)
306 {
307 unloadDAT(&kimono);
308
309 return;
310 }
311
DrawFrame(void)312 int DrawFrame(void)
313 {
314 static int f = 0;
315
316 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
317 s_RenderSystem.Clear();
318
319 nn::math::Matrix34 mv, rot;
320 nn::math::Vector3 camPos(0.f, 0.f, 1.5f);
321 nn::math::Vector3 camUp(0.f, 1.f, 0.f);
322 nn::math::Vector3 target(0.f, 0.f, 0.f);
323
324 nn::math::MTX34LookAt(&mv, &camPos, &camUp, &target);
325
326 nn::math::MTX34RotXYZDeg(&rot, 0.f, static_cast<f32>(-f), 0.f);
327 nn::math::MTX34Mult(&mv, &mv, &rot);
328
329 nn::math::Matrix44 tmp(mv);
330 glUniformMatrix4fv(glGetUniformLocation(s_ProgramID, "uModelView"), 1, GL_TRUE, static_cast<f32*>(tmp));
331
332 for (int i = 0; i < kimono.obj_num; i++)
333 {
334 glBindBuffer(GL_ARRAY_BUFFER, kimono.posVB);
335 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)kimono.obj[i].vtx_offset);
336 glBindBuffer(GL_ARRAY_BUFFER, kimono.normVB);
337 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)kimono.obj[i].nrm_offset);
338 if (kimono.obj[i].tex_size)
339 {
340 glBindBuffer(GL_ARRAY_BUFFER, kimono.tangVB);
341 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)kimono.obj[i].tgt_offset);
342 glBindBuffer(GL_ARRAY_BUFFER, kimono.texVB);
343 glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, (void*)kimono.obj[i].tex_offset);
344 glEnableVertexAttribArray(2);
345 glEnableVertexAttribArray(3) ;
346 glUniform1i(glGetUniformLocation(s_ProgramID, "uTangentEnabled"), GL_TRUE);
347 }
348 else
349 {
350 glDisableVertexAttribArray(2);
351 glDisableVertexAttribArray(3);
352 glUniform1i(glGetUniformLocation(s_ProgramID, "uTangentEnabled"), GL_FALSE);
353 }
354
355 for (unsigned j = kimono.obj[i].patch_offset; j < kimono.obj[i].patch_size + kimono.obj[i].patch_offset; j++)
356 {
357 GLfloat ma[4] = {0.f, 0.f, 0.f, 1.f};
358 GLfloat md[4] = {0.f, 0.f, 0.f, 1.f};
359 GLfloat ms[4] = {0.f, 0.f, 0.f, 1.f};
360 for (int col = 0; col < 3; col++)
361 {
362 ma[col] = kimono.patch[j].ambient[col];
363 md[col] = kimono.patch[j].diffuse[col];
364 ms[col] = kimono.patch[j].specular[col];
365 }
366 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.diffuse"), 1, md);
367 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.specular0"), 1, ms);
368 glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_FragmentMaterial.ambient"), 1, ma);
369
370 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, kimono.idxVB);
371 glDrawElements(GL_TRIANGLES, kimono.patch[j].elm_size,
372 GL_UNSIGNED_SHORT, (GLvoid*)(kimono.patch[j].elm_offset + kimono.obj[i].elm_offset));
373 }
374 }
375
376 glFinish();
377
378 s_RenderSystem.SwapBuffers();
379
380 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
381 s_RenderSystem.Clear();
382 s_RenderSystem.SwapBuffers();
383
384 s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
385
386 f++;
387
388 return !glGetError();
389 }
390
391 /* initialization */
Initialize(void)392 static int Initialize(void)
393 {
394 // fs initialization
395 nn::fs::Initialize();
396
397 const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
398 static char buffer[ROMFS_BUFFER_SIZE];
399 NN_UTIL_PANIC_IF_FAILED(
400 nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
401
402 s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize() );
403 s_HeapForGx = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_GxHeapSize));
404 /* Initialize display */
405 s_RenderSystem.Initialize(s_HeapForGx, s_GxHeapSize);
406
407 /* Create heap for malloc*/
408 s_HeapForMalloc = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_HeapSize));
409 setMemoryHeap(s_HeapForMalloc, s_HeapSize);
410
411 glClearColor(0.36f, 0.42f, 0.5f, 1.0f);
412 glClearDepthf(1.f);
413
414 glEnable(GL_DEPTH_TEST);
415 glDepthFunc(GL_LESS);
416
417 glEnable(GL_CULL_FACE);
418 glFrontFace(GL_CCW);
419 glCullFace(GL_BACK);
420
421 /* create program and load & attach vertex shader */
422 s_ProgramID = glCreateProgram();
423 s_ShaderID = glCreateShader(GL_VERTEX_SHADER);
424
425 nn::fs::FileReader file(L"rom:/shader.shbin");
426 size_t fileSize = file.GetSize();
427 void* buf = s_AppHeap.Allocate(fileSize);
428
429 s32 read = file.Read(buf, fileSize);
430 glShaderBinary(1, &s_ShaderID, GL_PLATFORM_BINARY_DMP, buf, read);
431 file.Finalize();
432 s_AppHeap.Free(buf);
433
434 glAttachShader(s_ProgramID, s_ShaderID);
435
436 /* attach fixed-function fragment shader */
437 glAttachShader(s_ProgramID, GL_DMP_FRAGMENT_SHADER_DMP);
438
439 glBindAttribLocation(s_ProgramID, 0, "aPosition");
440 glBindAttribLocation(s_ProgramID, 1, "aNormal");
441 glBindAttribLocation(s_ProgramID, 2, "aTang");
442 glBindAttribLocation(s_ProgramID, 3, "aTexCoord");
443
444 glLinkProgram(s_ProgramID);
445 glValidateProgram(s_ProgramID);
446 /* set program as current one to enable setting its uniforms */
447 glUseProgram(s_ProgramID);
448
449 /* create and bind texture collection object to capture subsequent modifications in the texture state
450 both lookup table-related one and ordinary (2D, cube) textures */
451 glGenTextures(1, &s_TexColl);
452 glBindTexture(GL_TEXTURE_COLLECTION_DMP, s_TexColl);
453
454 LoadObjects();
455
456 /* enable arrays that will be mapped to position and normal */
457 glEnableVertexAttribArray(0);
458 glEnableVertexAttribArray(1);
459
460 return 0;
461 }
462
nnMain(void)463 void nnMain(void)
464 {
465 // Call only nn::applet::Enable to also allow execution from the HOME Menu
466 // HOME Menu transitions, POWER Button presses, and sleep are all unsupported
467 nn::applet::Enable();
468
469 /* initialization */
470 if (Initialize() >= 0)
471 {
472 /* set another render state */
473 SetRenderState();
474
475 /* Enter loop */
476 while (1)
477 {
478 (void)DrawFrame();
479 }
480 }
481
482 UnloadObjects();
483 /* shutdown_display */
484 s_RenderSystem.Finalize();
485 s_AppHeap.Free(reinterpret_cast<void*>(s_HeapForMalloc));
486 s_AppHeap.Free(reinterpret_cast<void*>(s_HeapForGx));
487 s_AppHeap.Finalize();
488 }
489
490