/*
								+--------------------------------+
								|                                |
								|  ***   OpenGL ES shader   ***  |
								|                                |
								|  Copyright © -tHE SWINe- 2013  |
								|                                |
								|            Shader.h            |
								|                                |
								+--------------------------------+
*/

#pragma once
#ifndef __GLES20_SHADER_INCLUDED
#define __GLES20_SHADER_INCLUDED

/**
 *	@file gles2/Shader.h
 *	@author -tHE SWINe-
 *	@date 2013
 *	@brief OpenGL ES 2.0 shaders
 */

#ifdef __HAVE_GLES
#include "GLES20.h" // android
#else // __HAVE_GLES
#include "GLES20Emu.h" // win/mac
#endif // __HAVE_GLES

/**
 *	@def __GLES20SHADER_HOLD_SHADER_OBJECTS
 *	@brief if defined, CGLESShader has member variables, containing shader object id's
 *	@note Having shader object id's makes CGLESShader somewhat bigger in memory, but
 *		avoids having to call glGetAttachedShaders() in CGLESShader::n_Program_Stages()
 *		and in CGLESShader::Compile() (when recompiling the shader only).
 */
//#define __GLES20SHADER_HOLD_SHADER_OBJECTS

/**
 *	@def __GLES20SHADER_HOLD_STATUS_INFO
 *	@brief if defined, compilation and linkage status is held for a shader
 *	@note Ommiting this saves a few bytes, but makes CGLESShader::b_Compiled()
 *		and CGLESShader::b_Linked() slower; those are, however, present in debug code only.
 */
//#define __GLES20SHADER_HOLD_STATUS_INFO

/**
 *	@brief a class, encapsulating OpenGL 4 high-level vertex and fragment shaders
 */
class CGLESShader {
protected:
	GLuint m_n_program_object; /**< @brief OpenGL program object handle */

#ifdef __GLES20SHADER_HOLD_SHADER_OBJECTS
	GLuint m_n_vs_object; /**< @brief vertex shader object @note This is only defined if ::__GLES20SHADER_HOLD_SHADER_OBJECTS is defined. */
#if 0 // not (yet) in OpenGL ES 2.0
	GLuint m_n_tcs_object; /**< @brief tessellation control shader object @note This is only defined if ::__GLES20SHADER_HOLD_SHADER_OBJECTS is defined. */
	GLuint m_n_tes_object; /**< @brief tessellation evaluation shader object @note This is only defined if ::__GLES20SHADER_HOLD_SHADER_OBJECTS is defined. */
	GLuint m_n_gs_object; /**< @brief geometry shader object @note This is only defined if ::__GLES20SHADER_HOLD_SHADER_OBJECTS is defined. */
#endif // 0
	GLuint m_n_fs_object; /**< @brief fragment shader object @note This is only defined if ::__GLES20SHADER_HOLD_SHADER_OBJECTS is defined. */
#endif // __GLES20SHADER_HOLD_SHADER_OBJECTS

#ifdef __GLES20SHADER_HOLD_STATUS_INFO
	bool m_b_compiled; /**< @brief last compilation attempt outcome @note This is only defined if ::__GLES20SHADER_HOLD_STATUS_INFO is defined. */
	bool m_b_linked; /**< @brief last linkage attempt outcome @note This is only defined if ::__GLES20SHADER_HOLD_STATUS_INFO is defined. */
#endif // __GLES20SHADER_HOLD_STATUS_INFO

public:
	/**
	 *	@brief default constructor; has no effect
	 */
	CGLESShader();

	/**
	 *	@brief destructor; deletes the program object and all the shaders
	 */
	~CGLESShader();

	/**
	 *	@brief gets program object allocation status
	 *	@return Returns true in case the program object was allocated, or false otherwise.
	 */
	inline bool b_Initialized() const;

	/**
	 *	@brief gets program object compilation status
	 *	@return Returns true in case the program object
	 *		was successfuly compiled, or false otherwise.
	 *	@note This is relatively fast, provided ::__GLES20SHADER_HOLD_STATUS_INFO
	 *		is defined. Otherwise glGetAttachedShaders() and glGetShaderiv()
	 *		are called, potentially several times.
	 */
	inline bool b_Compiled() const;

	/**
	 *	@brief gets program object link status
	 *	@return Returns true in case the program object
	 *		was successfuly linked, or false otherwise.
	 *	@note This is relatively fast, provided ::__GLES20SHADER_HOLD_STATUS_INFO
	 *		is defined. Otherwise glGetProgramiv() must be called to determine
	 *		the value of GL_LINK_STATUS.
	 */
	inline bool b_Linked() const;

	/**
	 *	@brief binds the program so it can be used
	 *	@note This function assumes the program was successfuly compiled and linked.
	 */
	inline void Bind() const;

	/**
	 *	@brief releases the program
	 *	@note This function binds program 0 so this program is no longer used.
	 *		This is not necessary to do. Also, in core profile, it effectively
	 *		disables any drawing commands as there is no fixed-function pipeline.
	 */
	static inline void Release();

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief binds (a part of) the program to a specified pipeline
	 *
	 *	@param[in] n_pipeline is the pipeline to bind the program to
	 *	@param[in] n_stages is a list of program stages to use (a combination of
	 *		GL_VERTEX_SHADER_BIT, GL_FRAGMENT_SHADER_BIT, GL_GEOMETRY_SHADER_BIT,
	 *		GL_TESS_CONTROL_SHADER_BIT and GL_TESS_EVALUATION_SHADER_BIT, or GL_ALL_SHADER_BITS,
	 *		it can be obtained using the n_Program_Stages() function)
	 *
	 *	@note This function requires the GL_ARB_separate_shader_objects extension (part of OpenGL 4.1 core).
	 */
	inline void Bind(GLuint n_pipeline, GLbitfield n_stages = GL_ALL_SHADER_BITS);

	/**
	 *	@brief releases (a part of) the program from a specified pipeline
	 *
	 *	@param[in] n_pipeline is the pipeline to bind the program to
	 *	@param[in] n_stages is a list of program stages to use (a combination of
	 *		GL_VERTEX_SHADER_BIT, GL_FRAGMENT_SHADER_BIT, GL_GEOMETRY_SHADER_BIT,
	 *		GL_TESS_CONTROL_SHADER_BIT and GL_TESS_EVALUATION_SHADER_BIT, or GL_ALL_SHADER_BITS,
	 *		it can be obtained using the n_Program_Stages() function)
	 *
	 *	@note This function binds program 0 so this program is no longer used.
	 *		This is not necessary to do. Also, in core profile, it effectively
	 *		disables any drawing commands as there is no fixed-function pipeline.
	 *	@note This function requires the GL_ARB_separate_shader_objects extension (part of OpenGL 4.1 core).
	 */
	inline void Release(GLuint n_pipeline, GLbitfield n_stages = GL_ALL_SHADER_BITS);

	/**
	 *	@brief makes the program active in a specified pipeline
	 *
	 *	@param[in] n_pipeline is the pipeline to activate the program in
	 *
	 *	@note This is used for setting uniforms using the traditional Uniform*() functions.
	 *		This is discouraged, the newer ProgramUniform*() functions should be used instead.
	 *		These do not require the program to be active.
	 *	@note This function requires the GL_ARB_separate_shader_objects extension (part of OpenGL 4.1 core).
	 */
	inline void MakeActive(GLuint n_pipeline);

	/**
	 *	@brief gets active program stages
	 *	@return Returns active program stages (a combination of GL_VERTEX_SHADER_BIT,
	 *		GL_FRAGMENT_SHADER_BIT, GL_GEOMETRY_SHADER_BIT, GL_TESS_CONTROL_SHADER_BIT
	 *		and GL_TESS_EVALUATION_SHADER_BIT).
	 *	@note If ::__GLES20SHADER_HOLD_SHADER_OBJECTS is defined, this operation
	 *		doesn't involve any glGet*(), and is therefore relatively fast.
	 *		If it's not defined, glGetAttachedShaders() needs to be called.
	 */
	GLenum n_Program_Stages() const;
#endif // 0

	/**
	 *	@brief deletes the program object and all the shaders
	 */
	void Delete();

	/**
	 *	@brief compiles specified shaders and attaches them to this program object
	 *
	 *	@param[in] p_s_vertex_shader is vertex shader source code
	 *	@param[in] p_s_fragment_shader is fragment shader source code
	 *	@param[out] r_s_info_log is filled with compiler output
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note In case the program is recompiled for some reason, all (or most of the)
	 *		the state associated with the program remains unchanged, only the old shader
	 *		objects which are replaced by a new ones.
	 *	@note Despite this functions returns true (success), r_s_info_log may still
	 *		contain warnings, or even a line saying that everything is ok (ATI).
	 */
	bool Compile(const char *p_s_vertex_shader, const char *p_s_fragment_shader,
		std::string &r_s_info_log);

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief loads precompiled program binary
	 *
	 *	This loads precompiled program binary and links it (an inseparable step).
	 *	The program parameters are restored to the state they were in when the
	 *	binary was saved. To set different values, it is necessary to relink
	 *	the program (fixme - will relinking work at all?).
	 *
	 *	@param[in] n_size is size of the binary, in bytes
	 *	@param[in] n_binary_format is name of the format the binary is stored in
	 *	@param[in] p_binary is pointer to the binary data
	 *	@param[out] r_s_info_log is filled with compiler output
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note The driver is usually very picky about the binary. In case the binary
	 *		was compiled on different hardware, different OS (x86 / x64 matters) or
	 *		even slightly different driver version, it will almost always refuse to
	 *		load the program.
	 *	@note This function requires the GL_ARB_get_program_binary extension (part of OpenGL 4.1 core).
	 */
	bool FromBinary(size_t n_size, GLenum n_binary_format,
		const void *p_binary, std::string &r_s_info_log);

