Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages
vertexlight.h
Go to the documentation of this file.00001 /* 00002 Copyright (C) 2005 by Marten Svanfeldt 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public 00015 License along with this library; if not, write to the Free 00016 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00017 */ 00018 00019 #ifndef __CS_CSGFX_VERTEXLIGHT_H__ 00020 #define __CS_CSGFX_VERTEXLIGHT_H__ 00021 00022 #include "csqsqrt.h" 00023 #include "csgeom/math.h" 00024 #include "csgeom/transfrm.h" 00025 #include "csgeom/vector3.h" 00026 #include "csgfx/lightsvcache.h" 00027 #include "csgfx/vertexlistwalker.h" 00028 #include "csutil/cscolor.h" 00029 00030 #include "iengine/light.h" 00031 #include "iengine/movable.h" 00032 #include "ivideo/shader/shader.h" 00033 00041 struct CS_CRYSTALSPACE_EXPORT csLightProperties 00042 { 00044 csVector3 attenuationConsts; 00046 csVector3 posObject; 00051 csVector3 dirObject; 00053 csColor color; 00055 float spotFalloffInner; 00057 float spotFalloffOuter; 00059 csLightType type; 00061 csLightAttenuationMode attenuationMode; 00062 00063 csLightProperties () : spotFalloffInner(0.0f), spotFalloffOuter(0.0f), 00064 type(CS_LIGHT_POINTLIGHT) {} 00069 csLightProperties (size_t lightNum, csLightShaderVarCache& svcache, 00070 const csShaderVarStack &stacks) 00071 { 00072 csStringID id; 00073 00074 id = svcache.GetLightSVId (lightNum, 00075 csLightShaderVarCache::lightAttenuation); 00076 if ((stacks.Length() > id) && (stacks[id] != 0)) 00077 stacks[id]->GetValue (attenuationConsts); 00078 00079 id = svcache.GetLightSVId (lightNum, 00080 csLightShaderVarCache::lightPosition); 00081 if ((stacks.Length() > id) && (stacks[id] != 0)) 00082 stacks[id]->GetValue (posObject); 00083 00084 id = svcache.GetLightSVId (lightNum, 00085 csLightShaderVarCache::lightDirection); 00086 if ((stacks.Length() > id) && (stacks[id] != 0)) 00087 stacks[id]->GetValue (dirObject); 00088 00089 id = svcache.GetLightSVId (lightNum, 00090 csLightShaderVarCache::lightDiffuse); 00091 if ((stacks.Length() > id) && (stacks[id] != 0)) 00092 stacks[id]->GetValue (color); 00093 00094 id = svcache.GetLightSVId (lightNum, 00095 csLightShaderVarCache::lightInnerFalloff); 00096 if ((stacks.Length() > id) && (stacks[id] != 0)) 00097 stacks[id]->GetValue (spotFalloffInner); 00098 00099 id = svcache.GetLightSVId (lightNum, 00100 csLightShaderVarCache::lightOuterFalloff); 00101 if ((stacks.Length() > id) && (stacks[id] != 0)) 00102 stacks[id]->GetValue (spotFalloffOuter); 00103 00104 int t = CS_LIGHT_POINTLIGHT; 00105 id = svcache.GetLightSVId (lightNum, 00106 csLightShaderVarCache::lightType); 00107 if ((stacks.Length() > id) && (stacks[id] != 0)) 00108 stacks[id]->GetValue (t); 00109 type = (csLightType)t; 00110 00111 t = CS_ATTN_NONE; 00112 id = svcache.GetLightSVId (lightNum, 00113 csLightShaderVarCache::lightAttenuationMode); 00114 if ((stacks.Length() > id) && (stacks[id] != 0)) 00115 stacks[id]->GetValue (t); 00116 attenuationMode = (csLightAttenuationMode)t; 00117 } 00118 }; 00119 00123 struct CS_CRYSTALSPACE_EXPORT csNoAttenuation 00124 { 00125 csNoAttenuation (const csLightProperties& /*light*/) 00126 {} 00127 00128 CS_FORCEINLINE void operator() (float /*distance*/, float & /*dp*/) const 00129 {} 00130 }; 00131 00136 struct CS_CRYSTALSPACE_EXPORT csLinearAttenuation 00137 { 00138 csLinearAttenuation (const csLightProperties& light) 00139 { 00140 invrad = 1/light.attenuationConsts.x; 00141 } 00142 00143 CS_FORCEINLINE void operator() (float distance, float& dp) const 00144 { 00145 dp = csMax (dp * (1 - distance * invrad), 0.0f); 00146 } 00147 00148 float invrad; 00149 }; 00150 00155 struct CS_CRYSTALSPACE_EXPORT csInverseAttenuation 00156 { 00157 csInverseAttenuation (const csLightProperties& /*light*/) 00158 {} 00159 00160 CS_FORCEINLINE void operator() (float distance, float& dp) const 00161 { 00162 dp = dp / distance; 00163 } 00164 }; 00165 00166 00171 struct CS_CRYSTALSPACE_EXPORT csRealisticAttenuation 00172 { 00173 csRealisticAttenuation (const csLightProperties& /*light*/) 00174 {} 00175 00176 CS_FORCEINLINE void operator() (float distance, float& dp) const 00177 { 00178 dp = dp / (distance*distance); 00179 } 00180 }; 00181 00186 struct CS_CRYSTALSPACE_EXPORT csCLQAttenuation 00187 { 00188 csCLQAttenuation (const csLightProperties& light) 00189 : attnVec (light.attenuationConsts) 00190 {} 00191 00192 CS_FORCEINLINE void operator() (float distance, float& dp) const 00193 { 00194 dp = dp/(csVector3 (1.0, distance, distance*distance)*attnVec); 00195 } 00196 00197 csVector3 attnVec; 00198 }; 00199 00200 00206 template<class AttenuationProc> 00207 class csPointLightProc 00208 { 00209 public: 00210 csPointLightProc (const csLightProperties& light, 00211 float blackLimit = 0.0001f) 00212 : attn (light), nullColor (0.0f, 0.0f, 0.0f), blackLimit (blackLimit) 00213 { 00214 lightPos = light.posObject; 00215 lightCol = light.color; 00216 } 00217 00218 CS_FORCEINLINE 00219 csColor ProcessVertex (const csVector3 &v,const csVector3 &n) const 00220 { 00221 //compute gouraud shading.. 00222 csVector3 direction = lightPos-v; 00223 float distance = csQsqrt(direction.SquaredNorm ()); 00224 float dp = (direction*n)/distance; 00225 if (dp > blackLimit) 00226 { 00227 attn (distance, dp); 00228 return lightCol*dp; 00229 } 00230 return nullColor; 00231 } 00232 00233 private: 00234 AttenuationProc attn; 00235 csVector3 lightPos; //localspace 00236 csColor lightCol; 00237 csColor nullColor; 00238 float blackLimit; 00239 }; 00240 00246 template<class AttenuationProc> 00247 class csDirectionalLightProc 00248 { 00249 public: 00250 csDirectionalLightProc (const csLightProperties& light, 00251 float blackLimit = 0.0001f) 00252 : attn (light), nullColor (0.0f, 0.0f, 0.0f), blackLimit (blackLimit) 00253 { 00254 lightPos = light.posObject; 00255 lightDir = light.dirObject; 00256 lightCol = light.color; 00257 } 00258 00259 CS_FORCEINLINE 00260 csColor ProcessVertex (const csVector3 &v,const csVector3 &n) const 00261 { 00262 //compute gouraud shading.. 00263 float dp = -lightDir*n; 00264 if (dp > blackLimit) 00265 { 00266 csVector3 direction = lightPos-v; 00267 float distance = csQsqrt(direction.SquaredNorm ()); 00268 attn (distance, dp); 00269 return lightCol*dp; 00270 } 00271 return nullColor; 00272 } 00273 00274 private: 00275 AttenuationProc attn; 00276 csVector3 lightPos; //localspace 00277 csVector3 lightDir; //localspace 00278 csColor lightCol; 00279 csColor nullColor; 00280 float blackLimit; 00281 }; 00282 00288 template<class AttenuationProc> 00289 class csSpotLightProc 00290 { 00291 public: 00292 csSpotLightProc (const csLightProperties& light, 00293 float blackLimit = 0.0001f) 00294 : attn (light), nullColor (0.0f, 0.0f, 0.0f), blackLimit (blackLimit) 00295 { 00296 lightPos = light.posObject; 00297 lightDir = light.dirObject; 00298 00299 lightCol = light.color; 00300 falloffInner = light.spotFalloffInner; 00301 falloffOuter = light.spotFalloffOuter; 00302 } 00303 00304 CS_FORCEINLINE 00305 csColor ProcessVertex (const csVector3 &v,const csVector3 &n) const 00306 { 00307 csVector3 direction = (lightPos-v).Unit (); 00308 00309 //compute gouraud shading.. 00310 float dp = direction*n; 00311 if (dp > blackLimit) 00312 { 00313 float cosfact = 00314 csSmoothStep (-(direction*lightDir), falloffOuter, falloffInner); 00315 float distance = csQsqrt(direction.SquaredNorm ()); 00316 if (cosfact > 0) 00317 { 00318 attn (distance, dp); 00319 return lightCol*dp*cosfact; 00320 } 00321 } 00322 return nullColor; 00323 } 00324 00325 private: 00326 AttenuationProc attn; 00327 csVector3 lightPos; //localspace 00328 csVector3 lightDir; //localspace 00329 csColor lightCol; 00330 csColor nullColor; 00331 float blackLimit; 00332 float falloffInner, falloffOuter; 00333 }; 00334 00338 struct iVertexLightCalculator 00339 { 00340 public: 00349 virtual void CalculateLighting (const csLightProperties& light, 00350 size_t numvert, csVertexListWalker<csVector3> vb, 00351 csVertexListWalker<csVector3> nb, csColor *litColor) const = 0; 00352 00357 virtual void CalculateLightingAdd (const csLightProperties& light, 00358 size_t numvert, csVertexListWalker<csVector3> vb, 00359 csVertexListWalker<csVector3> nb, csColor *litColor) const = 0; 00360 00365 virtual void CalculateLightingMul (const csLightProperties& light, 00366 size_t numvert, csVertexListWalker<csVector3> vb, 00367 csVertexListWalker<csVector3> nb, csColor *litColor) const = 0; 00368 }; 00369 00375 template<class LightProc> 00376 class csVertexLightCalculator : public iVertexLightCalculator 00377 { 00378 public: 00379 virtual void CalculateLighting (const csLightProperties& light, 00380 size_t numvert, csVertexListWalker<csVector3> vb, 00381 csVertexListWalker<csVector3> nb, csColor *litColor) const 00382 { 00383 // setup the light calculator 00384 LightProc lighter (light); 00385 00386 for (size_t n = 0; n < numvert; n++) 00387 { 00388 litColor[n] = lighter.ProcessVertex (vb[n], nb[n]); 00389 } 00390 } 00391 00392 virtual void CalculateLightingAdd (const csLightProperties& light, 00393 size_t numvert, csVertexListWalker<csVector3> vb, 00394 csVertexListWalker<csVector3> nb, csColor *litColor) const 00395 { 00396 // setup the light calculator 00397 LightProc lighter (light); 00398 00399 for (size_t n = 0; n < numvert; n++) 00400 { 00401 litColor[n] += lighter.ProcessVertex (vb[n], nb[n]); 00402 } 00403 } 00404 00405 virtual void CalculateLightingMul (const csLightProperties& light, 00406 size_t numvert, csVertexListWalker<csVector3> vb, 00407 csVertexListWalker<csVector3> nb, csColor *litColor) const 00408 { 00409 // setup the light calculator 00410 LightProc lighter (light); 00411 00412 for (size_t n = 0; n < numvert; n++) 00413 { 00414 litColor[n] *= lighter.ProcessVertex (vb[n], nb[n]); 00415 } 00416 } 00417 }; 00418 00419 #endif //__CS_VERTEXLIGHT_H__
Generated for Crystal Space by doxygen 1.4.4