· 6 years ago · Jan 21, 2020, 03:44 PM
1/*--------------------------------------------------------------------------------*
2 Copyright (C)Nintendo All rights reserved.
3
4 These coded instructions, statements, and computer programs contain proprietary
5 information of Nintendo and/or its licensed developers and are protected by
6 national and international copyright laws. They may not be disclosed to third
7 parties or copied or duplicated in any form, in whole or in part, without the
8 prior written consent of Nintendo.
9
10 The content herein is highly confidential and should be handled accordingly.
11 *--------------------------------------------------------------------------------*/
12
13
14
15 /**
16 * @examplesource{TexturedCube.cpp,PageSampleNvnSimple03}
17 *
18 * @brief
19 * A class that implements the drawing of a spinning textured cube.
20 */
21
22 /**
23 * @page PageSampleNvnSimple03 Nvn Simple 03 : Textured Cube
24 * @tableofcontents
25 *
26 * @brief
27 * This sample implements the drawing of a spinning textured cube to introduces how to use textures and samplers.
28 *
29 * @section PageSampleNvnSimple03_SectionBrief Overview
30 * This sample implements the drawing of a spinning textured cube to
31 * introduces how to use textures and samplers. A spinning textured cube
32 * is rendered to show the using of tiled textures and linear textures,
33 * and different samplers.
34 *
35 * @subsection PageSampleNvnSimple03_SectionExpectedOutput Expected Output
36 * @image html Applications\NvnSimple03TexturedCube\NvnSimple03TexturedCube.png
37 *
38 * @section PageSampleNvnSimple03_SectionFileStructure File Structure
39 * The sample's source file and Visual Studio solutions can be found at
40 * @link ../../../Samples/Sources/Applications/NvnSimple03TexturedCube Samples/Sources/Applications/NvnSimple03TexturedCube @endlink
41 *
42 * <table>
43 * <tr><td> @link TexturedCube.h TexturedCube.h@endlink, @link TexturedCube.cpp TexturedCube.cpp@endlink </td><td> @copybrief TexturedCube.h </td></tr>
44 * <tr><td> NvnSimple03.vs </td><td> Dependent vetex shader which is used for rendering the textured cube </td></tr>
45 * <tr><td> NvnSimple03.fs </td><td> Dependent fragment shader which is used for rendering the textured cube </td></tr>
46 * </table>
47 *
48 * The resources conversion tools and library which contains common code shared by the NvnSimple samples can be found at
49 * @link ../../../Samples/Sources/Libraries/NvnSimple Samples/Sources/Libraries/NvnSimple @endlink
50 *
51 * @section PageSampleNvnSimple03_SectionNecessaryEnvironment System Requirements
52 * No extra system requirements.
53 *
54 * @section PageSampleNvnSimple03_SectionHowToOperate Operation Procedures
55 * Use Joy-Con、DebugPad、Keyboard when using PC to operate.
56 * <p>
57 * <table>
58 * <tr><th> Input </th><th> Operation </th></tr>
59 * <tr><td> A Button or A Key </td><td> Toggle command buffer reuse on/off </td></tr>
60 * <tr><td> B Button or B Key </td><td> Show/hide information </td></tr>
61 * <tr><td> X Button or X Key </td><td> Cycle through different textures and samplers </td></tr>
62 * </table>
63 * </p>
64 *
65 * @section PageSampleNvnSimple03_SectionPrecaution Precautions
66 * None.
67 *
68 * @section PageSampleNvnSimple03_SectionHowToExecute Execution Procedure
69 * Build the Visual Solution in the desired configuration and run it.
70 *
71 * @section PageSampleNvnSimple03_SectionDetail Description
72 * A large part of the work involved with texturing with NVN is implemented in the
73 * GraphicsTextureManager class, which this sample utilizes. Building on the previous demo,
74 * WorldSpaceTriangles, this class shows how to use textures when rendering
75 * primitives, which involves the following:
76 * - Setting up NVN texture pool and sampler pool objects
77 * - Initializing NVN texture and sampler objects and registering them to the respective pools
78 * - Looking up sampler location from shader reflection info and using it to bind a texture when rendering
79 * This demo also shows both tiled textures and linear textures in action.
80 *
81 * The NvnSimpleTextureConverter tool, whose source code is included in this solution, is used to
82 * convert the source images into texture asset files with tiling that is optimized for
83 * the NX GPU. See Properties > Build Event >Pre-Build Event for texture conversion command
84 * line details.
85 */
86
87
88
89#include <nn/fs.h>
90#include <nn/nn_Log.h>
91#include <nn/nn_Assert.h>
92#include <FileSystem.h>
93#include <GraphicsUtilities.h>
94#include <GraphicsStructures.h>
95#include <SimpleFramework.h>
96#include <UserInput.h>
97#include "TexturedCube.h"
98
99
100
101namespace
102{
103//-------------------------------------------------------------------------------------------------
104// Data structures
105//-------------------------------------------------------------------------------------------------
106class Vertex
107{
108public:
109 Vertex() NN_NOEXCEPT : m_Pos(), m_Uv() {}
110 Vector3 m_Pos;
111 Vector2 m_Uv;
112};
113
114
115
116//-------------------------------------------------------------------------------------------------
117// Globals
118//-------------------------------------------------------------------------------------------------
119float g_VertexPositions[] =
120{
121 // front
122 -1.0f, 1.0f, 1.0f,
123 1.0f, 1.0f, 1.0f,
124 1.0f, -1.0f, 1.0f,
125 -1.0f, -1.0f, 1.0f,
126
127 // back
128 1.0f, 1.0f, -1.0f,
129 -1.0f, 1.0f, -1.0f,
130 -1.0f, -1.0f, -1.0f,
131 1.0f, -1.0f, -1.0f,
132
133 // left
134 1.0f, 1.0f, 1.0f,
135 1.0f, 1.0f, -1.0f,
136 1.0f, -1.0f, -1.0f,
137 1.0f, -1.0f, 1.0f,
138
139 // right
140 -1.0f, 1.0f, -1.0f,
141 -1.0f, 1.0f, 1.0f,
142 -1.0f, -1.0f, 1.0f,
143 -1.0f, -1.0f, -1.0f,
144
145 // top
146 -1.0f, 1.0f, -1.0f,
147 1.0f, 1.0f, -1.0f,
148 1.0f, 1.0f, 1.0f,
149 -1.0f, 1.0f, 1.0f,
150
151 // bottom
152 -1.0f, -1.0f, 1.0f,
153 1.0f, -1.0f, 1.0f,
154 1.0f, -1.0f, -1.0f,
155 -1.0f, -1.0f, -1.0f,
156};
157
158
159float g_VertexUvs[] =
160{
161 // front
162 0.0f, 0.0f,
163 0.25f, 0.0f,
164 0.25f, 0.5f,
165 0.0f, 0.5f,
166
167 // back
168 0.0f, 0.5f,
169 0.25f, 0.5f,
170 0.25f, 1.0f,
171 0.0f, 1.0f,
172
173 // left
174 0.25f, 0.0f,
175 0.5f, 0.0f,
176 0.5f, 0.5f,
177 0.25f, 0.5f,
178
179 // right
180 0.5f, 0.0f,
181 0.75f, 0.0f,
182 0.75f, 0.5f,
183 0.5f, 0.5f,
184
185 // top
186 0.25f, 0.5f,
187 0.5f, 0.5f,
188 0.5f, 1.0f,
189 0.25f, 1.0f,
190
191 // bottom
192 0.5f, 0.5f,
193 0.75f, 0.5f,
194 0.75f, 1.0f,
195 0.5f, 1.0f,
196};
197
198
199uint32_t g_VertexIndices[] =
200{
201 0, 1, 2, 0, 2, 3
202};
203
204
205}
206
207
208
209//-------------------------------------------------------------------------------------------------
210// Public API
211//-------------------------------------------------------------------------------------------------
212void TexturedCube::Initialize(GraphicsSystem* pGraphicsSystem) NN_NOEXCEPT
213{
214 if (!m_IsInitialized)
215 {
216 m_pGraphicsSystem = pGraphicsSystem;
217
218 int64_t shaderBinFileSize = 0;
219
220 // read shader binary, create GraphicsShader object from it, and get uniform block reflection info
221 m_GlslcData = ReadFile(&shaderBinFileSize, "rom:/NvnSimple03.glslc", m_pGraphicsSystem->GetAllocator());
222
223 m_Shader.Initialize(m_pGraphicsSystem, static_cast<GLSLCoutput*>(m_GlslcData));
224
225 m_pUniformBlockInfo = &m_Shader.LookupUniformBlockInfo("VertexShaderUniformBlock");
226
227
228 // create memory pool for vertex data
229 size_t attributeDataSize = sizeof(g_VertexPositions) + sizeof(g_VertexUvs);
230 size_t indexDataSize = sizeof(g_VertexIndices) * 6;
231 size_t uniformAlignment = m_pGraphicsSystem->GetResourceInfo().uniformBufferAlignment;
232
233 size_t alignedUniformBlockSize = nn::util::align_up(m_pUniformBlockInfo->GetSize(), uniformAlignment);
234 size_t memPoolSize = attributeDataSize + indexDataSize + alignedUniformBlockSize + 1024; // add in extra 1 KB to hold linear texture below
235
236 m_VertexAndUniformDataMemPool.Initialize(m_pGraphicsSystem, nvn::MemoryPoolFlags::CPU_UNCACHED | nvn::MemoryPoolFlags::GPU_CACHED, memPoolSize, "TexturedCube MemPool");
237
238
239 // allocate blocks of memory for vertex and uniform data
240 m_VertexAndUniformDataMemPool.AllocateBuffer(&m_VertexDataBuffer, attributeDataSize);
241 m_VertexAndUniformDataMemPool.AllocateBuffer(&m_IndexDataBuffer, indexDataSize);
242 m_VertexAndUniformDataMemPool.AllocateBuffer(&m_UniformDataBuffer, indexDataSize, uniformAlignment);
243
244
245 // load vertex and index data into memory pool
246 const int numFaces = 6;
247 const int numVertices = 4 * numFaces;
248 Vertex* vertices = static_cast<Vertex*>(m_VertexDataBuffer.Map());
249
250 // we use a single vertex buffer with interleaved attributes
251 for (int i = 0; i < numVertices; ++i)
252 {
253 Vertex* pVertex = vertices + i;
254
255 float x = g_VertexPositions[3 * i];
256 float y = g_VertexPositions[3 * i + 1];
257 float z = g_VertexPositions[3 * i + 2];
258
259 float u = g_VertexUvs[2 * i];
260 float v = g_VertexUvs[2 * i + 1];
261
262 pVertex->m_Pos.Set(x, y, z);
263 pVertex->m_Uv.Set(u, v);
264 }
265
266 // indices
267 m_NumIndices = 6 * numFaces;
268 uint32_t* indices = static_cast<uint32_t*>(m_IndexDataBuffer.Map());
269
270 for (uint32_t i = 0; i < m_NumIndices; ++i)
271 {
272 uint32_t delta = 4 * (i / 6);
273 uint32_t index = i % 6;
274
275 indices[i] = g_VertexIndices[index] + delta;
276 }
277
278
279 // compute and load uniform data into memory pool
280 char* baseUniformBlockAddr = static_cast<char*>(m_UniformDataBuffer.Map());
281
282 // projection transform
283 const UniformBlockMemberInfo& projMtxInfo = m_pUniformBlockInfo->LookupMemberInfo("projMtx");
284 char* projMtxAddr = baseUniformBlockAddr + projMtxInfo.GetOffset();
285
286 nn::util::Matrix4x4fType projMtx;
287 nn::util::Float4x4 mtxStorage;
288
289 nn::util::MatrixIdentity(&projMtx);
290 nn::util::MatrixPerspectiveFieldOfViewRightHanded(&projMtx, nn::util::FloatPi / 3.0f, 16.0f / 9.0f, 0.1f, 1000.0f);
291 nn::util::MatrixStore(&mtxStorage, projMtx);
292
293 memcpy(projMtxAddr, &mtxStorage, projMtxInfo.GetSize());
294
295 // The modelView transform will update per frame, so we don't actually load anything here.
296 // Instead, we compute the view transform up front and set the address of the modelView uniform for later computation.
297
298 const UniformBlockMemberInfo& modelViewMtxInfo = m_pUniformBlockInfo->LookupMemberInfo("modelViewMtx");
299
300 m_ModelViewMtxAddr = baseUniformBlockAddr + modelViewMtxInfo.GetOffset();
301 m_Theta = 0.0f;
302 m_IsRotateHorizontal = true;
303
304 nn::util::Vector3f cameraPos(0, 2, 4);
305 nn::util::Vector3f targetPos(0, 0, 0);
306 nn::util::Vector3f up(0, 1, 0);
307
308 nn::util::MatrixLookAtRightHanded(&m_ViewMtx, cameraPos, targetPos, up);
309
310
311 // set up NVN VertexStreamState and VertexAttribState objects based on vertex attribute names and shader
312 // the ordering of the attribute names must logically match up with the attribute ordering in our vertex data structure (see above)
313 const char* attributeNames[NumVertexAttributes] = { "attr_position", "attr_uv" };
314
315 // we use an interleaved vertex buffer layout for this demo
316 SetupVertexAttribAndStreamStateInterleaved(attributeNames, NumVertexAttributes, m_Shader, m_VertexAttribStates, &m_VertexStreamState);
317
318
319 // load texture files
320 const int NumTextureAssets = 4;
321 const char* textureFiles[NumTextureAssets] = { "rom:/CubeTexture.tex", "rom:/BrickTexture.tex", "rom:/DdsTexture.tex", "rom:/DdsTextureIndexed.tex" };
322 TextureAsset* textureAssets[NumTextureAssets];
323 int totalSize = 0; // calculate total size required to store the textures to be loaded
324
325 for (int i = 0; i < NumTextureAssets; ++i)
326 {
327 textureAssets[i] = ReadTexture(textureFiles[i], m_pGraphicsSystem->GetAllocator());
328 totalSize += textureAssets[i]->header.texelsDataSize;
329 }
330
331
332 // create texture manager instance
333 m_TextureManager.Initialize(m_pGraphicsSystem, nvn::MemoryPoolFlags::CPU_UNCACHED | nvn::MemoryPoolFlags::GPU_CACHED,
334 32, totalSize, "TexturedCube Texture Pool");
335
336
337 // initialize nvn::Textures from texture asset files
338 int textureIds[NumTextureAssets];
339
340 for (int i = 0; i < NumTextureAssets; ++i)
341 {
342 textureIds[i] = m_TextureManager.AddTexture(textureAssets[i]);
343 }
344
345
346 // inititalize linear nvn::Texture
347 m_LinearTexWidth = 16;
348 m_LinearTexHeight = 8;
349
350 nvn::TextureBuilder textureBuilder;
351 textureBuilder.SetDefaults()
352 .SetDevice(m_pGraphicsSystem->GetDevice())
353 .SetFlags(nvn::TextureFlags::LINEAR)
354 .SetTarget(nvn::TextureTarget::TARGET_2D)
355 .SetFormat(nvn::Format::RGBA8)
356 .SetSize2D(m_LinearTexWidth, m_LinearTexHeight);
357
358 // stride must be set when building linear textures w/ nvn
359 size_t linearTexStride = m_LinearTexWidth * 4; // 4 bytes per pixel
360 NN_ASSERT(linearTexStride % m_pGraphicsSystem->GetResourceInfo().linearTextureStrideAlignment == 0);
361
362 textureBuilder.SetStride(linearTexStride);
363
364 // We place the linear texture in a separate memory pool from our tiled textures. Instead, we place it in m_VertexAndUniformDataMemPool.
365 // One reason: we want to update the linear texture per-frame, but on Windows, CPU_UNCACHED is not supported for memory pools
366 // with non-linear textures in them, and furthermore flushing such memory pools causes texture corruption, so using the same
367 // memory pool is not an option here.
368
369 size_t linearTexSize = textureBuilder.GetStorageSize();
370 size_t linearTexAlign = textureBuilder.GetStorageAlignment();
371
372 ptrdiff_t linearTexStartOffset = m_VertexAndUniformDataMemPool.Allocate(linearTexSize, linearTexAlign);
373 m_LinearTexels = reinterpret_cast<uint32_t*>(m_VertexAndUniformDataMemPool.GetBaseCpuAddress() + linearTexStartOffset);
374
375 textureBuilder.SetStorage(m_VertexAndUniformDataMemPool.GetMemoryPool(), linearTexStartOffset);
376
377 // make a checkerboard pattern for the linear texture
378 for (int row = 0; row < m_LinearTexHeight; ++row)
379 {
380 for (int col = 0; col < m_LinearTexWidth; ++col)
381 {
382 uint32_t color = 0xffffffff;
383
384 if ((row % 2) == (col % 2))
385 {
386 color = 0xff000000;
387 }
388
389 m_LinearTexels[row * m_LinearTexWidth + col] = color;
390 }
391 }
392
393 int linearTexId = m_TextureManager.AddTexture(textureBuilder);
394
395
396 // initialize nvn::Samplers
397 const int NUM_SAMPLERS = 2;
398 int samplerIds[NUM_SAMPLERS];
399
400 nvn::SamplerBuilder samplerBuilder;
401 samplerBuilder.SetDefaults();
402 samplerBuilder.SetDevice(m_pGraphicsSystem->GetDevice());
403 samplerBuilder.SetMinMagFilter(nvn::MinFilter::LINEAR, nvn::MagFilter::LINEAR);
404 samplerIds[0] = m_TextureManager.AddSampler(samplerBuilder);
405
406 samplerBuilder.SetMinMagFilter(nvn::MinFilter::NEAREST, nvn::MagFilter::NEAREST);
407 samplerIds[1] = m_TextureManager.AddSampler(samplerBuilder);
408
409
410 // generate texture handles
411 m_TextureHandles[0] = m_TextureManager.RegisterTextureHandle(textureIds[0], samplerIds[0]);
412 m_TextureHandles[1] = m_TextureManager.RegisterTextureHandle(textureIds[1], samplerIds[1]);
413 m_TextureHandles[2] = m_TextureManager.RegisterTextureHandle(textureIds[1], samplerIds[0]);
414 m_TextureHandles[3] = m_TextureManager.RegisterTextureHandle(textureIds[2], samplerIds[0]);
415 m_TextureHandles[4] = m_TextureManager.RegisterTextureHandle(textureIds[3], samplerIds[1]);
416 m_TextureHandles[LinearTextureIndex] = m_TextureManager.RegisterTextureHandle(linearTexId, samplerIds[1]);
417
418
419 // free memory for texture files since texel data was loaded into TextureManager MemoryPool
420 for (int i = 0; i < NumTextureAssets; ++i)
421 {
422 m_pGraphicsSystem->GetAllocator()->Free(textureAssets[i]);
423 }
424
425
426 // get shader binding location for sampler uniform
427 m_SamplerLocation = m_Shader.LookupUniformInfo("sampler").GetBindingLocations(nvn::ShaderStage::FRAGMENT);
428
429
430 // initialize render state
431 m_RenderState.Initialize();
432
433 m_RenderState.GetColorState()->SetBlendEnable(0, true);
434 m_RenderState.GetBlendState()->SetBlendTarget(0);
435 m_RenderState.GetBlendState()->SetBlendEquation(nvn::BlendEquation::ADD, nvn::BlendEquation::ADD);
436 m_RenderState.GetBlendState()->SetBlendFunc(nvn::BlendFunc::SRC_ALPHA, nvn::BlendFunc::ONE_MINUS_SRC_ALPHA, nvn::BlendFunc::SRC_ALPHA, nvn::BlendFunc::ONE_MINUS_SRC_ALPHA);
437
438 m_RenderState.GetPolygonState()->SetFrontFace(nvn::FrontFace::CW);
439 m_RenderState.GetPolygonState()->SetCullFace(nvn::Face::BACK);
440 m_RenderState.GetPolygonState()->SetPolygonMode(nvn::PolygonMode::FILL);
441
442 m_RenderState.GetDepthStencilState()->SetDepthTestEnable(true);
443 m_RenderState.GetDepthStencilState()->SetDepthWriteEnable(true);
444 m_RenderState.GetDepthStencilState()->SetDepthFunc(nvn::DepthFunc::LESS);
445
446
447 // build our command buffer to hold GPU commands to draw our triangles up front once
448 m_CommandBuffer.Initialize(m_pGraphicsSystem);
449
450 GenerateCommandBuffer();
451
452
453 m_CurTextureHandleIndex = 0;
454 m_IsInitialized = true;
455 }
456}//NOLINT(impl/function_size)
457
458
459
460void TexturedCube::DrawFrame() NN_NOEXCEPT
461{
462 // update modelView uniform
463 nn::util::Matrix4x3fType rotateMtx;
464 nn::util::Matrix4x3fType modelViewMtx;
465
466 nn::util::Vector3f rotate(0, 0, 0);
467
468 if (m_IsRotateHorizontal)
469 {
470 rotate.SetY(m_Theta);
471 }
472 else
473 {
474 rotate.SetX(m_Theta);
475 }
476
477 nn::util::MatrixIdentity(&rotateMtx);
478 nn::util::MatrixSetRotateXyz(&rotateMtx, rotate);
479 nn::util::MatrixMultiply(&modelViewMtx, rotateMtx, m_ViewMtx);
480
481 LoadMatrix43(m_ModelViewMtxAddr, modelViewMtx);
482
483
484 // check to see if the texture handle is to be updated
485 bool updateTextureHandle = false;
486
487 if (IsTriggered(PadButton_X))
488 {
489 m_CurTextureHandleIndex = (m_CurTextureHandleIndex + 1) % NumTextureHandles;
490 updateTextureHandle = true;
491 }
492
493
494 // generate the command buffer if necessary and execute it
495 if (!m_IsPrebuiltCommandBufferUsed || updateTextureHandle || m_IsScreenResolutionChanged)
496 {
497 GenerateCommandBuffer();
498 }
499 m_pGraphicsSystem->GetQueue()->SubmitCommands(1, &m_CommandHandle);
500
501
502 // update per frame state
503 m_Theta += 0.01f;
504
505 if (m_Theta > 2 * nn::util::FloatPi)
506 {
507 m_Theta -= (2 * nn::util::FloatPi);
508 m_IsRotateHorizontal = !m_IsRotateHorizontal;
509 }
510
511
512 // with our linear texture, we update the texels on the CPU
513 // given that our texture memory pool is CPU_UNCACHED, the updated texture will be reflected to the GPU
514 if (m_CurTextureHandleIndex == LinearTextureIndex)
515 {
516 float ramp = sinf(m_Theta / 2.0f);
517
518 for (int i = 0; i < m_LinearTexWidth * m_LinearTexHeight; ++i)
519 {
520 uint32_t texel = m_LinearTexels[i];
521
522 // update the white squares to ramp the red component from 0.0 to 1.0
523 if (texel != 0xff000000)
524 {
525 uint8_t red = static_cast<uint8_t>(0xff * ramp);
526 texel = (texel & 0xffffff00) | red;
527 m_LinearTexels[i] = texel;
528 }
529 }
530 }
531}
532
533
534
535void TexturedCube::Finalize() NN_NOEXCEPT
536{
537 if (m_IsInitialized)
538 {
539 m_TextureManager.Finalize();
540 m_CommandBuffer.Finalize();
541
542 m_VertexDataBuffer.Finalize();
543 m_IndexDataBuffer.Finalize();
544 m_UniformDataBuffer.Finalize();
545 m_VertexAndUniformDataMemPool.Finalize();
546
547 m_Shader.Finalize();
548
549 m_pGraphicsSystem->GetAllocator()->Free(m_GlslcData);
550 m_GlslcData = nullptr;
551
552 m_pGraphicsSystem = nullptr;
553 m_CommandHandle = 0;
554
555 m_ModelViewMtxAddr = nullptr;
556 m_Theta = 0.0f;
557 m_IsRotateHorizontal = true;
558
559 m_IsInitialized = false;
560 }
561}
562
563
564
565//-------------------------------------------------------------------------------------------------
566// Private methods
567//-------------------------------------------------------------------------------------------------
568void TexturedCube::GenerateCommandBuffer() NN_NOEXCEPT
569{
570 nvn::CommandBuffer* pCommandBuffer = m_CommandBuffer.StartRecording();
571 {
572 // scissor/viewport
573 m_pGraphicsSystem->SetDefaultViewportAndScissor(pCommandBuffer);
574
575 // clear color and depth/stencil buffers
576 static float color[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
577
578 pCommandBuffer->ClearColor(0, color, nvn::ClearColorMask::RGBA);
579 pCommandBuffer->ClearDepthStencil(1.0f, true, 0, 0);
580
581 // render state
582 m_RenderState.Bind(pCommandBuffer);
583
584 // bind shader
585 m_Shader.Bind(pCommandBuffer);
586
587 // bind uniform buffer
588 int32_t bindingLocation = m_pUniformBlockInfo->GetBindingLocations(nvn::ShaderStage::VERTEX);
589 BindUniformBuffer(nvn::ShaderStage::VERTEX, bindingLocation, &m_UniformDataBuffer, pCommandBuffer);
590
591 // bind vertex buffer data
592 pCommandBuffer->BindVertexAttribState(NumVertexAttributes, m_VertexAttribStates);
593 pCommandBuffer->BindVertexStreamState(1, &m_VertexStreamState);
594
595 BindVertexBuffer(0, &m_VertexDataBuffer, pCommandBuffer);
596
597 // set texture and sampler pools
598 m_TextureManager.SetTextureAndSamplerPools(pCommandBuffer);
599
600 // bind texture
601 pCommandBuffer->BindTexture(nvn::ShaderStage::FRAGMENT, m_SamplerLocation, m_TextureHandles[m_CurTextureHandleIndex]);
602
603 // draw call
604 pCommandBuffer->DrawElements(nvn::DrawPrimitive::TRIANGLES, nvn::IndexType::UNSIGNED_INT, m_NumIndices, m_IndexDataBuffer.GetAddress());
605 }
606 m_CommandHandle = m_CommandBuffer.EndRecording();
607}
608
609
610
611//-------------------------------------------------------------------------------------------------
612// main
613//-------------------------------------------------------------------------------------------------
614extern "C" void nnMain()
615{
616 TexturedCube scene;
617 SimpleFrameworkMainWithDebugInfo(&scene, GraphicsSystemParams(), u8"TexturedCube", Color(0xffffff));
618}