1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: GasColorSimple.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 "Util.h"
33 #include "Loader.h"
34 #include "Gas.h"
35
36 #include "Memory.h"
37
38 #include "demo.h"
39
40 /* program id */
41 GLuint pAccId;
42 GLuint pPostId;
43
44 /* shader id */
45 GLuint s_Shaders[2];
46
47 /* Standard object (triangles, not gaseous object) */
48 struct gas_data gas;
49 dat_t plane;
50
51 /* ExpHeap for app. */
52 nn::fnd::ExpHeap s_AppHeap;
53 uptr s_HeapForGx;
54 uptr s_HeapForMalloc;
55 const u32 s_GxHeapSize = 0x400000;
56 const u32 s_HeapSize = 0x200000;
57
58 demo::RenderSystem s_RenderSystem;
59
60 /*=======================================================*/
61 /* Static function declaration */
62 /*=======================================================*/
63 static int DrawFrame(void);
64
65 /*=======================================================*/
66 /* initialization */
67 /*=======================================================*/
68
Initialize(void)69 static void Initialize(void)
70 {
71 s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize() );
72 s_HeapForGx = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_GxHeapSize));
73 /* Initialize display */
74 s_RenderSystem.Initialize(s_HeapForGx, s_GxHeapSize);
75
76 /* Create heap for malloc*/
77 s_HeapForMalloc = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_HeapSize));
78 setMemoryHeap(s_HeapForMalloc, s_HeapSize);
79
80 /* Initialization for gas */
81 GLuint depthStencilBufferId = s_RenderSystem.GetRenderBufferObjectId(NN_GX_DISPLAY0, GL_DEPTH_STENCIL_ATTACHMENT);
82 GasInitialize(depthStencilBufferId);
83 }
84
SceneObjectInitialize(void)85 static void SceneObjectInitialize(void)
86 {
87 /* Load object (non-gaseous object) */
88 loadDAT( "rom:/resources/planeXY3.dat", &plane);
89
90 /* Load Gaseous object */
91 float tr_flame[24] =
92 {
93 0.0f, 0.00f, 0.0f, /* 0 */
94 0.2f, 0.15f, 0.05f, /* 1 */
95 0.6f, 0.25f, 0.15f, /* 2 */
96 0.9f, 0.35f, 0.2f, /* 3 */
97 0.92f, 0.6f, 0.15f, /* 4 */
98 0.95f, 0.85f, 0.05f, /* 5 */
99 1.0f, 0.95f, 0.0f, /* 6 */
100 1.0f, 1.0f, 1.0f /* 7 */
101 };
102 DefaultGasObject(&gas, tr_flame);
103
104 /* Define the gaseous object geometry */
105 /* A simple quad in this sample */
106 float cx = 0.0;
107 float cy = 0.0;
108 float rd = 8.0;
109 float _vertex[16]=
110 {
111 cx - rd, cy - rd, 0.0f, 1.0f,
112 cx - rd, cy + rd, 0.0f, 1.0f,
113 cx + rd, cy + rd, 0.0f, 1.0f,
114 cx + rd, cy - rd, 0.0f, 1.0f
115 };
116
117 float density = 1.0;
118 float _color[4]= {density, density, density, density };
119
120 float t0 = 0.0f, t1 = 1.0f;
121 float _texture[8]=
122 {
123 t0, t0,
124 t1, t0,
125 t1, t1,
126 t0, t1
127 };
128
129 glGenBuffers(1, &gas.gasgeo_center_ID);
130 glGenBuffers(1, &gas.gasgeo_density_ID);
131 glGenBuffers(1, &gas.gasgeo_tx0_ID);
132 glGenBuffers(1, &gas.gasgeo_tri_ID);
133
134 glBindBuffer(GL_ARRAY_BUFFER, gas.gasgeo_center_ID);
135 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 16, &_vertex[0], GL_STATIC_DRAW);
136 gas.gasgeo_size = 6;
137
138 glBindBuffer(GL_ARRAY_BUFFER, gas.gasgeo_tx0_ID);
139 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, &_texture[0], GL_STATIC_DRAW);
140
141 glBindBuffer(GL_ARRAY_BUFFER, gas.gasgeo_density_ID);
142 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4, &_color[0], GL_STATIC_DRAW);
143
144 GLushort idxs[6] = {0, 1, 2, 0, 2, 3};
145 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gas.gasgeo_tri_ID);
146 glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*sizeof(GLushort), idxs, GL_STATIC_DRAW);
147 }
148
149 /*=======================================================*/
150 /* finalization */
151 /*=======================================================*/
UnloadObjects(void)152 static void UnloadObjects(void)
153 {
154 unloadDAT(&plane);
155
156 return;
157 }
158
159 /*=======================================================*/
160 /* Initialization of s_Shaders */
161 /*=======================================================*/
ShaderInitialize(void)162 int ShaderInitialize(void)
163 {
164 s_Shaders[0] = glCreateShader(GL_VERTEX_SHADER);
165 s_Shaders[1] = glCreateShader(GL_VERTEX_SHADER);
166
167 nn::fs::FileReader file(L"rom:/shader.shbin");
168 size_t fileSize = file.GetSize();
169 void* buf = s_AppHeap.Allocate(fileSize);
170
171 s32 read = file.Read(buf, fileSize);
172 glShaderBinary(2, s_Shaders, GL_PLATFORM_BINARY_DMP, buf, read);
173 file.Finalize();
174 s_AppHeap.Free(buf);
175
176 pAccId = glCreateProgram();
177 glAttachShader(pAccId, s_Shaders[0]);
178 glAttachShader(pAccId, GL_DMP_FRAGMENT_SHADER_DMP);
179 glBindAttribLocation(pAccId, 0, "aPosition");
180 glBindAttribLocation(pAccId, 1, "aTexCoord");
181 glBindAttribLocation(pAccId, 2, "aColor");
182
183 glLinkProgram(pAccId);
184 glValidateProgram(pAccId);
185 glUseProgram(pAccId);
186
187 pPostId = glCreateProgram();
188 glAttachShader(pPostId, s_Shaders[1]);
189 glAttachShader(pPostId, GL_DMP_FRAGMENT_SHADER_DMP);
190 glBindAttribLocation(pPostId, 0, "aPosition");
191 glBindAttribLocation(pPostId, 1, "aTexCoord");
192 glBindAttribLocation(pPostId, 2, "aColor");
193
194 glLinkProgram(pPostId);
195 glValidateProgram(pPostId);
196 glUseProgram(pPostId);
197
198 return 0;
199 }
200
201 /*=======================================================*/
202 /* draw object */
203 /*=======================================================*/
DrawObject(void)204 static void DrawObject(void)
205 {
206 /* This function draws only one quadrangle. */
207 glUseProgram(pAccId);
208 glClearColor(0.2f, 0.4f, 0.7f, 1.0f);
209 glClearDepthf(1.f);
210
211 /* Set fragment operation mode to GL_FRAGOP_MODE_GL_DMP */
212 glUniform1i(glGetUniformLocation(pAccId, "dmp_FragOperation.mode"), GL_FRAGOP_MODE_GL_DMP);
213
214 /*
215 * Setup texture and blending unit
216 * The color of the object is defined as a constant color from blending unit 0
217 */
218 glUniform1i(glGetUniformLocation(pAccId, "dmp_Texture[0].samplerType"), GL_FALSE);
219 glUniform1i(glGetUniformLocation(pAccId, "dmp_TexEnv[0].combineRgb"), GL_REPLACE);
220 glUniform1i(glGetUniformLocation(pAccId, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
221 glUniform3i(glGetUniformLocation(pAccId, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
222 glUniform3i(glGetUniformLocation(pAccId, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
223 glUniform3i(glGetUniformLocation(pAccId, "dmp_TexEnv[0].srcRgb"), GL_CONSTANT, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
224 glUniform3i(glGetUniformLocation(pAccId, "dmp_TexEnv[0].srcAlpha"), GL_CONSTANT, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
225
226 float almostblack[4] = {0.15f, 0.15f, 0.15f, 0.0f};
227 glUniform4fv(glGetUniformLocation(pAccId, "dmp_TexEnv[0].constRgba"), 1, almostblack);
228
229 /*
230 * Miscellaneous settings
231 */
232 glDisable(GL_BLEND);
233 glEnable(GL_DEPTH_TEST);
234 glDepthMask(GL_TRUE);
235 glDepthFunc(GL_LEQUAL);
236
237 glDisable(GL_CULL_FACE);
238 glFrontFace(GL_CCW);
239 glCullFace(GL_BACK);
240
241 glEnableVertexAttribArray(0); /* enable position */
242 glDisableVertexAttribArray(1); /* disable texture coordinate */
243 glDisableVertexAttribArray(2); /* disable color */
244
245 for (int i = 0; i < plane.obj_num; i++)
246 {
247 glBindBuffer(GL_ARRAY_BUFFER, plane.posVB);
248 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)plane.obj[i].vtx_offset);
249 for (unsigned j = plane.obj[i].patch_offset; j < plane.obj[i].patch_size + plane.obj[i].patch_offset; j++)
250 {
251 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, plane.idxVB);
252 glDrawElements(GL_TRIANGLES, plane.patch[j].elm_size,
253 GL_UNSIGNED_SHORT, (GLvoid*)(plane.patch[j].elm_offset + plane.obj[i].elm_offset));
254 }
255 }
256
257 /*
258 * Finalization
259 */
260 glDisableVertexAttribArray(0);
261 }
262
263 /*=======================================================*/
264 /* draw frame */
265 /*=======================================================*/
DrawFrame(void)266 static int DrawFrame(void)
267 {
268 static int f = 0;
269 static const int step = 60;
270
271 /* Clear display buffer */
272 glBindFramebuffer(GL_FRAMEBUFFER, DISPLAY_BUFFER);
273 glClearColor(0.2f, 0.4f, 0.7f, 1.0f);
274 glClearDepthf(1.f);
275
276 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
277 s_RenderSystem.Clear();
278
279 glUseProgram(pAccId);
280 nn::math::Matrix44 proj, m;
281 nn::math::MTX44Perspective(&proj, 45.0f, static_cast<f32>(DISPLAY_WIDTH) / static_cast<f32>(DISPLAY_HEIGHT), 1.0f, 200.f);
282 glUniformMatrix4fv(glGetUniformLocation(pAccId, "uProjection"), 1, GL_TRUE, static_cast<f32*>(proj));
283
284 nn::math::Matrix34 mv, rot;
285 nn::math::Vector3 camPos(0.f, 0.f, 80.0f);
286 nn::math::Vector3 camUp(0.f, 1.f, 0.f);
287 nn::math::Vector3 target(0.f, 0.f, 0.f);
288
289 nn::math::MTX34LookAt(&mv, &camPos, &camUp, &target);
290 nn::math::MTX34RotXYZDeg(&rot, 0.f, 0.f, -90.0f);
291 nn::math::MTX34Mult(&mv, &mv, &rot);
292
293 {
294 /* Draw the Object */
295 nn::math::Matrix34 mv_rot;
296 nn::math::MTX34RotXYZDeg(&mv_rot, 0.f, 45.0f, 0.f);
297 nn::math::MTX34Mult(&mv_rot, &mv, &mv_rot);
298 m = nn::math::Matrix44(mv_rot);
299
300 glUniformMatrix4fv(glGetUniformLocation(pAccId, "uModelView"), 1, GL_TRUE, static_cast<f32*>(m));
301 DrawObject();
302 }
303
304 {
305 /* Gas accumulation pass */
306 nn::math::Matrix34 mv_tr;
307 nn::math::Vector3 trans(static_cast<f32>(f - 20), 0.f, 0.f);
308
309 nn::math::MTX34MultTranslate(&mv_tr, &mv, &trans);
310 m = nn::math::Matrix44(mv_tr);
311 glUniformMatrix4fv(glGetUniformLocation(pAccId, "uModelView"), 1, GL_TRUE, static_cast<f32*>(m));
312 GasAccumulation();
313 }
314
315 /* Gas shading pass */
316 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
317 GasShading();
318
319 /* swap buffer */
320 glFinish();
321
322 s_RenderSystem.SwapBuffers();
323
324 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
325 s_RenderSystem.Clear();
326 s_RenderSystem.SwapBuffers();
327
328 s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
329
330 if (++f == step)
331 f = 0;
332
333 /* return 0 when 16 frames done */
334 return !glGetError();
335 }
336
337 /*=======================================================*/
338 /* main function */
339 /*=======================================================*/
nnMain(void)340 void nnMain(void)
341 {
342 // Call only nn::applet::Enable to also allow execution from the HOME Menu
343 // HOME Menu transitions, POWER Button presses, and sleep are all unsupported
344 nn::applet::Enable();
345
346 // fs initialization
347 nn::fs::Initialize();
348
349 const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
350 static char buffer[ROMFS_BUFFER_SIZE];
351 NN_UTIL_PANIC_IF_FAILED(
352 nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
353
354 /* Initialize the framebuffer and gas buffer*/
355 Initialize();
356
357 /* Initialization of s_Shaders */
358 if (ShaderInitialize() >= 0)
359 {
360 /*Initialize standard and gaseous objects */
361 SceneObjectInitialize();
362
363 /* Enter loop */
364 while (1)
365 {
366 (void)DrawFrame();
367 }
368 }
369
370 UnloadObjects();
371 /* shutdown_display */
372 s_RenderSystem.Finalize();
373 s_AppHeap.Free(reinterpret_cast<void*>(s_HeapForMalloc));
374 s_AppHeap.Free(reinterpret_cast<void*>(s_HeapForGx));
375 s_AppHeap.Finalize();
376 }
377
378