/*
								+---------------------------------+
								|                                 |
								| ***   OpenGL 2.0 textures   *** |
								|                                 |
								|  Copyright  © -tHE SWINe- 2006  |
								|                                 |
								|            Texture.h            |
								|                                 |
								+---------------------------------+
*/

#pragma once
#ifndef __TEXTURE_MANAGER_INCLUDED
#define __TEXTURE_MANAGER_INCLUDED

/**
 *	@file gl2/Texture.h
 *	@date 2006
 *	@author -tHE SWINe-
 *	@brief OpenGL 2.0 textures
 *
 *	@date 2006-01-11
 *
 *	passed code revision
 *
 *	bool CGLTexture::b_State() const renamed to bool CGLTexture::b_Status() const
 *	(want to have unified naming over the whole OpenGL framework)
 *
 *	@date 2007-02-05
 *
 *	passed code revision
 *
 *	"static GLenum CGLTexture_Cube::p_cube_face[6]" is now
 *	"static const GLenum CGLTexture_Cube::p_cube_face[6]"
 *
 *	@date 2007-05-10
 *
 *	added CGLState::NotifyDeleteTexture() to texture destructor to prevent
 *	"unbindable" textures with id of currently bound texture which was destroyed
 *
 *	@date 2007-07-14
 *
 *	added CGLTexture_Rect class (encapsulating GL_ARB_texture_rectangle extension textures)
 *	removed target from texture constructors
 *	changed __inline to inline
 *	added comments to texture constructors
 *	changed order of texture faces in cube-map texture constructor (swapped positive and
 *	negative ones)
 *
 *	@date 2007-10-29
 *
 *	added extension support flags to CGLTextureParams so it doesn't use features that may
 *	not be supported on older hardware. this applies to CGLTextureParams::UpdateState which
 *	is called everytim texture is created as well as both versions of CGLTextureParams::SetState
 *	and all other CGLTextureParams::Set_* functions
 *
 *	note extensions are determined in CGLTextureParams constructors as there could be more
 *	contexts with different capabilities (but the operation is quite fast, on new machines
 *	it should reduce to conversion of gl version string to number and several comparisons)
 *
 *	added texture state caching to all CGLTextureParams::Set_* functions
 *
 *	removed texture target from all CGLTextureParams functions, target is now set via
 *	CGLTextureParams constructor or CGLTextureParams::SetTarget. reason was awkward construct
 *	CTexture::r_Params(CGLState*).Set_*(value, CTexture::n_Target()) which required passing target
 *	as second parameter and was quite error prone because different target could be easily
 *	supplied by mistake
 *
 *	added support for anisotropic filtering to CGLTextureParams
 *
 *	@date 2007-11-09
 *
 *	texture extension checking is conditional when GL_STATE_SINGLE_CONTEXT_ONLY is defined
 *	so texture constructors aren't slowed-down anymore
 *
 *	@date 2007-11-10
 *
 *	improved linux compatibility
 *
 *	@date 2008-08-08
 *
 *	added \#ifdef for windows 64
 *
 *	@date 2009-05-03
 *
 *	added CGLTexture::n_Max_Size() static function
 *
 *	@date 2009-05-04
 *
 *	fixed mixed windows / linux line endings
 *
 *	using glTexParameterf() instead of glTexParameteri() for setting GL_TEXTURE_MAX_ANISOTROPY_EXT
 *
 *	@date 2009-10-20
 *
 *	added assertions to check if internal format and format, passed to glTexImage* corresponds.
 *	for example, if creating texture with internal format GL_DEPTH_COMPONENT16 while format
 *	is GL_RGBA (default), OpenGL error is generated, even if no texture data are supplied.
 *	this will hopefully save some headaches.
 *
 *	fixed some warnings when compiling under VC 2005, implemented "Security
 *	Enhancements in the CRT" for VC 2008. compare against MyProjects_2009-10-19_
 *
 *	@date 2012-06-19
 *
 *	Moved multiple inclusion guard before file documentation comment.
 *
 */

