1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: gx_TriangleSimpleCmd.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/os.h>
21 #include <nn/init.h>
22 #include <nn/applet.h>
23 #include <nn/fnd/fnd_ExpHeap.h>
24
25 #include "nn/gx/CTR/gx_CommandAccess.h"
26
27 #include "MemoryManager.h"
28
29 /* Objects for system API */
30 GLuint s_CmdlistID;
31 GLuint s_FramebufferID;
32 GLuint s_RenderbufferID[2];
33 GLuint s_Displaybuffer0ID[2];
34 GLuint s_Displaybuffer1ID[2];
35 GLint s_CurrentDisplaybuffer0 = 0;
36 GLint s_CurrentDisplaybuffer1 = 0;
37
38 /* buffer id */
39 GLuint s_ArrayBufferID;
40 GLuint s_ElementArrayBufferID;
41
42 /* ExpHeap for app. */
43 nn::fnd::ExpHeap s_AppHeap;
44 uptr s_HeapForGx;
45 const u32 s_GxHeapSize = 0x400000;
46
47 GLfloat* s_VertexArray = NULL;
48 GLushort* s_IndexArray = NULL;
49
50 u32 s_VertexAttributeBaseAddress = 0x0;
51 u32 s_VertexAttribute0AddressOffset = 0x0;
52 u32 s_VertexAttribute1AddressOffset = 0x0;
53 u32 s_VertexIndexAddressOffset = 0x0;
54 u32 s_VertexNum = 3;
55 u32 s_IndexNum = 3;
56
57 const u32 FRAME_COUNTER_THRE = 60;
58 u32 s_FrameCount = 0;
59
60
61
62 int Initialize(void);
63 void InitializeGraphics(void);
64 void AddDepthBufferCommand(void);
65 void InitializeVBO(void);
66
67 int DrawFrame(void);
68 void DrawFrameUpper(void);
69 void DrawFrameLower(void);
70
71 void AddViewportCommand(const s32 display);
72
73 void AddFirstDrawCommand(void);
74 void AddVertexShaderCommand(void);
75 void AddVertexAttributeCommand(void);
76 void AddVertexShaderUniformCommand(void);
77 void AddTextureCombinerCommand(void);
78
79 void AddDrawTriangleCommand(void);
80
81 void AddFrameBufferControlCommand(void);
82
Initialize(void)83 int Initialize(void)
84 {
85
86 // fs initialization
87 nn::fs::Initialize();
88
89 const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
90 static char buffer[ROMFS_BUFFER_SIZE];
91 NN_UTIL_PANIC_IF_FAILED(
92 nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
93
94 s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize() );
95 s_HeapForGx = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_GxHeapSize));
96
97 InitializeGraphics();
98
99 return 0;
100 }
101
InitializeGraphics(void)102 void InitializeGraphics(void)
103 {
104 demo::InitializeMemoryManager(s_HeapForGx, s_GxHeapSize);
105 nngxInitialize(demo::GetAllocator, demo::GetDeallocator);
106
107 /* Generate and allocate command list object */
108 nngxGenCmdlists(1, &s_CmdlistID);
109 nngxBindCmdlist(s_CmdlistID);
110 nngxCmdlistStorage(0x40000, 128);
111
112 /* Generate, allocate and attach framebuffer object and render buffer */
113 glGenFramebuffers(1, &s_FramebufferID);
114 glBindFramebuffer(GL_FRAMEBUFFER, s_FramebufferID);
115
116 glGenRenderbuffers(2, s_RenderbufferID);
117 glBindRenderbuffer(GL_RENDERBUFFER, s_RenderbufferID[0]);
118 glRenderbufferStorage(GL_RENDERBUFFER | NN_GX_MEM_VRAMA, GL_RGBA8_OES,
119 nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT);
120 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, s_RenderbufferID[0]);
121
122 glBindRenderbuffer(GL_RENDERBUFFER, s_RenderbufferID[1]);
123 glRenderbufferStorage(GL_RENDERBUFFER | NN_GX_MEM_VRAMB, GL_DEPTH24_STENCIL8_EXT,
124 nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT);
125 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, s_RenderbufferID[1]);
126
127 /* Generate and allocate display buffer; set display region */
128 nngxGenDisplaybuffers(2, s_Displaybuffer0ID);
129 nngxActiveDisplay(NN_GX_DISPLAY0);
130 nngxDisplayEnv(0, 0);
131 nngxBindDisplaybuffer(s_Displaybuffer0ID[0]);
132 nngxDisplaybufferStorage(GL_RGB8_OES, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT, NN_GX_MEM_FCRAM);
133
134 nngxBindDisplaybuffer(s_Displaybuffer0ID[1]);
135 nngxDisplaybufferStorage(GL_RGB8_OES, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT, NN_GX_MEM_FCRAM);
136
137 nngxGenDisplaybuffers(2, s_Displaybuffer1ID);
138 nngxActiveDisplay(NN_GX_DISPLAY1);
139 nngxDisplayEnv(0, 0);
140 nngxBindDisplaybuffer(s_Displaybuffer1ID[0]);
141 nngxDisplaybufferStorage(GL_RGB8_OES, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT, NN_GX_MEM_FCRAM);
142
143 nngxBindDisplaybuffer(s_Displaybuffer1ID[1]);
144 nngxDisplaybufferStorage(GL_RGB8_OES, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT, NN_GX_MEM_FCRAM);
145
146 nngxRunCmdlist();
147
148 glClearColor(0.36f, 0.42f, 0.5f, 1.0f);
149 glClearDepthf(1.f);
150
151 AddDepthBufferCommand();
152
153 glFrontFace(GL_CCW);
154
155 InitializeVBO();
156 }
157
AddDepthBufferCommand(void)158 void AddDepthBufferCommand(void)
159 {
160 /*
161 glEnable(GL_DEPTH_TEST);
162 glDepthFunc(GL_LESS);
163 */
164
165 u32 commandBuffer[] =
166 {
167 // Depth test
168 // 0x107
169 PICA_CMD_DATA_DEPTH_COLOR_MASK(
170 // enableDepthTest
171 1,
172 // depthFunc
173 PICA_DATA_DEPTH_TEST_LESS,
174 // red, green, blue, alpha
175 0, 0, 0, 0,
176 // depthMask
177 0),
178 PICA_CMD_HEADER_SINGLE_BE(PICA_REG_DEPTH_COLOR_MASK, 0x1),
179
180 // dmp_Gas.deltaZ
181 // 0x126 [25:24]
182 PICA_CMD_DATA_GAS_DELTAZ_DEPTH(0, PICA_DATA_DEPTH_TEST2_OTHER),
183 PICA_CMD_HEADER_SINGLE_BE(PICA_REG_GAS_DELTAZ_DEPTH, 0x8),
184 };
185
186 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
187 }
188
InitializeVBO(void)189 void InitializeVBO(void)
190 {
191 GLenum arrayFlag = GL_ARRAY_BUFFER | NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP;
192 GLenum elementArrayFlag = GL_ELEMENT_ARRAY_BUFFER | NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP;
193
194 u32 positionSize = sizeof(GLfloat) * s_VertexNum * 4;
195 u32 colorSize = sizeof(GLfloat) * s_VertexNum * 3;
196 u32 indexSize = sizeof(GLushort) * s_IndexNum;
197
198 s_VertexArray = (GLfloat*) demo::Alloc(NN_GX_MEM_VERTEXBUFFER, positionSize + colorSize);
199 u32 vertexArrayPhysicalAddress = nngxGetPhysicalAddr( (uptr) s_VertexArray );
200 // NN_LOG("s_VertexArray = 0x%x, Physical address = 0x%p\n", s_VertexArray, vertexArrayPhysicalAddress);
201
202 /*
203 GLfloat coords[] =
204 {
205 0.5f, 0.0f, 0.f, 1.f,
206 -0.5f, 0.5f, 0.f, 1.f,
207 -0.5f,-0.5f, 0.f, 1.f
208 };
209 */
210
211 s_VertexArray[ 0 ] = 0.5f;
212 s_VertexArray[ 1 ] = 0.0f;
213 s_VertexArray[ 2 ] = 0.0f;
214 s_VertexArray[ 3 ] = 1.0f;
215
216 s_VertexArray[ 4 ] = -0.5f;
217 s_VertexArray[ 5 ] = 0.5f;
218 s_VertexArray[ 6 ] = 0.0f;
219 s_VertexArray[ 7 ] = 1.0f;
220
221 s_VertexArray[ 8 ] = -0.5f;
222 s_VertexArray[ 9 ] = -0.5f;
223 s_VertexArray[ 10 ] = 0.0f;
224 s_VertexArray[ 11 ] = 1.0f;
225
226 /*
227 GLfloat color[] =
228 {
229 1.f, 1.0f, 0.0f,
230 0.f, 1.0f, 0.0f,
231 0.f, 0.0f, 1.0f
232 };
233 */
234
235 const u32 offset = 12;
236 s_VertexArray[ offset + 0 ] = 1.0f;
237 s_VertexArray[ offset + 1 ] = 0.0f;
238 s_VertexArray[ offset + 2 ] = 0.0f;
239
240 s_VertexArray[ offset + 3 ] = 0.0f;
241 s_VertexArray[ offset + 4 ] = 1.0f;
242 s_VertexArray[ offset + 5 ] = 0.0f;
243
244 s_VertexArray[ offset + 6 ] = 0.0f;
245 s_VertexArray[ offset + 7 ] = 0.0f;
246 s_VertexArray[ offset + 8 ] = 1.0f;
247
248 s_IndexArray = (GLushort*) demo::Alloc(NN_GX_MEM_VERTEXBUFFER, indexSize);
249 u32 indexArrayPhysicalAddress = nngxGetPhysicalAddr( (uptr) s_IndexArray);
250
251 // NN_LOG("s_IndexArray = 0x%x, physical address = 0x%p\n", s_IndexArray, indexArrayPhysicalAddress);
252
253 /*
254 GLushort idxs[] = {0, 1, 2};
255 */
256 s_IndexArray[ 0 ] = 0;
257 s_IndexArray[ 1 ] = 1;
258 s_IndexArray[ 2 ] = 2;
259
260 glGenBuffers(1, &s_ArrayBufferID);
261 glBindBuffer(GL_ARRAY_BUFFER, s_ArrayBufferID);
262 glBufferData(arrayFlag, positionSize + colorSize, s_VertexArray, GL_STATIC_DRAW);
263
264 glGenBuffers(1, &s_ElementArrayBufferID);
265 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_ElementArrayBufferID);
266 glBufferData(elementArrayFlag, indexSize, s_IndexArray, GL_STATIC_DRAW);
267
268 // Base address is aligned to 16 bytes
269 u32 alignOffset = (uptr)vertexArrayPhysicalAddress % 16;
270 u32 baseAddress = vertexArrayPhysicalAddress - alignOffset;
271
272 s_VertexAttributeBaseAddress = PICA_CMD_DATA_VERTEX_ATTR_ARRAYS_BASE_ADDR(baseAddress);
273 s_VertexAttribute0AddressOffset = vertexArrayPhysicalAddress - baseAddress;
274 s_VertexAttribute1AddressOffset = alignOffset + positionSize;
275 s_VertexIndexAddressOffset = indexArrayPhysicalAddress - baseAddress;
276 }
277
278
279
DrawFrame(void)280 int DrawFrame(void)
281 {
282 DrawFrameUpper();
283 DrawFrameLower();
284
285 nngxActiveDisplay(NN_GX_DISPLAY0);
286 nngxBindDisplaybuffer(s_Displaybuffer0ID[s_CurrentDisplaybuffer0]);
287
288 nngxActiveDisplay(NN_GX_DISPLAY1);
289 nngxBindDisplaybuffer(s_Displaybuffer1ID[s_CurrentDisplaybuffer1]);
290
291 nngxSwapBuffers(NN_GX_DISPLAY_BOTH);
292
293 s_CurrentDisplaybuffer0 = (s_CurrentDisplaybuffer0 == 0 ? 1 : 0);
294 s_CurrentDisplaybuffer1 = (s_CurrentDisplaybuffer1 == 0 ? 1 : 0);
295
296 nngxClearCmdlist();
297 nngxRunCmdlist();
298
299 nngxWaitVSync(NN_GX_DISPLAY_BOTH);
300
301 if ( s_FrameCount == 0 )
302 {
303 nngxStartLcdDisplay();
304 }
305
306 if ( ( s_FrameCount % FRAME_COUNTER_THRE) == 0 )
307 {
308 NN_LOG("Total frame count = %d\n", s_FrameCount);
309 }
310
311 s_FrameCount += 1;
312
313 return 1;
314 }
315
DrawFrameUpper(void)316 void DrawFrameUpper(void)
317 {
318 static bool firstFlag = true;
319
320 AddViewportCommand(NN_GX_DISPLAY0);
321 glBindFramebuffer(GL_FRAMEBUFFER, s_FramebufferID);
322 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
323
324 if ( firstFlag )
325 {
326 AddFirstDrawCommand();
327 firstFlag = false;
328 }
329
330 AddDrawTriangleCommand();
331
332 nngxSplitDrawCmdlist();
333 nngxRunCmdlist();
334 nngxWaitCmdlistDone();
335
336 nngxTransferRenderImage(s_Displaybuffer0ID[s_CurrentDisplaybuffer0], NN_GX_ANTIALIASE_NOT_USED, GL_FALSE, 0, 0);
337 }
338
DrawFrameLower(void)339 void DrawFrameLower(void)
340 {
341 // Just clear the lower screen; do not render anything
342 AddViewportCommand(NN_GX_DISPLAY1);
343 glBindFramebuffer(GL_FRAMEBUFFER, s_FramebufferID);
344 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
345 nngxTransferRenderImage(s_Displaybuffer1ID[s_CurrentDisplaybuffer1], NN_GX_ANTIALIASE_NOT_USED, GL_FALSE, 0, 0);
346
347 nngxRunCmdlist();
348 nngxWaitCmdlistDone();
349 }
350
AddViewportCommand(s32 display)351 void AddViewportCommand(s32 display)
352 {
353 if ( display == NN_GX_DISPLAY0 )
354 {
355 // glViewport(0, 0, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT);
356 u32 commandBuffer[] =
357 {
358 // Set the Viewport width (set width to f32, divide by two, and convert to f24)
359 // 0x41
360 0x45E000, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_WIDTH1),
361
362 // Set the Viewport height (set height to f32, divide by two, and convert to f24)
363 // 0x43
364 0x469000, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_HEIGHT1),
365
366 // Set Viewport width (Divide 2 by width, convert to f31, and shift 1 bit left)
367 // 0x42
368 0x38111111, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_WIDTH2),
369
370 // Set Viewport height (Divide 2 by height, convert to f31, and shift 1 bit left)
371 // 0x44
372 0x3747AE14, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_HEIGHT2),
373
374 // x = 0, y = 0
375 // 0x68
376 PICA_CMD_DATA_VIEWPORT_XY(0, 0), PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_XY)
377 };
378
379 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
380 }
381 else if ( display == NN_GX_DISPLAY1 )
382 {
383 // glViewport(0, 0, nn::gx::DISPLAY1_WIDTH, nn::gx::DISPLAY1_HEIGHT);
384 u32 commandBuffer[] =
385 {
386 // Set the Viewport width (set width to f32, divide by two, and convert to f24)
387 // 0x41
388 0x45E000, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_WIDTH1),
389
390 // Set the Viewport height (set height to f32, divide by two, and convert to f24)
391 // 0x43
392 0x464000, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_HEIGHT1),
393
394 // Set Viewport width (Divide 2 by width, convert to f31, and shift 1 bit left)
395 // 0x42
396 0x38111111, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_WIDTH2),
397
398 // Set Viewport height (Divide 2 by height, convert to f31, and shift 1 bit left)
399 // 0x44
400 0x37999999, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_HEIGHT2),
401
402 // x = 0, y = 0
403 // 0x68
404 PICA_CMD_DATA_VIEWPORT_XY(0, 0), PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_XY)
405 };
406
407 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
408 }
409 }
410
AddFirstDrawCommand(void)411 void AddFirstDrawCommand(void)
412 {
413 AddVertexShaderCommand();
414 AddVertexAttributeCommand();
415
416 AddVertexShaderUniformCommand();
417
418 AddTextureCombinerCommand();
419 }
420
AddVertexShaderCommand(void)421 void AddVertexShaderCommand(void)
422 {
423 /*
424 s_PgID = glCreateProgram();
425 s_ShID = glCreateShader(GL_VERTEX_SHADER);
426
427 nn::fs::FileReader file(L"rom:/shader.shbin");
428 size_t fileSize = file.GetSize();
429 void* buf = s_AppHeap.Allocate(fileSize);
430
431 s32 read = file.Read(buf, fileSize);
432 glShaderBinary(1, &s_ShID, GL_PLATFORM_BINARY_DMP, buf, read);
433 file.Finalize();
434 s_AppHeap.Free(buf);
435
436 glAttachShader(s_PgID, s_ShID);
437 glAttachShader(s_PgID, GL_DMP_FRAGMENT_SHADER_DMP);
438
439 glBindAttribLocation(s_PgID, 0, "aPosition");
440 glBindAttribLocation(s_PgID, 1, "aColor");
441
442 glLinkProgram(s_PgID);
443 glValidateProgram(s_PgID);
444 glUseProgram(s_PgID);
445 */
446
447 {
448 u32 commandBuffer[] =
449 {
450 // Do not use geometry shader
451 // 0x229
452 PICA_CMD_SET_VS_GS_MODE(0x0, 0x0),
453 // Do not use geometry shader
454 // 0x244 : 0x0 (BE 0x1)
455 PICA_CMD_SET_VS_COM_MODE(0x0),
456 // Set the load address for the vertex shader program code to 0
457 // 0x2CB : 0x0 (BE 0xF)
458 PICA_CMD_DATA_VS_PROG_ADDR(0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_PROG_ADDR)
459 };
460
461 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
462 }
463
464 {
465 // Vertex shader program data
466 u32 commandBuffer[] =
467 {
468 // BurstSingle (13 times, BE 0xF)
469 // 0x2CC : 0xBE24000
470 0xBE24000, PICA_CMD_HEADER_BURST(PICA_REG_VS_PROG_DATA0, 13),
471 // 0x2CC : 0xBE25001
472 // 0x2CC : 0xBE26002
473 0xBE25001, 0xBE26002,
474 // 0x2CC : 0xBE27003
475 // 0x2CC : 0x8020F80
476 0xBE27003, 0x8020F80,
477 // 0x2CC : 0x8021F81
478 // 0x2CC : 0x8022F82
479 0x8021F81, 0x8022F82,
480 // 0x2CC : 0x8023F83
481 // 0x2CC : 0x84000000
482 0x8023F83, 0x84000000,
483 // 0x2CC : 0x90000008
484 // 0x2CC :0x4C201004
485 0x90000008, 0x4C201004,
486 // 0x2CC : 0x88000000
487 // 0x2CC : 0x84000000
488 0x88000000, 0x84000000
489 };
490
491 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
492 }
493
494 {
495 // Notification that update of vertex shader program is complete
496 u32 commandBuffer[] =
497 {
498 // 0x2BF : 0x1 (BE 0xF)
499 PICA_CMD_DATA_VS_PROG_END(0x1), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_PROG_UPDATE_END)
500 };
501
502 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
503 }
504
505 {
506 // Swizzle
507 u32 commandBuffer[] =
508 {
509 // Set the Swizzle pattern's load address to 0
510 // 0x2D5 : 0x0 (BE 0xF)
511 PICA_CMD_DATA_VS_PROG_SWIZZLE_ADDR(0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_PROG_SWIZZLE_ADDR),
512
513 // Set the Swizzle pattern's data
514 // BurstSingle (5 times, BE 0xF)
515 // 0x2D6 : 0x8006C368
516 PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8006C368), PICA_CMD_HEADER_BURST(PICA_REG_VS_PROG_SWIZZLE_DATA0, 5),
517 // 0x2D6 : 0x8006C364
518 // 0x2D6 : 0x8006C362
519 PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8006C364), PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8006C362),
520 // 0x2D6 : 0x8006C361
521 // 0x2D6 : 0x8000036F
522 PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8006C361), PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8000036F)
523 };
524
525 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
526 }
527 }
528
AddVertexAttributeCommand(void)529 void AddVertexAttributeCommand(void)
530 {
531 {
532 u32 commandBuffer[] =
533 {
534 // BurstSequence (39 times, BE 0xF)
535
536 // Common base address for all vertex arrays
537 // 0x200 : BaseAddress
538 s_VertexAttributeBaseAddress, PICA_CMD_HEADER_BURSTSEQ(PICA_REG_VERTEX_ATTR_ARRAYS_BASE_ADDR, 39),
539
540 // 0x201 : 0xBFF
541 // Attribute0 [3:0] 0xF : size=4, GL_FLOAT
542 // Attribute1 [7:4] 0xB : size=3, GL_FLOAT
543 //
544 // 0x202 : 0x10000000
545 // [31:28] TotalVertexAttributeNum - 1
546 0xBF, 0x10000000,
547
548 // 0x203 : 0x0
549 // Byte offset from the the base address of load array 0
550 //
551 // 0x204 : 0x0
552 // [3:0] The 1st element of load array 0 is internal vertex attribute 0
553 s_VertexAttribute0AddressOffset, 0x0,
554
555 // 0x205 : 0x10100000
556 // [23:16] : Number of bytes per vertex in load array 0: 16 (Bytes)
557 // [31:28] : Number of elements in load array 0: 1
558 //
559 // 0x206 : 0x30
560 // Byte offset from the the base address of load array 1
561 0x10100000, s_VertexAttribute1AddressOffset,
562
563 // 0x207 : 0x1
564 // [3:0] The 1st element of load array 1 is internal vertex attribute 1
565 //
566 // 0x208 : 0x100C0000
567 // [23:16] : Number of bytes per vertex in load array 1: 12 (Bytes)
568 // [31:28] : Number of elements in load array 1: 1
569 0x1, 0x100C0000,
570
571 // 0x209 : 0x0
572 // 0x20A : 0x0
573 0x0, 0x0,
574
575 // 0x20B : 0x0
576 // 0x20C : 0x0
577 0x0, 0x0,
578
579 // 0x20D : 0x0
580 // 0x20E : 0x0
581 0x0, 0x0,
582
583 // 0x20F : 0x0
584 // 0x210 : 0x0
585 0x0, 0x0,
586
587 // 0x211 : 0x0
588 // 0x212 : 0x0
589 0x0, 0x0,
590
591 // 0x213 : 0x0
592 // 0x214 : 0x0
593 0x0, 0x0,
594
595 // 0x215 : 0x0
596 // 0x216 : 0x0
597 0x0, 0x0,
598
599 // 0x217 : 0x0
600 // 0x218 : 0x0
601 0x0, 0x0,
602
603 // 0x219 : 0x0
604 // 0x21A : 0x0
605 0x0, 0x0,
606
607 // 0x21B : 0x0
608 // 0x21C : 0x0
609 0x0, 0x0,
610
611 // 0x21D : 0x0
612 // 0x21E : 0x0
613 0x0, 0x0,
614
615 // 0x21F : 0x0
616 // 0x220 : 0x0
617 0x0, 0x0,
618
619 // 0x221 : 0x0
620 // 0x222 : 0x0
621 0x0, 0x0,
622
623 // 0x223 : 0x0
624 // 0x224 : 0x0
625 0x0, 0x0,
626
627 // 0x225 : 0x0
628 // 0x226 : 0x0
629 0x0, 0x0
630 };
631
632 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
633 }
634
635 {
636 u32 commandBuffer[] =
637 {
638 // 0x2BB : 0x10 (BE 0xF)
639 // Register that sets the input register map for vertex attributes 0-8
640 // [3:0] = 0 (The index of the input register for the storage location of the first vertex attribute that was input)
641 // [7:4] = 1 (The index of the input register for the storage location of the second vertex attribute that was input)
642 PICA_CMD_DATA_VS_ATTR_IN_REG_MAP0(0, 1, 0, 0, 0, 0, 0, 0),
643 PICA_CMD_HEADER_SINGLE(PICA_REG_VS_ATTR_IN_REG_MAP0),
644
645 // 0x2BC : 0x0 (BE 0xF)
646 // Register that sets the input register map for vertex attributes 9-12
647 PICA_CMD_DATA_VS_ATTR_IN_REG_MAP1(0, 0, 0, 0),
648 PICA_CMD_HEADER_SINGLE(PICA_REG_VS_ATTR_IN_REG_MAP1)
649 };
650
651 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
652 }
653
654 {
655 u32 commandBuffer[] =
656 {
657 // Register that sets the number of vertex attribute inputs.
658 //
659 // 0x2B9 : 0xA0000000 | 0x1, (BE 0xB = 1011(2) )
660 // PICA_CMD_DATA_VS_ATTR_NUM0(0x2), PICA_CMD_HEADER_SINGLE_BE(PICA_REG_VS_ATTR_NUM0, 0xB),
661 //
662 // 0x242 : 0x1 (BE 0xF)
663 // PICA_CMD_DATA_VS_ATTR_NUM1(0x2), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_ATTR_NUM1)
664 PICA_CMD_SET_VS_ATTR_NUM( 0x2 ),
665
666 // Register that sets the number of vertex attributes to input to the vertex shader
667 //
668 // 0x4F : 0x2
669 // 0x2, PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_REG_NUM0)
670 //
671 // 0x24A : 0x1 (BE 0xF)
672 // 0x1, PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_REG_NUM1),
673 //
674 // 0x251 [3:0] : 0x2 (BE 0xF)
675 // 0x1, PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_REG_NUM2),
676 PICA_CMD_SET_VS_GS_OUT_REG_NUM( 0x2 ),
677
678 // 0x2BA [15:0] : Sets the data address of the vertex shader
679 // [31:16] : Sets 0x7FFF
680 // 0x7FFF0009 (BE 0xF)
681 PICA_CMD_DATA_VS_START_ADDR(0x9), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_START_ADDR),
682
683 // 0x2BD : 0x3 (BE 0xF)
684 // Set the mask for the vertex shader output register (o0 = [0:0], o1 = [1;1])
685 PICA_CMD_DATA_VS_OUT_MASK(0x3), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_REG_MASK),
686
687 // Register that sets the vertex shader output attribute
688 // 0x50 : 0x3020100 (BE 0xF)
689 // #pragma output_map ( position, o0 )
690 // [ 4: 0] : Vertex coordinate x, 0x00
691 // [12: 8] : Vertex coordinate y, 0x01
692 // [20:16] : Vertex coordinate z, 0x02
693 // [28:24] : Vertex coordinate w, 0x03
694 PICA_CMD_DATA_VS_GS_OUT_ATTR(PICA_DATA_VS_OUT_ATTR_X,
695 PICA_DATA_VS_OUT_ATTR_Y, PICA_DATA_VS_OUT_ATTR_Z,
696 PICA_DATA_VS_OUT_ATTR_W),
697 PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_ATTR0),
698
699 // Register that sets the vertex shader output attribute
700 // 0x51 : 0xB0A0908 (BE 0xF)
701 // #pragma output_map (color, o1)
702 // [ 4: 0] : Vertex color R, 0x08
703 // [12: 8] : Vertex color G, 0x09
704 // [20:16] : Vertex color B, 0x0a
705 // [28:24] : Vertex color A, 0x0b
706 PICA_CMD_DATA_VS_GS_OUT_ATTR(PICA_DATA_VS_OUT_ATTR_R,
707 PICA_DATA_VS_OUT_ATTR_G, PICA_DATA_VS_OUT_ATTR_B,
708 PICA_DATA_VS_OUT_ATTR_A),
709 PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_ATTR1),
710
711 // Clock control setting register for output attributes from the vertex shader
712 // 0x6F : 0x3 (BE 0xF)
713 // Output the vertex's z coordinate; output the vertex color
714 PICA_CMD_DATA_VS_GS_OUT_ATTR_CLK(1, 1, 0, 0, 0, 0, 0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_ATTR_CLK)
715 };
716
717 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
718 }
719 }
720
AddVertexShaderUniformCommand(void)721 void AddVertexShaderUniformCommand(void)
722 {
723 /*
724 // Upper screen vertex uniform settings
725 nn::math::Matrix44 proj;
726 nn::math::MTX44Frustum(&proj, -0.02f, 0.02f, -0.02f*nn::gx::DISPLAY0_HEIGHT/nn::gx::DISPLAY0_WIDTH,
727 0.02f*nn::gx::DISPLAY0_HEIGHT/nn::gx::DISPLAY0_WIDTH, 0.2f, 10.f);
728 glUniformMatrix4fv(glGetUniformLocation(s_PgID, "uProjection"), 1, GL_TRUE, static_cast<f32*>(proj));
729
730 nn::math::Matrix34 eye, rot;
731 nn::math::Vector3 camPos(0.f, 0.4f, 9.5f);
732 nn::math::Vector3 camUp(0.f, 1.f, 0.f);
733 nn::math::Vector3 target(0.f, 0.f, 0.f);
734 nn::math::Vector3 rotAxis(0.f, 1.f, 0.f);
735
736 nn::math::MTX34Identity(&eye);
737 nn::math::MTX34LookAt(&eye, &camPos, &camUp, &target);
738 nn::math::MTX34RotAxisDeg(&rot, &rotAxis, -6.f * 0.0f);
739
740 nn::math::MTX34Mult(&eye, &eye, &rot);
741 nn::math::Matrix44 mv(eye);
742 glUniformMatrix4fv(glGetUniformLocation(s_PgID, "uModelView"), 1, GL_TRUE, (f32*)(mv));
743 */
744
745 {
746 // Index of floating-point registers for vertex shader
747 u32 commandBuffer[] =
748 {
749 // 0x2C0 : 0x80000000 (BE 0xF)
750 PICA_CMD_DATA_VS_FLOAT_ADDR(PICA_DATA_VS_F32, 0x0),
751 PICA_CMD_HEADER_SINGLE(PICA_REG_VS_FLOAT_ADDR)
752 };
753
754 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
755 }
756
757 {
758 // Settings for floating-point registers of the vertex shader
759 u32 commandBuffer[] =
760 {
761 // BurstSingle (32 times, BE 0xF)
762 // 0x2C1 : 0x0
763 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_HEADER_BURST(PICA_REG_VS_FLOAT1, 32),
764
765 // 0x2C1 : 0x0
766 // 0x2C1 : 0x0
767 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x0),
768
769 // 0x2C1 : 0x41200000
770 // 0x2C1 : 0x0
771 PICA_CMD_DATA_VS_FLOAT(0x41200000), PICA_CMD_DATA_VS_FLOAT(0x0),
772
773 // 0x2C1 : 0x0
774 // 0x2C1 : 0x40BFFFFF
775 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x40BFFFFF),
776
777 // 0x2C1 : 0x0
778 // 0x2C1 : 0x3E50FAC6
779 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x3E50FAC6),
780
781 // 0x2C1 : 0x3F829CBC
782 // 0x2C1 : 0x0
783 PICA_CMD_DATA_VS_FLOAT(0x3F829CBC), PICA_CMD_DATA_VS_FLOAT(0x0),
784
785 // 0x2C1 : 0x0
786 // 0x2C1 : 0x0
787 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x0),
788
789 // 0x2C1 : 0xBF800000
790 // 0x2C1 : 0x0
791 PICA_CMD_DATA_VS_FLOAT(0xBF800000), PICA_CMD_DATA_VS_FLOAT(0x0),
792
793 // 0x2C1 : 0x0
794 // 0x2C1 : 0x0
795 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x0),
796
797 // 0x2C1 : 0x0
798 // 0x2C1 : 0x0
799 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x0),
800
801 // 0x2C1 : 0x3F800000
802 // 0x2C1 : 0x0
803 PICA_CMD_DATA_VS_FLOAT(0x3F800000), PICA_CMD_DATA_VS_FLOAT(0x0),
804
805 // 0x2C1 : 0xBD2C4F7C
806 // 0x2C1 : 0x3F7FC5FC
807 PICA_CMD_DATA_VS_FLOAT(0xBD2C4F7C), PICA_CMD_DATA_VS_FLOAT(0x3F7FC5FC),
808
809 // 0x2C1 : 0x0
810 // 0x2C1 : 0xC118227B
811 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0xC118227B),
812
813 // 0x2C1 : 0x3F7FC5FC
814 // 0x2C1 : 0x3D2C4F7C
815 PICA_CMD_DATA_VS_FLOAT(0x3F7FC5FC), PICA_CMD_DATA_VS_FLOAT(0x3D2C4F7C),
816
817 // 0x2C1 : 0x0
818 // 0x2C1 : 0x3F800000
819 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x3F800000),
820
821 // 0x2C1 : 0x0
822 // 0x2C1 : 0x0
823 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x0),
824
825 // 0x2C1 : 0x0, 0x5544
826 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x5544)
827 };
828
829 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
830 }
831
832 {
833 u32 commandBuffer[] =
834 {
835 // Vertex shader Boolean register
836 // 0x2B0 : 0x7FFF0000 (BE 0xF)
837 PICA_CMD_DATA_VS_BOOL(0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_BOOL),
838
839 // Vertex shader integer register i0
840 // 0x2B1 : 0x0 (BE 0xF)
841 PICA_CMD_DATA_VS_INT(0x0, 0x0, 0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_INT0),
842
843 // Vertex shader integer register i1
844 // 0x2B2 : 0x0 (BE 0xF)
845 PICA_CMD_DATA_VS_INT(0x0, 0x0, 0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_INT1),
846
847 // Vertex shader integer register i2
848 // 0x2B3 : 0x0 (BE 0xF)
849 PICA_CMD_DATA_VS_INT(0x0, 0x0, 0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_INT2),
850
851 // Vertex shader integer register i3
852 // 0x2B4 : 0x0 (BE 0xF)
853 PICA_CMD_DATA_VS_INT(0x0, 0x0, 0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_INT3)
854 };
855
856 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
857 }
858 }
859
AddTextureCombinerCommand(void)860 void AddTextureCombinerCommand(void)
861 {
862 {
863 u32 commandBuffer[] =
864 {
865 // 0xc0 + 0
866 // srcRgb, srcAlpha
867 // glUniform3i(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].srcRgb"), GL_PRIMARY_COLOR, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
868 // glUniform3i(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].srcAlpha"), GL_PRIMARY_COLOR, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
869 PICA_CMD_DATA_TEX_ENV_SRC(PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR, PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
870 PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR, PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
871 PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR, PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR),
872
873 // 0xc0
874 // Start register of texture combiner 0
875 PICA_CMD_HEADER_BURSTSEQ(PICA_REG_TEX_ENV0, 0x5),
876
877 // operandRgb, operandAlpha
878 // 0xc0 + 1
879 // glUniform3i(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
880 // glUniform3i(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
881 PICA_CMD_DATA_TEX_ENV_OPERAND(PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
882 PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA),
883
884 // combineRgb, combineAlpha
885 // 0xc0 + 2
886 // glUniform1i(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].combineRgb"), GL_REPLACE);
887 // glUniform1i(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
888 PICA_CMD_DATA_TEX_ENV_COMBINE(PICA_DATA_TEX_ENV_COMBINE_REPLACE, PICA_DATA_TEX_ENV_COMBINE_REPLACE),
889
890 // constRgba
891 // 0xc0 + 3
892 // glUniform4f(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].constRgba"), 0.0f, 0.0f, 0.0f, 0.0f);
893 PICA_CMD_DATA_TEX_ENV_CONST(0x0, 0x0, 0x0, 0x0),
894
895 // scaleRgb, scaleAlpha
896 // 0xc0 + 4
897 // glUniform1f(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].scaleRgb"), 1.0f);
898 // glUniform1f(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].scaleAlpha"), 1.0f);
899 PICA_CMD_DATA_TEX_ENV_SCALE(PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1)
900 };
901
902 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
903 }
904 }
905
906
AddDrawTriangleCommand(void)907 void AddDrawTriangleCommand(void)
908 {
909 AddFrameBufferControlCommand();
910
911 {
912 u32 commandBuffer[] =
913 {
914 // 0x229
915 // Using glDrawElements function and GL_TRIANGLES, so drawMode = 1
916 PICA_CMD_SET_DRAW_MODE0( 1 )
917 };
918
919 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
920 }
921
922 {
923 u32 commandBuffer[] =
924 {
925 // 0x253 [0:8]
926 // Using glDrawElements function and GL_TRIANGLES, so [8:8] = 1
927 0x100,
928 PICA_CMD_HEADER_SINGLE_BE( PICA_REG_DRAW_MODE1, 0x2 ),
929
930 // 0x25e [9:8]
931 // Using glDrawElements function and mode = GL_TRIANGLES, so [9:8] = PICA_DATA_DRAW_TRIANGLES = 3
932 PICA_CMD_SET_DRAW_MODE2( PICA_DATA_DRAW_TRIANGLES ),
933
934 // Clear the internal states of vertex indices when drawing triangles
935 // 0x25f
936 PICA_CMD_DATA_START_DRAW_FUNC1(0x1),
937 PICA_CMD_HEADER_SINGLE(PICA_REG_START_DRAW_FUNC1),
938
939 // 0x253[0:0] is set equal to 0 when nngxInitialize() is run, so this is unnecessary.
940 // 0x253 [0:0]
941 // Using vertex buffer and glDrawElements function, so [0:0] = 0
942 // PICA_CMD_DATA_DRAW_MODE1(0x0, 0x0),
943 // PICA_CMD_HEADER_SINGLE_BE(PICA_REG_DRAW_MODE1, 0x1),
944
945 // 0x227 [27:0]
946 // Vertex index address offset
947 // Vertex index type is GL_UNSIGNED_SHORT, so [31:31] = 1
948 PICA_CMD_DATA_INDEX_ARRAY_ADDR_OFFSET(s_VertexIndexAddressOffset, PICA_DATA_INDEX_ARRAY_UNSIGNED_SHORT),
949 PICA_CMD_HEADER_SINGLE(PICA_REG_INDEX_ARRAY_ADDR_OFFSET),
950
951 // 0x228 [31:0]
952 // Set the number of vertices to render: 3
953 s_IndexNum, PICA_CMD_HEADER_SINGLE(PICA_REG_DRAW_VERTEX_NUM),
954
955 // Render kick command macro
956 // 1. Set to 0 immediately before Draw
957 // 0x245 = 0x0
958 // 2. Render kick command
959 // 0x22f = Write 1 to any bit
960 // 3. Set to 1 immediately after Draw
961 // 0x245 = 0x1
962 // 4. Immediately after the render kick command, clear the vertex cache.
963 // 0x231 = 0x1
964 PICA_CMD_SET_START_DRAW_ELEMENT(1),
965
966 // Immediately after the render kick command, clear both color buffer and depth buffer caches.
967 PICA_CMD_SET_COLOR_DEPTH_BUFFER_CLEAR(0x1, 0x1),
968 };
969
970 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
971 }
972 }
973
AddFrameBufferControlCommand(void)974 void AddFrameBufferControlCommand(void)
975 {
976 {
977 u32 cmdbuf[] =
978 {
979 // Clear the color buffer and depth buffer caches.
980 PICA_CMD_SET_COLOR_DEPTH_BUFFER_CLEAR(0x1, 0x1),
981
982 // To disable color buffer read, set to 0
983 // 0x112 [3:0]
984 PICA_CMD_DATA_FRAME_BUFFER_MODE(0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_COLOR_BUFFER_READ),
985
986 // To enable color buffer write, set to 0xF.
987 // 0x113 [3:0]
988 PICA_CMD_DATA_FRAME_BUFFER_MODE(0xF), PICA_CMD_HEADER_SINGLE(PICA_REG_COLOR_BUFFER_WRITE),
989
990 // To enable depth buffer read, set [1:1] to 1.
991 // To disable stencil buffer read, set to [0:0] to 1.
992 // 0x114 [1:0]
993 PICA_CMD_DATA_FRAME_BUFFER_MODE(0x2), PICA_CMD_HEADER_SINGLE(PICA_REG_DEPTH_STENCIL_BUFFER_READ),
994
995 // To enable depth buffer write, set to [1:1] to 1.
996 // To enable stencil buffer write, set [0:0] to 1.
997 // 0x115 [1:0]
998 PICA_CMD_DATA_FRAME_BUFFER_MODE(0x2), PICA_CMD_HEADER_SINGLE(PICA_REG_DEPTH_STENCIL_BUFFER_WRITE),
999
1000 // Clear the color buffer and depth buffer caches.
1001 PICA_CMD_SET_COLOR_DEPTH_BUFFER_CLEAR(0x1, 0x1)
1002 };
1003
1004 nngxAdd3DCommand(cmdbuf, sizeof(cmdbuf), GL_TRUE);
1005 }
1006 }
1007
nnMain(void)1008 void nnMain(void)
1009 {
1010 // Call only nn::applet::Enable to also allow execution from the HOME Menu
1011 // HOME Menu transitions, POWER Button presses, and sleep are all unsupported
1012 nn::applet::Enable();
1013
1014 /* initialization */
1015 if (Initialize() >= 0)
1016 {
1017 while (1)
1018 {
1019 (void)DrawFrame();
1020 }
1021 }
1022
1023 if ( s_VertexArray != NULL )
1024 {
1025 demo::Free(s_VertexArray);
1026 s_VertexArray = NULL;
1027 }
1028
1029 if ( s_IndexArray != NULL )
1030 {
1031 demo::Free(s_IndexArray);
1032 s_IndexArray = NULL;
1033 }
1034
1035 nngxFinalize();
1036
1037 /* shutdown_display */
1038 s_AppHeap.Free(reinterpret_cast<void*>(s_HeapForGx));
1039 s_AppHeap.Finalize();
1040 }
1041