	/**
	 *	@brief gets size of the program binary
	 *
	 *	@return Returns size of the program binary (in bytes) on success, or 0 on failure.
	 *
	 *	@note The program must have the GL_PROGRAM_BINARY_RETRIEVABLE_HINT flag set
	 *		(use Set_Program_Retrievable()) and must be successfuly linked in order
	 *		for the binary to be available.
	 *	@note This function requires the GL_ARB_get_program_binary extension (part of OpenGL 4.1 core).
	 */
	size_t n_Get_Program_Binary_Size() const; // must be linked

	/**
	 *	@brief gets the program binary
	 *
	 *	@param[in,out] r_n_size is size of the buffer to store the binary,
	 *		it will contain the real size of the binary upon successful return
	 *	@param[out] r_n_binary_format is name of the format the binary is stored in
	 *	@param[out] p_binary is pointer to the buffer to store the binary (must
	 *		be allocated at least to r_n_size bytes; use n_Get_Program_Binary_Size()
	 *		to determine the required size)
	 *
	 *	@note The program must have the GL_PROGRAM_BINARY_RETRIEVABLE_HINT flag set
	 *		(use Set_Program_Retrievable()) and must be successfuly linked in order
	 *		for the binary to be available.
	 *	@note This function requires the GL_ARB_get_program_binary extension (part of OpenGL 4.1 core).
	 */
	void Get_Program_Binary(size_t &r_n_size, GLenum &r_n_binary_format, void *p_binary);

	/**
	 *	@brief sets program binary retrievability property
	 *
	 *	@param[in] b_retrievable is retrievability flag
	 *		(set it to be able to use Get_Program_Binary() function)
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This must be called before linking the program (or the program
	 *		must be relinked for the setting to take effect).
	 *	@note This function requires the GL_ARB_get_program_binary extension (part of OpenGL 4.1 core).
	 */
	bool Set_Program_BinaryRetrievable(bool b_retrievable);

	/**
	 *	@brief sets program separability property
	 *
	 *	@param[in] b_separable is separabiltiy flag
	 *		(set it to be able to use this program in a program pipeline)
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This must be called before linking the program (or the program
	 *		must be relinked for the setting to take effect).
	 *	@note This function requires the GL_ARB_separate_shader_objects extension (part of OpenGL 4.1 core).
	 */
	bool Set_Program_Separable(bool b_separable);

	/**
	 *	@brief gets program separability property
	 *	@return Returns true in case the program is separable (can be used
	 *		in a program pipeline), otherwise returns false.
	 *	@note This function requires the GL_ARB_separate_shader_objects extension (part of OpenGL 4.1 core).
	 */
	bool b_Get_Program_Separable() const;

	/**
	 *	@brief gets program binary retrievability property
	 *	@return Returns true in case the program binary is retrievable
	 *		(Get_Program_Binary() can be used to retrieve the program
	 *		binary), otherwise returns false.
	 *	@note This function requires the GL_ARB_get_program_binary extension (part of OpenGL 4.1 core).
	 */
	bool b_Get_Program_BinaryRetrievable() const;
#endif // 0

	/**
	 *	@brief compiles, configures and links the shader
	 *
	 *	@param[in] p_s_vertex_shader is vertex shader source code
	 *	@param[in] p_s_tess_control_shader is tessellation control shader source code
	 *	@param[in] p_s_tess_evaluation_shader is tessellation evalutaion shader source code
	 *	@param[in] p_s_geometry_shader is geometry shader source code
	 *	@param[in] p_s_fragment_shader is fragment shader source code
	 *	@param[in] p_s_config is configuration string (see Configure() function documentation)
	 *	@param[in] b_want_separable_program is separable program flag
	 *		(see b_Get_Program_Separable() function documentation)
	 *	@param[in] b_want_retrievable_binary is program binary retrievable flag
	 *		(see b_Get_Program_BinaryRetrievable() function documentation)
	 *	@param[out] r_s_compile_log is filled with compiler output
	 *	@param[out] r_s_configure_log is filled with configurator output
	 *	@param[out] r_s_link_log is filled with linker output
	 *	@param[in] b_stderr_output
	 *
	 *	@return Returns true on success, false on failure.
	 */
	bool CompileConfigureLink(const char *p_s_vertex_shader, /*const char *p_s_tess_control_shader,
		const char *p_s_tess_evaluation_shader, const char *p_s_geometry_shader,*/
		const char *p_s_fragment_shader, const char *p_s_config, /*bool b_want_separable_program,
		bool b_want_retrievable_binary,*/ std::string &r_s_compile_log,
		std::string &r_s_configure_log, std::string &r_s_link_log, bool b_stderr_output);

	/**
	 *	@brief configures the shader from a config string
	 *
	 *	The language used is similar to that of cascaded style sheets.
	 *	The value of p_s_config can be set as follows:
	 *	@code
	 *		vertex {
	 *			texcoord: 0; // vertex attribute 0
	 *			position: 1; // vertex attribute 1
	 *		}
	 *
	 *		tessellation-control {
	 *			vertices-out: N; // currently, there is no way to set this and setting this causes error
	 *			mode: GL_POINTS|GL_LINES|GL_TRIANGLES; // currently, there is no way to set this and setting this causes error
	 *		}
	 *
	 *		tessellation-evaluation {
	 *			spacing: GL_EQUAL|GL_FRACTIONAL_EVEN|GL_FRACTIONAL_ODD; // currently, there is no way to set this and setting this causes error
	 *			vertex-order: GL_CW|GL_CCW; // currently, there is no way to set this and setting this causes error
	 *			point-mode: GL_TRUE|GL_FALSE; // currently, there is no way to set this and setting this causes error
	 *		}
	 *
	 *		geometry {
	 *			input-type: GL_TRIANGLES; // input primitive type
	 *			output-type: GL_TRIANGLE_STRIP; // output primitive type
	 *			max-vertices: 50; // maximal # of emitted vertices per shader call
	 *			invocations: 1; // currently must be 1, there is no way of setting this, other than in the code
	 *		}
	 *
	 *		fragment {
	 *			color: 0; // output to color buffer 0
	 *		}
	 *	@endcode
	 *
	 *	@param[in] p_s_config is shader configuration string
	 *	@param[out] r_s_configure_log is filled with configurator output
	 *
	 *	@note This is largerly obsoleted by GLSL layout qualifiers which
	 *		allows for configuration specification directly in the shader source.
	 *		Use this in case the configuration is not known prior runtime,
	 *		or in case the shaders are older than version 1.40.
	 */
	bool Configure(const char *p_s_config, std::string &r_s_configure_log);

	/**
	 *	@brief binds vertex attribute location
	 *
	 *	@param[in] n_location is the location
	 *	@param[in] p_s_attrib_name is vertex attribute name
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This must be called before linking the program (or the program
	 *		must be relinked for the setting to take effect).
	 */
	bool Bind_Attribute_Location(int n_location, const char *p_s_attrib_name);

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief binds fragment data location
	 *
	 *	@param[in] n_color_number is zero-based index of output color buffer
	 *	@param[in] p_s_output_name is shader output name
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This must be called before linking the program (or the program
	 *		must be relinked for the setting to take effect).
	 */
	bool Bind_FragData_Location(int n_color_number, const char *p_s_output_name);

	/**
	 *	@brief binds fragment data location
	 *
	 *	@param[in] n_color_number is zero-based index of output color buffer
	 *	@param[in] n_index is zero-based index of component (primary color, secondary color)
	 *	@param[in] p_s_output_name is shader output name
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This must be called before linking the program (or the program
	 *		must be relinked for the setting to take effect).
	 *	@note This function requires the GL_ARB_blend_func_extended extension (part of OpenGL 3.3 core).
	 */
	bool Bind_FragData_Location(int n_color_number, int n_index, const char *p_s_output_name);

	/**
	 *	@brief sets geometry shader input primitive type
	 *
	 *	@param[in] n_input_type is input primitive type (one of GL_POINTS, GL_LINES,
	 *		GL_LINES_ADJACENCY_EXT, GL_TRIANGLES or GL_TRIANGLES_ADJACENCY_EXT,
	 *		default is GL_TRIANGLES)
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This must be called before linking the program (or the program
	 *		must be relinked for the setting to take effect).
	 *	@note This function requires the GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core).
	 */
	bool Set_Geometry_InputType(GLenum n_input_type = GL_TRIANGLES);

	/**
	 *	@brief sets geometry shader output primitive type
	 *
	 *	@param[in] n_output_type is output primitive type (one of GL_POINTS,
	 *		GL_LINE_STRIP or GL_TRIANGLE_STRIP, default is GL_TRIANGLE_STRIP)
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This must be called before linking the program (or the program
	 *		must be relinked for the setting to take effect).
	 *	@note This function requires the GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core).
	 */
	bool Set_Geometry_OutputType(GLenum n_output_type = GL_TRIANGLE_STRIP);

