GLC_lib  2.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glc_light.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 
3  This file is part of the GLC-lib library.
4  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
5  http://glc-lib.sourceforge.net
6 
7  GLC-lib is free software; you can redistribute it and/or modify
8  it under the terms of the GNU Lesser General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  GLC-lib is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with GLC-lib; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21 *****************************************************************************/
22 
24 
25 #include <QGLContext>
26 #include <QtDebug>
27 
28 #include "glc_light.h"
29 #include "../glc_openglexception.h"
30 #include "../glc_context.h"
31 
32 GLint GLC_Light::m_MaxLight= 8;
33 QHash<const QGLContext*, QSet<GLenum> > GLC_Light::m_ContextToFreeLightSet;
34 
36 // Constructor Destructor
38 GLC_Light::GLC_Light(const QGLContext* pContext, const QColor& color)
39 :GLC_Object("Light")
40 , m_LightID(-1)
41 , m_LightType(LightPosition)
42 , m_AmbientColor(Qt::black)
43 , m_DiffuseColor(color)
44 , m_SpecularColor(Qt::white)
45 , m_Position()
46 , m_SpotDirection(0.0, 0.0, -1.0)
47 , m_SpotExponent(0.0f)
48 , m_SpotCutoffAngle(180.0f)
49 , m_ConstantAttenuation(1.0f)
50 , m_LinearAttenuation(0.0f)
51 , m_QuadraticAttenuation(0.0f)
52 , m_TwoSided(false)
53 , m_pContext(const_cast<QGLContext*>(pContext))
54 , m_IsValid(false)
55 {
56  addNewLight();
57 }
58 
59 GLC_Light::GLC_Light(LightType lightType, const QGLContext* pContext, const QColor& color)
60 :GLC_Object("Light")
61 , m_LightID(-1)
62 , m_LightType(lightType)
63 , m_AmbientColor(Qt::black)
64 , m_DiffuseColor(color)
65 , m_SpecularColor(Qt::white)
66 , m_Position()
67 , m_SpotDirection(0.0, 0.0, -1.0)
68 , m_SpotExponent(0.0f)
69 , m_SpotCutoffAngle(180.0f)
70 , m_ConstantAttenuation(1.0f)
71 , m_LinearAttenuation(0.0f)
72 , m_QuadraticAttenuation(0.0f)
73 , m_TwoSided(false)
74 , m_pContext(const_cast<QGLContext*>(pContext))
75 , m_IsValid(false)
76 {
77  addNewLight();
78 }
79 
81 :GLC_Object(light)
82 , m_LightID(-1)
83 , m_LightType(light.m_LightType)
84 , m_AmbientColor(light.m_AmbientColor)
85 , m_DiffuseColor(light.m_DiffuseColor)
86 , m_SpecularColor(light.m_SpecularColor)
87 , m_Position(light.m_Position)
88 , m_SpotDirection(light.m_SpotDirection)
89 , m_SpotExponent(light.m_SpotExponent)
90 , m_SpotCutoffAngle(light.m_SpotCutoffAngle)
91 , m_ConstantAttenuation(light.m_ConstantAttenuation)
92 , m_LinearAttenuation(light.m_LinearAttenuation)
93 , m_QuadraticAttenuation(light.m_QuadraticAttenuation)
94 , m_TwoSided(light.m_TwoSided)
95 , m_pContext(light.m_pContext)
96 , m_IsValid(false)
97 {
98  addNewLight();
99 }
100 
102 {
103  removeThisLight();
104 }
105 
107 // Get Functions
109 
111 {
112  return m_MaxLight;
113 }
114 
115 int GLC_Light::builtAbleLightCount(QGLContext* pContext)
116 {
117  if (m_ContextToFreeLightSet.contains(pContext))
118  {
119  return m_ContextToFreeLightSet.value(pContext).size();
120  }
121  else return m_MaxLight;
122 }
123 
125 // Set Functions
128 {
129  for (int i= 0; i < m_MaxLight; ++i)
130  {
131  m_ContextToFreeLightSet[m_pContext].insert(GL_LIGHT0 + i);
132  }
133 }
134 
136 {
137  m_Position= pos;
138 }
139 
140 void GLC_Light::setPosition(GLfloat x, GLfloat y, GLfloat z)
141 {
142  m_Position.setVect(static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
143 }
144 
145 void GLC_Light::setAmbientColor(const QColor& color)
146 {
147  m_AmbientColor= color;
148  m_IsValid= false;
149 }
150 
151 void GLC_Light::setDiffuseColor(const QColor& color)
152 {
153  m_DiffuseColor= color;
154  m_IsValid= false;
155 }
156 
157 void GLC_Light::setSpecularColor(const QColor& color)
158 {
159  m_SpecularColor= color;
160  m_IsValid= false;
161 }
162 
163 void GLC_Light::setTwoSided(const bool mode)
164 {
165  m_TwoSided= mode;
166  m_IsValid= false;
167 }
168 
169 void GLC_Light::setConstantAttenuation(GLfloat constantAttenuation)
170 {
172  m_IsValid= false;
173 }
174 
175 void GLC_Light::setLinearAttenuation(GLfloat linearAttenuation)
176 {
178  m_IsValid= false;
179 }
180 
181 void GLC_Light::setQuadraticAttenuation(GLfloat quadraticAttenuation)
182 {
184  m_IsValid= false;
185 }
186 
188 {
189  m_SpotDirection= direction;
190  m_IsValid= false;
191 }
192 
193 void GLC_Light::setSpotCutoffAngle(GLfloat cutoffAngle)
194 {
195  m_SpotCutoffAngle= cutoffAngle;
196  m_IsValid= false;
197 }
198 
199 void GLC_Light::setSpotEponent(GLfloat exponent)
200 {
201  m_SpotExponent= exponent;
202  m_IsValid= false;
203 }
204 
206 // OpenGL Functions
208 
209 
211 {
212  if (NULL != m_pContext)
213  {
214  glDisable(m_LightID);
215  }
216 }
217 
218 
220 {
221  if (NULL == m_pContext)
222  {
223  m_pContext= const_cast<QGLContext*>(QGLContext::currentContext());
224  Q_ASSERT(NULL != m_pContext);
225  addNewLight();
226  }
227 
229  glEnable(m_LightID);
230 
231  if (m_pContext != QGLContext::currentContext())
232  {
233  Q_ASSERT(QGLContext::areSharing(m_pContext, QGLContext::currentContext()));
234  m_IsValid= false;
235  }
236  Q_ASSERT(m_pContext->isValid());
237 
238  GLfloat setArray[4];
239 
240  // Position
241  setArray[0]= static_cast<GLfloat>(m_Position.x());
242  setArray[1]= static_cast<GLfloat>(m_Position.y());
243  setArray[2]= static_cast<GLfloat>(m_Position.z());
244 
246  {
247  setArray[3]= 0.0f;
248  glLightfv(m_LightID, GL_POSITION, setArray); // Direction of the Light
249  }
250  else
251  {
252  setArray[3]= 1.0f;
253  glLightfv(m_LightID, GL_POSITION, setArray); // Position of the Light
254  }
255 
256 
257  if (!m_IsValid)
258  {
259  // Set the lighting model
260  if (m_TwoSided)
261  {
262  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
263  }
264  else
265  {
266  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
267  }
268 
269  // Color
270  setArray[0]= static_cast<GLfloat>(m_AmbientColor.redF());
271  setArray[1]= static_cast<GLfloat>(m_AmbientColor.greenF());
272  setArray[2]= static_cast<GLfloat>(m_AmbientColor.blueF());
273  setArray[3]= static_cast<GLfloat>(m_AmbientColor.alphaF());
274  glLightfv(m_LightID, GL_AMBIENT, setArray); // Setup The Ambient Light
275 
276  setArray[0]= static_cast<GLfloat>(m_DiffuseColor.redF());
277  setArray[1]= static_cast<GLfloat>(m_DiffuseColor.greenF());
278  setArray[2]= static_cast<GLfloat>(m_DiffuseColor.blueF());
279  setArray[3]= static_cast<GLfloat>(m_DiffuseColor.alphaF());
280  glLightfv(m_LightID, GL_DIFFUSE, setArray); // Setup The Diffuse Light
281 
282 
283  setArray[0]= static_cast<GLfloat>(m_SpecularColor.redF());
284  setArray[1]= static_cast<GLfloat>(m_SpecularColor.greenF());
285  setArray[2]= static_cast<GLfloat>(m_SpecularColor.blueF());
286  setArray[3]= static_cast<GLfloat>(m_SpecularColor.alphaF());
287  glLightfv(m_LightID, GL_SPECULAR, setArray); // Setup The specular Light
288 
290  glLightf(m_LightID, GL_CONSTANT_ATTENUATION, m_ConstantAttenuation);
291  glLightf(m_LightID, GL_LINEAR_ATTENUATION, m_LinearAttenuation);
292  glLightf(m_LightID, GL_QUADRATIC_ATTENUATION, m_QuadraticAttenuation);
293 
294  // Spot light parameters
295  if (LightSpot == m_LightType)
296  {
297  // Spot Direction
298  setArray[0]= static_cast<GLfloat>(m_SpotDirection.x());
299  setArray[1]= static_cast<GLfloat>(m_SpotDirection.y());
300  setArray[2]= static_cast<GLfloat>(m_SpotDirection.z());
301  glLightfv(m_LightID, GL_SPOT_DIRECTION, setArray);
302  glLightf(m_LightID, GL_SPOT_EXPONENT, m_SpotExponent);
303  glLightf(m_LightID, GL_SPOT_CUTOFF, m_SpotCutoffAngle);
304  }
305 
306  m_IsValid= true;
307  }
308 
309  // OpenGL error handler
310  GLenum error= glGetError();
311  if (error != GL_NO_ERROR)
312  {
313  qDebug() << "GLC_Light::glExecute Exception, id= " << m_LightID;
314  GLC_OpenGlException OpenGlException("GLC_Light::glExecute ", error);
315  throw(OpenGlException);
316  }
317 
318 }
319 
321 // Private services Functions
323 
324 
326 // Private services fonction
329 {
330  if (NULL != m_pContext)
331  {
332  if (!m_ContextToFreeLightSet.contains(m_pContext))
333  {
334  m_ContextToFreeLightSet.insert(m_pContext, QSet<GLenum>());
336  }
337 
338  // Some OpenGL driver support only Light0 ???
339  if (m_ContextToFreeLightSet.value(m_pContext).size() == m_MaxLight)
340  {
341  m_LightID= GL_LIGHT0;
342  }
343  else
344  {
345  m_LightID= *(m_ContextToFreeLightSet[m_pContext].constBegin());
346  }
347 
349  }
350 }
351 
353 {
354  if (NULL != m_pContext)
355  {
356  Q_ASSERT(m_ContextToFreeLightSet.contains(m_pContext));
357  Q_ASSERT(!m_ContextToFreeLightSet[m_pContext].contains(m_LightID));
360  {
362  }
363  }
364 }

©2005-2013 Laurent Ribon