glc_light.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
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 // Constructor Destructor
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 // Get Functions
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 // Set Functions
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 // OpenGL Functions
00216 
00217 void GLC_Light::creationList(GLenum Mode)
00218 {
00219         if(0 == m_ListID)               // OpenGL list not created
00220         {
00221                 m_ListID= glGenLists(1);
00222 
00223                 if (0 == m_ListID)      // OpenGL List Id not get
00224                 {
00225                         glDraw();
00226                         qDebug("GLC_Light::CreationListe Display list not create");
00227                 }
00228         }
00229         if (0 != m_ListID)
00230         {
00231                 // OpenGL list creation and execution
00232                 glNewList(m_ListID, Mode);
00233 
00234                 // Light execution
00235                 glDraw();
00236 
00237                 glEndList();
00238 
00239                 m_ListIsValid= true;
00240         }
00241 
00242         // OpenGL error handler
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                 // OpenGL list is not valid
00276                 /*
00277                 GLfloat value;
00278                 glGetFloatv(GL_CONSTANT_ATTENUATION, &value);
00279                 qDebug() << "GL_CONSTANT_ATTENUATION " << value;
00280                 glGetFloatv(GL_LINEAR_ATTENUATION, &value);
00281                 qDebug() << "GL_LINEAR_ATTENUATION " << value;
00282                 glGetFloatv(GL_QUADRATIC_ATTENUATION, &value);
00283                 qDebug() << "GL_QUADRATIC_ATTENUATION " << value;
00284                 */
00285                 creationList(Mode);
00286         }
00287         else
00288         {
00289                 glCallList(m_ListID);
00290         }
00291 
00292         // OpenGL error handler
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         //qDebug() << "GLC_Light::GlDraw id= " << m_LightID;
00305         // Set the lighting model
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         // Color
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);             // Setup The Ambient Light
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);             // Setup The Diffuse Light
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);    // Setup The specular Light
00334 
00335         // Position
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);    // Direction of the Light
00344         }
00345         else
00346         {
00347                 setArray[3]= 1.0f;
00348                 glLightfv(m_LightID, GL_POSITION, setArray);    // Position of the Light
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         // Spot light parameters
00356         if (LightSpot == m_LightType)
00357         {
00358                 // Spot Direction
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         // OpenGL error handler
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 // Private services Functions
00382 
00383 void GLC_Light::deleteList(void)
00384 {
00385         // if the list is valid, the list is deleted
00386         if (glIsList(m_ListID))
00387         {
00388                 disable();
00389                 glDeleteLists(m_ListID, 1);
00390         }
00391 }
00392 
00394 // Private services fonction
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 }

SourceForge.net Logo

©2005-2011 Laurent Ribon