	/**
	 *	@brief sets maximal number of vertices emitted by the geometry shader
	 *
	 *	@param[in] n_max_vertex_num is the maximal number of vertices emitted
	 *		by the geometry shader in a single invocation
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This must be set, using this function or the GLSL location qualifier,
	 *		otherwise linking the program is going to fail.
	 *	@note The maximal value of n_max_vertex_num is constrained by n_Geometry_MaxOutputVertices()
	 *		and indirectly by n_Geometry_MaxOutputComponents(), depending on the output primitive type.
	 *	@note This must be called before linking the program (or the program
	 *		must be relinked for the setting to take effect).
	 *	@note This function requires the GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core).
	 */
	bool Set_Geometry_VerticesOut(int n_max_vertex_num);
#endif // 0

	/**
	 *	@brief links the compiled program
	 *
	 *	@param[out] r_s_info_log is filled with linker output
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note Some settings do not take effect until the program is linked.
	 *		Changing them once the program has been linked requires the program
	 *		to be linked again; it is therefore safe to call this function multiple
	 *		times on the same program.
	 *	@note Despite this functions returns true (success), r_s_info_log may still
	 *		contain warnings, or even a line saying that everything is ok (ATI).
	 */
	bool Link(std::string &r_s_info_log);

	/**
	 *	@brief gets the number of vertex attributes
	 *	@return Returns the number of vertex attributes.
	 */
	size_t n_Get_Attribute_Num() const;

	/**
	 *	@brief gets vertex attribute name and data type
	 *
	 *	@param[in] n_index is zero-based index of the vertex attribute
	 *	@param[out] r_s_name is filled with the name of the attribute
	 *	@param[out] r_n_data_type is filled OpenGL data type name
	 *	@param[out] r_n_size is filled with size of the attribute
	 *		(returns 1 for scalars, 1 or more for arrays)
	 *
	 *	@return Returns true on success, false on failure.
	 */
	bool Get_Attribute(GLuint n_index, std::string &r_s_name,
		GLenum &r_n_data_type, int &r_n_size) const;

	/**
	 *	@brief gets vertex attribute name and data type
	 *
	 *	@param[in] n_index is zero-based index of the vertex attribute
	 *	@param[out] r_n_data_type is filled OpenGL data type name
	 *	@param[out] r_n_size is filled with size of the attribute
	 *		(returns 1 for scalars, 1 or more for arrays)
	 *
	 *	@return Returns the name of the attribute on success (the caller
	 *		is responsible for freeing the pointer), 0 on failure.
	 */
	char *p_s_Get_Attribute(GLuint n_index, GLenum &r_n_data_type, int &r_n_size) const;

	/**
	 *	@brief gets number of uniforms
	 *
	 *	@return Returns the number of uniform variables.
	 *
	 *	@note The count may also include OpenGL builtin uniforms,
	 *		such as gl_ModelViewProjectionMatrix.
	 *	@note This also includes uniforms in named uniform blocks (if any). // fixme?
	 *	@note This requires the shader to be linked (not necessarily successfully).
	 */
	size_t n_Get_Uniform_Num() const;

	/**
	 *	@brief gets number of uniform variables in an uniform block
	 *	@param[in] n_block_index is zero-based uniform block index
	 *	@return Returns number of variables in the uniform block.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	size_t n_Get_UniformBlock_Uniform_Num(GLuint n_block_index);

	/**
	 *	@brief gets uniform name and data type
	 *
	 *	@param[in] n_index is zero-based index of the uniform
	 *	@param[out] r_s_name is filled with the name of the uniform
	 *	@param[out] r_n_data_type is filled OpenGL data type name
	 *	@param[out] r_n_size is filled with size of the uniform
	 *		(returns 1 for scalars, 1 or more for arrays)
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This requires the shader to be linked (not necessarily successfully).
	 *	@note This can be used to query uniforms from the default uniform block
	 *		as well as "gl_" uniforms and uniforms from named uniform blocks. // fixme?
	 */
	bool Get_Uniform(GLuint n_index, std::string &r_s_name,
		GLenum &r_n_data_type, int &r_n_size) const;

	/**
	 *	@brief gets uniform name and data type
	 *
	 *	@param[in] n_index is zero-based index of the uniform
	 *	@param[out] r_n_data_type is filled OpenGL data type name
	 *	@param[out] r_n_size is filled with size of the uniform
	 *		(returns 1 for scalars, 1 or more for arrays)
	 *
	 *	@return Returns the name of the uniform on success (the caller
	 *		is responsible for freeing the pointer), 0 on failure.
	 *
	 *	@note This requires the shader to be linked (not necessarily successfully).
	 *	@note This can be used to query uniforms from the default uniform block
	 *		as well as "gl_" uniforms and uniforms from named uniform blocks. // fixme?
	 */
	char *p_s_Get_Uniform(GLuint n_index, GLenum &r_n_data_type, int &r_n_size) const;

	/**
	 *	@brief gets uniform name, data type, block index and block offset
	 *
	 *	@param[in] n_index is zero-based index of the uniform
	 *	@param[out] r_s_name is filled with the uniform variable name
	 *	@param[out] r_n_data_type is filled with OpenGL data type name
	 *	@param[out] r_n_size is filled with size of the uniform
	 *		(returns 1 for scalars, 1 or more for arrays)
	 *	@param[out] r_n_block_index is uniform block index (-1 for default block uniforms)
	 *	@param[out] r_n_block_offset is uniform block offset (only valid for named block uniforms)
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This requires the shader to be linked (not necessarily successfully).
	 *	@note This can be used to query uniforms from the default uniform block
	 *		as well as "gl_" uniforms and uniforms from named uniform blocks. // fixme?
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	bool Get_Uniform(GLuint n_index, std::string &r_s_name, GLenum &r_n_data_type,
		int &r_n_size, int &r_n_block_index, int &r_n_block_offset) const;

	/**
	 *	@brief gets uniform name, data type, block index, block offset and array stride
	 *
	 *	@param[in] n_index is zero-based index of the uniform
	 *	@param[out] r_s_name is filled with the uniform variable name
	 *	@param[out] r_n_data_type is filled with OpenGL data type name
	 *	@param[out] r_n_size is filled with size of the uniform
	 *		(returns 1 for scalars, 1 or more for arrays)
	 *	@param[out] r_n_block_index is uniform block index (-1 for default block uniforms)
	 *	@param[out] r_n_block_offset is uniform block offset (only valid for named block uniforms)
	 *	@param[out] r_n_block_array_stride is uniform array stride
	 *		(only valid for named block uniform arrays)
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This requires the shader to be linked (not necessarily successfully).
	 *	@note This can be used to query uniforms from the default uniform block
	 *		as well as "gl_" uniforms and uniforms from named uniform blocks. // fixme?
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	bool Get_Uniform(GLuint n_index, std::string &r_s_name, GLenum &r_n_data_type,
		int &r_n_size, int &r_n_block_index, int &r_n_block_offset,
		int &r_n_block_array_stride) const;

	/**
	 *	@brief gets uniform name, data type, block index, block offset and matrix memory layout
	 *
	 *	@param[in] n_index is zero-based index of the uniform
	 *	@param[out] r_s_name is filled with the uniform variable name
	 *	@param[out] r_n_data_type is filled with OpenGL data type name
	 *	@param[out] r_n_size is filled with size of the uniform
	 *		(returns 1 for scalars, 1 or more for arrays)
	 *	@param[out] r_n_block_index is uniform block index (-1 for default block uniforms)
	 *	@param[out] r_n_block_offset is uniform block offset (only valid for named block uniforms)
	 *	@param[out] r_n_block_matrix_stride is uniform matrix stride
	 *		(only valid for named block uniform matrices)
	 *	@param[out] r_b_block_row_major is set to true if uniform matrix is row major
	 *		(otherwise it's column major; this is only valid for named block uniform matrices)
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This requires the shader to be linked (not necessarily successfully).
	 *	@note This can be used to query uniforms from the default uniform block
	 *		as well as "gl_" uniforms and uniforms from named uniform blocks. // fixme?
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	bool Get_Uniform(GLuint n_index, std::string &r_s_name, GLenum &r_n_data_type,
		int &r_n_size, int &r_n_block_index, int &r_n_block_offset,
		int &r_n_block_matrix_stride, bool &r_b_block_row_major) const;

	/**
	 *	@brief gets uniform location by name
	 *
	 *	@param[in] p_s_uniform_name is uniform name
	 *
	 *	@return Returns uniform location on success, or -1 on failure (the uniform was not found).
	 *
	 *	@note This requires the shader to be linked (not necessarily successfully).
	 *	@note This cannot be used for uniforms outside the default uniform block. // fixme?
	 */
	int n_Get_Uniform_Location(const char *p_s_uniform_name) const;

