/*
This source file is part of Castor3D (https://sourceforge.net/projects/castor3d/)

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

This program 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
the program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
*/
#ifndef ___C3DGL_GlObjects___
#define ___C3DGL_GlObjects___

#include <Castor3D/TextureUnit.hpp>
#include <Castor3D/BufferElement.hpp>

#pragma warning( push )
#pragma warning( disable:4251 )
#pragma warning( disable:4275 )

#if !defined( CALLBACK )
#	if defined( _WIN32 )
#		define CALLBACK __stdcall
#	else
#		define CALLBACK
#	endif
#endif

//*************************************************************************************************

namespace GlRender
{
	typedef enum eGL_BUFFER
	{	eGL_BUFFER_NONE				= 0
	,	eGL_BUFFER_FRONT_LEFT		= 0x0400
	,	eGL_BUFFER_FRONT_RIGHT		= 0x0401
	,	eGL_BUFFER_BACK_LEFT		= 0x0402
	,	eGL_BUFFER_BACK_RIGHT		= 0x0403
	,	eGL_BUFFER_FRONT			= 0x0404
	,	eGL_BUFFER_BACK				= 0x0405
	,	eGL_BUFFER_LEFT				= 0x0406
	,	eGL_BUFFER_RIGHT			= 0x0407
	,	eGL_BUFFER_FRONT_AND_BACK	= 0x0408
	,	eGL_BUFFER_COLOR0			= 0x8CE0
	,	eGL_BUFFER_COLOR1			= 0x8CE1
	,	eGL_BUFFER_COLOR2			= 0x8CE2
	,	eGL_BUFFER_COLOR3			= 0x8CE3
	,	eGL_BUFFER_COLOR4			= 0x8CE4
	,	eGL_BUFFER_COLOR5			= 0x8CE5
	,	eGL_BUFFER_COLOR6			= 0x8CE6
	,	eGL_BUFFER_COLOR7			= 0x8CE7
	,	eGL_BUFFER_COLOR8			= 0x8CE8
	,	eGL_BUFFER_COLOR9			= 0x8CE9
	,	eGL_BUFFER_COLOR10			= 0x8CEA
	,	eGL_BUFFER_COLOR11			= 0x8CEB
	,	eGL_BUFFER_COLOR12			= 0x8CEC
	,	eGL_BUFFER_COLOR13			= 0x8CED
	,	eGL_BUFFER_COLOR14			= 0x8CEE
	,	eGL_BUFFER_COLOR15			= 0x8CEF
	}	eGL_BUFFER;

	typedef enum eGL_PATCH_PARAMETER
	{	eGL_PATCH_PARAMETER_VERTICES			= 0x8E72
	,	eGL_PATCH_PARAMETER_DEFAULT_INNER_LEVEL	= 0x8E73
	,	eGL_PATCH_PARAMETER_DEFAULT_OUTER_LEVEL	= 0x8E74
	}	eGL_PATCH_PARAMETER;

	typedef enum eGL_PRIMITIVE CASTOR_TYPE( uint32_t )
	{	eGL_PRIMITIVE_POINTS			= 0x0000
	,	eGL_PRIMITIVE_LINES				= 0x0001
	,	eGL_PRIMITIVE_LINE_LOOP			= 0x0002
	,	eGL_PRIMITIVE_LINE_STRIP		= 0x0003
	,	eGL_PRIMITIVE_TRIANGLES			= 0x0004
	,	eGL_PRIMITIVE_TRIANGLE_STRIP	= 0x0005
	,	eGL_PRIMITIVE_TRIANGLE_FAN		= 0x0006
	,	eGL_PRIMITIVE_QUADS				= 0x0007
	,	eGL_PRIMITIVE_QUAD_STRIP		= 0x0008
	,	eGL_PRIMITIVE_POLYGON			= 0x0009
	,	eGL_PRIMITIVE_PATCHES			= 0x000E
	}	eGL_PRIMITIVE;

	typedef enum eGL_INTERNAL_FORMAT				//	Base Type	Components	Norm	0	1	2	3
	{	eGL_INTERNAL_FORMAT_RGBA8		= 0x8058	//	uint		4			YES		R	G	B	A
	,	eGL_INTERNAL_FORMAT_RGBA16		= 0x805B	//	short		4			YES		R	G	B	A
	,	eGL_INTERNAL_FORMAT_R8			= 0x8229	//	ubyte		1			YES		R	0	0	1
	,	eGL_INTERNAL_FORMAT_R16			= 0x822A	//	ushort		1			YES		R	0	0	1
	,	eGL_INTERNAL_FORMAT_RG8			= 0x822B	//	ubyte		2			YES		R	G	0	1
	,	eGL_INTERNAL_FORMAT_RG16		= 0x822C	//	ushort		2			YES		R	G	0	1
	,	eGL_INTERNAL_FORMAT_R16F		= 0x822D	//	half		1			NO		R	0	0	1
	,	eGL_INTERNAL_FORMAT_R32F		= 0x822E	//	float		1			NO		R	0	0	1
	,	eGL_INTERNAL_FORMAT_RG16F		= 0x822F	//	half		2			NO		R	G	0	1
	,	eGL_INTERNAL_FORMAT_RG32F		= 0x8230	//	float		2			NO		R	G	0	1
	,	eGL_INTERNAL_FORMAT_R8I			= 0x8231	//	byte		1			NO		R	0	0	1
	,	eGL_INTERNAL_FORMAT_R8UI		= 0x8232	//	ubyte		1			NO		R	0	0	1
	,	eGL_INTERNAL_FORMAT_R16I		= 0x8233	//	short		1			NO		R	0	0	1
	,	eGL_INTERNAL_FORMAT_R16UI		= 0x8234	//	ushort		1			NO		R	0	0	1
	,	eGL_INTERNAL_FORMAT_R32I		= 0x8235	//	int			1			NO		R	0	0	1
	,	eGL_INTERNAL_FORMAT_R32UI		= 0x8236	//	uint		1			NO		R	0	0	1
	,	eGL_INTERNAL_FORMAT_RG8I		= 0x8237	//	byte		2			NO		R	G	0	1
	,	eGL_INTERNAL_FORMAT_RG8UI		= 0x8238	//	ubyte		2			NO		R	G	0	1
	,	eGL_INTERNAL_FORMAT_RG16I		= 0x8239	//	short		2			NO		R	G	0	1
	,	eGL_INTERNAL_FORMAT_RG16UI		= 0x823A	//	ushort		2			NO		R	G	0	1
	,	eGL_INTERNAL_FORMAT_RG32I		= 0x823B	//	int			2			NO		R	G	0	1
	,	eGL_INTERNAL_FORMAT_RG32UI		= 0x823C	//	uint		2			NO		R	G	0	1
	,	eGL_INTERNAL_FORMAT_RGBA32F		= 0x8814	//	float		4			NO		R	G	B	A
	,	eGL_INTERNAL_FORMAT_RGBA16F		= 0x881A	//	half		4			NO		R	G	B	A
	,	eGL_INTERNAL_FORMAT_RGBA32UI	= 0x8D70	//	uint		4			NO		R	G	B	A
	,	eGL_INTERNAL_FORMAT_RGBA16UI	= 0x8D76	//	ushort		4			NO		R	G	B	A
	,	eGL_INTERNAL_FORMAT_RGB16UI		= 0x8D77	//	ushort		3			NO		R	G	B	1
	,	eGL_INTERNAL_FORMAT_RGBA8UI		= 0x8D7C	//	ubyte		4			NO		R	G	B	A
	,	eGL_INTERNAL_FORMAT_RGBA32I		= 0x8D82	//	int			4			NO		R	G	B	A
	,	eGL_INTERNAL_FORMAT_RGBA16I		= 0x8D88	//	short		4			NO		R	G	B	A
	,	eGL_INTERNAL_FORMAT_RGBA8I		= 0x8D8E	//	byte		4			NO		R	G	B	A
	}	eGL_INTERNAL_FORMAT;

	typedef enum eGL_TEXDIM
	{	eGL_TEXDIM_1D					= 0x0DE0
	,	eGL_TEXDIM_2D					= 0x0DE1
	,	eGL_TEXDIM_3D					= 0x806F
	,	eGL_TEXDIM_2D_ARRAY				= 0x8C1A
	,	eGL_TEXDIM_2D_MULTISAMPLE		= 0x9100
	}	eGL_TEXDIM;

	typedef enum eGL_FUNC
	{	eGL_FUNC_NEVER		= 0x0200
	, 	eGL_FUNC_LESS		= 0x0201
	,	eGL_FUNC_EQUAL		= 0x0202
	,	eGL_FUNC_LEQUAL		= 0x0203
	,	eGL_FUNC_GREATER	= 0x0204
	,	eGL_FUNC_NOTEQUAL	= 0x0205
	,	eGL_FUNC_GEQUAL		= 0x0206
	,	eGL_FUNC_ALWAYS		= 0x0207
	}	eGL_FUNC;

	typedef enum eGL_WRAP_MODE
	{	eGL_WRAP_MODE_CLAMP				= 0x2900
	,	eGL_WRAP_MODE_REPEAT			= 0x2901
	,	eGL_WRAP_MODE_CLAMP_TO_BORDER	= 0x812D
	,	eGL_WRAP_MODE_CLAMP_TO_EDGE		= 0x812F
	}	eGL_WRAP_MODE;

	typedef enum eGL_INTERPOLATION_MODE
	{	eGL_INTERPOLATION_MODE_NEAREST					= 0x2600
	,	eGL_INTERPOLATION_MODE_LINEAR					= 0x2601
	,	eGL_INTERPOLATION_MODE_NEAREST_MIPMAP_NEAREST	= 0x2700
	,	eGL_INTERPOLATION_MODE_LINEAR_MIPMAP_NEAREST	= 0x2701
	,	eGL_INTERPOLATION_MODE_NEAREST_MIPMAP_LINEAR	= 0x2702
	,	eGL_INTERPOLATION_MODE_LINEAR_MIPMAP_LINEAR		= 0x2703
	}	eGL_INTERPOLATION_MODE;

	typedef enum eGL_LIGHT_INDEX
	{	eGL_LIGHT_INDEX_INVALID	= 0xFFFFFFFF
	,	eGL_LIGHT_INDEX_0		= 0x4000
	,	eGL_LIGHT_INDEX_1		= 0x4001
	,	eGL_LIGHT_INDEX_2		= 0x4002
	,	eGL_LIGHT_INDEX_3		= 0x4003
	,	eGL_LIGHT_INDEX_4		= 0x4004
	,	eGL_LIGHT_INDEX_5		= 0x4005
	,	eGL_LIGHT_INDEX_6		= 0x4006
	,	eGL_LIGHT_INDEX_7		= 0x4007
	}	eGL_LIGHT_INDEX;

	typedef enum eGL_BLEND_FACTOR
	{	eGL_BLEND_FACTOR_ZERO					= 0
	,	eGL_BLEND_FACTOR_ONE					= 1
	,	eGL_BLEND_FACTOR_SRC_COLOR				= 0x0300
	,	eGL_BLEND_FACTOR_ONE_MINUS_SRC_COLOR	= 0x0301
	,	eGL_BLEND_FACTOR_SRC_ALPHA				= 0x0302
	,	eGL_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA	= 0x0303
	,	eGL_BLEND_FACTOR_DST_ALPHA				= 0x0304
	,	eGL_BLEND_FACTOR_ONE_MINUS_DST_ALPHA	= 0x0305
	,	eGL_BLEND_FACTOR_DST_COLOR				= 0x0306
	,	eGL_BLEND_FACTOR_ONE_MINUS_DST_COLOR	= 0x0307
	,	eGL_BLEND_FACTOR_SRC_ALPHA_SATURATE		= 0x0308
	,	eGL_BLEND_FACTOR_CONSTANT				= 0x8001
	,	eGL_BLEND_FACTOR_ONE_MINUS_CONSTANT		= 0x8002
	,	eGL_BLEND_FACTOR_SRC1_ALPHA				= 0x8589
	,	eGL_BLEND_FACTOR_SRC1_COLOR				= 0x88F9
	,	eGL_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR	= 0x88FA
	,	eGL_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA	= 0x88FB
	}	eGL_BLEND_FACTOR;

	typedef enum eGL_BUFFER_USAGE
	{	eGL_BUFFER_USAGE_VERTEX_ARRAY			= 0x8074
	,	eGL_BUFFER_USAGE_NORMAL_ARRAY			= 0x8075
	,	eGL_BUFFER_USAGE_COLOR_ARRAY			= 0x8076
	,	eGL_BUFFER_USAGE_INDEX_ARRAY			= 0x8077
	,	eGL_BUFFER_USAGE_TEXTURE_COORD_ARRAY	= 0x8078
	,	eGL_BUFFER_USAGE_TANGENT_ARRAY			= 0x8439
	,	eGL_BUFFER_USAGE_BINORMAL_ARRAY			= 0x843A
	}	eGL_BUFFER_USAGE;

	typedef enum eGL_TEXTURE_INDEX
	{	eGL_TEXTURE_INDEX_0		= 0x84C0
	,	eGL_TEXTURE_INDEX_1		= 0x84C1
	,	eGL_TEXTURE_INDEX_2		= 0x84C2
	,	eGL_TEXTURE_INDEX_3		= 0x84C3
	,	eGL_TEXTURE_INDEX_4		= 0x84C4
	,	eGL_TEXTURE_INDEX_5		= 0x84C5
	,	eGL_TEXTURE_INDEX_6		= 0x84C6
	,	eGL_TEXTURE_INDEX_7		= 0x84C7
	,	eGL_TEXTURE_INDEX_8		= 0x84C8
	,	eGL_TEXTURE_INDEX_9		= 0x84C9
	,	eGL_TEXTURE_INDEX_10	= 0x84CA
	,	eGL_TEXTURE_INDEX_11	= 0x84CB
	,	eGL_TEXTURE_INDEX_12	= 0x84CC
	,	eGL_TEXTURE_INDEX_13	= 0x84CD
	,	eGL_TEXTURE_INDEX_14	= 0x84CE
	,	eGL_TEXTURE_INDEX_15	= 0x84CF
	,	eGL_TEXTURE_INDEX_16	= 0x84D0
	,	eGL_TEXTURE_INDEX_17	= 0x84D1
	,	eGL_TEXTURE_INDEX_18	= 0x84D2
	,	eGL_TEXTURE_INDEX_19	= 0x84D3
	,	eGL_TEXTURE_INDEX_20	= 0x84D4
	,	eGL_TEXTURE_INDEX_21	= 0x84D5
	,	eGL_TEXTURE_INDEX_22	= 0x84D6
	,	eGL_TEXTURE_INDEX_23	= 0x84D7
	,	eGL_TEXTURE_INDEX_24	= 0x84D8
	,	eGL_TEXTURE_INDEX_25	= 0x84D9
	,	eGL_TEXTURE_INDEX_26	= 0x84DA
	,	eGL_TEXTURE_INDEX_27	= 0x84DB
	,	eGL_TEXTURE_INDEX_28	= 0x84DC
	,	eGL_TEXTURE_INDEX_29	= 0x84DD
	,	eGL_TEXTURE_INDEX_30	= 0x84DE
	,	eGL_TEXTURE_INDEX_31	= 0x84DF
	}	eGL_TEXTURE_INDEX;

	typedef enum eGL_BLEND_SOURCE
	{	eGL_BLEND_SOURCE_TEXTURE		= 0x1702
	,	eGL_BLEND_SOURCE_TEXTURE0		= 0x84C0
	,	eGL_BLEND_SOURCE_TEXTURE1		= 0x84C1
	,	eGL_BLEND_SOURCE_TEXTURE2		= 0x84C2
	,	eGL_BLEND_SOURCE_TEXTURE3		= 0x84C3
	,	eGL_BLEND_SOURCE_CONSTANT		= 0x8576
	,	eGL_BLEND_SOURCE_PRIMARY_COLOR	= 0x8577
	,	eGL_BLEND_SOURCE_PREVIOUS		= 0x8578
	}	eGL_BLEND_SOURCE;

	typedef enum eGL_BLEND_FUNC
	{	eGL_BLEND_FUNC_ADD			= 0x0104
	,	eGL_BLEND_FUNC_REPLACE		= 0x1E01
	,	eGL_BLEND_FUNC_MODULATE		= 0x2100
	,	eGL_BLEND_FUNC_SUBTRACT		= 0x84E7
	,	eGL_BLEND_FUNC_ADD_SIGNED	= 0x8574
	,	eGL_BLEND_FUNC_INTERPOLATE	= 0x8575
	,	eGL_BLEND_FUNC_DOT3_RGB		= 0x86AE
	,	eGL_BLEND_FUNC_DOT3_RGBA	= 0x86AF
	}	eGL_BLEND_FUNC;

	typedef enum eGL_BLEND_OP
	{	eGL_BLEND_OP_ADD			= 0x8006
	,	eGL_BLEND_OP_MIN			= 0x8007
	,	eGL_BLEND_OP_MAX			= 0x8008
	,	eGL_BLEND_OP_SUBTRACT		= 0x800A
	,	eGL_BLEND_OP_REV_SUBTRACT	= 0x800B
	}	eGL_BLEND_OP;

