// OGL_LIGHTS.H : the OpenGL light classes.

// Copyright (C) 1998 Tommi Hassinen.

// This package is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.

// This package is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this package; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

/*################################################################################################*/

//#include "config.h"

#ifndef OGL_LIGHTS_H
#define OGL_LIGHTS_H

/*################################################################################################*/

class ogl_light;
class ogl_spot_light;
class ogl_directional_light;

#include "ogl_objects.h"
#include "base_wnd.h"

/*################################################################################################*/

struct ogl_light_components
{
	GLfloat * amb_comp;
	GLfloat * diff_comp;
	GLfloat * spec_comp;
};

/**	The "##light" class is a base class for OpenGL lights. All lights must be 
	dummy_objects, because they are connected to a camera rather than to a set of 
	windows. That's because cameras will drag their local lights along when they 
	are rotated/translated...
	
	Also there is no need for lights to respond to any connectivity/geometry changes.
*/

class ogl_light :
	public ogl_light_components,
	public ogl_dummy_object
{
	public:
	
/**	This should be either NULL (for a global light) or some valid camera of 
	the model (for a local light). Only model::Add???Light()-functions are allowed 
	to make modifications to "##owner" !!!
*/
	ogl_camera * owner;
	
/**	This is the OpenGL light number GL_LIGHTi for this light. The actual values 
	are determined in the model when adding/removing local/global lights...
*/
	GLint number;
	
	static const GLfloat def_amb_comp[4];
	static const GLfloat def_diff_comp[4];
	static const GLfloat def_spec_comp[4];
	
	static const ogl_light_components def_components;
	
	public:
	
	ogl_light(const ogl_object_location &, const ogl_light_components &);
	virtual ~ogl_light(void);
	
/**	This is used to set up those light properties that are independent on 
	location/orientation -> should be called for every window when it's created 
	and always when the light numbering is changed.
*/
	virtual void SetupProperties(void) = 0;
	
/**	This should be called for all active lights always when rendering them, 
	after the modelview-matrix is ready but before any actual rendering commands.
*/
	virtual void SetupLocation(void) = 0;
	
	bool BeginTransformation(void) { return false; }	// virtual
	bool EndTransformation(void) { return false; }		// virtual
	
	private:
	
	void InitComponents(const ogl_light_components *);
};

/*################################################################################################*/

/**	The OpenGL spotlight (a light source at finite distance, like a flashlight or a candle). 
	It has the standard cutoff/exponent-properties, and will be rendered as a sphere/cone...
*/

class ogl_spot_light :
	public ogl_light
{
	public:
	
	GLfloat cutoff;
	GLfloat exponent;
	
	static GLfloat size;
	
	static GLfloat shade1[3];
	static GLfloat shade2[3];
	
	static GLfloat bulb_on[3];
	static GLfloat bulb_off[3];
	
	static const GLfloat def_cutoff;
	static const GLfloat def_exponent;
	
	public:
	
	ogl_spot_light(const ogl_object_location &, const ogl_light_components & = ogl_light::def_components, GLfloat = ogl_spot_light::def_cutoff, GLfloat = ogl_spot_light::def_exponent);
	virtual ~ogl_spot_light(void);
	
	const char * GetObjectName(void) { return "light (spotlight)"; }	// virtual
	
	void SetupProperties(void);		// virtual
	void SetupLocation(void);		// virtual
	
	void Render(void) { }		// virtual
};

/*################################################################################################*/

/**	The OpenGL directional light (a light source at infinite distance, like the sunlight). 
	No rendering for this one...
*/

class ogl_directional_light :
	public ogl_light
{
	protected:
	
	public:
	
	ogl_directional_light(const ogl_object_location &, const ogl_light_components & = ogl_light::def_components);
	virtual ~ogl_directional_light(void);
	
	const char * GetObjectName(void) { return "light (directional)"; }	// virtual
	
	void SetupProperties(void);		// virtual
	void SetupLocation(void);		// virtual
	
	void Render(void) { }		// virtual
};

/*################################################################################################*/

#endif	// OGL_LIGHTS_H

// eof
