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