00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024
00025 #include <QGlContext>
00026 #include <QtDebug>
00027
00028 #include "glc_light.h"
00029 #include "../glc_openglexception.h"
00030
00031 GLint GLC_Light::m_MaxLight= 8;
00032 QHash<const QGLContext*, QSet<GLenum> > GLC_Light::m_ContextToFreeLightSet;
00033
00035
00037 GLC_Light::GLC_Light(const QGLContext* pContext, const QColor& color)
00038 :GLC_Object("Light")
00039 , m_LightID(-1)
00040 , m_LightType(LightPosition)
00041 , m_ListID(0)
00042 , m_ListIsValid(false)
00043 , m_AmbientColor(Qt::black)
00044 , m_DiffuseColor(color)
00045 , m_SpecularColor(Qt::white)
00046 , m_Position()
00047 , m_SpotDirection(0.0, 0.0, -1.0)
00048 , m_SpotExponent(0.0f)
00049 , m_SpotCutoffAngle(180.0f)
00050 , m_ConstantAttenuation(1.0f)
00051 , m_LinearAttenuation(0.0f)
00052 , m_QuadraticAttenuation(0.0f)
00053 , m_TwoSided(false)
00054 , m_pContext(const_cast<QGLContext*>(pContext))
00055 {
00056 addNewLight();
00057 }
00058
00059 GLC_Light::GLC_Light(LightType lightType, const QGLContext* pContext, const QColor& color)
00060 :GLC_Object("Light")
00061 , m_LightID(-1)
00062 , m_LightType(lightType)
00063 , m_ListID(0)
00064 , m_ListIsValid(false)
00065 , m_AmbientColor(Qt::black)
00066 , m_DiffuseColor(color)
00067 , m_SpecularColor(Qt::white)
00068 , m_Position()
00069 , m_SpotDirection(0.0, 0.0, -1.0)
00070 , m_SpotExponent(0.0f)
00071 , m_SpotCutoffAngle(180.0f)
00072 , m_ConstantAttenuation(1.0f)
00073 , m_LinearAttenuation(0.0f)
00074 , m_QuadraticAttenuation(0.0f)
00075 , m_TwoSided(false)
00076 , m_pContext(const_cast<QGLContext*>(pContext))
00077 {
00078 addNewLight();
00079 }
00080
00081 GLC_Light::GLC_Light(const GLC_Light& light)
00082 :GLC_Object(light)
00083 , m_LightID(-1)
00084 , m_LightType(light.m_LightType)
00085 , m_ListID(0)
00086 , m_ListIsValid(false)
00087 , m_AmbientColor(light.m_AmbientColor)
00088 , m_DiffuseColor(light.m_DiffuseColor)
00089 , m_SpecularColor(light.m_SpecularColor)
00090 , m_Position(light.m_Position)
00091 , m_SpotDirection(light.m_SpotDirection)
00092 , m_SpotExponent(light.m_SpotExponent)
00093 , m_SpotCutoffAngle(light.m_SpotCutoffAngle)
00094 , m_ConstantAttenuation(light.m_ConstantAttenuation)
00095 , m_LinearAttenuation(light.m_LinearAttenuation)
00096 , m_QuadraticAttenuation(light.m_QuadraticAttenuation)
00097 , m_TwoSided(light.m_TwoSided)
00098 , m_pContext(light.m_pContext)
00099 {
00100 addNewLight();
00101 }
00102
00103 GLC_Light::~GLC_Light(void)
00104 {
00105 deleteList();
00106 removeThisLight();
00107 }
00108
00110
00112
00113 int GLC_Light::maxLightCount()
00114 {
00115 return m_MaxLight;
00116 }
00117
00118 int GLC_Light::builtAbleLightCount(QGLContext* pContext)
00119 {
00120 if (m_ContextToFreeLightSet.contains(pContext))
00121 {
00122 return m_ContextToFreeLightSet.value(pContext).size();
00123 }
00124 else return m_MaxLight;
00125 }
00126
00128
00130 void GLC_Light::initForThisContext()
00131 {
00132 for (int i= 0; i < m_MaxLight; ++i)
00133 {
00134 m_ContextToFreeLightSet[m_pContext].insert(GL_LIGHT0 + i);
00135 }
00136 }
00137
00138 void GLC_Light::setPosition(const GLC_Point3d &pos)
00139 {
00140 m_Position= pos;
00141 m_ListIsValid = false;
00142 }
00143
00144 void GLC_Light::setPosition(GLfloat x, GLfloat y, GLfloat z)
00145 {
00146 m_Position.setVect(static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
00147 m_ListIsValid = false;
00148 }
00149
00150 void GLC_Light::setAmbientColor(const QColor& color)
00151 {
00152 m_AmbientColor= color;
00153 m_ListIsValid = false;
00154 }
00155
00156 void GLC_Light::setDiffuseColor(const QColor& color)
00157 {
00158 m_DiffuseColor= color;
00159 m_ListIsValid = false;
00160 }
00161
00162 void GLC_Light::setSpecularColor(const QColor& color)
00163 {
00164 m_SpecularColor= color;
00165 m_ListIsValid = false;
00166 }
00167
00168 void GLC_Light::setTwoSided(const bool mode)
00169 {
00170 if (m_TwoSided != mode)
00171 {
00172 m_TwoSided= mode;
00173 m_ListIsValid = false;
00174 }
00175 }
00176
00177 void GLC_Light::setConstantAttenuation(GLfloat constantAttenuation)
00178 {
00179 m_ConstantAttenuation= constantAttenuation;
00180 m_ListIsValid = false;
00181 }
00182
00183 void GLC_Light::setLinearAttenuation(GLfloat linearAttenuation)
00184 {
00185 m_LinearAttenuation= linearAttenuation;
00186 m_ListIsValid = false;
00187 }
00188
00189 void GLC_Light::setQuadraticAttenuation(GLfloat quadraticAttenuation)
00190 {
00191 m_QuadraticAttenuation= quadraticAttenuation;
00192 m_ListIsValid = false;
00193 }
00194
00195 void GLC_Light::setSpotDirection(const GLC_Vector3d& direction)
00196 {
00197 m_SpotDirection= direction;
00198 m_ListIsValid = false;
00199 }
00200
00201 void GLC_Light::setSpotCutoffAngle(GLfloat cutoffAngle)
00202 {
00203 m_SpotCutoffAngle= cutoffAngle;
00204 m_ListIsValid = false;
00205 }
00206
00207 void GLC_Light::setSpotEponent(GLfloat exponent)
00208 {
00209 m_SpotExponent= exponent;
00210 m_ListIsValid = false;
00211 }
00212
00214
00216
00217 void GLC_Light::creationList(GLenum Mode)
00218 {
00219 if(0 == m_ListID)
00220 {
00221 m_ListID= glGenLists(1);
00222
00223 if (0 == m_ListID)
00224 {
00225 glDraw();
00226 qDebug("GLC_Light::CreationListe Display list not create");
00227 }
00228 }
00229 if (0 != m_ListID)
00230 {
00231
00232 glNewList(m_ListID, Mode);
00233
00234
00235 glDraw();
00236
00237 glEndList();
00238
00239 m_ListIsValid= true;
00240 }
00241
00242
00243 GLenum error= glGetError();
00244 if (error != GL_NO_ERROR)
00245 {
00246 GLC_OpenGlException OpenGlException("GLC_Light::CreationList ", error);
00247 throw(OpenGlException);
00248 }
00249 }
00250 void GLC_Light::enable()
00251 {
00252 if (NULL == m_pContext)
00253 {
00254 m_pContext= const_cast<QGLContext*>(QGLContext::currentContext());
00255 Q_ASSERT(NULL != m_pContext);
00256 addNewLight();
00257 }
00258
00259 glEnable(m_LightID);
00260 }
00261
00262 void GLC_Light::disable()
00263 {
00264 if (NULL != m_pContext)
00265 {
00266 glDisable(m_LightID);
00267 }
00268 }
00269
00270
00271 void GLC_Light::glExecute(GLenum Mode)
00272 {
00273 if (!m_ListIsValid)
00274 {
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 creationList(Mode);
00286 }
00287 else
00288 {
00289 glCallList(m_ListID);
00290 }
00291
00292
00293 GLenum error= glGetError();
00294 if (error != GL_NO_ERROR)
00295 {
00296 GLC_OpenGlException OpenGlException("GLC_Light::GlExecute ", error);
00297 throw(OpenGlException);
00298 }
00299
00300 }
00301
00302 void GLC_Light::glDraw(void)
00303 {
00304
00305
00306 if (m_TwoSided)
00307 {
00308 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
00309 }
00310 else
00311 {
00312 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
00313 }
00314
00315
00316 GLfloat setArray[4]= {static_cast<GLfloat>(m_AmbientColor.redF()),
00317 static_cast<GLfloat>(m_AmbientColor.greenF()),
00318 static_cast<GLfloat>(m_AmbientColor.blueF()),
00319 static_cast<GLfloat>(m_AmbientColor.alphaF())};
00320 glLightfv(m_LightID, GL_AMBIENT, setArray);
00321
00322 setArray[0]= static_cast<GLfloat>(m_DiffuseColor.redF());
00323 setArray[1]= static_cast<GLfloat>(m_DiffuseColor.greenF());
00324 setArray[2]= static_cast<GLfloat>(m_DiffuseColor.blueF());
00325 setArray[3]= static_cast<GLfloat>(m_DiffuseColor.alphaF());
00326 glLightfv(m_LightID, GL_DIFFUSE, setArray);
00327
00328
00329 setArray[0]= static_cast<GLfloat>(m_SpecularColor.redF());
00330 setArray[1]= static_cast<GLfloat>(m_SpecularColor.greenF());
00331 setArray[2]= static_cast<GLfloat>(m_SpecularColor.blueF());
00332 setArray[3]= static_cast<GLfloat>(m_SpecularColor.alphaF());
00333 glLightfv(m_LightID, GL_SPECULAR, setArray);
00334
00335
00336 setArray[0]= static_cast<GLfloat>(m_Position.x());
00337 setArray[1]= static_cast<GLfloat>(m_Position.y());
00338 setArray[2]= static_cast<GLfloat>(m_Position.z());
00339
00340 if (LightDirection == m_LightType)
00341 {
00342 setArray[3]= 0.0f;
00343 glLightfv(m_LightID, GL_POSITION, setArray);
00344 }
00345 else
00346 {
00347 setArray[3]= 1.0f;
00348 glLightfv(m_LightID, GL_POSITION, setArray);
00349 glLightf(m_LightID, GL_CONSTANT_ATTENUATION, m_ConstantAttenuation);
00350 glLightf(m_LightID, GL_LINEAR_ATTENUATION, m_LinearAttenuation);
00351 glLightf(m_LightID, GL_QUADRATIC_ATTENUATION, m_QuadraticAttenuation);
00352
00353 }
00354
00355
00356 if (LightSpot == m_LightType)
00357 {
00358
00359 setArray[0]= static_cast<GLfloat>(m_SpotDirection.x());
00360 setArray[1]= static_cast<GLfloat>(m_SpotDirection.y());
00361 setArray[2]= static_cast<GLfloat>(m_SpotDirection.z());
00362 glLightfv(m_LightID, GL_SPOT_DIRECTION, setArray);
00363 glLightf(m_LightID, GL_SPOT_EXPONENT, m_SpotExponent);
00364 glLightf(m_LightID, GL_SPOT_CUTOFF, m_SpotCutoffAngle);
00365 }
00366
00367
00368
00369 GLenum error= glGetError();
00370 if (error != GL_NO_ERROR)
00371 {
00372 qDebug() << "GLC_Light::GlDraw Exception, id= " << m_LightID;
00373 GLC_OpenGlException OpenGlException("GLC_Light::GlDraw ", error);
00374 throw(OpenGlException);
00375 }
00376
00377 }
00378
00380
00382
00383 void GLC_Light::deleteList(void)
00384 {
00385
00386 if (glIsList(m_ListID))
00387 {
00388 disable();
00389 glDeleteLists(m_ListID, 1);
00390 }
00391 }
00392
00394
00396 void GLC_Light::addNewLight()
00397 {
00398 if (NULL != m_pContext)
00399 {
00400 if (!m_ContextToFreeLightSet.contains(m_pContext))
00401 {
00402 m_ContextToFreeLightSet.insert(m_pContext, QSet<GLenum>());
00403 initForThisContext();
00404 }
00405 m_LightID= *(m_ContextToFreeLightSet[m_pContext].constBegin());
00406 m_ContextToFreeLightSet[m_pContext].remove(m_LightID);
00407 }
00408 }
00409
00410 void GLC_Light::removeThisLight()
00411 {
00412 if (NULL != m_pContext)
00413 {
00414 Q_ASSERT(m_ContextToFreeLightSet.contains(m_pContext));
00415 Q_ASSERT(!m_ContextToFreeLightSet[m_pContext].contains(m_LightID));
00416 m_ContextToFreeLightSet[m_pContext].insert(m_LightID);
00417 if (m_ContextToFreeLightSet[m_pContext].size() == m_MaxLight)
00418 {
00419 m_ContextToFreeLightSet.remove(m_pContext);
00420 }
00421 }
00422 }