You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1322 lines
60 KiB

#ifndef Magnum_AbstractShaderProgram_h
#define Magnum_AbstractShaderProgram_h
/*
15 years ago
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
/** @file
* @brief Class Magnum::AbstractShaderProgram
*/
#include <string>
#include <Containers/EnumSet.h>
#include "Magnum.h"
#include "magnumVisibility.h"
/** @todo early asserts (no bool returns?) */
namespace Magnum {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<class> struct Attribute;
template<class> struct AttributeTraits;
}
#endif
/**
14 years ago
@brief Base for shader program implementations
@section AbstractShaderProgram-subclassing Subclassing workflow
This class is designed to be used via subclassing. Subclasses define these
functions and properties:
- <strong>%Attribute definitions</strong> with location and type for
configuring meshes, for example:
@code
typedef Attribute<0, Point3D> Position;
typedef Attribute<1, Vector3> Normal;
typedef Attribute<2, Vector2> TextureCoordinates;
@endcode
- **Output attribute locations**, if desired, for example:
@code
enum: GLuint {
ColorOutput = 0,
NormalOutput = 1
};
@endcode
- **Layers for texture uniforms** to which the textures will be bound before
rendering, for example:
@code
enum: GLint {
DiffuseTextureLayer = 0,
SpecularTextureLayer = 1
};
@endcode
- **Uniform locations** for setting uniform data (see below) (private
variables), for example:
@code
GLint TransformationUniform = 0,
ProjectionUniform = 1,
DiffuseTextureUniform = 2,
SpecularTextureUniform = 3;
@endcode
- **Constructor**, which attaches particular shaders, links the program and
gets uniform locations, for example:
@code
MyShader() {
// Load shaders from file and attach them to the program
attachShader(Shader::fromFile(Version::430, Shader::Type::Vertex, "PhongShader.vert"));
attachShader(Shader::fromFile(Version::430, Shader::Type::Fragment, "PhongShader.frag"));
// Link
link();
}
@endcode
- **Uniform setting functions**, which will provide public interface for
protected setUniform() functions. For usability purposes you can implement
also method chaining. Example:
@code
MyShader* setTransformation(const Matrix4& matrix) {
setUniform(TransformationUniform, matrix);
return this;
}
MyShader* setProjection(const Matrix4& matrix) {
setUniform(ProjectionUniform, matrix);
return this;
}
@endcode
@subsection AbstractShaderProgram-attribute-location Binding attribute location
The preferred workflow is to specify attribute location for vertex shader
input attributes and fragment shader output attributes explicitly in the
shader code, e.g.:
@code
// GLSL 3.30, or
#extension GL_ARB_explicit_attrib_location: enable
layout(location = 0) in vec4 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 textureCoordinates;
@endcode
Similarly for ouput attributes, you can also specify blend equation color
index for them (see Framebuffer::BlendFunction for more information about
using color input index):
@code
layout(location = 0, index = 0) out vec4 color;
layout(location = 1, index = 1) out vec3 normal;
@endcode
If you don't have the required extension, you can use functions
bindAttributeLocation() and bindFragmentDataLocation() /
bindFragmentDataLocationIndexed() between attaching the shaders and linking
the program:
@code
// Shaders attached...
bindAttributeLocation(Position::Location, "position");
bindAttributeLocation(Normal::Location, "normal");
bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
bindFragmentDataLocationIndexed(ColorOutput, 0, "color");
bindFragmentDataLocationIndexed(NormalOutput, 1, "normal");
// Link...
@endcode
@requires_gl30 %Extension @extension{EXT,gpu_shader4} for using
bindFragmentDataLocation().
@requires_gl33 %Extension @extension{ARB,blend_func_extended} for using
bindFragmentDataLocationIndexed().
@requires_gl33 %Extension @extension{ARB,explicit_attrib_location} for
explicit attribute location instead of using bindAttributeLocation(),
bindFragmentDataLocation() or bindFragmentDataLocationIndexed().
@requires_gles30 Explicit location specification of input attributes is not
supported in OpenGL ES 2.0, use bindAttributeLocation() instead.
@requires_gles30 Multiple fragment shader outputs are not available in OpenGL
ES 2.0, similar functionality is available in extension
@extension{NV,draw_buffers}.
@subsection AbstractShaderProgram-uniform-location Uniform locations
The preferred workflow is to specify uniform locations directly in the shader
code, e.g.:
@code
// GLSL 4.30, or
#extension GL_ARB_explicit_uniform_location: enable
layout(location = 0) uniform mat4 transformation;
layout(location = 1) uniform mat4 projection;
@endcode
If you don't have the required extension, you can get uniform location using
uniformLocation() after linking stage:
@code
GLint transformationUniform = uniformLocation("transformation");
GLint projectionUniform = uniformLocation("projection");
@endcode
14 years ago
@requires_gl43 %Extension @extension{ARB,explicit_uniform_location} for
explicit uniform location instead of using uniformLocation().
@requires_gl Explicit uniform location is not supported in OpenGL ES. Use
uniformLocation() instead.
@subsection AbstractShaderProgram-texture-layer Binding texture layer uniforms
The preferred workflow is to specify texture layers directly in the shader
code, e.g.:
@code
// GLSL 4.20, or
#extension GL_ARB_shading_language_420pack: enable
layout(binding = 0) uniform sampler2D diffuseTexture;
layout(binding = 1) uniform sampler2D specularTexture;
@endcode
If you don't have the required extension (or if you want to change the layer
later), you can set the texture layer uniform using setUniform(GLint, GLint):
@code
setUniform(DiffuseTextureUniform, DiffuseTextureLayer);
setUniform(SpecularTextureUniform, SpecularTextureLayer);
@endcode
14 years ago
@requires_gl42 %Extension @extension{ARB,shading_language_420pack} for explicit
texture layer binding instead of using setUniform(GLint, GLint).
@requires_gl Explicit texture layer binding is not supported in OpenGL ES. Use
setUniform(GLint, GLint) instead.
@section AbstractShaderProgram-rendering-workflow Rendering workflow
Basic workflow with %AbstractShaderProgram subclasses is: instance shader
class, configure attribute binding in meshes (see @ref Mesh-configuration "Mesh documentation"
for more information) and map shader outputs to framebuffer attachments if
needed (see @ref Framebuffer-usage "Framebuffer documentation" for more
information). In each draw event set uniforms, mark the shader for use, bind
specific framebuffer (if needed) and bind required textures to their
respective layers using AbstractTexture::bind(GLint). Then call Mesh::draw().
Example:
@code
shader->setTransformation(transformation)
->setProjection(projection)
->use();
diffuseTexture->bind(MyShader::DiffuseTextureLayer);
specularTexture->bind(MyShader::SpecularTextureLayer);
mesh.draw();
@endcode
@section AbstractShaderProgram-types Mapping between GLSL and Magnum types
- `vec2`, `vec3` and `vec4` is @ref Math::Vector "Math::Vector<2, GLfloat>",
@ref Math::Vector "Math::Vector<3, GLfloat>" and
@ref Math::Vector "Math::Vector<4, GLfloat>".
- `mat2`, `mat3` and `mat4` is @ref Math::Matrix "Math::Matrix<2, GLfloat>",
@ref Math::Matrix "Math::Matrix<3, GLfloat>" and
@ref Math::Matrix "Math::Matrix<4, GLfloat>".
- `mat2x3`, `mat3x2`, `mat2x4`, `mat4x2`, `mat3x4`, `mat4x3` is
@ref Math::RectangularMatrix "Math::RectangularMatrix<2, 3, GLfloat>",
@ref Math::RectangularMatrix "Math::RectangularMatrix<3, 2, GLfloat>",
@ref Math::RectangularMatrix "Math::RectangularMatrix<2, 4, GLfloat>",
@ref Math::RectangularMatrix "Math::RectangularMatrix<4, 2, GLfloat>",
@ref Math::RectangularMatrix "Math::RectangularMatrix<3, 4, GLfloat>" and
@ref Math::RectangularMatrix "Math::RectangularMatrix<4, 3, GLfloat>".
- `ivec2`, `ivec3` and `ivec4` is @ref Math::Vector "Math::Vector<2, GLint>",
@ref Math::Vector "Math::Vector<3, GLint>" and
@ref Math::Vector "Math::Vector<4, GLint>", `uvec2`, `uvec3` and `uvec4` is
@ref Math::Vector "Math::Vector<2, GLuint>",
@ref Math::Vector "Math::Vector<3, GLuint>" and
@ref Math::Vector "Math::Vector<4, GLuint>".
@requires_gl30 %Extension @extension{EXT,gpu_shader4} (for integer attributes
and unsigned integer uniforms)
@requires_gles30 Integer attributes and unsigned integer uniforms are not
available in OpenGL ES 2.0.
- `dvec2`, `dvec3` and `dvec4` is @ref Math::Vector "Math::Vector<2, GLdouble>",
@ref Math::Vector "Math::Vector<3, GLdouble>" and
@ref Math::Vector "Math::Vector<4, GLdouble>", `dmat2`, `dmat3` and `dmat4`
is @ref Math::Matrix "Math::Matrix<2, GLdouble>",
@ref Math::Matrix "Math::Matrix<3, GLdouble>" and
@ref Math::Matrix "Math::Matrix<4, GLdouble>", `dmat2x3`, `dmat3x2`,
`dmat2x4`, `dmat4x2`, `dmat3x4`, `dmat4x3` is
@ref Math::RectangularMatrix "Math::RectangularMatrix<2, 3, GLdouble>",
@ref Math::RectangularMatrix "Math::RectangularMatrix<3, 2, GLdouble>",
@ref Math::RectangularMatrix "Math::RectangularMatrix<2, 4, GLdouble>",
@ref Math::RectangularMatrix "Math::RectangularMatrix<4, 2, GLdouble>",
@ref Math::RectangularMatrix "Math::RectangularMatrix<3, 4, GLdouble>" and
@ref Math::RectangularMatrix "Math::RectangularMatrix<4, 3, GLdouble>".
@requires_gl41 %Extension @extension{ARB,vertex_attrib_64bit} (for double
attributes)
@requires_gl Double attributes are not available in OpenGL ES.
Only types listed here (and their subclasses and specializations, such as
@ref Matrix3 or Color4) can be used for setting uniforms and specifying
vertex attributes.
@section AbstractShaderProgram-performance-optimization Performance optimizations
The engine tracks currently used shader program to avoid unnecessary calls to
@fn_gl{UseProgram}. %Shader limits (such as maxSupportedVertexAttributeCount())
are cached, so repeated queries don't result in repeated @fn_gl{Get} calls.
If extension @extension{ARB,separate_shader_objects} or
@extension{EXT,direct_state_access} is available, uniform setting functions
use DSA functions to avoid unnecessary calls to @fn_gl{UseProgram}. See
setUniform(GLint, GLfloat) documentation for more information.
To achieve least state changes, set all uniforms in one run -- method chaining
comes in handy.
@todo Uniform arrays support
*/
class MAGNUM_EXPORT AbstractShaderProgram {
friend class Context;
AbstractShaderProgram(const AbstractShaderProgram& other) = delete;
AbstractShaderProgram(AbstractShaderProgram&& other) = delete;
AbstractShaderProgram& operator=(const AbstractShaderProgram& other) = delete;
AbstractShaderProgram& operator=(AbstractShaderProgram&& other) = delete;
public:
/**
* @brief Base struct for attribute location and type
*
* Template parameter @p location is vertex attribute location, number
* between `0` and maxSupportedVertexAttributeCount(). To ensure
* compatibility, you should always have vertex attribute with
* location `0`.
*
* Template parameter @p T is the type which is used for shader
* attribute, e.g. @ref Vector4i for `ivec4`. DataType is type of
* passed data when adding vertex buffers to mesh. By default it is
* the same as type used in shader (e.g. @ref DataType "DataType::Int"
* for @ref Vector4i). It's also possible to pass integer data to
* floating-point shader inputs. In this case you may want to
* normalize the values (e.g. color components from 0-255 to
* 0.0f - 1.0f) -- see @ref DataOption "DataOption::Normalize".
*
* Only some types are allowed as attribute types, see
* @ref AbstractShaderProgram-types or TypeTraits::AttributeType for
* more information.
*
* See @ref AbstractShaderProgram-subclassing for example usage in
* shaders and @ref Mesh-configuration for example usage when adding
* vertex buffers to mesh.
*/
template<GLuint location, class T> class Attribute {
public:
enum: GLuint {
Location = location /**< Location to which the attribute is bound */
};
/**
* @brief Type
*
* Type used in shader code.
* @see DataType
*/
typedef typename Implementation::AttributeTraits<T>::AttributeType Type;
/**
* @brief Data type
*
* Type of data passed to shader.
* @see Type, DataOptions, Attribute()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
enum class DataType: GLenum {
UnsignedByte = GL_UNSIGNED_BYTE, /**< Unsigned byte */
Byte = GL_BYTE, /**< Byte */
UnsignedShort = GL_UNSIGNED_SHORT, /**< Unsigned short */
Short = GL_SHORT, /**< Short */
UnsignedInt = GL_UNSIGNED_INT, /**< Unsigned int */
Int = GL_INT, /**< Int */
/**
* Half float. Only for float attribute types.
* @requires_gl30 %Extension @extension{NV,half_float}
* @requires_gles30 %Extension @es_extension{OES,vertex_half_float}
*/
HalfFloat = GL_HALF_FLOAT,
/** Float. Only for float attribute types. */
Float = GL_FLOAT,
#ifndef MAGNUM_TARGET_GLES
/**
* Double. Only for float and double attribute types.
* @requires_gl Only floats are available in OpenGL ES.
*/
Double = GL_DOUBLE,
#endif
/* GL_FIXED not supported */
#ifndef MAGNUM_TARGET_GLES2
/**
* Unsigned 2.10.10.10 packed integer. Only for
* four-component float vector attribute type.
* @todo How about (incompatible) @es_extension{OES,vertex_type_10_10_10_2}?
* @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev}
* @requires_gles30 (no extension providing this functionality)
*/
UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV,
/**
* Signed 2.10.10.10 packed integer. Only for
* four-component float vector attribute type.
* @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev}
* @requires_gles30 (no extension providing this functionality)
*/
Int2101010Rev = GL_INT_2_10_10_10_REV
#endif
};
#else
typedef typename Implementation::Attribute<T>::DataType DataType;
#endif
/**
* @brief Data option
* @see DataOptions, Attribute()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
enum class DataOption: std::uint8_t {
/**
* Normalize integer components. Only for float attribute
* types. Default is to not normalize.
*/
Normalize = 1 << 0,
/**
* BGRA component ordering. Default is RGBA. Only for
* four-component float vector attribute type.
* @requires_gl32 %Extension @extension{ARB,vertex_array_bgra}
* @requires_gl Only RGBA component ordering is supported
* in OpenGL ES.
*/
BGRA = 1 << 1
};
#else
typedef typename Implementation::Attribute<T>::DataOption DataOption;
#endif
/**
* @brief Data options
* @see Attribute()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
typedef typename Corrade::Containers::EnumSet<DataOption, std::uint8_t> DataOptions;
#else
typedef typename Implementation::Attribute<T>::DataOptions DataOptions;
#endif
/**
* @brief Constructor
* @param dataType Type of passed data. Default is the
* same as type used in shader (e.g. DataType::Integer
* for Vector4i).
* @param dataOptions Data options. Default is no options.
*/
inline constexpr Attribute(DataType dataType = Implementation::Attribute<T>::DefaultDataType, DataOptions dataOptions = DataOptions()): _dataType(dataType), _dataOptions(dataOptions) {}
/** @brief Type of passed data */
inline constexpr DataType dataType() const { return _dataType; }
/** @brief Size of passed data */
inline std::size_t dataSize() const {
return Implementation::Attribute<T>::size(Implementation::Attribute<T>::components(), _dataType);
}
/** @brief Data options */
inline constexpr DataOptions dataOptions() const { return _dataOptions; }
private:
const DataType _dataType;
const DataOptions _dataOptions;
};
/**
* @brief Max supported vertex attribute count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls.
* @see Attribute, @fn_gl{Get} with @def_gl{MAX_VERTEX_ATTRIBS}
*/
static GLint maxSupportedVertexAttributeCount();
/**
* @brief Constructor
*
* Creates one OpenGL shader program.
* @see @fn_gl{CreateProgram}
*/
inline explicit AbstractShaderProgram(): state(Initialized) {
_id = glCreateProgram();
}
/**
* @brief Destructor
*
* Deletes associated OpenGL shader program.
* @see @fn_gl{DeleteProgram}
*/
virtual ~AbstractShaderProgram() = 0;
/**
* @brief Use shader for rendering
* @return False if the program wasn't successfully linked, true
* otherwise.
*
* @see @fn_gl{UseProgram}
*/
bool use();
protected:
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Allow retrieving program binary
*
* Initially disabled.
* @note This function should be called after attachShader() calls and
* before link().
* @see @fn_gl{ProgramParameter} with @def_gl{PROGRAM_BINARY_RETRIEVABLE_HINT}
14 years ago
* @requires_gl41 %Extension @extension{ARB,get_program_binary}
* @requires_gles30 Always allowed in OpenGL ES 2.0.
*/
inline void setRetrievableBinary(bool enabled) {
glProgramParameteri(_id, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, enabled ? GL_TRUE : GL_FALSE);
}
#endif
/**
* @brief Allow the program to be bound to individual pipeline stages
*
* Initially disabled.
* @note This function should be called after attachShader() calls and
* before link().
* @see @fn_gl{ProgramParameter} with @def_gl{PROGRAM_SEPARABLE}
14 years ago
* @requires_gl41 %Extension @extension{ARB,separate_shader_objects}
* @requires_es_extension %Extension @es_extension{EXT,separate_shader_objects}
*/
inline void setSeparable(bool enabled) {
/** @todo Remove when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES
glProgramParameteri(_id, GL_PROGRAM_SEPARABLE, enabled ? GL_TRUE : GL_FALSE);
#else
static_cast<void>(enabled);
#endif
}
/**
* @brief Load shader
* @return False if the shader wasn't successfully compiled, true
* otherwise.
*
* Compiles the shader, if it is not already, and prepares it for
* linking.
* @see Shader::compile(), @fn_gl{AttachShader}
*/
bool attachShader(Shader& shader);
/** @overload */
inline bool attachShader(Shader&& shader) {
return attachShader(shader);
}
/**
* @brief Bind attribute to given location
* @param location Location
* @param name Attribute name
*
14 years ago
* Binds attribute to location which is used later for binding vertex
* buffers.
* @note This function should be called after attachShader() calls and
* before link().
* @deprecated Preferred usage is to specify attribute location
* explicitly in the shader instead of using this function. See
* @ref AbstractShaderProgram-attribute-location "class documentation"
* for more information.
* @see @fn_gl{BindAttribLocation}
*/
void bindAttributeLocation(GLuint location, const std::string& name);
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Bind fragment data to given location and color input index
* @param location Location
* @param name Fragment output variable name
* @param index Blend equation color input index (`0` or `1`)
*
* Binds fragment data to location which is used later for framebuffer
* operations. See also Framebuffer::BlendFunction for more
* information about using color input index.
* @note This function should be called after attachShader() calls and
* before link().
* @deprecated Preferred usage is to specify attribute location
* explicitly in the shader instead of using this function. See
* @ref AbstractShaderProgram-attribute-location "class documentation"
* for more information.
* @see @fn_gl{BindFragDataLocationIndexed}
14 years ago
* @requires_gl33 %Extension @extension{ARB,blend_func_extended}
* @requires_gl Multiple blend function inputs are not available in
* OpenGL ES.
*/
void bindFragmentDataLocationIndexed(GLuint location, GLuint index, const std::string& name);
/**
* @brief Bind fragment data to given location and first color input index
* @param location Location
* @param name Fragment output variable name
*
* The same as bindFragmentDataLocationIndexed(), but with `index` set
* to `0`.
* @see @fn_gl{BindFragDataLocation}
14 years ago
* @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gl Use explicit location specification in OpenGL ES 3.0
* instead.
*/
void bindFragmentDataLocation(GLuint location, const std::string& name);
#endif
/**
* @brief Link the shader
*
* Binds previously specified attributes to given indexes and links the
* shader program together.
* @see @fn_gl{LinkProgram}, @fn_gl{GetProgram} with
* @def_gl{LINK_STATUS}, @fn_gl{GetProgramInfoLog}
*/
void link();
/**
* @brief Get uniform location
* @param name Uniform name
*
* @note This function should be called after link().
* @deprecated Preferred usage is to specify uniform location
* explicitly in the shader instead of using this function. See
* @ref AbstractShaderProgram-uniform-location "class documentation"
* for more information.
* @see @fn_gl{GetUniformLocation}
*/
GLint uniformLocation(const std::string& name);
/**
* @brief Set uniform value
* @param location Uniform location (see uniformLocation())
* @param value Value
*
* If neither @extension{ARB,separate_shader_objects} nor
* @extension{EXT,direct_state_access} is available, the shader is
* marked for use before the operation.
* @see @fn_gl{UseProgram}, @fn_gl{Uniform} or `glProgramUniform()`
* from @extension{ARB,separate_shader_objects}/@extension{EXT,direct_state_access}.
*/
inline void setUniform(GLint location, GLfloat value) {
(this->*uniform1fImplementation)(location, value);
}
/** @copydoc setUniform(GLint, GLfloat) */
inline void setUniform(GLint location, const Math::Vector<2, GLfloat>& value) {
(this->*uniform2fvImplementation)(location, value);
}
/** @copydoc setUniform(GLint, GLfloat) */
inline void setUniform(GLint location, const Math::Vector<3, GLfloat>& value) {
(this->*uniform3fvImplementation)(location, value);
}
/** @copydoc setUniform(GLint, GLfloat) */
inline void setUniform(GLint location, const Math::Vector<4, GLfloat>& value) {
(this->*uniform4fvImplementation)(location, value);
}
/** @copydoc setUniform(GLint, GLfloat) */
inline void setUniform(GLint location, GLint value) {
(this->*uniform1iImplementation)(location, value);
}
/** @copydoc setUniform(GLint, GLfloat) */
inline void setUniform(GLint location, const Math::Vector<2, GLint>& value) {
(this->*uniform2ivImplementation)(location, value);
}
/** @copydoc setUniform(GLint, GLfloat) */
inline void setUniform(GLint location, const Math::Vector<3, GLint>& value) {
(this->*uniform3ivImplementation)(location, value);
}
/** @copydoc setUniform(GLint, GLfloat) */
inline void setUniform(GLint location, const Math::Vector<4, GLint>& value) {
(this->*uniform4ivImplementation)(location, value);
}
#ifndef MAGNUM_TARGET_GLES2
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gles30 Only signed integers are available in OpenGL ES 2.0.
*/
inline void setUniform(GLint location, GLuint value) {
(this->*uniform1uiImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gles30 Only signed integers are available in OpenGL ES 2.0.
*/
inline void setUniform(GLint location, const Math::Vector<2, GLuint>& value) {
(this->*uniform2uivImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gles30 Only signed integers are available in OpenGL ES 2.0.
*/
inline void setUniform(GLint location, const Math::Vector<3, GLuint>& value) {
(this->*uniform3uivImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gles30 Only signed integers are available in OpenGL ES 2.0.
*/
inline void setUniform(GLint location, const Math::Vector<4, GLuint>& value) {
(this->*uniform4uivImplementation)(location, value);
}
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, GLdouble value) {
(this->*uniform1dImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, const Math::Vector<2, GLdouble>& value) {
(this->*uniform2dvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, const Math::Vector<3, GLdouble>& value) {
(this->*uniform3dvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, const Math::Vector<4, GLdouble>& value) {
(this->*uniform4dvImplementation)(location, value);
}
#endif
/** @copydoc setUniform(GLint, GLfloat) */
inline void setUniform(GLint location, const Math::Matrix<2, GLfloat>& value) {
(this->*uniformMatrix2fvImplementation)(location, value);
}
/** @copydoc setUniform(GLint, GLfloat) */
inline void setUniform(GLint location, const Math::Matrix<3, GLfloat>& value) {
(this->*uniformMatrix3fvImplementation)(location, value);
}
/** @copydoc setUniform(GLint, GLfloat) */
inline void setUniform(GLint location, const Math::Matrix<4, GLfloat>& value) {
(this->*uniformMatrix4fvImplementation)(location, value);
}
#ifndef MAGNUM_TARGET_GLES2
/**
* @copydoc setUniform(GLint, GLfloat)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/
inline void setUniform(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) {
(this->*uniformMatrix2x3fvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/
inline void setUniform(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) {
(this->*uniformMatrix3x2fvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/
inline void setUniform(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) {
(this->*uniformMatrix2x4fvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/
inline void setUniform(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) {
(this->*uniformMatrix4x2fvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/
inline void setUniform(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) {
(this->*uniformMatrix3x4fvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/
inline void setUniform(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) {
(this->*uniformMatrix4x3fvImplementation)(location, value);
}
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, const Math::Matrix<2, GLdouble>& value) {
(this->*uniformMatrix2dvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, const Math::Matrix<3, GLdouble>& value) {
(this->*uniformMatrix3dvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, const Math::Matrix<4, GLdouble>& value) {
(this->*uniformMatrix4dvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value) {
(this->*uniformMatrix2x3dvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value) {
(this->*uniformMatrix3x2dvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value) {
(this->*uniformMatrix2x4dvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value) {
(this->*uniformMatrix4x2dvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value) {
(this->*uniformMatrix3x4dvImplementation)(location, value);
}
/**
* @copydoc setUniform(GLint, GLfloat)
14 years ago
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value) {
(this->*uniformMatrix4x3dvImplementation)(location, value);
}
#endif
private:
enum State {
Initialized,
Linked,
Failed
};
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
typedef void(AbstractShaderProgram::*Uniform1fImplementation)(GLint, GLfloat);
typedef void(AbstractShaderProgram::*Uniform2fvImplementation)(GLint, const Math::Vector<2, GLfloat>&);
typedef void(AbstractShaderProgram::*Uniform3fvImplementation)(GLint, const Math::Vector<3, GLfloat>&);
typedef void(AbstractShaderProgram::*Uniform4fvImplementation)(GLint, const Math::Vector<4, GLfloat>&);
typedef void(AbstractShaderProgram::*Uniform1iImplementation)(GLint, GLint);
typedef void(AbstractShaderProgram::*Uniform2ivImplementation)(GLint, const Math::Vector<2, GLint>&);
typedef void(AbstractShaderProgram::*Uniform3ivImplementation)(GLint, const Math::Vector<3, GLint>&);
typedef void(AbstractShaderProgram::*Uniform4ivImplementation)(GLint, const Math::Vector<4, GLint>&);
#ifndef MAGNUM_TARGET_GLES2
typedef void(AbstractShaderProgram::*Uniform1uiImplementation)(GLint, GLuint);
typedef void(AbstractShaderProgram::*Uniform2uivImplementation)(GLint, const Math::Vector<2, GLuint>&);
typedef void(AbstractShaderProgram::*Uniform3uivImplementation)(GLint, const Math::Vector<3, GLuint>&);
typedef void(AbstractShaderProgram::*Uniform4uivImplementation)(GLint, const Math::Vector<4, GLuint>&);
#endif
#ifndef MAGNUM_TARGET_GLES
typedef void(AbstractShaderProgram::*Uniform1dImplementation)(GLint, GLdouble);
typedef void(AbstractShaderProgram::*Uniform2dvImplementation)(GLint, const Math::Vector<2, GLdouble>&);
typedef void(AbstractShaderProgram::*Uniform3dvImplementation)(GLint, const Math::Vector<3, GLdouble>&);
typedef void(AbstractShaderProgram::*Uniform4dvImplementation)(GLint, const Math::Vector<4, GLdouble>&);
#endif
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLfloat value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLint value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLint>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLint>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLint>& value);
#ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLuint value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLuint>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLuint>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLuint>& value);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLdouble value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLfloat value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLint value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLint>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLint>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLint>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLuint value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLuint>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLuint>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLuint>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLdouble value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLdouble>& value);
#endif
static Uniform1fImplementation uniform1fImplementation;
static Uniform2fvImplementation uniform2fvImplementation;
static Uniform3fvImplementation uniform3fvImplementation;
static Uniform4fvImplementation uniform4fvImplementation;
static Uniform1iImplementation uniform1iImplementation;
static Uniform2ivImplementation uniform2ivImplementation;
static Uniform3ivImplementation uniform3ivImplementation;
static Uniform4ivImplementation uniform4ivImplementation;
#ifndef MAGNUM_TARGET_GLES2
static Uniform1uiImplementation uniform1uiImplementation;
static Uniform2uivImplementation uniform2uivImplementation;
static Uniform3uivImplementation uniform3uivImplementation;
static Uniform4uivImplementation uniform4uivImplementation;
#endif
#ifndef MAGNUM_TARGET_GLES
static Uniform1dImplementation uniform1dImplementation;
static Uniform2dvImplementation uniform2dvImplementation;
static Uniform3dvImplementation uniform3dvImplementation;
static Uniform4dvImplementation uniform4dvImplementation;
#endif
typedef void(AbstractShaderProgram::*UniformMatrix2fvImplementation)(GLint, const Math::Matrix<2, GLfloat>&);
typedef void(AbstractShaderProgram::*UniformMatrix3fvImplementation)(GLint, const Math::Matrix<3, GLfloat>&);
typedef void(AbstractShaderProgram::*UniformMatrix4fvImplementation)(GLint, const Math::Matrix<4, GLfloat>&);
#ifndef MAGNUM_TARGET_GLES2
typedef void(AbstractShaderProgram::*UniformMatrix2x3fvImplementation)(GLint, const Math::RectangularMatrix<2, 3, GLfloat>&);
typedef void(AbstractShaderProgram::*UniformMatrix3x2fvImplementation)(GLint, const Math::RectangularMatrix<3, 2, GLfloat>&);
typedef void(AbstractShaderProgram::*UniformMatrix2x4fvImplementation)(GLint, const Math::RectangularMatrix<2, 4, GLfloat>&);
typedef void(AbstractShaderProgram::*UniformMatrix4x2fvImplementation)(GLint, const Math::RectangularMatrix<4, 2, GLfloat>&);
typedef void(AbstractShaderProgram::*UniformMatrix3x4fvImplementation)(GLint, const Math::RectangularMatrix<3, 4, GLfloat>&);
typedef void(AbstractShaderProgram::*UniformMatrix4x3fvImplementation)(GLint, const Math::RectangularMatrix<4, 3, GLfloat>&);
#endif
#ifndef MAGNUM_TARGET_GLES
typedef void(AbstractShaderProgram::*UniformMatrix2dvImplementation)(GLint, const Math::Matrix<2, GLdouble>&);
typedef void(AbstractShaderProgram::*UniformMatrix3dvImplementation)(GLint, const Math::Matrix<3, GLdouble>&);
typedef void(AbstractShaderProgram::*UniformMatrix4dvImplementation)(GLint, const Math::Matrix<4, GLdouble>&);
typedef void(AbstractShaderProgram::*UniformMatrix2x3dvImplementation)(GLint, const Math::RectangularMatrix<2, 3, GLdouble>&);
typedef void(AbstractShaderProgram::*UniformMatrix3x2dvImplementation)(GLint, const Math::RectangularMatrix<3, 2, GLdouble>&);
typedef void(AbstractShaderProgram::*UniformMatrix2x4dvImplementation)(GLint, const Math::RectangularMatrix<2, 4, GLdouble>&);
typedef void(AbstractShaderProgram::*UniformMatrix4x2dvImplementation)(GLint, const Math::RectangularMatrix<4, 2, GLdouble>&);
typedef void(AbstractShaderProgram::*UniformMatrix3x4dvImplementation)(GLint, const Math::RectangularMatrix<3, 4, GLdouble>&);
typedef void(AbstractShaderProgram::*UniformMatrix4x3dvImplementation)(GLint, const Math::RectangularMatrix<4, 3, GLdouble>&);
#endif
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<2, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<3, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<4, GLfloat>& value);
#ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<2, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<3, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<4, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<2, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<3, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<4, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<2, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<3, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<4, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value);
void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value);
#endif
static UniformMatrix2fvImplementation uniformMatrix2fvImplementation;
static UniformMatrix3fvImplementation uniformMatrix3fvImplementation;
static UniformMatrix4fvImplementation uniformMatrix4fvImplementation;
#ifndef MAGNUM_TARGET_GLES2
static UniformMatrix2x3fvImplementation uniformMatrix2x3fvImplementation;
static UniformMatrix3x2fvImplementation uniformMatrix3x2fvImplementation;
static UniformMatrix2x4fvImplementation uniformMatrix2x4fvImplementation;
static UniformMatrix4x2fvImplementation uniformMatrix4x2fvImplementation;
static UniformMatrix3x4fvImplementation uniformMatrix3x4fvImplementation;
static UniformMatrix4x3fvImplementation uniformMatrix4x3fvImplementation;
#endif
#ifndef MAGNUM_TARGET_GLES
static UniformMatrix2dvImplementation uniformMatrix2dvImplementation;
static UniformMatrix3dvImplementation uniformMatrix3dvImplementation;
static UniformMatrix4dvImplementation uniformMatrix4dvImplementation;
static UniformMatrix2x3dvImplementation uniformMatrix2x3dvImplementation;
static UniformMatrix3x2dvImplementation uniformMatrix3x2dvImplementation;
static UniformMatrix2x4dvImplementation uniformMatrix2x4dvImplementation;
static UniformMatrix4x2dvImplementation uniformMatrix4x2dvImplementation;
static UniformMatrix3x4dvImplementation uniformMatrix3x4dvImplementation;
static UniformMatrix4x3dvImplementation uniformMatrix4x3dvImplementation;
#endif
GLuint _id;
State state;
};
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<class> struct Attribute {};
template<> struct Attribute<GLfloat> {
enum class DataType: GLenum {
UnsignedByte = GL_UNSIGNED_BYTE,
Byte = GL_BYTE,
UnsignedShort = GL_UNSIGNED_SHORT,
Short = GL_SHORT,
UnsignedInt = GL_UNSIGNED_INT,
Int = GL_INT,
#ifndef MAGNUM_TARGET_GLES2
HalfFloat = GL_HALF_FLOAT,
#else
HalfFloat = GL_HALF_FLOAT_OES,
#endif
Float = GL_FLOAT
#ifndef MAGNUM_TARGET_GLES
,
Double = GL_DOUBLE
#endif
};
enum class DataOption: std::uint8_t {
Normalized = 1 << 0
};
typedef Corrade::Containers::EnumSet<DataOption, std::uint8_t> DataOptions;
static const DataType DefaultDataType = DataType::Float;
inline constexpr static GLint components(DataOptions = {}) { return 1; }
static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType);
inline constexpr static std::size_t vectorCount() { return 1; }
};
CORRADE_ENUMSET_OPERATORS(Attribute<GLfloat>::DataOptions)
template<std::size_t vectorSize> struct Attribute<Math::Vector<vectorSize, GLfloat>>: public Attribute<GLfloat> {
inline constexpr static GLint components(DataOptions = {}) { return vectorSize; }
inline constexpr static std::size_t vectorCount() { return 1; }
};
template<std::size_t cols, std::size_t rows> struct Attribute<Math::RectangularMatrix<cols, rows, GLfloat>>: public Attribute<GLfloat> {
inline constexpr static GLint components(DataOptions = {}) { return rows; }
inline constexpr static std::size_t vectorCount() { return cols; }
};
template<std::size_t matrixSize> struct Attribute<Math::Matrix<matrixSize, GLfloat>>: public Attribute<GLfloat> {
inline constexpr static GLint components(DataOptions = {}) { return matrixSize; }
inline constexpr static std::size_t vectorCount() { return matrixSize; }
};
template<> struct Attribute<Math::Vector<4, GLfloat>> {
enum class DataType: GLenum {
UnsignedByte = GL_UNSIGNED_BYTE,
Byte = GL_BYTE,
UnsignedShort = GL_UNSIGNED_SHORT,
Short = GL_SHORT,
UnsignedInt = GL_UNSIGNED_INT,
Int = GL_INT,
#ifndef MAGNUM_TARGET_GLES2
HalfFloat = GL_HALF_FLOAT,
#else
HalfFloat = GL_HALF_FLOAT_OES,
#endif
Float = GL_FLOAT
#ifndef MAGNUM_TARGET_GLES
,
Double = GL_DOUBLE
#endif
#ifndef MAGNUM_TARGET_GLES2
,
UnsignedInt2101010REV = GL_UNSIGNED_INT_2_10_10_10_REV,
Int2101010REV = GL_INT_2_10_10_10_REV
#endif
};
enum class DataOption: std::uint8_t {
Normalized = 1 << 0
#ifndef MAGNUM_TARGET_GLES
,
BGRA = 2 << 0
#endif
};
typedef Corrade::Containers::EnumSet<DataOption, std::uint8_t> DataOptions;
static const DataType DefaultDataType = DataType::Float;
#ifndef MAGNUM_TARGET_GLES
inline constexpr static GLint components(DataOptions options = {}) {
return options & DataOption::BGRA ? GL_BGRA : 4;
}
#else
inline constexpr static GLint components(DataOptions = {}) { return 4; }
#endif
static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType);
inline constexpr static std::size_t vectorCount() { return 1; }
};
typedef Math::Vector<4, GLfloat> _Vector4;
CORRADE_ENUMSET_OPERATORS(Attribute<_Vector4>::DataOptions)
template<> struct Attribute<GLint> {
enum class DataType: GLenum {
UnsignedByte = GL_UNSIGNED_BYTE,
Byte = GL_BYTE,
UnsignedShort = GL_UNSIGNED_SHORT,
Short = GL_SHORT,
UnsignedInt = GL_UNSIGNED_INT,
Int = GL_INT
};
enum class DataOption: std::uint8_t {};
typedef Corrade::Containers::EnumSet<DataOption, std::uint8_t> DataOptions;
static const DataType DefaultDataType = DataType::Int;
inline constexpr static GLint components() { return 1; }
static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType);
};
template<> struct Attribute<GLuint> {
typedef Attribute<GLint>::DataType DataType;
typedef Attribute<GLint>::DataOption DataOption;
typedef Corrade::Containers::EnumSet<DataOption, std::uint8_t> DataOptions;
static const DataType DefaultDataType = DataType::UnsignedInt;
inline constexpr static GLint components() { return 1; }
inline static std::size_t size(GLint components, DataType dataType) {
return Attribute<GLint>::size(components, dataType);
}
};
template<std::size_t size_> struct Attribute<Math::Vector<size_, GLint>>: public Attribute<GLint> {
inline constexpr static GLint components() { return size_; }
};
template<std::size_t size_> struct Attribute<Math::Vector<size_, GLuint>>: public Attribute<GLuint> {
inline constexpr static GLint components() { return size_; }
};
#ifndef MAGNUM_TARGET_GLES
template<> struct Attribute<GLdouble> {
enum class DataType: GLenum {
Double = GL_DOUBLE
};
enum class DataOption: std::uint8_t {};
typedef Corrade::Containers::EnumSet<DataOption, std::uint8_t> DataOptions;
static const DataType DefaultDataType = DataType::Double;
inline constexpr static GLint components() { return 1; }
inline constexpr static std::size_t vectorCount() { return 1; }
static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType);
};
template<std::size_t cols, std::size_t rows> struct Attribute<Math::RectangularMatrix<cols, rows, GLdouble>>: public Attribute<GLdouble> {
inline constexpr static GLint components() { return rows; }
inline constexpr static std::size_t vectorCount() { return cols; }
};
template<std::size_t size_> struct Attribute<Math::Matrix<size_, GLdouble>>: public Attribute<GLdouble> {
inline constexpr static GLint components() { return size_; }
inline constexpr static std::size_t vectorCount() { return size_; }
};
template<std::size_t size_> struct Attribute<Math::Vector<size_, GLdouble>>: public Attribute<GLdouble> {
inline constexpr static GLint components() { return size_; }
inline constexpr static std::size_t vectorCount() { return size_; }
};
#endif
template<class T> struct Attribute<Math::Vector2<T>>: public Attribute<Math::Vector<2, T>> {};
template<class T> struct Attribute<Math::Vector3<T>>: public Attribute<Math::Vector<3, T>> {};
template<class T> struct Attribute<Math::Vector4<T>>: public Attribute<Math::Vector<4, T>> {};
template<class T> struct Attribute<Math::Point2D<T>>: public Attribute<Math::Vector3<T>> {};
template<class T> struct Attribute<Math::Point3D<T>>: public Attribute<Math::Vector4<T>> {};
template<class T> struct Attribute<Color3<T>>: public Attribute<Math::Vector3<T>> {};
template<class T> struct Attribute<Color4<T>>: public Attribute<Math::Vector4<T>> {};
template<class T> struct Attribute<Math::Matrix3<T>>: public Attribute<Math::Matrix<3, T>> {};
template<class T> struct Attribute<Math::Matrix4<T>>: public Attribute<Math::Matrix<4, T>> {};
/* Types allowed as GLSL attributes */
template<> struct AttributeTraits<GLuint> { typedef GLuint AttributeType; };
template<> struct AttributeTraits<GLint> { typedef GLint AttributeType; };
template<> struct AttributeTraits<GLfloat> { typedef GLfloat AttributeType; };
#ifndef MAGNUM_TARGET_GLES
template<> struct AttributeTraits<GLdouble> { typedef GLdouble AttributeType; };
#endif
/* Only some vectors can be used as attributes */
template<class> struct VectorAttributeTraits {};
template<> struct VectorAttributeTraits<GLuint> { typedef GLuint AttributeType; };
template<> struct VectorAttributeTraits<GLint> { typedef GLint AttributeType; };
template<> struct VectorAttributeTraits<GLfloat> { typedef GLfloat AttributeType; };
#ifndef MAGNUM_TARGET_GLES
template<> struct VectorAttributeTraits<GLdouble> { typedef GLdouble AttributeType; };
#endif
template<class T> struct AttributeTraits<Math::Vector<2, T>>: VectorAttributeTraits<T> {};
template<class T> struct AttributeTraits<Math::Vector<3, T>>: VectorAttributeTraits<T> {};
template<class T> struct AttributeTraits<Math::Vector<4, T>>: VectorAttributeTraits<T> {};
template<class T> struct AttributeTraits<Math::Vector2<T>>: AttributeTraits<Math::Vector<2, T>> {};
template<class T> struct AttributeTraits<Math::Vector3<T>>: AttributeTraits<Math::Vector<3, T>> {};
template<class T> struct AttributeTraits<Math::Vector4<T>>: AttributeTraits<Math::Vector<4, T>> {};
template<class T> struct AttributeTraits<Math::Point2D<T>>: AttributeTraits<Math::Vector<3, T>> {};
template<class T> struct AttributeTraits<Math::Point3D<T>>: AttributeTraits<Math::Vector<4, T>> {};
template<class T> struct AttributeTraits<Color3<T>>: AttributeTraits<Math::Vector<3, T>> {};
template<class T> struct AttributeTraits<Color4<T>>: AttributeTraits<Math::Vector<4, T>> {};
/* Only some floating-point matrices can be used as attributes */
template<class> struct MatrixAttributeTraits {};
template<> struct MatrixAttributeTraits<GLfloat> { typedef GLfloat AttributeType; };
#ifndef MAGNUM_TARGET_GLES
template<> struct MatrixAttributeTraits<GLdouble> { typedef GLdouble AttributeType; };
#endif
template<class T> struct AttributeTraits<Math::RectangularMatrix<2, 2, T>>: MatrixAttributeTraits<T> {};
template<class T> struct AttributeTraits<Math::RectangularMatrix<3, 3, T>>: MatrixAttributeTraits<T> {};
template<class T> struct AttributeTraits<Math::RectangularMatrix<4, 4, T>>: MatrixAttributeTraits<T> {};
#ifndef MAGNUM_TARGET_GLES2
template<class T> struct AttributeTraits<Math::RectangularMatrix<2, 3, T>>: MatrixAttributeTraits<T> {};
template<class T> struct AttributeTraits<Math::RectangularMatrix<3, 2, T>>: MatrixAttributeTraits<T> {};
template<class T> struct AttributeTraits<Math::RectangularMatrix<2, 4, T>>: MatrixAttributeTraits<T> {};
template<class T> struct AttributeTraits<Math::RectangularMatrix<4, 2, T>>: MatrixAttributeTraits<T> {};
template<class T> struct AttributeTraits<Math::RectangularMatrix<3, 4, T>>: MatrixAttributeTraits<T> {};
template<class T> struct AttributeTraits<Math::RectangularMatrix<4, 3, T>>: MatrixAttributeTraits<T> {};
#endif
template<class T> struct AttributeTraits<Math::Matrix3<T>>: MatrixAttributeTraits<T> {};
template<class T> struct AttributeTraits<Math::Matrix4<T>>: MatrixAttributeTraits<T> {};
}
#endif
}
#endif