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 #include "../glc_context.h"
00031 
00032 GLint GLC_Light::m_MaxLight= 8;
00033 QHash<const QGLContext*, QSet<GLenum> > GLC_Light::m_ContextToFreeLightSet;
00034 
00036 // Constructor Destructor
00038 GLC_Light::GLC_Light(const QGLContext* pContext, const QColor& color)
00039 :GLC_Object("Light")
00040 , m_LightID(-1)
00041 , m_LightType(LightPosition)
00042 , m_AmbientColor(Qt::black)
00043 , m_DiffuseColor(color)
00044 , m_SpecularColor(Qt::white)
00045 , m_Position()
00046 , m_SpotDirection(0.0, 0.0, -1.0)
00047 , m_SpotExponent(0.0f)
00048 , m_SpotCutoffAngle(180.0f)
00049 , m_ConstantAttenuation(1.0f)
00050 , m_LinearAttenuation(0.0f)
00051 , m_QuadraticAttenuation(0.0f)
00052 , m_TwoSided(false)
00053 , m_pContext(const_cast<QGLContext*>(pContext))
00054 , m_IsValid(false)
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_AmbientColor(Qt::black)
00064 , m_DiffuseColor(color)
00065 , m_SpecularColor(Qt::white)
00066 , m_Position()
00067 , m_SpotDirection(0.0, 0.0, -1.0)
00068 , m_SpotExponent(0.0f)
00069 , m_SpotCutoffAngle(180.0f)
00070 , m_ConstantAttenuation(1.0f)
00071 , m_LinearAttenuation(0.0f)
00072 , m_QuadraticAttenuation(0.0f)
00073 , m_TwoSided(false)
00074 , m_pContext(const_cast<QGLContext*>(pContext))
00075 , m_IsValid(false)
00076 {
00077         addNewLight();
00078 }
00079 
00080 GLC_Light::GLC_Light(const GLC_Light& light)
00081 :GLC_Object(light)
00082 , m_LightID(-1)
00083 , m_LightType(light.m_LightType)
00084 , m_AmbientColor(light.m_AmbientColor)
00085 , m_DiffuseColor(light.m_DiffuseColor)
00086 , m_SpecularColor(light.m_SpecularColor)
00087 , m_Position(light.m_Position)
00088 , m_SpotDirection(light.m_SpotDirection)
00089 , m_SpotExponent(light.m_SpotExponent)
00090 , m_SpotCutoffAngle(light.m_SpotCutoffAngle)
00091 , m_ConstantAttenuation(light.m_ConstantAttenuation)
00092 , m_LinearAttenuation(light.m_LinearAttenuation)
00093 , m_QuadraticAttenuation(light.m_QuadraticAttenuation)
00094 , m_TwoSided(light.m_TwoSided)
00095 , m_pContext(light.m_pContext)
00096 , m_IsValid(false)
00097 {
00098         addNewLight();
00099 }
00100 
00101 GLC_Light::~GLC_Light(void)
00102 {
00103         removeThisLight();
00104 }
00105 
00107 // Get Functions
00109 
00110 int GLC_Light::maxLightCount()
00111 {
00112         return m_MaxLight;
00113 }
00114 
00115 int GLC_Light::builtAbleLightCount(QGLContext* pContext)
00116 {
00117         if (m_ContextToFreeLightSet.contains(pContext))
00118         {
00119                 return m_ContextToFreeLightSet.value(pContext).size();
00120         }
00121         else return m_MaxLight;
00122 }
00123 
00125 // Set Functions
00127 void GLC_Light::initForThisContext()
00128 {
00129         for (int i= 0; i < m_MaxLight; ++i)
00130         {
00131                 m_ContextToFreeLightSet[m_pContext].insert(GL_LIGHT0 + i);
00132         }
00133 }
00134 
00135 void GLC_Light::setPosition(const GLC_Point3d &pos)
00136 {
00137         m_Position= pos;
00138 }
00139 
00140 void GLC_Light::setPosition(GLfloat x, GLfloat y, GLfloat z)
00141 {
00142         m_Position.setVect(static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
00143 }
00144 
00145 void GLC_Light::setAmbientColor(const QColor& color)
00146 {
00147         m_AmbientColor= color;
00148         m_IsValid= false;
00149 }
00150 
00151 void GLC_Light::setDiffuseColor(const QColor& color)
00152 {
00153         m_DiffuseColor= color;
00154         m_IsValid= false;
00155 }
00156 
00157 void GLC_Light::setSpecularColor(const QColor& color)
00158 {
00159         m_SpecularColor= color;
00160         m_IsValid= false;
00161 }
00162 
00163 void GLC_Light::setTwoSided(const bool mode)
00164 {
00165         m_TwoSided= mode;
00166         m_IsValid= false;
00167 }
00168 
00169 void GLC_Light::setConstantAttenuation(GLfloat constantAttenuation)
00170 {
00171         m_ConstantAttenuation= constantAttenuation;
00172         m_IsValid= false;
00173 }
00174 
00175 void GLC_Light::setLinearAttenuation(GLfloat linearAttenuation)
00176 {
00177         m_LinearAttenuation= linearAttenuation;
00178         m_IsValid= false;
00179 }
00180 
00181 void GLC_Light::setQuadraticAttenuation(GLfloat quadraticAttenuation)
00182 {
00183         m_QuadraticAttenuation= quadraticAttenuation;
00184         m_IsValid= false;
00185 }
00186 
00187 void GLC_Light::setSpotDirection(const GLC_Vector3d& direction)
00188 {
00189         m_SpotDirection= direction;
00190         m_IsValid= false;
00191 }
00192 
00193 void GLC_Light::setSpotCutoffAngle(GLfloat cutoffAngle)
00194 {
00195         m_SpotCutoffAngle= cutoffAngle;
00196         m_IsValid= false;
00197 }
00198 
00199 void GLC_Light::setSpotEponent(GLfloat exponent)
00200 {
00201         m_SpotExponent= exponent;
00202         m_IsValid= false;
00203 }
00204 
00206 // OpenGL Functions
00208 
00209 
00210 void GLC_Light::disable()
00211 {
00212         if (NULL != m_pContext)
00213         {
00214                 glDisable(m_LightID);
00215         }
00216 }
00217 
00218 
00219 void GLC_Light::glExecute()
00220 {
00221         if (NULL == m_pContext)
00222         {
00223                 m_pContext= const_cast<QGLContext*>(QGLContext::currentContext());
00224                 Q_ASSERT(NULL != m_pContext);
00225                 addNewLight();
00226         }
00227 
00228         GLC_Context::current()->glcEnableLighting(true);
00229         glEnable(m_LightID);
00230 
00231         if (m_pContext != QGLContext::currentContext())
00232         {
00233                 Q_ASSERT(QGLContext::areSharing(m_pContext, QGLContext::currentContext()));
00234                 m_IsValid= false;
00235         }
00236         Q_ASSERT(m_pContext->isValid());
00237 
00238         GLfloat setArray[4];
00239 
00240         // Position
00241         setArray[0]= static_cast<GLfloat>(m_Position.x());
00242         setArray[1]= static_cast<GLfloat>(m_Position.y());
00243         setArray[2]= static_cast<GLfloat>(m_Position.z());
00244 
00245         if (LightDirection == m_LightType)
00246         {
00247                 setArray[3]= 0.0f;
00248                 glLightfv(m_LightID, GL_POSITION, setArray);    // Direction of the Light
00249         }
00250         else
00251         {
00252                 setArray[3]= 1.0f;
00253                 glLightfv(m_LightID, GL_POSITION, setArray);    // Position of the Light
00254         }
00255 
00256 
00257         if (!m_IsValid)
00258         {
00259                 // Set the lighting model
00260                 if (m_TwoSided)
00261                 {
00262                         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
00263                 }
00264                 else
00265                 {
00266                         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
00267                 }
00268 
00269                 // Color
00270                 setArray[0]= static_cast<GLfloat>(m_AmbientColor.redF());
00271                 setArray[1]= static_cast<GLfloat>(m_AmbientColor.greenF());
00272                 setArray[2]= static_cast<GLfloat>(m_AmbientColor.blueF());
00273                 setArray[3]= static_cast<GLfloat>(m_AmbientColor.alphaF());
00274                 glLightfv(m_LightID, GL_AMBIENT, setArray);             // Setup The Ambient Light
00275 
00276                 setArray[0]= static_cast<GLfloat>(m_DiffuseColor.redF());
00277                 setArray[1]= static_cast<GLfloat>(m_DiffuseColor.greenF());
00278                 setArray[2]= static_cast<GLfloat>(m_DiffuseColor.blueF());
00279                 setArray[3]= static_cast<GLfloat>(m_DiffuseColor.alphaF());
00280                 glLightfv(m_LightID, GL_DIFFUSE, setArray);             // Setup The Diffuse Light
00281 
00282 
00283                 setArray[0]= static_cast<GLfloat>(m_SpecularColor.redF());
00284                 setArray[1]= static_cast<GLfloat>(m_SpecularColor.greenF());
00285                 setArray[2]= static_cast<GLfloat>(m_SpecularColor.blueF());
00286                 setArray[3]= static_cast<GLfloat>(m_SpecularColor.alphaF());
00287                 glLightfv(m_LightID, GL_SPECULAR, setArray);    // Setup The specular Light
00288 
00289                 if (LightDirection != m_LightType)
00290                         glLightf(m_LightID, GL_CONSTANT_ATTENUATION, m_ConstantAttenuation);
00291                         glLightf(m_LightID, GL_LINEAR_ATTENUATION, m_LinearAttenuation);
00292                         glLightf(m_LightID, GL_QUADRATIC_ATTENUATION, m_QuadraticAttenuation);
00293 
00294                 // Spot light parameters
00295                 if (LightSpot == m_LightType)
00296                 {
00297                         // Spot Direction
00298                         setArray[0]= static_cast<GLfloat>(m_SpotDirection.x());
00299                         setArray[1]= static_cast<GLfloat>(m_SpotDirection.y());
00300                         setArray[2]= static_cast<GLfloat>(m_SpotDirection.z());
00301                         glLightfv(m_LightID, GL_SPOT_DIRECTION, setArray);
00302                         glLightf(m_LightID, GL_SPOT_EXPONENT, m_SpotExponent);
00303                         glLightf(m_LightID, GL_SPOT_CUTOFF, m_SpotCutoffAngle);
00304                 }
00305 
00306                 m_IsValid= true;
00307         }
00308 
00309         // OpenGL error handler
00310         GLenum error= glGetError();
00311         if (error != GL_NO_ERROR)
00312         {
00313                 qDebug() << "GLC_Light::glExecute Exception, id= " << m_LightID;
00314                 GLC_OpenGlException OpenGlException("GLC_Light::glExecute ", error);
00315                 throw(OpenGlException);
00316         }
00317 
00318 }
00319 
00321 // Private services Functions
00323 
00324 
00326 // Private services fonction
00328 void GLC_Light::addNewLight()
00329 {
00330         if (NULL != m_pContext)
00331         {
00332                 if (!m_ContextToFreeLightSet.contains(m_pContext))
00333                 {
00334                         m_ContextToFreeLightSet.insert(m_pContext, QSet<GLenum>());
00335                         initForThisContext();
00336                 }
00337 
00338                 // Some OpenGL driver support only Light0 ???
00339                 if (m_ContextToFreeLightSet.value(m_pContext).size() == m_MaxLight)
00340                 {
00341                         m_LightID= GL_LIGHT0;
00342                 }
00343                 else
00344                 {
00345                         m_LightID= *(m_ContextToFreeLightSet[m_pContext].constBegin());
00346                 }
00347 
00348                 m_ContextToFreeLightSet[m_pContext].remove(m_LightID);
00349         }
00350 }
00351 
00352 void GLC_Light::removeThisLight()
00353 {
00354         if (NULL != m_pContext)
00355         {
00356                 Q_ASSERT(m_ContextToFreeLightSet.contains(m_pContext));
00357                 Q_ASSERT(!m_ContextToFreeLightSet[m_pContext].contains(m_LightID));
00358                 m_ContextToFreeLightSet[m_pContext].insert(m_LightID);
00359                 if (m_ContextToFreeLightSet[m_pContext].size() == m_MaxLight)
00360                 {
00361                         m_ContextToFreeLightSet.remove(m_pContext);
00362                 }
00363         }
00364 }

SourceForge.net Logo

©2005-2011 Laurent Ribon