1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: SmSceneCtrl.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 #include "../include/SmSceneCtrl.h"
19
20
21 //----------------------------------------
22 //
23 struct RenderSceneInternalFunctor
24 : public std::unary_function<nw::gfx::RenderElement&, void>
25 {
26 nw::gfx::RenderContext* m_RenderContext;
27 nw::gfx::MeshRenderer* m_MeshRenderer;
28
RenderSceneInternalFunctorRenderSceneInternalFunctor29 RenderSceneInternalFunctor(nw::gfx::RenderContext* renderContext, nw::gfx::MeshRenderer* meshRenderer)
30 : m_RenderContext(renderContext), m_MeshRenderer(meshRenderer)
31 {
32 NW_NULL_ASSERT(renderContext);
33 NW_NULL_ASSERT(meshRenderer);
34 }
35
operator ()RenderSceneInternalFunctor36 void operator()(nw::gfx::RenderElement& element)
37 {
38 if (element.IsCommand())
39 {
40 nw::gfx::RenderCommand* command = element.GetCommand();
41 NW_NULL_ASSERT(command);
42 command->Invoke(m_RenderContext);
43 }
44 else
45 {
46 nw::gfx::ResMesh mesh = element.GetMesh();
47 nw::gfx::Model* model = element.GetModel();
48 model->PreRenderSignal()(model, mesh, m_RenderContext);
49 m_MeshRenderer->RenderMesh(mesh, model);
50 model->PostRenderSignal()(model, mesh, m_RenderContext);
51 }
52 NW_GL_ASSERT();
53 }
54 };
55
56
57 //----------------------------------------
58 // コンストラクタ
SmSceneCtrl(nw::gfx::RenderContext * renderContext)59 SmSceneCtrl::SmSceneCtrl( nw::gfx::RenderContext* renderContext )
60 : m_SceneContext( NULL ),
61 m_SceneTraverser( NULL ),
62 m_SceneUpdater( NULL ),
63 m_SceneInitializer( NULL ),
64 m_RenderContext( renderContext ),
65 m_PriorMaterialRenderKeyFactory( NULL ),
66 m_PriorDepthRenderKeyFactory( NULL ),
67 m_RenderQueue( NULL ),
68 m_MeshRenderer( NULL )
69 {
70 m_SceneContext = nw::gfx::SceneContext::Builder()
71 .MaxSceneNodes( 128 ).MaxModels(128).Create( m_Allocator );
72
73 m_SceneTraverser = nw::gfx::SceneTraverser::Builder()
74 .Create( m_Allocator );
75
76 nw::gfx::WorldMatrixUpdater* worldMatrixUpdater = nw::gfx::WorldMatrixUpdater::Builder()
77 .Create( m_Allocator );
78
79 nw::gfx::SkeletonUpdater* skeletonUpdater = nw::gfx::SkeletonUpdater::Builder()
80 .Create( m_Allocator );
81
82 m_SceneUpdater = nw::gfx::SceneUpdater::Builder()
83 .WorldMatrixUpdaterPtr(worldMatrixUpdater)
84 .SkeletonUpdaterPtr(skeletonUpdater)
85 .Create( m_Allocator );
86
87 nw::gfx::IMaterialIdGenerator* materialIdGenerator =
88 nw::gfx::SortingMaterialIdGenerator::Builder()
89 .IsFixedSizeMemory(true)
90 .MaxMaterials(128)
91 .Create(m_Allocator);
92
93 m_SceneInitializer = nw::gfx::SceneInitializer::Builder()
94 .MaterialIdGenerator(materialIdGenerator)
95 .Create( m_Allocator );
96
97 m_PriorMaterialRenderKeyFactory =
98 nw::gfx::CreatePriorMaterialRenderKeyFactory( m_Allocator );
99
100 m_PriorDepthRenderKeyFactory =
101 nw::gfx::CreatePriorDepthReverseDepthRenderKeyFactory( m_Allocator );
102
103 m_RenderQueue = nw::gfx::RenderQueue::Builder()
104 .MaxRenderElements(512)
105 .Create( m_Allocator );
106
107 m_RenderQueue->Reset(
108 m_PriorMaterialRenderKeyFactory,
109 m_PriorDepthRenderKeyFactory,
110 m_PriorMaterialRenderKeyFactory,
111 m_PriorMaterialRenderKeyFactory);
112
113 m_MeshRenderer = nw::gfx::MeshRenderer::Create( m_Allocator );
114 m_MeshRenderer->SetRenderContext( m_RenderContext );
115 }
116
117
118 //----------------------------------------
119 // デストラクタ
~SmSceneCtrl()120 SmSceneCtrl::~SmSceneCtrl()
121 {
122 nw::gfx::SafeDestroy(m_SceneInitializer);
123 nw::gfx::SafeDestroy(m_SceneTraverser);
124 nw::gfx::SafeDestroy(m_SceneUpdater);
125 nw::gfx::SafeDestroy(m_SceneContext);
126
127
128 nw::gfx::SafeDestroy(m_MeshRenderer);
129 nw::gfx::SafeDestroy(m_RenderQueue);
130 nw::gfx::SafeDestroy(m_PriorMaterialRenderKeyFactory);
131 nw::gfx::SafeDestroy(m_PriorDepthRenderKeyFactory);
132 }
133
134
135 //----------------------------------------
136 // シーンを更新する
137 void
UpdateScene()138 SmSceneCtrl::UpdateScene()
139 {
140 m_SceneUpdater->UpdateAll(m_SceneContext);
141 }
142
143
144 //----------------------------------------
145 // シーンを初期化する
146 void
InitializeScene(nw::gfx::SceneNode * sceneRoot)147 SmSceneCtrl::InitializeScene(nw::gfx::SceneNode* sceneRoot)
148 {
149 m_SceneTraverser->Begin(m_SceneContext);
150 sceneRoot->Accept(m_SceneInitializer);
151 m_SceneTraverser->End();
152
153 TraverseScene(sceneRoot);
154 }
155
156
157 //----------------------------------------
158 void
TraverseScene(nw::gfx::SceneNode * sceneRoot)159 SmSceneCtrl::TraverseScene(nw::gfx::SceneNode* sceneRoot)
160 {
161 this->m_SceneTraverser->Begin(this->m_SceneContext);
162 sceneRoot->Accept(this->m_SceneTraverser);
163 this->m_SceneTraverser->End();
164
165 // パーティクルセットの依存順でソートする
166 std::sort(
167 this->m_SceneContext->GetParticleSetBegin(),
168 this->m_SceneContext->GetParticleSetEnd(),
169 nw::gfx::ParticleSetCompare());
170 }
171
172 //----------------------------------------
173 void
SetSceneEnvironmentSetting(nw::gfx::SceneEnvironmentSetting * sceneEnvironmentSetting)174 SmSceneCtrl::SetSceneEnvironmentSetting( nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting )
175 {
176 nw::gfx::SceneEnvironment& sceneEnvironment = m_RenderContext->GetSceneEnvironment();
177 sceneEnvironmentSetting->ResolveReference(*m_SceneContext);
178 sceneEnvironment.ApplyFrom(*sceneEnvironmentSetting);
179 }
180
181
182
183 //----------------------------------------
184 // カメラの視界に基づいてシーンを更新し、描画キューを構築します。
185 void
SubmitView(nw::gfx::Camera * currentCamera)186 SmSceneCtrl::SubmitView( nw::gfx::Camera* currentCamera )
187 {
188 nw::gfx::SceneEnvironment& sceneEnvironment = m_RenderContext->GetSceneEnvironment();
189 // nw::gfx::Camera* camera = sceneEnvironment.GetActiveCamera();
190
191 // Fog を更新します。
192 nw::gfx::FogArray::iterator fogEnd = m_SceneContext->GetFogEnd();
193 for (nw::gfx::FogArray::iterator fog = m_SceneContext->GetFogBegin();
194 fog != fogEnd;
195 ++fog)
196 {
197 if (*fog != NULL)
198 {
199 (*fog)->Update( currentCamera );
200 }
201 }
202
203 m_RenderQueue->Reset();
204 m_SceneUpdater->SubmitView( m_RenderQueue, m_SceneContext, *currentCamera, 0 );
205
206 // ソートする
207 std::sort( m_RenderQueue->Begin(), m_RenderQueue->End(), nw::gfx::RenderElementCompare());
208 }
209
210 //----------------------------------------
211 // 描画を行います。
212 void
Render()213 SmSceneCtrl::Render()
214 {
215 // m_RenderContext->SetCameraMatrix(camera);
216
217 std::for_each(
218 m_RenderQueue->Begin(),
219 m_RenderQueue->End(),
220 RenderSceneInternalFunctor(m_RenderContext, m_MeshRenderer));
221 }
222
223
224 //----------------------------------------
225 // ログを出力します。
226 void
OutputLog()227 SmSceneCtrl::OutputLog()
228 {
229 // m_SceneContextが保持するノードの状況を出力します。
230 {
231 u32 cnt = 0;
232 {
233 nw::gfx::SceneContext::SceneNodeArray::iterator end = m_SceneContext->GetSceneNodesEnd();
234 for (nw::gfx::SceneContext::SceneNodeArray::iterator i = m_SceneContext->GetSceneNodesBegin(); i != end;)
235 {
236 i++;
237 cnt++;
238 }
239 NW_DEV_LOG( "SceneContex:SceneNode Num %d\n", cnt );
240 cnt = 0;
241 }
242
243 {
244 nw::gfx::SceneContext::ModelArray::iterator end = m_SceneContext->GetModelsEnd();
245 for (nw::gfx::SceneContext::ModelArray::iterator i = m_SceneContext->GetModelsBegin(); i != end;)
246 {
247 i++;
248 cnt++;
249 }
250 NW_DEV_LOG( "SceneContex:ModelArray Num %d\n", cnt );
251 cnt = 0;
252 }
253
254 {
255 nw::gfx::SceneContext::ParticleModelArray::iterator end = m_SceneContext->GetParticleModelEnd();
256 for (nw::gfx::SceneContext::ParticleModelArray::iterator i = m_SceneContext->GetParticleModelBegin(); i != end;)
257 {
258 i++;
259 cnt++;
260 }
261 NW_DEV_LOG( "SceneContex:Particle Model Array Num %d\n", cnt );
262 cnt = 0;
263 }
264
265 {
266 nw::gfx::SceneContext::ParticleSetArray::iterator end = m_SceneContext->GetParticleSetEnd();
267 for (nw::gfx::SceneContext::ParticleSetArray::iterator i = m_SceneContext->GetParticleSetBegin(); i != end;)
268 {
269 i++;
270 cnt++;
271 }
272 NW_DEV_LOG( "SceneContex:Particle Set Array Num %d\n", cnt );
273 cnt = 0;
274 }
275 }
276
277 }
278
279
280 #if 0
281 //----------------------------------------
282 // 描画環境をセットする
283 void
284 SmSceneCtrl::SetEnvironment( s32 cameraIndex )
285 {
286 NW_UNUSED_VARIABLE(cameraIndex);
287
288 nw::gfx::SceneEnvironment& sceneEnvironment = m_RenderContext->GetSceneEnvironment();
289
290 // sceneEnvironment.SetActiveCamera(cameraIndex);
291 m_RenderContext->SetActiveCamera(cameraIndex);
292
293 if (m_SceneContext->GetAmbientLightsBegin() != m_SceneContext->GetAmbientLightsEnd())
294 {
295 sceneEnvironment.SetAmbientLight(*m_SceneContext->GetAmbientLightsBegin());
296 }
297
298 if (m_SceneContext->GetHemiSphereLightsBegin() != m_SceneContext->GetHemiSphereLightsEnd())
299 {
300 sceneEnvironment.SetHemiSphereLight(*m_SceneContext->GetHemiSphereLightsBegin());
301 }
302
303 std::for_each(
304 m_SceneContext->GetFragmentLightsBegin(),
305 m_SceneContext->GetFragmentLightsEnd(),
306 std::bind1st(std::mem_fun(&nw::gfx::SceneEnvironment::SetFragmentLight), &sceneEnvironment));
307
308 std::for_each(
309 m_SceneContext->GetVertexLightsBegin(),
310 m_SceneContext->GetVertexLightsEnd(),
311 std::bind1st(std::mem_fun(&nw::gfx::SceneEnvironment::SetVertexLight), &sceneEnvironment));
312
313 if (m_SceneContext->GetFogBegin() != m_SceneContext->GetFogEnd())
314 {
315 sceneEnvironment.SetFog(0, *m_SceneContext->GetFogBegin());
316 }
317 }
318 #endif
319