	typedef enum eGL_INTERNAL
	{	eGL_INTERNAL_1							= 1
	,	eGL_INTERNAL_2							= 2
	,	eGL_INTERNAL_3							= 3
	,	eGL_INTERNAL_4							= 4
	,	eGL_INTERNAL_LUMINANCE					= 0x1909
	,	eGL_INTERNAL_R3_G3_B2					= 0x2A10
	,	eGL_INTERNAL_ALPHA4						= 0x803B
	,	eGL_INTERNAL_ALPHA8						= 0x803C
	,	eGL_INTERNAL_ALPHA12					= 0x803D
	,	eGL_INTERNAL_ALPHA16					= 0x803E
	,	eGL_INTERNAL_COMPRESSED_ALPHA			= 0x84E9
	,	eGL_INTERNAL_COMPRESSED_LUMINANCE		= 0x84EA
	,	eGL_INTERNAL_COMPRESSED_LUMINANCE_ALPHA	= 0x84EB
	,	eGL_INTERNAL_COMPRESSED_INTENSITY		= 0x84EC
	,	eGL_INTERNAL_COMPRESSED_RGB				= 0x84ED
	,	eGL_INTERNAL_COMPRESSED_RGBA			= 0x84EE
	,	eGL_INTERNAL_LUMINANCE4					= 0x803F
	,	eGL_INTERNAL_LUMINANCE8					= 0x8040
	,	eGL_INTERNAL_LUMINANCE12				= 0x8041
	,	eGL_INTERNAL_LUMINANCE16				= 0x8042
	,	eGL_INTERNAL_LUMINANCE4_ALPHA4			= 0x8043
	,	eGL_INTERNAL_LUMINANCE6_ALPHA2			= 0x8044
	,	eGL_INTERNAL_LUMINANCE8_ALPHA8			= 0x8045
	,	eGL_INTERNAL_LUMINANCE12_ALPHA4			= 0x8046
	,	eGL_INTERNAL_LUMINANCE12_ALPHA12		= 0x8047
	,	eGL_INTERNAL_LUMINANCE16_ALPHA16		= 0x8048
	,	eGL_INTERNAL_INTENSITY					= 0x8049
	,	eGL_INTERNAL_INTENSITY4					= 0x804A
	,	eGL_INTERNAL_INTENSITY8					= 0x804B
	,	eGL_INTERNAL_INTENSITY12				= 0x804C
	,	eGL_INTERNAL_INTENSITY16				= 0x804D
	,	eGL_INTERNAL_RGB4						= 0x804F
	,	eGL_INTERNAL_RGB5						= 0x8050
	,	eGL_INTERNAL_RGB8						= 0x8051
	,	eGL_INTERNAL_RGB10						= 0x8052
	,	eGL_INTERNAL_RGB12						= 0x8053
	,	eGL_INTERNAL_RGB16						= 0x8054
	,	eGL_INTERNAL_RGBA2						= 0x8055
	,	eGL_INTERNAL_RGBA4						= 0x8056
	,	eGL_INTERNAL_RGB5_A1					= 0x8057
	,	eGL_INTERNAL_RGBA8						= 0x8058
	,	eGL_INTERNAL_RGB10_A2					= 0x8059
	,	eGL_INTERNAL_RGBA12						= 0x805A
	,	eGL_INTERNAL_RGBA16						= 0x805B
	,	eGL_INTERNAL_DEPTH_COMPONENT16			= 0x81A5
	,	eGL_INTERNAL_DEPTH_COMPONENT24			= 0x81A6
	,	eGL_INTERNAL_DEPTH_COMPONENT32			= 0x81A7
	,	eGL_INTERNAL_R8							= 0x8229
	,	eGL_INTERNAL_RG8						= 0x822B
	,	eGL_INTERNAL_RG16						= 0x822C
	,	eGL_INTERNAL_R16F						= 0x822D
	,	eGL_INTERNAL_R32F						= 0x822E
	,	eGL_INTERNAL_RG16F						= 0x822F
	,	eGL_INTERNAL_RG32F						= 0x8230
	,	eGL_INTERNAL_COMPRESSED_RGBA_S3TC_DXT1	= 0x83F1
	,	eGL_INTERNAL_COMPRESSED_RGBA_S3TC_DXT3	= 0x83F2
	,	eGL_INTERNAL_COMPRESSED_RGBA_S3TC_DXT5	= 0x83F3
	,	eGL_INTERNAL_RGBA32F					= 0x8814
	,	eGL_INTERNAL_RGB32F						= 0x8815
	,	eGL_INTERNAL_RGBA16F					= 0x881A
	,	eGL_INTERNAL_RGB16F						= 0x881B
	,	eGL_INTERNAL_DEPTH24_STENCIL8			= 0x88F0
	,	eGL_INTERNAL_SRGB						= 0x8C40
	,	eGL_INTERNAL_SRGB8						= 0x8C41
	,	eGL_INTERNAL_SRGB_ALPHA					= 0x8C42
	,	eGL_INTERNAL_SRGB8_ALPHA8				= 0x8C43
	,	eGL_INTERNAL_SLUMINANCE_ALPHA			= 0x8C44
	,	eGL_INTERNAL_SLUMINANCE8_ALPHA8			= 0x8C45
	,	eGL_INTERNAL_SLUMINANCE					= 0x8C46
	,	eGL_INTERNAL_SLUMINANCE8				= 0x8C47
	,	eGL_INTERNAL_DEPTH_COMPONENT32F			= 0x8CAC
	,	eGL_INTERNAL_STENCIL_INDEX1				= 0x8D46
	,	eGL_INTERNAL_STENCIL_INDEX4				= 0x8D47
	,	eGL_INTERNAL_STENCIL_INDEX8				= 0x8D48
	,	eGL_INTERNAL_STENCIL_INDEX16			= 0x8D49
	}	eGL_INTERNAL;

	typedef enum eGL_BUFFER_MODE
	{	eGL_BUFFER_MODE_STREAM_DRAW		= 0x88E0
	,	eGL_BUFFER_MODE_STREAM_READ		= 0x88E1
	,	eGL_BUFFER_MODE_STREAM_COPY		= 0x88E2
	,	eGL_BUFFER_MODE_STATIC_DRAW		= 0x88E4
	,	eGL_BUFFER_MODE_STATIC_READ		= 0x88E5
	,	eGL_BUFFER_MODE_STATIC_COPY		= 0x88E6
	,	eGL_BUFFER_MODE_DYNAMIC_DRAW	= 0x88E8
	,	eGL_BUFFER_MODE_DYNAMIC_READ	= 0x88E9
	,	eGL_BUFFER_MODE_DYNAMIC_COPY	= 0x88EA
	}	eGL_BUFFER_MODE;

	typedef enum eGL_COMPONENT
	{	eGL_COMPONENT_COLOR		= 0x1900
	,	eGL_COMPONENT_STENCIL	= 0x1901
	,	eGL_COMPONENT_DEPTH		= 0x1902
	}	eGL_COMPONENT;

	typedef enum eGL_BUFFER_TARGET
	{	eGL_BUFFER_TARGET_ARRAY			= 0x8892
	,	eGL_BUFFER_TARGET_ELEMENT_ARRAY	= 0x8893
	,	eGL_BUFFER_TARGET_PIXEL_PACK	= 0x88EB
	,	eGL_BUFFER_TARGET_PIXEL_UNPACK	= 0x88EC
	,	eGL_BUFFER_TARGET_TEXTURE		= 0x8C2A
	,	eGL_BUFFER_TARGET_UNIFORM		= 0x8A11//0x8DEE
	}	eGL_BUFFER_TARGET;

	typedef enum eGL_SHADER_TYPE
	{	eGL_SHADER_TYPE_FRAGMENT		= 0x8B30
	,	eGL_SHADER_TYPE_VERTEX			= 0x8B31
	,	eGL_SHADER_TYPE_GEOMETRY		= 0x8DD9
	,	eGL_SHADER_TYPE_TESS_EVALUATION	= 0x8E87
	,	eGL_SHADER_TYPE_TESS_CONTROL	= 0x8E88
	,	eGL_SHADER_TYPE_COMPUTE			= 0x91B9
	}	eGL_SHADER_TYPE;

	typedef enum eGL_LOCK
	{	eGL_LOCK_READ_ONLY	= 0x88B8
	,	eGL_LOCK_WRITE_ONLY	= 0x88B9
	,	eGL_LOCK_READ_WRITE	= 0x88BA
	}	eGL_LOCK;

	typedef enum eGL_LIGHT_COMPONENT
	{	eGL_LIGHT_COMPONENT_AMBIENT					= 0x1200
	,	eGL_LIGHT_COMPONENT_DIFFUSE					= 0x1201
	,	eGL_LIGHT_COMPONENT_SPECULAR				= 0x1202
	,	eGL_LIGHT_COMPONENT_POSITION				= 0x1203
	,	eGL_LIGHT_COMPONENT_SPOT_DIRECTION			= 0x1204
	,	eGL_LIGHT_COMPONENT_SPOT_EXPONENT			= 0x1205
	,	eGL_LIGHT_COMPONENT_SPOT_CUTOFF				= 0x1206
	,	eGL_LIGHT_COMPONENT_CONSTANT_ATTENUATION	= 0x1207
	,	eGL_LIGHT_COMPONENT_LINEAR_ATTENUATION		= 0x1208
	,	eGL_LIGHT_COMPONENT_QUADRATIC_ATTENUATION	= 0x1209
	}	eGL_LIGHT_COMPONENT;

	typedef enum eGL_MATERIAL_COMPONENT
	{	eGL_MATERIAL_COMPONENT_AMBIENT		= 0x1200
	,	eGL_MATERIAL_COMPONENT_DIFFUSE		= 0x1201
	,	eGL_MATERIAL_COMPONENT_SPECULAR		= 0x1202
	,	eGL_MATERIAL_COMPONENT_POSITION		= 0x1203
	,	eGL_MATERIAL_COMPONENT_EMISSION		= 0x1600
	,	eGL_MATERIAL_COMPONENT_SHININESS	= 0x1601
	}	eGL_MATERIAL_COMPONENT;

	typedef enum eGL_UNIFORM_NAME
	{	eGL_UNIFORM_SIZE			= 0x8A38
	,	eGL_UNIFORM_OFFSET			= 0x8A3B
	,	eGL_UNIFORM_BLOCK_DATA_SIZE	= 0x8A40
	}	eGL_UNIFORM_NAME;

	typedef enum eGL_CREATECONTEXT_ATTRIB
	{	eGL_CREATECONTEXT_ATTRIB_DEBUG_BIT				= 0x0001
	,	eGL_CREATECONTEXT_ATTRIB_FORWARD_COMPATIBLE_BIT	= 0x0002
	,	eGL_CREATECONTEXT_ATTRIB_MAJOR_VERSION			= 0x2091
	,	eGL_CREATECONTEXT_ATTRIB_MINOR_VERSION			= 0x2092
	,	eGL_CREATECONTEXT_ATTRIB_LAYER_PLANE			= 0x2093
	,	eGL_CREATECONTEXT_ATTRIB_FLAGS					= 0x2094
	}	eGL_CREATECONTEXT_ATTRIB;

	typedef enum eGL_PROFILE_ATTRIB
	{	eGL_PROFILE_ATTRIB_CORE_BIT				= 0x0001
	,	eGL_PROFILE_ATTRIB_COMPATIBILITY_BIT	= 0x0002
	,	eGL_PROFILE_ATTRIB_MASK					= 0x9126
	}	eGL_PROFILE_ATTRIB;

	typedef enum eGL_SHADER_STATUS
	{	eGL_SHADER_STATUS_DELETE			= 0x8B80
	,	eGL_SHADER_STATUS_COMPILE			= 0x8B81
	,	eGL_SHADER_STATUS_LINK				= 0x8B82
	,	eGL_SHADER_STATUS_VALIDATE			= 0x8B83
	,	eGL_SHADER_STATUS_INFO_LOG_LENGTH	= 0x8B84
	}	eGL_SHADER_STATUS;

	typedef enum eGL_TYPE
	{	eGL_TYPE_DEFAULT						= 0
	,	eGL_TYPE_BYTE							= 0x1400
	,	eGL_TYPE_UNSIGNED_BYTE					= 0x1401
	,	eGL_TYPE_SHORT							= 0x1402
	,	eGL_TYPE_UNSIGNED_SHORT					= 0x1403
	,	eGL_TYPE_INT							= 0x1404
	,	eGL_TYPE_UNSIGNED_INT					= 0x1405
	,	eGL_TYPE_FLOAT							= 0x1406
	,	eGL_TYPE_DOUBLE							= 0x140A
	,	eGL_TYPE_BITMAP							= 0X1A00
	,	eGL_TYPE_UNSIGNED_BYTE_3_3_2			= 0x8032
	,	eGL_TYPE_UNSIGNED_SHORT_4_4_4_4			= 0x8033
	,	eGL_TYPE_UNSIGNED_SHORT_5_5_5_1			= 0x8034
	,	eGL_TYPE_UNSIGNED_INT_8_8_8_8			= 0x8035
	,	eGL_TYPE_UNSIGNED_INT_10_10_10_2		= 0x8036
	,	eGL_TYPE_UNSIGNED_BYTE_2_3_3_REV		= 0x8362
	,	eGL_TYPE_UNSIGNED_SHORT_5_6_5			= 0x8363
	,	eGL_TYPE_UNSIGNED_SHORT_5_6_5_REV		= 0x8364
	,	eGL_TYPE_UNSIGNED_SHORT_4_4_4_4_REV		= 0x8365
	,	eGL_TYPE_UNSIGNED_SHORT_1_5_5_5_REV		= 0x8366
	,	eGL_TYPE_UNSIGNED_INT_8_8_8_8_REV		= 0x8367
	,	eGL_TYPE_UNSIGNED_INT_2_10_10_10_REV	= 0x8368
	,	eGL_TYPE_UNSIGNED_INT_24_8				= 0x84FA
#if CASTOR_USE_DOUBLE
	,	eGL_TYPE_REAL							= eGL_TYPE_DOUBLE
#else
	,	eGL_TYPE_REAL							= eGL_TYPE_FLOAT
#endif
	}	eGL_TYPE;

	typedef enum eGL_FORMAT
	{	eGL_FORMAT_STENCIL			= 0x1901
	,	eGL_FORMAT_DEPTH			= 0x1902
	,	eGL_FORMAT_RED				= 0x1903
	,	eGL_FORMAT_GREEN			= 0x1904
	,	eGL_FORMAT_BLUE				= 0x1905
	,	eGL_FORMAT_ALPHA			= 0x1906
	,	eGL_FORMAT_RGB				= 0x1907
	,	eGL_FORMAT_RGBA				= 0x1908
	,	eGL_FORMAT_LUMINANCE		= 0x1909
	,	eGL_FORMAT_LUMINANCE_ALPHA	= 0x190A
	,	eGL_FORMAT_BGR				= 0x80E0
	,	eGL_FORMAT_BGRA				= 0x80E1
	,	eGL_FORMAT_RG				= 0x8227
	,	eGL_FORMAT_DEPTH_STENCIL	= 0x84F9
	}	eGL_FORMAT;

	typedef enum eGL_TEXTURE_PARAMETER
	{	eGL_TEXTURE_PARAMETER_BORDERCOLOUR		= 0x1004
	,	eGL_TEXTURE_PARAMETER_MAG_FILTER		= 0x2800
	,	eGL_TEXTURE_PARAMETER_MIN_FILTER		= 0x2801
	,	eGL_TEXTURE_PARAMETER_WRAP_S			= 0x2802
	,	eGL_TEXTURE_PARAMETER_WRAP_T			= 0x2803
	,	eGL_TEXTURE_PARAMETER_WRAP_R			= 0x8072
	,	eGL_TEXTURE_PARAMETER_MINLOD			= 0x813A
	,	eGL_TEXTURE_PARAMETER_MAXLOD			= 0x813B
	,	eGL_TEXTURE_PARAMETER_GENERATE_MIPMAP	= 0x8191
	,	eGL_TEXTURE_PARAMETER_LODBIAS			= 0x8501
	}	eGL_TEXTURE_PARAMETER;

	typedef enum eGL_TEXENV_TARGET
	{	eGL_TEXENV_TARGET_TEXTURE_ENV		= 0x2300
	,	eGL_TEXENV_TARGET_POINT_SPRITE		= 0x8861
	}	eGL_TEXENV_TARGET;

	typedef enum eGL_TEXENV_ARGNAME
	{	eGL_TEXENV_ARGNAME_ALPHA_SCALE			= 0x0D1C
	,	eGL_TEXENV_ARGNAME_TEXTURE_ENV_MODE		= 0x2200
	,	eGL_TEXENV_ARGNAME_TEXTURE_ENV_COLOR	= 0x2201
	,	eGL_TEXENV_ARGNAME_COMBINE_RGB			= 0x8571
	,	eGL_TEXENV_ARGNAME_COMBINE_ALPHA		= 0x8572
	,	eGL_TEXENV_ARGNAME_RGB_SCALE			= 0x8573
	,	eGL_TEXENV_ARGNAME_SOURCE0_RGB			= 0x8580
	,	eGL_TEXENV_ARGNAME_SOURCE1_RGB			= 0x8581
	,	eGL_TEXENV_ARGNAME_SOURCE2_RGB			= 0x8582
	,	eGL_TEXENV_ARGNAME_SOURCE0_ALPHA		= 0x8588
	,	eGL_TEXENV_ARGNAME_SOURCE1_ALPHA		= 0x8589
	,	eGL_TEXENV_ARGNAME_SOURCE2_ALPHA		= 0x858A
	,	eGL_TEXENV_ARGNAME_OPERAND0_RGB			= 0x8590
	,	eGL_TEXENV_ARGNAME_OPERAND1_RGB			= 0x8591
	,	eGL_TEXENV_ARGNAME_OPERAND2_RGB			= 0x8592
	,	eGL_TEXENV_ARGNAME_OPERAND0_ALPHA		= 0x8598
	,	eGL_TEXENV_ARGNAME_OPERAND1_ALPHA		= 0x8599
	,	eGL_TEXENV_ARGNAME_OPERAND2_ALPHA		= 0x859A
	,	eGL_TEXENV_ARGNAME_COORD_REPLACE		= 0x8862
	}	eGL_TEXENV_ARGNAME;

	typedef enum eGL_TEXENV_PARAM
	{	eGL_TEXENV_PARAM_ADD					= 0x0104
	,	eGL_TEXENV_PARAM_BLEND					= 0x0BE2
	,	eGL_TEXENV_PARAM_TEXTURE				= 0x1702
	,	eGL_TEXENV_PARAM_REPLACE				= 0x1E01
	,	eGL_TEXENV_PARAM_MODULATE				= 0x2100
	,	eGL_TEXENV_PARAM_DECAL					= 0x2101
	,	eGL_TEXENV_PARAM_SRC_COLOR				= 0x0300
	,	eGL_TEXENV_PARAM_ONE_MINUS_SRC_COLOR	= 0x0301
	,	eGL_TEXENV_PARAM_SRC_ALPHA				= 0x0302
	,	eGL_TEXENV_PARAM_ONE_MINUS_SRC_ALPHA	= 0x0303
	,	eGL_TEXENV_PARAM_SUBTRACT				= 0x84E7
	,	eGL_TEXENV_PARAM_COMBINE				= 0x8570
	,	eGL_TEXENV_PARAM_ADD_SIGNED				= 0x8574
	,	eGL_TEXENV_PARAM_INTERPOLATE			= 0x8575
	,	eGL_TEXENV_PARAM_CONSTANT				= 0x8576
	,	eGL_TEXENV_PARAM_PRIMARY_COLOR			= 0x8577
	,	eGL_TEXENV_PARAM_PREVIOUS				= 0x8578
	,	eGL_TEXENV_PARAM_DOT3_RGB				= 0x86AE
	,	eGL_TEXENV_PARAM_DOT3_RGBA				= 0x86AF
	}	eGL_TEXENV_PARAM;

	typedef enum eGL_TEXGEN_COORD
	{	eGL_TEXGEN_COORD_S	= 0x2000
	,	eGL_TEXGEN_COORD_T	= 0x2001
	,	eGL_TEXGEN_COORD_R	= 0x2002
	,	eGL_TEXGEN_COORD_Q	= 0x2003
	}	eGL_TEXGEN_COORD;

	typedef enum eGL_TEXGEN_PARAM
	{	eGL_TEXGEN_PARAM_TEXTURE_GEN_MODE	= 0x2500
	,	eGL_TEXGEN_PARAM_OBJECT_PLANE		= 0x2501
	,	eGL_TEXGEN_PARAM_EYE_PLANE			= 0x2502
	}	eGL_TEXGEN_PARAM;