enum {
	coord_S = 0,
	coord_T = 1,
	coord_R = 2
};

/*
 *	class CGLTextureParams
 *		- class for guarding texture parameters
 */
class CGLTextureParams {
protected:
	/*
	 *	CGLTextureParams::<unnamed>
	 *		- texture parameter extensions
	 */
	enum {
		support_EXT_Tex3D = 1,
		support_SGIS_TexLod = 2,
		support_EXT_LodBias = 4,
		support_ARB_DepthTex = 8,
		support_ARB_Shadow = 16,
		support_SGIS_MipMap = 32,
		support_EXT_FilterAniso = 64,
		support_InitFlag = 1 << 31
	};

#ifdef GL_STATE_SINGLE_CONTEXT_ONLY
	static int m_n_support_flags; // support flags so unsupported ops don't cause GL errors
#else // GL_STATE_SINGLE_CONTEXT_ONLY
	int m_n_support_flags; // support flags so unsupported ops don't cause GL errors
#endif // GL_STATE_SINGLE_CONTEXT_ONLY

	GLenum m_n_target;
	GLenum m_n_wrap_mode[3]; // s, t, r
	GLenum m_n_minify_filter;
	GLenum m_n_magnify_filter;
	float m_p_border_color[4];
	float m_f_priority;
	float m_f_min_lod, m_f_max_lod;
	float m_f_lod_bias;
	int m_n_base_level, m_n_max_level;
	GLenum m_n_depth_mode;
	GLenum m_n_compare_mode, m_n_compare_func;
	float m_f_anisotropy;
	bool m_b_generate_mipmap;

	static const float m_f_compare_epsilon/* = 1e-3f*/; // comparison epsilon

public:
	/*
	 *	CGLTextureParams::CGLTextureParams(GLenum n_target = GL_TEXTURE_2D)
	 *		- default constructor
	 *		- fill itself with default texture parameters
	 */
	CGLTextureParams(GLenum n_target = GL_TEXTURE_2D);

	/*
	 *	void CGLTextureParams::SetTarget(GLenum n_target = GL_TEXTURE_2D)
	 *		- sets texture target (default value is GL_TEXTURE_2D)
	 *		  so it doesn't need to be passed to functions below
	 */
	void SetTarget(GLenum n_target = GL_TEXTURE_2D);

	/*
	 *	void CGLTextureParams::UpdateState()
	 *		- get texture parameters from OpenGL
	 *		- note texture must be bound and enabled
	 *		- OpenGL error(s) may be generated, call glGetError() afterwards
	 */
	void UpdateState();

	/*
	 *	void CGLTextureParams::SetState() const
	 *		- set texture parameters to OpenGL
	 *		- note texture must be bound and enabled
	 *		- OpenGL error(s) may be generated, call glGetError() afterwards
	 */
	void SetState() const;

	/*
	 *	void CGLTextureParams::SetState(const CGLTextureParams &r_state) const
	 *		- set texture parameters different from corresponding parameters in r_state to OpenGL
	 *		  (effect is the same as calling r_state.SetState() but equal values aren't set
	 *		  so OpenGL call overhead is lower which should result in better performance)
	 *		- note floating-point number comparison is done with epsilon = 1e-3
	 *		- note texture must be bound and enabled
	 *		- OpenGL error(s) may be generated, call glGetError() afterwards
	 */
	void SetState(const CGLTextureParams &r_state) const;

	/*
	 *	bool CGLTextureParams::operator ==(const CGLTextureParams &r_state) const
	 *		- compare two texture parameters objects, return true if equal, otherwise false
	 *		- does no changes to OpenGL state, needs no particular state nor generates any errors
	 *		- note floating-point number comparison is done with epsilon = 1e-3
	 */
	bool operator ==(const CGLTextureParams &r_state) const;