	/**
	 *	@brief gets a list of uniforms in a named uniform block
	 *
	 *	@param[in] n_block_index is zero-based uniform block index
	 *	@param[in] n_buffer_size is size of the output buffer, in indices (not in bytes)
	 *	@param[out] r_n_index_num is filled with number of uniforms in the uniform block
	 *	@param[out] p_indices is filled with the uniform indices
	 *		(only if n_buffer_size >= r_n_index_num)
	 *
	 *	@return Returns true on success, false on failure (the buffer can't hold all the indices).
	 *
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	bool Get_UniformBlock_Uniform_Indices(GLuint n_block_index,
		size_t n_buffer_size, size_t &r_n_index_num, int *p_indices);

	/**
	 *	@brief gets a list of uniforms in a named uniform block
	 *
	 *	@param[in] n_block_index is zero-based uniform block index
	 *	@param[out] r_index_list is filled with the uniform indices
	 *
	 *	@return Returns true on success, false on failure (not enough memory).
	 *
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	bool Get_UniformBlock_Uniform_Indices(GLuint n_block_index, std::vector<int> &r_index_list);

	/**
	 *	@brief gets number of uniform blocks
	 *
	 *	@return Returns the number of uniform blocks.
	 *
	 *	@note This requires the shader to be linked (not necessarily successfully).
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	size_t n_Get_UniformBlock_Num() const;

	/**
	 *	@brief gets uniform block name
	 *
	 *	@param[in] n_block_index is zero-based index of the uniform block
	 *	@param[out] r_s_name is filled with the name of the uniform block
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This requires the shader to be linked (not necessarily successfully).
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	bool Get_UniformBlock_Name(GLuint n_block_index, std::string &r_s_name) const;

	/**
	 *	@brief gets uniform block name
	 *
	 *	@param[in] n_block_index is zero-based index of the uniform block
	 *
	 *	@return Returns the name of the uniform on success (the caller
	 *		is responsible for freeing the pointer), 0 on failure.
	 *
	 *	@note This requires the shader to be linked (not necessarily successfully).
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	const char *p_s_Get_UniformBlock_Name(GLuint n_block_index) const;

	/**
	 *	@brief gets uniform block index by name
	 *
	 *	@param[in] p_s_uniform_block_name is uniform block name
	 *
	 *	@return Returns uniform block index on success, GL_INVALID_INDEX on failure.
	 *
	 *	@note This requires the shader to be linked (not necessarily successfully).
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	GLuint n_Get_UniformBlock_Index(const char *p_s_uniform_block_name);

	/**
	 *	@brief gets uniform block data size
	 *	@param[in] n_block_index is zero-based uniform block index
	 *	@return Returns the specified uniform block data size (in bytes).
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	size_t n_Get_UniformBlock_DataSize(GLuint n_block_index);

	/**
	 *	@brief determines whether is an uniform block referenced by vertex shader
	 *	@param[in] n_block_index is zero-based uniform block index
	 *	@return Returns true if the uniform block is referenced, otherwise returns false.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	bool b_Get_UniformBlock_ReferencedByVertexShader(GLuint n_block_index);

	/**
	 *	@brief determines whether is an uniform block referenced by tessellation control shader
	 *	@param[in] n_block_index is zero-based uniform block index
	 *	@return Returns true if the uniform block is referenced, otherwise returns false.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	bool b_Get_UniformBlock_ReferencedByTessControlShader(GLuint n_block_index);

	/**
	 *	@brief determines whether is an uniform block referenced by tessellation evaluation shader
	 *	@param[in] n_block_index is zero-based uniform block index
	 *	@return Returns true if the uniform block is referenced, otherwise returns false.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	bool b_Get_UniformBlock_ReferencedByTessEvaluationShader(GLuint n_block_index);

	/**
	 *	@brief determines whether is an uniform block referenced by geometry shader
	 *	@param[in] n_block_index is zero-based uniform block index
	 *	@return Returns true if the uniform block is referenced, otherwise returns false.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	bool b_Get_UniformBlock_ReferencedByGeometryShader(GLuint n_block_index);

	/**
	 *	@brief determines whether is an uniform block referenced by fragment shader
	 *	@param[in] n_block_index is zero-based uniform block index
	 *	@return Returns true if the uniform block is referenced, otherwise returns false.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	bool b_Get_UniformBlock_ReferencedByFragmentShader(GLuint n_block_index);

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief gets fragment data location by name
	 *	@param[in] p_s_output_name is shader output name
	 *	@return Returns fragment data location.
	 *	@note This requires the shader to be initialized (see b_Initialized()).
	 */
	int n_Get_FragData_Location(const char *p_s_output_name) const;

	/**
	 *	@brief gets fragment data color index by name
	 *
	 *	@param[in] p_s_output_name is shader output name
	 *
	 *	@return Returns fragment data color index.
	 *
	 *	@note This requires the shader to be initialized (see b_Initialized()).
	 *	@note This requires GL_ARB_blend_func_extended extension (part of OpenGL 3.3 core).
	 */
	int n_Get_FragData_Index(const char *p_s_output_name) const;

	/**
	 *	@brief gets number of invocations of geometry shader
	 *
	 *	@return Returns a number of invocations, set for geometry shader.
	 *
	 *	@note Currerntly, the only way to set the number of invocations
	 *		is using a GLSL layout qualifier. The shader must therefore
	 *		be compiled in order for this to give the correct result
	 *		and not the default value of 1.
	 *	@note This requires the shader to be initialized (see b_Initialized()).
	 *	@note This requires GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core) and
	 *		the GL_ARB_gpu_shader5 extension (part of OpenGL 4.0 core).
	 */
	int n_Get_Geometry_Invocation_Num() const; // must contain valid program object which holds the value // GL_ARB_gpu_shader5

	/**
	 *	@brief gets output primitive type for geometry shader
	 *
	 *	@return Returns output primitive type for geometry shader.
	 *
	 *	@note This requires the shader to be initialized (see b_Initialized()).
	 *	@note This requires GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core).
	 */
	GLenum n_Get_Geometry_OutType() const;

	/**
	 *	@brief gets input primitive type for geometry shader
	 *
	 *	@return Returns input primitive type for geometry shader.
	 *
	 *	@note This requires the shader to be initialized (see b_Initialized()).
	 *	@note This requires GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core).
	 */
	GLenum n_Get_Geometry_InType() const;

	/**
	 *	@brief gets maximal number of vertices written by geometry shader
	 *
	 *	@return Returns gets maximal number of vertices written by geometry shader.
	 *
	 *	@note This requires the shader to be initialized (see b_Initialized()).
	 *	@note This requires GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core).
	 */
	int n_Get_Geometry_OutVertex_Num() const;

	/**
	 *	@brief sets varyings to be recorded by a transform feedback
	 *
	 *	@param[in] n_varying_num is number of varyings to record
	 *	@param[in] p_varying_list is list of names of varying to record
	 *	@param[in] n_buffer_mode is either GL_INTERLEAVED_ATTRIBS or GL_SEPARATE_ATTRIBS
	 *		(chooses how are the varyings stored in memory)
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note Some settings do not take effect until the program is linked.
	 *		Changing them once the program has been linked requires the program
	 *		to be linked again; it is therefore safe to call this function multiple
	 *		times on the same program.
	 *	@note This requires GL_EXT_transform_feedback extension (part of OpenGL 3.0 core).
	 */
	bool Set_TransformFeedback_Varyings(size_t n_varying_num,
		const char **p_varying_list, GLenum n_buffer_mode);

	/**
	 *	@brief gets the physical layout of stored varyings
	 *
	 *	@return Returns GL_INTERLEAVED_ATTRIBS or GL_SEPARATE_ATTRIBS
	 *		(chooses how are the varyings stored in memory).
	 *
	 *	@note This requires the shader to be linked
	 *	@note This requires GL_EXT_transform_feedback extension (part of OpenGL 3.0 core).
	 */
	GLenum n_Get_TransformFeedback_BufferMode() const;

	/**
	 *	@brief gets number of varyings to be recorded in transform feedback
	 *
	 *	@return Returns number of varyings to be recorded in transform feedback.
	 *
	 *	@note This requires the shader to be linked
	 *	@note This requires GL_EXT_transform_feedback extension (part of OpenGL 3.0 core).
	 */
	size_t n_Get_TransformFeedback_Varying_Num() const;

	/**
	 *	@brief gets a name and data type of a varying, set for transform feedback
	 *
	 *	@param[in] n_index is zero-based index of the varying
	 *	@param[out] r_s_name is filled with the name of the varying
	 *	@param[out] r_n_data_type is filled OpenGL data type name
	 *	@param[out] r_n_size is filled with size of the varying
	 *		(returns 1 for scalars, 1 or more for arrays)
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This requires the shader to be linked
	 *	@note This requires GL_EXT_transform_feedback extension (part of OpenGL 3.0 core).
	 */
	bool Get_TransformFeedback_Varying(GLuint n_index, std::string &r_s_name,
		GLenum &r_n_data_type, int &r_n_size) const;

	/**
	 *	@brief gets a name and data type of a varying, set for transform feedback
	 *
	 *	@param[in] n_index is zero-based index of the varying
	 *	@param[out] r_n_data_type is filled OpenGL data type name
	 *	@param[out] r_n_size is filled with size of the varying
	 *		(returns 1 for scalars, 1 or more for arrays)
	 *
	 *	@return Returns the name of the varying on success (the caller
	 *		is responsible for freeing the pointer), 0 on failure.
	 *
	 *	@note This requires the shader to be linked
	 *	@note This requires GL_EXT_transform_feedback extension (part of OpenGL 3.0 core).
	 */
	char *p_s_Get_TransformFeedback_Varying(GLuint n_index, GLenum &r_n_data_type, int &r_n_size) const;