	typedef enum eGL_TEXGEN_MODE
	{	eGL_TEXGEN_MODE_SPHERE_MAP		= 0x2402
	,	eGL_TEXGEN_MODE_NORMAL_MAP		= 0x8511
	,	eGL_TEXGEN_MODE_REFLECTION_MAP	= 0x8512
	,	eGL_TEXGEN_MODE_CUBE_MAP		= 0x8513
	}	eGL_TEXGEN_MODE;

	typedef enum eGL_BOOLEAN
	{	eGL_FALSE	= 0
	,	eGL_TRUE	= 1
	}	eGL_BOOLEAN;

	typedef enum eGL_LIGHT_MODEL_PARAM
	{	eGL_LIGHT_MODEL_PARAM_LOCAL_VIEWER				= 0x0B51
	,	eGL_LIGHT_MODEL_PARAM_COLOR_CONTROL				= 0x81F8
	,	eGL_LIGHT_MODEL_PARAM_SEPARATE_SPECULAR_COLOR	= 0x81FA
	}	eGL_LIGHT_MODEL_PARAM;

	typedef enum eGL_SHADE_MODEL
	{	eGL_SHADE_MODEL_FLAT					= 0x1D00
	,	eGL_SHADE_MODEL_SMOOTH					= 0x1D01
	}	eGL_SHADE_MODEL;

	typedef enum eGL_TWEAK
	{	eGL_TWEAK_LINE_SMOOTH				= 0x0B20
	,	eGL_TWEAK_CULL_FACE					= 0x0B44
	,	eGL_TWEAK_LIGHTING					= 0x0B50
	,	eGL_TWEAK_FOG						= 0x0B60
	,	eGL_TWEAK_DEPTH_TEST				= 0x0B71
	,	eGL_TWEAK_STENCIL_TEST				= 0x0B90
	,	eGL_TWEAK_NORMALIZE					= 0x0BA1
	,	eGL_TWEAK_ALPHA_TEST				= 0x0BC0
	,	eGL_TWEAK_DITHER					= 0x0BD0
	,	eGL_TWEAK_BLEND						= 0x0BE2
	,	eGL_TWEAK_SCISSOR_TEST				= 0x0C11
	,	eGL_TWEAK_TEXTURE_GEN_S				= 0x0C60
	,	eGL_TWEAK_TEXTURE_GEN_T				= 0x0C61
	,	eGL_TWEAK_TEXTURE_GEN_R				= 0x0C62
	,	eGL_TWEAK_TEXTURE_GEN_Q				= 0x0C63
	,	eGL_TWEAK_MULTISAMPLE				= 0x809D
	,	eGL_TWEAK_ALPHA_TO_COVERAGE			= 0x809E
	,	eGL_TWEAK_DEBUG_OUTPUT_SYNCHRONOUS	= 0x8242
	,	eGL_TWEAK_DEPTH_CLAMP				= 0x864F
	}	eGL_TWEAK;

	typedef enum eGL_RENDER_MODE
	{	eGL_RENDER_MODE_RENDER     = 0x1C00
	,	eGL_RENDER_MODE_FEEDBACK   = 0x1C01
	,	eGL_RENDER_MODE_SELECT     = 0x1C02
	}	eGL_RENDER_MODE;

	typedef enum eGL_FRAMEBUFFER_STATUS
	{	eGL_FRAMEBUFFER_COMPLETE						= 0x8CD5
	,	eGL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT			= 0x8CD6
	,	eGL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT	= 0x8CD7
	,	eGL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER			= 0x8CDB
	,	eGL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER			= 0x8CDC
	,	eGL_FRAMEBUFFER_UNSUPPORTED						= 0x8CDD
	,	eGL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE			= 0x8D56
	,	eGL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS		= 0x8DA8
	}	eGL_FRAMEBUFFER_STATUS;

	typedef enum eGL_TEXTURE_ATTACHMENT
	{	eGL_TEXTURE_ATTACHMENT_NONE		= 0
	,	eGL_TEXTURE_ATTACHMENT_COLOR0	= 0x8CE0
	,	eGL_TEXTURE_ATTACHMENT_COLOR1	= 0x8CE1
	,	eGL_TEXTURE_ATTACHMENT_COLOR2	= 0x8CE2
	,	eGL_TEXTURE_ATTACHMENT_COLOR3	= 0x8CE3
	,	eGL_TEXTURE_ATTACHMENT_COLOR4	= 0x8CE4
	,	eGL_TEXTURE_ATTACHMENT_COLOR5	= 0x8CE5
	,	eGL_TEXTURE_ATTACHMENT_COLOR6	= 0x8CE6
	,	eGL_TEXTURE_ATTACHMENT_COLOR7	= 0x8CE7
	,	eGL_TEXTURE_ATTACHMENT_COLOR8	= 0x8CE8
	,	eGL_TEXTURE_ATTACHMENT_COLOR9	= 0x8CE9
	,	eGL_TEXTURE_ATTACHMENT_COLOR10	= 0x8CEA
	,	eGL_TEXTURE_ATTACHMENT_COLOR11	= 0x8CEB
	,	eGL_TEXTURE_ATTACHMENT_COLOR12	= 0x8CEC
	,	eGL_TEXTURE_ATTACHMENT_COLOR13	= 0x8CED
	,	eGL_TEXTURE_ATTACHMENT_COLOR14	= 0x8CEE
	,	eGL_TEXTURE_ATTACHMENT_COLOR15	= 0x8CEF
	,	eGL_TEXTURE_ATTACHMENT_DEPTH	= 0x8D00
	,	eGL_TEXTURE_ATTACHMENT_STENCIL	= 0x8D20
	}	eGL_TEXTURE_ATTACHMENT;

	typedef enum eGL_FRAMEBUFFER_MODE
	{	eGL_FRAMEBUFFER_MODE_READ		= 0x8CA8
	,	eGL_FRAMEBUFFER_MODE_DRAW		= 0x8CA9
	,	eGL_FRAMEBUFFER_MODE_DEFAULT	= 0x8D40
	}	eGL_FRAMEBUFFER_MODE;

	typedef enum eGL_RENDERBUFFER_MODE
	{	eGL_RENDERBUFFER_MODE_DEFAULT	= 0x8D41
	}	eGL_RENDERBUFFER_MODE;

	typedef enum eGL_RENDERBUFFER_ATTACHMENT
	{	eGL_RENDERBUFFER_ATTACHMENT_NONE	= 0
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR0	= 0x8CE0
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR1	= 0x8CE1
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR2	= 0x8CE2
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR3	= 0x8CE3
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR4	= 0x8CE4
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR5	= 0x8CE5
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR6	= 0x8CE6
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR7	= 0x8CE7
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR8	= 0x8CE8
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR9	= 0x8CE9
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR10	= 0x8CEA
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR11	= 0x8CEB
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR12	= 0x8CEC
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR13	= 0x8CED
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR14	= 0x8CEE
	,	eGL_RENDERBUFFER_ATTACHMENT_COLOR15	= 0x8CEF
	,	eGL_RENDERBUFFER_ATTACHMENT_DEPTH	= 0x8D00
	,	eGL_RENDERBUFFER_ATTACHMENT_STENCIL	= 0x8D20
	}	eGL_RENDERBUFFER_ATTACHMENT;

	typedef enum eGL_RENDERBUFFER_PARAMETER
	{	eGL_RENDERBUFFER_PARAMETER_WIDTH			= 0x8D42
	,	eGL_RENDERBUFFER_PARAMETER_HEIGHT			= 0x8D43
	,	eGL_RENDERBUFFER_PARAMETER_INTERNAL_FORMAT	= 0x8D44
	,	eGL_RENDERBUFFER_PARAMETER_RED_SIZE			= 0x8D50
	,	eGL_RENDERBUFFER_PARAMETER_GREEN_SIZE		= 0x8D51
	,	eGL_RENDERBUFFER_PARAMETER_BLUE_SIZE		= 0x8D52
	,	eGL_RENDERBUFFER_PARAMETER_ALPHA_SIZE		= 0x8D53
	,	eGL_RENDERBUFFER_PARAMETER_DEPTH_SIZE		= 0x8D54
	,	eGL_RENDERBUFFER_PARAMETER_STENCIL_SIZE		= 0x8D55
	}	eGL_RENDERBUFFER_PARAMETER;

	typedef enum eGL_RENDERBUFFER_STORAGE
	{	eGL_RENDERBUFFER_STORAGE_L8			= 0x8229
	,	eGL_RENDERBUFFER_STORAGE_L16F		= 0x822D
	,	eGL_RENDERBUFFER_STORAGE_L32F		= 0x822E
	,	eGL_RENDERBUFFER_STORAGE_A8L8		= 0x822C
	,	eGL_RENDERBUFFER_STORAGE_AL16F		= 0x822F
	,	eGL_RENDERBUFFER_STORAGE_AL32F		= 0x8230
	,	eGL_RENDERBUFFER_STORAGE_RGB5_A1	= 0x8057
	,	eGL_RENDERBUFFER_STORAGE_RGBA4		= 0x8056
	,	eGL_RENDERBUFFER_STORAGE_RGB565		= 0x8D62
	,	eGL_RENDERBUFFER_STORAGE_RGB8		= 0x8051
	,	eGL_RENDERBUFFER_STORAGE_RGBA8		= 0x8058
	,	eGL_RENDERBUFFER_STORAGE_RGB16F		= 0x881B
	,	eGL_RENDERBUFFER_STORAGE_RGBA16F	= 0x881A
	,	eGL_RENDERBUFFER_STORAGE_RGB32F		= 0x8815
	,	eGL_RENDERBUFFER_STORAGE_RGBA32F	= 0x8814
	,	eGL_RENDERBUFFER_STORAGE_DXTC1		= 0x83F1
	,	eGL_RENDERBUFFER_STORAGE_DXTC3		= 0x83F2
	,	eGL_RENDERBUFFER_STORAGE_DXTC5		= 0x83F3
	,	eGL_RENDERBUFFER_STORAGE_DEPTH16	= 0x81A5
	,	eGL_RENDERBUFFER_STORAGE_DEPTH24	= 0x81A6
	,	eGL_RENDERBUFFER_STORAGE_DEPTH32	= 0x81A7
	,	eGL_RENDERBUFFER_STORAGE_STENCIL1	= 0x8D46
	,	eGL_RENDERBUFFER_STORAGE_STENCIL4	= 0x8D47
	,	eGL_RENDERBUFFER_STORAGE_STENCIL8	= 0x8D48
	,	eGL_RENDERBUFFER_STORAGE_STENCIL16	= 0x8D49
	}	eGL_RENDERBUFFER_STORAGE;

	typedef enum eGL_FRONT_FACE_DIRECTION
	{	eGL_FRONT_FACE_DIRECTION_CW     = 0x0900
	,	eGL_FRONT_FACE_DIRECTION_CCW    = 0x0901
	}	eGL_FRONT_FACE_DIRECTION;

	typedef enum eGL_DRAW_BUFFER_MODE
	{	eGL_DRAW_BUFFER_MODE_NONE           = 0
	,	eGL_DRAW_BUFFER_MODE_FRONT_LEFT     = 0x0400
	,	eGL_DRAW_BUFFER_MODE_FRONT_RIGHT    = 0x0401
	,	eGL_DRAW_BUFFER_MODE_BACK_LEFT      = 0x0402
	,	eGL_DRAW_BUFFER_MODE_BACK_RIGHT     = 0x0403
	,	eGL_DRAW_BUFFER_MODE_FRONT          = 0x0404
	,	eGL_DRAW_BUFFER_MODE_BACK           = 0x0405
	,	eGL_DRAW_BUFFER_MODE_LEFT           = 0x0406
	,	eGL_DRAW_BUFFER_MODE_RIGHT          = 0x0407
	,	eGL_DRAW_BUFFER_MODE_FRONT_AND_BACK = 0x0408
	,	eGL_DRAW_BUFFER_MODE_AUX0           = 0x0409
	,	eGL_DRAW_BUFFER_MODE_AUX1           = 0x040A
	,	eGL_DRAW_BUFFER_MODE_AUX2           = 0x040B
	,	eGL_DRAW_BUFFER_MODE_AUX3           = 0x040C
	}	eGL_DRAW_BUFFER_MODE;

	typedef enum eGL_MATRIX_TYPE CASTOR_TYPE( uint32_t )
	{	eGL_MATRIX_TYPE_MODELVIEW			= 0x1700
	,	eGL_MATRIX_TYPE_PROJECTION			= 0x1701
	,	eGL_MATRIX_TYPE_TEXTURE				= 0x1702
	}	eGL_MATRIX_TYPE;

	typedef enum eGL_MATRIX CASTOR_TYPE( uint32_t )
	{	eGL_MATRIX_MODELVIEW	= 0x0BA6
	,	eGL_MATRIX_PROJECTION	= 0x0BA7
	,	eGL_MATRIX_TEXTURE		= 0x0BA8
	}	eGL_MATRIX;

	typedef enum eGL_GETINTEGER_PARAM
	{	eGL_GETINTEGER_PARAM_VIEWPORT						= 0x0BA2
	,	eGL_GETINTEGER_PARAM_MAX_GEOMETRY_OUTPUT_VERTICES	= 0x8DE0
	}	eGL_GETINTEGER_PARAM;

	typedef enum eGL_PROGRAM_PARAM
	{	eGL_PROGRAM_PARAM_GEOMETRY_VERTICES_OUT	= 0x8DDA//0x8916
	,	eGL_PROGRAM_PARAM_GEOMETRY_INPUT_TYPE	= 0x8DDB//0x8917
	,	eGL_PROGRAM_PARAM_GEOMETRY_OUTPUT_TYPE	= 0x8DDC//0x8918
	}	eGL_PROGRAM_PARAM;

	typedef enum eGL_BUFFER_BIT
	{	eGL_BUFFER_BIT_COLOR		= 0x00004000
	,	eGL_BUFFER_BIT_DEPTH		= 0x00000100
	,	eGL_BUFFER_BIT_STENCIL		= 0x00000400
	}	eGL_BUFFER_BIT;

	typedef enum eGL_OTHERS CASTOR_TYPE( uint32_t )
	{	eGL_INVALID_INDEX			= 0xFFFFFFFF
	}	eGL_OTHERS;

	typedef enum eGL_BUFFER_MAPPING_BIT
	{	eGL_BUFFER_MAPPING_BIT_READ					= 0x0001
	,	eGL_BUFFER_MAPPING_BIT_WRITE				= 0x0002
	,	eGL_BUFFER_MAPPING_BIT_INVALIDATE_RANGE		= 0x0004
	,	eGL_BUFFER_MAPPING_BIT_INVALIDATE_BUFFER	= 0x0008
	,	eGL_BUFFER_MAPPING_BIT_FLUSH_EXPLICIT		= 0x0010
	,	eGL_BUFFER_MAPPING_BIT_UNSYNCHRONIZED		= 0x0020
	}	eGL_BUFFER_MAPPING_BIT;

	typedef enum eGL_FACE
	{	eGL_FACE_FRONT			= 0x0404
	,	eGL_FACE_BACK			= 0x0405
	,	eGL_FACE_FRONT_AND_BACK	= 0x0408
	}	eGL_FACE;

	typedef enum eGL_STENCIL_OP
	{	eGL_STENCIL_OP_ZERO			= 0
	,	eGL_STENCIL_OP_INVERT		= 0x150A
	,	eGL_STENCIL_OP_KEEP			= 0x1E00
	,	eGL_STENCIL_OP_REPLACE		= 0x1E01
	,	eGL_STENCIL_OP_INCR			= 0x1E02
	,	eGL_STENCIL_OP_DECR			= 0x1E03
	,	eGL_STENCIL_OP_INCR_WRAP	= 0x8507
	,	eGL_STENCIL_OP_DECR_WRAP	= 0x8508
	}	eGL_STENCIL_OP;

	typedef enum eGL_FILL_MODE
	{	eGL_FILL_MODE_POINT				= 0x1B00
	,	eGL_FILL_MODE_LINE				= 0x1B01
	,	eGL_FILL_MODE_FILL				= 0x1B02
	}	eGL_FILL_MODE;

	typedef enum eGL_SAMPLER_PARAMETER
	{	eGL_SAMPLER_PARAMETER_BORDERCOLOUR	= 0x1004
	,	eGL_SAMPLER_PARAMETER_MAGFILTER		= 0x2800
	,	eGL_SAMPLER_PARAMETER_MINFILTER		= 0x2801
	,	eGL_SAMPLER_PARAMETER_UWRAP			= 0x2802
	,	eGL_SAMPLER_PARAMETER_VWRAP			= 0x2803
	,	eGL_SAMPLER_PARAMETER_WWRAP			= 0x8072
	,	eGL_SAMPLER_PARAMETER_MINLOD		= 0x813A
	,	eGL_SAMPLER_PARAMETER_MAXLOD		= 0x813B
	,	eGL_SAMPLER_PARAMETER_MAXANISOTROPY	= 0x84FE
	,	eGL_SAMPLER_PARAMETER_LODBIAS		= 0x8501
	}	eGL_SAMPLER_PARAMETER;

	typedef enum eGL_DEBUG_TYPE CASTOR_TYPE( uint32_t )
	{	eGL_DEBUG_TYPE_ERROR				= 0x824C
	,	eGL_DEBUG_TYPE_DEPRECATED_BEHAVIOR	= 0x824D
	,	eGL_DEBUG_TYPE_UNDEFINED_BEHAVIOR	= 0x824E
	,	eGL_DEBUG_TYPE_PORTABILITY			= 0x824F
	,	eGL_DEBUG_TYPE_PERFORMANCE			= 0x8250
	,	eGL_DEBUG_TYPE_OTHER				= 0x8251
	}	eGL_DEBUG_TYPE;

	typedef enum eGL_DEBUG_SOURCE CASTOR_TYPE( uint32_t )
	{	eGL_DEBUG_SOURCE_API                = 0x8246
	,	eGL_DEBUG_SOURCE_WINDOW_SYSTEM      = 0x8247
	,	eGL_DEBUG_SOURCE_SHADER_COMPILER    = 0x8248
	,	eGL_DEBUG_SOURCE_THIRD_PARTY        = 0x8249
	,	eGL_DEBUG_SOURCE_APPLICATION        = 0x824A
	,	eGL_DEBUG_SOURCE_OTHER				= 0x824B
	}	eGL_DEBUG_SOURCE;

	typedef enum eGL_DEBUG_CATEGORY CASTOR_TYPE( uint32_t )
	{	eGL_DEBUG_CATEGORY_API_ERROR			= 0x9149
	,	eGL_DEBUG_CATEGORY_WINDOW_SYSTEM		= 0x914A
	,	eGL_DEBUG_CATEGORY_DEPRECATION			= 0x914B
	,	eGL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR	= 0x914C
	,	eGL_DEBUG_CATEGORY_PERFORMANCE			= 0x914D
	,	eGL_DEBUG_CATEGORY_SHADER_COMPILER		= 0x914E
	,	eGL_DEBUG_CATEGORY_APPLICATION			= 0x914F
	,	eGL_DEBUG_CATEGORY_OTHER				= 0x9150
	}	eGL_DEBUG_CATEGORY;

