From beea8235b1590446153ca1eb51874d9a35e03ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 8 Oct 2012 16:55:03 +0200 Subject: [PATCH] Using EXT_direct_state_access/ARB_separate_shader_objects for uniforms. Also explicitly calling use() on default (non-DSA) setUniform() implementation. Because of that, it is now possible to conveniently call use() at the end, instead of at the beginning of uniform setting chain, for example: // before shader->use(); shader->setTransformation(transformation) ->setProjection(projection) ->setColor(color); // now shader->setTransformation(transformation) ->setProjection(projection) ->setColor(color) ->use(); Note that you still have to explicitly call use(), because if DSA is available, no use() is called explicitly on any setUniform(). If DSA is not available, use() is called on first setUniform() and subsequent calls have no negative performance impacts. --- src/AbstractShaderProgram.cpp | 399 ++++++++++++++++++++++++++++++++++ src/AbstractShaderProgram.h | 283 +++++++++++++++++++----- src/Context.cpp | 2 + 3 files changed, 626 insertions(+), 58 deletions(-) diff --git a/src/AbstractShaderProgram.cpp b/src/AbstractShaderProgram.cpp index feddb2c8a..f6c42240d 100644 --- a/src/AbstractShaderProgram.cpp +++ b/src/AbstractShaderProgram.cpp @@ -17,9 +17,11 @@ #include +#include "Math/Matrix.h" #include "Shader.h" #include "Implementation/State.h" #include "Implementation/ShaderProgramState.h" +#include "Extensions.h" #define LINKER_MESSAGE_MAX_LENGTH 1024 @@ -27,6 +29,46 @@ using namespace std; namespace Magnum { +AbstractShaderProgram::Uniform1fImplementation AbstractShaderProgram::uniform1fImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform2fvImplementation AbstractShaderProgram::uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform3fvImplementation AbstractShaderProgram::uniform3fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform4fvImplementation AbstractShaderProgram::uniform4fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform1iImplementation AbstractShaderProgram::uniform1iImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform2ivImplementation AbstractShaderProgram::uniform2ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform3ivImplementation AbstractShaderProgram::uniform3ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform4ivImplementation AbstractShaderProgram::uniform4ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform1uiImplementation AbstractShaderProgram::uniform1uiImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform2uivImplementation AbstractShaderProgram::uniform2uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform3uivImplementation AbstractShaderProgram::uniform3uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform4uivImplementation AbstractShaderProgram::uniform4uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; +#ifndef MAGNUM_TARGET_GLES +AbstractShaderProgram::Uniform1dImplementation AbstractShaderProgram::uniform1dImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform2dvImplementation AbstractShaderProgram::uniform2dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform3dvImplementation AbstractShaderProgram::uniform3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform4dvImplementation AbstractShaderProgram::uniform4dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +#endif + +AbstractShaderProgram::UniformMatrix2fvImplementation AbstractShaderProgram::uniformMatrix2fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix3fvImplementation AbstractShaderProgram::uniformMatrix3fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix4fvImplementation AbstractShaderProgram::uniformMatrix4fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix2x3fvImplementation AbstractShaderProgram::uniformMatrix2x3fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix3x2fvImplementation AbstractShaderProgram::uniformMatrix3x2fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix2x4fvImplementation AbstractShaderProgram::uniformMatrix2x4fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix4x2fvImplementation AbstractShaderProgram::uniformMatrix4x2fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix3x4fvImplementation AbstractShaderProgram::uniformMatrix3x4fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix4x3fvImplementation AbstractShaderProgram::uniformMatrix4x3fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +#ifndef MAGNUM_TARGET_GLES +AbstractShaderProgram::UniformMatrix2dvImplementation AbstractShaderProgram::uniformMatrix2dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix3dvImplementation AbstractShaderProgram::uniformMatrix3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix4dvImplementation AbstractShaderProgram::uniformMatrix4dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix2x3dvImplementation AbstractShaderProgram::uniformMatrix2x3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix3x2dvImplementation AbstractShaderProgram::uniformMatrix3x2dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix2x4dvImplementation AbstractShaderProgram::uniformMatrix2x4dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix4x2dvImplementation AbstractShaderProgram::uniformMatrix4x2dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix3x4dvImplementation AbstractShaderProgram::uniformMatrix3x4dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix4x3dvImplementation AbstractShaderProgram::uniformMatrix4x3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +#endif + AbstractShaderProgram::~AbstractShaderProgram() { /* Remove current usage from the state */ GLuint& current = Context::current()->state()->shaderProgram->current; @@ -114,4 +156,361 @@ GLint AbstractShaderProgram::uniformLocation(const std::string& name) { return location; } +void AbstractShaderProgram::initializeContextBasedFunctionality(Context* context) { + if(context->isExtensionSupported() || + context->isExtensionSupported()) { + Debug() << "AbstractShaderProgram: using" << (context->isExtensionSupported() ? + Extensions::GL::ARB::separate_shader_objects::string() : Extensions::GL::EXT::direct_state_access::string()) << "features"; + uniform1fImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1iImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform2ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform3ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform4ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1uiImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform2uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform3uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform4uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; + #ifndef MAGNUM_TARGET_GLES + uniform1dImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + #endif + + uniformMatrix2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix2x3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix3x2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix2x4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix4x2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix3x4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix4x3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + #ifndef MAGNUM_TARGET_GLES + uniformMatrix2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix2x3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix3x2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix2x4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix4x2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix3x4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix4x3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + #endif + } +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLfloat value) { + use(); + glUniform1f(location, value); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLfloat value) { + glProgramUniform1f(_id, location, value); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLfloat>& value) { + use(); + glUniform2fv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLfloat>& value) { + glProgramUniform2fv(_id, location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLfloat>& value) { + use(); + glUniform3fv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLfloat>& value) { + glProgramUniform3fv(_id, location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLfloat>& value) { + use(); + glUniform4fv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLfloat>& value) { + glProgramUniform4fv(_id, location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLint value) { + use(); + glUniform1i(location, value); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLint value) { + glProgramUniform1i(_id, location, value); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLint>& value) { + use(); + glUniform2iv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLint>& value) { + glProgramUniform2iv(_id, location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLint>& value) { + use(); + glUniform3iv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLint>& value) { + glProgramUniform3iv(_id, location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLint>& value) { + use(); + glUniform4iv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLint>& value) { + glProgramUniform4iv(_id, location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLuint value) { + use(); + glUniform1ui(location, value); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLuint value) { + glProgramUniform1ui(_id, location, value); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLuint>& value) { + use(); + glUniform2uiv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLuint>& value) { + glProgramUniform2uiv(_id, location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLuint>& value) { + use(); + glUniform3uiv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLuint>& value) { + glProgramUniform3uiv(_id, location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLuint>& value) { + use(); + glUniform4uiv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLuint>& value) { + glProgramUniform4uiv(_id, location, 1, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLdouble value) { + use(); + glUniform1d(location, value); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLdouble value) { + glProgramUniform1d(_id, location, value); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLdouble>& value) { + use(); + glUniform2dv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLdouble>& value) { + glProgramUniform2dv(_id, location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLdouble>& value) { + use(); + glUniform3dv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLdouble>& value) { + glProgramUniform3dv(_id, location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLdouble>& value) { + use(); + glUniform4dv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLdouble>& value) { + glProgramUniform4dv(_id, location, 1, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<2, GLfloat>& value) { + use(); + glUniformMatrix2fv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<2, GLfloat>& value) { + glProgramUniformMatrix2fv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<3, GLfloat>& value) { + use(); + glUniformMatrix3fv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<3, GLfloat>& value) { + glProgramUniformMatrix3fv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<4, GLfloat>& value) { + use(); + glUniformMatrix4fv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<4, GLfloat>& value) { + glProgramUniformMatrix4fv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) { + use(); + glUniformMatrix2x3fv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) { + glProgramUniformMatrix2x3fv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) { + use(); + glUniformMatrix3x2fv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) { + glProgramUniformMatrix3x2fv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) { + use(); + glUniformMatrix2x4fv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) { + glProgramUniformMatrix2x4fv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) { + use(); + glUniformMatrix4x2fv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) { + glProgramUniformMatrix4x2fv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) { + use(); + glUniformMatrix3x4fv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) { + glProgramUniformMatrix3x4fv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) { + use(); + glUniformMatrix4x3fv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) { + glProgramUniformMatrix4x3fv(_id, location, 1, GL_FALSE, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<2, GLdouble>& value) { + use(); + glUniformMatrix2dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<2, GLdouble>& value) { + glProgramUniformMatrix2dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<3, GLdouble>& value) { + use(); + glUniformMatrix3dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<3, GLdouble>& value) { + glProgramUniformMatrix3dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<4, GLdouble>& value) { + use(); + glUniformMatrix4dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<4, GLdouble>& value) { + glProgramUniformMatrix4dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value) { + use(); + glUniformMatrix2x3dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value) { + glProgramUniformMatrix2x3dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value) { + use(); + glUniformMatrix3x2dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value) { + glProgramUniformMatrix3x2dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value) { + use(); + glUniformMatrix2x4dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value) { + glProgramUniformMatrix2x4dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value) { + use(); + glUniformMatrix4x2dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value) { + glProgramUniformMatrix4x2dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value) { + use(); + glUniformMatrix3x4dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value) { + glProgramUniformMatrix3x4dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value) { + use(); + glUniformMatrix4x3dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value) { + glProgramUniformMatrix4x3dv(_id, location, 1, GL_FALSE, value.data()); +} +#endif + } diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index fbe4dcb9b..57d36c8e5 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -19,15 +19,22 @@ * @brief Class Magnum::AbstractShaderProgram */ -#include +#include +#include -#include "Math/RectangularMatrix.h" #include "Magnum.h" #include "magnumVisibility.h" namespace Magnum { +namespace Math { + template class RectangularMatrix; + template class Matrix; + template class Vector; +} + +class Context; class Shader; /** @@ -191,9 +198,10 @@ void draw(const Magnum::Matrix4& transformationMatrix, Magnum::Camera* camera) { @endcode @todo Uniform arrays support -@todo DSA for uniforms - glProgramUniform*() (OpenGL 4.1, @extension{ARB,separate_shader_objects}) */ class MAGNUM_EXPORT AbstractShaderProgram { + friend class Context; + AbstractShaderProgram(const AbstractShaderProgram& other) = delete; AbstractShaderProgram(AbstractShaderProgram&& other) = delete; AbstractShaderProgram& operator=(const AbstractShaderProgram& other) = delete; @@ -232,7 +240,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { virtual ~AbstractShaderProgram() = 0; /** - * @brief Use shader + * @brief Use shader for rendering * @return False if the program wasn't successfully linked, true * otherwise. * @@ -369,46 +377,49 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @param location Uniform location (see uniformLocation()) * @param value Value * - * @attention This function doesn't check whether this shader is in use! - * @see @fn_gl{Uniform} + * If neither @extension{ARB,separate_shader_objects} nor + * @extension{EXT,direct_state_access} is available, use() is called + * before the operation. + * @see use(), @fn_gl{Uniform} or `glProgramUniform()` from + * @extension{ARB,separate_shader_objects}/@extension{EXT,direct_state_access}. */ inline void setUniform(GLint location, GLfloat value) { - glUniform1f(location, value); + (this->*uniform1fImplementation)(location, value); } /** @copydoc setUniform(GLint, GLfloat) */ - inline void setUniform(GLint location, const Math::RectangularMatrix<1, 2, GLfloat>& value) { - glUniform2fv(location, 1, value.data()); + 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::RectangularMatrix<1, 3, GLfloat>& value) { - glUniform3fv(location, 1, value.data()); + 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::RectangularMatrix<1, 4, GLfloat>& value) { - glUniform4fv(location, 1, value.data()); + 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) { - glUniform1i(location, value); + (this->*uniform1iImplementation)(location, value); } /** @copydoc setUniform(GLint, GLfloat) */ - inline void setUniform(GLint location, const Math::RectangularMatrix<1, 2, GLint>& value) { - glUniform2iv(location, 1, value.data()); + 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::RectangularMatrix<1, 3, GLint>& value) { - glUniform3iv(location, 1, value.data()); + 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::RectangularMatrix<1, 4, GLint>& value) { - glUniform4iv(location, 1, value.data()); + inline void setUniform(GLint location, const Math::Vector<4, GLint>& value) { + (this->*uniform4ivImplementation)(location, value); } /** @@ -417,7 +428,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gles30 (no extension providing this functionality) */ inline void setUniform(GLint location, GLuint value) { - glUniform1ui(location, value); + (this->*uniform1uiImplementation)(location, value); } /** @@ -425,8 +436,8 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gl30 Extension @extension{EXT,gpu_shader4} * @requires_gles30 (no extension providing this functionality) */ - inline void setUniform(GLint location, const Math::RectangularMatrix<1, 2, GLuint>& value) { - glUniform2uiv(location, 1, value.data()); + inline void setUniform(GLint location, const Math::Vector<2, GLuint>& value) { + (this->*uniform2uivImplementation)(location, value); } /** @@ -434,8 +445,8 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gl30 Extension @extension{EXT,gpu_shader4} * @requires_gles30 (no extension providing this functionality) */ - inline void setUniform(GLint location, const Math::RectangularMatrix<1, 3, GLuint>& value) { - glUniform3uiv(location, 1, value.data()); + inline void setUniform(GLint location, const Math::Vector<3, GLuint>& value) { + (this->*uniform3uivImplementation)(location, value); } /** @@ -443,8 +454,8 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gl30 Extension @extension{EXT,gpu_shader4} * @requires_gles30 (no extension providing this functionality) */ - inline void setUniform(GLint location, const Math::RectangularMatrix<1, 4, GLuint>& value) { - glUniform4uiv(location, 1, value.data()); + inline void setUniform(GLint location, const Math::Vector<4, GLuint>& value) { + (this->*uniform4uivImplementation)(location, value); } #ifndef MAGNUM_TARGET_GLES @@ -454,7 +465,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gl Only floats are available in OpenGL ES. */ inline void setUniform(GLint location, GLdouble value) { - glUniform1d(location, value); + (this->*uniform1dImplementation)(location, value); } /** @@ -462,8 +473,8 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @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<1, 2, GLdouble>& value) { - glUniform2dv(location, 1, value.data()); + inline void setUniform(GLint location, const Math::Vector<2, GLdouble>& value) { + (this->*uniform2dvImplementation)(location, value); } /** @@ -471,8 +482,8 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @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<1, 3, GLdouble>& value) { - glUniform3dv(location, 1, value.data()); + inline void setUniform(GLint location, const Math::Vector<3, GLdouble>& value) { + (this->*uniform3dvImplementation)(location, value); } /** @@ -480,24 +491,24 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @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<1, 4, GLdouble>& value) { - glUniform4dv(location, 1, value.data()); + 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::RectangularMatrix<2, 2, GLfloat>& value) { - glUniformMatrix2fv(location, 1, GL_FALSE, value.data()); + 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::RectangularMatrix<3, 3, GLfloat>& value) { - glUniformMatrix3fv(location, 1, GL_FALSE, value.data()); + 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::RectangularMatrix<4, 4, GLfloat>& value) { - glUniformMatrix4fv(location, 1, GL_FALSE, value.data()); + inline void setUniform(GLint location, const Math::Matrix<4, GLfloat>& value) { + (this->*uniformMatrix4fvImplementation)(location, value); } /** @@ -505,7 +516,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gles30 (no extension providing this functionality) */ inline void setUniform(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) { - glUniformMatrix2x3fv(location, 1, GL_FALSE, value.data()); + (this->*uniformMatrix2x3fvImplementation)(location, value); } /** @@ -513,7 +524,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gles30 (no extension providing this functionality) */ inline void setUniform(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) { - glUniformMatrix3x2fv(location, 1, GL_FALSE, value.data()); + (this->*uniformMatrix3x2fvImplementation)(location, value); } /** @@ -521,7 +532,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gles30 (no extension providing this functionality) */ inline void setUniform(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) { - glUniformMatrix2x4fv(location, 1, GL_FALSE, value.data()); + (this->*uniformMatrix2x4fvImplementation)(location, value); } /** @@ -529,7 +540,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gles30 (no extension providing this functionality) */ inline void setUniform(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) { - glUniformMatrix4x2fv(location, 1, GL_FALSE, value.data()); + (this->*uniformMatrix4x2fvImplementation)(location, value); } /** @@ -537,7 +548,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gles30 (no extension providing this functionality) */ inline void setUniform(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) { - glUniformMatrix3x4fv(location, 1, GL_FALSE, value.data()); + (this->*uniformMatrix3x4fvImplementation)(location, value); } /** @@ -545,7 +556,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gles30 (no extension providing this functionality) */ inline void setUniform(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) { - glUniformMatrix4x3fv(location, 1, GL_FALSE, value.data()); + (this->*uniformMatrix4x3fvImplementation)(location, value); } #ifndef MAGNUM_TARGET_GLES @@ -554,8 +565,8 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @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, 2, GLdouble>& value) { - glUniformMatrix2dv(location, 1, GL_FALSE, value.data()); + inline void setUniform(GLint location, const Math::Matrix<2, GLdouble>& value) { + (this->*uniformMatrix2dvImplementation)(location, value); } /** @@ -563,8 +574,8 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @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, 3, GLdouble>& value) { - glUniformMatrix3dv(location, 1, GL_FALSE, value.data()); + inline void setUniform(GLint location, const Math::Matrix<3, GLdouble>& value) { + (this->*uniformMatrix3dvImplementation)(location, value); } /** @@ -572,8 +583,8 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @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, 4, GLdouble>& value) { - glUniformMatrix4dv(location, 1, GL_FALSE, value.data()); + inline void setUniform(GLint location, const Math::Matrix<4, GLdouble>& value) { + (this->*uniformMatrix4dvImplementation)(location, value); } /** @@ -582,7 +593,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gl Only floats are available in OpenGL ES. */ inline void setUniform(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value) { - glUniformMatrix2x3dv(location, 1, GL_FALSE, value.data()); + (this->*uniformMatrix2x3dvImplementation)(location, value); } /** @@ -591,7 +602,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gl Only floats are available in OpenGL ES. */ inline void setUniform(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value) { - glUniformMatrix3x2dv(location, 1, GL_FALSE, value.data()); + (this->*uniformMatrix3x2dvImplementation)(location, value); } /** @@ -600,7 +611,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gl Only floats are available in OpenGL ES. */ inline void setUniform(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value) { - glUniformMatrix2x4dv(location, 1, GL_FALSE, value.data()); + (this->*uniformMatrix2x4dvImplementation)(location, value); } /** @@ -609,7 +620,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gl Only floats are available in OpenGL ES. */ inline void setUniform(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value) { - glUniformMatrix4x2dv(location, 1, GL_FALSE, value.data()); + (this->*uniformMatrix4x2dvImplementation)(location, value); } /** @@ -618,7 +629,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gl Only floats are available in OpenGL ES. */ inline void setUniform(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value) { - glUniformMatrix3x4dv(location, 1, GL_FALSE, value.data()); + (this->*uniformMatrix3x4dvImplementation)(location, value); } /** @@ -627,7 +638,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @requires_gl Only floats are available in OpenGL ES. */ inline void setUniform(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value) { - glUniformMatrix4x3dv(location, 1, GL_FALSE, value.data()); + (this->*uniformMatrix4x3dvImplementation)(location, value); } #endif @@ -638,6 +649,162 @@ class MAGNUM_EXPORT AbstractShaderProgram { Failed }; + static void 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>&); + 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>&); + #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); + 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); + #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); + #endif + 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); + #ifndef MAGNUM_TARGET_GLES + 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; + static Uniform1uiImplementation uniform1uiImplementation; + static Uniform2uivImplementation uniform2uivImplementation; + static Uniform3uivImplementation uniform3uivImplementation; + static Uniform4uivImplementation uniform4uivImplementation; + #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>&); + 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>&); + #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); + 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); + #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); + #endif + 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); + #ifndef MAGNUM_TARGET_GLES + 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; + static UniformMatrix2x3fvImplementation uniformMatrix2x3fvImplementation; + static UniformMatrix3x2fvImplementation uniformMatrix3x2fvImplementation; + static UniformMatrix2x4fvImplementation uniformMatrix2x4fvImplementation; + static UniformMatrix4x2fvImplementation uniformMatrix4x2fvImplementation; + static UniformMatrix3x4fvImplementation uniformMatrix3x4fvImplementation; + static UniformMatrix4x3fvImplementation uniformMatrix4x3fvImplementation; + #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; }; diff --git a/src/Context.cpp b/src/Context.cpp index 92247c051..d3361f8a5 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -19,6 +19,7 @@ #include #include +#include "AbstractShaderProgram.h" #include "Buffer.h" #include "Extensions.h" #include "Implementation/State.h" @@ -198,6 +199,7 @@ Context::Context() { _state = new Implementation::State; /* Initialize functionality based on current OpenGL version and extensions */ + AbstractShaderProgram::initializeContextBasedFunctionality(this); Buffer::initializeContextBasedFunctionality(this); }