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: 27615 $
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 }
96 
97 //----------------------------------------
98 void
ResetFragmentLights()99 SceneEnvironment::ResetFragmentLights()
100 {
101     for (int i = 0; i < m_ActiveFragmentLightCount; ++i)
102     {
103         m_FragmentLights[i] = NULL;
104     }
105     m_ActiveFragmentLightCount = 0;
106     m_FragmentLightsDirty = true;
107 }
108 
109 //----------------------------------------
110 void
ResetVertexLights()111 SceneEnvironment::ResetVertexLights()
112 {
113     for (int i = 0; i < m_ActiveVertexLightCount; ++i)
114     {
115         m_VertexLights[i] = NULL;
116     }
117     m_ActiveVertexLightCount = 0;;
118     m_VertexLightsDirty = true;
119 }
120 
121 //----------------------------------------
122 void
ResetHemiSphereLight()123 SceneEnvironment::ResetHemiSphereLight()
124 {
125     m_HemiSphereLight = NULL;
126     m_HemiSphereLightDirty = true;
127 }
128 
129 //----------------------------------------
130 void
ResetAmbientLight()131 SceneEnvironment::ResetAmbientLight()
132 {
133     m_AmbientLight = NULL;
134     m_AmbientLightDirty = true;
135 }
136 
137 //----------------------------------------
138 void
ResetFog()139 SceneEnvironment::ResetFog()
140 {
141     m_Fog = NULL;
142     m_FogDirty =true;
143 }
144 
145 //----------------------------------------
146 void
ResetLightSet()147 SceneEnvironment::ResetLightSet()
148 {
149     m_LightSetIndex = -1;
150 }
151 
152 //----------------------------------------
153 void
SetActiveLightSet(int index)154 SceneEnvironment::SetActiveLightSet(int index)
155 {
156     NW_MINMAX_ASSERT(index, 0, m_LightSets.size());
157     LightSet* lightSet = this->m_LightSets[index];
158 
159     // LightSet が NULL の場合は前回の設定をそのまま利用する。
160     // 同一の LightSet が設定された場合は設定を無視します。
161     if ((lightSet != NULL) && (m_LightSetIndex != index))
162     {
163         m_LightSetIndex = index;
164 
165         AmbientLight* ambientLight = lightSet->GetAmbientLight();
166         if (m_AmbientLight != ambientLight)
167         {
168             m_AmbientLightDirty = true;
169             m_AmbientLight = (ambientLight != NULL && ambientLight->GetResAmbientLight().IsLightEnabled()) ? ambientLight : NULL;
170         }
171 
172         HemiSphereLight* hemiSphereLight = lightSet->GetHemiSphereLight();
173         if (m_HemiSphereLight != hemiSphereLight)
174         {
175             m_HemiSphereLightDirty = true;
176             m_HemiSphereLight = (hemiSphereLight != NULL && hemiSphereLight->GetResHemiSphereLight().IsLightEnabled()) ? hemiSphereLight : NULL;
177         }
178 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
179         m_ActiveVertexLightCount = 0;
180         int vertexLightMaxCount = m_VertexLights.capacity();
181         VertexLightArray::iterator vertexLightEnd = lightSet->GetVertexLightEnd();
182         for (VertexLightArray::iterator iter = lightSet->GetVertexLightBegin();
183             iter != vertexLightEnd;
184             ++iter)
185         {
186             m_VertexLightsDirty = true;
187             if (m_ActiveVertexLightCount == vertexLightMaxCount)
188             {
189                 break;
190             }
191 
192             if ((*iter)->GetResVertexLight().IsLightEnabled())
193             {
194                 m_VertexLights[m_ActiveVertexLightCount] = (*iter);
195                 ++m_ActiveVertexLightCount;
196             }
197         }
198 #endif
199 
200         m_ActiveFragmentLightCount = 0;
201         FixedFragmentLightArray::iterator fragmentLightEnd = lightSet->GetFragmentLightEnd();
202         for (FixedFragmentLightArray::iterator iter = lightSet->GetFragmentLightBegin();
203             iter != fragmentLightEnd;
204             ++iter)
205         {
206             m_FragmentLightsDirty = true;
207             if (m_ActiveFragmentLightCount == LIGHT_COUNT)
208             {
209                 break;
210             }
211 
212             if ((*iter)->GetResFragmentLight().IsLightEnabled())
213             {
214                 m_FragmentLights[m_ActiveFragmentLightCount] = (*iter);
215                 ++m_ActiveFragmentLightCount;
216             }
217         }
218     }
219 }
220 
221 } // namespace gfx
222 } // namespace nw
223