/*
								+---------------------------------+
								|                                 |
								|   ***   OGL state guard   ***   |
								|                                 |
								|  Copyright  © -tHE SWINe- 2005  |
								|                                 |
								|          OpenGLState.h          |
								|                                 |
								+---------------------------------+
*/

#pragma once
#ifndef __GLSTATE_INCLUDED
#define __GLSTATE_INCLUDED

/**
 *	@file gl2/OpenGLState.h
 *	@author -tHE SWINe-
 *	@date 2005
 *	@brief OpenGL state guard
 *
 *	@date 2006-05-16
 *
 *  integers used to store just true or false were changed to bool
 *	fixed some minor errors with stencil write-mask
 *  body of CGLState::Update_States moved to TGLState::Update where it belongs
 *
 *	@date 2006-07-15
 *
 *	modified PolygonOffset support to match OpenGL 1.1 (EXT is actualy older)
 *
 *	@date 2006-07-25
 *
 *	files GlState.cpp and GlState.h renamed to OpenGLState.cpp and OpenGLState.h
 *
 *	@date 2006-08-13
 *
 *	fixed "CallStack.h" and <vector> include order
 *
 *	@date 2006-10-12
 *
 *	minor modifications and improvements in using std::vector
 *
 *	@date 2007-02-20
 *
 *	fixed some confusing comments about functions argument values
 *
 *	@date 2007-03-06
 *
 *	removed __declspec(dllexport)
 *
 *	@date 2007-04-02
 *
 *	added support for glBlendEquation, glBlendEquationSeparate and glBlendFuncSeparate
 *	note calling one of blending functions invalidates state cache for the other ones
 *	note these functions are extensions. be sure to initialize properly them before using
 *
 *	@date 2007-05-10
 *
 *	added TexGenObjectPlane and TexGenEyePlane functions (uncached at the moment)
 *	added delete notifiaction for textures and shader / program objects
 *	added state caching for buffer objects (including delete notification)
 *	removed __fastcall calling convention as compiller wouldn't inline such a functions
 *	in release mode, losing some speed
 *
 *	@date 2007-05-16
 *
 *	TexGenObjectPlane and TexGenEyePlane is now cached as it should be
 *	removed some old TexGen_*_fv functions
 *	added couple of assertions on function parameters that can be easily confused
 *	(GL_S versus 0, GL_TEXTURE0 versus 0, etc)
 *  some integer parameters with boolean significance were changed to bool
 *
 *	@date 2007-07-16
 *
 *	fixed error in Color3f and Color3ub where alpha channel variable
 *	wasn't set to 1 as it should be according to OpenGL specs
 *
 *	@date 2007-07-29
 *
 *	found error in caching policy: texcoord eye plane, clip planes, light positions and light
 *	directions are dependent on model-view matrix in time they are set and must be invalidated
 *	once model-view matrix is changed; possible sollutions involve not to cache them or to add
 *	matix-op functions and invalidate values everytime modelview changes (which is inefficient
 *	because modelview matrix will likely be invalidated several times every frame), again and
 *	again so the choice is not to cache them
 *	renamed __MULTITEXTURE_ENABLED to GL_STATE_MULTITEXTURE_ENABLED
 *	changed behavior of multi-coord texgen*fv commands so they take multiple quadruples of floats
 *	as input and sets each texgen plane to corresponding quadruple (before they set all planes
 *	to the same single coordinate which is mostly useless)
 *
 *	@date 2007-09-25
 *
 *	deprecated support for unsigned byte colors
 *	added functions for entering constant blend color (available with imaging subset only)
 *	renamed some array members of TGLState to begin with p_ prefix
 *
 *	@date 2007-10-28
 *
 *	fixed some minor bugs that emerged on very old OpenGL implementations
 *	(debugged on S3 Trio 64V+ and OpenGL 1.2.1)
 *	don't forget to switch-off multitexturing support using GL_STATE_MULTITEXTURE_ENABLED \#define
 *	added runtime multitexture support detection to TGLState::Update() so even if
 *	GL_STATE_MULTITEXTURE_ENABLED is defined and implementation doesn't support OpenGL,
 *	application doesn't crash in case it isn't directly using multitexture functions such
 *	as ActiveTextureUnit or MultiTexCoord
 *
 *	@date 2007-10-29
 *
 *	improved linux compatibility
 *
 *	@date 2007-11-09
 *
 *	created single-context interface as in most of today's code frmabuffers win over P-Buffers
 *	so the application really don't get to have more than single context
 *	antialiassed CGLState functions
 *
 *	@date 2007-11-10
 *
 *	improved linux compatibility
 *
 *	@date 2007-12-30
 *
 *	fixed error causing null pointer dereference when all OpenGL state managers are deleted and
 *	some OpenGL object (like CGLTexture_2D) is dealocated and calls CGLState::NotifyDelete*
 *
 *	@date 2008-03-11
 *
 *	added functions CGLState::PolygonModeFront() and CGLState::PolygonModeBack()
 *
 *	@date 2008-08-08
 *
 *	added \#ifdef for windows 64
 *
 *	@date 2008-08-19
 *
 *	fixed state caching inconsistencies in CGLState::Enable() and CGLState::Disable() (stencil test
 *	and vertex / fragment program state caching was missing there)
 *	disabled vertex color caching (use GL_STATE_FORCE_COLOR_CACHING if necessary)
 *	behavior of generic Enable, Disable changed - must not be used for enabling / disabling of
 *	states that are cached by CGLState - performance feature, avoiding switch in CGLState code,
 *	followed by similar switch in OpenGL driver (use GL_STATE_CACHE_GENERIC_ENABLE_DISABLE)
 *
 *	@date 2009-05-04
 *
 *	fixed mixed windows / linux line endings
 *
 *	@date 2010-10-29
 *
 *	Unified windows detection macro to "\#if defined(_WIN32) || defined(_WIN64)".
 *
 *	@date 2012-06-19
 *
 *	Moved multiple inclusion guard before file documentation comment.
 *
 */

