1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: gx_RenderToTexture.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 #include <nn/os.h>
17 #include <nn/fnd.h>
18 #include <nn/gx.h>
19 #include <nn/math.h>
20 #include <nn/fs.h>
21 #include <nn/init.h>
22 #include <nn/applet.h>
23
24 #include "demo.h"
25
26 namespace
27 {
28 GLuint s_ProgramId = 0;
29 GLuint s_ShaderId = 0;
30
31 nn::fnd::ExpHeap s_AppHeap;
32 uptr s_AddrForGxHeap;
33 const u32 s_GxHeapSize = 0x400000;
34
35 demo::RenderSystem s_RenderSystem;
36
37 nn::math::Vector3 s_CameraPosition(0.0f, 4.0f, 6.0f);
38 nn::math::Vector3 s_CameraUp(0.0f, 1.0f, 0.0f);
39 nn::math::Vector3 s_CameraTarget(0.0f, 0.0f, 0.0f);
40
41 nn::math::Matrix34 s_ViewMatrix;
42 nn::math::Matrix44 s_Display0ProjectionMatrix;
43 nn::math::Matrix44 s_Display1ProjectionMatrix;
44 nn::math::Matrix44 s_RenderTextureProjectionMatrix;
45
46 const u32 MAX_LIGHT_NUM = 1;
47 f32 s_GlobalAmbientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f};
48 demo::Light s_LightArray[MAX_LIGHT_NUM];
49
50 f32 s_MaterialAmbient[] = {0.2f, 0.2f, 0.2f, 1.0f};
51 f32 s_MaterialDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};
52 f32 s_MaterialSpecular0[] = {1.0f, 1.0f, 1.0f, 1.0f};
53 f32 s_MaterialSpecular1[] = {0.0f, 0.0f, 0.0f, 1.0f};
54
55 demo::Cube s_Cube;
56
57 GLuint s_FrameBufferId = 0;
58 GLuint s_RenderColorTextureId = 0;
59 GLsizei s_RenderTextureWidth = 256;
60 GLsizei s_RenderTextureHeight = 256;
61
62 GLuint s_DepthBufferId = 0;
63
64 const nn::math::Vector3 s_InitialPosition(0.0f, -3.0f, 0.0f);
65 const nn::math::Vector3 s_InitialVelocity(0.0f, 1.0f, 0.0f);
66 const nn::math::Vector3 s_Gravity(0.0f, -0.1f, 0.0f);
67
68 const f32 s_DeltaTime = 0.1f;
69 const u32 MAX_PARTICLE_NUM = 64;
70 demo::Particle s_ParticleArray[MAX_PARTICLE_NUM];
71 }
72
73 void InitializeGraphics(void);
74 void InitializeParticles(void);
75 void InitializeLights(void);
76 void InitializeShader(void);
77 void InitializeRenderTexture(void);
78
79 void Finalize(void);
80
81 void UseShader(void);
82 void UpdateCamera(void);
83 void UpdateLights(void);
84 void UpdateParticles(void);
85
86 void RenderTexture(void);
87 void DrawDisplay0(void);
88 void DrawDisplay1(void);
89
90 void UseShaderParticle(void);
91 void DrawParticles(void);
92
93 void UseShaderTexture(void);
94 void UpdateBody(demo::Body& body);
95 void DrawBody(demo::Body& body);
96
Initialize(void)97 void Initialize(void)
98 {
99 // fs initialization
100 nn::fs::Initialize();
101
102 const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
103 static char buffer[ROMFS_BUFFER_SIZE];
104 NN_UTIL_PANIC_IF_FAILED(
105 nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
106
107 InitializeGraphics();
108 InitializeParticles();
109 }
110
InitializeGraphics(void)111 void InitializeGraphics(void)
112 {
113 s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(),
114 nn::os::GetDeviceMemorySize() );
115 s_AddrForGxHeap = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_GxHeapSize));
116
117 s_RenderSystem.Initialize(s_AddrForGxHeap, s_GxHeapSize);
118
119 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
120 glClearDepthf(1.0f);
121
122 glEnable(GL_DEPTH_TEST);
123 glDepthFunc(GL_LESS);
124
125 glEnable(GL_CULL_FACE);
126 glFrontFace(GL_CCW);
127 glCullFace(GL_BACK);
128
129 InitializeLights();
130 InitializeShader();
131 InitializeRenderTexture();
132
133 // Initialize projection matrix
134 nn::math::MTX44PerspectivePivotDeg(&s_Display0ProjectionMatrix, 45.0f,
135 demo::DISPLAY0_ASPECT, 0.1f, 20.0f,
136 nn::math::PIVOT_UPSIDE_TO_TOP);
137
138 nn::math::MTX44PerspectivePivotDeg(&s_Display1ProjectionMatrix, 45.0f,
139 demo::DISPLAY1_ASPECT, 0.1f, 20.0f,
140 nn::math::PIVOT_UPSIDE_TO_TOP);
141
142 nn::math::MTX44PerspectivePivotDeg(&s_RenderTextureProjectionMatrix, 45.0f,
143 1.0f, 0.1f, 20.0f,
144 nn::math::PIVOT_NONE);
145
146 // Initialize cube
147 u32 vertexAttributes = demo::VERTEX_POSITION_ATTRIBUTE |
148 demo::VERTEX_COLOR_ATTRIBUTE |
149 demo::VERTEX_NORMAL_ATTRIBUTE |
150 demo::VERTEX_TEXCOORD_ATTRIBUTE;
151 s_Cube.InitializeCube(vertexAttributes, 1.6f, 1.6f, 1.6f);
152 s_Cube.SetColor(1.0f, 0.0f, 0.0f);
153 s_Cube.SetWorldPosition(0.0f, 0.0f, 0.0f);
154 s_Cube.SetWorldAngle(0.0f, 0.0f, 0.0f);
155 }
156
InitializeLights(void)157 void InitializeLights(void)
158 {
159 for (u32 lightIndex = 0; lightIndex < MAX_LIGHT_NUM; lightIndex++)
160 {
161 s_LightArray[lightIndex].Initialize();
162 }
163
164 // Light0
165 u32 lightIndex = 0;
166 s_LightArray[lightIndex].m_Ambient[0] = 0.0f;
167 s_LightArray[lightIndex].m_Ambient[1] = 0.0f;
168 s_LightArray[lightIndex].m_Ambient[2] = 0.0f;
169 s_LightArray[lightIndex].m_Ambient[3] = 1.0f;
170 s_LightArray[lightIndex].m_Diffuse[0] = 0.9f;
171 s_LightArray[lightIndex].m_Diffuse[1] = 0.9f;
172 s_LightArray[lightIndex].m_Diffuse[2] = 0.9f;
173 s_LightArray[lightIndex].m_Diffuse[3] = 1.0f;
174 s_LightArray[lightIndex].m_Specular0[0] = 0.0f;
175 s_LightArray[lightIndex].m_Specular0[1] = 0.0f;
176 s_LightArray[lightIndex].m_Specular0[2] = 0.0f;
177 s_LightArray[lightIndex].m_Specular0[3] = 0.0f;
178 }
179
InitializeRenderTexture(void)180 void InitializeRenderTexture(void)
181 {
182 glGenFramebuffers(1, &s_FrameBufferId);
183
184 glGenTextures(1, &s_RenderColorTextureId);
185 glBindTexture(GL_TEXTURE_2D, s_RenderColorTextureId);
186
187 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
188 s_RenderTextureWidth, s_RenderTextureHeight, 0,
189 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
190
191 GLfloat bcolor[] = {0.0f, 1.0f, 0.0f, 1.0f};
192 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bcolor);
193 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
196 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
197
198 glGenRenderbuffers(1, &s_DepthBufferId);
199 glBindRenderbuffer(GL_RENDERBUFFER, s_DepthBufferId);
200 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_EXT,
201 s_RenderTextureWidth, s_RenderTextureHeight);
202
203 glBindFramebuffer(GL_FRAMEBUFFER, s_FrameBufferId);
204 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
205 GL_TEXTURE_2D, s_RenderColorTextureId, 0);
206
207 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
208 GL_RENDERBUFFER, s_DepthBufferId);
209 }
210
InitializeShader(void)211 void InitializeShader(void)
212 {
213 s_ProgramId = glCreateProgram();
214
215 // Load vertex shader
216 s_ShaderId = glCreateShader(GL_VERTEX_SHADER);
217 nn::fs::FileReader file(L"rom:/shader.shbin");
218 size_t fileSize = file.GetSize();
219 void* buf = s_AppHeap.Allocate(fileSize);
220 s32 read = file.Read(buf, fileSize);
221 glShaderBinary(1, &s_ShaderId, GL_PLATFORM_BINARY_DMP, buf, read);
222 file.Finalize();
223 s_AppHeap.Free(buf);
224
225 glAttachShader(s_ProgramId, s_ShaderId);
226 glAttachShader(s_ProgramId, GL_DMP_FRAGMENT_SHADER_DMP);
227
228 glBindAttribLocation(s_ProgramId, 0, "aPosition");
229 glBindAttribLocation(s_ProgramId, 1, "aColor");
230 glBindAttribLocation(s_ProgramId, 2, "aTexcoord");
231 glBindAttribLocation(s_ProgramId, 3, "aNormal");
232
233 glLinkProgram(s_ProgramId);
234 glValidateProgram(s_ProgramId);
235
236 demo::InitializeUniforms(s_ProgramId);
237 }
238
InitializeParticles(void)239 void InitializeParticles(void)
240 {
241 demo::Particle::s_InitialPosition = ::s_InitialPosition;
242 demo::Particle::s_InitialVelocity = ::s_InitialVelocity;
243 demo::Particle::s_Gravity = ::s_Gravity;
244
245 for (u32 particleIndex = 0; particleIndex < MAX_PARTICLE_NUM; particleIndex++)
246 {
247 s_ParticleArray[particleIndex].Initialize();
248 }
249 }
250
Finalize(void)251 void Finalize(void)
252 {
253 s_Cube.Finalize();
254
255 for (u32 particleIndex = 0; particleIndex < MAX_PARTICLE_NUM; particleIndex++)
256 {
257 s_ParticleArray[particleIndex].Finalize();
258 }
259
260 glDeleteTextures(1, &s_RenderColorTextureId);
261 glDeleteRenderbuffers(1, &s_DepthBufferId);
262
263 s_RenderSystem.Finalize();
264
265 s_AppHeap.Free(reinterpret_cast<void*>(s_AddrForGxHeap));
266 s_AppHeap.Finalize();
267 }
268
DrawFrame(void)269 bool DrawFrame(void)
270 {
271 UpdateCamera();
272 UpdateParticles();
273
274 RenderTexture();
275
276 DrawDisplay0();
277 DrawDisplay1();
278
279 s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
280
281 return true;
282 }
283
UpdateCamera(void)284 void UpdateCamera(void)
285 {
286 nn::math::MTX34LookAt(&s_ViewMatrix, s_CameraPosition, s_CameraUp, s_CameraTarget);
287 }
288
UpdateParticles(void)289 void UpdateParticles(void)
290 {
291 for (u32 particleIndex = 0; particleIndex < MAX_PARTICLE_NUM; particleIndex++)
292 {
293 s_ParticleArray[particleIndex].Update(s_DeltaTime);
294 }
295 }
296
RenderTexture(void)297 void RenderTexture(void)
298 {
299 glBindFramebuffer(GL_FRAMEBUFFER, s_FrameBufferId);
300
301 glViewport(0, 0, s_RenderTextureWidth, s_RenderTextureHeight);
302 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
303 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
304
305 UseShaderParticle();
306 glUniformMatrix4fv(demo::s_UniformLocations[demo::VERTEX_UNIFORM_PROJECTION],
307 1, GL_TRUE, static_cast<f32*>(s_RenderTextureProjectionMatrix));
308
309 DrawParticles();
310 }
311
UseShaderParticle(void)312 void UseShaderParticle(void)
313 {
314 glUseProgram(s_ProgramId);
315
316 // Fragment uniform
317 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_ALPHA_TEST], GL_FALSE);
318
319 // Fragment uniform : Texture samplerType
320 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXTURE0_SAMPLER_TYPE], GL_FALSE);
321 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXTURE1_SAMPLER_TYPE], GL_FALSE);
322 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXTURE2_SAMPLER_TYPE], GL_FALSE);
323 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXTURE3_SAMPLER_TYPE], GL_FALSE);
324
325 // Fragment uniform : Fragment lighting
326 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHTING_ENABLED], GL_FALSE);
327
328 // Fragment uniform : Texture combiner
329 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_SRC_RGB],
330 GL_PRIMARY_COLOR, GL_PREVIOUS, GL_PREVIOUS);
331 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_SRC_ALPHA],
332 GL_PRIMARY_COLOR, GL_PREVIOUS, GL_PREVIOUS);
333 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_OPERAND_RGB],
334 GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
335 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_OPERAND_ALPHA],
336 GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
337 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_COMBINE_RGB],
338 GL_REPLACE);
339 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_COMBINE_ALPHA],
340 GL_REPLACE);
341 }
342
DrawDisplay0(void)343 void DrawDisplay0(void)
344 {
345 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
346 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
347 s_RenderSystem.Clear();
348
349 UseShaderTexture();
350 glUniformMatrix4fv(demo::s_UniformLocations[demo::VERTEX_UNIFORM_PROJECTION],
351 1, GL_TRUE, static_cast<f32*>(s_Display0ProjectionMatrix));
352 UpdateBody(s_Cube);
353
354 DrawBody(s_Cube);
355
356 s_RenderSystem.SwapBuffers();
357 }
358
UseShaderTexture(void)359 void UseShaderTexture(void)
360 {
361 glUseProgram(s_ProgramId);
362
363 glActiveTexture(GL_TEXTURE0);
364 glBindTexture(GL_TEXTURE_2D, s_RenderColorTextureId);
365
366 // Fragment uniform
367 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_ALPHA_TEST], GL_FALSE);
368
369 // Fragment uniform : Texture samplerType
370 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXTURE0_SAMPLER_TYPE], GL_TEXTURE_2D);
371 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXTURE1_SAMPLER_TYPE], GL_FALSE);
372 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXTURE2_SAMPLER_TYPE], GL_FALSE);
373 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXTURE3_SAMPLER_TYPE], GL_FALSE);
374
375 // Fragment uniform : Fragment lighting
376 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHTING_ENABLED], GL_TRUE);
377 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHTING_AMBIENT], 1, s_GlobalAmbientLight);
378
379 // Light0
380 u32 lightIndex = 0;
381 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_ENABLED], GL_TRUE);
382 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_AMBIENT], 1, s_LightArray[lightIndex].m_Ambient);
383 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_DIFFUSE], 1, s_LightArray[lightIndex].m_Diffuse);
384 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_SPECULAR0], 1, s_LightArray[lightIndex].m_Specular0);
385 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_SPECULAR1], 1, s_LightArray[lightIndex].m_Specular1);
386
387 // Compute Light0 view matrix
388 nn::math::MTX34 s_LightWorldMatrix;
389 nn::math::MTX34Identity(&s_LightWorldMatrix);
390 nn::math::VEC3 position(0.0f, 10.0f, 10.0f);
391 nn::math::MTX34Translate(&s_LightWorldMatrix, &position);
392 nn::math::Matrix34 lightViewMatrix;
393 nn::math::MTX34Mult(&lightViewMatrix, s_ViewMatrix, s_LightWorldMatrix);
394 glUniform4f(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_POSITION],
395 lightViewMatrix.m[0][3], lightViewMatrix.m[1][3], lightViewMatrix.m[2][3],
396 1.0f);
397
398 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_GEOM_FACTOR1], GL_FALSE);
399 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_GEOM_FACTOR0], GL_FALSE);
400 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_TWO_SIDE_DIFFUSE], GL_FALSE);
401
402 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE1_ENABLED], GL_FALSE);
403 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE2_ENABLED], GL_FALSE);
404 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE3_ENABLED], GL_FALSE);
405
406 // Fragment uniform : Material
407 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_AMBIENT], 1, s_MaterialAmbient);
408 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_DIFFUSE], 1, s_MaterialDiffuse);
409 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_SPECULAR0], 1, s_MaterialSpecular0);
410 glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_SPECULAR1], 1, s_MaterialSpecular1);
411
412 // Fragment uniform : Texture combiner
413 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_SRC_RGB],
414 GL_TEXTURE0, GL_FRAGMENT_PRIMARY_COLOR_DMP, GL_PREVIOUS);
415 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_SRC_ALPHA],
416 GL_TEXTURE0, GL_FRAGMENT_PRIMARY_COLOR_DMP, GL_PREVIOUS);
417
418 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_OPERAND_RGB],
419 GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
420 glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_OPERAND_ALPHA],
421 GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
422 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_COMBINE_RGB],
423 GL_MODULATE);
424 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_COMBINE_ALPHA],
425 GL_MODULATE);
426 }
427
DrawParticles(void)428 void DrawParticles(void)
429 {
430 for (u32 particleIndex = 0; particleIndex < MAX_PARTICLE_NUM; particleIndex++)
431 {
432 DrawBody(s_ParticleArray[particleIndex]);
433 }
434 }
435
DrawDisplay1(void)436 void DrawDisplay1(void)
437 {
438 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
439 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
440 s_RenderSystem.Clear();
441
442 glUniformMatrix4fv(demo::s_UniformLocations[demo::VERTEX_UNIFORM_PROJECTION],
443 1, GL_TRUE, static_cast<f32*>(s_Display1ProjectionMatrix));
444
445 UseShaderParticle();
446 DrawParticles();
447
448 s_RenderSystem.SwapBuffers();
449 }
450
UpdateBody(demo::Body & body)451 void UpdateBody(demo::Body& body)
452 {
453 f32 worldAngle[3];
454 body.GetWorldAngle(worldAngle[0], worldAngle[1], worldAngle[2]);
455 worldAngle[1] += 1.0f;
456 if ( worldAngle[1] > 360.0f )
457 {
458 worldAngle[1] = 0.0f;
459 }
460 body.SetWorldAngle(worldAngle[0], worldAngle[1], worldAngle[2]);
461 }
462
DrawBody(demo::Body & body)463 void DrawBody(demo::Body& body)
464 {
465 nn::math::MTX44 modelViewMatrix(s_ViewMatrix);
466 nn::math::Matrix44 worldMatrix = body.GetWorldMatrix();
467 nn::math::MTX44Mult(&modelViewMatrix, &modelViewMatrix, &worldMatrix);
468 glUniformMatrix4fv(demo::s_UniformLocations[demo::VERTEX_UNIFORM_MODELVIEW],
469 1, GL_TRUE, static_cast<f32*>(modelViewMatrix));
470 body.Draw();
471 }
472
nnMain(void)473 void nnMain(void)
474 {
475 // Call only nn::applet::Enable to also allow execution from the HOME Menu
476 // HOME Menu transitions, POWER Button presses, and sleep are all unsupported
477 nn::applet::Enable();
478
479 Initialize();
480
481 bool flag = true;
482 while ( flag )
483 {
484 flag = DrawFrame();
485 }
486
487 Finalize();
488 }
489