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