/**
 *	@def GL_STATE_MULTITEXTURE_ENABLED
 *
 *	@brief undef this part if it's not supposed to run on multitexturing mashine
 *		(supposedly texturing state calls are so frequent it's too costy to check
 *		for support every time and it's supported on every today's graphics card)
 */
#define GL_STATE_MULTITEXTURE_ENABLED


/**
 *	@def GL_STATE_SINGLE_CONTEXT_ONLY
 *
 *	@brief this define disables support for caching more than one GL state. use when
 *		not working with multiple rendering contexts and under linux
 */
#define GL_STATE_SINGLE_CONTEXT_ONLY
// 

/**
 *	@def GL_STATE_FORCE_COLOR_CACHING
 *
 *	@brief this macro enables color caching (glColor[3|4]f), it has been disabled
 *		because of display list issues and small-to-none performance benefit
 */
//#define GL_STATE_FORCE_COLOR_CACHING

/**
 *	@def GL_STATE_CACHE_GENERIC_ENABLE_DISABLE
 *
 *	@brief if defined, it is allowed to use CGLState::Enable() and CGLState::Disable()
 *		with states that have specialized function (for example it is normally not allowed
 *		to use CGLState::Enable(GL_DEPTH_TEST), one must use CGLState::EnableDepthTest())
 */
//#define GL_STATE_CACHE_GENERIC_ENABLE_DISABLE

#if !defined(_WIN32) && !defined(_WIN64)
#define HDC void*
#define HGLRC void*
#endif
// no handle types for linux, values passed to CGLState::CGLState must be both NULL
// (which regretably leaves us with single state under linux)

/**
 *	@brief OpenGL state structure
 *
 *	Contains copy of OpenGL state, it is used to speed-up OpenGL operation by only
 *		calling those OpenGL functions that modify OpenGL state at the moment.
 *
 *	@note You don't create instances of TGLState, use CGLState instead.
 */
struct TGLState {
#ifndef GL_STATE_SINGLE_CONTEXT_ONLY
	HGLRC h_glrc;
	// rendering context state is attached to
#endif // GL_STATE_SINGLE_CONTEXT_ONLY

	int n_reference_num;
	// number of references to this state

#ifndef GL_STATE_FORCE_COLOR_CACHING
	GLfloat p_color[4];
	// color; caching disabled as it is vertex attribute just like texcoord or any other
#endif // GL_STATE_FORCE_COLOR_CACHING

	GLclampf p_clr_color[4];
	// clear color

	GLclampd f_clr_depth;
	// clear depth

	GLint n_clr_stencil;
	// clear stencil

