1 /**************************************************************************\
2  * Copyright (c) Kongsberg Oil & Gas Technologies AS
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32 
33 /*!
34   \class SoPointLight SoPointLight.h Inventor/nodes/SoPointLight.h
35   \brief The SoPointLight class is a node type for light sources.
36 
37   \ingroup nodes
38 
39   Pointlights emits light equally in all directions from a specified
40   3D location.
41 
42   See also documentation of parent class for important information
43   regarding light sources in general.
44 
45   <b>FILE FORMAT/DEFAULTS:</b>
46   \code
47     PointLight {
48         on TRUE
49         intensity 1
50         color 1 1 1
51         location 0 0 1
52     }
53   \endcode
54 */
55 
56 // *************************************************************************
57 
58 #include <Inventor/nodes/SoPointLight.h>
59 
60 #ifdef HAVE_CONFIG_H
61 #include <config.h>
62 #endif // HAVE_CONFIG_H
63 
64 #include <Inventor/SbColor4f.h>
65 #include <Inventor/SbVec4f.h>
66 #include <Inventor/actions/SoGLRenderAction.h>
67 #include <Inventor/elements/SoEnvironmentElement.h>
68 #include <Inventor/elements/SoGLLightIdElement.h>
69 #include <Inventor/elements/SoModelMatrixElement.h>
70 #include <Inventor/elements/SoViewingMatrixElement.h>
71 #include <Inventor/elements/SoLightElement.h>
72 #include <Inventor/errors/SoDebugError.h>
73 #include <Inventor/system/gl.h>
74 
75 #include "nodes/SoSubNodeP.h"
76 
77 // *************************************************************************
78 
79 /*!
80   \var SoSFVec3f SoPointLight::location
81   3D position of lightsource. Default value is <0, 0, 1>.
82 */
83 
84 // *************************************************************************
85 
86 SO_NODE_SOURCE(SoPointLight);
87 
88 // *************************************************************************
89 
90 /*!
91   Constructor.
92 */
SoPointLight(void)93 SoPointLight::SoPointLight(void)
94 {
95   SO_NODE_INTERNAL_CONSTRUCTOR(SoPointLight);
96 
97   SO_NODE_ADD_FIELD(location, (0.0f, 0.0f, 1.0f));
98 }
99 
100 /*!
101   Destructor.
102 */
~SoPointLight()103 SoPointLight::~SoPointLight()
104 {
105 }
106 
107 // Doc from superclass.
108 void
initClass(void)109 SoPointLight::initClass(void)
110 {
111   SO_NODE_INTERNAL_INIT_CLASS(SoPointLight, SO_FROM_INVENTOR_1|SoNode::VRML1);
112 }
113 
114 // Doc from superclass.
115 void
GLRender(SoGLRenderAction * action)116 SoPointLight::GLRender(SoGLRenderAction * action)
117 {
118   if (!this->on.getValue()) return;
119 
120   int idx = SoGLLightIdElement::increment(action->getState());
121 
122   if (idx < 0) {
123 #if COIN_DEBUG
124     SoDebugError::post("SoPointLight::GLRender()",
125                        "Max # lights exceeded :(\n");
126 #endif // COIN_DEBUG
127     return;
128   }
129 
130   SoState * state = action->getState();
131 
132   SoLightElement::add(state, this, SoModelMatrixElement::get(state) *
133                       SoViewingMatrixElement::get(state));
134 
135   GLenum light = (GLenum) (idx + GL_LIGHT0);
136 
137   SbVec3f attenuation = SoEnvironmentElement::getLightAttenuation(state);
138   glLightf(light, GL_QUADRATIC_ATTENUATION, attenuation[0]);
139   glLightf(light, GL_LINEAR_ATTENUATION, attenuation[1]);
140   glLightf(light, GL_CONSTANT_ATTENUATION, attenuation[2]);
141 
142   SbColor4f lightcolor(0.0f, 0.0f, 0.0f, 1.0f);
143   // disable ambient contribution from this light source
144   glLightfv(light, GL_AMBIENT, lightcolor.getValue());
145 
146   lightcolor.setRGB(this->color.getValue());
147   lightcolor *= this->intensity.getValue();
148 
149   glLightfv(light, GL_DIFFUSE, lightcolor.getValue());
150   glLightfv(light, GL_SPECULAR, lightcolor.getValue());
151 
152   SbVec3f loc = this->location.getValue();
153 
154   // point (or spot) light when w = 1.0
155   SbVec4f posvec(loc[0], loc[1], loc[2], 1.0f);
156   glLightfv(light, GL_POSITION, posvec.getValue());
157 
158   // turning off spot light properties for ordinary lights
159   glLightf(light, GL_SPOT_EXPONENT, 0.0);
160   glLightf(light, GL_SPOT_CUTOFF, 180.0);
161 }
162