Commit 2c552974 authored by Robert Menzel's avatar Robert Menzel

cleanups, working on VAOs

parent 7eec3733
......@@ -24,6 +24,33 @@
* itself are called ArrayBuffer and ElementArrayBuffer.
*/
/***************************************************************************************************************
* Attributes:
*************
*
* _type is the GL type
* _size the number of elements in this attribute (1..4)
* _normalized is the attribute normalization for int types
*
* Want to add tightly packed attributes in order?
* -> use defineAttribute()
*
* Want to add attributes with individual padding in order?
* -> use defineAttributeWithPadding()
*
* Want to add attributes out-of-order?
* -> use defineAttributeWithOffset()
*
* The stride size gets always set to the minimal stride size that covers all defined attributes (/w padding).
* All define methods can get mixed!
*
*
* ab->defineAttribute( "pos", GL_FLOAT, 3 ); // stride: 12 bytes
* ab->defineAttributeWithPadding( "color", GL_CHAR, 3, 1 ); // stride: 12 + 3 + 1 = 16 bytes
* ab->defineAttributeWithOffset( "colorNorm", GL_CHAR, 3, 12, GL_TRUE ); // stride is still 16 as 12+3 <= 16!
*
**************************************************************************************************************/
#include <ACGL/ACGL.hh>
#include <ACGL/Base/Macros.hh>
......@@ -49,9 +76,9 @@ public:
{
std::string name; // human readable name, can be used to match the attribute to shader programs
GLenum type; // GL_FLOAT, GL_UNSIGNED_BYTE etc.
GLint size; // #elements per attribute
GLint size; // #elements per attribute, size in bytes would be: size*sizeof(type)
GLuint offset; // offset in bytes into the array
GLboolean normalized; // int types can get normalzed to 0..1 / -1..1 by GL
GLboolean normalized; // int types can get normalzed to 0..1 / -1..1 by GL, useful e.g. for colors
};
// ===================================================================================================== \/
......@@ -80,39 +107,20 @@ public:
// ============================================================================================ GETTERS \/
// ==================================================================================================== \/
public:
//! often the number of vertices:
inline GLsizei getElements (void) const { return mSize/mStride; }
//! size in bytes of all attributes that make up one element (vertex):
inline GLsizei getStride (void) const { return mStride; }
//! Returns the definitions of the attributes:
inline const AttributeVec& getAttributes (void) const { return mAttributes; }
// ==================================================================================================== \/
// ============================================================================================ METHODS \/
// ==================================================================================================== \/
public:
//int_t getAttributeIndexByName(const std::string& _nameInArray) const;
/* Attributes:
*
* _type is the GL type
* _size the number of elements in this attribute (1..4)
* _normalized is the attribute normalization for int types
*
* Want to add tightly packed attributes in order?
* -> use defineAttribute()
*
* Want to add attributes with individual padding in order?
* -> use defineAttributeWithPadding()
*
* Want to add attributes out-of-order?
* -> use defineAttributeWithOffset()
*
* The stride size gets always set to the minimal stride size that covers all defined attributes (/w padding).
* All define methods can get mixed!
*
*
* ab->defineAttribute( "pos", GL_FLOAT, 3 ); // stride: 12 bytes
* ab->defineAttributeWithPadding( "color", GL_CHAR, 3, 1 ); // stride: 12 + 3 + 1 = 16 bytes
* ab->defineAttributeWithOffset( "colorNorm", GL_CHAR, 3, 12, GL_TRUE ); // stride is still 16 as 12+3 <= 16!
*/
//! Adds the attribute at the end of the existing attributes, stride gets computed automatically
void defineAttribute(
const std::string& _name,
......@@ -121,13 +129,12 @@ public:
GLboolean _normalized = GL_FALSE)
{
GLuint offset = mStride;
Attribute attribute = { _name, _type, _size, offset, _normalized };
defineAttribute(attribute);
}
//! Adds the attribute at the end of the existing attributes, stride gets computed automatically
//! + extra padding in bytes
//! + extra padding in bytes at the end
void defineAttributeWithPadding(
const std::string& _name,
GLenum _type,
......@@ -135,7 +142,8 @@ public:
GLuint _padding,
GLboolean _normalized = GL_FALSE)
{
Attribute attribute = { _name, _type, _size, (GLuint)mStride, _normalized };
GLuint offset = mStride;
Attribute attribute = { _name, _type, _size, offset, _normalized };
defineAttribute(attribute);
// defineAttribute will shift the mStride to the end of this attribute, so we only have to
// add the explicit padding:
......@@ -143,7 +151,8 @@ public:
}
//! Adds an attribute defined by an offset: this way an attribute can get added at arbitrary
//! locations in the stride. If it's added at the end, the stride gets resized.
//! locations in the stride. If it's added at the end, the stride gets resized. This way attributes can even
//! overlap, hope you know what you're doing...
void defineAttributeWithOffset(
const std::string& _name,
GLenum _type,
......@@ -159,8 +168,8 @@ public:
void defineAttribute( const Attribute &_attribute )
{
// this way attribute definitions don't have to be in order!
mStride = std::max( (GLsizei)_attribute.offset + getGLTypeSize(_attribute.type)*_attribute.size,
mStride);
GLsizei attributeWidth = getGLTypeSize(_attribute.type)*_attribute.size; // in bytes
mStride = std::max( (GLsizei)_attribute.offset + attributeWidth, mStride);
mAttributes.push_back( _attribute );
}
......
......@@ -31,7 +31,7 @@ namespace ACGL{
namespace OpenGL{
/*
/**
* A minimal(!) wrapper to allow multiple Buffer objects pointing to the same
* OpenGL resource (like an ArrayBuffer and a TransformFeedbackBuffer).
*
......@@ -39,6 +39,7 @@ namespace OpenGL{
* below to allow a unified API.
*/
class BufferObject {
ACGL_NOT_COPYABLE(BufferObject)
public:
BufferObject()
{
......
......@@ -62,15 +62,16 @@ public:
mType = _type;
}
//! Returns the number of indices:
GLuint getElements() {
return getSize() / getGLTypeSize(mType);
}
//! Overloaded from the base class to _prevent_ redefining of the binding target! (see Buffer)
inline void setTarget( GLenum ) {
ACGL::Utils::error() << "DON'T redefine the target binding point of an ElementArrayBuffer" << std::endl;
}
GLuint getElements() {
return getSize() / getGLTypeSize(mType);
}
// =================================================================================================== \/
// ============================================================================================ FIELDS \/
// =================================================================================================== \/
......
......@@ -140,15 +140,7 @@ public:
openGLRareError();
}*/
inline bool isFrameBufferObjectComplete(void) const
{
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
Utils::error() << "Failed to make complete FrameBufferObject object: " << (glCheckFramebufferStatus(GL_FRAMEBUFFER)) << std::endl;
return false;
}
return true;
}
bool isFrameBufferObjectComplete() const;
inline bool attachColorRenderBuffer(const std::string _name, const ConstSharedRenderBuffer& _renderBuffer)
{
......
......@@ -6,24 +6,39 @@
#ifndef ACGL_OPENGL_OBJECTS_LOCATIONMAPPINGS_HH
#define ACGL_OPENGL_OBJECTS_LOCATIONMAPPINGS_HH
/*
* LocationMappings is a map from strings to GLuints that stores the mappings from
*
* attribute names to attribute locations
* or
* fragment outputs to fragdata locations
*
* A mapping like this can be used to init all mappings of multiple ShaderProgram
* in the same way to they can be used with the same VAOs or FBOs, similar, these
* mapping objects can be used to configute VAOs and FBOs!
*
* To fully automate the mappings in a program the creation of these mappings can
* be done automatically by parsing shader sources, querying locations and names from
* ShaderPrograms or any other way that best suits the use case of the application.
*/
#include <map>
#include <string>
#include <ACGL/ACGL.hh>
#include <ACGL/Base/Macros.hh>
#include <ACGL/OpenGL/GL.hh>
namespace ACGL{
namespace OpenGL{
class LocationMappings
{
ACGL_NOT_COPYABLE(LocationMappings)
// ===================================================================================================== \/
// ============================================================================================ TYPEDEFS \/
// ===================================================================================================== \/
public:
typedef std::map< std::string, int_t > LocationMap;
typedef std::map< std::string, GLuint > LocationMap;
// ========================================================================================================= \/
// ============================================================================================ CONSTRUCTORS \/
......@@ -40,11 +55,12 @@ public:
// ============================================================================================ GETTERS \/
// ==================================================================================================== \/
public:
inline int_t getLocation(const std::string& _name) const
//! Returns the stored location for a given name or -1 if the name could not get found (similar to how GL behaves)
GLint getLocation(const std::string& _name) const
{
if(exists(_name))
{
return mMappings.at(_name);
return (GLint) mMappings.at(_name);
}
else
{
......@@ -52,15 +68,18 @@ public:
}
}
inline const LocationMap& getLocations() const { return mMappings; }
//! Returns the raw location map:
const LocationMap& getLocations() const { return mMappings; }
// ==================================================================================================== \/
// ============================================================================================ SETTERS \/
// ==================================================================================================== \/
public:
inline void setLocation(const std::string& _name, int_t _location)
//! Adds one location:
inline void setLocation(const std::string& _name, GLuint _location)
{
if(exists(_name))
if (exists(_name) && (mMappings[_name] != _location))
{
ACGL::Utils::warning() << "LocationMappings: Overwriting location mapping for " << _name;
ACGL::Utils::warning() << " (previous value: " << mMappings[_name] << ", new value: " << _location<< ")" << std::endl;
......
......@@ -46,7 +46,6 @@
#include <ACGL/OpenGL/GL.hh>
#include <ACGL/OpenGL/Objects/Shader.hh>
#include <ACGL/OpenGL/Objects/Texture.hh>
//#include <ACGL/OpenGL/Objects/FrameBufferObject.hh>
#include <ACGL/OpenGL/Objects/LocationMappings.hh>
#include <ACGL/Math/Math.hh>
......@@ -55,11 +54,11 @@
namespace ACGL{
namespace OpenGL{
class VertexArrayObject;
ACGL_SHARED_TYPEDEF(VertexArrayObject)
//class VertexArrayObject;
//ACGL_SHARED_TYPEDEF(VertexArrayObject)
class FrameBufferObject;
ACGL_SHARED_TYPEDEF(FrameBufferObject)
//class FrameBufferObject;
//ACGL_SHARED_TYPEDEF(FrameBufferObject)
class ShaderProgram
{
......@@ -123,11 +122,10 @@ public:
// ============================================================================================= METHODS \/
// ===================================================================================================== \/
public:
//! Matches the attribute locations of this ShaderProgram to the names of the ArrayBuffer attributes currently attached to _vao
void setAttributeLocationsByVAO( ConstSharedVertexArrayObject _vao );
//! Matches the fragment data locations of this ShaderProgram to the names of the color attachments of _fbo
void setFragmentDataLocationsByFBO( ConstSharedFrameBufferObject _fbo );
// Matches the attribute locations of this ShaderProgram to the names of the ArrayBuffer attributes currently attached to _vao
//void setAttributeLocationsByVAO( ConstSharedVertexArrayObject _vao );
// Matches the fragment data locations of this ShaderProgram to the names of the color attachments of _fbo
//void setFragmentDataLocationsByFBO( ConstSharedFrameBufferObject _fbo );
//! Sets the attribute locations of this ShaderProgram according to the mappings specified in
void setAttributeLocations( ConstSharedLocationMappings _locationMappings );
......@@ -245,9 +243,22 @@ public:
inline void setProgramUniform (GLint _location, const glm::dmat4& _v, GLboolean _transpose = GL_FALSE) const { glProgramUniformMatrix4dv (mObjectName, _location, 1, _transpose, glm::value_ptr(_v)); }
#endif // OpenGL >= 4.0
// texture
inline void setTexture (GLint _location, const ConstSharedTexture& _texture, GLenum _unit = 0) const { glUniform1i(_location, _unit); _texture->bind(_unit); }
inline void setProgramTexture (const std::string& _nameInShader, const ConstSharedTexture& _texture, GLenum _unit = 0) const { setProgramUniform( getUniformLocation(_nameInShader), (GLint) _unit); _texture->bind(_unit); }
//! sets a texture uniform to a given texture unit and also binds the texture to the same unit
inline void setTexture (GLint _location, const ConstSharedTexture& _texture, GLenum _unit) const { glUniform1i(_location, _unit); _texture->bind(_unit); }
inline void setTexture (const std::string& _nameInShader, const ConstSharedTexture& _texture, GLenum _unit) const { setUniform( getUniformLocation(_nameInShader), (GLint) _unit); _texture->bind(_unit); }
inline void setProgramTexture (GLint _location, const ConstSharedTexture& _texture, GLenum _unit) const { glProgramUniform1i(mObjectName, _location, _unit); _texture->bind(_unit); }
inline void setProgramTexture (const std::string& _nameInShader, const ConstSharedTexture& _texture, GLenum _unit) const { setProgramUniform( getUniformLocation(_nameInShader), (GLint) _unit); _texture->bind(_unit); }
//! set the texture to the texture unit the uniform is set to.
//! Note: it is not guaranteed that all uniforms for textures are set to unique samplers by default after linking!
void setTexture( const std::string& _nameInShader, const ConstSharedTexture& _texture ) {
GLint unit;
GLint uniformLocation = getUniformLocation(_nameInShader);
if ( uniformLocation != -1 ) {
glGetUniformiv( mObjectName, uniformLocation, &unit );
_texture->bind( unit );
}
}
// ======================================================================================================= \/
// ============================================================================================ HIGH LEVEL \/
......@@ -295,9 +306,6 @@ public:
setProgramUniform( getUniformLocation(_nameInShader), _v, _transpose);
}
inline void setTexture (const std::string& _nameInShader, const ConstSharedTexture& _texture, GLenum _unit = 0) const { setUniform( getUniformLocation(_nameInShader), (GLint) _unit); _texture->bind(_unit); }
inline void setProgramTexture (GLint _location, const ConstSharedTexture& _texture, GLenum _unit = 0) const { glProgramUniform1i(mObjectName, _location, _unit); _texture->bind(_unit); }
// =================================================================================================== \/
// ============================================================================================ FIELDS \/
// =================================================================================================== \/
......
......@@ -253,6 +253,7 @@ public:
* Query the attribute locations based on the attribute names in the ArrayBuffers and the ShaderProgram
* If they match, use the location reported from the ShaderProgram.
*/
/*
void setAttributeLocationsByShaderProgram( const SharedShaderProgram &_shaderProgram )
{
// TODO: deprecate
......@@ -296,82 +297,19 @@ public:
disable();
}
}
}*/
/**
* Query the attribute locations based on the attribute names in the ArrayBuffers and the ShaderProgram
* If they match, use the location reported from the ShaderProgram.
* Query the attribute locations based on the attribute names in the ArrayBuffers.
* If they match, use the location reported from _locationMappings.
*/
void setAttributeLocations( ConstSharedLocationMappings _locationMappings )
{
bool fullUpdateNeeded = false;
for (AttributeVec::size_type i = 0; i < mAttributes.size(); ++i)
{
std::string attributeName = mAttributes[i].arrayBuffer->getAttributes()[ mAttributes[i].attributeID ].name;
int_t location = _locationMappings->getLocation(attributeName);
if(location == -1)
{
// TODO: fail silently?
ACGL::Utils::error() << "can't update VAO mappings: attribute " << attributeName << " not specified" << std::endl;
continue; // try to match as much as possible
}
if(mAttributes[i].location != location)
{
mAttributes[i].location = location;
fullUpdateNeeded = true;
}
}
// why the full update? setting the new location right when a change is detected will get problamatic
// if two attributes exchange there position...
if (fullUpdateNeeded)
{
enable();
// disable all attributes
GLint maxAttributes;
glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, &maxAttributes );
for (GLint i = 0; i < maxAttributes; ++i)
glDisableVertexAttribArray( i );
// set all attributes:
for (uint32_t i = 0; i < mAttributes.size(); ++i)
{
setAttributePointer(mAttributes[i]);
}
disable();
}
}
void setAttributeLocations( ConstSharedLocationMappings _locationMappings );
private:
//! Sets the vertex attribute pointer for the current VAO according to the specified attribute data
//! Note: expects that this VAO is currently bound
//! Note: will bind the ArrayBuffer referenced by _attribute.arrayBuffer
void setAttributePointer(const Attribute& _attribute)
{
if(_attribute.location == -1)
{
// An attribute location of -1 indicates that this attribute should remain unbound for now
return;
}
SharedArrayBuffer arrayBuffer = _attribute.arrayBuffer;
arrayBuffer->bind();
ArrayBuffer::Attribute arrayBufferAttribute = arrayBuffer->getAttributes()[_attribute.attributeID];
glVertexAttribPointer(_attribute.location,
arrayBufferAttribute.size,
arrayBufferAttribute.type,
arrayBufferAttribute.normalized,
arrayBuffer->getStride(),
reinterpret_cast<GLvoid*>(arrayBufferAttribute.offset)
);
glEnableVertexAttribArray(_attribute.location);
}
void setAttributePointer(const Attribute& _attribute);
// ===================================================================================================== \/
// ============================================================================================ WRAPPERS \/
......@@ -383,39 +321,17 @@ public:
glBindVertexArray( mObjectName );
}
//! Bind this VAO and remember the previously bound VAO
//! Note: every call to this method must be paired with a corresponding call to disable()
inline void enable(void) const
{
// remember old VAO
glGetIntegerv( GL_VERTEX_ARRAY_BINDING, &sPreviousVAOName );
bind();
}
//! Bind the VAO that was bound before the most recent enable() call
inline void disable(void) const
{
glBindVertexArray(sPreviousVAOName);
}
//! Nothing has to be prepared for a render call
inline void render (void) const
inline void render (void)
{
enable();
draw();
disable();
}
//! Will select the matching draw call. Remember to enable first!
//! Will select the matching draw call. Remember to bind() first!
void draw(void) const
{
// TODO: fail silently?
if(mAttributes.empty())
{
ACGL::Utils::error() << "cannot draw VAO with no attributes attached" << std::endl;
return;
}
if(mpElementArrayBuffer)
drawElements();
else
......@@ -447,20 +363,39 @@ public:
//! Draws all elements
inline void drawArrays(void) const
{
if(mAttributes.empty())
{
ACGL::Utils::error() << "cannot draw VAO with no attributes attached" << std::endl;
return;
}
drawArrays(mAttributes[0].arrayBuffer->getElements());
}
// =================================================================================================== \/
// ============================================================================================ FIELDS \/
// =================================================================================================== \/
protected:
private:
GLuint mObjectName; // OpenGL object name
SharedElementArrayBuffer mpElementArrayBuffer; // optional EAB
AttributeVec mAttributes; // vertex attributes
GLenum mMode; // primitive type to render (e.g. GL_TRIANGLES)
private:
static GLint sPreviousVAOName; // the VAO that was bound before the last enable() call
//! Bind this VAO and remember the previously bound VAO
//! Note: every call to this method must be paired with a corresponding call to disable()
inline void enable(void)
{
// remember old VAO
glGetIntegerv( GL_VERTEX_ARRAY_BINDING, &mPreviousVAOName );
if (mObjectName != (GLuint)mPreviousVAOName) bind();
}
//! Bind the VAO that was bound before the most recent enable() call
inline void disable(void)
{
if (mObjectName != (GLuint)mPreviousVAOName) glBindVertexArray((GLuint)mPreviousVAOName);
}
GLint mPreviousVAOName; // the VAO that was bound before the last enable() call
};
ACGL_SHARED_TYPEDEF(VertexArrayObject)
......
......@@ -34,8 +34,35 @@ int_t FrameBufferObject::getColorAttachmentIndexByName(const std::string& _name)
return -1;
}
bool FrameBufferObject::isFrameBufferObjectComplete() const
{
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
Utils::error() << "Failed to make complete FrameBufferObject object: ";
if (status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) {
Utils::error() << "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
} else if (status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) {
Utils::error() << "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
} else if (status == GL_FRAMEBUFFER_UNSUPPORTED) {
Utils::error() << "GL_FRAMEBUFFER_UNSUPPORTED";
} else if (status == GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE) {
Utils::error() << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
} else {
Utils::error() << status;
}
Utils::error() << std::endl;
return false;
}
return true;
}
void FrameBufferObject::validate(void) const
{
// if OpenGL says were ok, return
if (isFrameBufferObjectComplete()) return;
// the above call will create some output, but let's try to get more infos:
if(mColorAttachments.size() > 0)
{
int width = -1;
......
......@@ -79,7 +79,7 @@ void RenderObject::enableVertexArrayObject() const
{
if(mpVertexArrayObject)
{
mpVertexArrayObject->enable();
mpVertexArrayObject->bind();
}
else
{
......
......@@ -50,29 +50,24 @@ bool ShaderProgram::link() const
return true;
}
void ShaderProgram::setAttributeLocationsByVAO(ConstSharedVertexArrayObject _vao)
void ShaderProgram::setAttributeLocations(ConstSharedLocationMappings _locationMappings)
{
// TODO: deprecate
bool needsRelink = false;
// search through all attributes of _vao
VertexArrayObject::AttributeVec vaoAttributes = _vao->getAttributes();
for(VertexArrayObject::AttributeVec::size_type i = 0; i < vaoAttributes.size(); ++i)
{
if(vaoAttributes[i].location == -1)
continue;
// search through all attributes:
LocationMappings::LocationMap locations = _locationMappings->getLocations();
// find the name of the current attribute in its ArrayBuffer
std::string arrayBufferAttributeName = vaoAttributes[i].arrayBuffer->getAttributes()[vaoAttributes[i].attributeID].name;
for(LocationMappings::LocationMap::iterator it = locations.begin();
it != locations.end();
++it)
{
// find out whether a fragment data location with a matching name exists in this shader
GLint attributeLocation = getAttributeLocation((*it).first);
// find out whether an attribute with a matching name exists in this ShaderProgram
GLint attribLocation = getAttributeLocation(arrayBufferAttributeName);
if(attribLocation != -1 // attribute with that name exists?
&& attribLocation != vaoAttributes[i].location) // attribute with that name not already bound correctly?
if ( attributeLocation != -1 // attributeLocation with that name exists?
&& ((GLuint)attributeLocation) != (*it).second) // attributeLocation with that name not already bound correctly?
{
bindAttributeLocation(arrayBufferAttributeName, vaoAttributes[i].location);
bindAttributeLocation((*it).first, (*it).second);
needsRelink = true;
}
}
......@@ -85,23 +80,24 @@ void ShaderProgram::setAttributeLocationsByVAO(ConstSharedVertexArrayObject _vao
}
}
void ShaderProgram::setFragmentDataLocationsByFBO(ConstSharedFrameBufferObject _fbo)
void ShaderProgram::setFragmentDataLocations(ConstSharedLocationMappings _locationMappings)
{
// TODO: deprecate
bool needsRelink = false;
// search through all color attachments of _fbo
FrameBufferObject::AttachmentVec fboAttachments = _fbo->getColorAttachments();
for(FrameBufferObject::AttachmentVec::size_type i = 0; i < fboAttachments.size(); ++i)
// search through all color attachments:
LocationMappings::LocationMap locations = _locationMappings->getLocations();
for(LocationMappings::LocationMap::iterator it = locations.begin();
it != locations.end();
++it)
{
// find out whether a fragment data location with a matching name exists in this shader
GLint fragmentDataLocation = getFragmentDataLocation(fboAttachments[i].name);
if ( fragmentDataLocation != -1 // fragment data location with that name exists?
&& fragmentDataLocation != (GLint) i) // fragment data location with that name not already bound correctly?
{
bindFragmentDataLocation(fboAttachments[i].name, i);
GLint fragmentDataLocation = getFragmentDataLocation((*it).first);
if ( fragmentDataLocation != -1 // fragment data location with that name exists?
&& ((GLuint) fragmentDataLocation) != (*it).second) // fragment data location with that name not already bound correctly?
{
bindFragmentDataLocation((*it).first, (*it).second);
needsRelink = true;
}
}
......@@ -114,24 +110,31 @@ void ShaderProgram::setFragmentDataLocationsByFBO(ConstSharedFrameBufferObject _
}
}
void ShaderProgram::setAttributeLocations(ConstSharedLocationMappings _locationMappings)
/*
void ShaderProgram::setAttributeLocationsByVAO(ConstSharedVertexArrayObject _vao)
{
bool needsRelink = false;
// TODO: deprecate
// search through all color attachments of _fbo
LocationMappings::LocationMap locations = _locationMappings->getLocations();
bool needsRelink = false;
for(LocationMappings::LocationMap::iterator it = locations.begin();
it != locations.end();
++it)
// search through all attributes of _vao
VertexArrayObject::AttributeVec vaoAttributes = _vao->getAttributes();
for(VertexArrayObject::AttributeVec::size_type i = 0; i < vaoAttributes.size(); ++i)
{
// find out whether a fragment data location with a matching name exists in this shader
GLint fragmentDataLocation = getAttributeLocation((*it).first);
if(vaoAttributes[i].location == -1)
continue;
if(fragmentDataLocation != -1 // fragment data location with that name exists?
&& fragmentDataLocation != (*it).second) // fragment data location with that name not already bound correctly?
// find the name of the current attribute in its ArrayBuffer
std::string arrayBufferAttributeName = vaoAttributes[i].arrayBuffer->getAttributes()[vaoAttributes[i].attributeID].name;
// find out whether an attribute with a matching name exists in this ShaderProgram
GLint attribLocation = getAttributeLocation(arrayBufferAttributeName);
if(attribLocation != -1 // attribute with that name exists?
&& attribLocation != vaoAttributes[i].location) // attribute with that name not already bound correctly?
{
bindAttributeLocation((*it).first, (*it).second);
bindAttributeLocation(arrayBufferAttributeName, vaoAttributes[i].location);
needsRelink = true;
}
......@@ -143,26 +146,24 @@ void ShaderProgram::setAttributeLocations(ConstSharedLocationMappings _locationM
link();
openGLRareError();
}
}
void ShaderProgram::setFragmentDataLocations(ConstSharedLocationMappings _locationMappings)
}*/
/*
void ShaderProgram::setFragmentDataLocationsByFBO(ConstSharedFrameBufferObject _fbo)
{
// TODO: deprecate
bool needsRelink = false;
// search through all color attachments of _fbo
LocationMappings::LocationMap locations = _locationMappings->getLocations();
for(LocationMappings::LocationMap::iterator it = locations.begin();
it != locations.end();
++it)
FrameBufferObject::AttachmentVec fboAttachments = _fbo->getColorAttachments();
for(FrameBufferObject::AttachmentVec::size_type i = 0; i < fboAttachments.size(); ++i)