|
|
|
|
/*
|
|
|
|
|
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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "AbstractShaderProgram.h"
|
|
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <type_traits>
|
|
|
|
|
|
|
|
|
|
#include "Math/Matrix.h"
|
|
|
|
|
#include "Shader.h"
|
|
|
|
|
#include "Implementation/State.h"
|
|
|
|
|
#include "Implementation/ShaderProgramState.h"
|
|
|
|
|
#include "Extensions.h"
|
|
|
|
|
|
|
|
|
|
#define LINKER_MESSAGE_MAX_LENGTH 1024
|
|
|
|
|
|
|
|
|
|
namespace Magnum {
|
|
|
|
|
|
|
|
|
|
#ifndef DOXYGEN_GENERATING_OUTPUT
|
|
|
|
|
static_assert(std::is_same<GLubyte, std::uint8_t>::value, "GLubyte is not the same as std::uint8_t");
|
|
|
|
|
static_assert(std::is_same<GLbyte, std::int8_t>::value, "GLbyte is not the same as std::int8_t");
|
|
|
|
|
static_assert(std::is_same<GLushort, std::uint16_t>::value, "GLushort is not the same as std::uint16_t");
|
|
|
|
|
static_assert(std::is_same<GLshort, std::int16_t>::value, "GLshort is not the same as std::int16_t");
|
|
|
|
|
static_assert(std::is_same<GLuint, std::uint32_t>::value, "GLuint is not the same as std::uint32_t");
|
|
|
|
|
static_assert(std::is_same<GLint, std::int32_t>::value, "GLint is not the same as std::int32_t");
|
|
|
|
|
static_assert(std::is_same<GLsizei, std::int32_t>::value, "GLsizei is not the same as std::int32_t");
|
|
|
|
|
static_assert(std::is_same<GLfloat, float>::value, "GLfloat is not the same as float");
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
static_assert(std::is_same<GLdouble, double>::value, "GLdouble is not the same as double");
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES2
|
|
|
|
|
AbstractShaderProgram::Uniform1uiImplementation AbstractShaderProgram::uniform1uiImplementation = &AbstractShaderProgram::uniformImplementationDefault;
|
|
|
|
|
AbstractShaderProgram::Uniform2uivImplementation AbstractShaderProgram::uniform2uivImplementation = &AbstractShaderProgram::uniformImplementationDefault;
|
|
|
|
|
AbstractShaderProgram::Uniform3uivImplementation AbstractShaderProgram::uniform3uivImplementation = &AbstractShaderProgram::uniformImplementationDefault;
|
|
|
|
|
AbstractShaderProgram::Uniform4uivImplementation AbstractShaderProgram::uniform4uivImplementation = &AbstractShaderProgram::uniformImplementationDefault;
|
|
|
|
|
#endif
|
|
|
|
|
#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;
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES2
|
|
|
|
|
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;
|
|
|
|
|
#endif
|
|
|
|
|
#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
|
|
|
|
|
|
|
|
|
|
GLint AbstractShaderProgram::maxSupportedVertexAttributeCount() {
|
|
|
|
|
GLint& value = Context::current()->state()->shaderProgram->maxSupportedVertexAttributeCount;
|
|
|
|
|
|
|
|
|
|
/* Get the value, if not already cached */
|
|
|
|
|
if(value == 0)
|
|
|
|
|
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value);
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AbstractShaderProgram::~AbstractShaderProgram() {
|
|
|
|
|
/* Remove current usage from the state */
|
|
|
|
|
GLuint& current = Context::current()->state()->shaderProgram->current;
|
|
|
|
|
if(current == _id) current = 0;
|
|
|
|
|
|
|
|
|
|
glDeleteProgram(_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AbstractShaderProgram::use() {
|
|
|
|
|
if(state != Linked) return false;
|
|
|
|
|
|
|
|
|
|
/* Use only if the program isn't already in use */
|
|
|
|
|
GLuint& current = Context::current()->state()->shaderProgram->current;
|
|
|
|
|
if(current != _id) glUseProgram(current = _id);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AbstractShaderProgram::attachShader(Shader& shader) {
|
|
|
|
|
GLuint _shader = shader.compile();
|
|
|
|
|
if(!_shader) return false;
|
|
|
|
|
|
|
|
|
|
glAttachShader(_id, _shader);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::bindAttributeLocation(GLuint location, const std::string& name) {
|
|
|
|
|
CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: attribute cannot be bound after linking.", );
|
|
|
|
|
|
|
|
|
|
glBindAttribLocation(_id, location, name.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::bindFragmentDataLocation(GLuint location, const std::string& name) {
|
|
|
|
|
CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: fragment data location cannot be bound after linking.", );
|
|
|
|
|
|
|
|
|
|
glBindFragDataLocation(_id, location, name.c_str());
|
|
|
|
|
}
|
|
|
|
|
void AbstractShaderProgram::bindFragmentDataLocationIndexed(GLuint location, GLuint index, const std::string& name) {
|
|
|
|
|
CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: fragment data location cannot be bound after linking.", );
|
|
|
|
|
|
|
|
|
|
glBindFragDataLocationIndexed(_id, location, index, name.c_str());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::link() {
|
|
|
|
|
/* Already compiled or failed, exit */
|
|
|
|
|
if(state != Initialized) return;
|
|
|
|
|
|
|
|
|
|
/* Link shader program */
|
|
|
|
|
glLinkProgram(_id);
|
|
|
|
|
|
|
|
|
|
/* Check link status */
|
|
|
|
|
GLint status;
|
|
|
|
|
glGetProgramiv(_id, GL_LINK_STATUS, &status);
|
|
|
|
|
|
|
|
|
|
/* Display errors or warnings */
|
|
|
|
|
char message[LINKER_MESSAGE_MAX_LENGTH];
|
|
|
|
|
glGetProgramInfoLog(_id, LINKER_MESSAGE_MAX_LENGTH, nullptr, message);
|
|
|
|
|
|
|
|
|
|
/* Show error log and delete shader */
|
|
|
|
|
if(status == GL_FALSE) {
|
|
|
|
|
Error() << "AbstractShaderProgram: linking failed with the following message:\n"
|
|
|
|
|
<< message;
|
|
|
|
|
|
|
|
|
|
/* Or just warnings, if there are any */
|
|
|
|
|
} else if(message[0] != 0) {
|
|
|
|
|
Debug() << "AbstractShaderProgram: linking succeeded with the following message:\n"
|
|
|
|
|
<< message;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
state = status == GL_FALSE ? Failed : Linked;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GLint AbstractShaderProgram::uniformLocation(const std::string& name) {
|
|
|
|
|
/** @todo What if linking just failed (not programmer error?) */
|
|
|
|
|
CORRADE_ASSERT(state == Linked, "AbstractShaderProgram: uniform location cannot be retrieved before linking.", -1);
|
|
|
|
|
|
|
|
|
|
GLint location = glGetUniformLocation(_id, name.c_str());
|
|
|
|
|
if(location == -1)
|
|
|
|
|
Warning() << "AbstractShaderProgram: location of uniform \'" + name + "\' cannot be retrieved!";
|
|
|
|
|
return location;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::initializeContextBasedFunctionality(Context* context) {
|
|
|
|
|
/** @todo OpenGL ES 2 has extension @es_extension{EXT,separate_shader_objects} for this */
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
if(context->isExtensionSupported<Extensions::GL::ARB::separate_shader_objects>() ||
|
|
|
|
|
context->isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
|
|
|
|
|
Debug() << "AbstractShaderProgram: using" << (context->isExtensionSupported<Extensions::GL::ARB::separate_shader_objects>() ?
|
|
|
|
|
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;
|
|
|
|
|
uniform1dImplementation = &AbstractShaderProgram::uniformImplementationDSA;
|
|
|
|
|
uniform2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
|
|
|
|
|
uniform3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
|
|
|
|
|
uniform4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
static_cast<void>(context);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLfloat value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniform1f(location, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLfloat value) {
|
|
|
|
|
glProgramUniform1f(_id, location, value);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLfloat>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniform2fv(location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLfloat>& value) {
|
|
|
|
|
glProgramUniform2fv(_id, location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLfloat>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniform3fv(location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLfloat>& value) {
|
|
|
|
|
glProgramUniform3fv(_id, location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLfloat>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniform4fv(location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLfloat>& value) {
|
|
|
|
|
glProgramUniform4fv(_id, location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLint value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniform1i(location, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLint value) {
|
|
|
|
|
glProgramUniform1i(_id, location, value);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLint>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniform2iv(location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLint>& value) {
|
|
|
|
|
glProgramUniform2iv(_id, location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLint>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniform3iv(location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLint>& value) {
|
|
|
|
|
glProgramUniform3iv(_id, location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLint>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniform4iv(location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLint>& value) {
|
|
|
|
|
glProgramUniform4iv(_id, location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES2
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLuint value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniform1ui(location, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLuint value) {
|
|
|
|
|
glProgramUniform1ui(_id, location, value);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLuint>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniform2uiv(location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLuint>& value) {
|
|
|
|
|
glProgramUniform2uiv(_id, location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLuint>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniform3uiv(location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLuint>& value) {
|
|
|
|
|
glProgramUniform3uiv(_id, location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLuint>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniform4uiv(location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLuint>& value) {
|
|
|
|
|
glProgramUniform4uiv(_id, location, 1, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#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());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<2, GLfloat>& value) {
|
|
|
|
|
glProgramUniformMatrix2fv(_id, location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<3, GLfloat>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniformMatrix3fv(location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<3, GLfloat>& value) {
|
|
|
|
|
glProgramUniformMatrix3fv(_id, location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<4, GLfloat>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniformMatrix4fv(location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<4, GLfloat>& value) {
|
|
|
|
|
glProgramUniformMatrix4fv(_id, location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES2
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniformMatrix2x3fv(location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) {
|
|
|
|
|
glProgramUniformMatrix2x3fv(_id, location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniformMatrix3x2fv(location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) {
|
|
|
|
|
glProgramUniformMatrix3x2fv(_id, location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniformMatrix2x4fv(location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) {
|
|
|
|
|
glProgramUniformMatrix2x4fv(_id, location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniformMatrix4x2fv(location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) {
|
|
|
|
|
glProgramUniformMatrix4x2fv(_id, location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniformMatrix3x4fv(location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) {
|
|
|
|
|
glProgramUniformMatrix3x4fv(_id, location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) {
|
|
|
|
|
use();
|
|
|
|
|
glUniformMatrix4x3fv(location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) {
|
|
|
|
|
glProgramUniformMatrix4x3fv(_id, location, 1, GL_FALSE, value.data());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#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
|
|
|
|
|
|
|
|
|
|
#ifndef DOXYGEN_GENERATING_OUTPUT
|
|
|
|
|
namespace Implementation {
|
|
|
|
|
|
|
|
|
|
std::size_t Attribute<GLfloat>::size(GLint components, DataType dataType) {
|
|
|
|
|
switch(dataType) {
|
|
|
|
|
case DataType::UnsignedByte:
|
|
|
|
|
case DataType::Byte:
|
|
|
|
|
return components;
|
|
|
|
|
case DataType::UnsignedShort:
|
|
|
|
|
case DataType::Short:
|
|
|
|
|
case DataType::HalfFloat:
|
|
|
|
|
return 2*components;
|
|
|
|
|
case DataType::UnsignedInt:
|
|
|
|
|
case DataType::Int:
|
|
|
|
|
case DataType::Float:
|
|
|
|
|
return 4*components;
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
case DataType::Double:
|
|
|
|
|
return 8*components;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CORRADE_INTERNAL_ASSERT(false);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::size_t Attribute<GLint>::size(GLint components, DataType dataType) {
|
|
|
|
|
switch(dataType) {
|
|
|
|
|
case DataType::UnsignedByte:
|
|
|
|
|
case DataType::Byte:
|
|
|
|
|
return components;
|
|
|
|
|
case DataType::UnsignedShort:
|
|
|
|
|
case DataType::Short:
|
|
|
|
|
return 2*components;
|
|
|
|
|
case DataType::UnsignedInt:
|
|
|
|
|
case DataType::Int:
|
|
|
|
|
return 4*components;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CORRADE_INTERNAL_ASSERT(false);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
std::size_t Attribute<GLdouble>::size(GLint components, DataType dataType) {
|
|
|
|
|
switch(dataType) {
|
|
|
|
|
case DataType::Double:
|
|
|
|
|
return 8*components;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CORRADE_INTERNAL_ASSERT(false);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
std::size_t Attribute<Math::Vector<4, GLfloat>>::size(GLint components, DataType dataType) {
|
|
|
|
|
switch(dataType) {
|
|
|
|
|
case DataType::UnsignedByte:
|
|
|
|
|
case DataType::Byte:
|
|
|
|
|
return components;
|
|
|
|
|
case DataType::UnsignedShort:
|
|
|
|
|
case DataType::Short:
|
|
|
|
|
case DataType::HalfFloat:
|
|
|
|
|
return 2*components;
|
|
|
|
|
case DataType::UnsignedInt:
|
|
|
|
|
case DataType::Int:
|
|
|
|
|
case DataType::Float:
|
|
|
|
|
return 4*components;
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES
|
|
|
|
|
case DataType::Double:
|
|
|
|
|
return 8*components;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef MAGNUM_TARGET_GLES2
|
|
|
|
|
case DataType::UnsignedInt2101010Rev:
|
|
|
|
|
case DataType::Int2101010Rev:
|
|
|
|
|
CORRADE_INTERNAL_ASSERT(components == 4);
|
|
|
|
|
return 4;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CORRADE_INTERNAL_ASSERT(false);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
}
|