/* (c) 1999-2000 Tino Schwarze, see COPYING for details */
/**@pkg cObject.cVisibleObject.cInteractiveObject.cLight*/
/**
* a class for managing an OpenGL light
*
* #include "cLight.hh"
*
* -lMesaGL or -lGL
*
* This is the base class for lights and represents a point light.
* GL_x_ATTENUATION is not (yet) supported. (It's not terribly useful
* anyway.)
*
* @see cInteractiveObject
* @pkgdoc cObject.cVisibleObject.cInteractiveObject.cLight
*/
#ifndef cLight_hh
#define cLight_hh
// include class cVisibleObject to derive from
#include "cInteractiveObject.hh"
// include class cColor representing an RGB(A) color for use
// with OpenGL
#include "cADSEColor.hh"
// include common project macros, definitions and headers
#include "common.hh"
// I don't want to include glu.h here; we just need a type.
typedef struct GLUquadricObj GLUquadricObj;
/**
* A class for managing OpenGL lights.
*
* Lights are very special since there might be only a limited amount
* of them active at once. We need to check that before turning a
* light on (that's what the static variables are for).
*
* It's a special object since it does not draw itself, but only
* is glEnabled() during SetUpForDrawing and glDisabled() during
* CleanUpAfterDrawing() (of course, the light needs to be turned on).
*
* It might (and actually is) derived from this class, e.g. for
* providing a directional and a spot light.
*
* Note that cLights are treatened like all other cObjects as far as they
* might have siblings and take part in the normal scene hierarchy.
*
* The inherited mRotation quaternion is not used.
*/
class cLight
: public cInteractiveObject
{
public:
/**
* an extra type for the light status
*/
typedef enum eLightState {
LIGHT_OFF,
LIGHT_ON
} teLightState;
/**
* default constructor
*/
cLight (
cEventDispatcher *disp,
const char *name = NULL);
#if DEBUG
/**
* copy constructor (inherited)
*/
cLight (const cLight &);
#endif
/**
* constructor with initialization of position and name
* @param pos initial position of light source
* @param state initial state of light source (default: on)
* @param name name of light source (optional)
*/
cLight (
cEventDispatcher *disp,
const cVertex &pos,
const char *name = NULL);
/**
* constructor with initialization of position, state and name
* @param pos initial position of light source
* @param state initial state of light source (default: on)
* @param name name of light source (optional)
*/
cLight (
cEventDispatcher *disp,
const cVertex &pos,
const teLightState state = LIGHT_ON,
const char *name = NULL);
/**
* constructor with initialization of position, color, state
* and name
* @param pos initial position of light source
* @param col color of the light source (cADSEColor object)
* (emissive color component is not used)
* @param state initial state of light source (default: on)
* @param name name of light source (optional)
*/
cLight (
cEventDispatcher *disp,
const cVertex &pos,
const cADSEColor &col,
const teLightState state = LIGHT_ON,
const char *name = NULL);
/**
* destructor
*/
virtual ~cLight ();
// OPERATIONS
// note: translating the light is obtained via functions inherited from
// cVisibleObject (@see cVisibleObject::MoveBy, cVisibleObject::MoveTo)
// ACCESS
/**
* enable the light
* @param state teLightState - LIGHT_ON or LIGHT_OFF
*/
void SetState (teLightState state);
/**
* query light status
* @return bool stating whether the light is on or off
*/
bool IsOn () const;
/**
* set ambient color
* @param c new ambient color of light
*/
virtual void SetAmbientColor (const cColor &c);
/**
* set diffuse color
* @param c new diffuse color of light
*/
virtual void SetDiffuseColor (const cColor &c);
/**
* set specular color
* @param c new specular color of light
*/
virtual void SetSpecularColor (const cColor &c);
/**
* event receiver - we listen for switchon/switchoff events
*
* @return 0 - event accepted, -1 - event not
* accepted
*/
virtual int ReceiveEvent (const cEvent &event);
/**
* overload cVisibleObject::MoveTo since we want to ignore
* mRotation while moving (it's used to determine direction only)
*/
virtual void MoveTo (const cVertex &v);
/**
* overload cVisibleObject::MoveBy since we want to ignore
* mRotation while moving (it's used to determine direction only)
*/
virtual void MoveBy (const cVertex &v);
protected:
/**
* set up for drawing (overloaded from cVisibleObject)
*
* Lights should follow the following behaviour:
* 1. If you change a standard parameter for a light,
* undo it in Deactivate()
* 2. Position and {Ambient,Diffuse,Specular}Color do not
* count for 1.
*/
virtual void Activate ();
/**
* this one performs the actual set up of the light
*
* (called by Activate()); separeted to simplify
* cDirectionLight
*/
virtual void ActivateLight ();
/**
* suppress transformation
*/
virtual void Transform ();
/**
* A light is a visible object therefore it needs a drawing function
*
* It is used when the light is shown.
*/
virtual void DrawThisObject ();
/**
* clean up after drawing (overloaded from cVisibleObject)
*/
virtual void Deactivate ();
/**
* perform steps neccessary before freeing the light slot
* (e.g. disabling the light)
*/
virtual void DeactivateLight ();
/**
* aquire a light slot (stored in mLightSlot)
* @return -1 on error (no free slot), 0 on success
*/
virtual int AllocateLightSlot ();
/**
* free the light slot
* @return -1 on error (slot was not allocated), 0 on success
*/
virtual int FreeLightSlot ();
/**
* we want to get switchon/switchoff events if we're selected
*/
virtual void SubscribeToActiveEvents ();
/**
* unsubscribe from switchon/switchoff if we get deselected
*/
virtual void UnsubscribeFromActiveEvents ();
/**
* identify an instance of this class if it's got no name
*/
virtual const char *GetDefaultName () const
{
return "cLight";
}
/**
* current status of light (LIGHT_ON or LIGHT_OFF)
*/
teLightState mState;
/**
* ambient color component of light
*/
cADSEColor mLightColor;
/**
* keep track of status of OpenGL lights
*
* As OpenGL allows 8 lights at once, we need to keep track
* of which lights are currently in use and which are not.
*
* At runtime, to enable a light, we look for a free "slot"
* and use it for our light source.
*/
static teLightState mgLightSlots[8];
/**
* keep track of how many lights are currently active
*/
static int mgActiveLights;
/**
* actually used light slot (-1 = no slot used)
*/
int mLightSlot;
/**
* only used if the light source is to be drawn
*/
GLUquadricObj *mQuadric;
};
#endif // ifndef cLight_hh
|