1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: gx_FragmentLightingSimple.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 #include <nn/os.h>
18 #include <nn/fnd.h>
19 #include <nn/gx.h>
20 #include <nn/math.h>
21 #include <nn/fs.h>
22 #include <nn/init.h>
23 #include <nn/applet.h>
24
25 #include "demo.h"
26
27 namespace
28 {
29 GLuint s_ProgramId = 0;
30 GLuint s_ShaderId = 0;
31
32 nn::fnd::ExpHeap s_AppHeap;
33 uptr s_AddrForGxHeap;
34 const u32 s_GxHeapSize = 0x400000;
35
36 demo::RenderSystem s_RenderSystem;
37
38 nn::math::Vector3 s_CameraPosition(0.0f, 4.0f, 6.0f);
39 nn::math::Vector3 s_CameraUp(0.0f, 1.0f, 0.0f);
40 nn::math::Vector3 s_CameraTarget(0.0f, 0.0f, 0.0f);
41
42 nn::math::Matrix34 s_ViewMatrix;
43 nn::math::Matrix44 s_Display0ProjectionMatrix;
44 nn::math::Matrix44 s_Display1ProjectionMatrix;
45
46 const u32 MAX_LIGHT_NUM = 4;
47 f32 s_GlobalAmbientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f};
48
49 demo::Light s_LightArray[MAX_LIGHT_NUM];
50
51 f32 s_LightPhi[MAX_LIGHT_NUM];
52 f32 s_LightRadius = 3.0f;
53 f32 s_LightDeltaPhi = 1.0f;
54
55 f32 s_MaterialAmbient[] = {0.2f, 0.2f, 0.2f, 1.0f};
56 f32 s_MaterialDiffuse[] = {0.6f, 0.6f, 0.6f, 1.0f};
57 f32 s_MaterialSpecular0[] = {1.0f, 1.0f, 1.0f, 1.0f};
58 f32 s_MaterialSpecular1[] = {0.0f, 0.0f, 0.0f, 1.0f};
59 u32 s_MaterialShininess = 8;
60
61 demo::Cube s_Cube;
62
63 const u32 MAX_SPHERE_NUM = MAX_LIGHT_NUM;
64 demo::Sphere s_LightSphereArray[MAX_SPHERE_NUM];
65
66 GLuint s_D0LutTextureId = 0;
67 }
68
69 void InitializeGraphics(void);
70 void InitializeLights(void);
71 void InitializeShader(void);
72 void InitializeD0Lut(const u32& materialShininess);
73
74 void UseShader(void);
75 void UpdateCamera(void);
76 void UpdateLights(void);
77
78 void DrawDisplay0(void);
79 void DrawDisplay1(void);
80
81 void UseShader(void);
82 void UpdateBody(demo::Body& body);
83 void DrawBody(demo::Body& body);
84
85 void SetLightUniform(void);
86 void DrawLights(void);
87
Initialize(void)88 void Initialize(void)
89 {
90 // fs initialization
91 nn::fs::Initialize();
92
93 const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
94 static char buffer[ROMFS_BUFFER_SIZE];
95 NN_UTIL_PANIC_IF_FAILED(
96 nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
97
98 InitializeGraphics();
99 }
100
InitializeGraphics(void)101 void InitializeGraphics(void)
102 {
103 s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(),
104 nn::os::GetDeviceMemorySize() );
105 s_AddrForGxHeap = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_GxHeapSize));
106
107 s_RenderSystem.Initialize(s_AddrForGxHeap, s_GxHeapSize);
108
109 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
110 glClearDepthf(1.0f);
111
112 glEnable(GL_DEPTH_TEST);
113 glDepthFunc(GL_LESS);
114
115 glEnable(GL_CULL_FACE);
116 glFrontFace(GL_CCW);
117 glCullFace(GL_BACK);
118
119 InitializeLights();
120
121 InitializeShader();
122
123 // Initialize projection matrix
124 nn::math::MTX44PerspectivePivotDeg(&s_Display0ProjectionMatrix, 45.0f,
125 demo::DISPLAY0_ASPECT, 0.1f, 20.0f,
126 nn::math::PIVOT_UPSIDE_TO_TOP);
127
128 nn::math::MTX44PerspectivePivotDeg(&s_Display1ProjectionMatrix, 45.0f,
129 demo::DISPLAY1_ASPECT, 0.1f, 20.0f,
130 nn::math::PIVOT_UPSIDE_TO_TOP);
131
132 // Initialize cube
133 u32 vertexAttributes = demo::VERTEX_POSITION_ATTRIBUTE |
134 demo::VERTEX_COLOR_ATTRIBUTE |
135 demo::VERTEX_NORMAL_ATTRIBUTE;
136 s_Cube.InitializeCube(vertexAttributes, 1.5f, 1.5f, 1.5f);
137 s_Cube.SetColor(1.0f, 0.0f, 0.0f);
138 s_Cube.SetWorldPosition(0.0f, 0.0f, 0.0f);
139 s_Cube.SetWorldAngle(0.0f, 0.0f, 0.0f);
140
141 // Initialize sphere
142 for (u32 sphereIndex = 0; sphereIndex < MAX_SPHERE_NUM; sphereIndex++)
143 {
144 s_LightSphereArray[sphereIndex].InitializeSphere(vertexAttributes, 0.2, 4);
145 s_LightSphereArray[sphereIndex].SetWorldPosition(0.0f, 0.0f, 0.0f);
146 s_LightSphereArray[sphereIndex].SetWorldAngle(0.0f, 0.0f, 0.0f);
147 }
148
149 u32 sphereIndex = 0;
150 s_LightSphereArray[sphereIndex].SetColor(1.0f, 0.0f, 0.0f);
151
152 sphereIndex = 1;
153 s_LightSphereArray[sphereIndex].SetColor(0.0f, 1.0f, 0.0f);
154
155 sphereIndex = 2;
156 s_LightSphereArray[sphereIndex].SetColor(0.0f, 0.0f, 1.0f);
157
158 sphereIndex = 3;
159 s_LightSphereArray[sphereIndex].SetColor(1.0f, 1.0f, 0.0f);
160 }
161
InitializeLights(void)162 void InitializeLights(void)
163 {
164 for (u32 lightIndex = 0; lightIndex < MAX_LIGHT_NUM; lightIndex++)
165 {
166 s_LightArray[lightIndex].Initialize();
167 }
168
169 s_LightPhi[0] = 0.0f;
170 s_LightPhi[1] = 180.0f;
171 s_LightPhi[2] = 270.0f;
172 s_LightPhi[3] = 0.0f;
173
174 // Light0 (Red)
175 u32 lightIndex = 0;
176 s_LightArray[lightIndex].m_Ambient[0] = 0.0f;
177 s_LightArray[lightIndex].m_Ambient[1] = 0.0f;
178 s_LightArray[lightIndex].m_Ambient[2] = 0.0f;
179 s_LightArray[lightIndex].m_Ambient[3] = 1.0f;
180 s_LightArray[lightIndex].m_Diffuse[0] = 1.0f;
181 s_LightArray[lightIndex].m_Diffuse[1] = 0.0f;
182 s_LightArray[lightIndex].m_Diffuse[2] = 0.0f;
183 s_LightArray[lightIndex].m_Diffuse[3] = 1.0f;
184 s_LightArray[lightIndex].m_Specular0[0] = 1.0f;
185 s_LightArray[lightIndex].m_Specular0[1] = 1.0f;
186 s_LightArray[lightIndex].m_Specular0[2] = 1.0f;
187 s_LightArray[lightIndex].m_Specular0[3] = 1.0f;
188
189 // Light1 (Green)
190 lightIndex = 1;
191 s_LightArray[lightIndex].m_Ambient[0] = 0.0f;
192 s_LightArray[lightIndex].m_Ambient[1] = 0.0f;
193 s_LightArray[lightIndex].m_Ambient[2] = 0.0f;
194 s_LightArray[lightIndex].m_Ambient[3] = 1.0f;
195 s_LightArray[lightIndex].m_Diffuse[0] = 0.0f;
196 s_LightArray[lightIndex].m_Diffuse[1] = 1.0f;
197 s_LightArray[lightIndex].m_Diffuse[2] = 0.0f;
198 s_LightArray[lightIndex].m_Diffuse[3] = 1.0f;
199 s_LightArray[lightIndex].m_Specular0[0] = 1.0f;
200 s_LightArray[lightIndex].m_Specular0[1] = 1.0f;
201 s_LightArray[lightIndex].m_Specular0[2] = 1.0f;
202 s_LightArray[lightIndex].m_Specular0[3] = 1.0f;
203
204 // Light2 (Blue)
205 lightIndex = 2;
206 s_LightArray[lightIndex].m_Ambient[0] = 0.0f;
207 s_LightArray[lightIndex].m_Ambient[1] = 0.0f;
208 s_LightArray[lightIndex].m_Ambient[2] = 0.0f;
209 s_LightArray[lightIndex].m_Ambient[3] = 1.0f;
210 s_LightArray[lightIndex].m_Diffuse[0] = 0.0f;
211 s_LightArray[lightIndex].m_Diffuse[1] = 0.0f;
212 s_LightArray[lightIndex].m_Diffuse[2] = 1.0f;
213 s_LightArray[lightIndex].m_Diffuse[3] = 1.0f;
214 s_LightArray[lightIndex].m_Specular0[0] = 1.0f;
215 s_LightArray[lightIndex].m_Specular0[1] = 1.0f;
216 s_LightArray[lightIndex].m_Specular0[2] = 1.0f;
217 s_LightArray[lightIndex].m_Specular0[3] = 1.0f;
218
219 // Light3 (Yellow)
220 lightIndex = 3;
221 s_LightArray[lightIndex].m_Ambient[0] = 0.0f;
222 s_LightArray[lightIndex].m_Ambient[1] = 0.0f;
223 s_LightArray[lightIndex].m_Ambient[2] = 0.0f;
224 s_LightArray[lightIndex].m_Ambient[3] = 1.0f;
225 s_LightArray[lightIndex].m_Diffuse[0] = 1.0f;
226 s_LightArray[lightIndex].m_Diffuse[1] = 1.0f;
227 s_LightArray[lightIndex].m_Diffuse[2] = 0.0f;
228 s_LightArray[lightIndex].m_Diffuse[3] = 1.0f;
229 s_LightArray[lightIndex].m_Specular0[0] = 1.0f;
230 s_LightArray[lightIndex].m_Specular0[1] = 1.0f;
231 s_LightArray[lightIndex].m_Specular0[2] = 1.0f;
232 s_LightArray[lightIndex].m_Specular0[3] = 1.0f;
233 }
234
InitializeShader(void)235 void InitializeShader(void)
236 {
237 s_ProgramId = glCreateProgram();
238
239 // Load vertex shader
240 s_ShaderId = glCreateShader(GL_VERTEX_SHADER);
241 nn::fs::FileReader file(L"rom:/shader.shbin");
242 size_t fileSize = file.GetSize();
243 void* buf = s_AppHeap.Allocate(fileSize);
244 s32 read = file.Read(buf, fileSize);
245 glShaderBinary(1, &s_ShaderId, GL_PLATFORM_BINARY_DMP, buf, read);
246 file.Finalize();
247 s_AppHeap.Free(buf);
248
249 glAttachShader(s_ProgramId, s_ShaderId);
250 glAttachShader(s_ProgramId, GL_DMP_FRAGMENT_SHADER_DMP);
251
252 glBindAttribLocation(s_ProgramId, 0, "aPosition");
253 glBindAttribLocation(s_ProgramId, 1, "aColor");
254 glBindAttribLocation(s_ProgramId, 2, "aNormal");
255
256 glLinkProgram(s_ProgramId);
257 glValidateProgram(s_ProgramId);
258
259 demo::InitializeUniforms(s_ProgramId);
260
261 InitializeD0Lut(s_MaterialShininess);
262 }
263
InitializeD0Lut(const u32 & materialShininess)264 void InitializeD0Lut(const u32& materialShininess)
265 {
266 const u32 LUT_TABLE_SIZE = 512;
267 const u32 LUT_TABLE_HALF_SIZE = LUT_TABLE_SIZE / 2;
268 GLfloat lutArray[LUT_TABLE_SIZE];
269 for (u32 index = 0; index < LUT_TABLE_SIZE; index++)
270 {
271 lutArray[index] = 0.0f;
272 }
273
274 for (u32 j = 0; j < LUT_TABLE_HALF_SIZE; j++)
275 {
276 f32 value = 1.0f;
277 for (u32 count = 0; count < materialShininess; count++)
278 {
279 value *= (j / 255.0f);
280 }
281 lutArray[j] = value;
282 }
283
284 for (u32 j = 0; j < (LUT_TABLE_HALF_SIZE - 1); j++)
285 {
286 lutArray[j + LUT_TABLE_HALF_SIZE] = lutArray[j + 1] - lutArray[j];
287 }
288 lutArray[(LUT_TABLE_HALF_SIZE - 1) + LUT_TABLE_HALF_SIZE] =
289 1.0f - lutArray[LUT_TABLE_HALF_SIZE - 1];
290
291 glGenTextures(1, &s_D0LutTextureId);
292 glBindTexture(GL_LUT_TEXTURE0_DMP, s_D0LutTextureId);
293 glTexImage1D(GL_LUT_TEXTURE0_DMP, 0, GL_LUMINANCEF_DMP, LUT_TABLE_SIZE,
294 0, GL_LUMINANCEF_DMP, GL_FLOAT, lutArray);
295 }
296
Finalize(void)297 void Finalize(void)
298 {
299 s_Cube.Finalize();
300 for (u32 sphereIndex = 0; sphereIndex < MAX_SPHERE_NUM; sphereIndex++)
301 {
302 s_LightSphereArray[sphereIndex].Finalize();
303 }
304
305 glDeleteTextures(1, &s_D0LutTextureId);
306
307 s_RenderSystem.Finalize();
308
309 s_AppHeap.Free(reinterpret_cast<void*>(s_AddrForGxHeap));
310 s_AppHeap.Finalize();
311 }
312
DrawFrame(void)313 bool DrawFrame(void)
314 {
315 UpdateCamera();
316 UpdateLights();
317
318 DrawDisplay0();
319 DrawDisplay1();
320
321 s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
322
323 return true;
324 }
325
UpdateCamera(void)326 void UpdateCamera(void)
327 {
328 nn::math::MTX34LookAt(&s_ViewMatrix, s_CameraPosition, s_CameraUp, s_CameraTarget);
329 }
330
UpdateLights(void)331 void UpdateLights(void)
332 {
333 // Light0 (Red)
334 u32 lightIndex = 0;
335 f32 sinPhi = 0.0f;
336 f32 cosPhi = 0.0f;
337 nn::math::SinCosDeg(&sinPhi, &cosPhi, s_LightPhi[0]);
338 s_LightArray[lightIndex].m_Position[0] = 0.0f;
339 s_LightArray[lightIndex].m_Position[1] = s_LightRadius * cosPhi;
340 s_LightArray[lightIndex].m_Position[2] = s_LightRadius * sinPhi;
341
342 // Light1 (Green)
343 lightIndex = 1;
344 nn::math::SinCosDeg(&sinPhi, &cosPhi, s_LightPhi[1]);
345 s_LightArray[lightIndex].m_Position[0] = s_LightRadius * cosPhi;
346 s_LightArray[lightIndex].m_Position[1] = 0.0f;
347 s_LightArray[lightIndex].m_Position[2] = s_LightRadius * sinPhi;
348
349 // Light2 (Blue)
350 lightIndex = 2;
351 nn::math::SinCosDeg(&sinPhi, &cosPhi, s_LightPhi[2]);
352 s_LightArray[lightIndex].m_Position[0] = s_LightRadius * cosPhi;
353 s_LightArray[lightIndex].m_Position[1] = s_LightRadius * sinPhi;
354 s_LightArray[lightIndex].m_Position[2] = 0.0f;
355
356 // Light3 (Yellow)
357 lightIndex = 3;
358 nn::math::SinCosDeg(&sinPhi, &cosPhi, s_LightPhi[3]);
359 s_LightArray[lightIndex].m_Position[0] = s_LightRadius * cosPhi;
360 s_LightArray[lightIndex].m_Position[1] = 0.0f;
361 s_LightArray[lightIndex].m_Position[2] = s_LightRadius * sinPhi;
362
363 for (u32 index = 0; index < MAX_LIGHT_NUM; index++)
364 {
365 s_LightSphereArray[index].SetWorldPosition(s_LightArray[index].m_Position[0],
366 s_LightArray[index].m_Position[1], s_LightArray[index].m_Position[2]);
367
368 s_LightPhi[index] += s_LightDeltaPhi;
369 if ( s_LightPhi[index] > 360.0f )
370 {
371 s_LightPhi[index] -= 360.0f;
372 }
373 }
374 }
375
DrawDisplay0(void)376 void DrawDisplay0(void)
377 {
378 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
379 s_RenderSystem.Clear();
380
381 UseShader();
382 glUniformMatrix4fv(demo::s_UniformLocations[demo::VERTEX_UNIFORM_PROJECTION],
383 1, GL_TRUE, static_cast<f32*>(s_Display0ProjectionMatrix));
384 UpdateBody(s_Cube);
385 DrawBody(s_Cube);
386
387 SetLightUniform();
388 DrawLights();
389
390 s_RenderSystem.SwapBuffers();
391 }
392
UseShader(void)393 void UseShader(void)
394 {
395 glUseProgram(s_ProgramId);
396
397 // Fragment uniform
398 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_ALPHA_TEST], GL_FALSE);
399
400 // Fragment uniform : Texture samplerType
401 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXTURE0_SAMPLER_TYPE], GL_FALSE);
402 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXTURE1_SAMPLER_TYPE], GL_FALSE);
403 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXTURE2_SAMPLER_TYPE], GL_FALSE);
404 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXTURE3_SAMPLER_TYPE], GL_FALSE);
405
406 // LightEnv
407 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_LIGHT_ENV_CONFIG], GL_LIGHT_ENV_LAYER_CONFIG0_DMP);
408 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_LIGHT_ENV_LUT_ENABLED_REFL], GL_FALSE);
409 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_LIGHT_ENV_CLAMP_HIGHLIGHTS], GL_TRUE);
410
411 // D0
412 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_LIGHT_ENV_LUT_ENABLED_D0], GL_TRUE);
413 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_LIGHT_ENV_ABS_LUT_INPUT_D0], GL_TRUE);
414 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_LIGHT_ENV_LUT_INPUT_D0], GL_LIGHT_ENV_NH_DMP);
415 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_SAMPLER_D0], 0);
416
417 // Fragment uniform : Fragment lighting
418 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHTING_ENABLED], GL_TRUE);
419 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHTING_AMBIENT], 1, s_GlobalAmbientLight);
420
421 // Light0 (Red)
422 u32 lightIndex = 0;
423 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_ENABLED], GL_TRUE);
424 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_AMBIENT], 1, s_LightArray[lightIndex].m_Ambient);
425 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_DIFFUSE], 1, s_LightArray[lightIndex].m_Diffuse);
426 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_SPECULAR0], 1, s_LightArray[lightIndex].m_Specular0);
427 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_SPECULAR1], 1, s_LightArray[lightIndex].m_Specular1);
428 // Compute Light0 view matrix
429 nn::math::MTX34 s_LightWorldMatrix;
430 nn::math::MTX34Identity(&s_LightWorldMatrix);
431 nn::math::VEC3 position(s_LightArray[lightIndex].m_Position[0], s_LightArray[lightIndex].m_Position[1], s_LightArray[lightIndex].m_Position[2]);
432 nn::math::MTX34Translate(&s_LightWorldMatrix, &position);
433 nn::math::Matrix34 lightViewMatrix;
434 nn::math::MTX34Mult(&lightViewMatrix, s_ViewMatrix, s_LightWorldMatrix);
435 glUniform4f(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_POSITION],
436 lightViewMatrix.m[0][3], lightViewMatrix.m[1][3], lightViewMatrix.m[2][3],
437 1.0f);
438 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_GEOM_FACTOR1], GL_FALSE);
439 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_GEOM_FACTOR0], GL_FALSE);
440 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_TWO_SIDE_DIFFUSE], GL_FALSE);
441
442 // Light1 (Green)
443 lightIndex = 1;
444 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE1_ENABLED], GL_TRUE);
445 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE1_AMBIENT], 1, s_LightArray[lightIndex].m_Ambient);
446 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE1_DIFFUSE], 1, s_LightArray[lightIndex].m_Diffuse);
447 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE1_SPECULAR0], 1, s_LightArray[lightIndex].m_Specular0);
448 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE1_SPECULAR1], 1, s_LightArray[lightIndex].m_Specular1);
449 // Compute Light1 view matrix
450 nn::math::MTX34Identity(&s_LightWorldMatrix);
451 position.x = s_LightArray[lightIndex].m_Position[0];
452 position.y = s_LightArray[lightIndex].m_Position[1];
453 position.z = s_LightArray[lightIndex].m_Position[2];
454 nn::math::MTX34Translate(&s_LightWorldMatrix, &position);
455 nn::math::MTX34Mult(&lightViewMatrix, s_ViewMatrix, s_LightWorldMatrix);
456 glUniform4f(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE1_POSITION],
457 lightViewMatrix.m[0][3], lightViewMatrix.m[1][3], lightViewMatrix.m[2][3],
458 1.0f);
459 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE1_GEOM_FACTOR1], GL_FALSE);
460 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE1_GEOM_FACTOR0], GL_FALSE);
461 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE1_TWO_SIDE_DIFFUSE], GL_FALSE);
462
463 // Light2 (Blue)
464 lightIndex = 2;
465 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE2_ENABLED], GL_TRUE);
466 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE2_AMBIENT], 1, s_LightArray[lightIndex].m_Ambient);
467 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE2_DIFFUSE], 1, s_LightArray[lightIndex].m_Diffuse);
468 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE2_SPECULAR0], 1, s_LightArray[lightIndex].m_Specular0);
469 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE2_SPECULAR1], 1, s_LightArray[lightIndex].m_Specular1);
470 // Compute Light2 view matrix
471 nn::math::MTX34Identity(&s_LightWorldMatrix);
472 position.x = s_LightArray[lightIndex].m_Position[0];
473 position.y = s_LightArray[lightIndex].m_Position[1];
474 position.z = s_LightArray[lightIndex].m_Position[2];
475 nn::math::MTX34Translate(&s_LightWorldMatrix, &position);
476 nn::math::MTX34Mult(&lightViewMatrix, s_ViewMatrix, s_LightWorldMatrix);
477 glUniform4f(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE2_POSITION],
478 lightViewMatrix.m[0][3], lightViewMatrix.m[1][3], lightViewMatrix.m[2][3],
479 1.0f);
480 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE2_GEOM_FACTOR1], GL_FALSE);
481 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE2_GEOM_FACTOR0], GL_FALSE);
482 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE2_TWO_SIDE_DIFFUSE], GL_FALSE);
483
484 // Light3 (Yellow)
485 lightIndex = 3;
486 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE3_ENABLED], GL_TRUE);
487 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE3_AMBIENT], 1, s_LightArray[lightIndex].m_Ambient);
488 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE3_DIFFUSE], 1, s_LightArray[lightIndex].m_Diffuse);
489 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE3_SPECULAR0], 1, s_LightArray[lightIndex].m_Specular0);
490 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE3_SPECULAR1], 1, s_LightArray[lightIndex].m_Specular1);
491 // Compute Light3 view matrix
492 nn::math::MTX34Identity(&s_LightWorldMatrix);
493 position.x = s_LightArray[lightIndex].m_Position[0];
494 position.y = s_LightArray[lightIndex].m_Position[1];
495 position.z = s_LightArray[lightIndex].m_Position[2];
496 nn::math::MTX34Translate(&s_LightWorldMatrix, &position);
497 nn::math::MTX34Mult(&lightViewMatrix, s_ViewMatrix, s_LightWorldMatrix);
498 glUniform4f(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE3_POSITION],
499 lightViewMatrix.m[0][3], lightViewMatrix.m[1][3], lightViewMatrix.m[2][3],
500 1.0f);
501 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE3_GEOM_FACTOR1], GL_FALSE);
502 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE3_GEOM_FACTOR0], GL_FALSE);
503 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE3_TWO_SIDE_DIFFUSE], GL_FALSE);
504
505 // Fragment uniform : Material
506 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_AMBIENT], 1, s_MaterialAmbient);
507 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_DIFFUSE], 1, s_MaterialDiffuse);
508 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_SPECULAR0], 1, s_MaterialSpecular0);
509 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_SPECULAR1], 1, s_MaterialSpecular1);
510
511 // Fragment uniform : Texture combiner
512 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_SRC_RGB],
513 GL_FRAGMENT_PRIMARY_COLOR_DMP, GL_FRAGMENT_SECONDARY_COLOR_DMP, GL_PREVIOUS);
514 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_SRC_ALPHA],
515 GL_FRAGMENT_PRIMARY_COLOR_DMP, GL_FRAGMENT_SECONDARY_COLOR_DMP, GL_PREVIOUS);
516
517 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_OPERAND_RGB],
518 GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
519 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_OPERAND_ALPHA],
520 GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
521 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_COMBINE_RGB],
522 GL_ADD);
523 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_COMBINE_ALPHA],
524 GL_ADD);
525 }
526
DrawDisplay1(void)527 void DrawDisplay1(void)
528 {
529 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
530 s_RenderSystem.Clear();
531
532 s_RenderSystem.SwapBuffers();
533 }
534
UpdateBody(demo::Body & body)535 void UpdateBody(demo::Body& body)
536 {
537 f32 worldAngle[3];
538 body.GetWorldAngle(worldAngle[0], worldAngle[1], worldAngle[2]);
539 worldAngle[1] += 1.0f;
540 if ( worldAngle[1] > 360.0f )
541 {
542 worldAngle[1] = 0.0f;
543 }
544 body.SetWorldAngle(worldAngle[0], worldAngle[1], worldAngle[2]);
545 }
546
DrawBody(demo::Body & body)547 void DrawBody(demo::Body& body)
548 {
549 nn::math::MTX44 modelViewMatrix(s_ViewMatrix);
550 nn::math::Matrix44 worldMatrix = body.GetWorldMatrix();
551 nn::math::MTX44Mult(&modelViewMatrix, &modelViewMatrix, &worldMatrix);
552 glUniformMatrix4fv(demo::s_UniformLocations[demo::VERTEX_UNIFORM_MODELVIEW],
553 1, GL_TRUE, static_cast<f32*>(modelViewMatrix));
554 body.Draw();
555 }
556
SetLightUniform(void)557 void SetLightUniform(void)
558 {
559 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHTING_ENABLED], GL_FALSE);
560
561 // Fragment uniform : Texture combiner
562 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_SRC_RGB],
563 GL_PRIMARY_COLOR, GL_PRIMARY_COLOR, GL_PREVIOUS);
564 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_SRC_ALPHA],
565 GL_PRIMARY_COLOR, GL_PRIMARY_COLOR, GL_PREVIOUS);
566 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_OPERAND_RGB],
567 GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
568 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_OPERAND_ALPHA],
569 GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
570 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_COMBINE_RGB],
571 GL_REPLACE);
572 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_COMBINE_ALPHA],
573 GL_REPLACE);
574 }
575
DrawLights(void)576 void DrawLights(void)
577 {
578 for (u32 lightIndex = 0; lightIndex < MAX_LIGHT_NUM; lightIndex++)
579 {
580 DrawBody(s_LightSphereArray[lightIndex]);
581 }
582 }
583
nnMain(void)584 void nnMain(void)
585 {
586 // Call only nn::applet::Enable to also allow execution from the HOME Menu
587 // HOME Menu transitions, POWER Button presses, and sleep are all unsupported
588 nn::applet::Enable();
589
590 Initialize();
591
592 bool flag = true;
593 while ( flag )
594 {
595 flag = DrawFrame();
596 }
597
598 Finalize();
599 }
600