	bool b_blend;
	GLenum p_blend_func[2]; // src, dest (rgb)
	GLenum p_blend_func_alpha[2]; // src, dest alpha
	GLenum p_blend_equation[2]; // rgb, alpha
	GLclampf p_blend_color[4];
	// blending

	GLenum n_front_face;
	bool b_cull_face;
	GLenum n_cull_face;
	// face culling

	bool b_alpha_test;
	GLenum n_alpha_func;
	GLclampf f_alpha_tresh;
	// alpha test

	bool b_depth_test;
	GLenum n_depth_func;
	// depth test

	bool b_stencil_test;
	GLenum p_stencil_func[2];
	GLint p_stencil_ref[2];
	GLuint p_stencil_mask[2];
	GLenum p_stencil_op_sfail[2];
	GLenum p_stencil_op_dfail[2];
	GLenum p_stencil_op_dpass[2];
	bool b_separate_gl2_stencil;
	// stencil test

	bool p_texture1d_enabled[32];
	bool p_texture2d_enabled[32];
	bool p_texture3d_enabled[32];
	bool p_texture_cubemap_enabled[32];
	bool p_texture_rect_enabled[32];
	//
	int n_active_tex_unit;
	int n_max_texture_units;
	//
	GLuint p_texture1d[32];
	GLuint p_texture2d[32];
	GLuint p_texture3d[32];
	GLuint p_texture_cubemap[32];
	GLuint p_texture_rect[32];
	// texture units

	int n_max_lights;
	bool b_lighting;
	bool p_light_enabled[32];
	//
	struct {
		GLfloat p_ambient[4];
		GLfloat p_diffuse[4];
		GLfloat p_specular[4];

		/*GLfloat p_position[4];
		GLfloat p_spot_direction[3];*/
		// caching disabled, depends on current modelview

		GLfloat f_spot_exponent;
		GLfloat f_spot_cutoff;
		GLfloat f_constant_attenuation;
		GLfloat f_linear_attenuation;
		GLfloat f_quadratic_attenuation;
	} p_light_data[32];
	// lights

	GLfloat p_model_ambient[4];
	GLboolean b_model_local_viewer;
	GLboolean b_model_two_side;
	GLenum n_model_color_control;
	// light model

	GLfloat p_material_ambient[2][4];
	GLfloat p_material_diffuse[2][4];
	GLfloat p_material_specular[2][4];
	GLfloat p_material_emission[2][4];
	GLfloat p_material_shininess[2];
	// materials (0 = back, 1 = front)

	bool b_fog;
	GLenum n_fog_type;
	GLfloat p_fog_color[4];
	GLfloat f_fog_density;
	GLfloat f_fog_start;
	GLfloat f_fog_end;
	// fog

	GLenum n_shade_model;
	// shade model

	GLenum n_polygon_mode[2];
	GLfloat f_line_width;
	GLfloat f_point_size;
	// polygon mode / line width

	bool p_texgen_enabled[32][4];
	GLenum p_texgen_mode[32][4];
	//GLfloat p_texgen_eye_plane[32][4][4]; // caching disabled, depends on current modelview
	GLfloat p_texgen_object_plane[32][4][4];
	// the last index is coord index, middle is texcoord
	// index and the first one is texture unit index
	// texgen

	bool b_depth_write;
	GLuint p_stencil_write[2]; // back / front (back = 0)
	bool p_color_write[4];
	// write masks (stencil mask is real bit-wise mask)

	bool b_polygon_offset_support;
	bool p_polygon_offset_enabled[3]; // fill / line / point
	GLfloat f_polygon_offset_bias;
	GLfloat f_polygon_offset_factor;
	// polygon offset

	bool b_vertex_program_support, b_fragment_program_support;
	GLuint n_vertex_program;
	GLuint n_fragment_program;
	bool b_vertex_program_enabled;
	bool b_fragment_program_enabled;
	//
	bool b_shader_support;
	bool b_shader_gl2_support;
	GLuint n_program_object;
	// programmable shading

	bool p_clip_plane_enabled[32];
	//GLdouble p_clip_plane[32][4]; // caching disabled, depends on current modelview
	int n_max_clip_planes;
	// clip planes

	bool b_vertex_buffer_support, b_pixel_buffer_support;
	GLuint n_vertex_array_buffer;
	GLuint n_vertex_element_array_buffer;
	GLuint n_pixel_pack_buffer;
	GLuint n_pixel_unpack_buffer;
	// buffer objects

