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