	typedef enum eGL_DEBUG_SEVERITY CASTOR_TYPE( uint32_t )
	{	eGL_DEBUG_SEVERITY_HIGH		= 0x9146
	,	eGL_DEBUG_SEVERITY_MEDIUM	= 0x9147
	,	eGL_DEBUG_SEVERITY_LOW		= 0x9148
	}	eGL_DEBUG_SEVERITY;

	typedef enum eGL_MAX CASTOR_TYPE( uint32_t )
	{	eGL_MAX_TEXTURE_SIZE						= 0x0D33
	,	eGL_MAX_ELEMENTS_VERTICES					= 0x80E8
	,	eGL_MAX_ELEMENTS_INDICES					= 0x80E9
	,	eGL_MAX_COMPUTE_SHARED_MEMORY_SIZE			= 0x8262
	,	eGL_MAX_COMPUTE_UNIFORM_COMPONENTS			= 0x8263
	,	eGL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS		= 0x8264
	,	eGL_MAX_COMPUTE_ATOMIC_COUNTERS				= 0x8265
	,	eGL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS = 0x8266
	,	eGL_MAX_RENDERBUFFER_SIZE					= 0x84E8
	,	eGL_MAX_TEXTURE_LOD_BIAS					= 0x84FD
	,	eGL_MAX_RECTANGLE_TEXTURE_SIZE				= 0x84F8
	,	eGL_MAX_TEXTURE_UNITS						= 0x84E2
	,	eGL_MAX_CUBE_MAP_TEXTURE_SIZE				= 0x851C
	,	eGL_MAX_DRAW_BUFFERS						= 0x8824
	,	eGL_MAX_VERTEX_ATTRIBS						= 0x8869
	,	eGL_MAX_TEXTURE_COORDS						= 0x8871
	,	eGL_MAX_TEXTURE_IMAGE_UNITS					= 0x8872
	,	eGL_MAX_FRAGMENT_UNIFORM_COMPONENTS			= 0x8B49
	,	eGL_MAX_VERTEX_UNIFORM_COMPONENTS			= 0x8B4A
	,	eGL_MAX_VARYING_FLOATS						= 0x8B4B
	,	eGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS			= 0x8B4C
	,	eGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS		= 0x8B4D
	,	eGL_MAX_TEXTURE_BUFFER_SIZE					= 0x8C2B
	,	eGL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS		= 0x8C29
	,	eGL_MAX_COLOR_ATTACHMENTS					= 0x8CDF
	,	eGL_MAX_SAMPLES								= 0x8D57
	,	eGL_MAX_GEOMETRY_UNIFORM_COMPONENTS			= 0x8DDF
	,	eGL_MAX_GEOMETRY_OUTPUT_VERTICES			= 0x8DE0
	,	eGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS	= 0x8DE1
	,	eGL_MAX_VERTEX_OUTPUT_COMPONENTS			= 0x9122
	,	eGL_MAX_GEOMETRY_INPUT_COMPONENTS			= 0x9123
	,	eGL_MAX_GEOMETRY_OUTPUT_COMPONENTS			= 0x9124
	,	eGL_MAX_FRAGMENT_INPUT_COMPONENTS			= 0x9125
	,	eGL_MAX_DEBUG_MESSAGE_LENGTH_ARB			= 0x9143
	,	eGL_MAX_DEBUG_LOGGED_MESSAGES_ARB			= 0x9144
	,	eGL_MAX_COMPUTE_UNIFORM_BLOCKS				= 0x91BB
	,	eGL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS			= 0x91BC
	,	eGL_MAX_COMPUTE_IMAGE_UNIFORMS				= 0x91BD
	,	eGL_MAX_COMPUTE_WORK_GROUP_COUNT			= 0x91BE
	,	eGL_MAX_COMPUTE_WORK_GROUP_SIZE				= 0x91BF
	,	eGL_MAX_FRAMEBUFFER_WIDTH					= 0x9315
	,	eGL_MAX_FRAMEBUFFER_HEIGHT					= 0x9316
	,	eGL_MAX_FRAMEBUFFER_LAYERS					= 0x9317
	,	eGL_MAX_FRAMEBUFFER_SAMPLES					= 0x9318
	}	eGL_MAX;

	typedef enum eGL_HINT
	{	eGL_HINT_LINE_SMOOTH			= 0x0C52
	,	eGL_HINT_POLYGON_SMOOTH			= 0x0C53
	,	eGL_HINT_VOLUME_CLIPPING		= 0x80F0
	,	eGL_HINT_TEXTURE_COMPRESSION	= 0x84EF
	,	eGL_HINT_SHADER_DERIVATIVE		= 0x8B8B
	}	eGL_HINT;

	typedef enum eGL_HINT_VALUE
	{	eGL_HINT_VALUE_DONTCARE	= 0x1100
	,	eGL_HINT_VALUE_FASTEST	= 0x1101
	,	eGL_HINT_VALUE_NICEST	= 0x1102
	}	eGL_HINT_VALUE;

	typedef enum eGL_STORAGE_MODE CASTOR_TYPE( uint32_t )
	{	eGL_STORAGE_MODE_UNPACK_SWAP_BYTES		= 0x0CF0
	,	eGL_STORAGE_MODE_UNPACK_LSB_FIRST		= 0x0CF1
	,	eGL_STORAGE_MODE_UNPACK_ROW_LENGTH		= 0x0CF2
	,	eGL_STORAGE_MODE_UNPACK_SKIP_ROWS		= 0x0CF3
	,	eGL_STORAGE_MODE_UNPACK_SKIP_PIXELS		= 0x0CF4
	,	eGL_STORAGE_MODE_UNPACK_ALIGNMENT		= 0x0CF5
	,	eGL_STORAGE_MODE_PACK_SWAP_BYTES		= 0x0D00
	,	eGL_STORAGE_MODE_PACK_LSB_FIRST			= 0x0D01
	,	eGL_STORAGE_MODE_PACK_ROW_LENGTH		= 0x0D02
	,	eGL_STORAGE_MODE_PACK_SKIP_ROWS			= 0x0D03
	,	eGL_STORAGE_MODE_PACK_SKIP_PIXELS		= 0x0D04
	,	eGL_STORAGE_MODE_PACK_ALIGNMENT			= 0x0D05
	,	eGL_STORAGE_MODE_PACK_IMAGE_HEIGHT		= 0x806C
	,	eGL_STORAGE_MODE_UNPACK_IMAGE_HEIGHT	= 0x806E
	}	eGL_STORAGE_MODE;

// #define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB               0x9143
// #define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB              0x9144
// #define GL_DEBUG_LOGGED_MESSAGES_ARB                  0x9145
// #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB       0x8243
// #define GL_DEBUG_CALLBACK_FUNCTION_ARB                0x8244
// #define GL_DEBUG_CALLBACK_USER_PARAM_ARB              0x8245

	class OpenGl;

	class MtxFunctionsBase
	{
	protected:
		OpenGl & m_gl;

	public:
		MtxFunctionsBase( OpenGl & p_gl );
		virtual bool MatrixMode( eGL_MATRIX_TYPE mode )=0;
		virtual bool LoadIdentity()=0;
		virtual bool Ortho( double left, double right, double bottom, double top, double zNear, double zFar )=0;
		virtual bool Frustum( double left, double right, double bottom, double top, double zNear, double zFar )=0;
		virtual bool PushMatrix()=0;
		virtual bool PopMatrix()=0;
		virtual bool Translate( real x, real y, real z )=0;
		virtual bool Rotate( real angle, real x, real y, real z )=0;
		virtual bool Scale( real x, real y, real z )=0;
		virtual bool MultMatrix( real const * matrix )=0;
	};

	class MtxFunctions : public MtxFunctionsBase
	{
	public:
		std::function< void	( uint32_t mode ) > m_pfnMatrixMode;
		std::function< void	() > m_pfnLoadIdentity;
#if CASTOR_HAS_VARIADIC_TEMPLATES
		std::function< void	( double left, double right, double bottom, double top, double zNear, double zFar ) > m_pfnOrtho;
		std::function< void	( double left, double right, double bottom, double top, double zNear, double zFar ) > m_pfnFrustum;
#else
		void (CALLBACK * m_pfnOrtho)( double left, double right, double bottom, double top, double zNear, double zFar );
		void (CALLBACK * m_pfnFrustum)( double left, double right, double bottom, double top, double zNear, double zFar );
#endif
		std::function< void	() > m_pfnPushMatrix;
		std::function< void	() > m_pfnPopMatrix;
		std::function< void	( real x, real y, real z ) > m_pfnTranslate;
		std::function< void	( real angle, real x, real y, real z ) > m_pfnRotate;
		std::function< void	( real x, real y, real z ) > m_pfnScale;
		std::function< void	( real const * matrix ) > m_pfnMultMatrix;

		MtxFunctions( OpenGl & p_gl );
		virtual bool MatrixMode( eGL_MATRIX_TYPE mode );
		virtual bool LoadIdentity();
		virtual bool Ortho( double left, double right, double bottom, double top, double zNear, double zFar );
		virtual bool Frustum( double left, double right, double bottom, double top, double zNear, double zFar );
		virtual bool PushMatrix();
		virtual bool PopMatrix();
		virtual bool Translate( real x, real y, real z );
		virtual bool Rotate( real angle, real x, real y, real z );
		virtual bool Scale( real x, real y, real z );
		virtual bool MultMatrix( real const * matrix );
	};

	class MtxFunctionsDSA : public MtxFunctionsBase
	{
	public:
		eGL_MATRIX_TYPE					m_eMatrixMode;
		std::function< void	( uint32_t mtxMode ) > m_pfnMatrixLoadIdentity;
#if CASTOR_HAS_VARIADIC_TEMPLATES
		std::function< void	( uint32_t mtxMode, double left, double right, double bottom, double top, double zNear, double zFar ) > m_pfnMatrixOrtho;
		std::function< void	( uint32_t mtxMode, double left, double right, double bottom, double top, double zNear, double zFar ) > m_pfnMatrixFrustum;
#else
		void (CALLBACK * m_pfnMatrixOrtho)( uint32_t mtxMode, double left, double right, double bottom, double top, double zNear, double zFar );
		void (CALLBACK * m_pfnMatrixFrustum)( uint32_t mtxMode, double left, double right, double bottom, double top, double zNear, double zFar );
#endif
		std::function< void	( uint32_t mtxMode ) > m_pfnMatrixPush;
		std::function< void	( uint32_t mtxMode ) > m_pfnMatrixPop;
#if CASTOR_USE_DOUBLE
		std::function< void	( uint32_t mtxMode, real x, real y, real z ) > m_pfnMatrixTranslated;
		std::function< void	( uint32_t mtxMode, real angle, real x, real y, real z ) > m_pfnMatrixRotated;
		std::function< void	( uint32_t mtxMode, real x, real y, real z ) > m_pfnMatrixScaled;
		std::function< void	( uint32_t mtxMode, real const * matrix ) > m_pfnMatrixMultd;
#else
		std::function< void	( uint32_t mtxMode, real x, real y, real z ) > m_pfnMatrixTranslatef;
		std::function< void	( uint32_t mtxMode, real angle, real x, real y, real z ) > m_pfnMatrixRotatef;
		std::function< void	( uint32_t mtxMode, real x, real y, real z ) > m_pfnMatrixScalef;
		std::function< void	( uint32_t mtxMode, real const * matrix ) > m_pfnMatrixMultf;
#endif

		MtxFunctionsDSA( OpenGl & p_gl );
		virtual bool MatrixMode( eGL_MATRIX_TYPE mode ) { m_eMatrixMode = mode;return true; }
		virtual bool LoadIdentity();
		virtual bool Ortho( double left, double right, double bottom, double top, double zNear, double zFar );
		virtual bool Frustum( double left, double right, double bottom, double top, double zNear, double zFar );
		virtual bool PushMatrix();
		virtual bool PopMatrix();
		virtual bool Translate( real x, real y, real z );
		virtual bool Rotate( real angle, real x, real y, real z );
		virtual bool Scale( real x, real y, real z );
		virtual bool MultMatrix( real const * matrix );
	};

	class TexFunctionsBase
	{
	protected:
		OpenGl & m_gl;

	public:
		TexFunctionsBase( OpenGl & p_gl );
		virtual bool GenerateMipmap( eGL_TEXDIM p_eTarget )=0;
		virtual bool BindTexture( eGL_TEXDIM p_eTarget, uint32_t texture )=0;
		virtual bool TexSubImage1D( eGL_TEXDIM p_eTarget, int level, int xoffset, int width, eGL_FORMAT format, eGL_TYPE type, void const * data )=0;
		virtual bool TexSubImage2D( eGL_TEXDIM p_eTarget, int level, int xoffset, int yoffset, int width, int height, eGL_FORMAT format, eGL_TYPE type, void const * data )=0;
		virtual bool TexSubImage2D( eGL_TEXDIM p_eTarget, int level, Castor::Position const & p_position, Castor::Size const & p_size, eGL_FORMAT format, eGL_TYPE type, void const * data )=0;
		virtual bool TexSubImage2D( eGL_TEXDIM p_eTarget, int level, Castor::Rect const & p_rect, eGL_FORMAT format, eGL_TYPE type, void const * data )=0;
		virtual bool TexSubImage3D( eGL_TEXDIM p_eTarget, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, eGL_FORMAT format, eGL_TYPE type, void const * data )=0;
		virtual bool TexImage1D( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, int width, int border, eGL_FORMAT format, uint32_t type, void const * data )=0;
		virtual bool TexImage2D( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, int width, int height, int border, eGL_FORMAT format, uint32_t type, void const * data )=0;
		virtual bool TexImage2D( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, Castor::Size const & p_size, int border, eGL_FORMAT format, uint32_t type, void const * data )=0;
		virtual bool TexImage3D( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, int width, int height, int depth, int border, eGL_FORMAT format, uint32_t type, void const * data )=0;
		virtual bool TexParameter( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, int param )=0;
		virtual bool TexParameter( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, float param )=0;
		virtual bool TexParameter( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, const int * params )=0;
		virtual bool TexParameter( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, const float * params )=0;
		virtual bool GetTexImage( eGL_TEXDIM p_eTarget, int level, eGL_FORMAT format, eGL_TYPE type, void * img )=0;
	};

	class TexFunctions : public TexFunctionsBase
	{
	public:
		std::function< void	( uint32_t mode, uint32_t texture ) > m_pfnBindTexture;
#if CASTOR_HAS_VARIADIC_TEMPLATES
		std::function< void	( uint32_t target, int level, int xoffset, int width, uint32_t format, uint32_t type, void const * data ) > m_pfnTexSubImage1D;
		std::function< void	( uint32_t target, int level, int xoffset, int yoffset, int width, int height, uint32_t format, uint32_t type, void const * data ) > m_pfnTexSubImage2D;
		std::function< void	( uint32_t target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, uint32_t format, uint32_t type, void const * data ) > m_pfnTexSubImage3D;
		std::function< void	( uint32_t target, int level, int internalFormat, int width, int border, uint32_t format, uint32_t type, void const * data ) > m_pfnTexImage1D;
		std::function< void	( uint32_t target, int level, int internalFormat, int width, int height, int border, uint32_t format, uint32_t type, void const * data ) > m_pfnTexImage2D;
		std::function< void	( uint32_t target, int level, int internalFormat, int width, int height, int depth, int border, uint32_t format, uint32_t type, void const * data ) > m_pfnTexImage3D;
#else
		void (CALLBACK * m_pfnTexSubImage1D)( uint32_t target, int level, int xoffset, int width, uint32_t format, uint32_t type, void const * data );
		void (CALLBACK * m_pfnTexSubImage2D)( uint32_t target, int level, int xoffset, int yoffset, int width, int height, uint32_t format, uint32_t type, void const * data );
		void (CALLBACK * m_pfnTexSubImage3D)( uint32_t target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, uint32_t format, uint32_t type, void const * data );
		void (CALLBACK * m_pfnTexImage1D)( uint32_t target, int level, int internalFormat, int width, int border, uint32_t format, uint32_t type, void const * data );
		void (CALLBACK * m_pfnTexImage2D)( uint32_t target, int level, int internalFormat, int width, int height, int border, uint32_t format, uint32_t type, void const * data );
		void (CALLBACK * m_pfnTexImage3D)( uint32_t target, int level, int internalFormat, int width, int height, int depth, int border, uint32_t format, uint32_t type, void const * data );
#endif
		std::function< void	( uint32_t target, int level, uint32_t format, uint32_t type, void * pixels ) > m_pfnGetTexImage;
		std::function< void	( uint32_t target, uint32_t pname, int param ) > m_pfnTexParameteri;
		std::function< void	( uint32_t target, uint32_t pname, float param ) > m_pfnTexParameterf;
		std::function< void	( uint32_t target, uint32_t pname, const int * params ) > m_pfnTexParameteriv;
		std::function< void	( uint32_t target, uint32_t pname, const float * param ) > m_pfnTexParameterfv;
		std::function< void	( uint32_t target ) > m_pfnGenerateMipmap;

		TexFunctions( OpenGl & p_gl );
		virtual bool BindTexture( eGL_TEXDIM p_eTarget, uint32_t texture );
		virtual bool GenerateMipmap( eGL_TEXDIM p_eTarget );
		virtual bool TexSubImage1D( eGL_TEXDIM p_eTarget, int level, int xoffset, int width, eGL_FORMAT format, eGL_TYPE type, void const * data );
		virtual bool TexSubImage2D( eGL_TEXDIM p_eTarget, int level, int xoffset, int yoffset, int width, int height, eGL_FORMAT format, eGL_TYPE type, void const * data );
		virtual bool TexSubImage2D( eGL_TEXDIM p_eTarget, int level, Castor::Position const & p_position, Castor::Size const & p_size, eGL_FORMAT format, eGL_TYPE type, void const * data );
		virtual bool TexSubImage2D( eGL_TEXDIM p_eTarget, int level, Castor::Rect const & p_rect, eGL_FORMAT format, eGL_TYPE type, void const * data );
		virtual bool TexSubImage3D( eGL_TEXDIM p_eTarget, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, eGL_FORMAT format, eGL_TYPE type, void const * data );
		virtual bool TexImage1D( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, int width, int border, eGL_FORMAT format, uint32_t type, void const * data );
		virtual bool TexImage2D( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, int width, int height, int border, eGL_FORMAT format, uint32_t type, void const * data );
		virtual bool TexImage2D( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, Castor::Size const & p_size, int border, eGL_FORMAT format, uint32_t type, void const * data );
		virtual bool TexImage3D( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, int width, int height, int depth, int border, eGL_FORMAT format, uint32_t type, void const * data );
		virtual bool TexParameter( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, int param );
		virtual bool TexParameter( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, float param );
		virtual bool TexParameter( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, const int * params );
		virtual bool TexParameter( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, const float * params );
		virtual bool GetTexImage( eGL_TEXDIM p_eTarget, int level, eGL_FORMAT format, eGL_TYPE type, void * img );
	};