	/**
	 *	@brief reads current gl-state into itself
	 *
	 *	@note It may take a few milliseconds, not a candidate to be called every frame.
	 */
	void Update();
};

/**
 *	@brief OpenGL state guard
 */
class CGLState {
private:
#ifdef GL_STATE_SINGLE_CONTEXT_ONLY
	static TGLState *m_p_cur_state;
#else // GL_STATE_SINGLE_CONTEXT_ONLY
	static std::vector<TGLState*> *m_p_state;
	static int m_n_state_reference_num;
	TGLState *m_p_cur_state;
	HDC m_h_dc;
	HGLRC m_h_glrc;
	bool m_b_init;

	class CFindState {
	protected:
		HGLRC m_h_glrc;

	public:
		inline CFindState(HGLRC h_glrc)
			:m_h_glrc(h_glrc)
		{}

		inline bool operator ()(TGLState *p_state) const
		{
			return p_state->h_glrc == m_h_glrc;
		}
	};
#endif // GL_STATE_SINGLE_CONTEXT_ONLY

public:
#ifdef GL_STATE_SINGLE_CONTEXT_ONLY
	/**
	 *	@brief default constructor
	 *
	 *	Copies current OpenGL state to TGLState.
	 */
	CGLState();
#else // GL_STATE_SINGLE_CONTEXT_ONLY
	/**
	 *	@brief default constructor
	 *
	 *	@param[in] h_dc is device context, associated with h_glrc
	 *	@param[in] h_glrc is OpenGL rendering context
	 *
	 *	Copies current OpenGL state to TGLState.
	 */
	CGLState(HDC h_dc, HGLRC h_glrc);
#endif // GL_STATE_SINGLE_CONTEXT_ONLY

	/**
	 *	@brief destructor
	 */
	~CGLState();

	/**
	 *	@brief forces reading current OpenGL state to TGLState
	 */
	void Update_States();

#ifndef GL_STATE_SINGLE_CONTEXT_ONLY
	/**
	 *	@brief gets device context
	 *
	 *	@return Returns device context, associated with this OpenGL state.
	 */
	HDC h_DeviceContext();

	/**
	 *	@brief gets OpenGL rendering context
	 *
	 *	@return Returns OpenGL rendering context, associated with this OpenGL state.
	 */
	HGLRC h_RenderingContext();
#endif // GL_STATE_SINGLE_CONTEXT_ONLY

	/**
	 *	@brief gets OpenGL state
	 *
	 *	@return Returns pointer to TGLState, containing copy of current OpenGL state.
	 */
	inline const TGLState *p_State() { return m_p_cur_state; }

	void Enable(GLenum n_value);
	void Disable(GLenum n_value);

	void LineWidth(GLfloat f_width);
	void PointSize(GLfloat f_size);
	void PolygonMode(GLenum n_side, GLenum n_mode);
	void PolygonModeFront(GLenum n_mode);
	void PolygonModeBack(GLenum n_mode);
	// raster props

	void EnableFog();
	void DisableFog();
	//
	void FogMode(GLenum n_value);
	void FogDensity(GLfloat f_value);
	void FogStart(GLfloat f_value);
	void FogEnd(GLfloat f_value);
	void FogColor(const GLfloat *p_fog_color4);
	// fog

	void EnableLighting();
	void DisableLighting();
	void EnableLight(int n_light); // 0 - 7
	void DisableLight(int n_light); // 0 - 7
	//
	void ShadeModel(GLenum n_model);
	//
	void LightAmbient(int n_light, const GLfloat *p_color4);
	void LightDiffuse(int n_light, const GLfloat *p_color4);
	void LightSpecular(int n_light, const GLfloat *p_color4);
	void LightPosition(int n_light, const GLfloat *p_position4);
	void LightSpotDirection(int n_light, const GLfloat *p_direction3);
	void LightSpotExponent(int n_light, GLfloat f_value);
	void LightSpotCutoff(int n_light, GLfloat f_value);
	void LightConstantAttenuation(int n_light, GLfloat f_value);
	void LightLinearAttenuation(int n_light, GLfloat f_value);
	void LightQuadraticAttenuation(int n_light, GLfloat f_value);
	// lighting

