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