	inline GLenum n_Texture_Wrap_S() const { return m_n_wrap_mode[coord_S]; }
	inline GLenum n_Texture_Wrap_T() const { return m_n_wrap_mode[coord_T]; }
	inline GLenum n_Texture_Wrap_R() const { return m_n_wrap_mode[coord_R]; }
	inline GLenum n_Texture_Min_Filter() const { return m_n_minify_filter; }
	inline GLenum n_Texture_Mag_Filter() const { return m_n_magnify_filter; }
	inline const float *p_Texture_Border_Color() const { return m_p_border_color; }
	inline float f_Texture_Priority() const { return m_f_priority; }
	inline float f_Texture_Min_LOD() const { return m_f_min_lod; }
	inline float f_Texture_Max_LOD() const { return m_f_max_lod; }
	inline int n_Texture_Base_Level() const { return m_n_base_level; }
	inline int n_Texture_Max_Level() const { return m_n_max_level; }
	inline float f_Texture_LOD_Bias() const { return m_f_lod_bias; }
	inline GLenum n_Depth_Texture_Mode() const { return m_n_depth_mode; }
	inline GLenum n_Texture_Compare_Mode() const { return m_n_compare_mode; }
	inline GLenum n_Texture_Compare_Func() const { return m_n_compare_func; }
	inline bool b_Generate_Mipmap() const { return m_b_generate_mipmap; }
	inline float f_Texture_Anisotropy() const { return m_f_anisotropy; }

	inline GLenum &n_Texture_Wrap_S() { return m_n_wrap_mode[coord_S]; }
	inline GLenum &n_Texture_Wrap_T() { return m_n_wrap_mode[coord_T]; }
	inline GLenum &n_Texture_Wrap_R() { return m_n_wrap_mode[coord_R]; }
	inline GLenum &n_Texture_Min_Filter() { return m_n_minify_filter; }
	inline GLenum &n_Texture_Mag_Filter() { return m_n_magnify_filter; }
	inline float *p_Texture_Border_Color() { return m_p_border_color; }
	inline float &f_Texture_Priority() { return m_f_priority; }
	inline float &f_Texture_Min_LOD() { return m_f_min_lod; }
	inline float &f_Texture_Max_LOD() { return m_f_max_lod; }
	inline int &n_Texture_Base_Level() { return m_n_base_level; }
	inline int &n_Texture_Max_Level() { return m_n_max_level; }
	inline float &f_Texture_LOD_Bias() { return m_f_lod_bias; }
	inline GLenum &n_Depth_Texture_Mode() { return m_n_depth_mode; }
	inline GLenum &n_Texture_Compare_Mode() { return m_n_compare_mode; }
	inline GLenum &n_Texture_Compare_Func() { return m_n_compare_func; }
	inline bool &b_Generate_Mipmap() { return m_b_generate_mipmap; }
	inline float &f_Texture_Anisotropy() { return m_f_anisotropy; }

	void Set_Texture_Wrap_S(GLenum n_wrap_mode);
	void Set_Texture_Wrap_T(GLenum n_wrap_mode);
	void Set_Texture_Wrap_R(GLenum n_wrap_mode);
	void Set_Texture_Min_Filter(GLenum n_minify_filter);
	void Set_Texture_Mag_Filter(GLenum n_magnify_filter);
	void Set_Texture_Border_Color(const float *p_border_color);
	void Set_Texture_Priority(float f_priority);
	void Set_Texture_Min_LOD(float f_min_lod);
	void Set_Texture_Max_LOD(float f_max_lod);
	void Set_Texture_Base_Level(int n_base_level);
	void Set_Texture_Max_Level(int n_max_level);
	void Set_Texture_LOD_Bias(float f_lod_bias);
	void Set_Depth_Texture_Mode(GLenum n_depth_mode);
	void Set_Texture_Compare_Mode(GLenum n_compare_mode);
	void Set_Texture_Compare_Func(GLenum n_compare_func);
	void Set_Generate_Mipmap(bool b_generate_mipmap);
	void Set_Texture_Anisotropy(float f_anisotropy);
};

