From efe80f5a696b4a3be2378dc6d635c89676afa12d Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 28 Sep 2008 15:40:26 +0000 Subject: [PATCH] Convert Light to object model Add class Lighting to encapsulate lighting state as a whole --- source/light.cpp | 51 +++++++++++++++++++++++++------- source/light.h | 9 ++++-- source/lighting.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++ source/lighting.h | 52 +++++++++++++++++++++++++++++++++ source/misc.cpp | 12 ++++++++ source/misc.h | 3 ++ 6 files changed, 185 insertions(+), 13 deletions(-) create mode 100644 source/lighting.cpp create mode 100644 source/lighting.h diff --git a/source/light.cpp b/source/light.cpp index 5b0fa1d7..899e22c9 100644 --- a/source/light.cpp +++ b/source/light.cpp @@ -5,9 +5,12 @@ 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 { @@ -44,22 +47,50 @@ void Light::set_position(float x_, float y_, float z_, float w_) w=w_; } -void Light::apply() const +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, &x); + current_lights[current_unit]=this; + } +} + +void Light::bind_to(unsigned i) const +{ + activate(i); + bind(); +} + +void Light::activate(unsigned i) { - apply_to(current); + 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_to(unsigned l) const +void Light::unbind() { - l+=GL_LIGHT0; - enable(l); - glLightfv(l, GL_AMBIENT, &ambient.r); - glLightfv(l, GL_DIFFUSE, &diffuse.r); - glLightfv(l, GL_SPECULAR, &specular.r); - glLightfv(l, GL_POSITION, &x); + if(current_lights[current_unit]) + { + disable(GL_LIGHT0+current_unit); + current_lights[current_unit]=0; + } } -unsigned Light::current=0; +unsigned Light::current_unit=0; +vector Light::current_lights(1); } // namespace GL } // namespace Msp diff --git a/source/light.h b/source/light.h index 6a686841..e9b03269 100644 --- a/source/light.h +++ b/source/light.h @@ -8,6 +8,7 @@ Distributed under the LGPL #ifndef MSP_GL_LIGHT_H_ #define MSP_GL_LIGHT_H_ +#include #include "color.h" namespace Msp { @@ -25,7 +26,8 @@ private: float spot_cutoff; float attenuation[3]; - static unsigned current; + static unsigned current_unit; + static std::vector current_lights; public: Light(); @@ -33,10 +35,11 @@ public: void set_diffuse(const Color &c); void set_specular(const Color &c); void set_position(float, float, float, float); - void apply() const; - void apply_to(unsigned) const; + void bind() const; + void bind_to(unsigned) const; static void activate(unsigned); + static void unbind(); }; } // namespace GL diff --git a/source/lighting.cpp b/source/lighting.cpp new file mode 100644 index 00000000..6b6af57c --- /dev/null +++ b/source/lighting.cpp @@ -0,0 +1,71 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2008 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include "light.h" +#include "lighting.h" +#include "misc.h" + +namespace Msp { +namespace GL { + +Lighting::Lighting(): + ambient(0.2) +{ } + +void Lighting::set_ambient(const Color &a) +{ + ambient=a; +} + +void Lighting::attach(unsigned i, const Light &l) +{ + if(i>=lights.size()) + lights.resize(i+1); + + lights[i]=&l; +} + +void Lighting::detach(unsigned i) +{ + if(i>=lights.size()) + return; + + lights[i]=0; +} + +void Lighting::bind() const +{ + if(current!=this) + { + enable(LIGHTING); + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, &ambient.r); + for(unsigned i=0; ibind_to(i); + current=this; + } +} + +void Lighting::unbind() +{ + if(current) + { + for(unsigned i=0; ilights.size(); ++i) + if(current->lights[i]) + { + Light::activate(i); + Light::unbind(); + } + disable(LIGHTING); + current=0; + } +} + +const Lighting *Lighting::current=0; + +} // namespace GL +} // namespace Msp diff --git a/source/lighting.h b/source/lighting.h new file mode 100644 index 00000000..85d5fb04 --- /dev/null +++ b/source/lighting.h @@ -0,0 +1,52 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2008 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GL_LIGHTING_H_ +#define MSP_GL_LIGHTING_H_ + +#include +#include "color.h" +#include "gl.h" + +namespace Msp { +namespace GL { + +class Light; + +enum +{ + LIGHTING = GL_LIGHTING +}; + +/** +Encapsulates global lighting parameters and a number of individual lights. +*/ +class Lighting +{ +private: + Color ambient; + std::vector lights; + + static const Lighting *current; + +public: + Lighting(); + + void set_ambient(const Color &); + const Color &get_ambient() const { return ambient; } + + void attach(unsigned, const Light &); + void detach(unsigned); + void bind() const; + + static void unbind(); +}; + +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/misc.cpp b/source/misc.cpp index 9815383a..70b300a6 100644 --- a/source/misc.cpp +++ b/source/misc.cpp @@ -28,5 +28,17 @@ void set(GLenum state, bool value) disable(state); } +void get(GLenum state, int &data) +{ + glGetIntegerv(state, &data); +} + +int get_i(GLenum state) +{ + int data; + get(state, data); + return data; +} + } // namespace GL } // namespace Msp diff --git a/source/misc.h b/source/misc.h index 8a956a5a..e9ed91bf 100644 --- a/source/misc.h +++ b/source/misc.h @@ -17,6 +17,9 @@ void enable(GLenum); void disable(GLenum); void set(GLenum, bool); +void get(GLenum, int &); +int get_i(GLenum); + } // namespace GL } // namespace Msp -- 2.45.2