	class TexFunctionsDSA : public TexFunctionsBase
	{
	public:
		uint32_t m_uiTexture;
#if CASTOR_HAS_VARIADIC_TEMPLATES
		std::function< void	( uint32_t texture, uint32_t target, int level, int xoffset, int width, uint32_t format, uint32_t type, void const * data ) > m_pfnTextureSubImage1D;
		std::function< void	( uint32_t texture, uint32_t target, int level, int xoffset, int yoffset, int width, int height, uint32_t format, uint32_t type, void const * data ) > m_pfnTextureSubImage2D;
		std::function< void	( uint32_t texture, uint32_t target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, uint32_t format, uint32_t type, void const * data ) > m_pfnTextureSubImage3D;
		std::function< void	( uint32_t texture, uint32_t target, int level, int internalFormat, int width, int border, uint32_t format, uint32_t type, void const * data ) > m_pfnTextureImage1D;
		std::function< void	( uint32_t texture, uint32_t target, int level, int internalFormat, int width, int height, int border, uint32_t format, uint32_t type, void const * data ) > m_pfnTextureImage2D;
		std::function< void	( uint32_t texture, uint32_t target, int level, int internalFormat, int width, int height, int depth, int border, uint32_t format, uint32_t type, void const * data ) > m_pfnTextureImage3D;
		std::function< void	( uint32_t texture, uint32_t target, int level, uint32_t format, uint32_t type, void * pixels ) > m_pfnGetTextureImage;
#else
		void (CALLBACK * m_pfnTextureSubImage1D)( uint32_t texture, uint32_t target, int level, int xoffset, int width, uint32_t format, uint32_t type, void const * data );
		void (CALLBACK * m_pfnTextureSubImage2D)( uint32_t texture, uint32_t target, int level, int xoffset, int yoffset, int width, int height, uint32_t format, uint32_t type, void const * data );
		void (CALLBACK * m_pfnTextureSubImage3D)( uint32_t texture, uint32_t target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, uint32_t format, uint32_t type, void const * data );
		void (CALLBACK * m_pfnTextureImage1D)( uint32_t texture, uint32_t target, int level, int internalFormat, int width, int border, uint32_t format, uint32_t type, void const * data );
		void (CALLBACK * m_pfnTextureImage2D)( uint32_t texture, uint32_t target, int level, int internalFormat, int width, int height, int border, uint32_t format, uint32_t type, void const * data );
		void (CALLBACK * m_pfnTextureImage3D)( uint32_t texture, uint32_t target, int level, int internalFormat, int width, int height, int depth, int border, uint32_t format, uint32_t type, void const * data );
		void (CALLBACK * m_pfnGetTextureImage)( uint32_t texture, uint32_t target, int level, uint32_t format, uint32_t type, void * pixels );
#endif
		std::function< void	( uint32_t texture, uint32_t target, uint32_t pname, int param ) > m_pfnTextureParameteri;
		std::function< void	( uint32_t texture, uint32_t target, uint32_t pname, float param ) > m_pfnTextureParameterf;
		std::function< void	( uint32_t texture, uint32_t target, uint32_t pname, const int * params ) > m_pfnTextureParameteriv;
		std::function< void	( uint32_t texture, uint32_t target, uint32_t pname, const float * param ) > m_pfnTextureParameterfv;
		std::function< void	( uint32_t texture, uint32_t target ) > m_pfnGenerateTextureMipmap;

		TexFunctionsDSA( OpenGl & p_gl );
		virtual bool BindTexture( eGL_TEXDIM /*p_eTarget*/, uint32_t texture ) { m_uiTexture = texture;return true; }
		virtual bool GenerateMipmap( eGL_TEXDIM p_eTarget );
		virtual bool TexSubImage1D( eGL_TEXDIM p_eTarget, int level, int xoffset, int width, eGL_FORMAT format, eGL_TYPE type, void const * data );
		virtual bool TexSubImage2D( eGL_TEXDIM p_eTarget, int level, int xoffset, int yoffset, int width, int height, eGL_FORMAT format, eGL_TYPE type, void const * data );
		virtual bool TexSubImage2D( eGL_TEXDIM p_eTarget, int level, Castor::Position const & p_position, Castor::Size const & p_size, eGL_FORMAT format, eGL_TYPE type, void const * data );
		virtual bool TexSubImage2D( eGL_TEXDIM p_eTarget, int level, Castor::Rect const & p_rect, eGL_FORMAT format, eGL_TYPE type, void const * data );
		virtual bool TexSubImage3D( eGL_TEXDIM p_eTarget, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, eGL_FORMAT format, eGL_TYPE type, void const * data );
		virtual bool TexImage1D( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, int width, int border, eGL_FORMAT format, uint32_t type, void const * data );
		virtual bool TexImage2D( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, int width, int height, int border, eGL_FORMAT format, uint32_t type, void const * data );
		virtual bool TexImage2D( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, Castor::Size const & p_size, int border, eGL_FORMAT format, uint32_t type, void const * data );
		virtual bool TexImage3D( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, int width, int height, int depth, int border, eGL_FORMAT format, uint32_t type, void const * data );
		virtual bool TexParameter( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, int param );
		virtual bool TexParameter( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, float param );
		virtual bool TexParameter( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, const int * params );
		virtual bool TexParameter( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, const float * params );
		virtual bool GetTexImage( eGL_TEXDIM p_eTarget, int level, eGL_FORMAT format, eGL_TYPE type, void * img );
	};

	class BufFunctionsBase
	{
	protected:
		OpenGl & m_gl;

	public:
		std::function< void		( uint32_t array ) > m_pfnEnableClientState;
		std::function< void		( uint32_t array ) > m_pfnDisableClientState;

		BufFunctionsBase( OpenGl & p_gl );
		virtual bool	EnableClientState( eGL_BUFFER_USAGE p_eArray );
		virtual bool	DisableClientState( eGL_BUFFER_USAGE p_eArray );
		virtual bool	BindBuffer( eGL_BUFFER_TARGET target, uint32_t buffer )=0;
		virtual bool	BufferData( eGL_BUFFER_TARGET target, ptrdiff_t size, void const * data, eGL_BUFFER_MODE usage )=0;
		virtual bool	BufferSubData( eGL_BUFFER_TARGET target, ptrdiff_t offset, ptrdiff_t size, void const * data )=0;
		virtual void *	MapBuffer( eGL_BUFFER_TARGET target, eGL_LOCK access )=0;
		virtual bool	UnmapBuffer( eGL_BUFFER_TARGET target )=0;
		virtual void *	MapBufferRange( eGL_BUFFER_TARGET target, ptrdiff_t offset, ptrdiff_t length, uint32_t access )=0;
		virtual bool	GetBufferParameter( eGL_BUFFER_TARGET target, uint32_t pname, int * params )=0;
		virtual bool	FlushMappedBufferRange( eGL_BUFFER_TARGET target, ptrdiff_t offset, ptrdiff_t length )=0;
	};

	class BufFunctions : public BufFunctionsBase
	{
	public:
		std::function< void		( uint32_t target, uint32_t buffer ) > m_pfnBindBuffer;
		std::function< void		( uint32_t target, ptrdiff_t size, void const * data, uint32_t usage ) > m_pfnBufferData;
		std::function< void		( uint32_t target, ptrdiff_t offset, ptrdiff_t size, void const * data ) > m_pfnBufferSubData;
		std::function< void*	( uint32_t target, uint32_t access ) > m_pfnMapBuffer;
		std::function< uint8_t	( uint32_t target ) > m_pfnUnmapBuffer;
		std::function< void *	( uint32_t target, ptrdiff_t offset, ptrdiff_t length, uint32_t access ) > m_pfnMapBufferRange;
		std::function< void		( uint32_t target, ptrdiff_t offset, ptrdiff_t length ) > m_pfnFlushMappedBufferRange;
		std::function< void		( uint32_t target, uint32_t pname, int* params ) > m_pfnGetBufferParameteriv;

		BufFunctions( OpenGl & p_gl );
		virtual bool	BindBuffer( eGL_BUFFER_TARGET target, uint32_t buffer );
		virtual bool	BufferData( eGL_BUFFER_TARGET target, ptrdiff_t size, void const * data, eGL_BUFFER_MODE usage );
		virtual bool	BufferSubData( eGL_BUFFER_TARGET target, ptrdiff_t offset, ptrdiff_t size, void const * data );
		virtual void *	MapBuffer( eGL_BUFFER_TARGET target, eGL_LOCK access );
		virtual bool	UnmapBuffer( eGL_BUFFER_TARGET target );
		virtual void *	MapBufferRange( eGL_BUFFER_TARGET target, ptrdiff_t offset, ptrdiff_t length, uint32_t access );
		virtual bool	GetBufferParameter( eGL_BUFFER_TARGET target, uint32_t pname, int * params );
		virtual bool	FlushMappedBufferRange( eGL_BUFFER_TARGET target, ptrdiff_t offset, ptrdiff_t length );
	};

	class BufFunctionsDSA : public BufFunctionsBase
	{
	public:
		uint32_t m_uiBuffer;
		std::function< void		( uint32_t buffer, ptrdiff_t size, void const * data, uint32_t usage ) > m_pfnNamedBufferData;
		std::function< void		( uint32_t buffer, ptrdiff_t offset, ptrdiff_t size, void const * data ) > m_pfnNamedBufferSubData;
		std::function< void*	( uint32_t buffer, uint32_t access ) > m_pfnMapNamedBuffer;
		std::function< uint8_t	( uint32_t buffer ) > m_pfnUnmapNamedBuffer;
		std::function< void *	( uint32_t buffer, ptrdiff_t offset, ptrdiff_t length, uint32_t access ) > m_pfnMapNamedBufferRange;
		std::function< void		( uint32_t buffer, ptrdiff_t offset, ptrdiff_t length ) > m_pfnFlushMappedNamedBufferRange;
		std::function< void		( uint32_t buffer, uint32_t pname, int* params ) > m_pfnGetNamedBufferParameteriv;

		BufFunctionsDSA( OpenGl & p_gl );
		virtual bool	BindBuffer( eGL_BUFFER_TARGET /*target*/, uint32_t buffer ) { m_uiBuffer = buffer;return true; }
		virtual bool	BufferData( eGL_BUFFER_TARGET target, ptrdiff_t size, void const * data, eGL_BUFFER_MODE usage );
		virtual bool	BufferSubData( eGL_BUFFER_TARGET target, ptrdiff_t offset, ptrdiff_t size, void const * data );
		virtual void *	MapBuffer( eGL_BUFFER_TARGET target, eGL_LOCK access );
		virtual bool	UnmapBuffer( eGL_BUFFER_TARGET target );
		virtual void *	MapBufferRange( eGL_BUFFER_TARGET target, ptrdiff_t offset, ptrdiff_t length, uint32_t access );
		virtual bool	GetBufferParameter( eGL_BUFFER_TARGET target, uint32_t pname, int * params );
		virtual bool	FlushMappedBufferRange( eGL_BUFFER_TARGET target, ptrdiff_t offset, ptrdiff_t length );
	};

	class C3D_Gl_API OpenGl : CuNonCopyable
	{
	public:
		struct PixelFmt
		{
			eGL_FORMAT		Format;
			eGL_INTERNAL	Internal;
			eGL_TYPE		Type;

			PixelFmt(){}

			PixelFmt( eGL_FORMAT p_eFormat, eGL_INTERNAL p_eInternal, eGL_TYPE p_eType )
				:	Format		( p_eFormat		)
				,	Internal	( p_eInternal	)
				,	Type		( p_eType		)
			{
			}
		};

		typedef void (CALLBACK * PFNGLDEBUGPROC)( uint32_t source, uint32_t type, uint32_t id, uint32_t severity, int length, const char * message, void * userParam );
		typedef void (CALLBACK * PFNGLDEBUGAMDPROC)( uint32_t id, uint32_t category, uint32_t severity, int length, const char* message, void* userParam);

	private:
		Castor::String					GlslStrings				[8];
		Castor::String					GlslErrors				[8];
		eGL_PRIMITIVE					PrimitiveTypes			[Castor3D::eTOPOLOGY_COUNT];
		eGL_TEXDIM						TextureDimensions		[Castor3D::eTEXTURE_DIMENSION_COUNT];
		eGL_FUNC						AlphaFuncs				[Castor3D::eALPHA_FUNC_COUNT];
		eGL_WRAP_MODE					TextureWrapMode			[Castor3D::eWRAP_MODE_COUNT];
		eGL_INTERPOLATION_MODE			TextureInterpolation	[Castor3D::eINTERPOLATION_MODE_COUNT];
		eGL_LIGHT_INDEX	 				LightIndexes			[Castor3D::eLIGHT_INDEXES_COUNT];
		eGL_BLEND_FACTOR				BlendFactors			[Castor3D::eBLEND_COUNT];
		eGL_BUFFER_USAGE				Usages					[Castor3D::eELEMENT_USAGE_COUNT];
		eGL_BLEND_SOURCE	 			TextureArguments		[Castor3D::eBLEND_SOURCE_COUNT];
		eGL_BLEND_FUNC	 				RgbBlendFuncs			[Castor3D::eRGB_BLEND_FUNC_COUNT];
		eGL_BLEND_FUNC	 				AlphaBlendFuncs			[Castor3D::eALPHA_BLEND_FUNC_COUNT];
		eGL_BLEND_OP		 			BlendOps				[Castor3D::eBLEND_OP_COUNT];
		PixelFmt						PixelFormats			[Castor::ePIXEL_FORMAT_COUNT];
		eGL_SHADER_TYPE					ShaderTypes				[Castor3D::eSHADER_TYPE_COUNT];
		eGL_INTERNAL_FORMAT				Internals				[Castor::ePIXEL_FORMAT_COUNT];
		eGL_TEXTURE_ATTACHMENT			Attachments				[Castor3D::eATTACHMENT_POINT_COUNT];
		eGL_FRAMEBUFFER_MODE			FramebufferModes		[Castor3D::eFRAMEBUFFER_MODE_COUNT];
		eGL_RENDERBUFFER_ATTACHMENT		RboAttachments			[Castor3D::eATTACHMENT_POINT_COUNT];
		eGL_RENDERBUFFER_STORAGE		RboStorages				[Castor::ePIXEL_FORMAT_COUNT];
		eGL_TWEAK						Tweaks					[Castor3D::eTWEAK_COUNT];
		eGL_BUFFER						Buffers					[Castor3D::eBUFFER_COUNT];
		eGL_FACE						Faces					[Castor3D::eFACE_COUNT];
		eGL_FILL_MODE					FillModes				[3];
		eGL_STENCIL_OP					StencilOps				[Castor3D::eSTENCIL_OP_COUNT];
		eGL_FUNC						StencilFuncs			[Castor3D::eSTENCIL_FUNC_COUNT];
		bool							DepthMasks				[Castor3D::eDEPTH_MASK_COUNT];
		eGL_FUNC						DepthFuncs				[Castor3D::eDEPTH_FUNC_COUNT];
		std::map< eGL_TEXTURE_ATTACHMENT,		eGL_BUFFER	 >	BuffersTA;
		std::map< eGL_RENDERBUFFER_ATTACHMENT,	eGL_BUFFER	 >	BuffersRBA;

		bool							m_bHasVao;
		bool							m_bHasUbo;
		bool							m_bHasPbo;
		bool							m_bHasTbo;
		bool							m_bHasFbo;
		bool							m_bHasVbo;
		bool							m_bHasVSh;
		bool							m_bHasPSh;
		bool							m_bHasGSh;
		bool							m_bHasTSh;
		bool							m_bHasCSh;
		bool							m_bHasSpl;
		bool							m_bHasDepthClipping;
		bool							m_bHasAnisotropic;
		Castor::String					m_strExtensions;
		Castor::String					m_strVendor;
		Castor::String					m_strRenderer;
		Castor::String					m_strVersion;
		int								m_iVersion;
		int								m_iGlslVersion;
		bool							m_bHasInstancedDraw;
		bool							m_bHasInstancedArrays;
		bool							m_bHasDirectStateAccess;
		bool							m_bHasNonPowerOfTwoTextures;
		MtxFunctionsBase *				m_pMtxFunctions;
		TexFunctionsBase *				m_pTexFunctions;
		BufFunctionsBase *				m_pBufFunctions;

		/**@name General */
		//@{

		std::function< uint32_t		() > m_pfnGetError;
		std::function< void			( float red, float green, float blue, float alpha ) > m_pfnClearColor;
		std::function< void			( uint32_t mode ) > m_pfnShadeModel;
		std::function< void			( uint32_t mask ) > m_pfnClear;
		std::function< void			( uint32_t mode ) > m_pfnEnable;
		std::function< void			( uint32_t mode ) > m_pfnDisable;
		std::function< void			( int size, uint32_t * buffer ) > m_pfnSelectBuffer;
		std::function< void			( uint32_t pname, int * params ) > m_pfnGetIntegerv;
		std::function< int			( uint32_t mode ) > m_pfnRenderMode;
		std::function< void			( PFNGLDEBUGPROC callback, void * userParam ) > m_pfnDebugMessageCallback;
		std::function< void			( PFNGLDEBUGAMDPROC callback, void * userParam ) > m_pfnDebugMessageCallbackAMD;

		//@}
		/**@name Depth stencil state */
		//@{

		std::function< void			( uint32_t func ) >m_pfnDepthFunc;
		std::function< void			( uint8_t flag ) > m_pfnDepthMask;
		std::function< void			( uint32_t sfail, uint32_t dpfail, uint32_t dppass ) > m_pfnStencilOp;
		std::function< void			( uint32_t func, int ref, uint32_t mask ) > m_pfnStencilFunc;
		std::function< void			( uint32_t mask ) > m_pfnStencilMask;
		std::function< void			( uint32_t face, uint32_t sfail, uint32_t dpfail, uint32_t dppass ) > m_pfnStencilOpSeparate;
		std::function< void			( uint32_t frontFunc, uint32_t backFunc, int ref, uint32_t mask ) > m_pfnStencilFuncSeparate;
		std::function< void			( uint32_t face, uint32_t mask ) > m_pfnStencilMaskSeparate;

		//@}
		/**@name Rasterizer state */
		//@{

		std::function< void			( uint32_t face, uint32_t mode ) > m_pfnPolygonMode;
		std::function< void			( uint32_t face ) > m_pfnCullFace;
		std::function< void			( uint32_t face ) > m_pfnFrontFace;
		std::function< void			( uint32_t target, uint32_t mode ) > m_pfnHint;
		std::function< void			( float factor, float units ) >m_pfnPolygonOffset;

