1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_SceneEnvironment.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: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #include "precompiled.h"
19 
20 #include <nw/os/os_Memory.h>
21 #include <nw/gfx/gfx_SceneEnvironment.h>
22 #include <nw/gfx/gfx_SceneContext.h>
23 #include <algorithm>
24 
25 namespace nw
26 {
27 namespace gfx
28 {
29 
30 //----------------------------------------
31 void
ApplyFrom(const SceneEnvironmentSetting & setting)32 SceneEnvironment::ApplyFrom(
33     const SceneEnvironmentSetting& setting
34 )
35 {
36     SceneEnvironmentSetting::CameraBinderArray::const_iterator cameraBinderEnd = setting.GetCameraEnd();
37     for (SceneEnvironmentSetting::CameraBinderArray::const_iterator cameraBinder = setting.GetCameraBegin();
38         cameraBinder != cameraBinderEnd;
39         ++cameraBinder)
40     {
41         int cameraIndex = (*cameraBinder).index;
42         Camera* camera = (*cameraBinder).camera;
43 
44         NW_MINMAX_ASSERT(cameraIndex, 0, m_Cameras.size());
45         m_Cameras[cameraIndex] = camera;
46     }
47 
48     SceneEnvironmentSetting::FogBinderArray::const_iterator fogBinderEnd = setting.GetFogEnd();
49     for (SceneEnvironmentSetting::FogBinderArray::const_iterator fogBinder = setting.GetFogBegin();
50         fogBinder != fogBinderEnd;
51         ++fogBinder)
52     {
53         int fogIndex = (*fogBinder).index;
54         Fog* fog = (*fogBinder).fog;
55 
56         NW_MINMAX_ASSERT(fogIndex, 0, m_Fogs.size());
57         m_Fogs[fogIndex] = fog;
58     }
59 
60     SceneEnvironmentSetting::LightSetBinderArray::const_iterator lightSetBinderEnd = setting.GetLightSetEnd();
61     for (SceneEnvironmentSetting::LightSetBinderArray::const_iterator lightSetBinder = setting.GetLightSetBegin();
62         lightSetBinder != lightSetBinderEnd;
63         ++lightSetBinder)
64     {
65         int lightSetIndex = (*lightSetBinder).index;
66         LightSet* lightSet = (*lightSetBinder).lightSet.Get();
67 
68         NW_MINMAX_ASSERT(lightSetIndex, 0, m_LightSets.size());
69         m_LightSets[lightSetIndex] = lightSet;
70     }
71 }
72 
73 //----------------------------------------
74 void
ClearSettings()75 SceneEnvironment::ClearSettings()
76 {
77     std::fill(this->m_Cameras.begin(), this->m_Cameras.end(), static_cast<nw::gfx::Camera*>(NULL));
78     std::fill(this->m_Fogs.begin(), this->m_Fogs.end(), static_cast<nw::gfx::Fog*>(NULL));
79     std::fill(this->m_LightSets.begin(), this->m_LightSets.end(), static_cast<nw::gfx::LightSet*>(NULL));
80 }
81 
82 //----------------------------------------
83 void
Reset()84 SceneEnvironment::Reset()
85 {
86     ResetLightSet();
87     ResetAmbientLight();
88     ResetHemiSphereLight();
89     ResetFragmentLights();
90 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
91     ResetVertexLights();
92 #endif
93     ResetFog();
94 
95     m_Camera = NULL;
96     m_CameraIndex = -1;
97 }
98 
99 //----------------------------------------
100 void
ResetFragmentLights()101 SceneEnvironment::ResetFragmentLights()
102 {
103     for (int i = 0; i < m_ActiveFragmentLightCount; ++i)
104     {
105         m_FragmentLights[i] = NULL;
106     }
107     m_ActiveFragmentLightCount = 0;
108     m_FragmentLightsDirty = true;
109 }
110 
111 //----------------------------------------
112 void
ResetVertexLights()113 SceneEnvironment::ResetVertexLights()
114 {
115     for (int i = 0; i < m_ActiveVertexLightCount; ++i)
116     {
117         m_VertexLights[i] = NULL;
118     }
119     m_ActiveVertexLightCount = 0;;
120     m_VertexLightsDirty = true;
121 }
122 
123 //----------------------------------------
124 void
ResetHemiSphereLight()125 SceneEnvironment::ResetHemiSphereLight()
126 {
127     m_HemiSphereLight = NULL;
128     m_HemiSphereLightDirty = true;
129 }
130 
131 //----------------------------------------
132 void
ResetAmbientLight()133 SceneEnvironment::ResetAmbientLight()
134 {
135     m_AmbientLight = NULL;
136     m_AmbientLightDirty = true;
137 }
138 
139 //----------------------------------------
140 void
ResetFog()141 SceneEnvironment::ResetFog()
142 {
143     m_Fog = NULL;
144     m_FogDirty =true;
145 }
146 
147 //----------------------------------------
148 void
ResetLightSet()149 SceneEnvironment::ResetLightSet()
150 {
151     m_LightSetIndex = -1;
152 }
153 
154 //----------------------------------------
155 void
SetActiveLightSet(int index)156 SceneEnvironment::SetActiveLightSet(int index)
157 {
158     NW_MINMAX_ASSERT(index, 0, m_LightSets.size());
159     LightSet* lightSet = this->m_LightSets[index];
160 
161     // LightSet が NULL の場合は前回の設定をそのまま利用する。
162     // 同一の LightSet が設定された場合は設定を無視します。
163     if ((lightSet != NULL) && (m_LightSetIndex != index))
164     {
165         m_LightSetIndex = index;
166 
167         AmbientLight* ambientLight = lightSet->GetAmbientLight();
168         if (m_AmbientLight != ambientLight)
169         {
170             m_AmbientLightDirty = true;
171             m_AmbientLight = (ambientLight != NULL && ambientLight->GetResAmbientLight().IsLightEnabled()) ? ambientLight : NULL;
172         }
173 
174         HemiSphereLight* hemiSphereLight = lightSet->GetHemiSphereLight();
175         if (m_HemiSphereLight != hemiSphereLight)
176         {
177             m_HemiSphereLightDirty = true;
178             m_HemiSphereLight = (hemiSphereLight != NULL && hemiSphereLight->GetResHemiSphereLight().IsLightEnabled()) ? hemiSphereLight : NULL;
179         }
180 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
181         m_ActiveVertexLightCount = 0;
182         int vertexLightMaxCount = m_VertexLights.capacity();
183         VertexLightArray::iterator vertexLightEnd = lightSet->GetVertexLightEnd();
184         for (VertexLightArray::iterator iter = lightSet->GetVertexLightBegin();
185             iter != vertexLightEnd;
186             ++iter)
187         {
188             m_VertexLightsDirty = true;
189             if (m_ActiveVertexLightCount == vertexLightMaxCount)
190             {
191                 break;
192             }
193 
194             if ((*iter)->GetResVertexLight().IsLightEnabled())
195             {
196                 m_VertexLights[m_ActiveVertexLightCount] = (*iter);
197                 ++m_ActiveVertexLightCount;
198             }
199         }
200 #endif
201 
202         m_ActiveFragmentLightCount = 0;
203         FixedFragmentLightArray::iterator fragmentLightEnd = lightSet->GetFragmentLightEnd();
204         for (FixedFragmentLightArray::iterator iter = lightSet->GetFragmentLightBegin();
205             iter != fragmentLightEnd;
206             ++iter)
207         {
208             m_FragmentLightsDirty = true;
209             if (m_ActiveFragmentLightCount == LIGHT_COUNT)
210             {
211                 break;
212             }
213 
214             if ((*iter)->GetResFragmentLight().IsLightEnabled())
215             {
216                 m_FragmentLights[m_ActiveFragmentLightCount] = (*iter);
217                 ++m_ActiveFragmentLightCount;
218             }
219         }
220     }
221 }
222 
223 } // namespace gfx
224 } // namespace nw
225