· 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 * @examplesource{ScreenSpaceTriangles.cpp,PageSampleNvnSimple01}
16 *
17 * @brief
18 * A class that implements the drawing of some triangles in screen space coordinates
19 * in a very simple fashion where no shader uniforms are used.
20 */
21
22 /**
23 * @page PageSampleNvnSimple01 Nvn Simple 01 : Screen Space Triangles
24 * @tableofcontents
25 *
26 * @brief
27 * This sample implements the drawing of some triangles in screen space
28 * coordinates to introduces the basics of shader and vertex data setup.
29 *
30 * @section PageSampleNvnSimple01_SectionBrief Overview
31 * This sample implements the drawing of some triangles in screen space
32 * coordinates to introduces the basics of shader and vertex data setup.
33 * Two triangles are rendered in screen space coordinates in a very simple
34 * fashion where no shader uniforms are used.
35 *
36 * @subsection PageSampleNvnSimple01_SectionExpectedOutput Expected Output
37 * @image html Applications\NvnSimple01ScreenSpaceTriangles\NvnSimple01ScreenSpaceTriangles.png
38 *
39 * @section PageSampleNvnSimple01_SectionFileStructure File Structure
40 * The sample's source file and Visual Studio solutions can be found at
41 * @link ../../../Samples/Sources/Applications/NvnSimple02WorldSpaceTriangles Samples/Sources/Applications/NvnSimple01ScreenSpaceTriangles @endlink
42 * <table>
43 * <tr><td> @link ScreenSpaceTriangles.h ScreenSpaceTriangles.h@endlink, @link ScreenSpaceTriangles.cpp ScreenSpaceTriangles.cpp@endlink </td><td> @copybrief ScreenSpaceTriangles.h </td></tr>
44 * <tr><td> NvnSimple01.vs </td><td> Dependent vetex shader which is used for rendering triangles in screen space coordinates </td></tr>
45 * <tr><td> NvnSimple01.fs </td><td> Dependent fragment shader which is used for rendering triangles in screen space coordinates </td></tr>
46 * </table>
47 *
48 * The tool NvnSimpleShaderCompiler, 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 PageSampleNvnSimple01_SectionNecessaryEnvironment System Requirements
52 * No extra system requirements.
53 *
54 * @section PageSampleNvnSimple01_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 * </table>
62 * </p>
63 *
64 * @section PageSampleNvnSimple01_SectionPrecaution Precautions
65 * None.
66 *
67 * @section PageSampleNvnSimple01_SectionHowToExecute Execution Procedure
68 * Build the Visual Solution in the desired configuration and run it.
69 *
70 * @section PageSampleNvnSimple01_SectionDetail Description
71 * This application simply draws two triangles in screen space coordinates with no shader uniforms used.
72 * In this application we create the following objects:
73 * - A GraphicsShader object to load shader binary code and bind vertex buffer data to attributes.
74 * - A GraphicsMemoryPool object into which we load vertex data for the triangles via nvn::Buffers.
75 * - nvn::VertexAttribState and nvn::VertexStreamState objects to describe the format of our vertex data.
76 * - A GraphicsRenderState object to generate commands for setting GPU render state.
77 * - A GraphicsCommandBuffer object to gather all of our GPU commands for rendering.
78 *
79 * The NvnSimpleShaderCompiler tool, whose source code is included in this solution, is used to convert the glsl shader
80 * code into a binary format that is then loaded and used to generate a GraphicsShader object.
81 * The conversion command is integrated into the build through a Visual Studio Pre-Build Event.
82 *
83 */
84
85
86#include <nn/fs.h>
87#include <nn/nn_Log.h>
88#include <nn/nn_Assert.h>
89#include <FileSystem.h>
90#include <GraphicsUtilities.h>
91#include <SimpleFramework.h>
92#include "ScreenSpaceTriangles.h"
93
94
95//-------------------------------------------------------------------------------------------------
96// Globals
97//-------------------------------------------------------------------------------------------------
98namespace
99{
100// data for vertices for a list of two triangles
101float g_VertexPositions[] =
102{
103 -0.7f, 0.7f, 0.0f,
104 -0.1f, -0.7f, 0.0f,
105 0.1f, 0.0f, 0.0f,
106
107 -0.1f, 0.7f, 0.0f,
108 0.7f, 0.7f, 0.0f,
109 0.7f, -0.7f, 0.0f,
110};
111
112float g_VertexColors[] =
113{
114 1.0f, 0.0f, 0.0f, 1.0f,
115 0.0f, 1.0f, 0.0f, 1.0f,
116 0.0f, 0.0f, 1.0f, 1.0f,
117
118 1.0f, 0.0f, 0.0f, 1.0f,
119 0.0f, 1.0f, 0.0f, 1.0f,
120 0.0f, 0.0f, 1.0f, 1.0f,
121};
122
123uint32_t g_VertexIndices[] =
124{
125 0, 1, 2,
126 3, 4, 5,
127};
128}
129
130
131
132//-------------------------------------------------------------------------------------------------
133// Public API
134//-------------------------------------------------------------------------------------------------
135void ScreenSpaceTriangles::Initialize(GraphicsSystem* pGraphicsSystem) NN_NOEXCEPT
136{
137 if (!m_IsInitialized)
138 {
139 m_pGraphicsSystem = pGraphicsSystem;
140
141 int64_t shaderBinFileSize = 0;
142
143 // read shader binary and create GraphicsShader object from it
144 m_GlslcData = ReadFile(&shaderBinFileSize, "rom:/NvnSimple01.glslc", m_pGraphicsSystem->GetAllocator());
145
146 m_Shader.Initialize(m_pGraphicsSystem, static_cast<GLSLCoutput*>(m_GlslcData));
147
148
149 // create memory pool for vertex data
150 size_t positionDataSize = sizeof(g_VertexPositions);
151 size_t colorDataSize = sizeof(g_VertexColors);
152 size_t indexDataSize = sizeof(g_VertexIndices);
153
154 size_t memPoolSize = positionDataSize + colorDataSize + indexDataSize;
155
156 m_VertexDataMemPool.Initialize(m_pGraphicsSystem, nvn::MemoryPoolFlags::CPU_UNCACHED | nvn::MemoryPoolFlags::GPU_CACHED, memPoolSize, "ScreenSpaceTriangles MemPool");
157
158
159 // allocate memory from our memory pool and load attribute data and indices into it
160 m_VertexDataMemPool.AllocateBuffer(&m_PositionDataBuffer, positionDataSize);
161 m_VertexDataMemPool.AllocateBuffer(&m_ColorDataBuffer, colorDataSize);
162 m_VertexDataMemPool.AllocateBuffer(&m_IndexDataBuffer, indexDataSize);
163
164 memcpy(m_PositionDataBuffer.Map(), g_VertexPositions, positionDataSize);
165 memcpy(m_ColorDataBuffer.Map(), g_VertexColors, colorDataSize);
166 memcpy(m_IndexDataBuffer.Map(), g_VertexIndices, indexDataSize);
167
168
169 // set up NVN VertexStreamState and VertexAttribState objects based on vertex attribute names and shader
170 const char* attributeNames[NumVertexAttributes];
171
172 // the ordering of the attribute names must logically match up with the ordering of the vertex streams being setup and bound
173 // (see SetupVertexAttribAndStreamStateSeparate and GenerateCommandBuffer below)
174 attributeNames[0] = "attr_position";
175 attributeNames[1] = "attr_color";
176
177 // The following function helps set up the vertex stream and attribute state objects based on vertex attribute reflection data
178 // that is provided by the GraphicsShader class. This function (and its cousin SetupVertexAttribAndStreamStateInterleaved) is
179 // used widely throughout this entire code project, so studying its internals is recommended.
180 // Here we use separate vertex streams/buffers, one for each vertex attribute.
181 SetupVertexAttribAndStreamStateSeparate(attributeNames, NumVertexAttributes, m_Shader, m_VertexAttribStates, m_VertexStreamStates);
182
183
184 // initialize render state
185 m_RenderState.Initialize();
186
187 m_RenderState.GetPolygonState()->SetCullFace(nvn::Face::NONE);
188 m_RenderState.GetPolygonState()->SetPolygonMode(nvn::PolygonMode::FILL);
189
190 m_RenderState.GetDepthStencilState()->SetDepthTestEnable(false);
191 m_RenderState.GetDepthStencilState()->SetDepthWriteEnable(false);
192
193
194 // build our command buffer to hold GPU commands to draw our triangles
195 m_CommandBuffer.Initialize(m_pGraphicsSystem);
196
197 GenerateCommandBuffer();
198
199
200 m_IsInitialized = true;
201 }
202}
203
204
205
206void ScreenSpaceTriangles::DrawFrame() NN_NOEXCEPT
207{
208 if (!m_IsPrebuiltCommandBufferUsed || m_IsScreenResolutionChanged)
209 {
210 GenerateCommandBuffer();
211 }
212
213 // execute GPU commands to draw the triangles
214 m_pGraphicsSystem->GetQueue()->SubmitCommands(1, &m_CommandHandle);
215
216 m_IsScreenResolutionChanged = false;
217}
218
219
220
221void ScreenSpaceTriangles::Finalize() NN_NOEXCEPT
222{
223 if (m_IsInitialized)
224 {
225 m_CommandBuffer.Finalize();
226
227 m_PositionDataBuffer.Finalize();
228 m_ColorDataBuffer.Finalize();
229 m_IndexDataBuffer.Finalize();
230 m_VertexDataMemPool.Finalize();
231
232 m_Shader.Finalize();
233
234 m_pGraphicsSystem->GetAllocator()->Free(m_GlslcData);
235 m_GlslcData = nullptr;
236
237 m_pGraphicsSystem = nullptr;
238 m_CommandHandle = 0;
239
240 m_IsInitialized = false;
241 }
242}
243
244
245
246//-------------------------------------------------------------------------------------------------
247// Private methods
248//-------------------------------------------------------------------------------------------------
249void ScreenSpaceTriangles::GenerateCommandBuffer() NN_NOEXCEPT
250{
251 // generate GPU commands to draw the triangles
252 nvn::CommandBuffer* pCommandBuffer = m_CommandBuffer.StartRecording();
253 {
254 // scissor/viewport
255 m_pGraphicsSystem->SetDefaultViewportAndScissor(pCommandBuffer);
256
257 // clear color buffer
258 static float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
259
260 pCommandBuffer->ClearColor(0, color, nvn::ClearColorMask::RGBA);
261
262 // render state
263 m_RenderState.Bind(pCommandBuffer);
264
265 // bind shader
266 m_Shader.Bind(pCommandBuffer);
267
268 // bind vertex buffer data
269 pCommandBuffer->BindVertexAttribState(NumVertexAttributes, m_VertexAttribStates);
270 pCommandBuffer->BindVertexStreamState(NumVertexAttributes, m_VertexStreamStates);
271
272 BindVertexBuffer(0, &m_PositionDataBuffer, pCommandBuffer);
273 BindVertexBuffer(1, &m_ColorDataBuffer, pCommandBuffer);
274
275 // draw call
276 int numIndices = sizeof(g_VertexIndices) / sizeof(*g_VertexIndices);
277 pCommandBuffer->DrawElements(nvn::DrawPrimitive::TRIANGLES, nvn::IndexType::UNSIGNED_INT, numIndices, m_IndexDataBuffer.GetAddress());
278 }
279 m_CommandHandle = m_CommandBuffer.EndRecording();
280}
281
282
283//-------------------------------------------------------------------------------------------------
284// main
285//-------------------------------------------------------------------------------------------------
286extern "C" void nnMain()
287{
288 ScreenSpaceTriangles scene;
289 SimpleFrameworkMainWithDebugInfo(&scene, GraphicsSystemParams(), u8"ScreenSpaceTriangles", Color(0x000000));
290}