1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: gx_FragmentLightingSimpleCmd.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/os.h>
17 #include <nn/fnd.h>
18 #include <nn/gx.h>
19 #include <nn/math.h>
20 #include <nn/fs.h>
21 #include <nn/init.h>
22 #include <nn/applet.h>
23
24 #include "MemoryManager.h"
25
26 #include "nn/gx/CTR/gx_CommandAccess.h"
27
28 namespace
29 {
30 GLuint s_CmdlistID = 0;
31 GLuint s_FramebufferID = 0;
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 nn::fnd::ExpHeap s_AppHeap;
39 uptr s_HeapForGx;
40 const u32 s_GxHeapSize = 0x800000;
41
42 nn::math::Vector3 s_CameraPosition(0.0f, 1.0f, 4.0f);
43 nn::math::Vector3 s_CameraUp(0.0f, 1.0f, 0.0f);
44 nn::math::Vector3 s_CameraTarget(0.0f, 0.0f, 0.0f);
45
46 nn::math::Matrix34 s_ViewMatrix;
47
48 u32 s_MaterialShininess = 8;
49
50 GLuint s_ArrayBufferID = 0;
51 GLuint s_ElementArrayBufferID = 0;
52
53 GLfloat* s_VertexArray = NULL;
54 GLushort* s_IndexArray = NULL;
55
56 const u32 LUT_TABLE_SIZE = 512;
57 const u32 LUT_TABLE_HALF_SIZE = LUT_TABLE_SIZE / 2;
58 GLfloat s_LutArray[LUT_TABLE_SIZE];
59
60 u32 s_VertexAttributeBaseAddress = 0x0;
61 u32 s_VertexAttribute0AddressOffset = 0x0;
62 u32 s_VertexAttribute1AddressOffset = 0x0;
63 u32 s_VertexAttribute2AddressOffset = 0x0;
64 u32 s_VertexIndexAddressOffset = 0x0;
65 u32 s_VertexNum = 4;
66 u32 s_IndexNum = 6;
67
68 const u32 FRAME_COUNTER_THRE = 60;
69 u32 s_FrameCount = 0;
70 }
71
72 void InitializeGraphics(void);
73 void InitializeVBO(void);
74 void InitializeD0Lut(const u32 materialShininess);
75
76 void AddDepthBufferCommand(void);
77
78 void UpdateCamera(void);
79
80 void DrawDisplay0(void);
81 void DrawDisplay1(void);
82 void AddViewportCommand(const s32 display);
83
84 void AddFirstDrawCommand(void);
85 void AddVertexShaderCommand(void);
86 void AddVertexAttributeCommand(void);
87 void AddVertexShaderUniformCommand(void);
88 void AddTextureCombinerCommand(void);
89 void AddFragmentLightCommand(void);
90 void AddLUTCommand(void);
91
92 void AddDrawPlaneCommand(void);
93
94 void AddFrameBufferControlCommand(void);
95
Initialize(void)96 void Initialize(void)
97 {
98 // fs initialization
99 nn::fs::Initialize();
100
101 const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
102 static char buffer[ROMFS_BUFFER_SIZE];
103 NN_UTIL_PANIC_IF_FAILED(
104 nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
105
106 InitializeGraphics();
107 }
108
InitializeVBO(void)109 void InitializeVBO(void)
110 {
111 u32 positionSize = sizeof(GLfloat) * 4 * s_VertexNum;
112 u32 colorSize = sizeof(GLfloat) * 4 * s_VertexNum;
113 u32 normalSize = sizeof(GLfloat) * 3 * s_VertexNum;
114 u32 vertexSize = positionSize + colorSize + normalSize;
115 u32 indexSize = sizeof(GLushort) * s_IndexNum;
116
117 GLenum arrayFlag = GL_ARRAY_BUFFER | NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP;
118 GLenum elementArrayFlag = GL_ELEMENT_ARRAY_BUFFER | NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP;
119
120 s_VertexArray = (GLfloat*) demo::memory_manager::Alloc(NN_GX_MEM_VERTEXBUFFER, vertexSize);
121
122 u32 vertexArrayPhysicalAddress = nngxGetPhysicalAddr( (uptr) s_VertexArray );
123 // NN_LOG("s_VertexArray = 0x%x, Physical address = 0x%p\n", s_VertexArray, vertexArrayPhysicalAddress);
124
125 f32 s_HalfEdge = 2.0f;
126
127 // Position
128 s_VertexArray[0] = s_HalfEdge;
129 s_VertexArray[1] = 0.0f;
130 s_VertexArray[2] = s_HalfEdge;
131 s_VertexArray[3] = 1.0f;
132
133 s_VertexArray[4] = (- s_HalfEdge);
134 s_VertexArray[5] = 0.0f;
135 s_VertexArray[6] = s_HalfEdge;
136 s_VertexArray[7] = 1.0f;
137
138 s_VertexArray[8] = (- s_HalfEdge);
139 s_VertexArray[9] = 0.0f;
140 s_VertexArray[10] = (- s_HalfEdge);
141 s_VertexArray[11] = 1.0f;
142
143 s_VertexArray[12] = s_HalfEdge;
144 s_VertexArray[13] = 0.0f;
145 s_VertexArray[14] = (- s_HalfEdge);
146 s_VertexArray[15] = 1.0f;
147
148 // Color
149 u32 offset = 4 * s_VertexNum;
150 s_VertexArray[offset + 0] = 1.0f;
151 s_VertexArray[offset + 1] = 0.0f;
152 s_VertexArray[offset + 2] = 0.0f;
153 s_VertexArray[offset + 3] = 0.0f;
154
155 s_VertexArray[offset + 4] = 0.0f;
156 s_VertexArray[offset + 5] = 1.0f;
157 s_VertexArray[offset + 6] = 0.0f;
158 s_VertexArray[offset + 7] = 0.0f;
159
160 s_VertexArray[offset + 8] = 0.0f;
161 s_VertexArray[offset + 9] = 0.0f;
162 s_VertexArray[offset + 10] = 1.0f;
163 s_VertexArray[offset + 11] = 1.0f;
164
165 s_VertexArray[offset + 12] = 1.0f;
166 s_VertexArray[offset + 13] = 1.0f;
167 s_VertexArray[offset + 14] = 0.0f;
168 s_VertexArray[offset + 15] = 1.0f;
169
170 // Normal
171 offset += 16;
172
173 s_VertexArray[offset + 0] = 0.0f;
174 s_VertexArray[offset + 1] = 1.0f;
175 s_VertexArray[offset + 2] = 0.0f;
176
177 s_VertexArray[offset + 3] = 0.0f;
178 s_VertexArray[offset + 4] = 1.0f;
179 s_VertexArray[offset + 5] = 0.0f;
180
181 s_VertexArray[offset + 6] = 0.0f;
182 s_VertexArray[offset + 7] = 1.0f;
183 s_VertexArray[offset + 8] = 0.0f;
184
185 s_VertexArray[offset + 9] = 0.0f;
186 s_VertexArray[offset + 10] = 1.0f;
187 s_VertexArray[offset + 11] = 0.0f;
188
189 s_IndexArray = (GLushort*) demo::memory_manager::Alloc(NN_GX_MEM_VERTEXBUFFER, indexSize);
190
191 u32 indexArrayPhysicalAddress = nngxGetPhysicalAddr( (uptr) s_IndexArray);
192 // NN_LOG("s_IndexArray = 0x%x, physical address = 0x%p\n", s_IndexArray, indexArrayPhysicalAddress);
193
194 // Index
195 s_IndexArray[0] = 0;
196 s_IndexArray[1] = 2;
197 s_IndexArray[2] = 1;
198
199 s_IndexArray[3] = 0;
200 s_IndexArray[4] = 3;
201 s_IndexArray[5] = 2;
202
203 glGenBuffers(1, &s_ArrayBufferID);
204 glBindBuffer(GL_ARRAY_BUFFER, s_ArrayBufferID);
205 glBufferData(arrayFlag, vertexSize, s_VertexArray, GL_STATIC_DRAW);
206
207 glGenBuffers(1, &s_ElementArrayBufferID);
208 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_ElementArrayBufferID);
209 glBufferData(elementArrayFlag, indexSize, s_IndexArray, GL_STATIC_DRAW);
210
211 // Base address is aligned to 16 bytes
212 u32 alignOffset = (uptr)vertexArrayPhysicalAddress % 16;
213 u32 baseAddress = vertexArrayPhysicalAddress - alignOffset;
214
215 s_VertexAttributeBaseAddress = PICA_CMD_DATA_VERTEX_ATTR_ARRAYS_BASE_ADDR(baseAddress);
216 s_VertexAttribute0AddressOffset = vertexArrayPhysicalAddress - baseAddress;
217 s_VertexAttribute1AddressOffset = alignOffset + positionSize;
218 s_VertexAttribute2AddressOffset = alignOffset + positionSize + colorSize;
219 s_VertexIndexAddressOffset = indexArrayPhysicalAddress - baseAddress;
220 }
221
InitializeGraphics(void)222 void InitializeGraphics(void)
223 {
224 s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(),
225 nn::os::GetDeviceMemorySize() );
226 s_HeapForGx = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_GxHeapSize));
227
228 demo::memory_manager::InitializeMemoryManager(s_HeapForGx, s_GxHeapSize);
229 nngxInitialize(demo::memory_manager::GetAllocator, demo::memory_manager::GetDeallocator);
230
231 /* Generate and allocate command list object */
232 nngxGenCmdlists(1, &s_CmdlistID);
233 nngxBindCmdlist(s_CmdlistID);
234 nngxCmdlistStorage(0x40000, 128);
235
236 /* Generate, allocate and attach framebuffer object and render buffer */
237 glGenFramebuffers(1, &s_FramebufferID);
238 glBindFramebuffer(GL_FRAMEBUFFER, s_FramebufferID);
239
240 glGenRenderbuffers(2, s_RenderbufferID);
241 glBindRenderbuffer(GL_RENDERBUFFER, s_RenderbufferID[0]);
242 glRenderbufferStorage(GL_RENDERBUFFER | NN_GX_MEM_VRAMA, GL_RGBA8_OES,
243 nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT);
244 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, s_RenderbufferID[0]);
245
246 glBindRenderbuffer(GL_RENDERBUFFER, s_RenderbufferID[1]);
247 glRenderbufferStorage(GL_RENDERBUFFER | NN_GX_MEM_VRAMB, GL_DEPTH24_STENCIL8_EXT,
248 nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT);
249 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, s_RenderbufferID[1]);
250
251 /* Generate and allocate display buffer; set display region */
252 nngxGenDisplaybuffers(2, s_Displaybuffer0ID);
253 nngxActiveDisplay(NN_GX_DISPLAY0);
254 nngxDisplayEnv(0, 0);
255 nngxBindDisplaybuffer(s_Displaybuffer0ID[0]);
256 nngxDisplaybufferStorage(GL_RGB8_OES, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT, NN_GX_MEM_FCRAM);
257
258 nngxBindDisplaybuffer(s_Displaybuffer0ID[1]);
259 nngxDisplaybufferStorage(GL_RGB8_OES, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT, NN_GX_MEM_FCRAM);
260
261 nngxGenDisplaybuffers(2, s_Displaybuffer1ID);
262 nngxActiveDisplay(NN_GX_DISPLAY1);
263 nngxDisplayEnv(0, 0);
264 nngxBindDisplaybuffer(s_Displaybuffer1ID[0]);
265 nngxDisplaybufferStorage(GL_RGB8_OES, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT, NN_GX_MEM_FCRAM);
266
267 nngxBindDisplaybuffer(s_Displaybuffer1ID[1]);
268 nngxDisplaybufferStorage(GL_RGB8_OES, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT, NN_GX_MEM_FCRAM);
269
270 nngxRunCmdlist();
271
272 glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
273 glClearDepthf(1.0f);
274
275 AddDepthBufferCommand();
276
277 glEnable(GL_CULL_FACE);
278 glFrontFace(GL_CCW);
279 glCullFace(GL_BACK);
280
281 InitializeD0Lut(s_MaterialShininess);
282 InitializeVBO();
283 }
284
285
AddDepthBufferCommand(void)286 void AddDepthBufferCommand(void)
287 {
288 /*
289 glEnable(GL_DEPTH_TEST);
290 glDepthFunc(GL_LESS);
291 */
292
293 u32 commandBuffer[] =
294 {
295 // Depth test
296 // 0x107
297 PICA_CMD_DATA_DEPTH_COLOR_MASK(
298 // enableDepthTest
299 1,
300 // depthFunc
301 PICA_DATA_DEPTH_TEST_LESS,
302 // red, green, blue, alpha
303 0, 0, 0, 0,
304 // depthMask
305 0),
306 PICA_CMD_HEADER_SINGLE_BE(PICA_REG_DEPTH_COLOR_MASK, 0x1),
307
308 // dmp_Gas.deltaZ
309 // 0x126 [25:24]
310 PICA_CMD_DATA_GAS_DELTAZ_DEPTH(0, PICA_DATA_DEPTH_TEST2_OTHER),
311 PICA_CMD_HEADER_SINGLE_BE(PICA_REG_GAS_DELTAZ_DEPTH, 0x8),
312 };
313
314 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
315 }
316
AddViewportCommand(s32 display)317 void AddViewportCommand(s32 display)
318 {
319 if ( display == NN_GX_DISPLAY0 )
320 {
321 // glViewport(0, 0, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT);
322 u32 commandBuffer[] =
323 {
324 // Set the Viewport width (set width to f32, divide by two, and convert to f24)
325 // 0x41
326 0x45E000, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_WIDTH1),
327
328 // Set the Viewport height (set height to f32, divide by two, and convert to f24)
329 // 0x43
330 0x469000, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_HEIGHT1),
331
332 // Set Viewport width (Divide 2 by width, convert to f31, and shift 1 bit left)
333 // 0x42
334 0x38111111, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_WIDTH2),
335
336 // Set Viewport height (Divide 2 by height, convert to f31, and shift 1 bit left)
337 // 0x44
338 0x3747AE14, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_HEIGHT2),
339
340 // x = 0, y = 0
341 // 0x68
342 PICA_CMD_DATA_VIEWPORT_XY(0, 0), PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_XY)
343 };
344
345 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
346 }
347 else if ( display == NN_GX_DISPLAY1 )
348 {
349 // glViewport(0, 0, nn::gx::DISPLAY1_WIDTH, nn::gx::DISPLAY1_HEIGHT);
350 u32 commandBuffer[] =
351 {
352 // Set the Viewport width (set width to f32, divide by two, and convert to f24)
353 // 0x41
354 0x45E000, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_WIDTH1),
355
356 // Set the Viewport height (set height to f32, divide by two, and convert to f24)
357 // 0x43
358 0x464000, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_HEIGHT1),
359
360 // Set Viewport width (Divide 2 by width, convert to f31, and shift 1 bit left)
361 // 0x42
362 0x38111111, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_WIDTH2),
363
364 // Set Viewport height (Divide 2 by height, convert to f31, and shift 1 bit left)
365 // 0x44
366 0x37999999, PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_HEIGHT2),
367
368 // x = 0, y = 0
369 // 0x68
370 PICA_CMD_DATA_VIEWPORT_XY(0, 0), PICA_CMD_HEADER_SINGLE(PICA_REG_VIEWPORT_XY)
371 };
372
373 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
374 }
375 }
376
InitializeD0Lut(const u32 materialShininess)377 void InitializeD0Lut(const u32 materialShininess)
378 {
379 for (u32 index = 0; index < LUT_TABLE_SIZE; index++)
380 {
381 s_LutArray[index] = 0.0f;
382 }
383
384 for (u32 j = 0; j < LUT_TABLE_HALF_SIZE; j++)
385 {
386 f32 value = 1.0f;
387 for (u32 count = 0; count < materialShininess; count++)
388 {
389 value *= (j / 255.0f);
390 }
391 s_LutArray[j] = value;
392 }
393
394 for (u32 j = 0; j < (LUT_TABLE_HALF_SIZE - 1); j++)
395 {
396 s_LutArray[j + LUT_TABLE_HALF_SIZE] = s_LutArray[j + 1] - s_LutArray[j];
397 }
398 s_LutArray[(LUT_TABLE_HALF_SIZE - 1) + LUT_TABLE_HALF_SIZE] =
399 1.0f - s_LutArray[LUT_TABLE_HALF_SIZE - 1];
400 }
401
Finalize(void)402 void Finalize(void)
403 {
404 if ( s_VertexArray != NULL )
405 {
406 demo::memory_manager::Free(s_VertexArray);
407 s_VertexArray = NULL;
408 }
409
410 if ( s_IndexArray != NULL )
411 {
412 demo::memory_manager::Free(s_IndexArray);
413 s_IndexArray = NULL;
414 }
415
416 nngxFinalize();
417
418 s_AppHeap.Free(reinterpret_cast<void*>( s_HeapForGx) );
419 s_AppHeap.Finalize();
420 }
421
DrawFrame(void)422 bool DrawFrame(void)
423 {
424 UpdateCamera();
425
426 DrawDisplay0();
427 DrawDisplay1();
428
429 nngxActiveDisplay(NN_GX_DISPLAY0);
430 nngxBindDisplaybuffer(s_Displaybuffer0ID[s_CurrentDisplaybuffer0]);
431
432 nngxActiveDisplay(NN_GX_DISPLAY1);
433 nngxBindDisplaybuffer(s_Displaybuffer1ID[s_CurrentDisplaybuffer1]);
434
435 nngxSwapBuffers(NN_GX_DISPLAY_BOTH);
436
437 s_CurrentDisplaybuffer0 = (s_CurrentDisplaybuffer0 == 0 ? 1 : 0);
438 s_CurrentDisplaybuffer1 = (s_CurrentDisplaybuffer1 == 0 ? 1 : 0);
439
440 nngxClearCmdlist();
441 nngxRunCmdlist();
442
443 nngxWaitVSync(NN_GX_DISPLAY_BOTH);
444
445 if ( s_FrameCount == 0 )
446 {
447 nngxStartLcdDisplay();
448 }
449
450 if ( ( s_FrameCount % FRAME_COUNTER_THRE) == 0 )
451 {
452 NN_LOG("Total frame count = %d\n", s_FrameCount);
453 }
454
455 s_FrameCount += 1;
456
457 return true;
458 }
459
UpdateCamera(void)460 void UpdateCamera(void)
461 {
462 nn::math::MTX34LookAt(&s_ViewMatrix, s_CameraPosition, s_CameraUp, s_CameraTarget);
463 }
464
DrawDisplay0(void)465 void DrawDisplay0(void)
466 {
467 static bool firstFlag = true;
468
469 glBindFramebuffer(GL_FRAMEBUFFER, s_FramebufferID);
470 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
471 AddViewportCommand(NN_GX_DISPLAY0);
472
473 if ( firstFlag )
474 {
475 AddFirstDrawCommand();
476 firstFlag = false;
477 }
478
479 AddDrawPlaneCommand();
480
481 nngxSplitDrawCmdlist();
482 nngxRunCmdlist();
483 nngxWaitCmdlistDone();
484
485 nngxTransferRenderImage(s_Displaybuffer0ID[s_CurrentDisplaybuffer0], NN_GX_ANTIALIASE_NOT_USED, GL_FALSE, 0, 0);
486 }
487
AddFirstDrawCommand(void)488 void AddFirstDrawCommand(void)
489 {
490 AddVertexShaderCommand();
491 AddVertexAttributeCommand();
492 AddVertexShaderUniformCommand();
493
494 AddFragmentLightCommand();
495 AddLUTCommand();
496 }
497
498
AddVertexShaderCommand(void)499 void AddVertexShaderCommand(void)
500 {
501 /*
502 s_ProgramId = glCreateProgram();
503
504 // Load vertex shader
505 s_ShaderId = glCreateShader(GL_VERTEX_SHADER);
506 nn::fs::FileReader file(L"rom:/shader.shbin");
507 size_t fileSize = file.GetSize();
508 void* buf = s_AppHeap.Allocate(fileSize);
509 s32 read = file.Read(buf, fileSize);
510 glShaderBinary(1, &s_ShaderId, GL_PLATFORM_BINARY_DMP, buf, read);
511 file.Finalize();
512 s_AppHeap.Free(buf);
513
514 glAttachShader(s_ProgramId, s_ShaderId);
515 glAttachShader(s_ProgramId, GL_DMP_FRAGMENT_SHADER_DMP);
516
517 glBindAttribLocation(s_ProgramId, 0, "aPosition");
518 glBindAttribLocation(s_ProgramId, 1, "aColor");
519 glBindAttribLocation(s_ProgramId, 2, "aNormal");
520
521 glLinkProgram(s_ProgramId);
522 glValidateProgram(s_ProgramId);
523 */
524
525 {
526 u32 commandBuffer[] =
527 {
528 // 0x229
529 // Do not use geometry shader
530 PICA_CMD_SET_VS_GS_MODE(0, 0),
531 // Do not use geometry shader
532 // 0x244 : 0x0 (BE 0x1)
533 PICA_CMD_SET_VS_COM_MODE(0x0),
534 // Set the load address for the vertex shader program code to 0
535 // 0x2CB : 0x0 (BE 0xF)
536 PICA_CMD_DATA_VS_PROG_ADDR(0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_PROG_ADDR)
537 };
538
539 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
540 }
541
542 {
543 u32 commandBuffer[] =
544 {
545 // Vertex shader program data
546 // BurstSingle (28 times, BE 0xF)
547 // 0x2CC : 0xBE24000
548 0xBE24000, PICA_CMD_HEADER_BURST(PICA_REG_VS_PROG_DATA0, 28),
549
550 // 0x2CC : 0xBE25001
551 // 0x2CC : 0xBE26002
552 0xBE25001, 0xBE26002,
553
554 // 0x2CC : 0xBE27003
555 // 0x2CC : 0x7C26102
556 0xBE27003, 0x7C26102,
557
558 // 0x2CC : 0x7C24100
559 // 0x2CC : 0x7C25101
560 0x7C24100, 0x7C25101,
561
562 // 0x2CC : 0x4C41F004
563 // 0x2CC : 0x8020F80
564 0x4C41F004, 0x8020F80,
565
566 // 0x2CC : 0x8021F81
567 // 0x2CC : 0xB807DF05
568 0x8021F81, 0xB807DF05,
569
570 // 0x2CC : 0x287DF06
571 // 0x2CC : 0x8022F82
572 0x287DF06, 0x8022F82,
573
574 // 0x2CC : 0x8023F83
575 // 0x2CC : 0x2287EA07
576 0x8023F83, 0x2287EA07,
577
578 // 0x2CC : 0x4C27D008
579 // 0x2CC : 0x3E814009
580 0x4C27D008, 0x3E814009,
581
582 // 0x2CC : 0x22A7EF07
583 // 0x2CC : 0xA1805401
584 0x22A7EF07, 0xA1805401,
585
586 // 0x2CC : 0x3821400A
587 // 0x2CC : 0x20215A0B
588 0x3821400A, 0x20215A0B,
589
590 // 0x2CC : 0x4C27D00C
591 // 0x2CC : 0x84000000
592 0x4C27D00C, 0x84000000,
593
594 // 0x2CC : 0x84000000
595 // 0x2CC : 0x90000017
596 0x84000000, 0x90000017,
597
598 // 0x2CC : 0x4C60100D
599 // 0x2CC : 0x88000000
600 0x4C60100D, 0x88000000,
601
602 // 0x2CC : 0x84000000
603 0x84000000, 0x0
604 };
605
606 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
607 }
608
609 {
610 u32 commandBuffer[] =
611 {
612 // Notification that update of vertex shader program is complete
613 // 0x2BF : 0x1 (BE 0xF)
614 PICA_CMD_DATA_VS_PROG_END(0x1), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_PROG_UPDATE_END)
615 };
616
617 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
618 }
619
620 {
621 u32 commandBuffer[] =
622 {
623 // Set the Swizzle pattern's load address to 0
624 // 0x2D5 : 0x0 (BE 0xF)
625 PICA_CMD_DATA_VS_PROG_SWIZZLE_ADDR(0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_PROG_SWIZZLE_ADDR),
626
627 // Set the Swizzle pattern's data
628 // BurstSingle (14 times, BE 0xF)
629 // 0x2D6 : 0x8006C368
630 PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8006C368), PICA_CMD_HEADER_BURST(PICA_REG_VS_PROG_SWIZZLE_DATA0, 14),
631
632 // 0x2D6 : 0x8006C364
633 // 0x2D6 : 0x8006C362
634 PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8006C364), PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8006C362),
635
636 // 0x2D6 : 0x8006C361
637 // 0x2D6 : 0x8000037F
638 PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8006C361), PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8000037F),
639
640 // 0x2D6 : 0x802A8AB0
641 // 0x2D6 : 0x802A8AAF
642 PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x802A8AB0), PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x802A8AAF),
643
644 // 0x2D6 : 0x8006D54F
645 // 0x2D6 : 0x80000001
646 PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8006D54F), PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x80000001),
647
648 // 0x2D6 : 0x8000000F
649 // 0x2D6 : 0x80000002
650 PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8000000F), PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x80000002),
651
652 // 0x2D6 : 0x8006C36C
653 // 0x2D6 : 0x8000080E
654 PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8006C36C), PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8000080E),
655
656 // 0x2D6 : 0x8000036F
657 PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x8000036F), PICA_CMD_DATA_VS_PROG_SWIZZLE_DATA(0x0),
658 };
659
660 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
661 }
662
663 {
664 u32 commandBuffer[] =
665 {
666 // BurstSequence (4 times, BE 0xF)
667 // 0x2C0 : 0x5D
668 PICA_CMD_DATA_VS_FLOAT_ADDR(PICA_DATA_VS_F24, 0x5D),
669 PICA_CMD_HEADER_BURSTSEQ(PICA_REG_VS_FLOAT_ADDR, 0x4),
670
671 // 0x2C1 : 0x40800040
672 // 0x2C2 : 0x3F00
673 PICA_CMD_DATA_VS_FLOAT_DATA(0x40800040), PICA_CMD_DATA_VS_FLOAT_DATA(0x3F00),
674
675 // 0x2C3 : 0x0
676 PICA_CMD_DATA_VS_FLOAT_DATA(0x0), PICA_CMD_DATA_VS_FLOAT_DATA(0x0)
677 };
678
679 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
680 }
681
682 {
683 u32 commandBuffer[] =
684 {
685 // BurstSequence (4 times, BE 0xF)
686 // 0x2C0 : 0x5E
687 PICA_CMD_DATA_VS_FLOAT_ADDR(PICA_DATA_VS_F24, 0x5E),
688 PICA_CMD_HEADER_BURSTSEQ(PICA_REG_VS_FLOAT_ADDR, 0x4),
689
690 // 0x2C1 : 0x3D00003E
691 // 0x2C2 : 0x3700
692 PICA_CMD_DATA_VS_FLOAT_DATA(0x3D00003E), PICA_CMD_DATA_VS_FLOAT_DATA(0x3700),
693
694 // 0x2C3 : 0x3C0000
695 PICA_CMD_DATA_VS_FLOAT_DATA(0x3C0000), PICA_CMD_DATA_VS_FLOAT_DATA(0x0)
696 };
697
698 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
699 }
700 }
701
AddVertexAttributeCommand(void)702 void AddVertexAttributeCommand(void)
703 {
704 {
705 u32 commandBuffer[] =
706 {
707 // BurstSequence (39 times, BE 0xF)
708
709 // Common base address for all vertex arrays
710 // 0x200 : BaseAddress
711 s_VertexAttributeBaseAddress, PICA_CMD_HEADER_BURSTSEQ(PICA_REG_VERTEX_ATTR_ARRAYS_BASE_ADDR, 39),
712
713 // 0x201 : 0xBFF
714 // Attribute0 [3:0] 0xF : size=4, GL_FLOAT
715 // Attribute1 [7:4] 0xF : size=4, GL_FLOAT
716 // Attribute1 [11:8] 0xB : size=3, GL_FLOAT
717 //
718 // 0x202 : 0x20000000
719 // [31:28] TotalVertexAttributeNum - 1
720 0xBFF, 0x20000000,
721
722 // 0x203 : 0x8
723 // Byte offset from the the base address of load array 0
724 //
725 // 0x204 : 0x0
726 // [3:0] The 1st element of load array 0 is internal vertex attribute 0
727 s_VertexAttribute0AddressOffset, 0x0,
728
729 // 0x205 : 0x10100000
730 // [23:16] : Number of bytes per vertex in load array 0: 16 (Bytes)
731 // [31:28] : Number of elements in load array 0: 1
732 //
733 // 0x206 : 0x30
734 // Byte offset from the the base address of load array 1
735 0x10100000, s_VertexAttribute1AddressOffset,
736
737 // 0x207 : 0x1
738 // [3:0] The 1st element of load array 1 is internal vertex attribute 1
739 //
740 // 0x208 : 0x10100000
741 // [23:16] : Number of bytes per vertex in load array 1: 16 (Bytes)
742 // [31:28] : Number of elements in load array 1: 1
743 0x1, 0x10100000,
744
745 // 0x209 : 0x88
746 // 0x20A : 0x2 internal vertex attribute 2
747 s_VertexAttribute2AddressOffset, 0x2,
748
749 // 0x20B : 0x100C0000
750 // [23:16] : Number of bytes per vertex in load array 1: 12 (Bytes)
751 // [31:28] : Number of elements in load array 1: 1
752 // 0x20C : 0x0
753 0x100C0000, 0x0,
754
755 // 0x20D : 0x0
756 // 0x20E : 0x0
757 0x0, 0x0,
758
759 // 0x20F : 0x0
760 // 0x210 : 0x0
761 0x0, 0x0,
762
763 // 0x211 : 0x0
764 // 0x212 : 0x0
765 0x0, 0x0,
766
767 // 0x213 : 0x0
768 // 0x214 : 0x0
769 0x0, 0x0,
770
771 // 0x215 : 0x0
772 // 0x216 : 0x0
773 0x0, 0x0,
774
775 // 0x217 : 0x0
776 // 0x218 : 0x0
777 0x0, 0x0,
778
779 // 0x219 : 0x0
780 // 0x21A : 0x0
781 0x0, 0x0,
782
783 // 0x21B : 0x0
784 // 0x21C : 0x0
785 0x0, 0x0,
786
787 // 0x21D : 0x0
788 // 0x21E : 0x0
789 0x0, 0x0,
790
791 // 0x21F : 0x0
792 // 0x220 : 0x0
793 0x0, 0x0,
794
795 // 0x221 : 0x0
796 // 0x222 : 0x0
797 0x0, 0x0,
798
799 // 0x223 : 0x0
800 // 0x224 : 0x0
801 0x0, 0x0,
802
803 // 0x225 : 0x0
804 // 0x226 : 0x0
805 0x0, 0x0
806 };
807
808 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
809 }
810
811 {
812 u32 commandBuffer[] =
813 {
814 // 0x2BB : 0x210 (BE 0xF)
815 // Register that sets the input register map for vertex attributes 0-8
816 // [3:0] = 0 (The index of the input register for the storage location of the first vertex attribute that was input)
817 // [7:4] = 1 (The index of the input register for the storage location of the second vertex attribute that was input)
818 // [11:8] = 2 (The index of the input register for the storage location of the third vertex attribute that was input)
819 PICA_CMD_DATA_VS_ATTR_IN_REG_MAP0(0, 1, 2, 0, 0, 0, 0, 0),
820 PICA_CMD_HEADER_SINGLE(PICA_REG_VS_ATTR_IN_REG_MAP0),
821
822 // 0x2BC : 0x0 (BE 0xF)
823 // Register that sets the input register map for vertex attributes 9-12
824 PICA_CMD_DATA_VS_ATTR_IN_REG_MAP1(0, 0, 0, 0),
825 PICA_CMD_HEADER_SINGLE(PICA_REG_VS_ATTR_IN_REG_MAP1)
826 };
827
828 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
829 }
830
831 /*
832 glEnableVertexAttribArray(0);
833 glEnableVertexAttribArray(1);
834 glEnableVertexAttribArray(2);
835
836 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0) ;
837 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*) positionSize);
838 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*) (positionSize + colorSize) );
839 */
840 {
841 u32 commandBuffer[] =
842 {
843 // Register that sets the number of vertex attribute inputs.
844 //
845 // 0x2B9 : 0xA0000000 | 0x2 (BE 0xB = 1011(2) )
846 // PICA_CMD_DATA_VS_ATTR_NUM0(0x3), PICA_CMD_HEADER_SINGLE_BE(PICA_REG_VS_ATTR_NUM0, 0xB),
847 //
848 // 0x242 : 0x2 (BE 0xF)
849 // PICA_CMD_DATA_VS_ATTR_NUM1(0x3), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_ATTR_NUM1)
850 PICA_CMD_SET_VS_ATTR_NUM(0x3),
851
852 // Register that sets the number of vertex attributes to input to the vertex shader
853 //
854 // 0x4F : 0x4
855 // 0x4, PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_REG_NUM0)
856 //
857 // 0x24A : 0x3 (BE 0xF)
858 // 0x4 - 0x1, PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_REG_NUM1),
859 //
860 // 0x251 [3:0] : 0x3 (BE 0xF)
861 // 0x4 - 0x1, PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_REG_NUM2),
862 PICA_CMD_SET_VS_GS_OUT_REG_NUM(0x4),
863
864 // 0x2BA [15:0] : Sets the data address of the vertex shader
865 // [31:16] : Sets 0x7FFF
866 // 0x7FFF0018 (BE 0xF)
867 PICA_CMD_DATA_VS_START_ADDR(0x18), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_START_ADDR),
868
869 // 0x2BD : 0x3 (BE 0xF)
870 // Set the mask for the vertex shader output register (o0 = [0:0], o1 = [1;1])
871 PICA_CMD_DATA_VS_OUT_MASK(0xF), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_REG_MASK),
872
873 // Register that sets the vertex shader output attribute
874 // 0x50 : 0x3020100 (BE 0xF)
875 // #pragma output_map ( position, o0 )
876 // [ 4: 0] : Vertex coordinate x, 0x00
877 // [12: 8] : Vertex coordinate y, 0x01
878 // [20:16] : Vertex coordinate z, 0x02
879 // [28:24] : Vertex coordinate w, 0x03
880 PICA_CMD_DATA_VS_GS_OUT_ATTR(PICA_DATA_VS_OUT_ATTR_X,
881 PICA_DATA_VS_OUT_ATTR_Y, PICA_DATA_VS_OUT_ATTR_Z,
882 PICA_DATA_VS_OUT_ATTR_W),
883 PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_ATTR0),
884
885 // Register that sets the vertex shader output attribute
886 // 0x51 : 0x7060504 (BE 0xF)
887 // #pragma output_map ( quaternion, o1 )
888 // [ 4: 0] : Quaternion x, 0x04
889 // [12: 8] : Quaternion y, 0x05
890 // [20:16] : Quaternion z, 0x06
891 // [28:24] : Quaternion w, 0x07
892 PICA_CMD_DATA_VS_GS_OUT_ATTR(PICA_DATA_VS_OUT_ATTR_QUART_X,
893 PICA_DATA_VS_OUT_ATTR_QUART_Y, PICA_DATA_VS_OUT_ATTR_QUART_Z,
894 PICA_DATA_VS_OUT_ATTR_QUART_W),
895 PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_ATTR1),
896
897 // Register that sets the vertex shader output attribute
898 // 0x52 : 0x1F141312
899 // #pragma output_map ( view, o2 )
900 // [ 4: 0] : View vector x, 0x12
901 // [12: 8] : View vector y, 0x13
902 // [20:16] : View vector z, 0x14
903 // [28:24] : Invalid, 0x1f
904 PICA_CMD_DATA_VS_GS_OUT_ATTR(PICA_DATA_VS_OUT_ATTR_VIEW_X,
905 PICA_DATA_VS_OUT_ATTR_VIEW_Y, PICA_DATA_VS_OUT_ATTR_VIEW_Z,
906 PICA_DATA_VS_OUT_ATTR_INVALID),
907 PICA_CMD_HEADER_SINGLE(0x52),
908
909 // 0x53 : 0xB0A0908
910 // #pragma output_map ( color, o3 )
911 // [ 4: 0] : Vertex color R, 0x08
912 // [12: 8] : Vertex color G, 0x09
913 // [20:16] : Vertex color B, 0x0a
914 // [28:24] : Vertex color A, 0x0b
915 PICA_CMD_DATA_VS_GS_OUT_ATTR(PICA_DATA_VS_OUT_ATTR_R,
916 PICA_DATA_VS_OUT_ATTR_G, PICA_DATA_VS_OUT_ATTR_B,
917 PICA_DATA_VS_OUT_ATTR_A),
918 PICA_CMD_HEADER_SINGLE(0x53),
919
920 // Clock control setting register for output attributes from the vertex shader
921 // 0x6F : 0x1000003 (BE 0xF)
922 // Output vertex coordinates z, output vertex colors, output view vectors, and quaternions
923 //
924 PICA_CMD_DATA_VS_GS_OUT_ATTR_CLK(1, 1, 0, 0, 0, 0, 1), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_OUT_ATTR_CLK)
925 };
926
927 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
928 }
929 }
930
AddVertexShaderUniformCommand(void)931 void AddVertexShaderUniformCommand(void)
932 {
933 /*
934 // Upper screen vertex uniform settings
935 nn::math::Matrix44 s_Display0ProjectionMatrix;
936 nn::math::Matrix44 s_Display1ProjectionMatrix;
937
938 nn::math::MTX34LookAt(&s_ViewMatrix, s_CameraPosition, s_CameraUp, s_CameraTarget);
939 nn::math::MTX44 modelViewMatrix(s_ViewMatrix);
940
941 nn::math::Matrix44 worldMatrix;
942 MTX44Identity(&worldMatrix);
943 nn::math::MTX44Mult(&modelViewMatrix, &modelViewMatrix, &worldMatrix);
944
945 glUniformMatrix4fv(demo::s_UniformLocations[demo::VERTEX_UNIFORM_MODELVIEW],
946 1, GL_TRUE, static_cast<f32*>(modelViewMatrix));
947
948 glUniformMatrix4fv(demo::s_UniformLocations[demo::VERTEX_UNIFORM_PROJECTION],
949 1, GL_TRUE, static_cast<f32*>(s_Display0ProjectionMatrix));
950 */
951
952 {
953 u32 commandBuffer[] =
954 {
955 // Index of floating-point registers for vertex shader
956 // 0x2C0 : 0x80000000 (BE 0xF)
957 PICA_CMD_DATA_VS_FLOAT_ADDR(PICA_DATA_VS_F32, 0x0),
958 PICA_CMD_HEADER_SINGLE(PICA_REG_VS_FLOAT_ADDR)
959 };
960
961 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
962 }
963
964 {
965 u32 commandBuffer[] =
966 {
967 // Settings for floating-point registers of the vertex shader
968 // BurstSingle (32 times, BE 0xF)
969 // 0x2C1 : 0x0
970 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_HEADER_BURST(PICA_REG_VS_FLOAT1, 32),
971
972 // 0x2C1 : 0x0
973 // 0x2C1 : 0x401A8279
974 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x401A8279),
975
976 // 0x2C1 : 0x0
977 // 0x2C1 : 0x80000000
978 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x80000000),
979
980 // 0x2C1 : 0x80000000
981 // 0x2C1 : 0x80000000
982 PICA_CMD_DATA_VS_FLOAT(0x80000000), PICA_CMD_DATA_VS_FLOAT(0x80000000),
983
984 // 0x2C1 : 0xBFB9695E
985 // 0x2C1 : 0x3DCDD443
986 PICA_CMD_DATA_VS_FLOAT(0xBFB9695E), PICA_CMD_DATA_VS_FLOAT(0x3DCDD443),
987
988 // 0x2C1 : 0x3F80A4AA
989 // 0x2C1 : 0x0
990 PICA_CMD_DATA_VS_FLOAT(0x3F80A4AA), PICA_CMD_DATA_VS_FLOAT(0x0),
991
992 // 0x2C1 : 0x0
993 // 0x2C1 : 0x0
994 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x0),
995
996 // 0x2C1 : 0xBF800000
997 // 0x2C1 : 0x0
998 PICA_CMD_DATA_VS_FLOAT(0xBF800000), PICA_CMD_DATA_VS_FLOAT(0x0),
999
1000 // 0x2C1 : 0x0
1001 // 0x2C1 : 0x0
1002 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x0),
1003
1004 // 0x2C1 : 0x0
1005 // 0x2C1 : 0x0
1006 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x0),
1007
1008 // 0x2C1 : 0x3F800000
1009 // 0x2C1 : 0x0
1010 PICA_CMD_DATA_VS_FLOAT(0x3F800000), PICA_CMD_DATA_VS_FLOAT(0x0),
1011
1012 // 0x2C1 : 0xBE785B43
1013 // 0x2C1 : 0x3F785B43
1014 PICA_CMD_DATA_VS_FLOAT(0xBE785B43), PICA_CMD_DATA_VS_FLOAT(0x3F785B43),
1015
1016 // 0x2C1 : 0x0
1017 // 0x2C1 : 0xC083F07C
1018 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0xC083F07C),
1019
1020 // 0x2C1 : 0x3F785B43
1021 // 0x2C1 : 0x3E785B43
1022 PICA_CMD_DATA_VS_FLOAT(0x3F785B43), PICA_CMD_DATA_VS_FLOAT(0x3E785B43),
1023
1024 // 0x2C1 : 0x0
1025 // 0x2C1 : 0x3F800000
1026 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x3F800000),
1027
1028 // 0x2C1 : 0x0
1029 // 0x2C1 : 0x0
1030 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x0),
1031
1032 // 0x2C1 : 0x0
1033 PICA_CMD_DATA_VS_FLOAT(0x0), PICA_CMD_DATA_VS_FLOAT(0x0)
1034 };
1035
1036 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1037 }
1038
1039 {
1040 u32 commandBuffer[] =
1041 {
1042 // Vertex shader Boolean register
1043 // 0x2B0 : 0x7FFF0000 (BE 0xF)
1044 PICA_CMD_DATA_VS_BOOL(0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_BOOL),
1045
1046 // Vertex shader integer register i0
1047 // 0x2B1 : 0x0 (BE 0xF)
1048 PICA_CMD_DATA_VS_INT(0x0, 0x0, 0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_INT0),
1049
1050 // Vertex shader integer register i1
1051 // 0x2B2 : 0x0 (BE 0xF)
1052 PICA_CMD_DATA_VS_INT(0x0, 0x0, 0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_INT1),
1053
1054 // Vertex shader integer register i2
1055 // 0x2B3 : 0x0 (BE 0xF)
1056 PICA_CMD_DATA_VS_INT(0x0, 0x0, 0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_INT2),
1057
1058 // Vertex shader integer register i3
1059 // 0x2B4 : 0x0 (BE 0xF)
1060 PICA_CMD_DATA_VS_INT(0x0, 0x0, 0x0), PICA_CMD_HEADER_SINGLE(PICA_REG_VS_INT3)
1061 };
1062
1063 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1064 }
1065 }
1066
AddTextureCombinerCommand(void)1067 void AddTextureCombinerCommand(void)
1068 {
1069 {
1070 u32 commandBuffer[] =
1071 {
1072 // 0xd0 : 0xF210F21 (BE 0xF)
1073 // srcRgb, srcAlpha
1074 // glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_SRC_RGB],
1075 // GL_FRAGMENT_PRIMARY_COLOR_DMP, GL_FRAGMENT_SECONDARY_COLOR_DMP, GL_PREVIOUS);
1076 // glUniform3i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_SRC_ALPHA],
1077 // GL_FRAGMENT_PRIMARY_COLOR_DMP, GL_FRAGMENT_SECONDARY_COLOR_DMP, GL_PREVIOUS);
1078 PICA_CMD_DATA_TEX_ENV_SRC(PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_PRIMARY_COLOR_DMP,
1079 PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_SECONDARY_COLOR_DMP,
1080 PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
1081 PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_PRIMARY_COLOR_DMP,
1082 PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_SECONDARY_COLOR_DMP,
1083 PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS),
1084 PICA_CMD_HEADER_SINGLE(PICA_REG_TEX_ENV2),
1085
1086 // combineRgb, combineAlpha
1087 // 0xd2 : 0x20002 (BE 0xF)
1088 // glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_COMBINE_RGB], GL_ADD);
1089 // glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_TEXENV2_COMBINE_ALPHA], GL_ADD);
1090 PICA_CMD_DATA_TEX_ENV_COMBINE(PICA_DATA_TEX_ENV_COMBINE_ADD, PICA_DATA_TEX_ENV_COMBINE_ADD),
1091 PICA_CMD_HEADER_SINGLE(PICA_REG_TEX_ENV2_COMBINE)
1092 };
1093
1094 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1095 }
1096 }
1097
AddFragmentLightCommand(void)1098 void AddFragmentLightCommand(void)
1099 {
1100 /*
1101 // LightEnv
1102 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_LIGHT_ENV_CONFIG], GL_LIGHT_ENV_LAYER_CONFIG0_DMP);
1103 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_LIGHT_ENV_LUT_ENABLED_REFL], GL_FALSE);
1104 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_LIGHT_ENV_CLAMP_HIGHLIGHTS], GL_TRUE);
1105
1106 // D0
1107 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_LIGHT_ENV_ABS_LUT_INPUT_D0], GL_TRUE);
1108 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_LIGHT_ENV_LUT_INPUT_D0], GL_LIGHT_ENV_NH_DMP);
1109 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_SAMPLER_D0], 0);
1110
1111 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_GEOM_FACTOR1], GL_FALSE);
1112 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_GEOM_FACTOR0], GL_FALSE);
1113 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_TWO_SIDE_DIFFUSE], GL_FALSE);
1114
1115 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE1_ENABLED], GL_FALSE);
1116 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE2_ENABLED], GL_FALSE);
1117 glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE3_ENABLED], GL_FALSE);
1118 */
1119
1120 // Enable FragmentLight
1121 // glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHTING_ENABLED], GL_TRUE);
1122 // 0x8F : 0x1 (BE 0xF)
1123 // 0x1C6 : 0x0 (BE 0xF)
1124 {
1125 u32 commandBuffer[] =
1126 {
1127 PICA_CMD_SET_FRAG_LIGHT_ENABLE(0x1)
1128 };
1129
1130 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1131 }
1132
1133 AddTextureCombinerCommand();
1134
1135 // 0x1c2
1136 // glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_ENABLED], GL_TRUE);
1137
1138 {
1139 // Light0 specular0, 0x140 : 0xFF3FCFF (BE 0xF)
1140 // glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_SPECULAR0], 1, s_MaterialSpecular0);
1141 // glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_SPECULAR1], 1, s_MaterialSpecular1);
1142 // glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_SPECULAR0], 1, s_Light0.m_Specular0);
1143 // glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_SPECULAR1], 1, s_Light0.m_Specular1);
1144 // dmp_FragmentMaterial.specular0 * dmp_FragmentLightSource[0].specular0
1145 // dmp_FragmentMaterial.specular1 * dmp_FragmentLightSource[0].specular1
1146
1147 // Fragment uniform : Material
1148 // f32 s_MaterialSpecular0[] = {1.0f, 1.0f, 1.0f, 1.0f};
1149 // f32 s_MaterialSpecular1[] = {0.0f, 0.0f, 0.0f, 1.0f};
1150 // s_Light0.m_Specular0[0] = 1.0f;
1151 // s_Light0.m_Specular0[1] = 1.0f;
1152 // s_Light0.m_Specular0[2] = 1.0f;
1153 // s_Light0.m_Specular0[3] = 1.0f;
1154 // s_Light0.m_Specular1[0] = 0.0.0f;
1155 // s_Light0.m_Specular1[1] = 0.0.0f;
1156 // s_Light0.m_Specular1[2] = 0.0.0f;
1157 // s_Light0.m_Specular1[3] = 1.0f;
1158
1159 u32 commandBuffer[] =
1160 {
1161 0xff3fcff, PICA_CMD_HEADER_SINGLE(PICA_REG_FRAG_LIGHT_START)
1162 };
1163
1164 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1165 }
1166
1167 {
1168 u32 commandBuffer[] =
1169 {
1170 // Light0 diffuse, 0x142 h: 0x9900000
1171 // f32 s_MaterialDiffuse[] = {0.6f, 0.6f, 0.6f, 1.0f};
1172 // s_Light0.m_Diffuse[0] = 1.0f;
1173 // s_Light0.m_Diffuse[1] = 0.0.0f;
1174 // s_Light0.m_Diffuse[2] = 0.0.0f;
1175 // s_Light0.m_Diffuse[3] = 1.0f;
1176 // glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_DIFFUSE], 1, s_MaterialDiffuse);
1177 // glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_DIFFUSE], 1, s_Light0.m_Diffuse);
1178 // dmp_FragmentMaterial.diffuse * dmp_FragmentLightSource[0].diffuse
1179 0x9900000,
1180 // BurstSequence (4 times, BE 0xF)
1181 PICA_CMD_HEADER_BURSTSEQ(PICA_REG_FRAG_LIGHT0_DIFFUSE, 0x4),
1182
1183 // Light0 ambient, 0x143 : 0xA0280A
1184 // f32 s_MaterialAmbient[] = {0.2f, 0.2f, 0.2f, 1.0f};
1185 // s_Light0.m_Ambient[0] = 0.2f;
1186 // s_Light0.m_Ambient[1] = 0.2f;
1187 // s_Light0.m_Ambient[2] = 0.2f;
1188 // s_Light0.m_Ambient[3] = 1.0f;
1189 // glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_AMBIENT], 1, s_Light0.m_Ambient);
1190 // glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_MATERIAL_AMBIENT], 1, s_MaterialAmbient);
1191 // dmp_FragmentMaterial.ambient * dmp_FragmentLightSource[0].ambient
1192 0xA0280A,
1193
1194 // Light0 position_xy, 0x144 : 0x3BC20000
1195 // s_Light0.m_Position[0] = 0.0f;
1196 // s_Light0.m_Position[1] = 1.0.0f;
1197 // s_Light0.m_Position[2] = 0.0f;
1198
1199 // nn::math::MTX34 s_LightWorldMatrix;
1200 // nn::math::MTX34Identity(&s_LightWorldMatrix);
1201 // nn::math::VEC3 position(s_Light0.m_Position[0], s_Light0.m_Position[1], s_Light0.m_Position[2]);
1202 // nn::math::MTX34Translate(&s_LightWorldMatrix, &position);
1203 // nn::math::Matrix34 lightViewMatrix;
1204 // nn::math::MTX34Mult(&lightViewMatrix, s_ViewMatrix, s_LightWorldMatrix);
1205 // glUniform4f(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHT_SOURCE0_POSITION],
1206 // lightViewMatrix.m[0][3], lightViewMatrix.m[1][3], lightViewMatrix.m[2][3],
1207 // 1.0f);
1208 // dmp_FragmentLightSource[i].position xy
1209 0x3BC20000,
1210
1211 // Light0 position_z, 0x145 : 0xC3C2
1212 // dmp_FragmentLightSource[i].position z
1213 0xC3C2, 0x0,
1214
1215 // Light0 position.w 0x149 : 0x0
1216 // dmp_FragmentLightSource[i].position w
1217 0x0, PICA_CMD_HEADER_SINGLE(PICA_REG_FRAG_LIGHT0_TYPE)
1218 };
1219
1220 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1221 }
1222
1223 u32 fragLightFuncMode = 0;
1224
1225 u32 shadowed = 0;
1226 u32 spotEnabled = 0;
1227 u32 distanceAttenuationEnabled = 0;
1228 for (u32 lightIndex = 0; lightIndex < 8; lightIndex++)
1229 {
1230 fragLightFuncMode |= PICA_CMD_DATA_FRAG_LIGHT_FUNC_MODE1_LIGHT_SOURCE(lightIndex,
1231 shadowed, spotEnabled, distanceAttenuationEnabled);
1232 }
1233
1234 u32 lutEnabledD0 = 1;
1235 u32 lutEnabledD1 = 0;
1236 u32 fresnelSelector = 0;
1237 u32 lutEnabledRef1 = 0;
1238 fragLightFuncMode |= PICA_CMD_DATA_FRAG_LIGHT_FUNC_MODE1_LUT(lutEnabledD0,
1239 lutEnabledD1, fresnelSelector, lutEnabledRef1);
1240 {
1241 u32 commandBuffer[] =
1242 {
1243 // 0x1C0 : 0x1405014 (BE 0xF)
1244 // f32 s_GlobalAmbientLight[] = { 0.4f, 0.4f, 0.4f, 1.0f};
1245 // glUniform4fv(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_FRAGMENT_LIGHTING_AMBIENT], 1, s_GlobalAmbientLight);
1246 0x1405014, PICA_CMD_HEADER_SINGLE(PICA_REG_FRAG_LIGHT_AMBIENT),
1247
1248 // 0x1C4 : 0xFFFEFFFF (BE 0xF)
1249 // glUniform1i(demo::s_UniformLocations[demo::FRAGMENT_UNIFORM_LIGHT_ENV_LUT_ENABLED_D0], GL_TRUE);
1250 fragLightFuncMode,
1251 PICA_CMD_HEADER_SINGLE(PICA_REG_FRAG_LIGHT_FUNC_MODE1),
1252
1253 // 0x1D0 : 0x2222220 (BE 0xF)
1254 PICA_CMD_DATA_FRAG_LIGHT_ABSLUTINPUT(1, 0, 0, 0, 0, 0, 0),
1255 PICA_CMD_HEADER_SINGLE(PICA_REG_FRAG_LIGHT_ABSLUTINPUT)
1256 };
1257
1258 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1259 }
1260 }
1261
1262 // Convert from float32 to unsigned fixed12 (12-bit fraction)
1263 #define UTL_F2UFX_12W_0I(_inarg, _outarg) \
1264 { \
1265 float f_ = (_inarg); \
1266 unsigned val_; \
1267 unsigned v_ = *(unsigned*)&f_; \
1268 if (f_ <= 0 || (v_ & 0x7f800000) == 0x7f800000) \
1269 val_ = 0; \
1270 else \
1271 { \
1272 f_ *= 1 << (12 - 0); \
1273 if (f_ >= (1 << 12)) \
1274 val_ = (1 << 12) - 1; \
1275 else \
1276 val_ = (unsigned)(f_); \
1277 } \
1278 (_outarg) = val_; \
1279 }
1280
1281 // Convert from float32 to signed fixed12 (11-bit fraction)
1282 #define UTL_F2FX_12W_1I_F(_inarg, _outarg) \
1283 { \
1284 float f_; \
1285 unsigned v_; \
1286 f_ = (_inarg); \
1287 v_ = *(unsigned*)&f_; \
1288 if (f_ == 0.f || (v_ & 0x7f800000) == 0x7f800000) \
1289 _outarg = 0; \
1290 else \
1291 { \
1292 f_ *= (1 << (12 - 1)); \
1293 if (f_ < 0) \
1294 { \
1295 _outarg = 1 << (12 - 1); \
1296 f_ = -f_; \
1297 } \
1298 else \
1299 _outarg = 0; \
1300 if (f_ >= (1 << (12 - 1))) f_ = (1 << (12 - 1)) - 1; \
1301 _outarg |= (unsigned)(f_); \
1302 } \
1303 }
1304
AddLUTCommand(void)1305 void AddLUTCommand(void)
1306 {
1307 /*
1308 GLenum target = GL_LUT_TEXTURE0_DMP;
1309 glGenTextures(1, &s_D0LutTextureId);
1310 glBindTexture(GL_LUT_TEXTURE0_DMP, s_D0LutTextureId);
1311 glTexImage1D(target, 0, GL_LUMINANCEF_DMP, LUT_TABLE_SIZE,
1312 0, GL_LUMINANCEF_DMP, GL_FLOAT, s_LutArray);
1313 */
1314
1315 {
1316 u32 commandBuffer[] =
1317 {
1318 // 0x1C5 : 0x0 (BE 0xF)
1319 PICA_CMD_DATA_FRAG_LIGHT_LUT(0x0, PICA_DATA_SAMPLER_D0),
1320 PICA_CMD_HEADER_SINGLE(PICA_REG_FRAG_LIGHT_LUT)
1321 };
1322
1323 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1324 }
1325
1326 // 0x1C8
1327 u32 old_data = 0;
1328 for (u32 i = 0; i < LUT_TABLE_HALF_SIZE; i++)
1329 {
1330 u32 index0 = i;
1331 u32 index1 = i + 256;
1332
1333 // Convert from float32 to unsigned fixed12 (12-bit fraction)
1334 u32 data0 = 0;
1335 UTL_F2UFX_12W_0I(s_LutArray[index0], data0);
1336 data0 &= 0xfff;
1337
1338 // Convert from float32 to signed fixed12 (11-bit fraction)
1339 u32 data1 = 0;
1340 UTL_F2FX_12W_1I_F(s_LutArray[index1], data1);
1341 data1 &= 0xfff;
1342
1343 u32 data = PICA_CMD_DATA_FRAG_LIGHT_LUT_DATA(data0, data1);
1344
1345 if ( i == 0 )
1346 {
1347 u32 commandBuffer[] =
1348 {
1349 data, PICA_CMD_HEADER_BURST(PICA_REG_FRAG_LIGHT_LUT_DATA0, LUT_TABLE_HALF_SIZE)
1350 };
1351
1352 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1353 }
1354 else if ( i == (LUT_TABLE_HALF_SIZE - 1) )
1355 {
1356 u32 commandBuffer[] =
1357 {
1358 data, 0x0
1359 };
1360
1361 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1362 }
1363 else if ( (i % 2) == 1 )
1364 {
1365 old_data = data;
1366 }
1367 else if ( (i % 2) == 0 )
1368 {
1369 u32 commandBuffer[] =
1370 {
1371 old_data, data
1372 };
1373
1374 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1375 }
1376 }
1377 }
1378
AddDrawPlaneCommand(void)1379 void AddDrawPlaneCommand(void)
1380 {
1381 AddFrameBufferControlCommand();
1382
1383 {
1384 u32 commandBuffer[] =
1385 {
1386 // 0x229
1387 // Using glDrawElements function and GL_TRIANGLES, so drawMode = 1
1388 PICA_CMD_SET_DRAW_MODE0(1)
1389 };
1390
1391 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1392 }
1393
1394 // glDrawElements(GL_TRIANGLES, indexNum, GL_UNSIGNED_SHORT, 0);
1395 {
1396 u32 commandBuffer[] =
1397 {
1398 // 0x253 [0:8]
1399 // Using glDrawElements function and GL_TRIANGLES, so [8:8] = 1
1400 0x100,
1401 PICA_CMD_HEADER_SINGLE_BE( PICA_REG_DRAW_MODE1, 0x2 ),
1402
1403 // 0x25e [9:8]
1404 // Using glDrawElements function and mode = GL_TRIANGLES, so [9:8] = PICA_DATA_DRAW_TRIANGLES = 3
1405 PICA_CMD_SET_DRAW_MODE2(PICA_DATA_DRAW_TRIANGLES),
1406
1407 // Clear the internal states of vertex indices when drawing triangles
1408 // 0x25f
1409 PICA_CMD_DATA_START_DRAW_FUNC1(0x1),
1410 PICA_CMD_HEADER_SINGLE(PICA_REG_START_DRAW_FUNC1),
1411
1412 // 0x253[0:0] is set equal to 0 when nngxInitialize() is run, so this is unnecessary.
1413 // 0x253 [0:0]
1414 // Using vertex buffer and glDrawElements function, so [0:0] = 0
1415 // PICA_CMD_DATA_DRAW_MODE1(0x0, 0x0),
1416 // PICA_CMD_HEADER_SINGLE_BE(PICA_REG_DRAW_MODE1, 0x1),
1417
1418 // 0x227 [27:0]
1419 // Vertex index address offset
1420 // Vertex index type is GL_UNSIGNED_SHORT, so [31:31] = 1
1421 PICA_CMD_DATA_INDEX_ARRAY_ADDR_OFFSET(s_VertexIndexAddressOffset,
1422 PICA_DATA_INDEX_ARRAY_UNSIGNED_SHORT),
1423 PICA_CMD_HEADER_SINGLE(PICA_REG_INDEX_ARRAY_ADDR_OFFSET),
1424
1425 // 0x228 [31:0]
1426 // Set the number of vertices to render: 6
1427 s_IndexNum, PICA_CMD_HEADER_SINGLE(PICA_REG_DRAW_VERTEX_NUM),
1428
1429 // Render kick command macro
1430 // 1. Set to 0 immediately before Draw
1431 // 0x245 = 0x0
1432 // 2. Render kick command
1433 // 0x22f = Write 1 to any bit
1434 // 3. Set to 1 immediately after Draw
1435 // 0x245 = 0x1
1436 // 4. Immediately after the render kick command, clear the vertex cache.
1437 // 0x231 = 0x1
1438 PICA_CMD_SET_START_DRAW_ELEMENT(1),
1439
1440 // Immediately after the render kick command, clear both color buffer and depth buffer caches.
1441 PICA_CMD_SET_COLOR_DEPTH_BUFFER_CLEAR(0x1, 0x1)
1442 };
1443
1444 nngxAdd3DCommand(commandBuffer, sizeof(commandBuffer), GL_TRUE);
1445 }
1446 }
1447
AddFrameBufferControlCommand(void)1448 void AddFrameBufferControlCommand(void)
1449 {
1450 {
1451 u32 cmdbuf[] =
1452 {
1453 // Clear the color buffer and depth buffer caches.
1454 PICA_CMD_SET_COLOR_DEPTH_BUFFER_CLEAR(0x1, 0x1),
1455
1456 // To disable color buffer read, set to 0
1457 // 0x112 [3:0]
1458 PICA_CMD_DATA_FRAME_BUFFER_MODE(0x0),
1459 PICA_CMD_HEADER_SINGLE(PICA_REG_COLOR_BUFFER_READ),
1460
1461 // To enable color buffer write, set to 0xF.
1462 // 0x113 [3:0]
1463 PICA_CMD_DATA_FRAME_BUFFER_MODE(0xF),
1464 PICA_CMD_HEADER_SINGLE(PICA_REG_COLOR_BUFFER_WRITE),
1465
1466 // To enable depth buffer read, set [1:1] to 1.
1467 // To disable stencil buffer read, set to [0:0] to 0.
1468 // 0x114 [1:0]
1469 PICA_CMD_DATA_FRAME_BUFFER_MODE(0x2),
1470 PICA_CMD_HEADER_SINGLE(PICA_REG_DEPTH_STENCIL_BUFFER_READ),
1471
1472 // To enable depth buffer write, set to [1:1] to 1.
1473 // To disable stencil buffer write, set to [0:0] to 0.
1474 // 0x115 [1:0]
1475 PICA_CMD_DATA_FRAME_BUFFER_MODE(0x2),
1476 PICA_CMD_HEADER_SINGLE(PICA_REG_DEPTH_STENCIL_BUFFER_WRITE),
1477
1478 // Clear the color buffer and depth buffer caches.
1479 PICA_CMD_SET_COLOR_DEPTH_BUFFER_CLEAR(0x1, 0x1)
1480 };
1481
1482 nngxAdd3DCommand(cmdbuf, sizeof(cmdbuf), GL_TRUE);
1483 }
1484 }
1485
DrawDisplay1(void)1486 void DrawDisplay1(void)
1487 {
1488 AddViewportCommand(NN_GX_DISPLAY1);
1489 glBindFramebuffer(GL_FRAMEBUFFER, s_FramebufferID);
1490 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1491 nngxTransferRenderImage(s_Displaybuffer1ID[s_CurrentDisplaybuffer1], NN_GX_ANTIALIASE_NOT_USED, GL_FALSE, 0, 0);
1492
1493 nngxRunCmdlist();
1494 nngxWaitCmdlistDone();
1495 }
1496
nnMain(void)1497 void nnMain(void)
1498 {
1499 // Call only nn::applet::Enable to also allow execution from the HOME Menu
1500 // HOME Menu transitions, POWER Button presses, and sleep are all unsupported
1501 nn::applet::Enable();
1502
1503 Initialize();
1504
1505 bool flag = true;
1506 while ( flag )
1507 {
1508 flag = DrawFrame();
1509 }
1510
1511 Finalize();
1512 }
1513