class CGLTexture {
protected:
	GLuint m_n_id;
	GLenum m_n_internal_format; // GL_RGB8
	GLenum m_n_target; // GL_TEXTURE_2D
	int m_n_border_width;
	CGLTextureParams m_tex_parameters;

public:
	/*
	 *	CGLTexture::CGLTexture()
	 *		- default constructor
	 *		- creates no texture object
	 */
	/*CGLTexture();*/

	/*
	 *	CGLTexture::CGLTexture(GLenum n_internal_format, GLenum n_target, int n_border_width)
	 *		- constructor accepting some of texture properties
	 *		- creates no texture object
	 */
	CGLTexture(GLenum n_internal_format, GLenum n_target, int n_border_width);

	/*
	 *	CGLTexture::~CGLTexture()
	 *		- default destructor
	 *		- deletes OpenGL texture object in case it was created
	 */
	~CGLTexture();

	/*
	 *	bool CGLTexture::b_Status() const
	 *		- returns true in case texture was successfuly created and can be used for texturing
	 */
	bool b_Status() const;

	/*
	 *	void CGLTexture::Bind(CGLState *p_state) const
	 *		- binds texture object to OpenGL state as active texture in current texture unit
	 */
	virtual void Bind(CGLState *p_state) const;

	/*
	 *	void CGLTexture::Bind_Enable(CGLState *p_state) const
	 *		- binds texture object to OpenGL state as active texture in current texture unit
	 *		- enables application of texture target (i.e. GL_TEXTURE_2D or similar)
	 */
	virtual void Bind_Enable(CGLState *p_state) const;

	/*
	 *	void CGLTexture::Disable(CGLState *p_state) const
	 *		- disables application of texture target (i.e. GL_TEXTURE_2D or similar)
	 */
	virtual void Disable(CGLState *p_state) const;

	inline GLenum n_Pixel_Format() const { return m_n_internal_format; }
	inline GLenum n_Target() const { return m_n_target; }
	inline int n_Border_Width() const { return m_n_border_width; }
	inline const CGLTextureParams &t_Parameters() const { return m_tex_parameters; }

	/*
	 *	static int CGLTexture::n_Max_Size()
	 *		- returns maximal texture size
	 *		- note this involves calling glGetIntegerv()
	 */
	static int n_Max_Size();

	/*
	 *	CGLTextureParams &CGLTexture::r_Parameters(CGLState *p_state)
	 *		- enables texture parameters to be changed
	 *		- binds and enables texture first (necessary for OpenGL texture parameter access)
	 */
	virtual CGLTextureParams &r_Parameters(CGLState *p_state);

private:
	friend class CGLFrameBuffer_FBO;

	/*
	 *	inline GLuint n_Id() const
	 *		- for use within CGLTexture_Friend inheritants
	 *		- do not free the texture nor change it's parameters, purpose is
	 *		  to enable access to texture id to functions needing it (such as
	 *		  framebuffer object texture binding, etc)
	 */
	inline GLuint n_Id() const { return m_n_id; }
};

class CGLTexture_1D : public CGLTexture {
protected:
	int m_n_width;

public:
	/*
	 *	CGLTexture_1D::CGLTexture_1D(CGLState *p_state, int n_width, GLenum n_internal_format,
	 *		bool b_create_mipmaps = true, int n_border_width = 0,
	 *		GLenum n_format = GL_RGB, GLenum n_data_type = GL_UNSIGNED_BYTE,
	 *		const void *p_src_data = 0)
	 *		- default constructor
	 *		- p_state is OpenGL state guard
	 *		- creates one-dimensional texture of size n_width and color format n_internal format
	 *		  with border n_border_width pixels wide
	 *		- texture can be initialized with image of color format n_format stored in
	 *		  data type n_data_type in array p_src_data
	 *		- call b_Status() to find out wheter constructor succeeded
	 *		- note this calls glGetError() and so it fails in case there are some
	 *		  uncaught errors despite texture creation is successful
	 */
	CGLTexture_1D(CGLState *p_state, int n_width, GLenum n_internal_format,
		bool b_create_mipmaps = true, int n_border_width = 0,
		GLenum n_format = GL_RGB, GLenum n_data_type = GL_UNSIGNED_BYTE,
		const void *p_src_data = 0);