		//@}
		/**@name Blend state */
		//@{

		std::function< void			( float red, float green, float blue, float alpha ) > m_pfnBlendColor;
		std::function< void			( uint32_t srcRGB, uint32_t dstRGB, uint32_t srcAlpha, uint32_t dstAlpha ) > m_pfnBlendFuncSeparate;
		std::function< void			( uint32_t buf, uint32_t srcRGB, uint32_t dstRGB, uint32_t srcAlpha, uint32_t dstAlpha ) > m_pfnBlendFuncSeparatei;
		std::function< void			( uint32_t mode ) > m_pfnBlendEquation;
		std::function< void			( uint32_t buf, uint32_t mode ) > m_pfnBlendEquationi;
		std::function< void			( float value, uint8_t invert ) > m_pfnSampleCoverage;

		//@}
		/**@name Buffer rendering */
		//@{

		std::function< void			( uint32_t mode, int first, int count ) > m_pfnDrawArrays;
		std::function< void			( uint32_t mode, int count, uint32_t type, void const *indices ) > m_pfnDrawElements;
		std::function< void			( uint32_t mode, int first, int count, int primcount ) > m_pfnDrawArraysInstanced;
		std::function< void			( uint32_t mode, int count, uint32_t type, const void *indices, int primcount ) > m_pfnDrawElementsInstanced;
		std::function< void			( uint32_t index, uint32_t divisor ) > m_pfnVertexAttribDivisor;

		//@}
		/**@name Light */
		//@{

		std::function< void			( uint32_t light, uint32_t pname, float param ) > m_pfnLightf;
		std::function< void			( uint32_t light, uint32_t pname, float const * params ) > m_pfnLightfv;
		std::function< void			( uint32_t pname, int param ) > m_pfnLightModeli;
		std::function< void			( uint32_t pname, int const * param ) > m_pfnLightModeliv;
		std::function< void			( uint32_t pname, float param ) > m_pfnLightModelf;
		std::function< void			( uint32_t pname, float const * param ) > m_pfnLightModelfv;

		//@}
		/**@name Context */
		//@{

#if defined( _WIN32 )
		std::function< BOOL			( HDC hdc, HGLRC hglrc ) > m_pfnMakeCurrent;
		std::function< BOOL			( HDC hdc ) > m_pfnSwapBuffers;
		std::function< HGLRC		( HDC hdc ) > m_pfnCreateContext;
		std::function< BOOL			( HGLRC hContext ) > m_pfnDeleteContext;
		std::function< HGLRC		( HDC hDC, HGLRC hShareContext, int const * attribList ) > m_pfnCreateContextAttribs;
		std::function< BOOL			( int interval ) > m_pfnSwapInterval;
#elif defined ( __linux__ )
		std::function< int			( Display * pDisplay, GLXDrawable drawable, GLXContext context ) > m_pfnMakeCurrent;
		std::function< void			( Display * pDisplay, GLXDrawable drawable ) > m_pfnSwapBuffers;
		std::function< GLXContext	( Display * pDisplay, XVisualInfo * pVisualInfo, GLXContext shareList, Bool direct ) > m_pfnCreateContext;
		std::function< void			( Display * pDisplay, GLXContext context ) > m_pfnDeleteContext;
		std::function< GLXContext	( Display * pDisplay, GLXFBConfig fbconfig, GLXContext shareList, Bool direct, int const * attribList ) > m_pfnCreateContextAttribs;
		std::function< void			( Display * pDisplay, GLXDrawable drawable, int interval ) > m_pfnSwapInterval;
#else
#	error "Yet unsupported OS"
#endif

		//@}
		/**@name Matrix */
		//@{

		std::function< void			( int x, int y, int width, int height ) > m_pfnViewport;

		//@}
		/**@name Material */
		//@{

		std::function< void			( uint32_t sfactor, uint32_t dfactor ) > m_pfnBlendFunc;
		std::function< void			( uint32_t func, float ref ) > m_pfnAlphaFunc;
		std::function< void			( uint32_t face, uint32_t pname, float param ) > m_pfnMaterialf;
		std::function< void			( uint32_t face, uint32_t pname, float const * params ) > m_pfnMaterialfv;

		//@}
		/**@name Texture */
		//@{

		std::function< void			( int n, uint32_t * textures ) > m_pfnGenTextures;
		std::function< void			( int n, uint32_t const * textures ) > m_pfnDeleteTextures;
		std::function< void			( uint32_t texture  ) > m_pfnActiveTexture;
		std::function< void			( uint32_t texture  ) > m_pfnClientActiveTexture;
		std::function< void			( uint32_t target, uint32_t pname, int param ) > m_pfnTexEnvi;
		std::function< void			( uint32_t target, uint32_t pname, int const * param ) > m_pfnTexEnviv;
		std::function< void			( uint32_t target, uint32_t pname, float param ) > m_pfnTexEnvf;
		std::function< void			( uint32_t target, uint32_t pname, float const * param ) > m_pfnTexEnvfv;
		std::function< uint8_t		( uint32_t texture ) > m_pfnIsTexture;
		std::function< void			( uint32_t coord, uint32_t pname, int param ) > m_pfnTexGeni;
		std::function< void			( uint32_t mode ) > m_pfnReadBuffer;
#if CASTOR_HAS_VARIADIC_TEMPLATES
		std::function< void			( int x, int y, int width, int height, uint32_t format, uint32_t type, void *pixels ) > m_pfnReadPixels;
#else
		void (CALLBACK * m_pfnReadPixels)	( int x, int y, int width, int height, uint32_t format, uint32_t type, void *pixels );
#endif
		std::function< void			( uint32_t mode ) > m_pfnDrawBuffer;
		std::function< void			( int width, int height, uint32_t format, uint32_t type, void const * data ) > m_pfnDrawPixels;
		std::function< void			( uint32_t pname, int param ) > m_pfnPixelStorei;
		std::function< void			( uint32_t pname, float param ) > m_pfnPixelStoref;

		//@}
		/**@name Sampler */
		//@{

		std::function< void			( int count, const uint32_t * samplers ) > m_pfnDeleteSamplers;
		std::function< void			( int count, uint32_t* samplers ) > m_pfnGenSamplers;
		std::function< uint8_t		( uint32_t sampler ) > m_pfnIsSampler;
		std::function< void			( uint32_t unit, uint32_t sampler ) > m_pfnBindSampler;
		std::function< void			( uint32_t sampler, uint32_t pname, uint32_t* params ) > m_pfnGetSamplerParameteruiv;
		std::function< void			( uint32_t sampler, uint32_t pname, float* params ) > m_pfnGetSamplerParameterfv;
		std::function< void			( uint32_t sampler, uint32_t pname, int* params ) > m_pfnGetSamplerParameteriv;
		std::function< void			( uint32_t sampler, uint32_t pname, const uint32_t* params ) > m_pfnSamplerParameteruiv;
		std::function< void			( uint32_t sampler, uint32_t pname, float param ) > m_pfnSamplerParameterf;
		std::function< void			( uint32_t sampler, uint32_t pname, const float* params ) > m_pfnSamplerParameterfv;
		std::function< void			( uint32_t sampler, uint32_t pname, int param ) > m_pfnSamplerParameteri;
		std::function< void			( uint32_t sampler, uint32_t pname, const int* params ) > m_pfnSamplerParameteriv;

		//@}
		/**@name Texture Buffer Objects */
		//@{

		std::function< void			( uint32_t target, uint32_t internalFormat, uint32_t buffer ) > m_pfnTexBuffer;

		//@}
		/**@name Buffer Objects */
		//@{

		std::function< void			( int n, uint32_t* buffers  ) > m_pfnGenBuffers;
		std::function< void			( int n, uint32_t const * buffers  ) > m_pfnDeleteBuffers;
		std::function< uint8_t		( uint32_t buffer  ) > m_pfnIsBuffer;
		std::function< void			( int size, uint32_t type, int stride, void const * pointer ) > m_pfnVertexPointer;
		std::function< void			( uint32_t type, int stride, void const * pointer ) > m_pfnNormalPointer;
		std::function< void			( uint32_t type, int stride, void * pointer ) > m_pfnTangentPointer;
		std::function< void			( uint32_t type, int stride, void * pointer ) > m_pfnBinormalPointer;
		std::function< void			( int size, uint32_t type, int stride, void const * pointer ) > m_pfnColorPointer;
		std::function< void			( int size, uint32_t type, int stride, void  const *pointer ) > m_pfnTexCoordPointer;

		//@}
		/**@name FBO */
		//@{

		std::function< void			( int n, uint32_t* framebuffers  ) > m_pfnGenFramebuffers;
		std::function< void			( int n, uint32_t const * framebuffers  ) > m_pfnDeleteFramebuffers;
		std::function< void			( uint32_t target, uint32_t framebuffer  ) > m_pfnBindFramebuffer;
		std::function< uint32_t		( uint32_t target  ) > m_pfnCheckFramebufferStatus;
		std::function< void			( uint32_t target, uint32_t attachment, uint32_t texture, int level  ) > m_pfnFramebufferTexture;
		std::function< void			( uint32_t target, uint32_t attachment, uint32_t textarget, uint32_t texture, int level  ) > m_pfnFramebufferTexture1D;
		std::function< void			( uint32_t target, uint32_t attachment, uint32_t textarget, uint32_t texture, int level  ) > m_pfnFramebufferTexture2D;
		std::function< void			( uint32_t target,uint32_t attachment, uint32_t texture,int level,int layer  ) > m_pfnFramebufferTextureLayer;
#if CASTOR_HAS_VARIADIC_TEMPLATES
		std::function< void			( uint32_t target, uint32_t attachment, uint32_t textarget, uint32_t texture, int level, int layer ) > m_pfnFramebufferTexture3D;
		std::function< void			( int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, uint32_t mask, uint32_t filter ) > m_pfnBlitFramebuffer;
#else
		void (CALLBACK * m_pfnFramebufferTexture3D)( uint32_t target, uint32_t attachment, uint32_t textarget, uint32_t texture, int level, int layer );
		void (CALLBACK * m_pfnBlitFramebuffer)( int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, uint32_t mask, uint32_t filter );
#endif
		std::function< void			( int n, uint32_t const * bufs ) > m_pfnDrawBuffers;

		//@}
		/**@name RBO */
		//@{

		std::function< void			( uint32_t target, uint32_t attachmentPoint, uint32_t renderbufferTarget, uint32_t renderbufferId ) > m_pfnFramebufferRenderbuffer;
		std::function< void			( int n, uint32_t * ids ) > m_pfnGenRenderbuffers;
		std::function< void			( int n, uint32_t const * ids ) > m_pfnDeleteRenderbuffers;
		std::function< void			( uint32_t target, uint32_t id ) > m_pfnBindRenderbuffer;
		std::function< void			( uint32_t target, uint32_t internalFormat, int width, int height ) > m_pfnRenderbufferStorage;
		std::function< void			( uint32_t target, int isamples, uint32_t internalFormat, int width, int height ) > m_pfnRenderbufferStorageMultisample;
#if CASTOR_HAS_VARIADIC_TEMPLATES
		std::function< void			( uint32_t target, int samples, int internalformat, int width, int height, uint8_t fixedsamplelocations ) > m_pfnTexImage2DMultisample;
#else
		void (CALLBACK * m_pfnTexImage2DMultisample)( uint32_t target, int samples, int internalformat, int width, int height, uint8_t fixedsamplelocations );
#endif
		std::function< void			( uint32_t target, uint32_t param, int* value ) > m_pfnGetRenderbufferParameteriv;

		//@}
		/**@name Uniform variables */
		//@{

		std::function< int			( uint32_t program, char const * name ) > m_pfnGetUniformLocation;
#if CASTOR_HAS_VARIADIC_TEMPLATES
		std::function< void			( uint32_t program, uint32_t index, int maxLength, int* length, int* size, uint32_t* type, char* name ) > m_pfnGetActiveUniform;
#else
		void (CALLBACK * m_pfnGetActiveUniform)( uint32_t program, uint32_t index, int maxLength, int* length, int* size, uint32_t* type, char* name );
#endif
		std::function< void			( int location, int v0 ) > m_pfnUniform1i;
		std::function< void			( int location, int v0, int v1 ) > m_pfnUniform2i;
		std::function< void			( int location, int v0, int v1, int v2 ) > m_pfnUniform3i;
		std::function< void			( int location, int v0, int v1, int v2, int v3 ) > m_pfnUniform4i;
		std::function< void			( int location, int count, int const * value ) > m_pfnUniform1iv;
		std::function< void			( int location, int count, int const * value ) > m_pfnUniform2iv;
		std::function< void			( int location, int count, int const * value ) > m_pfnUniform3iv;
		std::function< void			( int location, int count, int const * value ) > m_pfnUniform4iv;
		std::function< void			( int, uint32_t ) > m_pfnUniform1ui;
		std::function< void			( int, uint32_t, uint32_t ) > m_pfnUniform2ui;
		std::function< void			( int, uint32_t, uint32_t, uint32_t ) > m_pfnUniform3ui;
		std::function< void			( int, uint32_t, uint32_t, uint32_t, uint32_t ) > m_pfnUniform4ui;
		std::function< void			( int, int, uint32_t const * ) > m_pfnUniform1uiv;
		std::function< void			( int, int, uint32_t const * ) > m_pfnUniform2uiv;
		std::function< void			( int, int, uint32_t const * ) > m_pfnUniform3uiv;
		std::function< void			( int, int, uint32_t const * ) > m_pfnUniform4uiv;
		std::function< void			( int location, float v0 ) > m_pfnUniform1f;
		std::function< void			( int location, float v0, float v1 ) > m_pfnUniform2f;
		std::function< void			( int location, float v0, float v1, float v2 ) > m_pfnUniform3f;
		std::function< void			( int location, float v0, float v1, float v2, float v3 ) > m_pfnUniform4f;
		std::function< void			( int location, int count, float const * value ) > m_pfnUniform1fv;
		std::function< void			( int location, int count, float const * value ) > m_pfnUniform2fv;
		std::function< void			( int location, int count, float const * value ) > m_pfnUniform3fv;
		std::function< void			( int location, int count, float const * value ) > m_pfnUniform4fv;
		std::function< void			( int location, double x ) > m_pfnUniform1d;
		std::function< void			( int location, double x, double y ) > m_pfnUniform2d;
		std::function< void			( int location, double x, double y, double z ) > m_pfnUniform3d;
		std::function< void			( int location, double x, double y, double z, double w ) > m_pfnUniform4d;
		std::function< void			( int location, int count, double const * value ) > m_pfnUniform1dv;
		std::function< void			( int location, int count, double const * value ) > m_pfnUniform2dv;
		std::function< void			( int location, int count, double const * value ) > m_pfnUniform3dv;
		std::function< void			( int location, int count, double const * value ) > m_pfnUniform4dv;
		std::function< void			( int location, int count, uint8_t transpose, float const * value ) >m_pfnUniformMatrix2fv;
		std::function< void			( int location, int count, uint8_t transpose, float const * value ) >m_pfnUniformMatrix2x3fv;
		std::function< void			( int location, int count, uint8_t transpose, float const * value ) >m_pfnUniformMatrix2x4fv;
		std::function< void			( int location, int count, uint8_t transpose, float const * value ) >m_pfnUniformMatrix3fv;
		std::function< void			( int location, int count, uint8_t transpose, float const * value ) >m_pfnUniformMatrix3x2fv;
		std::function< void			( int location, int count, uint8_t transpose, float const * value ) >m_pfnUniformMatrix3x4fv;
		std::function< void			( int location, int count, uint8_t transpose, float const * value ) >m_pfnUniformMatrix4fv;
		std::function< void			( int location, int count, uint8_t transpose, float const * value ) >m_pfnUniformMatrix4x2fv;
		std::function< void			( int location, int count, uint8_t transpose, float const * value ) >m_pfnUniformMatrix4x3fv;
		std::function< void			( int location, int count, uint8_t transpose, double const * value ) > m_pfnUniformMatrix2dv;
		std::function< void			( int location, int count, uint8_t transpose, double const * value ) > m_pfnUniformMatrix2x3dv;
		std::function< void			( int location, int count, uint8_t transpose, double const * value ) > m_pfnUniformMatrix2x4dv;
		std::function< void			( int location, int count, uint8_t transpose, double const * value ) > m_pfnUniformMatrix3dv;
		std::function< void			( int location, int count, uint8_t transpose, double const * value ) > m_pfnUniformMatrix3x2dv;
		std::function< void			( int location, int count, uint8_t transpose, double const * value ) > m_pfnUniformMatrix3x4dv;
		std::function< void			( int location, int count, uint8_t transpose, double const * value ) > m_pfnUniformMatrix4dv;
		std::function< void			( int location, int count, uint8_t transpose, double const * value ) > m_pfnUniformMatrix4x2dv;
		std::function< void			( int location, int count, uint8_t transpose, double const * value ) > m_pfnUniformMatrix4x3dv;

		//@}
		/**@name Uniform buffer object */
		//@{

		std::function< uint32_t		( uint32_t program, char const * uniformBlockName ) > m_pfnGetUniformBlockIndex;
		std::function< void			( uint32_t target, uint32_t index, uint32_t buffer ) > m_pfnBindBufferBase;
		std::function< void			( uint32_t program, uint32_t uniformBlockIndex, uint32_t uniformBlockBinding ) > m_pfnUniformBlockBinding;
		std::function< void			( uint32_t program, int uniformCount, char const ** uniformNames, uint32_t* uniformIndices ) > m_pfnGetUniformIndices;
		std::function< void			( uint32_t program, int uniformCount, uint32_t const * uniformIndices, uint32_t pname, int* params ) > m_pfnGetActiveUniformsiv;
		std::function< void			( uint32_t program, uint32_t uniformBlockIndex, uint32_t pname, int* params ) > m_pfnGetActiveUniformBlockiv;

		//@}
		/**@name Shader object */
		//@{

		std::function< uint32_t		( uint32_t type ) > m_pfnCreateShader;
		std::function< void			( uint32_t shader ) > m_pfnDeleteShader;
		std::function< void			( uint32_t program, uint32_t shader ) > m_pfnAttachShader;
		std::function< void			( uint32_t program, uint32_t shader ) > m_pfnDetachShader;
		std::function< void			( uint32_t shader ) > m_pfnCompileShader;
		std::function< void			( uint32_t shader, uint32_t pname, int* param ) > m_pfnGetShaderiv;
		std::function< void			( uint32_t shader, int bufSize, int* length, char* infoLog ) > m_pfnGetShaderInfoLog;
		std::function< void			( uint32_t shader, int count, const char ** string, const int * length ) > m_pfnShaderSource;

		//@}
		/**@name Shader program */
		//@{

