57 #include "LightNode.hh" 58 #include <ACG/GL/IRenderer.hh> 61 #define M_PI 3.14159265358979323846 71 static LightSourceHandle* lightSourceHandle = 0;
78 fixedPosition_ =
false;
80 ambientColor_ =
Vec4f(0.1f,0.1f,0.1f,1.f);
81 diffuseColor_ =
Vec4f(1.f,1.f,1.f,1.f);
82 specularColor_ =
Vec4f(1.f,1.f,1.f,1.f);
84 position_ =
Vec4f(0.f,0.f,1.f,0.f);
85 realPosition_ =
Vec4f(0.f,0.f,1.f,0.f);
87 spotDirection_ =
Vec3d(0.0,0.0,-1.0);
88 realSpotDirection_ =
Vec3d(0.0,0.0,-1.0);
92 initialPosition_ =
Vec4f(0.f, 0.f, 0.f, 0.f);
93 initialSpotDirection_ =
Vec3d(0.0, 0.0, -1.0);
94 initialPositionInit_ =
false;
99 constantAttenuation_ = 1;
100 linearAttenuation_ = 0;
101 quadraticAttenuation_ = 0;
110 position_ =
Vec4d( _pos[0],_pos[1],_pos[2],1.0);
114 return Vec3d( position_[0], position_[1], position_[2]);
120 position_ =
Vec4d( _pos[0],_pos[1],_pos[2],0.0);
124 return Vec3d(position_[0], position_[1], position_[2]);
128 return ( position_[3] == 0.0 );
135 { enabled_ =
false; }
142 { spotDirection_ = _pos; }
145 return Vec3d(spotDirection_[0],spotDirection_[1],spotDirection_[2]);
149 { ambientColor_ = _color; }
152 {
return ambientColor_; }
155 { diffuseColor_ = _color; }
158 {
return diffuseColor_; }
161 { specularColor_ = _color; }
164 {
return specularColor_; }
166 void LightSource::setColor(
const Vec4f& _ambient,
const Vec4f& _diffuse,
const Vec4f& _specular) {
167 ambientColor_ = _ambient;
168 diffuseColor_ = _diffuse;
169 specularColor_ = _specular;
172 void LightSource::fixedPosition(
bool _state)
173 { fixedPosition_ = _state; }
175 bool LightSource::fixedPosition()
const {
176 return fixedPosition_;
179 void LightSource::spotExponent(
float _exponent) {
180 spotExponent_ = _exponent;
183 float LightSource::spotExponent()
const {
184 return spotExponent_;
187 void LightSource::spotCutoff(
float _cutoff) {
188 spotCutoff_ = _cutoff;
191 float LightSource::spotCutoff()
const {
195 void LightSource::constantAttenuation(
float _constantAttenuation) {
196 constantAttenuation_ = _constantAttenuation;
199 float LightSource::constantAttenuation()
const {
200 return constantAttenuation_;
203 void LightSource::linearAttenuation(
float _linearAttenuation) {
204 linearAttenuation_ = _linearAttenuation;
207 float LightSource::linearAttenuation()
const {
208 return linearAttenuation_;
211 void LightSource::quadraticAttenuation(
float _quadraticAttenuation) {
212 quadraticAttenuation_ = _quadraticAttenuation;
215 float LightSource::quadraticAttenuation()
const {
216 return quadraticAttenuation_;
219 void LightSource::brightness(
float _brightness) {
220 brightness_ = _brightness;
223 float LightSource::brightness()
const {
228 const std::string& _name)
231 lightId_(GL_INVALID_ENUM) {
233 if(lightSourceHandle == 0) {
238 cone_ =
new ACG::GLCone(10, 10, 1.0f, 1.0f,
false,
true);
273 (double)
light_.realPosition_[1],
274 (
double)
light_.realPosition_[2]);
291 if(
light_.fixedPosition_ && !
light_.initialPositionInit_) {
294 light_.initialPositionInit_ =
true;
297 if(
light_.fixedPosition_) {
316 for(
int i = 0; i < 3; ++i) {
317 if(ac[i] > max) max = ac[i];
321 for(
int i = 0; i < 3; ++i) {
322 if(dc[i] > max) max = dc[i];
326 for(
int i = 0; i < 3; ++i) {
327 if(sc[i] > max) max = sc[i];
332 GLboolean lighting_backup;
340 glGetBooleanv(GL_LIGHTING, &lighting_backup);
349 lightId_ = lightSourceHandle->getLight(
this);
362 glLightf(
lightId_, GL_SPOT_EXPONENT, 0.0f);
364 pos [0] = backup_position[0];
365 pos [1] = backup_position[1];
366 pos [2] = backup_position[2];
369 glLightfv(
lightId_, GL_POSITION, pos);
372 float gl_ac[] = {ac[0], ac[1], ac[2], ac[3]};
373 glLightfv(
lightId_, GL_AMBIENT, gl_ac);
374 float gl_dc[] = {dc[0], dc[1], dc[2], dc[3]};
375 glLightfv(
lightId_, GL_DIFFUSE, gl_dc);
376 float gl_sc[] = {sc[0], sc[1], sc[2], sc[3]};
377 glLightfv(
lightId_, GL_SPECULAR, gl_sc);
384 if(
light_.spotCutoff() < 180.0f) {
391 float angle = acos((z | spot)/(z.
norm()*spot.
norm()));
392 angle = angle*360/(2*M_PI);
394 _state.
rotate(angle, rA[0], rA[1], rA[2]);
397 cone_->setNormalOrientation(ACG::GLPrimitive::INSIDE);
404 cone_->setTopRadius(0.0f);
409 lightSourceHandle->removeLight(
this);
413 if(!backup_directional) {
437 if(
light_.fixedPosition_ && !
light_.initialPositionInit_) {
440 light_.initialPositionInit_ =
true;
443 if(
light_.fixedPosition_) {
452 glPushAttrib(GL_DEPTH_BUFFER_BIT);
472 if(
light_.spotCutoff() < 180.0f) {
479 float angle = acos((z | spot)/(z.
norm()*spot.
norm()));
480 angle = angle*360/(2*M_PI);
482 _state.
rotate(angle, rA[0], rA[1], rA[2]);
484 cone_->setNormalOrientation(ACG::GLPrimitive::OUTSIDE);
491 cone_->setTopRadius(0.0f);
508 if(
light_.fixedPosition_ && !
light_.initialPositionInit_) {
511 light_.initialPositionInit_ =
true;
515 lightId_ = lightSourceHandle->getLight(
this);
518 if(
lightId_ == GL_INVALID_ENUM)
return;
523 if(_state.compatibilityProfile())
531 if(
light_.fixedPosition_) {
546 if (_state.compatibilityProfile()) {
551 if (_state.compatibilityProfile())
565 if(
lightId_ == GL_INVALID_ENUM)
return;
567 if (_state.compatibilityProfile()) {
579 lightSourceHandle->removeLight(
this);
586 if (_state.compatibilityProfile()) {
589 Vec4f& a = _light.ambientColor_;
590 GLfloat ambient[4] = { a[0] * _light.brightness_,
591 a[1] * _light.brightness_,
592 a[2] * _light.brightness_,
593 a[3] * _light.brightness_ };
595 Vec4f& d = _light.diffuseColor_;
596 GLfloat diffuse[4] = { d[0] * _light.brightness_,
597 d[1] * _light.brightness_,
598 d[2] * _light.brightness_,
599 d[3] * _light.brightness_ };
601 Vec4f& s = _light.specularColor_;
602 GLfloat specular[4] = { s[0] * _light.brightness_,
603 s[1] * _light.brightness_,
604 s[2] * _light.brightness_,
605 s[3] * _light.brightness_ };
607 Vec3d& sd = _light.realSpotDirection_;
611 Vec4f& p = _light.realPosition_;
612 GLfloat realPos[4] = { (float)p[0], (
float)p[1], (float)p[2], (directional ? 0.0f : 1.0f) };
615 glLightfv(_index, GL_AMBIENT, ambient);
616 glLightfv(_index, GL_DIFFUSE, diffuse);
617 glLightfv(_index, GL_SPECULAR, specular);
619 glLightfv(_index, GL_POSITION, realPos);
622 GLfloat dir[3] = { (float)sd[0], (
float)sd[1], (float)sd[2] };
623 glLightfv(_index, GL_SPOT_DIRECTION, dir);
626 if (!directional) glLightf(_index, GL_SPOT_EXPONENT, _light.spotExponent_);
627 if (!directional) glLightf(_index, GL_SPOT_CUTOFF, _light.spotCutoff_);
629 glLightf(_index, GL_CONSTANT_ATTENUATION, _light.constantAttenuation_);
630 glLightf(_index, GL_LINEAR_ATTENUATION, _light.linearAttenuation_);
631 glLightf(_index, GL_QUADRATIC_ATTENUATION, _light.quadraticAttenuation_);
639 if (_state.compatibilityProfile()) {
641 glGetLightfv(_index, GL_AMBIENT, (GLfloat *)_light.ambientColor_.
data());
642 glGetLightfv(_index, GL_DIFFUSE, (GLfloat *)_light.diffuseColor_.
data());
643 glGetLightfv(_index, GL_SPECULAR, (GLfloat *)_light.specularColor_.
data());
644 glGetLightfv(_index, GL_POSITION, (GLfloat *)_light.position_.
data());
645 glGetLightfv(_index, GL_SPOT_DIRECTION, (GLfloat *)_light.spotDirection_.
data());
647 glGetLightfv(_index, GL_SPOT_EXPONENT, &_light.spotExponent_);
648 glGetLightfv(_index, GL_SPOT_CUTOFF, &_light.spotCutoff_);
649 glGetLightfv(_index, GL_CONSTANT_ATTENUATION, &_light.constantAttenuation_);
650 glGetLightfv(_index, GL_LINEAR_ATTENUATION, &_light.linearAttenuation_);
651 glGetLightfv(_index, GL_QUADRATIC_ATTENUATION, &_light.quadraticAttenuation_);
663 light.ltype = ACG::SG_LIGHT_DIRECTIONAL;
665 light.ltype = ACG::SG_LIGHT_POINT;
667 light.ltype = ACG::SG_LIGHT_SPOT;
669 #define V4toV3(v) (
ACG::Vec3f(v[0], v[1], v[2]))
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
void position(Vec3d _pos)
Set position for LightSource.
LightSource lightSave_
save old LightSources
void specularColor(Vec4f _color)
set Specular color for LightSource
void disable()
disable LightSource
void pop_modelview_matrix()
pop modelview matrix
bool enabled() const
Get light source status.
LightSource transformedLight_
pretransformed light position and direction in view space
void getLightSource(LightSource *_light) const
Get the light source parameters.
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode) override
Draw light source node.
picks faces (should be implemented for all nodes)
LightSource()
Default Constructor.
Namespace providing different geometric functions concerning angles.
virtual ~LightNode()
Destructor.
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const Material *_mat) override
Add this light to shader render interface.
VectorT< float, 4 > Vec4f
Vec4f specularColor() const
get Specular color for LightSource
virtual void addLight(const LightData &_light)
Callback for the scenegraph nodes, which send new lights to the renderer via this function...
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
void ambientColor(Vec4f _color)
set Ambient color for LightSource
Vec4f ambientColor() const
get Ambient color for LightSource
Scalar * data()
access to Scalar array
void leave(GLState &_state, const DrawModes::DrawMode &_drawmode) override
restores original Light Sources
float radius() const
Get light source radius.
void pick(GLState &_state, PickTarget _target) override
Picking.
PickTarget
What target to use for picking.
void push_modelview_matrix()
push modelview matrix
void diffuseColor(Vec4f _color)
set Diffuse color for LightSource
const GLMatrixd & inverse_modelview() const
get inverse modelview matrix
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
VectorT< float, 3 > Vec3f
Structure to hold options for one LightSource.
Vec3d position() const
Get the position of the LightSource.
pick any of the prior targets (should be implemented for all nodes)
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
GLenum lightId_
Internal light id.
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x',y',z',0) = A * (x,y,z,0)
void getParameters(GLState &_state, GLenum _index, LightSource &_light)
get _light Options in OpenGL for GL_LIGHT::_index
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM >>().sqrnorm()))
compute euclidean norm
Vec4f diffuseColor() const
get Diffuse color for LightSource
Vec3d spotDirection() const
get spot direction
void enable()
enable LightSource
void boundingBox(ACG::Vec3d &, ACG::Vec3d &) override
Get bounding box (for visualization purposes)
void enter(GLState &_state, const DrawModes::DrawMode &_drawmode) override
set current Light Sources
void rotate(double _angle, double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
rotate around axis (_x, _y, _z) by _angle
Vec3d direction() const
Get direction of the light source.
bool visualize_
Indicates whether light node should be visualized or not.
LightNode(BaseNode *_parent=0, const std::string &_name="<LightNode>")
Default constructor. Applies all properties.
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
void fixedPosition(bool _state)
make LightSource fixed or moveable with ModelViewMatrix
const GLMatrixd & modelview() const
get modelview matrix
bool directional() const
Check if the light source is a directional light source.
void spotDirection(Vec3d _pos)
Set spot direction.
LightSource light_
store LightSources of this node
void setParameters(GLState &_state, GLenum _index, LightSource &_light)
set _light Options in OpenGL for GL_LIGHT::_index
VectorT< double, 4 > Vec4d
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
void getLightSourceViewSpace(LightSource *_light) const
VectorT< double, 3 > Vec3d