	inline int n_Width() const { return m_n_width; }

	/*
	 *	void CGLTexture_1D::Bind(CGLState *p_state) const
	 *		- binds texture object to OpenGL state as active texture in current texture unit
	 */
	virtual void Bind(CGLState *p_state) const;

	/*
	 *	void CGLTexture_1D::Bind_Enable(CGLState *p_state) const
	 *		- binds texture object to OpenGL state as active texture in current texture unit
	 *		- enables application of texture target (i.e. GL_TEXTURE_1D or similar)
	 */
	virtual void Bind_Enable(CGLState *p_state) const;

	/*
	 *	void CGLTexture_1D::Disable(CGLState *p_state) const
	 *		- disables application of texture target (i.e. GL_TEXTURE_1D or similar)
	 */
	virtual void Disable(CGLState *p_state) const;

	/*
	 *	CGLTextureParams &CGLTexture_1D::r_Parameters(CGLState *p_state)
	 *		- enables texture parameters to be changed
	 *		- binds and enables texture first (necessary for OpenGL texture parameter access)
	 */
	virtual CGLTextureParams &r_Parameters(CGLState *p_state);
};

class CGLTexture_2D : public CGLTexture {
protected:
	int m_n_width;
	int m_n_height;

public:
	/*
	 *	CGLTexture_2D::CGLTexture_2D(CGLState *p_state, int n_width, int n_height,
	 *		GLenum n_internal_format, bool b_create_mipmaps = true, int n_border_width = 0,
	 *		GLenum n_format = GL_RGB, GLenum n_data_type = GL_UNSIGNED_BYTE,
	 *		const void *p_src_data = 0)
	 *		- default constructor
	 *		- p_state is OpenGL state guard
	 *		- creates two-dimensional texture of size n_width per n_height and color format
	 *		  n_internal format with border n_border_width pixels wide
	 *		- texture can be initialized with image of color format n_format stored in
	 *		  data type n_data_type in array p_src_data
	 *		- call b_Status() to find out wheter constructor succeeded
	 *		- note this calls glGetError() and so it fails in case there are some
	 *		  uncaught errors despite texture creation is successful
	 */
	CGLTexture_2D(CGLState *p_state, int n_width, int n_height, GLenum n_internal_format,
		bool b_create_mipmaps = true, int n_border_width = 0,
		GLenum n_format = GL_RGB, GLenum n_data_type = GL_UNSIGNED_BYTE,
		const void *p_src_data = 0);

	inline int n_Width() const { return m_n_width; }
	inline int n_Height() const { return m_n_height; }

	/*
	 *	void CGLTexture_2D::Bind(CGLState *p_state) const
	 *		- binds texture object to OpenGL state as active texture in current texture unit
	 */
	virtual void Bind(CGLState *p_state) const;

	/*
	 *	void CGLTexture_2D::Bind_Enable(CGLState *p_state) const
	 *		- binds texture object to OpenGL state as active texture in current texture unit
	 *		- enables application of texture target (i.e. GL_TEXTURE_2D or similar)
	 */
	virtual void Bind_Enable(CGLState *p_state) const;

	/*
	 *	void CGLTexture_2D::Disable(CGLState *p_state) const
	 *		- disables application of texture target (i.e. GL_TEXTURE_2D or similar)
	 */
	virtual void Disable(CGLState *p_state) const;

	/*
	 *	CGLTextureParams &CGLTexture_2D::r_Parameters(CGLState *p_state)
	 *		- enables texture parameters to be changed
	 *		- binds and enables texture first (necessary for OpenGL texture parameter access)
	 */
	virtual CGLTextureParams &r_Parameters(CGLState *p_state);
};

