]> git.mxchange.org Git - simgear.git/blob - simgear/scene/sky/clouds3d/SkyLight.cpp
Clouds3D crashes because there is no Light
[simgear.git] / simgear / scene / sky / clouds3d / SkyLight.cpp
1 //------------------------------------------------------------------------------
2 // File : SkyLight.cpp
3 //------------------------------------------------------------------------------
4 // SkyWorks : Copyright 2002 Mark J. Harris and
5 //                                              The University of North Carolina at Chapel Hill
6 //------------------------------------------------------------------------------
7 // Permission to use, copy, modify, distribute and sell this software and its 
8 // documentation for any purpose is hereby granted without fee, provided that 
9 // the above copyright notice appear in all copies and that both that copyright 
10 // notice and this permission notice appear in supporting documentation. 
11 // Binaries may be compiled with this software without any royalties or 
12 // restrictions. 
13 //
14 // The author(s) and The University of North Carolina at Chapel Hill make no 
15 // representations about the suitability of this software for any purpose. 
16 // It is provided "as is" without express or implied warranty.
17 /**
18  * @file SkyLight.cpp
19  * 
20  * Implementation of a class that maintains the state and operation of a light.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #  include <simgear_config.h>
25 #endif
26
27 #ifdef HAVE_WINDOWS_H
28 #  include <windows.h>
29 #endif
30
31 #include <GL/glu.h>
32
33 #include "glut_shapes.h"
34
35 #ifdef WIN32
36 # ifdef _MSC_VER
37 #  pragma warning( disable : 4786)
38 # endif
39 # include "extgl.h"
40 #endif
41
42 #include "SkyLight.hpp"
43 #include "SkyMaterial.hpp"
44 #include "mat44.hpp"
45
46 SkyMaterial* SkyLight::s_pMaterial = NULL;
47
48 //------------------------------------------------------------------------------
49 // Function               : SkyLight::SkyLight
50 // Description      : 
51 //------------------------------------------------------------------------------
52 /**
53 * @fn SkyLight::SkyLight(SkyLightType eType)
54 * @brief @todo <WRITE BRIEF SkyLight::SkyLight DOCUMENTATION>
55
56 * @todo <WRITE EXTENDED SkyLight::SkyLight FUNCTION DOCUMENTATION>
57 */ 
58 SkyLight::SkyLight(SkyLightType eType)
59 : _bEnabled(true),
60 _bDirty(true),
61 _iLastGLID(-1),
62 _eType(eType),
63 _vecPosition(0, 0, 1, 1),
64 _vecDirection(0, 0, -1, 0),
65 _vecDiffuse(1, 1, 1, 1),
66 _vecAmbient(0, 0, 0, 0),
67 _vecSpecular(1, 1, 1, 1),
68 _vecAttenuation(1, 0, 0),
69 _rSpotExponent(0),
70 _rSpotCutoff(180)  
71 {
72   if (!s_pMaterial)
73   {
74     s_pMaterial = new SkyMaterial;
75     s_pMaterial->SetColorMaterialMode(GL_DIFFUSE);
76     s_pMaterial->EnableColorMaterial(true);
77     s_pMaterial->EnableLighting(false);
78   }
79 }
80
81
82 //------------------------------------------------------------------------------
83 // Function               : SkyLight::~SkyLight
84 // Description      : 
85 //------------------------------------------------------------------------------
86 /**
87 * @fn SkyLight::~SkyLight()
88 * @brief @todo <WRITE BRIEF SkyLight::~SkyLight DOCUMENTATION>
89
90 * @todo <WRITE EXTENDED SkyLight::~SkyLight FUNCTION DOCUMENTATION>
91 */ 
92 SkyLight::~SkyLight()
93 {
94 }
95
96 //------------------------------------------------------------------------------
97 // Function               : SkyLight::Display
98 // Description      : 
99 //------------------------------------------------------------------------------
100 /**
101 * @fn SkyLight::Display() const
102 * @brief Displays a wireframe representation of the light.
103
104 * This is useful for debugging.
105 */ 
106 void SkyLight::Display() const
107 {
108   s_pMaterial->Activate();
109   //if (_bEnabled)
110     //glColor3fv(&(_vecDiffuse.x));
111   //else
112     glColor3f(0, 0, 0);
113
114   switch(_eType)
115   {
116   case SKY_LIGHT_POINT:
117     glMatrixMode(GL_MODELVIEW);
118     glPushMatrix();
119     {
120       glTranslatef(_vecPosition.x, _vecPosition.y, _vecPosition.z);
121       glutWireSphere(4, 8, 8);
122     }
123     glPopMatrix();
124     break;
125   case SKY_LIGHT_DIRECTIONAL:
126     {
127       glMatrixMode(GL_MODELVIEW);
128       glPushMatrix();
129       {
130         Mat44f mat;
131         Vec3f vecPos(_vecPosition.x, _vecPosition.y, _vecPosition.z);
132         Vec3f vecDir(_vecDirection.x, _vecDirection.y, _vecDirection.z);
133         Vec3f vecUp(0, 1, 0);
134         if (fabs(vecDir * vecUp) - 1 < 1e-6) // check that the view and up directions are not parallel.
135           vecUp.Set(1, 0, 0);
136         
137         mat.invLookAt(vecPos, vecPos + 10 * vecDir, vecUp);
138         
139         glPushMatrix();
140         {
141           glTranslatef(-50 * vecDir.x, -50 * vecDir.y, -50 * vecDir.z);
142           glMultMatrixf(mat);
143           glutWireCone(10, 10, 4, 1);
144         }
145         glPopMatrix(); 
146         
147         glMultMatrixf(mat); 
148         GLUquadric *pQuadric = gluNewQuadric();
149         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
150         gluCylinder(pQuadric, 4, 4, 50, 4, 4);
151         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
152       }
153       glPopMatrix();
154     }
155     break;
156   case SKY_LIGHT_SPOT:
157     {
158       glMatrixMode(GL_MODELVIEW);
159       glPushMatrix();
160       {
161         Mat44f mat;
162         Vec3f vecUp = Vec3f(0, 1, 0);
163         Vec3f vecPos(_vecPosition.x, _vecPosition.y, _vecPosition.z);
164         Vec3f vecDir(_vecDirection.x, _vecDirection.y, _vecDirection.z);
165         if (_vecDirection == vecUp)
166           vecUp.Set(1, 0, 0);
167         mat.invLookAt(vecPos + 50 * vecDir, vecPos + 51 * vecDir, vecUp);
168
169         glMultMatrixf(mat);   
170         float rAlpha= acos(pow(10, (-12 / _rSpotExponent)));
171         //glutWireCone(50 * tan(SKYDEGREESTORADS * rAlpha), 50, 16, 8);
172         glutWireCone(50 * tan(SKYDEGREESTORADS * _rSpotCutoff), 50, 16, 8);
173       }
174       glPopMatrix();
175     }
176     break;
177   default:
178     break;
179   }  
180 }
181
182 //------------------------------------------------------------------------------
183 // Function               : SkyLight::Activate
184 // Description      : 
185 //------------------------------------------------------------------------------
186 /**
187  * @fn SkyLight::Activate(int iLightID)
188  * @brief @todo <WRITE BRIEF SkyLight::Activate DOCUMENTATION>
189  * 
190  * @todo <WRITE EXTENDED SkyLight::Activate FUNCTION DOCUMENTATION>
191  */ 
192 SKYRESULT SkyLight::Activate(int iLightID)
193 {
194   glPushMatrix();
195   // set the position every frame
196   if (SKY_LIGHT_DIRECTIONAL != _eType)
197     glLightfv(GL_LIGHT0 + iLightID, GL_POSITION,              &(_vecPosition.x));
198   else
199     glLightfv(GL_LIGHT0 + iLightID, GL_POSITION,              &(_vecDirection.x));
200   
201   if (SKY_LIGHT_SPOT == _eType)
202     glLightfv(GL_LIGHT0 + iLightID, GL_SPOT_DIRECTION,      &(_vecDirection.x));
203
204   // set other light properties only when they change.
205   if (_bDirty || iLightID != _iLastGLID)
206   {     
207     glLightfv(GL_LIGHT0 + iLightID,   GL_DIFFUSE,               &(_vecDiffuse.x));
208     glLightfv(GL_LIGHT0 + iLightID,   GL_AMBIENT,               &(_vecAmbient.x));
209     glLightfv(GL_LIGHT0 + iLightID,   GL_SPECULAR,              &(_vecSpecular.x));
210     glLightf(GL_LIGHT0 + iLightID,    GL_CONSTANT_ATTENUATION,  _vecAttenuation.x);
211     glLightf(GL_LIGHT0 + iLightID,    GL_LINEAR_ATTENUATION,    _vecAttenuation.y);
212     glLightf(GL_LIGHT0 + iLightID,    GL_QUADRATIC_ATTENUATION, _vecAttenuation.z);
213     
214     if (SKY_LIGHT_SPOT == _eType)
215     {
216       glLightf(GL_LIGHT0 + iLightID,  GL_SPOT_CUTOFF,         _rSpotCutoff);
217       glLightf(GL_LIGHT0 + iLightID,  GL_SPOT_EXPONENT,       _rSpotExponent);
218     }
219     else
220     {
221       glLightf(GL_LIGHT0 + iLightID,  GL_SPOT_CUTOFF,         180);
222       glLightf(GL_LIGHT0 + iLightID,  GL_SPOT_EXPONENT,       0);
223     }
224  
225     if (_bEnabled)
226       glEnable(GL_LIGHT0 + iLightID);
227     else
228     {
229       glDisable(GL_LIGHT0 + iLightID);
230     }
231     
232     _iLastGLID = iLightID;
233     _bDirty = false;    
234   }
235   glPopMatrix();
236  
237   return SKYRESULT_OK;
238 }