	void LightModelAmbient(const GLfloat *p_ambient4);
	void LightModelViewer(bool b_local);
	void LightModelTwoSide(bool b_two_side);
	void LightModelColorControl(GLenum n_mode);
	// light model

	void MaterialAmbient(const GLfloat *p_ambient4);
	void MaterialAmbient(bool b_front, const GLfloat *p_ambient4);
	void MaterialDiffuse(const GLfloat *p_diffuse4);
	void MaterialDiffuse(bool b_front, const GLfloat *p_diffuse4);
	void MaterialSpecular(const GLfloat *p_specular4);
	void MaterialSpecular(bool b_front, const GLfloat *p_specular4);
	void MaterialEmission(const GLfloat *p_emission4);
	void MaterialEmission(bool b_front, const GLfloat *p_emission4);
	void MaterialShininess(GLfloat f_shininess);
	void MaterialShininess(bool b_front, GLfloat f_shininess);
	// material

	void EnableBlend();
	void DisableBlend();
	//
	void BlendFunc(GLenum n_src_op, GLenum n_dest_op);
	void BlendFuncSeparate(GLenum n_src_op_rgb, GLenum n_dest_op_rgb,
		GLenum n_src_op_a, GLenum n_dest_op_a);
	void BlendEquation(GLenum n_equation);
	void BlendEquationSeparate(GLenum n_equation_rgb, GLenum n_equation_alpha);
	// blending

	void EnableDepthTest();
	void DisableDepthTest();
	//
	void DepthFunc(GLenum n_op);
	// depth test

	void EnableStencilTest();
	void DisableStencilTest();
	//
	void StencilFunc(GLenum n_func, GLint n_ref, GLuint n_mask);
	void StencilFunc(bool b_front, GLenum n_func, GLint n_ref, GLuint n_mask);
	void StencilOp(GLenum n_s_fail, GLuint n_s_pass_d_fail, GLuint n_s_pass_d_pass);
	void StencilOp(bool b_front, GLenum n_s_fail, GLuint n_s_pass_d_fail, GLuint n_s_pass_d_pass);
	// stencil test

	void EnableAlphaTest();
	void DisableAlphaTest();
	//
	void AlphaFunc(GLenum n_op, GLclampf f_tresh);
	// alpha test

	void DisableAllTextures();
	void DisableAllTexture1D();
	void DisableAllTexture2D();
	void DisableAllTextureRect();
	void DisableAllTexture3D();
	void DisableAllTextureCubeMap();
	void DisableAllTexture(GLenum n_type); // n_type is *not* one of 1D, 2D, rect, 3D or cube
	//
	void EnableTexture1D();
	void EnableTexture2D();
	void EnableTextureRect();
	void EnableTexture3D();
	void EnableTextureCubeMap();
	void EnableTexture(GLenum n_type); // n_type is *not* one of 1D, 2D, rect, 3D or cube
	//
	void DisableTexture1D();
	void DisableTexture2D();
	void DisableTextureRect();
	void DisableTexture3D();
	void DisableTextureCubeMap();
	void DisableTexture(GLenum n_type); // n_type is *not* one of 1D, 2D, rect, 3D or cube
	//
	void ActiveTextureUnit(int n_unit); // 0 - 31
	int n_TexUnit_Num();
	//
	void BindTexture1D(GLuint n_texture);
	void BindTexture2D(GLuint n_texture);
	void BindTextureRect(GLuint n_texture);
	void BindTexture3D(GLuint n_texture);
	void BindTextureCubeMap(GLuint n_texture);
	void BindTexture(GLenum n_type, GLuint n_texture); // n_type is *not* one of 1D, 2D, rect, 3D or cube
	//
	static void NotifyDeleteTexture(GLuint n_texture);
	// textures

	void Color3f(GLfloat r, GLfloat g, GLfloat b);
	void Color4f(GLfloat f, GLfloat g, GLfloat b, GLfloat a);
	// color

	void BlendColor3f(GLfloat r, GLfloat g, GLfloat b);
	void BlendColor4f(GLfloat f, GLfloat g, GLfloat b, GLfloat a);
	// const blending color

	void ClearColor4f(GLclampf f, GLclampf g, GLclampf b, GLclampf a);
	void ClearDepth(GLclampd d);
	void ClearStencil(GLint s);
	// clear attribs