class CGLTexture_Rect : public CGLTexture {
protected:
	int m_n_width;
	int m_n_height;

public:
	/*
	 *	CGLTexture_Rect::CGLTexture_Rect(CGLState *p_state, int n_width, int n_height,
	 *		GLenum n_internal_format, GLenum n_format = GL_RGB,
	 *		GLenum n_data_type = GL_UNSIGNED_BYTE, const void *p_src_data = 0)
	 *		- default constructor
	 *		- p_state is OpenGL state guard
	 *		- creates two-dimensional texture of size n_width per n_height and color format
	 *		  n_internal format (no border and no mip-mapping allowed for rectangle textures)
	 *		- texture can be initialized with image of color format n_format stored in
	 *		  data type n_data_type in array p_src_data
	 *		- call b_Status() to find out wheter constructor succeeded
	 *		- note this calls glGetError() and so it fails in case there are some
	 *		  uncaught errors despite texture creation is successful
	 */
	CGLTexture_Rect(CGLState *p_state, int n_width, int n_height, GLenum n_internal_format,
		GLenum n_format = GL_RGB, GLenum n_data_type = GL_UNSIGNED_BYTE,
		const void *p_src_data = 0);

	inline int n_Width() const { return m_n_width; }
	inline int n_Height() const { return m_n_height; }

	/*
	 *	void CGLTexture_Rect::Bind(CGLState *p_state) const
	 *		- binds texture object to OpenGL state as active texture in current texture unit
	 */
	virtual void Bind(CGLState *p_state) const;

	/*
	 *	void CGLTexture_Rect::Bind_Enable(CGLState *p_state) const
	 *		- binds texture object to OpenGL state as active texture in current texture unit
	 *		- enables application of texture target (i.e. GL_TEXTURE_2D or similar)
	 */
	virtual void Bind_Enable(CGLState *p_state) const;

	/*
	 *	void CGLTexture_Rect::Disable(CGLState *p_state) const
	 *		- disables application of texture target (i.e. GL_TEXTURE_2D or similar)
	 */
	virtual void Disable(CGLState *p_state) const;

	/*
	 *	CGLTextureParams &CGLTexture_Rect::r_Parameters(CGLState *p_state)
	 *		- enables texture parameters to be changed
	 *		- binds and enables texture first (necessary for OpenGL texture parameter access)
	 */
	virtual CGLTextureParams &r_Parameters(CGLState *p_state);
};

class CGLTexture_3D : public CGLTexture {
protected:
	int m_n_width;
	int m_n_height;
	int m_n_depth;

public:
	/*
	 *	CGLTexture_3D::CGLTexture_3D(CGLState *p_state, int n_width, int n_height, int n_depth,
	 *		GLenum n_internal_format, bool b_create_mipmaps = true, int n_border_width = 0,
	 *		GLenum n_format = GL_RGB, GLenum n_data_type = GL_UNSIGNED_BYTE,
	 *		const void *p_src_data = 0)
	 *		- default constructor
	 *		- p_state is OpenGL state guard
	 *		- creates three-dimensional texture of size n_width per n_height per n_depth
	 *		  and color format n_internal format with border n_border_width pixels wide
	 *		- texture can be initialized with image of color format n_format stored in
	 *		  data type n_data_type in array p_src_data
	 *		- call b_Status() to find out wheter constructor succeeded
	 *		- note this calls glGetError() and so it fails in case there are some
	 *		  uncaught errors despite texture creation is successful
	 */
	CGLTexture_3D(CGLState *p_state, int n_width, int n_height, int n_depth,
		GLenum n_internal_format, bool b_create_mipmaps = true, int n_border_width = 0,
		GLenum n_format = GL_RGB, GLenum n_data_type = GL_UNSIGNED_BYTE,
		const void *p_src_data = 0);

	inline int n_Width() const { return m_n_width; }
	inline int n_Height() const { return m_n_height; }
	inline int n_Depth() const { return m_n_depth; }