		std::function< uint32_t		() > m_pfnCreateProgram;
		std::function< void			( uint32_t program ) > m_pfnDeleteProgram;
		std::function< uint8_t		( uint32_t program ) > m_pfnIsProgram;
		std::function< void			( uint32_t program ) > m_pfnLinkProgram;
		std::function< void			( uint32_t program ) > m_pfnValidateProgram;
		std::function< void			( uint32_t program ) > m_pfnUseProgram;
		std::function< void			( uint32_t program, uint32_t pname, int* param ) > m_pfnGetProgramiv;
		std::function< void			( uint32_t program, int bufSize, int* length, char* infoLog ) > m_pfnGetProgramInfoLog;
		std::function< int			( uint32_t program, char const * name ) > m_pfnGetAttribLocation;
		std::function< void			( uint32_t program, uint32_t pname, int value ) > m_pfnProgramParameteri;

		//@}
		/**@name Vertex Attribute Pointer */
		//@{

		std::function< void			( uint32_t ) > m_pfnEnableVertexAttribArray;
#if CASTOR_HAS_VARIADIC_TEMPLATES
		std::function< void			( uint32_t index, int size, uint32_t type, uint8_t normalized, int stride, void const * pointer ) > m_pfnVertexAttribPointer;
#else
		void (CALLBACK * m_pfnVertexAttribPointer)( uint32_t index, int size, uint32_t type, uint8_t normalized, int stride, void const * pointer );
#endif
		std::function< void			( uint32_t index, int size, uint32_t type, int stride, void const * pointer ) > m_pfnVertexAttribIPointer;
		std::function< void			( uint32_t ) > m_pfnDisableVertexAttribArray;

		//@}
		/**@name Vertex Array Object */
		//@{

		std::function< void			( int n, uint32_t* arrays ) > m_pfnGenVertexArrays;
		std::function< void			( int n, uint32_t const * arrays ) > m_pfnDeleteVertexArrays;
		std::function< void			( uint32_t array ) > m_pfnBindVertexArray;

		//@}

		std::function< void			( uint32_t p_param, int p_value ) > m_pfnPatchParameteri;

	public:
		OpenGl();
		~OpenGl();

		bool			Initialise					( Castor::String const & p_strExtensions );
		void			Cleanup						();
		bool			HasMultiTexturing			()const;
		inline bool		HasVao						()const { return m_bHasVao; }
		inline bool		HasUbo						()const { return m_bHasUbo; }
		inline bool		HasPbo						()const { return m_bHasPbo; }
		inline bool		HasTbo						()const { return m_bHasTbo; }
		inline bool		HasFbo						()const { return m_bHasFbo; }
		inline bool		HasVSh						()const { return m_bHasVSh; }
		inline bool		HasPSh						()const { return m_bHasPSh; }
		inline bool		HasGSh						()const { return m_bHasGSh; }
		inline bool		HasTSh						()const { return m_bHasTSh; }
		inline bool		HasCSh						()const { return m_bHasCSh; }
		inline bool		HasSpl						()const { return m_bHasSpl; }
		inline bool		HasVbo						()const { return m_bHasVbo; }
		inline bool		HasDepthClipping			()const { return m_bHasDepthClipping; }
		inline bool		HasInstancing				()const { return m_bHasInstancedDraw && m_bHasInstancedArrays; }
		inline bool		HasNonPowerOfTwoTextures	()const { return m_bHasNonPowerOfTwoTextures; }

		/**@name General Functions */
		//@{

		uint32_t		GetError					()const;
		bool			ClearColor					( float red, float green, float blue, float alpha );
		bool			ClearColor					( Castor::Colour const & p_colour );
		bool			ShadeModel					( eGL_SHADE_MODEL mode );
		bool			Clear						( uint32_t mask );
		bool			Enable						( eGL_TWEAK mode );
		bool			Disable						( eGL_TWEAK mode );
		bool			Enable						( eGL_LIGHT_INDEX light );
		bool			Disable						( eGL_LIGHT_INDEX light );
		bool			Enable						( eGL_TEXDIM texture );
		bool			Disable						( eGL_TEXDIM texture );
		bool			SelectBuffer				( int size, uint32_t * buffer );
		bool			GetIntegerv					( uint32_t pname, int * params );
		int				RenderMode					( eGL_RENDER_MODE mode );
		bool			DepthFunc					( eGL_FUNC p_eFunc );
		bool			DepthMask					( bool p_bFlag );
		bool			DebugMessageCallback		( PFNGLDEBUGPROC pfnProc, void * p_pThis );
		bool			DebugMessageCallback		( PFNGLDEBUGAMDPROC pfnProc, void * p_pThis );
		bool			PolygonMode					( eGL_FACE p_eFacing, eGL_FILL_MODE p_eMode );
		bool			StencilOp					( eGL_STENCIL_OP p_eStencilFail, eGL_STENCIL_OP p_eDepthFail, eGL_STENCIL_OP p_eStencilPass );
		bool			StencilFunc					( eGL_FUNC p_eFunc, int p_iRef, uint32_t p_uiMask );
		bool			StencilMask					( uint32_t p_uiMask );
		bool			StencilOpSeparate			( eGL_FACE p_eFacing, eGL_STENCIL_OP p_eStencilFail, eGL_STENCIL_OP p_eDepthFail, eGL_STENCIL_OP p_eStencilPass );
		bool			StencilFuncSeparate			( eGL_FACE p_eFacing, eGL_FUNC p_eFunc, int p_iRef, uint32_t p_uiMask );
		bool			StencilMaskSeparate			( eGL_FACE p_eFacing, uint32_t p_uiMask );
		bool			Hint						( eGL_HINT p_eHint, eGL_HINT_VALUE p_eValue );
		bool			PolygonOffset				( float p_fFactor, float p_fUnits );
		bool			BlendColor					( Castor::Colour const & p_clrFactors );
		bool			SampleCoverage				( float fValue, bool invert );

		//@}
		/**@name Draw Functions */
		//@{

		bool			DrawArrays					( eGL_PRIMITIVE mode, int first, int count );
		bool			DrawElements				( eGL_PRIMITIVE mode, int count, eGL_TYPE type, const void * indices );
		bool			DrawArraysInstanced			( eGL_PRIMITIVE mode, int first, int count, int primcount );
		bool			DrawElementsInstanced		( eGL_PRIMITIVE mode, int count, eGL_TYPE type, const void * indices, int primcount );

		//@}
		/**@name Instanciation Functions */
		//@{

		bool			VertexAttribDivisor			( uint32_t index, uint32_t divisor );

		//@}
		/**@name Light Functions */
		//@{

		bool			Light						( eGL_LIGHT_INDEX light, uint32_t pname, float param );
		bool			Light						( eGL_LIGHT_INDEX light, uint32_t pname, float const * param );
		bool			LightModel					( uint32_t pname, int param );
		bool			LightModel					( uint32_t pname, int const * param );
		bool			LightModel					( uint32_t pname, float param );
		bool			LightModel					( uint32_t pname, float const * param );

		//@}
		/**@name Context functions */
		//@{

#if defined( _WIN32 )
		bool			MakeCurrent					( HDC hdc, HGLRC hglrc );
		bool			SwapBuffers					( HDC hdc );
		bool			SwapInterval				( int interval );
		HGLRC			CreateContext				( HDC hdc );
		HGLRC			CreateContextAttribs		( HDC hDC, HGLRC hShareContext, int const * attribList );
		bool			DeleteContext				( HGLRC hContext );
		bool			HasCreateContextAttribs		();
#elif defined( __linux__ )
		bool			MakeCurrent					( Display * pDisplay, GLXDrawable drawable, GLXContext context );
		bool			SwapBuffers					( Display * pDisplay, GLXDrawable drawable );
		bool			SwapInterval				( Display * pDisplay, GLXDrawable drawable, int interval );
		GLXContext		CreateContext				( Display * pDisplay, XVisualInfo * pVisualInfo, GLXContext shareList, Bool direct );
		GLXContext		CreateContextAttribs		( Display * pDisplay, GLXFBConfig fbconfig, GLXContext shareList, Bool direct, int const * attribList );
		bool			DeleteContext				( Display * pDisplay, GLXContext context );
		bool			HasCreateContextAttribs		();
#else
#	error "Yet unsupported OS"
#endif

		//@}
		/**@name Matrix functions */
		//@{

		bool			Viewport					( int x, int y, int width, int height );
		bool			MatrixMode					( eGL_MATRIX_TYPE mode );
		bool			LoadIdentity				( );
		bool			Ortho						( double left, double right, double bottom, double top, double zNear, double zFar );
		bool			Frustum						( double left, double right, double bottom, double top, double zNear, double zFar );
		bool			PushMatrix					( );
		bool			PopMatrix					( );
		bool			Translate					( real x, real y, real z );
		bool			Rotate						( real angle, real x, real y, real z );
		bool			Scale						( real x, real y, real z );
		bool			MultMatrix					( real const * matrix );

		//@}
		/**@name Material functions */
		//@{

		bool			CullFace					( eGL_FACE face );
		bool			FrontFace					( eGL_FRONT_FACE_DIRECTION face );
		bool			Material					( eGL_DRAW_BUFFER_MODE face, eGL_MATERIAL_COMPONENT pname, float param );
		bool			Material					( eGL_DRAW_BUFFER_MODE face, eGL_MATERIAL_COMPONENT pname, float const * param );
		bool			BlendFunc					( eGL_BLEND_FACTOR sfactor, eGL_BLEND_FACTOR dfactor );
		bool			BlendFunc					( eGL_BLEND_FACTOR p_eRgbSrc, eGL_BLEND_FACTOR p_eRgbDst, eGL_BLEND_FACTOR p_eAlphaSrc, eGL_BLEND_FACTOR p_eAlphaDst );
		bool			BlendFunc					( uint32_t p_uiIndex, eGL_BLEND_FACTOR p_eRgbSrc, eGL_BLEND_FACTOR p_eRgbDst, eGL_BLEND_FACTOR p_eAlphaSrc, eGL_BLEND_FACTOR p_eAlphaDst );
		bool			BlendEquation				( eGL_BLEND_OP p_eOp );
		bool			BlendEquation				( uint32_t p_uiBuffer, eGL_BLEND_OP p_eOp );
		bool			AlphaFunc					( eGL_FUNC func, float ref );

		//@}
		/**@name Texture functions */
		//@{

		bool			GenTextures					( int n, uint32_t * textures );
		bool			DeleteTextures				( int n, uint32_t const * textures );
		bool			ActiveTexture				( eGL_TEXTURE_INDEX target );
		bool			ClientActiveTexture			( eGL_TEXTURE_INDEX target );
		bool			BindTexture					( eGL_TEXDIM p_eTarget, uint32_t texture );
		bool			EnableClientState			( eGL_BUFFER_USAGE p_eArray );
		bool			DisableClientState			( eGL_BUFFER_USAGE p_eArray );
		bool			GenerateMipmap				( eGL_TEXDIM p_eTarget );
		bool			TexSubImage1D				( eGL_TEXDIM p_eTarget, int level, int xoffset, int width, eGL_FORMAT format, eGL_TYPE type, void const * data );
		bool			TexSubImage2D				( eGL_TEXDIM p_eTarget, int level, int xoffset, int yoffset, int width, int height, eGL_FORMAT format, eGL_TYPE type, void const * data );
		bool			TexSubImage2D				( eGL_TEXDIM p_eTarget, int level, Castor::Position const & p_position, Castor::Size const & p_size, eGL_FORMAT format, eGL_TYPE type, void const * data );
		bool			TexSubImage2D				( eGL_TEXDIM p_eTarget, int level, Castor::Rect const & p_rect, eGL_FORMAT format, eGL_TYPE type, void const * data );
		bool			TexSubImage3D				( eGL_TEXDIM p_eTarget, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, eGL_FORMAT format, eGL_TYPE type, void const * data );
		bool			TexImage1D					( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, int width, int border, eGL_FORMAT format, uint32_t type, void const * data );
		bool			TexImage2D					( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, int width, int height, int border, eGL_FORMAT format, uint32_t type, void const * data );
		bool			TexImage2D					( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, Castor::Size const & p_size, int border, eGL_FORMAT format, uint32_t type, void const * data );
		bool			TexImage3D					( eGL_TEXDIM p_eTarget, int level, eGL_INTERNAL internalFormat, int width, int height, int depth, int border, eGL_FORMAT format, uint32_t type, void const * data );
		bool			TexImage2DMultisample		( eGL_TEXDIM p_eTarget, int p_iSamples, eGL_INTERNAL p_eInternalFormat, int p_iWidth, int p_iHeight, bool p_bFixedSampleLocations );
		bool			TexImage2DMultisample		( eGL_TEXDIM p_eTarget, int p_iSamples, eGL_INTERNAL p_eInternalFormat, Castor::Size const & p_size, bool p_bFixedSampleLocations );
		bool			TexParameter				( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, int param );
		bool			TexParameter				( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, float param );
		bool			TexParameter				( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, const int * params );
		bool			TexParameter				( eGL_TEXDIM p_eTarget, eGL_TEXTURE_PARAMETER pname, const float * params );
		bool			GetTexImage					( eGL_TEXDIM p_eTarget, int level, eGL_FORMAT format, eGL_TYPE type, void * img );
		bool			TexEnvi						( eGL_TEXENV_TARGET target, eGL_TEXENV_ARGNAME pname, int param );
		bool			TexEnviv					( eGL_TEXENV_TARGET target, eGL_TEXENV_ARGNAME pname, int const * param );
		bool			TexEnvf						( eGL_TEXENV_TARGET target, eGL_TEXENV_ARGNAME pname, float param );
		bool			TexEnvfv					( eGL_TEXENV_TARGET target, eGL_TEXENV_ARGNAME pname, float const * param );
		bool			IsTexture					( uint32_t texture );
		bool			TexGeni						( eGL_TEXGEN_COORD coord, eGL_TEXGEN_PARAM param, eGL_TEXGEN_MODE mode );
		bool			ReadBuffer					( eGL_BUFFER p_eBuffer );
		bool			ReadPixels					( int x, int y, int width, int height, eGL_FORMAT format, eGL_TYPE type, void * pixels );
		bool			ReadPixels					( Castor::Position const & p_position, Castor::Size const & p_size, eGL_FORMAT format, eGL_TYPE type, void * pixels );
		bool			ReadPixels					( Castor::Rect const & p_rect, eGL_FORMAT format, eGL_TYPE type, void * pixels );
		bool			DrawBuffer					( eGL_BUFFER p_eBuffer );
		bool			DrawPixels					( int width, int height, eGL_FORMAT format, eGL_TYPE type, void const * data );
		bool			PixelStore					( eGL_STORAGE_MODE p_eMode, int p_iParam );
		bool			PixelStore					( eGL_STORAGE_MODE p_eMode, float p_fParam );

		//@}
		/**@name Sampler functions */
		//@{

		bool			BindSampler					( uint32_t unit, uint32_t sampler );
		bool			DeleteSamplers				( int count, const uint32_t * samplers );
		bool			GenSamplers					( int count, uint32_t* samplers );
		bool			GetSamplerParameter			( uint32_t sampler, eGL_SAMPLER_PARAMETER pname, uint32_t* params );
		bool			GetSamplerParameter			( uint32_t sampler, eGL_SAMPLER_PARAMETER pname, float* params );
		bool			GetSamplerParameter			( uint32_t sampler, eGL_SAMPLER_PARAMETER pname, int* params );
		bool			IsSampler					( uint32_t sampler );
		bool			SetSamplerParameter			( uint32_t sampler, eGL_SAMPLER_PARAMETER pname, float param );
		bool			SetSamplerParameter			( uint32_t sampler, eGL_SAMPLER_PARAMETER pname, const float* params );
		bool			SetSamplerParameter			( uint32_t sampler, eGL_SAMPLER_PARAMETER pname, int param );
		bool			SetSamplerParameter			( uint32_t sampler, eGL_SAMPLER_PARAMETER pname, const int* params );
		bool			SetSamplerParameter			( uint32_t sampler, eGL_SAMPLER_PARAMETER pname, const uint32_t* params );

		//@}
		/**@name Texture Buffer objects functions */
		//@{

		bool			TexBuffer					( eGL_TEXDIM p_eTarget, eGL_INTERNAL_FORMAT p_eInternalFormat, uint32_t buffer );

		//@}
		/**@name Buffer objects functions */
		//@{

		bool			GenBuffers					( int n, uint32_t* buffers );
		bool			DeleteBuffers				( int n, uint32_t const * buffers );
		bool			IsBuffer					( uint32_t buffer );
		bool			BindBuffer					( eGL_BUFFER_TARGET target, uint32_t buffer );
		bool			BufferData					( eGL_BUFFER_TARGET target, ptrdiff_t size, void const * data, eGL_BUFFER_MODE usage );
		bool			BufferSubData				( eGL_BUFFER_TARGET target, ptrdiff_t offset, ptrdiff_t size, void const * data );
		void *			MapBuffer					( eGL_BUFFER_TARGET target, eGL_LOCK access );
		bool			UnmapBuffer					( eGL_BUFFER_TARGET target );
		void *			MapBufferRange				( eGL_BUFFER_TARGET target, ptrdiff_t offset, ptrdiff_t length, uint32_t access );
		bool			GetBufferParameter			( eGL_BUFFER_TARGET target, uint32_t pname, int * params );
		bool			FlushMappedBufferRange		( eGL_BUFFER_TARGET target, ptrdiff_t offset, ptrdiff_t length );
		bool			VertexPointer				( int size, uint32_t type, uint32_t stride, void const * pointer );
		bool			NormalPointer				( uint32_t type, uint32_t stride, void const * pointer );
		bool			TangentPointer				( uint32_t type, uint32_t stride, void const * pointer );
		bool			BinormalPointer				( uint32_t type, uint32_t stride, void const * pointer );
		bool			HasTangentPointer			();
		bool			HasBinormalPointer			();
		bool			ColorPointer				( int size, uint32_t type, uint32_t stride, void const * pointer );
		bool			TexCoordPointer				( int size, uint32_t type, uint32_t stride, void const * pointer );

		//@}
		/**@name FBO functions */
		//@{

