1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: TriangleSimple.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.h>
17 #include <nn/gx.h>
18 #include <nn/math.h>
19 #include <nn/fs.h>
20 #include <nn/init.h>
21 #include <nn/fnd/fnd_ExpHeap.h>
22
23 #include "demo.h"
24
25 /* buffer id */
26 GLuint s_ArrayBufferID;
27 GLuint s_ElementArrayBufferID;
28
29 /* program id */
30 GLuint s_PgID;
31
32 /* shader id */
33 GLuint s_ShID;
34
35 s32 s_Count = 0;
36
37 /* ExpHeap for app. */
38 nn::fnd::ExpHeap s_AppHeap;
39 uptr s_HeapForGx;
40 const u32 s_GxHeapSize = 0x400000;
41
42 demo::RenderSystem s_RenderSystem;
43
44 /* Define in gx_CaptureUtil.cpp */
45 extern int SaveDisplayBufferSD(const wchar_t *dirname, const wchar_t *filename, u32 index,
46 GLuint addr, const u32 width, const u32 height, u8 *work = NULL);
47 extern void GetProjectionForPartialCapture(nn::math::Matrix44* pOut, nn::math::Matrix44* proj,
48 s32 div, s32 indexH, s32 indexV, const f32 dist, nn::math::PivotDirection pivot);
49
50 /* generate simple object */
LoadObjects(void)51 static void LoadObjects(void)
52 {
53 GLfloat coords[] = {
54 0.5f, 0.0f, 0.f, 1.f,
55 -0.5f, 0.5f, 0.f, 1.f,
56 -0.5f,-0.5f, 0.f, 1.f
57 };
58 GLfloat color[] = {
59 1.f, 0.0f, 0.0f,
60 0.f, 1.0f, 0.0f,
61 0.f, 0.0f, 1.0f
62 };
63
64 GLushort idxs[] = {0, 1, 2};
65
66 glGenBuffers(1, &s_ArrayBufferID);
67 glBindBuffer(GL_ARRAY_BUFFER, s_ArrayBufferID);
68 glBufferData(GL_ARRAY_BUFFER, sizeof(coords) + sizeof(color), 0, GL_STATIC_DRAW);
69 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(coords), coords);
70 glBufferSubData(GL_ARRAY_BUFFER, sizeof(coords), sizeof(color), color);
71
72 glGenBuffers(1, &s_ElementArrayBufferID);
73 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_ElementArrayBufferID);
74 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(idxs), idxs, GL_STATIC_DRAW);
75
76 glEnableVertexAttribArray(0);
77 glEnableVertexAttribArray(1);
78
79 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0) ;
80 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)sizeof(coords));
81 }
82
DrawDisplay0(void)83 void DrawDisplay0(void)
84 {
85 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
86 s_RenderSystem.Clear();
87
88 nn::math::Matrix44 proj;
89 nn::math::MTX44Frustum(&proj, -0.02f, 0.02f, -0.02f*nn::gx::DISPLAY0_HEIGHT/nn::gx::DISPLAY0_WIDTH,
90 0.02f*nn::gx::DISPLAY0_HEIGHT/nn::gx::DISPLAY0_WIDTH, 0.2f, 10.f);
91 glUniformMatrix4fv(glGetUniformLocation(s_PgID, "uProjection"), 1, GL_TRUE, static_cast<f32*>(proj));
92
93 nn::math::Matrix34 eye, rot;
94 nn::math::Vector3 camPos(0.f, 0.4f, 9.5f);
95 nn::math::Vector3 camUp(0.f, 1.f, 0.f);
96 nn::math::Vector3 target(0.f, 0.f, 0.f);
97 nn::math::Vector3 rotAxis(0.f, 1.f, 0.f);
98
99 nn::math::MTX34Identity(&eye);
100 nn::math::MTX34LookAt(&eye, &camPos, &camUp, &target);
101 nn::math::MTX34RotAxisDeg(&rot, &rotAxis, -6.f * s_Count);
102
103 nn::math::MTX34Mult(&eye, &eye, &rot);
104 nn::math::Matrix44 mv(eye);
105 glUniformMatrix4fv(glGetUniformLocation(s_PgID, "uModelView"), 1, GL_TRUE, (f32*)(mv));
106
107 glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);
108
109 s_RenderSystem.SwapBuffers();
110 }
111
DrawDisplay0AndSave(void)112 void DrawDisplay0AndSave(void)
113 {
114 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
115 s_RenderSystem.Clear();
116
117 nn::math::Matrix44 proj, tmp;
118 s32 i, j;
119
120 s32 div = 2;
121 int currDispBuf = 0;
122
123 // Allocate the display buffer for SD saving and then obtain the address.
124 GLuint disp[2];
125 GLint addr[2];
126
127 nngxGenDisplaybuffers(2, disp);
128 nngxBindDisplaybuffer(disp[0]);
129 nngxDisplaybufferStorage(GL_RGB8_OES, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT, NN_GX_MEM_FCRAM);
130 nngxGetDisplaybufferParameteri(NN_GX_DISPLAYBUFFER_ADDRESS, &addr[0]);
131 nngxBindDisplaybuffer(disp[1]);
132 nngxDisplaybufferStorage(GL_RGB8_OES, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT, NN_GX_MEM_FCRAM);
133 nngxGetDisplaybufferParameteri(NN_GX_DISPLAYBUFFER_ADDRESS, &addr[1]);
134
135 NN_TLOG_("Start saving...\n");
136 DEMO_ASSERT_GL_ERROR();
137
138 nn::math::Matrix34 eye, rot;
139 nn::math::Vector3 camPos(0.f, 0.4f, 9.5f);
140 nn::math::Vector3 camUp(0.f, 1.f, 0.f);
141 nn::math::Vector3 target(0.f, 0.f, 0.f);
142 nn::math::Vector3 rotAxis(0.f, 1.f, 0.f);
143
144 nn::math::MTX34Identity(&eye);
145 nn::math::MTX34LookAt(&eye, &camPos, &camUp, &target);
146 nn::math::MTX34RotAxisDeg(&rot, &rotAxis, -6.f * s_Count);
147
148 nn::math::MTX34Mult(&eye, &eye, &rot);
149 nn::math::Matrix44 mv(eye);
150 glUniformMatrix4fv(glGetUniformLocation(s_PgID, "uModelView"), 1, GL_TRUE, (f32*)(mv));
151
152 void* buf = s_AppHeap.Allocate(nn::gx::DISPLAY0_HEIGHT * nn::gx::DISPLAY0_WIDTH *3 + 54);
153
154 // Divide into div x div and render. Transfer the color buffer to the display buffer for SD writing.
155 for (i = 0; i < div; ++i)
156 {
157 for (j = 0; j < div; ++j)
158 {
159 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
160 // Clear the color buffer held by the RenderSystem.
161 // If the buffer is not cleared, the previous render results are sent to the display buffer each time.
162 s_RenderSystem.Clear();
163
164 // Create the perspective projection matrix.
165 // Disable rotation using pivot since the matrix can be decomposed using the GetProjectionForPartialCapture function.
166 nn::math::MTX44Frustum(&tmp, -0.02f, 0.02f, -0.02f*nn::gx::DISPLAY0_HEIGHT/nn::gx::DISPLAY0_WIDTH,
167 0.02f*nn::gx::DISPLAY0_HEIGHT/nn::gx::DISPLAY0_WIDTH, 0.2f, 10.f);
168
169 GetProjectionForPartialCapture(&proj, &tmp, 2, i, j, 0.0f, nn::math::PIVOT_NONE);
170
171 glUniformMatrix4fv(glGetUniformLocation(s_PgID, "uProjection"), 1, GL_TRUE, static_cast<f32*>(proj));
172 glUniformMatrix4fv(glGetUniformLocation(s_PgID, "uModelView"), 1, GL_TRUE, (f32*)(mv));
173
174 glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);
175 // Render to the color buffer held by RenderSystem.
176 // Waits for rendering to finish in this function.
177 s_RenderSystem.SwapBuffers();
178
179 // Transfers the rendering results remaining in the RenderSystem color buffer to the display buffer for SD Card writes.
180 //
181 // Immediately after RenderSystem.SwapBuffers is called, the command list is stopped (by default), so call Run.
182 // To match the state after RenderSystem.SwapBuffers is called, clear the command list and stop.
183 nngxTransferRenderImage(disp[currDispBuf], NN_GX_ANTIALIASE_NOT_USED, GL_FALSE, 0, 0);
184 nngxRunCmdlist();
185 nngxWaitCmdlistDone();
186 nngxClearCmdlist();
187 nngxStopCmdlist();
188
189 int err;
190 err = SaveDisplayBufferSD(L"sdmc:/test", L"test", i * div + j, addr[currDispBuf],
191 nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT,
192 (u8 *)buf);
193
194 if (err != 0)
195 {
196 NN_TLOG_("SaveDisplayBufferSD failed. (err: %d)\n", err);
197 nngxDeleteDisplaybuffers(2, disp);
198 return;
199 }
200
201 // If the same display buffer is used repeatedly, the previously written image will be corrupted because of cache issues. Use double buffering.
202 //
203 currDispBuf = (currDispBuf == 1 ? 0 : 1);
204 NN_TLOG_("save. section (%d, %d)\n", i, j);
205 }
206 }
207 s_AppHeap.Free(buf);
208
209 NN_TLOG_("done.\n");
210 nngxDeleteDisplaybuffers(2, disp);
211 }
212
DrawFrame(bool isCapture)213 int DrawFrame(bool isCapture)
214 {
215 if (isCapture)
216 {
217 DrawDisplay0AndSave();
218 }
219 else
220 {
221 DrawDisplay0();
222 }
223
224 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
225 s_RenderSystem.Clear();
226 s_RenderSystem.SwapBuffers();
227
228 s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
229
230 s_Count++;
231
232 return !glGetError();
233 }
234
235 /* initialization */
Initialize(void)236 int Initialize(void)
237 {
238
239 // fs initialization
240 nn::fs::Initialize();
241
242 // Will not work without SD Card
243 nn::Result result = nn::fs::MountSdmc();
244 if (result.IsFailure())
245 {
246 NN_PANIC("SD memory card is unavailable.");
247 }
248
249 const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
250 static char buffer[ROMFS_BUFFER_SIZE];
251 NN_UTIL_PANIC_IF_FAILED(
252 nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
253
254 nn::hid::Initialize();
255
256 s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize() );
257 s_HeapForGx = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_GxHeapSize));
258 /* Initialize display */
259 s_RenderSystem.Initialize(s_HeapForGx, s_GxHeapSize);
260
261 s_PgID = glCreateProgram();
262 s_ShID = glCreateShader(GL_VERTEX_SHADER);
263
264 nn::fs::FileReader file(L"rom:/shader.shbin");
265 size_t fileSize = file.GetSize();
266 void* buf = s_AppHeap.Allocate(fileSize);
267
268 s32 read = file.Read(buf, fileSize);
269 glShaderBinary(1, &s_ShID, GL_PLATFORM_BINARY_DMP, buf, read);
270 file.Finalize();
271 s_AppHeap.Free(buf);
272
273 glAttachShader(s_PgID, s_ShID);
274 glAttachShader(s_PgID, GL_DMP_FRAGMENT_SHADER_DMP);
275
276 glBindAttribLocation(s_PgID, 0, "aPosition");
277 glBindAttribLocation(s_PgID, 1, "aColor");
278
279 glLinkProgram(s_PgID);
280 glValidateProgram(s_PgID);
281 glUseProgram(s_PgID);
282
283 glClearColor(0.36f, 0.42f, 0.5f, 1.0f);
284 glClearDepthf(1.f);
285
286 glEnable(GL_DEPTH_TEST);
287 glDepthFunc(GL_LESS);
288 glFrontFace(GL_CCW);
289
290 LoadObjects();
291
292 glUniform3i(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].srcRgb"), GL_PRIMARY_COLOR, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
293 glUniform3i(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].srcAlpha"), GL_PRIMARY_COLOR, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
294
295 return 0;
296 }
297
Finalize(void)298 void Finalize(void)
299 {
300 /* shutdown_display */
301 s_RenderSystem.Finalize();
302 s_AppHeap.Free(reinterpret_cast<void*>(s_HeapForGx));
303 s_AppHeap.Finalize();
304 }
305