	/**
	 *	@brief gets maximal number of vertices written by tessellation control shader
	 *
	 *	@return Returns gets maximal number of vertices written by tessellation control shader.
	 *
	 *	@note This requires the shader to be initialized (see b_Initialized()).
	 *	@note This requires GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	int n_Get_TessControl_OutVertex_Num() const;

	/**
	 *	@brief gets tessellation mode, requested by tessellation evaluation shader
	 *
	 *	@return Returns gets the name of primitives accepted by tessellation
	 *		evaluation shader (one of GL_TRIANGLES, GL_QUADS, or GL_ISOLINES).
	 *
	 *	@note This requires the shader to be successfuly compiled. // fixme?
	 *	@note This requires GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	GLenum n_Get_Tesselation_Mode() const;

	/**
	 *	@brief gets tessellation spacing, requested by tessellation evaluation shader
	 *
	 *	@return Returns the tessellation spacing mode, requested by tessellation
	 *		evaluation shader (one of GL_EQUAL, GL_FRACTIONAL_ODD, or GL_FRACTIONAL_EVEN).
	 *
	 *	@note This requires the shader to be successfuly compiled. // fixme?
	 *	@note This requires GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	GLenum n_Get_Tesselation_Spacing() const;

	/**
	 *	@brief gets tessellation vertex order, requested by tessellation evaluation shader
	 *
	 *	@return Returns the tessellation vertex order, requested by tessellation
	 *		evaluation shader (GL_CCW or GL_CW).
	 *
	 *	@note This requires the shader to be successfuly compiled. // fixme?
	 *	@note This requires GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	GLenum n_Get_Tesselation_VertexOrder() const;

	/**
	 *	@brief determines whether the point mode was enabled by tessellation evaluation shader
	 *
	 *	@return Returns true if the point mode was enabled by tessellation evaluation
	 *		shader (the tessellation primitive generator emits points), otherwise returns false.
	 *
	 *	@note This requires the shader to be successfuly compiled. // fixme?
	 *	@note This requires GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	bool b_Get_Tesselation_PointMode() const;
#endif // 0

	/**
	 *	@brief specifies the value of a uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the new uniform value
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform1f().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform1f(int n_location, float f_v0) const;

	/**
	 *	@brief specifies the value of a uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the first component of the new uniform value
	 *	@param[in] f_v1 is the second component of the new uniform value
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform2f().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform2f(int n_location, float f_v0, float f_v1) const;

	/**
	 *	@brief specifies the value of a uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the first component of the new uniform value
	 *	@param[in] f_v1 is second component of the new uniform value
	 *	@param[in] f_v2 is third component of the new uniform value
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform3f().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform3f(int n_location, float f_v0, float f_v1, float f_v2) const;

	/**
	 *	@brief specifies the value of a uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the first component of the new uniform value
	 *	@param[in] f_v1 is second component of the new uniform value
	 *	@param[in] f_v2 is third component of the new uniform value
	 *	@param[in] f_v3 is fourth component of the new uniform value
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform4f().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform4f(int n_location, float f_v0, float f_v1, float f_v2, float f_v3) const;

	/**
	 *	@brief specifies the value of a uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] p_value is pointer to the array containing the new uniform value(s)
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform*() variant of this function.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform1fv(int n_location, int n_count, const GLfloat *p_value) const;

	/**
	 *	@copydoc Uniform1fv
	 */
	inline void Uniform2fv(int n_location, int n_count, const GLfloat *p_value) const;

	/**
	 *	@copydoc Uniform1fv
	 */
	inline void Uniform3fv(int n_location, int n_count, const GLfloat *p_value) const;

	/**
	 *	@copydoc Uniform1fv
	 */
	inline void Uniform4fv(int n_location, int n_count, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of an integer uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the new uniform value
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform1i().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform1i(int n_location, int n_v0) const;

	/**
	 *	@brief specifies the value of an integer uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the first component of the new uniform value
	 *	@param[in] n_v1 is second component of the new uniform value
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform2i().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform2i(int n_location, int n_v0, int n_v1) const;

	/**
	 *	@brief specifies the value of an integer uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the first component of the new uniform value
	 *	@param[in] n_v1 is second component of the new uniform value
	 *	@param[in] n_v2 is third component of the new uniform value
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform3i().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform3i(int n_location, int n_v0, int n_v1, int n_v2) const;

	/**
	 *	@brief specifies the value of an integer uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the first component of the new uniform value
	 *	@param[in] n_v1 is second component of the new uniform value
	 *	@param[in] n_v2 is third component of the new uniform value
	 *	@param[in] n_v3 is fourth component of the new uniform value
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform4i().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform4i(int n_location, int n_v0, int n_v1, int n_v2, int n_v3) const;

	/**
	 *	@brief specifies the value of an integer uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] p_value is pointer to the array containing the new uniform value(s)
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform*() variant of this function.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform1iv(int n_location, int n_count, const GLint *p_value) const;

	/**
	 *	@copydoc Uniform1iv
	 */
	inline void Uniform2iv(int n_location, int n_count, const GLint *p_value) const;

	/**
	 *	@copydoc Uniform1iv
	 */
	inline void Uniform3iv(int n_location, int n_count, const GLint *p_value) const;

	/**
	 *	@copydoc Uniform1iv
	 */
	inline void Uniform4iv(int n_location, int n_count, const GLint *p_value) const;

	/**
	 *	@brief specifies the value of a 2x2 matrix uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 2x2 matrices
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix2fv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix2fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 3x3 matrix uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 3x3 matrices
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix3fv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix3fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 4x4 matrix uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 4x4 matrices
	 *
	 *	@note This is part of OpenGL 2.0 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix4fv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix4fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief specifies the value of a 2x3 matrix uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 2x3 matrices
	 *
	 *	@note This is part of OpenGL 2.1 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix2x3fv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix2x3fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 3x2 matrix uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 3x2 matrices
	 *
	 *	@note This is part of OpenGL 2.1 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix3x2fv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix3x2fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 2x4 matrix uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 2x4 matrices
	 *
	 *	@note This is part of OpenGL 2.1 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix2x4fv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix2x4fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 4x2 matrix uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 4x2 matrices
	 *
	 *	@note This is part of OpenGL 2.1 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix4x2fv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix4x2fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 3x4 matrix uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 3x4 matrices
	 *
	 *	@note This is part of OpenGL 2.1 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix3x4fv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix3x4fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 4x3 matrix uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 4x3 matrices
	 *
	 *	@note This is part of OpenGL 2.1 core.
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix4x3fv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix4x3fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;
#endif // 0

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief specifies the value of an unsigned integer uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the new uniform value
	 *
	 *	@note This is part of OpenGL 3.0 core (or GL_EXT_gpu_shader4 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform1ui().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform1ui(int n_location, unsigned int n_v0) const;

	/**
	 *	@brief specifies the value of an unsigned integer uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the first component of the new uniform value
	 *	@param[in] n_v1 is second component of the new uniform value
	 *
	 *	@note This is part of OpenGL 3.0 core (or GL_EXT_gpu_shader4 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform2ui().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform2ui(int n_location, unsigned int n_v0, unsigned int n_v1) const;

	/**
	 *	@brief specifies the value of an unsigned integer uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the first component of the new uniform value
	 *	@param[in] n_v1 is second component of the new uniform value
	 *	@param[in] n_v2 is third component of the new uniform value
	 *
	 *	@note This is part of OpenGL 3.0 core (or GL_EXT_gpu_shader4 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform3ui().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform3ui(int n_location, unsigned int n_v0, unsigned int n_v1, unsigned int n_v2) const;

	/**
	 *	@brief specifies the value of an unsigned integer uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the first component of the new uniform value
	 *	@param[in] n_v1 is second component of the new uniform value
	 *	@param[in] n_v2 is third component of the new uniform value
	 *	@param[in] n_v3 is fourth component of the new uniform value
	 *
	 *	@note This is part of OpenGL 3.0 core (or GL_EXT_gpu_shader4 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform4ui().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform4ui(int n_location, unsigned int n_v0, unsigned int n_v1, unsigned int n_v2, unsigned int n_v3) const;

	/**
	 *	@brief specifies the value of an unsigned integer uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] p_value is pointer to the array containing the new uniform value(s)
	 *
	 *	@note This is part of OpenGL 3.0 core (or GL_EXT_gpu_shader4 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform*() variant of this function.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform1uiv(int n_location, int n_count, const GLuint *p_value) const;

	/**
	 *	@copydoc Uniform1uiv
	 */
	inline void Uniform2uiv(int n_location, int n_count, const GLuint *p_value) const;

	/**
	 *	@copydoc Uniform1uiv
	 */
	inline void Uniform3uiv(int n_location, int n_count, const GLuint *p_value) const;

	/**
	 *	@copydoc Uniform1uiv
	 */
	inline void Uniform4uiv(int n_location, int n_count, const GLuint *p_value) const;
#endif // 0

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief specifies the value of a double-precision floating-point
	 *		uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the new uniform value
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform1d().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform1d(int n_location, double f_v0) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point
	 *		uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the first component of the new uniform value
	 *	@param[in] f_v1 is second component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform2d().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform2d(int n_location, double f_v0, double f_v1) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point
	 *		uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the first component of the new uniform value
	 *	@param[in] f_v1 is second component of the new uniform value
	 *	@param[in] f_v2 is third component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform3d().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform3d(int n_location, double f_v0, double f_v1, double f_v2) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point
	 *		uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the first component of the new uniform value
	 *	@param[in] f_v1 is second component of the new uniform value
	 *	@param[in] f_v2 is third component of the new uniform value
	 *	@param[in] f_v3 is fourth component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform4d().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform4d(int n_location, double f_v0, double f_v1, double f_v2, double f_v3) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point
	 *		uniform variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] p_value is pointer to the array containing the new uniform value(s)
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniform*() variant of this function.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void Uniform1dv(int n_location, int n_count, const double *p_value) const;