	void EnableCullFace();
	void DisableCullFace();
	//
	void CullFace(GLenum n_mode);
	void FrontFace(GLenum n_mode);
	// cull face

	void Enable_STRQ_TexGen();
	void Disable_STRQ_Texgen();
	//
	void Enable_S_TexGen();
	void Enable_T_TexGen();
	void Enable_R_TexGen();
	void Enable_Q_TexGen();
	void Disable_S_TexGen();
	void Disable_T_TexGen();
	void Disable_R_TexGen();
	void Disable_Q_TexGen();
	//
	void Enable_ST_TexGen();
	void Disable_ST_TexGen();
	void Enable_STR_TexGen();
	void Disable_STR_TexGen();
	void EnableTexGen(int n_coord); // 0 = S, 1 = T, 2 = R, 3 = Q
	void DisableTexGen(int n_coord); // 0 = S, 1 = T, 2 = R, 3 = Q
	//
	void TexGen_STRQ_fv(int n_name, GLfloat *p_param16);
	void TexGen_STR_fv(int n_name, GLfloat *p_param12);
	void TexGen_ST_fv(int n_name, GLfloat *p_param8);
	void TexGenfv(int n_coord, int n_name, GLfloat *p_param4); // n_name is either GL_OBJECT_PLANE or GL_EYE_PLANE
	void TexGenEyePlane(int n_coord, const float *p_plane4);
	void TexGenObjectPlane(int n_coord, const float *p_plane4);
	//
	void TexGen_STRQ_Mode(GLenum n_param);
	void TexGen_STR_Mode(GLenum n_param);
	void TexGen_S_Mode(GLenum n_param);
	void TexGen_T_Mode(GLenum n_param);
	void TexGen_R_Mode(GLenum n_param);
	void TexGen_Q_Mode(GLenum n_param);
	void TexGen_ST_Mode(GLenum n_param);
	void TexGenMode(int n_coord, GLenum n_param);
	// texture generation mode

	void ColorMask(bool b_r, bool b_g, bool b_b, bool b_a);
	void DepthMask(bool b_d);
	void StencilMask(GLuint n_mask);
	void StencilMask(bool b_front, GLuint n_mask);
	// write masks

	void EnablePolygonOffset(GLenum n_mode);
	void DisablePolygonOffset(GLenum n_mode);
	void EnablePolygonOffset_Line();
	void DisablePolygonOffset_Line();
	void EnablePolygonOffset_Fill();
	void DisablePolygonOffset_Fill();
	void EnablePolygonOffset_Point();
	void DisablePolygonOffset_Point();
	void PolygonOffset(GLfloat f_factor = -1.0f, GLfloat f_bias = -2.0f);
	// polygon offset

	void EnableVertexProgram();
	void EnableFragmentProgram();
	void DisableVertexProgram();
	void DisableFragmentProgram();
	//
	void BindProgramObject(GLhandleARB h_shader);
	void BindProgramObject_GL2(GLuint n_shader);
	void BindVertexProgram(GLuint n_program);
	void BindFragmentProgram(GLuint n_program);
	//
	static void NotifyDeleteProgramObject(GLhandleARB h_shader);
	static void NotifyDeleteProgramObject_GL2(GLuint n_shader);
	static void NotifyDeleteVertexProgram(GLuint n_program);
	static void NotifyDeleteFragmentProgram(GLuint n_program);
	// programmable shading

	void EnableClipPlane(int n_plane); // 0 - 6
	void DisableClipPlane(int n_plane); // 0 - 6
	void DisableAllClipPlanes();
	//
	void ClipPlane(int n_plane, GLdouble f_eqn0, GLdouble f_eqn1, GLdouble f_eqn2, GLdouble f_eqn3); // 0 - 6, normal{x, y, z}, dist
	// clip planes

	void BindVertexArrayBuffer(GLuint n_buffer);
	void BindVertexElementArrayBuffer(GLuint n_buffer);
	void BindPixelPackBuffer(GLuint n_buffer);
	void BindPixelUnPackBuffer(GLuint n_buffer);
	void BindBuffer(GLenum n_target, GLuint n_buffer);
	//
	static void NotifyDeleteBufferObject(GLuint n_buffer);
	// buffer objects

private:
	static inline void DeleteState(TGLState *p_state) { delete p_state; }
};

#endif // !__GLSTATE_INCLUDED
