1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: GrRenderer.cpp
4
5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain proprietary
8 information of Nintendo and/or its licensed developers and are protected by
9 national and international copyright laws. They may not be disclosed to third
10 parties or copied or duplicated in any form, in whole or in part, without the
11 prior written consent of Nintendo.
12
13 The content herein is highly confidential and should be handled accordingly.
14
15 $Revision: $
16 *---------------------------------------------------------------------------*/
17
18 #define NW_DEBUG_CHECK_MEMORY_LEAK
19
20 #include "GrRenderer.h"
21
22 //----------------------------------------------------------
23 void
Initialize(const nn::math::VEC3 & halfEdges)24 PrimitiveBox::Initialize(const nn::math::VEC3& halfEdges)
25 {
26 // 頂点ストリーム(Position)
27 static const f32 s_BoxVtxStreamPosition[PrimitiveBox::VERTEX_NUM * 3] =
28 {
29 -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
30 -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f,
31 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f,
32 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f,
33 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f,
34 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f,
35 -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
36 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
37 -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f,
38 -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f,
39 -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f,
40 -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f,
41 };
42
43 // 頂点ストリーム (Normal)
44 static const f32 s_BoxVtxStreamNormal[PrimitiveBox::VERTEX_NUM * 3] =
45 {
46 -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f,
47 -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f,
48 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f,
49 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f,
50 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f,
51 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f,
52 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f,
53 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f,
54 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f,
55 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f,
56 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f,
57 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f,
58 };
59
60 // 頂点ストリーム(Color)
61 static const f32 s_BoxVtxStreamColor[PrimitiveBox::VERTEX_NUM * 4] =
62 {
63 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
64 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
65 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
66 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
67 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
68 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
69 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
70 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
71 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
72 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
73 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
74 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f
75 } ;
76
77 // 6 面体の頂点インデックス
78 static const u16 s_BoxVtxStreamIndex[PrimitiveBox::VERTEX_NUM * 1] =
79 {
80 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
81 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
82 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
83 };
84
85 std::memcpy(m_StreamPosition, s_BoxVtxStreamPosition, sizeof(s_BoxVtxStreamPosition));
86
87
88 for (u32 index = 0; index < PrimitiveBox::VERTEX_NUM; index++)
89 {
90 m_StreamPosition[3 * index ] *= halfEdges.x;
91 m_StreamPosition[3 * index + 1] *= halfEdges.y;
92 m_StreamPosition[3 * index + 2] *= halfEdges.z;
93 }
94
95 std::memcpy(m_StreamNormal, s_BoxVtxStreamNormal, sizeof(s_BoxVtxStreamNormal));
96 std::memcpy(m_StreamColor, s_BoxVtxStreamColor, sizeof(s_BoxVtxStreamColor));
97 std::memcpy(m_StreamIndex, s_BoxVtxStreamIndex, sizeof(s_BoxVtxStreamIndex));
98
99 nngxUpdateBuffer(this, sizeof(PrimitiveBox));
100 }
101
102 //----------------------------------------------------------
103 void
Initialize(nw::demo::DemoAllocator * deviceAllocator,const wchar_t * shaderFilePath)104 GrPrimitiveRenderer::Initialize(
105 nw::demo::DemoAllocator* deviceAllocator,
106 const wchar_t* shaderFilePath
107 )
108 {
109 NW_NULL_ASSERT(deviceAllocator);
110 m_DeviceAllocator = deviceAllocator;
111
112 InitializeShader(shaderFilePath);
113
114 InitializePrimitive();
115
116 InitializeEnvironments();
117 }
118
119 //----------------------------------------------------------
120 void
Finalize()121 GrPrimitiveRenderer::Finalize()
122 {
123 m_VertexBox.DisableAll();
124
125 m_DeviceAllocator->Free(m_PrimitiveBox);
126 m_DeviceAllocator->Free(m_ShaderBinary);
127 }
128
129 //----------------------------------------------------------
130 void
InitializeShader(const wchar_t * shaderFilePath)131 GrPrimitiveRenderer::InitializeShader(const wchar_t* shaderFilePath)
132 {
133 bool isSuccess = false;
134 NW_UNUSED_VARIABLE(isSuccess);
135
136 // シェーダーの初期化
137 nw::ut::MoveArray<u8> shaderFile =
138 nw::demo::Utility::LoadFile(m_DeviceAllocator, shaderFilePath );
139 m_ShaderBinary = shaderFile.release();
140
141 // シェーダーバイナリを指定して初期化
142 // 0番目の実行イメージを頂点シェーダーとして有効化
143 m_Shader.SetupBinary(m_ShaderBinary, 0, -1);
144
145 // 文字列で、Uniform を検索
146 isSuccess = m_Shader.SearchBindSymbol(&m_BindSymbolWorldMtx, "world");
147 NW_ASSERT(isSuccess);
148
149 isSuccess = m_Shader.SearchBindSymbol(&m_BindSymbolProjMtx, "proj");
150 NW_ASSERT(isSuccess);
151
152 isSuccess = m_Shader.SearchBindSymbol(&m_BindSymbolViewMtx, "view");
153 NW_ASSERT(isSuccess);
154 }
155
156 //----------------------------------------------------------
157 void
InitializePrimitive()158 GrPrimitiveRenderer::InitializePrimitive()
159 {
160 bool isSuccess = false;
161 NW_UNUSED_VARIABLE(isSuccess);
162
163 uptr physicalAddr = 0;
164
165 nn::gr::CTR::BindSymbolVSInput symbolPosition;
166 nn::gr::CTR::BindSymbolVSInput symbolColor;
167 nn::gr::CTR::BindSymbolVSInput symbolNormal;
168
169 m_PrimitiveBox =
170 static_cast<PrimitiveBox*>(m_DeviceAllocator->Alloc(sizeof(PrimitiveBox), 128));
171 NW_ASSERT(m_PrimitiveBox);
172
173 const nn::math::VEC3 halfEdges(10.0f, 10.0f, 10.0f);
174
175 m_PrimitiveBox->Initialize(halfEdges);
176
177 // 文字列による location の検索
178 isSuccess = m_Shader.SearchBindSymbol(&symbolPosition, "Position");
179 NW_ASSERT(isSuccess);
180
181 isSuccess = m_Shader.SearchBindSymbol(&symbolColor, "Color");
182 NW_ASSERT(isSuccess);
183
184 isSuccess = m_Shader.SearchBindSymbol(&symbolNormal, "Normal");
185 NW_ASSERT(isSuccess);
186
187 // 頂点ストリーム(Position)の設定
188 physicalAddr = nngxGetPhysicalAddr(reinterpret_cast<uptr>(m_PrimitiveBox->m_StreamPosition));
189 m_VertexBox.EnableAttrAsArray(symbolPosition, physicalAddr, PICA_DATA_SIZE_3_FLOAT);
190
191 // 頂点ストリーム(Color)の設定
192 physicalAddr = nngxGetPhysicalAddr(reinterpret_cast<uptr>(m_PrimitiveBox->m_StreamColor));
193 m_VertexBox.EnableAttrAsArray(symbolColor, physicalAddr, PICA_DATA_SIZE_4_FLOAT);
194
195 // 頂点ストリーム(Normal)の設定
196 physicalAddr = nngxGetPhysicalAddr(reinterpret_cast<uptr>(m_PrimitiveBox->m_StreamNormal));
197 m_VertexBox.EnableAttrAsArray(symbolNormal, physicalAddr, PICA_DATA_SIZE_3_FLOAT);
198
199 // インデックスの設定
200 m_IndexStreamBox.physicalAddr = nngxGetPhysicalAddr(reinterpret_cast<uptr>(m_PrimitiveBox->m_StreamIndex));
201 m_IndexStreamBox.drawVtxNum = m_PrimitiveBox->VERTEX_NUM;
202
203 // インデックスを u16 で定義している
204 m_IndexStreamBox.isUnsignedByte = false;
205 }
206
207 //----------------------------------------------------------
208 void
InitializeEnvironments()209 GrPrimitiveRenderer::InitializeEnvironments()
210 {
211 m_Viewport.Set(0, 0, NN_GX_DISPLAY0_WIDTH, NN_GX_DISPLAY0_HEIGHT);
212 m_Scissor.Set(0, 0, NN_GX_DISPLAY0_WIDTH, NN_GX_DISPLAY0_HEIGHT);
213 }
214
215 //----------------------------------------------------------
216 bit32*
MakeSceneBeginCommand(bit32 * command)217 GrPrimitiveRenderer::MakeSceneBeginCommand(bit32* command)
218 {
219 command = nn::gr::CTR::MakeDisableAllCommand(command);
220
221 // ビューポート設定.
222 command = m_Viewport.MakeCommand(command);
223
224 // シザー設定.
225 command = m_Scissor.MakeCommand(command);
226
227 // シェーダバイナリの設定 ( glUseProgram() )
228 command = m_Shader.MakeFullCommand(command);
229
230 // レンダーステートの設定
231 // Cull, Depth, Stencil, AlphaTest, Blend, etc.
232 nn::gr::RenderState render_state;
233 command = render_state.MakeCommand(command);
234
235 // テクスチャの設定
236 nn::gr::Texture texture;
237 texture.unit0.texType = PICA_DATA_TEXTURE0_SAMPLER_TYPE_FALSE;
238 texture.unit1.texType = PICA_DATA_TEXTURE1_SAMPLER_TYPE_FALSE;
239 texture.unit2.texType = PICA_DATA_TEXTURE2_SAMPLER_TYPE_FALSE;
240 texture.unit3.texType = PICA_DATA_TEXTURE3_SAMPLER_TYPE_FALSE;
241
242 command = texture.MakeCommand(command);
243
244 //テクスチャコンバイナの設定
245 nn::gr::Combiner combiner;
246
247 // テクスチャコンバイナの設定の変更
248 // プライマリカラーで置換
249 combiner.stage[0].rgb.combine = PICA_DATA_TEX_ENV_COMBINE_REPLACE;
250 combiner.stage[0].rgb.source[0] = PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR;
251 combiner.stage[0].rgb.source[1] = PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_SECONDARY_COLOR_DMP;
252 command = combiner.MakeCommand(command);
253
254 // 頂点を使用し始める前に、全ての頂点属性を無効化
255 command = nn::gr::Vertex::MakeDisableCommand(command);
256
257 return command;
258 }
259
260 //----------------------------------------------------------
261 bit32*
MakeDrawBoxCommand(bit32 * command,const nn::math::MTX34 & worldMatrix)262 GrPrimitiveRenderer::MakeDrawBoxCommand(bit32* command, const nn::math::MTX34& worldMatrix)
263 {
264 nn::gr::Vertex* pVertex = &m_VertexBox;
265 nn::gr::Vertex::IndexStream* pIndexStream = &m_IndexStreamBox;
266
267 // モデル行列の設定
268 command = m_BindSymbolWorldMtx.MakeUniformCommand(command, worldMatrix);
269
270 // Box プリミティブを描画
271
272 // glBindBuffer( GL_ARRAY_BUFFER )
273 command = pVertex->MakeEnableAttrCommand(command);
274
275 // glBindBuffer( GL_ELEMENT_ARRAY_BUFFER ) + glDrawElements()
276 command = pVertex->MakeDrawCommand(command, *pIndexStream);
277
278 return command;
279 }
280