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