LightNode.hh 12.2 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2 3
*                                                                            *
*                              OpenFlipper                                   *
Martin Schultz's avatar
Martin Schultz committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
*                                                                            *
Jan Möbius's avatar
Jan Möbius committed
40 41 42
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
43 44 45 46 47
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
Jan Möbius's avatar
Jan Möbius committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
\*===========================================================================*/




//=============================================================================
//
//  CLASS LightNode
//
//=============================================================================

#ifndef ACG_LIGHT_NODE_HH
#define ACG_LIGHT_NODE_HH


//== INCLUDES =================================================================

65
#include <ACG/Scenegraph/BaseNode.hh>
Jan Möbius's avatar
Jan Möbius committed
66
#include <OpenFlipper/common/GlobalDefines.hh>
67
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
68
#include <ACG/GL/gl.hh>
69
#include <ACG/GL/GLPrimitives.hh>
70
#include <OpenFlipper/common/GlobalOptions.hh>
Jan Möbius's avatar
Jan Möbius committed
71 72 73 74 75 76 77 78
#include <string>
#include <vector>


//== NAMESPACES ===============================================================

namespace ACG {
namespace SceneGraph {
79

Jan Möbius's avatar
Jan Möbius committed
80 81 82 83 84

//== CLASS DEFINITION =========================================================

/** \class LightNode LightNode.hh <ACG/Scenegraph/LightNode.hh>

85
    Set LightSources (0 to 7) for this node and all its children.
Jan Möbius's avatar
Jan Möbius committed
86 87 88 89 90
    All changes will be done in the enter() method undone
    in the leave() method.
**/

/// Structure to hold options for one LightSource
Jan Möbius's avatar
Jan Möbius committed
91
class DLLEXPORT LightSource
Jan Möbius's avatar
Jan Möbius committed
92 93 94
{
  // Declare Node as friend for direct access to memberss
  friend class LightNode;
95

Jan Möbius's avatar
Jan Möbius committed
96
public:
97

Jan Möbius's avatar
Jan Möbius committed
98 99
  /// Default Constructor
  LightSource();
100

Jan Möbius's avatar
Jan Möbius committed
101
  /** \brief Set position for LightSource
102
  *
Jan Möbius's avatar
Jan Möbius committed
103 104 105 106 107
  * This function sets the position of a light source. OpenGL handles
  * a position for a light source if the homogeneous coordinate is
  * 1.0. If it is 0.0 the light source will be directional. So a
  * 1.0 is set in this function to get a positioned light source.
  */
108
  void position( Vec3d _pos);
109

Jan Möbius's avatar
Jan Möbius committed
110 111 112 113 114
  /** \brief Get the position of the LightSource
  *
  * Be careful with this function. Check if the light source is not directional with
  * the directional() function
  */
115 116
  Vec3d position() const;

Jan Möbius's avatar
Jan Möbius committed
117 118 119 120 121
  /** \brief Check if the light source is a directional light source
  *
  * If this light Source is a directional light source the function will return true.
  * Otherwise false as the light source has a position.
  */
122 123
  bool directional() const;

124 125 126 127
  /** \brief Get direction of the light source
  *
  * Get direction of light.
  */
128 129
  Vec3d direction() const;

Jan Möbius's avatar
Jan Möbius committed
130 131 132 133 134
  /** \brief Set the direction of the light source
  *
  * This function creates a directional light source. The position is not used by OpenGL.
  * Internally the positions homogeneous coordinate is set to 0.0.
  */
135
  void direction( Vec3d _pos);
136 137

   /// enable LightSource
Jan Möbius's avatar
Jan Möbius committed
138 139
  void enable();

140
  /// disable LightSource
Jan Möbius's avatar
Jan Möbius committed
141
  void disable();
142

Jan Möbius's avatar
Jan Möbius committed
143
  /// Get light source status
144 145 146
  bool enabled() const;

  /** \brief Set spot direction
Jan Möbius's avatar
Jan Möbius committed
147 148 149
  *
  * \todo Improve documentation
  */
Mike Kremer's avatar
Mike Kremer committed
150
  void spotDirection(Vec3d _pos);
151

Jan Möbius's avatar
Jan Möbius committed
152 153 154 155
  /** \brief get spot direction
  *
  * \todo Improve documentation
  */
156
  Vec3d spotDirection( ) const;
Jan Möbius's avatar
Jan Möbius committed
157

158
  /// set Ambient color for LightSource
Jan Möbius's avatar
Jan Möbius committed
159 160
  void ambientColor(  Vec4f _color);

161 162 163 164
  /// get Ambient color for LightSource
  Vec4f ambientColor() const;

  /// set Diffuse color for LightSource
Jan Möbius's avatar
Jan Möbius committed
165 166
  void diffuseColor(  Vec4f _color);

167 168 169 170
  /// get Diffuse color for LightSource
  Vec4f diffuseColor() const;

  /// set Specular color for LightSource
Jan Möbius's avatar
Jan Möbius committed
171
  void specularColor(  Vec4f _color);
172 173 174 175

  /// get Specular color for LightSource
  Vec4f specularColor() const;

176
  void setColor(const Vec4f& _ambient, const Vec4f& _diffuse, const Vec4f& _specular);
Jan Möbius's avatar
Jan Möbius committed
177 178 179

  /// make LightSource fixed or moveable with ModelViewMatrix
  void fixedPosition( bool _state);
180 181 182

  bool fixedPosition() const;

Jan Möbius's avatar
Jan Möbius committed
183
  void spotExponent(float _exponent);
184 185 186

  float spotExponent() const;

Jan Möbius's avatar
Jan Möbius committed
187
  void spotCutoff(float _cutoff);
188 189 190

  float spotCutoff() const;

Jan Möbius's avatar
Jan Möbius committed
191
  void constantAttenuation(float _constantAttenuation);
192 193 194

  float constantAttenuation() const;

Jan Möbius's avatar
Jan Möbius committed
195
  void linearAttenuation(float _linearAttenuation);
196 197 198

  float linearAttenuation() const;

Jan Möbius's avatar
Jan Möbius committed
199
  void quadraticAttenuation(float _quadraticAttenuation);
200 201 202

  float quadraticAttenuation() const;

203
  void brightness(const float _brightness);
204

205
  float brightness() const;
206

207
  /** \brief Get light source radius
208
  *
209 210 211
  * The light radius is the size of the lightsource. In OpenGL rendering this value is ignored.
  * You can use it for example in raytracers to implement soft shadows.
  */
212 213
  float radius() const { return radius_; }

214 215 216 217 218
  /** \brief Set light source radius
  *
  * The light radius is the size of the lightsource. In OpenGL rendering this value is ignored.
  * You can use it for example in raytracers to implement soft shadows.
  */
219
  void radius(const float _radius) { radius_ = _radius; }
220

Jan Möbius's avatar
Jan Möbius committed
221 222 223
protected:

  Vec4f position_;
Mike Kremer's avatar
Mike Kremer committed
224
  Vec4f realPosition_;
225

Jan Möbius's avatar
Jan Möbius committed
226 227 228 229 230
  bool enabled_;
  bool fixedPosition_;
  Vec4f ambientColor_;
  Vec4f diffuseColor_;
  Vec4f specularColor_;
231

232
  Vec3d spotDirection_;
Mike Kremer's avatar
Mike Kremer committed
233
  Vec3d realSpotDirection_;
234

235 236 237 238
  // Only if in fixed mode
  Vec4f initialPosition_;
  Vec3d initialSpotDirection_;
  bool initialPositionInit_;
239

Jan Möbius's avatar
Jan Möbius committed
240 241 242 243 244
  float spotExponent_;
  float spotCutoff_;
  float constantAttenuation_;
  float linearAttenuation_;
  float quadraticAttenuation_;
245

246
  float brightness_;
247

248 249 250 251
  /// When using ray tracing, light sources can have
  /// extent. We simplify to spherical light sources with
  /// radius radius_.
  float radius_;
Jan Möbius's avatar
Jan Möbius committed
252 253 254
};


Jan Möbius's avatar
Jan Möbius committed
255
class DLLEXPORT LightNode : public BaseNode
Jan Möbius's avatar
Jan Möbius committed
256 257 258 259 260 261 262 263 264
{

public:

  /// Default constructor. Applies all properties.
  LightNode( BaseNode*           _parent = 0,
		   const std::string&  _name = "<LightNode>");

  /// Destructor.
265
  virtual ~LightNode();
266

Jan Möbius's avatar
Jan Möbius committed
267 268 269
  /// Set the light source parameters
  void setLightSource(LightSource _light ) { light_ = _light; };

Jan Möbius's avatar
Jan Möbius committed
270 271 272
  /// Get the light source parameters
  void getLightSource(LightSource* _light) const;

273 274 275 276 277
  /// Get transformed light source parameters
  /// where position and direction are in view space
  void getLightSourceViewSpace(LightSource* _light) const;


Jan Möbius's avatar
Jan Möbius committed
278 279
  ACG_CLASSNAME(LightNode);

280 281
  /// Get bounding box (for visualization purposes)
  void boundingBox(ACG::Vec3d& /* _bbMin */, ACG::Vec3d& /*_bbMax*/ );
282

Jan Möbius's avatar
Jan Möbius committed
283
  /// set current Light Sources
284
  void enter(GLState& _state, const DrawModes::DrawMode& _drawmode);
285

Jan Möbius's avatar
Jan Möbius committed
286
  /// restores original Light Sources
287
  void leave(GLState& _state, const DrawModes::DrawMode& _drawmode);
288

289
  /// Draw light source node
290
  void draw(GLState& _state, const DrawModes::DrawMode& _drawMode);
291

292 293
  /// Picking
  void pick(GLState& _state, PickTarget _target);
Jan Möbius's avatar
Jan Möbius committed
294

295 296
  /// Should node be visualized?
  bool visualize() { return visualize_; }
297

298 299
  /// Set whether node should be visualized
  void visualize(bool _visualize) { visualize_ = _visualize; }
Jan Möbius's avatar
Jan Möbius committed
300

Jan Möbius's avatar
Jan Möbius committed
301 302 303 304 305

  /// Add this light to shader render interface
  void getRenderObjects(IRenderer* _renderer, GLState&  _state , const DrawModes::DrawMode&  _drawMode , const Material* _mat);


Jan Möbius's avatar
Jan Möbius committed
306 307 308 309 310 311 312 313 314 315 316 317 318
private:

  /// set _light Options in OpenGL for GL_LIGHT#_index
  void setParameters(GLenum _index, LightSource& _light);

  /// get _light Options in OpenGL for GL_LIGHT#_index
  void getParameters(GLenum _index, LightSource& _light);

private:

  /// store LightSources of this node
  LightSource light_;

319 320 321
  /// pretransformed light position and direction in view space
  LightSource transformedLight_;

Jan Möbius's avatar
Jan Möbius committed
322 323
  /// save old LightSources
  LightSource lightSave_;
324

325 326
  /// Indicates whether light node should be visualized or not
  bool visualize_;
327

328 329
  /// Internal light id
  GLenum lightId_;
330 331 332

  ACG::GLCone* cone_;
  ACG::GLSphere* sphere_;
Jan Möbius's avatar
Jan Möbius committed
333 334
};

335 336 337 338 339 340
/**
* \class LightSourceHandle
*
* Assign a unique OpenGL light source identifier to each of the
* light source nodes in the scene. These relations are
* stored in a map. If there is no free light source left,
341
* return GL_INVALID_ENUM as light source enumerant.
342 343
*/
class DLLEXPORT LightSourceHandle {
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
  public:
    LightSourceHandle() {
      GLint maxLights;

      // Get max number of lights
      if (OpenFlipper::Options::gui())
        glGetIntegerv(GL_MAX_LIGHTS, &maxLights);
      else
        maxLights = 50;

      for(int i = 0; i < maxLights; ++i) {
        lights_.insert(std::pair<GLenum, LightNode*>(GL_LIGHT0 + i, (LightNode*)0 ));
      }
    };

    GLenum getLight(LightNode* _node) {
      GLenum light = GL_INVALID_ENUM;
      for(std::map<GLenum, LightNode*>::iterator it = lights_.begin();
          it != lights_.end(); ++it) {

        if(it->second == 0) {
          lights_[it->first] = _node;
          light = it->first;
          break;
        }
      }
      return light;
    };

    void removeLight(LightNode* _node) {
      for(std::map<GLenum, LightNode*>::iterator it = lights_.begin();
          it != lights_.end(); ++it) {

        if(it->second == _node) {
          lights_[it->first] = 0;
          break;
        }
      }
    };

  private:
    std::map<GLenum, LightNode*> lights_;
386
};
Jan Möbius's avatar
Jan Möbius committed
387 388 389 390 391 392 393

//=============================================================================
} // namespace SceneGraph
} // namespace ACG
//=============================================================================
#endif // ACG_LIGHT_NODE_HH defined
//=============================================================================