		bool			GenFramebuffers					( int n, uint32_t * framebuffers );
		bool			DeleteFramebuffers				( int n, uint32_t const * framebuffers );
		bool			BindFramebuffer					( eGL_FRAMEBUFFER_MODE p_eBindingMode, uint32_t framebuffer );
		bool			FramebufferTexture				( eGL_FRAMEBUFFER_MODE p_eBindingMode, eGL_TEXTURE_ATTACHMENT p_eAttachment, uint32_t texture, int level );
		bool			FramebufferTexture1D			( eGL_FRAMEBUFFER_MODE p_eBindingMode, eGL_TEXTURE_ATTACHMENT p_eAttachment, eGL_TEXDIM textarget, uint32_t texture, int level );
		bool			FramebufferTexture2D			( eGL_FRAMEBUFFER_MODE p_eBindingMode, eGL_TEXTURE_ATTACHMENT p_eAttachment, eGL_TEXDIM textarget, uint32_t texture, int level );
		bool			FramebufferTexture3D			( eGL_FRAMEBUFFER_MODE p_eBindingMode, eGL_TEXTURE_ATTACHMENT p_eAttachment, eGL_TEXDIM textarget, uint32_t texture, int level, int layer );
		bool			FramebufferTextureLayer			( eGL_FRAMEBUFFER_MODE p_eBindingMode, eGL_TEXTURE_ATTACHMENT p_eAttachment, uint32_t texture, int level, int layer );
		bool			FramebufferRenderbuffer			( eGL_FRAMEBUFFER_MODE p_eBindingMode, eGL_RENDERBUFFER_ATTACHMENT p_eAttachment, eGL_RENDERBUFFER_MODE p_eRboTarget, uint32_t renderbufferId );
		uint32_t		CheckFramebufferStatus			( eGL_FRAMEBUFFER_MODE p_eBindingMode );
		bool			GenRenderbuffers				( int n, uint32_t * ids );
		bool			DeleteRenderbuffers				( int n, uint32_t const * ids );
		bool			BindRenderbuffer				( eGL_RENDERBUFFER_MODE p_eBindingMode, uint32_t id );
		bool			RenderbufferStorage				( eGL_RENDERBUFFER_MODE p_eBindingMode, eGL_RENDERBUFFER_STORAGE internalFormat, int width, int height );
		bool			RenderbufferStorageMultisample	( eGL_RENDERBUFFER_MODE p_eBindingMode, int p_iSamples, eGL_RENDERBUFFER_STORAGE internalFormat, int width, int height );
		bool			RenderbufferStorage				( eGL_RENDERBUFFER_MODE p_eBindingMode, eGL_RENDERBUFFER_STORAGE internalFormat, Castor::Size const & size );
		bool			RenderbufferStorageMultisample	( eGL_RENDERBUFFER_MODE p_eBindingMode, int p_iSamples, eGL_RENDERBUFFER_STORAGE internalFormat, Castor::Size const & size );
		bool			GetRenderbufferParameteriv		( eGL_RENDERBUFFER_MODE p_eBindingMode, eGL_RENDERBUFFER_PARAMETER param, int* value );
		bool			BlitFramebuffer					( int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, uint32_t mask, uint32_t filter );
		bool			BlitFramebuffer					( Castor::Rect const & rcSrc, Castor::Rect const & rcDst, uint32_t mask, uint32_t filter );
		bool			DrawBuffers						( int n, const uint32_t * bufs );

		//@}
		/**@name Uniform variable Functions */
		//@{

		int				GetUniformLocation			( uint32_t program, char const * name );
		bool			SetUniform					( int location, int v0 );
		bool			SetUniform					( int location, uint32_t v0 );
		bool			SetUniform					( int location, float v0 );
		bool			SetUniform					( int location, double v0 );
		bool			SetUniform					( int location, int v0, int v1 );
		bool			SetUniform					( int location, int v0, int v1, int v2 );
		bool			SetUniform					( int location, int v0, int v1, int v2, int v3 );
		bool			SetUniform					( int location, uint32_t v0, uint32_t v1 );
		bool			SetUniform					( int location, uint32_t v0, uint32_t v1, uint32_t v2 );
		bool			SetUniform					( int location, uint32_t v0, uint32_t v1, uint32_t v2, uint32_t v3 );
		bool			SetUniform					( int location, float v0, float v1 );
		bool			SetUniform					( int location, float v0, float v1, float v2 );
		bool			SetUniform					( int location, float v0, float v1, float v2, float v3 );
		bool			SetUniform					( int location, double v0, double v1 );
		bool			SetUniform					( int location, double v0, double v1, double v2 );
		bool			SetUniform					( int location, double v0, double v1, double v2, double v3 );
		bool			SetUniform1v				( int location, int count, int const * params );
		bool			SetUniform2v				( int location, int count, int const * params );
		bool			SetUniform3v				( int location, int count, int const * params );
		bool			SetUniform4v				( int location, int count, int const * params );
		bool			SetUniform1v				( int location, int count, uint32_t const * params );
		bool			SetUniform2v				( int location, int count, uint32_t const * params );
		bool			SetUniform3v				( int location, int count, uint32_t const * params );
		bool			SetUniform4v				( int location, int count, uint32_t const * params );
		bool			SetUniform1v				( int location, int count, float const * params );
		bool			SetUniform2v				( int location, int count, float const * params );
		bool			SetUniform3v				( int location, int count, float const * params );
		bool			SetUniform4v				( int location, int count, float const * params );
		bool			SetUniform1v				( int location, int count, double const * params );
		bool			SetUniform2v				( int location, int count, double const * params );
		bool			SetUniform3v				( int location, int count, double const * params );
		bool			SetUniform4v				( int location, int count, double const * params );
		bool			SetUniformMatrix2x2v		( int location, int count, bool transpose, float const * value );
		bool			SetUniformMatrix2x3v		( int location, int count, bool transpose, float const * value );
		bool			SetUniformMatrix2x4v		( int location, int count, bool transpose, float const * value );
		bool			SetUniformMatrix3x3v		( int location, int count, bool transpose, float const * value );
		bool			SetUniformMatrix3x2v		( int location, int count, bool transpose, float const * value );
		bool			SetUniformMatrix3x4v		( int location, int count, bool transpose, float const * value );
		bool			SetUniformMatrix4x4v		( int location, int count, bool transpose, float const * value );
		bool			SetUniformMatrix4x2v		( int location, int count, bool transpose, float const * value );
		bool			SetUniformMatrix4x3v		( int location, int count, bool transpose, float const * value );
		bool			SetUniformMatrix2x2v		( int location, int count, bool transpose, double const * value );
		bool			SetUniformMatrix2x3v		( int location, int count, bool transpose, double const * value );
		bool			SetUniformMatrix2x4v		( int location, int count, bool transpose, double const * value );
		bool			SetUniformMatrix3x3v		( int location, int count, bool transpose, double const * value );
		bool			SetUniformMatrix3x2v		( int location, int count, bool transpose, double const * value );
		bool			SetUniformMatrix3x4v		( int location, int count, bool transpose, double const * value );
		bool			SetUniformMatrix4x4v		( int location, int count, bool transpose, double const * value );
		bool			SetUniformMatrix4x2v		( int location, int count, bool transpose, double const * value );
		bool			SetUniformMatrix4x3v		( int location, int count, bool transpose, double const * value );

		//@}
		/**@name Uniform Buffer Objects Functions */
		//@{

		uint32_t		GetUniformBlockIndex		( uint32_t program, char const * uniformBlockName );
		bool			BindBufferBase				( uint32_t target, uint32_t index, uint32_t buffer );
		bool			UniformBlockBinding			( uint32_t program, uint32_t uniformBlockIndex, uint32_t uniformBlockBinding );
		bool			GetUniformIndices			( uint32_t program, int uniformCount, char const ** uniformNames, uint32_t* uniformIndices );
		bool			GetActiveUniformsiv			( uint32_t program, int uniformCount, uint32_t const * uniformIndices, eGL_UNIFORM_NAME pname, int* params );
		bool			GetActiveUniformBlockiv		( uint32_t program, uint32_t uniformBlockIndex, eGL_UNIFORM_NAME pname, int* params );

		//@}
		/**@name Shader object Functions */
		//@{

		uint32_t		CreateShader				( eGL_SHADER_TYPE type );
		bool			DeleteShader				( uint32_t shader );
		bool			AttachShader				( uint32_t program, uint32_t shader );
		bool			DetachShader				( uint32_t program, uint32_t shader );
		bool			CompileShader				( uint32_t shader );
		bool			GetShaderiv					( uint32_t shader, uint32_t pname, int* param );
		bool			GetShaderInfoLog			( uint32_t shader, int bufSize, int* length, char* infoLog );
		bool			ShaderSource				( uint32_t shader, int count, char const ** strings, int const * lengths );

		//@}
		/**@name Shader program Functions */
		//@{

		uint32_t		CreateProgram				();
		bool			DeleteProgram				( uint32_t program );
		bool			LinkProgram					( uint32_t program );
		bool			UseProgram					( uint32_t program );
		bool			GetProgramiv				( uint32_t program, uint32_t pname, int* param );
		bool			GetProgramInfoLog			( uint32_t program, int bufSize, int* length, char* infoLog );
		int				GetAttribLocation			( uint32_t program, char const * name );
		bool			IsProgram					( uint32_t program );
		bool			ProgramParameteri			( uint32_t program, uint32_t pname, int value );

		//@}
		/**@name Vertex Attribute Pointer functions */
		//@{

		bool			EnableVertexAttribArray		( uint32_t index );
		bool			VertexAttribPointer			( uint32_t index, int size, eGL_TYPE type, bool normalized, int stride, void const * pointer );
		bool			VertexAttribPointer			( uint32_t index, int size, eGL_TYPE type, int stride, void const * pointer );
		bool			DisableVertexAttribArray	( uint32_t index );

		//@}
		/**@name Vertex Array Objects */
		//@{

		bool			GenVertexArrays				( int n, uint32_t * arrays );
		bool			BindVertexArray				( uint32_t array );
		bool			DeleteVertexArrays			( int n, uint32_t * arrays );

		//@}
		/**@name Tesselation functions */
		//@{

		bool			PatchParameter				( eGL_PATCH_PARAMETER p_eParam, int p_iValue );

		//@}
		/**@name Other functions */
		//@{

		bool								GlCheckError		( std::string const & p_strText, bool p_bThrows=false )const;
		bool								GlCheckError		( std::wstring const & p_strText, bool p_bThrows=false )const;
		eGL_LOCK							GetLockFlags		( uint32_t p_uiFlags )const;
		uint32_t							GetBitfieldFlags	( uint32_t p_uiFlags )const;
		Castor::String						GetGlslErrorString	( int p_index)const											{ return GlslStrings[p_index]; }
		inline eGL_PRIMITIVE				Get					( Castor3D::eTOPOLOGY p_index)const					{ return PrimitiveTypes[p_index]; }
		inline eGL_TEXDIM					Get					( Castor3D::eTEXTURE_DIMENSION p_index)const				{ return TextureDimensions[p_index]; }
		inline eGL_LIGHT_INDEX				Get					( Castor3D::eLIGHT_INDEXES p_uiIndex)const					{ return LightIndexes[p_uiIndex]; }
		inline eGL_FUNC						Get					( Castor3D::eALPHA_FUNC p_eAlphaFunc)const					{ return AlphaFuncs[p_eAlphaFunc]; }
		inline eGL_WRAP_MODE				Get					( Castor3D::eWRAP_MODE p_eWrapMode)const					{ return TextureWrapMode[p_eWrapMode]; }
		inline eGL_INTERPOLATION_MODE		Get					( Castor3D::eINTERPOLATION_MODE p_eInterpolationMode)const	{ return TextureInterpolation[p_eInterpolationMode]; }
		inline int							Get					( Castor3D::eBLEND_SOURCE p_eArgument)const					{ return TextureArguments[p_eArgument]; }
		inline eGL_BLEND_FUNC				Get					( Castor3D::eRGB_BLEND_FUNC p_eMode)const					{ return RgbBlendFuncs[p_eMode]; }
		inline eGL_BLEND_FUNC				Get					( Castor3D::eALPHA_BLEND_FUNC p_eMode)const					{ return AlphaBlendFuncs[p_eMode]; }
		inline eGL_BLEND_FACTOR				Get					( Castor3D::eBLEND p_eBlendFactor)const						{ return BlendFactors[p_eBlendFactor]; }
		inline PixelFmt						Get					( Castor::ePIXEL_FORMAT p_pixelFormat)const					{ return PixelFormats[p_pixelFormat]; }
		inline eGL_BUFFER_USAGE				Get					( Castor3D::eELEMENT_USAGE p_eUsage)const					{ return Usages[p_eUsage]; }
		inline eGL_SHADER_TYPE				Get					( Castor3D::eSHADER_TYPE p_eType)const						{ return ShaderTypes[p_eType]; }
		inline eGL_INTERNAL_FORMAT			GetInternal			( Castor::ePIXEL_FORMAT p_eFormat )const					{ return Internals[p_eFormat]; }
		inline uint32_t						GetComponents		( uint32_t p_uiComponents )const							{ return (p_uiComponents & Castor3D::eBUFFER_COMPONENT_COLOUR ? eGL_BUFFER_BIT_COLOR : 0) | (p_uiComponents & Castor3D::eBUFFER_COMPONENT_DEPTH ? eGL_BUFFER_BIT_DEPTH : 0) | (p_uiComponents & Castor3D::eBUFFER_COMPONENT_STENCIL ? eGL_BUFFER_BIT_STENCIL : 0); }
		inline eGL_TEXTURE_ATTACHMENT		Get					( Castor3D::eATTACHMENT_POINT p_eAttachment )const			{ return Attachments[p_eAttachment]; }
		inline eGL_FRAMEBUFFER_MODE			Get					( Castor3D::eFRAMEBUFFER_TARGET p_eTarget )const			{ return FramebufferModes[p_eTarget]; }
		inline eGL_RENDERBUFFER_ATTACHMENT	GetRboAttachment	( Castor3D::eATTACHMENT_POINT p_eAttachment )const			{ return RboAttachments[p_eAttachment]; }
		inline eGL_RENDERBUFFER_STORAGE		GetRboStorage		( Castor::ePIXEL_FORMAT p_pixelFormat )const				{ return RboStorages[p_pixelFormat]; }
		inline eGL_TWEAK					Get					( Castor3D::eTWEAK p_eTweak )const							{ return Tweaks[p_eTweak]; }
		inline eGL_BUFFER					Get					( Castor3D::eBUFFER p_eBuffer )const						{ return Buffers[p_eBuffer]; }
		inline eGL_BUFFER					Get					( eGL_TEXTURE_ATTACHMENT p_eBuffer )						{ return BuffersTA[p_eBuffer]; }
		inline eGL_BUFFER					Get					( eGL_RENDERBUFFER_ATTACHMENT p_eBuffer )					{ return BuffersRBA[p_eBuffer]; }
		inline eGL_FACE						Get					( Castor3D::eFACE p_eFace )const							{ return Faces[p_eFace]; }
		inline eGL_FILL_MODE				Get					( Castor3D::eFILL_MODE p_eMode )const						{ return FillModes[p_eMode]; }
		inline eGL_FUNC						Get					( Castor3D::eSTENCIL_FUNC p_eFunc )const					{ return StencilFuncs[p_eFunc]; }
		inline eGL_STENCIL_OP				Get					( Castor3D::eSTENCIL_OP p_eOp )const						{ return StencilOps[p_eOp]; }
		inline eGL_BLEND_OP					Get					( Castor3D::eBLEND_OP p_eOp )const							{ return BlendOps[p_eOp]; }
		inline eGL_FUNC						Get					( Castor3D::eDEPTH_FUNC p_eFunc )const						{ return DepthFuncs[p_eFunc]; }
		inline bool							Get					( Castor3D::eDEPTH_MASK p_eMask )const						{ return DepthMasks[p_eMask]; }
		inline bool							HasDebugOutput		()const														{ return (m_pfnDebugMessageCallback || m_pfnDebugMessageCallbackAMD); }
		inline Castor::String const &		GetVendor			()const														{ return m_strVendor; }
		inline Castor::String const &		GetRenderer			()const														{ return m_strRenderer; }
		inline Castor::String const &		GetStrVersion		()const														{ return m_strVersion; }
		inline int							GetVersion			()const														{ return m_iVersion; }
		inline int							GetGlslVersion		()const														{ return m_iGlslVersion; }
		bool HasExtension( Castor::String const & p_strExtName )const;
		inline eGL_BUFFER_MODE GetBufferFlags( uint32_t p_uiFlags )const
		{

			eGL_BUFFER_MODE l_eReturn = eGL_BUFFER_MODE( 0 );

			if( p_uiFlags & Castor3D::eBUFFER_ACCESS_TYPE_DYNAMIC )
			{
				if( p_uiFlags & Castor3D::eBUFFER_ACCESS_NATURE_READ )
				{
					l_eReturn = eGL_BUFFER_MODE_DYNAMIC_READ;
				}
				else if( p_uiFlags & Castor3D::eBUFFER_ACCESS_NATURE_DRAW )
				{
					l_eReturn = eGL_BUFFER_MODE_DYNAMIC_DRAW;
				}
				else if( p_uiFlags & Castor3D::eBUFFER_ACCESS_NATURE_COPY )
				{
					l_eReturn = eGL_BUFFER_MODE_DYNAMIC_COPY;
				}
			}
			else if( p_uiFlags & Castor3D::eBUFFER_ACCESS_TYPE_STATIC )
			{
				if( p_uiFlags & Castor3D::eBUFFER_ACCESS_NATURE_READ )
				{
					l_eReturn = eGL_BUFFER_MODE_STATIC_READ;
				}
				else if( p_uiFlags & Castor3D::eBUFFER_ACCESS_NATURE_DRAW )
				{
					l_eReturn = eGL_BUFFER_MODE_STATIC_DRAW;
				}
				else if( p_uiFlags & Castor3D::eBUFFER_ACCESS_NATURE_COPY )
				{
					l_eReturn = eGL_BUFFER_MODE_STATIC_COPY;
				}
			}
			else if( p_uiFlags & Castor3D::eBUFFER_ACCESS_TYPE_STREAM )
			{
				if( p_uiFlags & Castor3D::eBUFFER_ACCESS_NATURE_READ )
				{
					l_eReturn = eGL_BUFFER_MODE_STREAM_READ;
				}
				else if( p_uiFlags & Castor3D::eBUFFER_ACCESS_NATURE_DRAW )
				{
					l_eReturn = eGL_BUFFER_MODE_STREAM_DRAW;
				}
				else if( p_uiFlags & Castor3D::eBUFFER_ACCESS_NATURE_COPY )
				{
					l_eReturn = eGL_BUFFER_MODE_STREAM_COPY;
				}
			}

			return l_eReturn;
		}
		//@}

		static void CALLBACK StDebugLog( eGL_DEBUG_SOURCE source, eGL_DEBUG_TYPE type, uint32_t id, eGL_DEBUG_SEVERITY severity, int length, const char * message, void * userParam );
		static void CALLBACK StDebugLogAMD( uint32_t id, eGL_DEBUG_CATEGORY category, eGL_DEBUG_SEVERITY severity, int length, const char * message, void * userParam );

	private:
		bool DoGlCheckError( Castor::String const & p_strText, bool p_bThrows=false )const;
		void DebugLog( eGL_DEBUG_SOURCE source, eGL_DEBUG_TYPE type, uint32_t id, eGL_DEBUG_SEVERITY severity, int length, const char * message );
		void DebugLogAMD( uint32_t id, eGL_DEBUG_CATEGORY category, eGL_DEBUG_SEVERITY severity, int length, const char * message );
	};
}

#   ifndef NDEBUG
#	    define glCheckError( txt )			OpenGl::GlCheckError( cuT( txt ), false )
#   else
#	    define glCheckError( txt )			true
#   endif

#pragma warning( pop )

#endif