	/*
	 *	void CGLTexture_3D::Bind(CGLState *p_state) const
	 *		- binds texture object to OpenGL state as active texture in current texture unit
	 */
	virtual void Bind(CGLState *p_state) const;

	/*
	 *	void CGLTexture_3D::Bind_Enable(CGLState *p_state) const
	 *		- binds texture object to OpenGL state as active texture in current texture unit
	 *		- enables application of texture target (i.e. GL_TEXTURE_3D or similar)
	 */
	virtual void Bind_Enable(CGLState *p_state) const;

	/*
	 *	void CGLTexture_3D::Disable(CGLState *p_state) const
	 *		- disables application of texture target (i.e. GL_TEXTURE_3D or similar)
	 */
	virtual void Disable(CGLState *p_state) const;

	/*
	 *	CGLTextureParams &CGLTexture_3D::r_Parameters(CGLState *p_state)
	 *		- enables texture parameters to be changed
	 *		- binds and enables texture first (necessary for OpenGL texture parameter access)
	 */
	virtual CGLTextureParams &r_Parameters(CGLState *p_state);
};

class CGLTexture_Cube : public CGLTexture {
protected:
	static const GLenum p_cube_face[6];
	int m_n_width;

public:
	/*
	 *	CGLTexture_Cube::CGLTexture_Cube(CGLState *p_state, int n_width, GLenum n_internal_format,
	 *		bool b_create_mipmaps = true, bool b_software_mipmaps = false, int n_border_width = 0,
	 *		GLenum n_format = GL_RGB, GLenum n_data_type = GL_UNSIGNED_BYTE,
	 *		const void *p_src_data[6] = 0)
	 *		- default constructor
	 *		- p_state is OpenGL state guard
	 *		- creates cube-map texture of size n_width per n_width per n_width
	 *		  and color format n_internal format with border n_border_width pixels wide
	 *		- texture can be initialized with six images image of color format n_format stored in
	 *		  data type n_data_type in array p_src_data (in order x- x+ y- y+ z- z+)
	 *		- call b_Status() to find out wheter constructor succeeded
	 *		- note this calls glGetError() and so it fails in case there are some
	 *		  uncaught errors despite texture creation is successful
	 */
	CGLTexture_Cube(CGLState *p_state, int n_width, GLenum n_internal_format,
		bool b_create_mipmaps = true, bool b_software_mipmaps = false, int n_border_width = 0,
		GLenum n_format = GL_RGB, GLenum n_data_type = GL_UNSIGNED_BYTE,
		const void *p_src_data[6] = 0);

	inline int n_Width() const { return m_n_width; }
	inline int n_Height() const { return m_n_width; }
	inline int n_Depth() const { return m_n_width; }

	/*
	 *	void CGLTexture_Cube::Bind(CGLState *p_state) const
	 *		- binds texture object to OpenGL state as active texture in current texture unit
	 */
	virtual void Bind(CGLState *p_state) const;

	/*
	 *	void CGLTexture_Cube::Bind_Enable(CGLState *p_state) const
	 *		- binds texture object to OpenGL state as active texture in current texture unit
	 *		- enables application of texture target (i.e. GL_TEXTURE_CUBE_MAP or similar)
	 */
	virtual void Bind_Enable(CGLState *p_state) const;

	/*
	 *	void CGLTexture_Cube::Disable(CGLState *p_state) const
	 *		- disables application of texture target (i.e. GL_TEXTURE_CUBE_MAP or similar)
	 */
	virtual void Disable(CGLState *p_state) const;

	/*
	 *	CGLTextureParams &CGLTexture_Cube::r_Parameters(CGLState *p_state)
	 *		- enables texture parameters to be changed
	 *		- binds and enables texture first (necessary for OpenGL texture parameter access)
	 */
	virtual CGLTextureParams &r_Parameters(CGLState *p_state);
};

#endif // !__TEXTURE_MANAGER_INCLUDED
