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 ).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(256)
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 #if 0
222 //----------------------------------------
223 // 描画環境をセットする
224 void
225 SmSceneCtrl::SetEnvironment( s32 cameraIndex )
226 {
227 NW_UNUSED_VARIABLE(cameraIndex);
228
229 nw::gfx::SceneEnvironment& sceneEnvironment = m_RenderContext->GetSceneEnvironment();
230
231 // sceneEnvironment.SetActiveCamera(cameraIndex);
232 m_RenderContext->SetActiveCamera(cameraIndex);
233
234 if (m_SceneContext->GetAmbientLightsBegin() != m_SceneContext->GetAmbientLightsEnd())
235 {
236 sceneEnvironment.SetAmbientLight(*m_SceneContext->GetAmbientLightsBegin());
237 }
238
239 if (m_SceneContext->GetHemiSphereLightsBegin() != m_SceneContext->GetHemiSphereLightsEnd())
240 {
241 sceneEnvironment.SetHemiSphereLight(*m_SceneContext->GetHemiSphereLightsBegin());
242 }
243
244 std::for_each(
245 m_SceneContext->GetFragmentLightsBegin(),
246 m_SceneContext->GetFragmentLightsEnd(),
247 std::bind1st(std::mem_fun(&nw::gfx::SceneEnvironment::SetFragmentLight), &sceneEnvironment));
248
249 std::for_each(
250 m_SceneContext->GetVertexLightsBegin(),
251 m_SceneContext->GetVertexLightsEnd(),
252 std::bind1st(std::mem_fun(&nw::gfx::SceneEnvironment::SetVertexLight), &sceneEnvironment));
253
254 if (m_SceneContext->GetFogBegin() != m_SceneContext->GetFogEnd())
255 {
256 sceneEnvironment.SetFog(0, *m_SceneContext->GetFogBegin());
257 }
258 }
259 #endif
260