	/**
	 *	@copydoc Uniform1dv
	 */
	inline void Uniform2dv(int n_location, int n_count, const double *p_value) const;

	/**
	 *	@copydoc Uniform1dv
	 */
	inline void Uniform3dv(int n_location, int n_count, const double *p_value) const;

	/**
	 *	@copydoc Uniform1dv
	 */
	inline void Uniform4dv(int n_location, int n_count, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point 2x2 matrix uniform
	 *		variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 2x2 matrices
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix2dv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix2dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point 3x3 matrix uniform
	 *		variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 3x3 matrices
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix3dv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix3dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point 4x4 matrix uniform
	 *		variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 4x4 matrices
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix4dv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix4dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point 2x3 matrix uniform
	 *		variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 2x3 matrices
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix2x3dv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix2x3dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point 3x2 matrix uniform
	 *		variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 3x2 matrices
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix3x2dv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix3x2dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point 2x4 matrix uniform
	 *		variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 2x4 matrices
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix2x4dv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix2x4dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point 4x2 matrix uniform
	 *		variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 4x2 matrices
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix4x2dv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix4x2dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point 3x4 matrix uniform
	 *		variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 3x4 matrices
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix3x4dv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix3x4dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point 4x3 matrix uniform
	 *		variable for the current program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 4x3 matrices
	 *
	 *	@note This is part of OpenGL 4.0 core (or GL_ARB_gpu_shader_fp64 extension).
	 *	@note This assumes this shader is currently bound (but does not do any error-checking).
	 *	@note In case a program pipeline is bound, this shader must also be active (see MakeActive()).
	 *		It is preferable to call the ProgramUniformMatrix4x3dv().
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void UniformMatrix4x3dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;
#endif // 0

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief specifies the value of a uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform1f(int n_location, float f_v0) const;

	/**
	 *	@brief specifies the value of a uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the first component of the new uniform value
	 *	@param[in] f_v1 is second component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform2f(int n_location, float f_v0, float f_v1) const;

	/**
	 *	@brief specifies the value of a uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the first component of the new uniform value
	 *	@param[in] f_v1 is second component of the new uniform value
	 *	@param[in] f_v2 is third component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform3f(int n_location, float f_v0, float f_v1, float f_v2) const;

	/**
	 *	@brief specifies the value of a uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the first component of the new uniform value
	 *	@param[in] f_v1 is second component of the new uniform value
	 *	@param[in] f_v2 is third component of the new uniform value
	 *	@param[in] f_v3 is fourth component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform4f(int n_location, float f_v0, float f_v1, float f_v2, float f_v3) const;

	/**
	 *	@brief specifies the value of an integer uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform1i(int n_location, int n_v0) const;

	/**
	 *	@brief specifies the value of an integer uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the first component of the new uniform value
	 *	@param[in] n_v1 is second component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform2i(int n_location, int n_v0, int n_v1) const;

	/**
	 *	@brief specifies the value of an integer uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the first component of the new uniform value
	 *	@param[in] n_v1 is second component of the new uniform value
	 *	@param[in] n_v2 is third component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform3i(int n_location, int n_v0, int n_v1, int n_v2) const;

	/**
	 *	@brief specifies the value of an integer uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the first component of the new uniform value
	 *	@param[in] n_v1 is second component of the new uniform value
	 *	@param[in] n_v2 is third component of the new uniform value
	 *	@param[in] n_v3 is fourth component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform4i(int n_location, int n_v0, int n_v1, int n_v2, int n_v3) const;

	/**
	 *	@brief specifies the value of an unsigned integer uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform1ui(int n_location, unsigned int n_v0) const;

	/**
	 *	@brief specifies the value of an unsigned integer uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the first component of the new uniform value
	 *	@param[in] n_v1 is second component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform2ui(int n_location, unsigned int n_v0, unsigned int n_v1) const;

	/**
	 *	@brief specifies the value of an unsigned integer uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the first component of the new uniform value
	 *	@param[in] n_v1 is second component of the new uniform value
	 *	@param[in] n_v2 is third component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform3ui(int n_location, unsigned int n_v0, unsigned int n_v1, unsigned int n_v2) const;

	/**
	 *	@brief specifies the value of an unsigned integer uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_v0 is the first component of the new uniform value
	 *	@param[in] n_v1 is second component of the new uniform value
	 *	@param[in] n_v2 is third component of the new uniform value
	 *	@param[in] n_v3 is fourth component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform4ui(int n_location, unsigned int n_v0, unsigned int n_v1,
		unsigned int n_v2, unsigned int n_v3) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point
	 *		uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform1d(int n_location, double f_v0) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point
	 *		uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the first component of the new uniform value
	 *	@param[in] f_v1 is second component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform2d(int n_location, double f_v0, double f_v1) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point
	 *		uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the first component of the new uniform value
	 *	@param[in] f_v1 is second component of the new uniform value
	 *	@param[in] f_v2 is third component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform3d(int n_location, double f_v0, double f_v1, double f_v2) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point
	 *		uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] f_v0 is the first component of the new uniform value
	 *	@param[in] f_v1 is second component of the new uniform value
	 *	@param[in] f_v2 is third component of the new uniform value
	 *	@param[in] f_v3 is fourth component of the new uniform value
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform4d(int n_location, double f_v0, double f_v1, double f_v2, double f_v3) const;

	/**
	 *	@brief specifies the value of a uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] p_value is pointer to the array containing the new uniform value(s)
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform1fv(int n_location, int n_count, const GLfloat *p_value) const;

	/**
	 *	@copydoc ProgramUniform1fv
	 */
	inline void ProgramUniform2fv(int n_location, int n_count, const GLfloat *p_value) const;

	/**
	 *	@copydoc ProgramUniform1fv
	 */
	inline void ProgramUniform3fv(int n_location, int n_count, const GLfloat *p_value) const;

	/**
	 *	@copydoc ProgramUniform1fv
	 */
	inline void ProgramUniform4fv(int n_location, int n_count, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of an integer uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] p_value is pointer to the array containing the new uniform value(s)
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform1iv(int n_location, int n_count, const GLint *p_value) const;

	/**
	 *	@copydoc ProgramUniform1iv
	 */
	inline void ProgramUniform2iv(int n_location, int n_count, const GLint *p_value) const;

	/**
	 *	@copydoc ProgramUniform1iv
	 */
	inline void ProgramUniform3iv(int n_location, int n_count, const GLint *p_value) const;

	/**
	 *	@copydoc ProgramUniform1iv
	 */
	inline void ProgramUniform4iv(int n_location, int n_count, const GLint *p_value) const;

	/**
	 *	@brief specifies the value of an unsigned integer uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] p_value is pointer to the array containing the new uniform value(s)
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform1uiv(int n_location, int n_count, const GLuint *p_value) const;
	
	/**
	 *	@copydoc ProgramUniform1uiv
	 */
	inline void ProgramUniform2uiv(int n_location, int n_count, const GLuint *p_value) const;
	
	/**
	 *	@copydoc ProgramUniform1uiv
	 */
	inline void ProgramUniform3uiv(int n_location, int n_count, const GLuint *p_value) const;
	
	/**
	 *	@copydoc ProgramUniform1uiv
	 */
	inline void ProgramUniform4uiv(int n_location, int n_count, const GLuint *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision floating-point
	 *		uniform variable for this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] p_value is pointer to the array containing the new uniform value(s)
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniform1dv(int n_location, int n_count, const double *p_value) const;
	
	/**
	 *	@copydoc ProgramUniform1dv
	 */
	inline void ProgramUniform2dv(int n_location, int n_count, const double *p_value) const;
	
	/**
	 *	@copydoc ProgramUniform1dv
	 */
	inline void ProgramUniform3dv(int n_location, int n_count, const double *p_value) const;
	
	/**
	 *	@copydoc ProgramUniform1dv
	 */
	inline void ProgramUniform4dv(int n_location, int n_count, const double *p_value) const;

	/**
	 *	@brief specifies the value of a 2x2 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 2x2 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix2fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 3x3 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 3x3 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix3fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 4x4 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 4x4 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix4fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision 2x2 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 2x2 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix2dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision 3x3 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 3x3 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix3dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision 4x4 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 4x4 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix4dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a 2x3 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 2x3 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix2x3fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 3x2 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 3x2 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix3x2fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 2x4 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 2x4 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix2x4fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 4x2 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 4x2 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix4x2fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 3x4 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 3x4 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix3x4fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a 4x3 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 4x3 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix4x3fv(int n_location, int n_count, bool b_transpose, const GLfloat *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision 2x3 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 2x3 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix2x3dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision 3x2 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 3x2 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix3x2dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision 2x4 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 2x4 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix2x4dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision 4x2 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 4x2 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix4x2dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision 3x4 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 3x4 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix3x4dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;

	/**
	 *	@brief specifies the value of a double-precision 4x3 matrix uniform variable for the this program object
	 *
	 *	@param[in] n_location is location of the uniform (returned by n_Get_Uniform_Location())
	 *	@param[in] n_count is number of elements that are to be modified (1 for scalars, 1 or more for arrays)
	 *	@param[in] b_transpose is transpose flag (set it if the matrix (matrices)
	 *		should be transposed before loading to the uniforms)
	 *	@param[in] p_value is pointer to the array of n_count 4x3 matrices
	 *
	 *	@note This is part of OpenGL 4.1 core (or GL_ARB_separate_shader_objects extension)).
	 *		This also requires the GL_ARB_gpu_shader_fp64 extension (part of OpenGL 4.0 core).
	 *	@note This doesn't require the shader to be bound or active.
	 *	@note The values set are retained until the program is (successfully) relinked.
	 */
	inline void ProgramUniformMatrix4x3dv(int n_location, int n_count, bool b_transpose, const double *p_value) const;
#endif // 0

	/**
	 *	@brief binds a (range of) buffer object as GL_UNIFORM_BUFFER and attaches it to this program object
	 *
	 *	@param[in] n_block_index is uniform block index
	 *	@param[in] n_block_binding is number of uniform block binding point
	 *		(must be less than value of n_UniformBuffer_MaxBinding_Num())
	 *	@param[in] n_buffer_object is name of uniform buffer object, containing the data
	 *	@param[in] n_offset is offset to uniform data, in bytes
	 *	@param[in] n_size is size of uniform data, in bytes
	 *
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	void UniformBuffer(GLuint n_block_index, GLuint n_block_binding,
		GLint n_buffer_object, GLintptr n_offset, GLsizeiptr n_size);

	/**
	 *	@brief binds a buffer object as GL_UNIFORM_BUFFER and attaches it to this program object
	 *
	 *	@param[in] n_block_index is uniform block index
	 *	@param[in] n_block_binding is number of uniform block binding point
	 *		(must be less than value of n_UniformBuffer_MaxBinding_Num())
	 *	@param[in] n_buffer_object is name of uniform buffer object, containing the data
	 *
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	void UniformBuffer(GLuint n_block_index, GLuint n_block_binding, GLint n_buffer_object);

	/**
	 *	@brief attaches bound uniform buffer to this program object
	 *
	 *	@param[in] n_block_index is uniform block index
	 *	@param[in] n_block_binding is number of uniform block binding point
	 *		the buffer containing the uniform data is bound to
	 *		(must be less than value of n_UniformBuffer_MaxBinding_Num())
	 *
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	void UniformBlock(GLuint n_block_index, GLuint n_block_binding);

	/**
	 *	@brief gets maximal number of vertex attributes
	 *	@return Returns maximal number of vertex attributes.
	 */
	static int n_Vertex_MaxVertexAttrib_Num();

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief gets maximal number of uniforms accessed in vertex shader
	 *	@return Returns maximal number of uniforms accessed in vertex shader.
	 */
	static int n_Vertex_MaxUniformComponent_Num();

	/**
	 *	@brief gets maximal number of uniform blocks available in vertex shader
	 *	@return Returns maximal number of uniform blocks available in vertex shader.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	static int n_Vertex_MaxUniformBlock_Num();
#endif // 0

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief gets maximal number of uniforms accessed in vertex shader,
	 *		including the default uniform block and all possible named uniform blocks
	 *	@return Returns maximal number of uniforms accessed in vertex shader,
	 *		including the default uniform block and all possible named uniform blocks.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	static int n_Vertex_MaxCombinedUniformComponent_Num();

	/**
	 *	@brief gets maximal number of output components generated by vertex shader
	 *	@return Returns maximal number of output components generated by vertex shader.
	 */
	static int n_Vertex_MaxOutputComponent_Num();
#endif // 0

	/**
	 *	@brief gets maximal number of texture image units accessed in vertex shader
	 *	@return Returns maximal number of texture image units accessed in vertex shader
	 *		(0 means texture fetches are not allowed in vertex shader).
	 */
	static int n_Vertex_MaxTextureImageUnit_Num();

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief gets maximal number of vertex streams
	 *	@return Returns maximal number of vertex streams.
	 *	@note This function requires the GL_EXT_transform_feedback extension (part of OpenGL 3.0 core)
	 *		and the GL_ARB_gpu_shader5 extension (part of OpenGL 4.0 core).
	 */
	static int n_MaxVertexStream_Num();

	/**
	 *	@brief gets the maximal total number of interleaved components to capture
	 *	@return Returns the maximal total number of components to capture
	 *		if the buffer mode is GL_INTERLEAVED_ATTRIBS.
	 *	@note This function requires the GL_EXT_transform_feedback extension (part of OpenGL 3.0 core).
	 */
	static int n_TransformFeedback_MaxInterleavedComponent_Num();

	/**
	 *	@brief gets the total number of variables that may be captured in separate mode
	 *	@return Returns the total number of variables that may be captured in separate mode.
	 *	@note This function requires the GL_EXT_transform_feedback extension (part of OpenGL 3.0 core).
	 */
	static int n_TransformFeedback_MaxSeparateAttrib_Num();

	/**
	 *	@brief gets the maximal number of components to capture (in any variable)
	 *	@return Returns the maximal number of components to capture
	 *		if the buffer mode is GL_SEPARATED_ATTRIBS.
	 *	@note This function requires the GL_EXT_transform_feedback extension (part of OpenGL 3.0 core).
	 */
	static int n_TransformFeedback_MaxSeparateComponent_Num();

	/**
	 *	@brief gets maximal number of uniforms accessed in tessellation control shader
	 *	@return Returns maximal number of uniforms accessed in tessellation control shader.
	 *	@note This function requires the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessControl_MaxUniformComponent_Num();

	/**
	 *	@brief gets maximal number of per-vertex output components generated by tessellation control shader
	 *	@return Returns maximal number of output components
	 *		generated by tessellation control shader.
	 *	@note This function requires the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessControl_MaxOutputComponent_Num();

	/**
	 *	@brief gets maximal number of per-patch output components generated by tessellation control shader
	 *	@return Returns maximal number of per-patch output components generated by tessellation control shader.
	 *	@note This function requires the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessControl_MaxPatchComponent_Num();

	/**
	 *	@brief gets maximal number of uniform blocks available in tessellation control shader
	 *	@return Returns maximal number of uniform blocks available in tessellation control shader.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core)
	 *		and the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessControl_MaxUniformBlock_Num();

	/**
	 *	@brief gets maximal number of uniforms accessed in tessellation control shader,
	 *		including the default uniform block and all possible named uniform blocks
	 *	@return Returns maximal number of uniforms accessed in tessellation control shader,
	 *		including the default uniform block and all possible named uniform blocks.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core)
	 *		and the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessControl_MaxCombinedUniformComponent_Num();

	/**
	 *	@brief gets maximal number of output components generated by tessellation
	 *		control shader, including per-vertex and per-patch components
	 *	@return Returns maximal number of output components generated by tessellation
	 *		control shader, including per-vertex and per-patch components.
	 *	@note This function requires the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessControl_MaxTotalOutputComponent_Num();

	/**
	 *	@brief gets maximal number of input components passed to tessellation control shader
	 *	@return Returns maximal number of input components passed to tessellation control shader.
	 *	@note This function requires the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessControl_MaxInputComponent_Num();

	/**
	 *	@brief gets maximal number of texture image units accessed in tessellation control shader
	 *	@return Returns maximal number of texture image units accessed in control evaluation
	 *		shader (0 means texture fetches are not allowed in tessellation control shader).
	 *	@note This function requires the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessControl_MaxTextureImageUnit_Num();

	/**
	 *	@brief gets maximal number of uniforms accessed in tessellation evaluation shader
	 *	@return Returns maximal number of uniforms accessed in tessellation evaluation shader.
	 *	@note This function requires the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessEvaluation_MaxUniformComponent_Num();

	/**
	 *	@brief gets maximal number of uniform blocks available in tessellation evaluation shader
	 *	@return Returns maximal number of uniform blocks available in tessellation evaluation shader.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core)
	 *		and the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessEvaluation_MaxUniformBlock_Num();

	/**
	 *	@brief gets maximal number of uniforms accessed in tessellation evaluation shader,
	 *		including the default uniform block and all possible named uniform blocks
	 *	@return Returns maximal number of uniforms accessed in tessellation evaluation shader,
	 *		including the default uniform block and all possible named uniform blocks.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core)
	 *		and the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessEvaluation_MaxCombinedUniformComponent_Num();

	/**
	 *	@brief gets maximal number of input components passed to tessellation evaluation shader
	 *	@return Returns maximal number of input components passed to tessellation evaluation shader.
	 *	@note This function requires the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessEvaluation_MaxInputComponent_Num();

	/**
	 *	@brief gets maximal number of output components generated by tessellation evaluation shader
	 *	@return Returns maximal number of output
	 *		components generated by tessellation evaluation shader.
	 *	@note This function requires the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessEvaluation_MaxOutputComponent_Num();

	/**
	 *	@brief gets maximal number of texture image units accessed in tessellation evaluation shader
	 *	@return Returns maximal number of texture image units accessed in tessellation evaluation
	 *		shader (0 means texture fetches are not allowed in tessellation evaluation shader).
	 *	@note This function requires the GL_ARB_tessellation_shader extension (part of OpenGL 4.0 core).
	 */
	static int n_TessEvaluation_MaxTextureImageUnit_Num();

	/**
	 *	@brief gets maximal number of uniforms accessed in geometry shader
	 *	@return Returns maximal number of uniforms accessed in geometry shader.
	 *	@note This function requires the GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core).
	 */
	static int n_Geometry_MaxUniformComponent_Num();

	/**
	 *	@brief gets maximal number of uniform blocks available in geometry shader
	 *	@return Returns maximal number of uniform blocks available in geometry shader.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	static int n_Geometry_MaxUniformBlock_Num();

	/**
	 *	@brief gets maximal number of uniforms accessed in geometry shader,
	 *		including the default uniform block and all possible named uniform blocks
	 *	@return Returns maximal number of uniforms accessed in geometry shader,
	 *		including the default uniform block and all possible named uniform blocks.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core)
	 *		and the GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core).
	 */
	static int n_Geometry_MaxCombinedUniformComponent_Num();

	/**
	 *	@brief gets maximal number of output components generated by geometry shader
	 *	@return Returns maximal number of output components generated by geometry shader.
	 *	@note This function requires the GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core).
	 */
	static int n_Geometry_MaxOutputComponent_Num();

	/**
	 *	@brief gets maximal number of vertices emitted by geometry shader
	 *	@return Returns maximal number of vertices emitted by geometry shader in a single
	 *		invocation (ie. the maximal value of Set_Geometry_VerticesOut() argument).
	 *	@note This function requires the GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core).
	 */
	static int n_Geometry_MaxOutputVertex_Num();

	/**
	 *	@brief gets the maximal number of vertex components produced by a geometry shader
	 *	@return Returns the maximal number of all vertex components produced
	 *		by a geometry shader in a single invocation.
	 *	@note This function requires the GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core).
	 */
	static int n_Geometry_MaxTotalOutputComponent_Num();

	/**
	 *	@brief gets the maximal number of vertex components produced by a geometry shader
	 *	@return Returns the maximal number of all vertex components produced
	 *		by a geometry shader in a single invocation.
	 *	@note This function requires the GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core).
	 */
	static int n_Geometry_MaxInvocation_Num();

	/**
	 *	@brief gets maximal number of texture image units accessed in geometry shader
	 *	@return Returns maximal number of texture image units accessed in geometry
	 *		shader (0 means texture fetches are not allowed in geometry shader).
	 *	@note This function requires the GL_ARB_geometry_shader4 extension (part of OpenGL 3.2 core)
	 *		and the GL_ARB_gpu_shader5 extension (part of OpenGL 4.0 core).
	 */
	static int n_Geometry_MaxTextureImageUnit_Num();
#endif // 0

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief gets maximal number of uniforms accessed in fragment shader
	 *	@return Returns maximal number of uniforms accessed in fragment shader.
	 */
	static int n_Fragment_MaxUniformComponent_Num();

	/**
	 *	@brief gets maximal number of uniform blocks available in fragment shader
	 *	@return Returns maximal number of uniform blocks available in fragment shader.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	static int n_Fragment_MaxUniformBlock_Num();

	/**
	 *	@brief gets maximal number of uniforms accessed in fragment shader,
	 *		including the default uniform block and all possible named uniform blocks
	 *	@return Returns maximal number of uniforms accessed in fragment shader,
	 *		including the default uniform block and all possible named uniform blocks.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	static int n_Fragment_MaxCombinedUniformComponent_Num();
#endif // 0

	/**
	 *	@brief gets maximal number of texture image units accessed in fragment shader
	 *	@return Returns maximal number of texture image units accessed in fragment
	 *		shader (0 means texture fetches are not allowed in fragment shader).
	 */
	static int n_Fragment_MaxTextureImageUnit_Num();

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief gets minimal value of texture interpolation offset
	 *	@return Returns minimal value of texture interpolation offset.
	 *	@note This function requires the GL_ARB_gpu_shader5 extension (part of OpenGL 4.0 core).
	 */
	static float f_Fragment_MinInterpolationOffset();

	/**
	 *	@brief gets maximal value of texture interpolation offset
	 *	@return Returns maximal value of texture interpolation offset.
	 *	@note This function requires the GL_ARB_gpu_shader5 extension (part of OpenGL 4.0 core).
	 */
	static float f_Fragment_MaxInterpolationOffset();

	/**
	 *	@brief gets number of bits that are used to reprezent texture interpolation offset
	 *	@return Returns number of bits that are used to reprezent texture interpolation offset.
	 *	@note This function requires the GL_ARB_gpu_shader5 extension (part of OpenGL 4.0 core).
	 */
	static int n_Fragment_InterpolationOffsetBit_Num();

	/**
	 *	@brief gets maximal number of dual-source draw buffers
	 *	@return Returns maximal number of dual-source draw buffers.
	 *	@note This function requires the GL_ARB_blend_func_extended extension (part of OpenGL 3.3 core).
	 */
	static int n_MaxDualSourceDrawBuffer_Num();
#endif // 0

	/**
	 *	@brief gets maximal combined number of texture image units used by the shaders
	 *	@return Returns maximal combined number of texture image units used by the shaders.
	 */
	static int n_MaxTextureImageUnit_Num();

	/**
	 *	@brief gets shading language version
	 *	@return Returns shading language version string.
	 */
	static const char *p_s_ShadingLanguge_Version();

#if 0 // not (yet) in OpenGL ES 2.0
	/**
	 *	@brief gets number of program binary formats
	 *	@return Returns number of program binary formats.
	 *	@note This function requires the GL_ARB_get_program_binary extension (part of OpenGL 4.1 core).
	 */
	static size_t n_Program_BinaryFormat_Num();

	/**
	 *	@brief gets a list of program binary formats
	 *
	 *	@param[out] r_format_list is the list to be filled with the formats
	 *		(it's size will be n_Program_BinaryFormat_Num())
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note The application rarely needs to know the actual names of supported
	 *		binary formats (binary formats are returned by Get_Program_Binary() and
	 *		all the application needs to do is to supply the returned value
	 *		to FromBinary() once loading the binary). This is kept mostly for
	 *		reference purposes and for the needs of the GLExt2 application.
	 *	@note This function requires the GL_ARB_get_program_binary extension (part of OpenGL 4.1 core).
	 */
	static bool Get_Program_BinaryFormats(std::vector<GLenum> &r_format_list);

	/**
	 *	@brief gets maximal number of uniform blocks available in total
	 *	@return Returns maximal number of uniform blocks available in total.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	static int n_MaxUniformBlock_Num();

	/**
	 *	@brief gets maximal uniform block size, in bytes
	 *	@return Returns maximal uniform block size, in bytes.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	static size_t n_MaxUniformBlock_Size();

	/**
	 *	@brief gets number of available uniform block binding points
	 *	@return Returns number of available uniform block binding points.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	static int n_UniformBuffer_MaxBinding_Num();

	/**
	 *	@brief gets uniform block offset alignment
	 *	@return Returns uniform block offset alignment, in bytes.
	 *	@note This function requires the GL_ARB_uniform_buffer_object extension (part of OpenGL 3.1 core).
	 */
	static int n_UniformBuffer_OffsetAlignment();
#endif // 0

protected:
	template <class CGetFunction>
	bool Get_VariableName(GLuint n_index, std::string &r_s_name, GLenum &r_n_data_type,
		int &r_n_size, CGetFunction func, GLenum n_longest_item_name) const;
	inline GLenum n_Get_Mode(GLenum n_name) const;
	inline size_t n_Get_Quantity(GLenum n_name) const;
	inline bool b_Get_State(GLenum n_name) const;
	static bool b_IsInteger(const std::string &r_s_string);
	static bool b_IsGLEnum(const std::string &r_s_string);
	static inline int b_IsIdentChar(int n_char, bool b_first_char);
	static inline int b_IsValueChar(int n_char, bool b_first_char);
	bool Get_ShaderList(std::vector<GLuint> &r_shader_list) const;

private:
	inline CGLESShader(const CGLESShader &UNUSED(r_shader)) {} /**< @brief copy-constructor (cannot be used) */
	inline CGLESShader &operator =(const CGLESShader &UNUSED(r_shader)) { return *this; } /**< @brief copy-operator (cannot be used) */
};

#include "Shader.inl"
// fast inline functions

#endif // !__GLES20_SHADER_INCLUDED
