1 /****************************************************************************
2 
3  Copyright (C) 2002-2014 Gilles Debunne. All rights reserved.
4 
5  This file is part of the QGLViewer library version 2.7.2.
6 
7  http://www.libqglviewer.com - contact@libqglviewer.com
8 
9  This file may be used under the terms of the GNU General Public License
10  versions 2.0 or 3.0 as published by the Free Software Foundation and
11  appearing in the LICENSE file included in the packaging of this file.
12  In addition, as a special exception, Gilles Debunne gives you certain
13  additional rights, described in the file GPL_EXCEPTION in this package.
14 
15  libQGLViewer uses dual licensing. Commercial/proprietary software must
16  purchase a libQGLViewer Commercial License.
17 
18  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
19  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 
21 *****************************************************************************/
22 
23 #include "drawLight.h"
24 #include <math.h>
25 
26 #include <QGLViewer/manipulatedFrame.h>
27 
28 using namespace std;
29 using namespace qglviewer;
30 
draw()31 void Viewer::draw() {
32   float pos[4] = {1.0, 0.5, 1.0, 0.0};
33   // Directionnal light
34   glLightfv(GL_LIGHT0, GL_POSITION, pos);
35 
36   pos[3] = 1.0;
37   // Spot light
38   Vec pos1 = light1->position();
39   pos[0] = float(pos1.x);
40   pos[1] = float(pos1.y);
41   pos[2] = float(pos1.z);
42   glLightfv(GL_LIGHT1, GL_POSITION, pos);
43   glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION,
44             light1->inverseTransformOf(Vec(0, 0, 1)));
45 
46   // Point light
47   Vec pos2 = light2->position();
48   pos[0] = float(pos2.x);
49   pos[1] = float(pos2.y);
50   pos[2] = float(pos2.z);
51   glLightfv(GL_LIGHT2, GL_POSITION, pos);
52 
53   // Draws the spiral
54   const float nbSteps = 200.0;
55   glBegin(GL_QUAD_STRIP);
56   for (float i = 0; i < nbSteps; ++i) {
57     float ratio = i / nbSteps;
58     float angle = 21.0 * ratio;
59     float c = cos(angle);
60     float s = sin(angle);
61     float r1 = 1.0 - 0.8 * ratio;
62     float r2 = 0.8 - 0.8 * ratio;
63     float alt = ratio - 0.5;
64     const float nor = .5;
65     const float up = sqrt(1.0 - nor * nor);
66     glColor3f(1 - ratio, 0.2f, ratio);
67     glNormal3f(nor * c, up, nor * s);
68     glVertex3f(r1 * c, alt, r1 * s);
69     glVertex3f(r2 * c, alt + 0.05, r2 * s);
70   }
71   glEnd();
72 
73   drawLight(GL_LIGHT0);
74 
75   if (light1->grabsMouse())
76     drawLight(GL_LIGHT1, 1.2f);
77   else
78     drawLight(GL_LIGHT1);
79 
80   if (light2->grabsMouse())
81     drawLight(GL_LIGHT2, 1.2f);
82   else
83     drawLight(GL_LIGHT2);
84 }
85 
init()86 void Viewer::init() {
87   glMatrixMode(GL_MODELVIEW);
88   glLoadIdentity();
89 
90   // Light0 is the default ambient light
91   glEnable(GL_LIGHT0);
92 
93   // Light1 is a spot light
94   glEnable(GL_LIGHT1);
95   const GLfloat light_ambient[4] = {0.8f, 0.2f, 0.2f, 1.0};
96   const GLfloat light_diffuse[4] = {1.0, 0.4f, 0.4f, 1.0};
97   const GLfloat light_specular[4] = {1.0, 0.0, 0.0, 1.0};
98 
99   glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 3.0);
100   glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 20.0);
101   glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 0.5);
102   glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 1.0);
103   glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 1.5);
104   glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
105   glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
106   glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
107 
108   // Light2 is a classical directionnal light
109   glEnable(GL_LIGHT2);
110   const GLfloat light_ambient2[4] = {0.2f, 0.2f, 2.0, 1.0};
111   const GLfloat light_diffuse2[4] = {0.8f, 0.8f, 1.0, 1.0};
112   const GLfloat light_specular2[4] = {0.0, 0.0, 1.0, 1.0};
113 
114   glLightfv(GL_LIGHT2, GL_AMBIENT, light_ambient2);
115   glLightfv(GL_LIGHT2, GL_SPECULAR, light_specular2);
116   glLightfv(GL_LIGHT2, GL_DIFFUSE, light_diffuse2);
117 
118   light1 = new ManipulatedFrame();
119   light2 = new ManipulatedFrame();
120   setMouseTracking(true);
121 
122   light1->setPosition(0.5, 0.5, 0);
123   // Align z axis with -position direction : look at scene center
124   light1->setOrientation(Quaternion(Vec(0, 0, 1), -light1->position()));
125 
126   light2->setPosition(-0.5, 0.5, 0);
127 
128   restoreStateFromFile();
129   help();
130 }
131 
helpString() const132 QString Viewer::helpString() const {
133   QString text("<h2>D r a w L i g h t</h2>");
134   text += "The <i>drawLight()</i> function displays a representation of the "
135           "OpenGL lights ";
136   text += "of your scene. This is convenient for debugging your light "
137           "setup.<br><br>";
138   text += "This scene features a directionnal ligth (arrow), a spot light "
139           "(cone) and a point ";
140   text += "light source (sphere). The representation color, position and shape "
141           "matches the light setup.<br><br>";
142   text += "Hover over the point light or the spot light to manipulate it using "
143           "the mouse (right ";
144   text += "button translates and left button rotates).";
145   return text;
146 }
147