#ifndef illumination_h #define illumination_h #include <jgl/defines.h> #include <jgl/colour.h> #include "light.h" #include "flags.h" #include "shadowfeeler.h" class rtl_light; class rtl_ray; class rtl_illumination { public: rtl_illumination(); ~rtl_illumination(); virtual jColour illuminate( rtl_ray&, const jVec3& ); virtual void prerender(); virtual void postrender(); void add( rtl_light* ); void clearlights(); const rtl_flags& flags() const { return f; } rtl_flags& flags() { return f; } static const jULng Shadows; static const jULng Recursion; static rtl_illumination Default; protected: virtual jColour diffuse( rtl_object*, rtl_material* m, jFlt NdL ) { return m->diffuse()*NdL*m->kD(); } virtual jColour specular( rtl_object*, rtl_material* m, jFlt RdV ) { return m->specular()*pow(RdV,m->n())*m->kS(); } virtual jColour ambient( rtl_object*, rtl_material* m ) { return m->diffuse()*m->kA(); } virtual jFlt shadow( rtl_shadowfeeler* ); struct l_node { l_node( rtl_light*_light, l_node*_next ) : light(_light),next(_next) {} ~l_node() { if(next) delete next; } l_node* next; rtl_light * light; } * lights; rtl_flags f; friend class rtl_world; public: class lightiter { public: lightiter( rtl_illumination* I ) : l(I->lights) {} void operator ++ () { l = l->next; } operator bool () { return l!=0; } rtl_light* light() { return l->light; } private: rtl_illumination::l_node* l; }; friend class rtl_illumination::lightiter; }; #endif