X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Flight.cpp;h=39693c4091a6b1579885bf79104ef60e38ca0426;hp=1570c5cd0c790840b1232dce96c6631dbbdefbf7;hb=f14435e58bfa0fa697a06ba9a454bb30cd37d9d8;hpb=832fb1872e6e5e664e2e5130122fd2f74729ed42 diff --git a/source/light.cpp b/source/light.cpp index 1570c5cd..39693c40 100644 --- a/source/light.cpp +++ b/source/light.cpp @@ -1,11 +1,8 @@ -/* $Id$ - -This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - +#include "except.h" #include "light.h" +#include "misc.h" + +using namespace std; namespace Msp { namespace GL { @@ -14,50 +11,114 @@ Light::Light(): ambient(0), diffuse(1), specular(1), - x(0), y(0), z(1), w(0), - sdx(0), sdy(0), sdz(-1), + position(0, 0, 1, 0), + spot_dir(0, 0, -1), spot_exp(0), spot_cutoff(180) -{ } +{ + attenuation[0] = 1; + attenuation[1] = 0; + attenuation[2] = 0; +} void Light::set_ambient(const Color &c) { - ambient=c; + ambient = c; } void Light::set_diffuse(const Color &c) { - diffuse=c; + diffuse = c; } void Light::set_specular(const Color &c) { - specular=c; + specular = c; +} + +void Light::set_position(const Vector4 &p) +{ + position = p; } -void Light::set_position(float x_, float y_, float z_, float w_) +void Light::set_spot_direction(const Vector3 &d) { - x=x_; - y=y_; - z=z_; - w=w_; + spot_dir = d; +} + +void Light::set_spot_exponent(float e) +{ + spot_exp = e; +} + +void Light::set_spot_cutoff(float c) +{ + spot_cutoff = c; +} + +void Light::set_attenuation(float c, float l, float q) +{ + attenuation[0] = c; + attenuation[1] = l; + attenuation[2] = q; +} + +void Light::bind() const +{ + if(current_lights[current_unit]!=this) + { + GLenum l = GL_LIGHT0+current_unit; + enable(l); + glLightfv(l, GL_AMBIENT, &ambient.r); + glLightfv(l, GL_DIFFUSE, &diffuse.r); + glLightfv(l, GL_SPECULAR, &specular.r); + glLightfv(l, GL_POSITION, &position.x); + glLightfv(l, GL_SPOT_DIRECTION, &spot_dir.x); + glLightf(l, GL_SPOT_EXPONENT, spot_exp); + glLightf(l, GL_SPOT_CUTOFF, spot_cutoff); + glLightf(l, GL_CONSTANT_ATTENUATION, attenuation[0]); + glLightf(l, GL_LINEAR_ATTENUATION, attenuation[1]); + glLightf(l, GL_QUADRATIC_ATTENUATION, attenuation[2]); + current_lights[current_unit] = this; + } +} + +void Light::bind_to(unsigned i) const +{ + activate(i); + bind(); +} + +void Light::activate(unsigned i) +{ + static unsigned max_lights = get_i(GL_MAX_LIGHTS); + + if(i>=max_lights) + throw InvalidParameterValue("Light unit index out of range"); + + if(i>=current_lights.size()) + current_lights.resize(i+1); + + current_unit = i; } -void Light::apply() +void Light::unbind() { - apply_to(current); + if(current_lights[current_unit]) + { + disable(GL_LIGHT0+current_unit); + current_lights[current_unit] = 0; + } } -void Light::apply_to(unsigned l) +void Light::unbind_from(unsigned i) { - l+=GL_LIGHT0; - glLightfv(l, GL_AMBIENT, &ambient.r); - glLightfv(l, GL_DIFFUSE, &diffuse.r); - glLightfv(l, GL_SPECULAR, &specular.r); - glLightfv(l, GL_POSITION, &x); + activate(i); + unbind(); } -unsigned Light::current=0; +unsigned Light::current_unit = 0; +vector Light::current_lights(1); } // namespace GL } // namespace Msp