00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <cstdlib>
00044 #include <cstdio>
00045
00046 #include "OSGConfig.h"
00047
00048 #include "OSGDSLightChunk.h"
00049
00050 #include "OSGGL.h"
00051 #include "OSGGLU.h"
00052
00053 #include "OSGDrawEnv.h"
00054
00055 OSG_BEGIN_NAMESPACE
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 StateChunkClass DSLightChunk::_class("DSLight", 1);
00067
00068
00069
00070
00071
00072 void DSLightChunk::initMethod(InitPhase ePhase)
00073 {
00074 Inherited::initMethod(ePhase);
00075
00076 if(ePhase == TypeObject::SystemPost)
00077 {
00078 }
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 DSLightChunk::DSLightChunk(void) :
00093 Inherited()
00094 {
00095 }
00096
00097 DSLightChunk::DSLightChunk(const DSLightChunk &source) :
00098 Inherited(source)
00099 {
00100 }
00101
00102 DSLightChunk::~DSLightChunk(void)
00103 {
00104 }
00105
00106
00107
00108 const StateChunkClass *DSLightChunk::getClass(void) const
00109 {
00110 return &_class;
00111 }
00112
00113 void DSLightChunk::changed(ConstFieldMaskArg whichField,
00114 UInt32 origin,
00115 BitVector details)
00116 {
00117 Inherited::changed(whichField, origin, details);
00118 }
00119
00120 void DSLightChunk::dump( UInt32 ,
00121 const BitVector ) const
00122 {
00123 SLOG << "Dump DSLightChunk NI" << std::endl;
00124 }
00125
00126
00127
00128 void DSLightChunk::activate(DrawEnv *drawEnv, UInt32 index)
00129 {
00130 glErr("dslight:activate:precheck");
00131
00132 Matrix matMV;
00133 calcModelView(drawEnv, matMV);
00134
00135 glPushMatrix();
00136 GLP::glLoadMatrixf(matMV.getValues());
00137
00138 GLP::glLightfv( GL_LIGHT0 + index,
00139 GL_DIFFUSE,
00140 _sfDiffuse.getValue().getValuesRGBA());
00141
00142 GLP::glLightfv( GL_LIGHT0 + index,
00143 GL_AMBIENT,
00144 _sfAmbient.getValue().getValuesRGBA());
00145
00146 GLP::glLightfv( GL_LIGHT0 + index,
00147 GL_SPECULAR,
00148 _sfSpecular.getValue().getValuesRGBA());
00149 GLP::glLightfv( GL_LIGHT0 + index,
00150 GL_POSITION,
00151 _sfPosition.getValue().getValues());
00152
00153 GLP::glLightf ( GL_LIGHT0 + index,
00154 GL_CONSTANT_ATTENUATION,
00155 _sfConstantAttenuation.getValue());
00156
00157 GLP::glLightf ( GL_LIGHT0 + index,
00158 GL_LINEAR_ATTENUATION,
00159 _sfLinearAttenuation.getValue());
00160
00161 GLP::glLightf ( GL_LIGHT0 + index,
00162 GL_QUADRATIC_ATTENUATION,
00163 _sfQuadraticAttenuation.getValue());
00164
00165 GLP::glLightf( GL_LIGHT0 + index,
00166 GL_SPOT_CUTOFF,
00167 _sfCutoff.getValue());
00168
00169 if(_sfCutoff.getValue() < 180.f)
00170 {
00171 GLP::glLightfv( GL_LIGHT0 + index,
00172 GL_SPOT_DIRECTION,
00173 _sfDirection.getValue().getValues());
00174
00175 GLP::glLightf( GL_LIGHT0 + index,
00176 GL_SPOT_EXPONENT,
00177 _sfExponent.getValue());
00178 }
00179
00180 glEnable(GL_LIGHT0 + index);
00181
00182 glPopMatrix();
00183
00184 glErr("dslight:activate:postcheck");
00185 }
00186
00187 void DSLightChunk::changeFrom(DrawEnv *drawEnv, StateChunk *old, UInt32 index)
00188 {
00189 glErr("dslight:change:precheck");
00190
00191 const DSLightChunk *oldChunk = dynamic_cast<const DSLightChunk *>(old);
00192
00193
00194
00195
00196
00197 if(oldChunk == this)
00198 return;
00199
00200 Matrix matMV;
00201 calcModelView(drawEnv, matMV);
00202
00203 glPushMatrix();
00204 GLP::glLoadMatrixf(matMV.getValues());
00205
00206
00207
00208
00209 GLP::glLightfv( GL_LIGHT0 + index,
00210 GL_DIFFUSE,
00211 _sfDiffuse.getValue().getValuesRGBA());
00212
00213 GLP::glLightfv( GL_LIGHT0 + index,
00214 GL_AMBIENT,
00215 _sfAmbient.getValue().getValuesRGBA());
00216
00217 GLP::glLightfv( GL_LIGHT0 + index,
00218 GL_SPECULAR,
00219 _sfSpecular.getValue().getValuesRGBA());
00220
00221 GLP::glLightfv( GL_LIGHT0 + index,
00222 GL_POSITION,
00223 _sfPosition.getValue().getValues());
00224
00225 GLP::glLightf ( GL_LIGHT0 + index,
00226 GL_CONSTANT_ATTENUATION,
00227 _sfConstantAttenuation.getValue());
00228
00229 GLP::glLightf ( GL_LIGHT0 + index,
00230 GL_LINEAR_ATTENUATION,
00231 _sfLinearAttenuation.getValue());
00232
00233 GLP::glLightf ( GL_LIGHT0 + index,
00234 GL_QUADRATIC_ATTENUATION,
00235 _sfQuadraticAttenuation.getValue());
00236
00237 GLP::glLightf( GL_LIGHT0 + index,
00238 GL_SPOT_CUTOFF,
00239 _sfCutoff.getValue());
00240
00241 if(_sfCutoff.getValue() < 180.f)
00242 {
00243 GLP::glLightfv( GL_LIGHT0 + index,
00244 GL_SPOT_DIRECTION,
00245 _sfDirection.getValue().getValues());
00246
00247 GLP::glLightf( GL_LIGHT0 + index,
00248 GL_SPOT_EXPONENT,
00249 _sfExponent.getValue());
00250 }
00251
00252 glPopMatrix();
00253
00254 glErr("dslight:change:postcheck");
00255 }
00256
00257 void DSLightChunk::deactivate(DrawEnv *drawEnv, UInt32 index)
00258 {
00259 glDisable(GL_LIGHT0 + index);
00260 }
00261
00262
00263
00264 Real32 DSLightChunk::switchCost(StateChunk *OSG_CHECK_ARG(chunk))
00265 {
00266 return 0;
00267 }
00268
00269 bool DSLightChunk::operator < (const StateChunk &other) const
00270 {
00271 return this < &other;
00272 }
00273
00274 bool DSLightChunk::operator == (const StateChunk &other) const
00275 {
00276 const DSLightChunk *tother = dynamic_cast<const DSLightChunk *>(&other);
00277
00278 if(!tother)
00279 return false;
00280
00281 if(tother == this)
00282 return true;
00283
00284 if(!getAmbient ().equals(tother->getAmbient (), Eps) ||
00285 !getDiffuse ().equals(tother->getDiffuse (), Eps) ||
00286 !getSpecular ().equals(tother->getSpecular (), Eps) ||
00287 !getPosition ().equals(tother->getPosition (), Eps) ||
00288 !getDirection().equals(tother->getDirection(), Eps) ||
00289
00290 getConstantAttenuation () != tother->getConstantAttenuation () ||
00291 getLinearAttenuation () != tother->getLinearAttenuation () ||
00292 getQuadraticAttenuation() != tother->getQuadraticAttenuation() ||
00293 getCutoff () != tother->getCutoff () ||
00294 getExponent () != tother->getExponent ()
00295 )
00296 {
00297 return false;
00298 }
00299
00300 return true;
00301 }
00302
00303 bool DSLightChunk::operator != (const StateChunk &other) const
00304 {
00305 return ! (*this == other);
00306 }
00307
00308
00309
00310 void DSLightChunk::calcModelView(DrawEnv *drawEnv, Matrixr &result)
00311 {
00312 result = drawEnv->getVPCameraViewing();
00313
00314 Matrixr toWorld;
00315
00316 if(_sfBeacon.getValue() != NULL)
00317 {
00318 _sfBeacon.getValue()->getToWorld(toWorld);
00319 }
00320 else
00321 {
00322 toWorld.setIdentity();
00323 }
00324
00325 result.mult(toWorld);
00326 }
00327
00328 OSG_END_NAMESPACE