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