Commit aa066185 authored by Robert Menzel's avatar Robert Menzel

FBO redone

parent 2c552974
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <ACGL/OpenGL/Tools.hh> #include <ACGL/OpenGL/Tools.hh>
#include <ACGL/OpenGL/Objects/RenderBuffer.hh> #include <ACGL/OpenGL/Objects/RenderBuffer.hh>
#include <ACGL/OpenGL/Objects/Texture.hh> #include <ACGL/OpenGL/Objects/Texture.hh>
#include <ACGL/OpenGL/Objects/ShaderProgram.hh> //#include <ACGL/OpenGL/Objects/ShaderProgram.hh>
#include <ACGL/OpenGL/Objects/LocationMappings.hh> #include <ACGL/OpenGL/Objects/LocationMappings.hh>
#include <vector> #include <vector>
...@@ -43,12 +43,6 @@ class FrameBufferObject ...@@ -43,12 +43,6 @@ class FrameBufferObject
{ {
ACGL_NOT_COPYABLE(FrameBufferObject) ACGL_NOT_COPYABLE(FrameBufferObject)
// =================================================================================================== \/
// ============================================================================================ STATIC \/
// =================================================================================================== \/
private:
static GLuint msBuffers[8];
// ==================================================================================================== \/ // ==================================================================================================== \/
// ============================================================================================ STRUCTS \/ // ============================================================================================ STRUCTS \/
// ==================================================================================================== \/ // ==================================================================================================== \/
...@@ -56,10 +50,10 @@ public: ...@@ -56,10 +50,10 @@ public:
//! An attachment can be a texture or a render buffer //! An attachment can be a texture or a render buffer
struct Attachment struct Attachment
{ {
std::string name; std::string name; // user defined name that matches the fragment shader out
ConstSharedTexture texture; ConstSharedTexture texture; // attached color texture, or:
ConstSharedRenderBuffer renderBuffer; ConstSharedRenderBuffer renderBuffer; // attached renderbuffer - only this or the texture should be set!
int_t fragDataLocation; // the frag data location that maps to this attachment GLuint location; // the frag data location that maps to this attachment
}; };
// ===================================================================================================== \/ // ===================================================================================================== \/
...@@ -74,10 +68,7 @@ public: ...@@ -74,10 +68,7 @@ public:
public: public:
FrameBufferObject(void) FrameBufferObject(void)
: mObjectName(0), : mObjectName(0),
mDrawBuffers(0),
mColorAttachments(), mColorAttachments(),
mColorAttachmentIndices(),
mFragDataLocationIndices(),
mDepthAttachment() mDepthAttachment()
{ {
glGenFramebuffers(1, &mObjectName); glGenFramebuffers(1, &mObjectName);
...@@ -86,9 +77,10 @@ public: ...@@ -86,9 +77,10 @@ public:
ACGL::Utils::error() << "could not generate FrameBufferObject!" << std::endl; ACGL::Utils::error() << "could not generate FrameBufferObject!" << std::endl;
return; return;
} }
mDepthAttachment.name = ""; mDepthAttachment.texture = ConstSharedTexture();
mDepthAttachment.texture = ConstSharedTexture();
mDepthAttachment.renderBuffer = ConstSharedRenderBuffer(); mDepthAttachment.renderBuffer = ConstSharedRenderBuffer();
mDepthAttachment.name = ""; // not useful here
mDepthAttachment.location = -1; // not useful here
} }
virtual ~FrameBufferObject(void) virtual ~FrameBufferObject(void)
...@@ -140,56 +132,36 @@ public: ...@@ -140,56 +132,36 @@ public:
openGLRareError(); openGLRareError();
}*/ }*/
//! let OpenGL validate the completeness
bool isFrameBufferObjectComplete() const; bool isFrameBufferObjectComplete() const;
inline bool attachColorRenderBuffer(const std::string _name, const ConstSharedRenderBuffer& _renderBuffer) /*
* Attach another RenderBuffer as a render target. If the name already exists the old target will get replaced.
*/
inline bool attachColorRenderBuffer(const std::string &_name, const ConstSharedRenderBuffer& _renderBuffer)
{ {
bind(); return attachColorAttachment( (Attachment){_name, SharedTexture(), _renderBuffer, mColorAttachments.size()} );
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + mDrawBuffers, GL_RENDERBUFFER, _renderBuffer->getObjectName() );
if (openGLCommonErrorOccured())
{
Utils::error() << "Attaching of render buffer to the FBO failed" << std::endl;
return false;
}
Attachment attachment = {_name, SharedTexture(), _renderBuffer};
mColorAttachments.push_back(attachment);
mColorAttachmentIndices[_name] = mDrawBuffers;
mFragDataLocationIndices[mDrawBuffers] = mDrawBuffers;
mDrawBuffers++;
return true;
} }
inline bool attachColorTexture(const std::string _name, const ConstSharedTexture& _texture) inline bool attachColorTexture(const std::string &_name, const ConstSharedTexture& _texture)
{ {
bind(); return attachColorAttachment( (Attachment){_name, _texture, SharedRenderBuffer(), mColorAttachments.size()} );
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + mDrawBuffers, _texture->getTarget(), _texture->getObjectName(), 0 );
if (openGLCommonErrorOccured())
{
Utils::error() << "Attaching of texture to the FBO failed" << std::endl;
return false;
}
Attachment attachment = {_name, _texture, SharedRenderBuffer()};
mColorAttachments.push_back(attachment);
mColorAttachmentIndices[_name] = mDrawBuffers;
mFragDataLocationIndices[mDrawBuffers] = mDrawBuffers;
mDrawBuffers++;
return true;
} }
inline bool setColorRenderBuffer(const std::string _name, const ConstSharedRenderBuffer& _renderBuffer) inline bool attachColorRenderBuffer(const std::string &_name, const ConstSharedRenderBuffer& _renderBuffer, GLuint _location )
{ {
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + mColorAttachmentIndices[_name], GL_RENDERBUFFER, _renderBuffer->getObjectName() ); return attachColorAttachment( (Attachment){_name, SharedTexture(), _renderBuffer, _location} );
return true;
} }
inline bool setColorTexture(const std::string _name, const ConstSharedTexture& _texture) inline bool attachColorTexture(const std::string &_name, const ConstSharedTexture& _texture, GLuint _location )
{ {
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + mColorAttachmentIndices[_name], _texture->getTarget(), _texture->getObjectName(), 0 ); return attachColorAttachment( (Attachment){_name, _texture, SharedRenderBuffer(), _location} );
return true;
} }
bool attachColorAttachment( const Attachment &_attachment );
void remapAttachments();
inline bool setDepthRenderBuffer(const ConstSharedRenderBuffer& _renderBuffer) inline bool setDepthRenderBuffer(const ConstSharedRenderBuffer& _renderBuffer)
{ {
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _renderBuffer->getObjectName() ); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _renderBuffer->getObjectName() );
...@@ -226,30 +198,20 @@ public: ...@@ -226,30 +198,20 @@ public:
// =========================================================================================== METHODS \/ // =========================================================================================== METHODS \/
// =================================================================================================== \/ // =================================================================================================== \/
public: public:
//! updates the attachment locations of this FBO so they match the locations of fragment shader output
//! variables of the same names in _shaderPorgram
void setAttachmentsByShaderProgram(ConstSharedShaderProgram _shaderProgram);
//! sets the attachment locations of this FBO where they match the names specified in _locationMappings //! sets the attachment locations of this FBO where they match the names specified in _locationMappings
void setAttachmentLocations(ConstSharedLocationMappings _locationMappings); void setAttachmentLocations(ConstSharedLocationMappings _locationMappings);
protected: //! get a list of attachment locations and names that can be used to set up a ShaderProgram
//! maps the frag data locations specified in mFragDataLocationIndices to the respective color attachments SharedLocationMappings getAttachmentLocations();
void updateDrawBuffers();
// =================================================================================================== \/ // =================================================================================================== \/
// ============================================================================================ FIELDS \/ // ============================================================================================ FIELDS \/
// =================================================================================================== \/ // =================================================================================================== \/
protected: protected:
GLuint mObjectName; GLuint mObjectName;
GLsizei mDrawBuffers;
AttachmentVec mColorAttachments; AttachmentVec mColorAttachments;
Attachment mDepthAttachment; // depth and stencil are combined
std::map<std::string, int> mColorAttachmentIndices; // maps color attachment names to attachment indices (GL_COLOR_ATTACHMENT0 + i) GLuint mBufferMappings[8]; // maps from mColorAttachment.loction (shader outs) to FBO locations (order of mColorAttachments)
std::map<int, int> mFragDataLocationIndices; // maps fragment data locations to attachment indices (GL_COLOR_ATTACHMENT0 + i)
Attachment mDepthAttachment; // depth and stencil are combined
}; };
ACGL_SHARED_TYPEDEF(FrameBufferObject) ACGL_SHARED_TYPEDEF(FrameBufferObject)
......
...@@ -99,39 +99,51 @@ public: ...@@ -99,39 +99,51 @@ public:
// ============================================================================================ WRAPPERS \/ // ============================================================================================ WRAPPERS \/
// ===================================================================================================== \/ // ===================================================================================================== \/
public: public:
inline GLint getUniformLocation (const std::string& _nameInShader) const { return glGetUniformLocation (mObjectName, _nameInShader.c_str()); } //! use, or activate it for rendering, also needed to set uniforms:
inline GLint getAttributeLocation (const std::string& _nameInShader) const { return glGetAttribLocation (mObjectName, _nameInShader.c_str()); }
inline void bindAttributeLocation (const std::string& _nameInShader, GLuint _location) const { glBindAttribLocation (mObjectName, _location, _nameInShader.c_str()); }
#if (ACGL_OPENGL_VERSION >= 30)
inline GLint getFragmentDataLocation (const std::string& _nameInShader) const { return glGetFragDataLocation(mObjectName, _nameInShader.c_str()); }
inline void bindFragmentDataLocation (const std::string& _nameInShader, GLuint _location) const { glBindFragDataLocation (mObjectName, _location, _nameInShader.c_str()); }
#endif // OpenGL >= 3.0
inline void use(void) const { glUseProgram(mObjectName); } inline void use(void) const { glUseProgram(mObjectName); }
//! attach a single shader, don't forget to relink!
inline void attachShader(const ConstSharedShader& _shader) inline void attachShader(const ConstSharedShader& _shader)
{ {
mShaders.push_back(_shader); mShaders.push_back(_shader);
glAttachShader( mObjectName, _shader->getObjectName() ); glAttachShader( mObjectName, _shader->getObjectName() );
} }
//! link the program, has to be redone after changing input or output locations:
bool link (void) const; bool link (void) const;
// ===================================================================================================== \/ // ===================================================================================================== \/
// ============================================================================================= METHODS \/ // =========================================================================================== LOCATIONS \/
// ===================================================================================================== \/ // ===================================================================================================== \/
public:
// Matches the attribute locations of this ShaderProgram to the names of the ArrayBuffer attributes currently attached to _vao //////////// uniform locations:
//void setAttributeLocationsByVAO( ConstSharedVertexArrayObject _vao ); inline GLint getUniformLocation (const std::string& _nameInShader) const { return glGetUniformLocation (mObjectName, _nameInShader.c_str()); }
// Matches the fragment data locations of this ShaderProgram to the names of the color attachments of _fbo
//void setFragmentDataLocationsByFBO( ConstSharedFrameBufferObject _fbo ); //////////// attribute locations:
inline GLint getAttributeLocation (const std::string& _nameInShader) const { return glGetAttribLocation (mObjectName, _nameInShader.c_str()); }
inline void bindAttributeLocation (const std::string& _nameInShader, GLuint _location) const { glBindAttribLocation (mObjectName, _location, _nameInShader.c_str()); }
//! Sets the attribute locations of this ShaderProgram according to the mappings specified in //! Sets the attribute locations of this ShaderProgram according to the mappings specified in
void setAttributeLocations( ConstSharedLocationMappings _locationMappings ); void setAttributeLocations( ConstSharedLocationMappings _locationMappings );
//! Get all attribute names with there locations:
SharedLocationMappings getAttributeLocations();
//////////// fragdata locations:
#if (ACGL_OPENGL_VERSION >= 30)
inline GLint getFragmentDataLocation (const std::string& _nameInShader) const { return glGetFragDataLocation(mObjectName, _nameInShader.c_str()); }
inline void bindFragmentDataLocation (const std::string& _nameInShader, GLuint _location) const { glBindFragDataLocation (mObjectName, _location, _nameInShader.c_str()); }
//! Sets the fragment data locations of this ShaderProgram according to the mappings specified in //! Sets the fragment data locations of this ShaderProgram according to the mappings specified in
void setFragmentDataLocations( ConstSharedLocationMappings _locationMappings ); void setFragmentDataLocations( ConstSharedLocationMappings _locationMappings );
//! Get all fragdata names with there locations:
SharedLocationMappings getFragmentDataLocations();
#endif // OpenGL >= 3.0
// 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 );
// ===================================================================================================== \/ // ===================================================================================================== \/
// ============================================================================================ UNIFORMS \/ // ============================================================================================ UNIFORMS \/
......
...@@ -8,21 +8,6 @@ ...@@ -8,21 +8,6 @@
using namespace ACGL; using namespace ACGL;
using namespace ACGL::OpenGL; using namespace ACGL::OpenGL;
/*
* We can't use the constants GL_COLOR_ATTACHMENT1 to GL_COLOR_ATTACHMENT7 here
* because OpenGL ES does not know these yet.
*/
GLuint FrameBufferObject::msBuffers[8] = {
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT0+1,
GL_COLOR_ATTACHMENT0+2,
GL_COLOR_ATTACHMENT0+3,
GL_COLOR_ATTACHMENT0+4,
GL_COLOR_ATTACHMENT0+5,
GL_COLOR_ATTACHMENT0+6,
GL_COLOR_ATTACHMENT0+7};
int_t FrameBufferObject::getColorAttachmentIndexByName(const std::string& _name) const int_t FrameBufferObject::getColorAttachmentIndexByName(const std::string& _name) const
{ {
for(AttachmentVec::size_type i = 0; i < mColorAttachments.size(); i++) for(AttachmentVec::size_type i = 0; i < mColorAttachments.size(); i++)
...@@ -96,132 +81,103 @@ void FrameBufferObject::validate(void) const ...@@ -96,132 +81,103 @@ void FrameBufferObject::validate(void) const
Utils::error() << "FrameBufferObject validation failed: No color attachments."<< std::endl; Utils::error() << "FrameBufferObject validation failed: No color attachments."<< std::endl;
} }
void FrameBufferObject::setAttachmentsByShaderProgram(ConstSharedShaderProgram _shaderProgram) bool FrameBufferObject::attachColorAttachment( const Attachment &_attachment )
{ {
// TODO: deprecate int realLocation = -1;
bool needsUpdate = false; for (unsigned int i = 0; i < mColorAttachments.size(); ++i) {
if (mColorAttachments[i].name == _attachment.name) {
// replace this attachment
mColorAttachments[i] = _attachment;
realLocation = i;
}
}
if (realLocation == -1) {
// it's a new attachment
realLocation = mColorAttachments.size();
mColorAttachments.push_back(_attachment);
}
for(AttachmentVec::size_type i = 0; i < mColorAttachments.size(); i++) // attach it to the OpenGL object:
bind();
openGLCriticalErrorOccured();
if (_attachment.renderBuffer) {
// it's a renderBuffer
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + realLocation, GL_RENDERBUFFER, _attachment.renderBuffer->getObjectName() );
} else {
// it's a texture
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + realLocation, _attachment.texture->getTarget(), _attachment.texture->getObjectName(), 0 );
Utils::debug() << "glFramebufferTexture2D( " << _attachment.name << " to " << realLocation <<" )" << std::endl;
}
if (openGLCommonErrorOccured())
{ {
GLint fragDataLocation = _shaderProgram->getFragmentDataLocation(mColorAttachments[i].name); Utils::error() << "Attaching of render target to the FBO failed" << std::endl;
return false;
}
if(fragDataLocation != -1 // does a fragment data location by that name exist in the ShaderProgram? remapAttachments();
&& fragDataLocation != mColorAttachmentIndices[mColorAttachments[i].name]) // does it match the index of the color attachment? return true;
{ }
mColorAttachmentIndices[mColorAttachments[i].name] = fragDataLocation;
needsUpdate = true; void FrameBufferObject::remapAttachments()
} {
} // max color attachments: 8, TODO
const int maxColorBuffers = 8;
GLenum bufferMappings[maxColorBuffers];
unsigned int attachments = std::min( maxColorBuffers, (int) mColorAttachments.size() );
if(needsUpdate) for (unsigned int i = 0; i < maxColorBuffers; ++i) {
{ bufferMappings[i] = GL_NONE;
bind(); }
for (unsigned int i = 0; i < attachments; ++i) {
bufferMappings[ mColorAttachments[i].location ] = GL_COLOR_ATTACHMENT0 + i;
}
for(AttachmentVec::size_type i = 0; i < mColorAttachments.size(); i++) // debug:
{ Utils::message() << "remapAttachments: " << std::endl;
if(mColorAttachments[i].texture) for (unsigned int i = 0; i < maxColorBuffers; ++i) {
glFramebufferTexture2D( if (bufferMappings[i] == GL_NONE) {
GL_FRAMEBUFFER, Utils::debug() << "bufferMappings["<<i<<"] GL_NONE" << std::endl;
GL_COLOR_ATTACHMENT0 + mColorAttachmentIndices[mColorAttachments[i].name], } else {
mColorAttachments[i].texture->getTarget(), Utils::debug() << "bufferMappings["<<i<<"] "<< bufferMappings[i]-GL_COLOR_ATTACHMENT0 << std::endl;
mColorAttachments[i].texture->getObjectName(),
0
);
if(mColorAttachments[i].renderBuffer)
glFramebufferRenderbuffer(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0 + mColorAttachmentIndices[mColorAttachments[i].name],
GL_RENDERBUFFER,
mColorAttachments[i].renderBuffer->getObjectName()
);
} }
} }
// end debug
openGLRareError(); bind(); // glDrawBuffers will get part of the FBO state!
glDrawBuffers( maxColorBuffers, bufferMappings );
} }
void FrameBufferObject::setAttachmentLocations(ConstSharedLocationMappings _locationMappings) void FrameBufferObject::setAttachmentLocations(ConstSharedLocationMappings _locationMappings)
{ {
bool needsUpdate = false; bool needsUpdate = false;
// First, erase all existing frag data location mappings that coincide with names specified in _locationMappings
for(AttachmentVec::size_type i = 0; i < mColorAttachments.size(); i++) for(AttachmentVec::size_type i = 0; i < mColorAttachments.size(); i++)
{ {
int_t location = _locationMappings->getLocation(mColorAttachments[i].name); int_t location = _locationMappings->getLocation(mColorAttachments[i].name);
if(location != -1) // is a mapping by that name specified? if (location != -1) // is a mapping by that name specified?
{ {
// remove previous frag data location pointing to this color attachment mColorAttachments[i].location = location;
mFragDataLocationIndices.erase(i);
//ACGL::Utils::debug() << "Dropping attachment for " << mColorAttachments[i].name << " (index " << i << ")" << std::endl;
needsUpdate = true; needsUpdate = true;
} }
} }
// Then, wire up the new mappings if(needsUpdate) remapAttachments();
for(AttachmentVec::size_type i = 0; i < mColorAttachments.size(); i++)
{
int_t location = _locationMappings->getLocation(mColorAttachments[i].name);
//ACGL::Utils::debug() << "Color attachment " << mColorAttachments[i].name << " (index " << i << ") should be mapped to frag data location " << location;
//ACGL::Utils::debug() << ". Currently mapped to: " << mFragDataLocationIndices[location] << std::endl;
if(location != -1) // is a mapping by that name specified?
{
//ACGL::Utils::debug() << "Attaching frag data location " << location << " to color attachment " << i << std::endl;
mFragDataLocationIndices[location] = i;
}
}
if(needsUpdate)
{
updateDrawBuffers();
}
} }
void FrameBufferObject::updateDrawBuffers()
{
// No fragment data mappings set up? -> Nothing to do
if(mFragDataLocationIndices.size() == 0)
{
return;
}
// The (temporary) buffer mapping table must be large enough to contain all mapped frag data locations SharedLocationMappings FrameBufferObject::getAttachmentLocations()
GLint maxDrawBuffers; glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); // TODO: clever caching? {
GLsizei numBuffers = std::min(mFragDataLocationIndices.rbegin()->first + 1, maxDrawBuffers); SharedLocationMappings locationMap = SharedLocationMappings( new LocationMappings() );
GLenum* buffers = new GLenum[numBuffers]; for (AttachmentVec::size_type i = 0; i < mColorAttachments.size(); i++)
for(GLsizei i = 0; i < numBuffers; ++i)
{ {
// frag data mapping for this index exists? locationMap->setLocation( mColorAttachments[i].name, mColorAttachments[i].location );
if(mFragDataLocationIndices.count(i) > 0) //ACGL::Utils::debug() << "locationMap->setLocation( "<<mColorAttachments[i].name<<", "<<mColorAttachments[i].location<<" );"<<std::endl;
{
// map the frag data location to the given color attachment
buffers[i] = GL_COLOR_ATTACHMENT0 + mFragDataLocationIndices[i];
//ACGL::Utils::debug() << "mFragDataLocationIndices[" << i << "] = " << mFragDataLocationIndices[i] << std::endl;
}
else
{
buffers[i] = GL_NONE;
}
} }
// TODO: remove debug output return locationMap;
// ACGL::Utils::debug() << "Uploading mapping:";
// for(int i = 0; i < numBuffers; ++i) {
// ACGL::Utils::debug() << " " << buffers[i];
// }
// ACGL::Utils::debug() << std::endl;
// upload the new mapping
bind();
glDrawBuffers(numBuffers, buffers);
delete[] buffers;
openGLRareError();
} }
...@@ -94,10 +94,13 @@ void ShaderProgram::setFragmentDataLocations(ConstSharedLocationMappings _locati ...@@ -94,10 +94,13 @@ void ShaderProgram::setFragmentDataLocations(ConstSharedLocationMappings _locati
// find out whether a fragment data location with a matching name exists in this shader // find out whether a fragment data location with a matching name exists in this shader
GLint fragmentDataLocation = getFragmentDataLocation((*it).first); GLint fragmentDataLocation = getFragmentDataLocation((*it).first);
//ACGL::Utils::debug() << "test ("<<(*it).first<<", "<<(*it).second<<"); loc:"<<fragmentDataLocation<<std::endl;
if ( fragmentDataLocation != -1 // fragment data location with that name exists? if ( fragmentDataLocation != -1 // fragment data location with that name exists?
&& ((GLuint) fragmentDataLocation) != (*it).second) // fragment data location with that name not already bound correctly? && ((GLuint) fragmentDataLocation) != (*it).second) // fragment data location with that name not already bound correctly?
{ {
bindFragmentDataLocation((*it).first, (*it).second); bindFragmentDataLocation((*it).first, (*it).second);
ACGL::Utils::debug() << "bindFragmentDataLocation("<<(*it).first<<", "<<(*it).second<<");"<<std::endl;
needsRelink = true; needsRelink = true;
} }
} }
...@@ -110,6 +113,47 @@ void ShaderProgram::setFragmentDataLocations(ConstSharedLocationMappings _locati ...@@ -110,6 +113,47 @@ void ShaderProgram::setFragmentDataLocations(ConstSharedLocationMappings _locati
} }
} }
SharedLocationMappings ShaderProgram::getAttributeLocations()
{
SharedLocationMappings locationMap = SharedLocationMappings( new LocationMappings() );
// query the number of _active_ attributes:
GLint attributeCount;
glGetProgramiv( mObjectName, GL_ACTIVE_ATTRIBUTES, &attributeCount );
if (attributeCount == 0) return locationMap;
// reserve a string long enought for the longest name:
GLint longestAttributeName;
glGetProgramiv( mObjectName, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &longestAttributeName );
char *name = new char[longestAttributeName+1];
// get the name and location of each active attribute:
for (int i = 0; i < attributeCount; ++i) {
GLenum type;
GLint size;
GLsizei length;
glGetActiveAttrib( mObjectName, i, longestAttributeName, &length, &size, &type, name );
name[ length+1 ] = 0; // null terminate
GLint attribLocation = glGetAttribLocation( mObjectName, name );
//ACGL::Utils::debug() << "found attrib " << name << " at " << attribLocation << std::endl;
locationMap->setLocation( std::string(name), (GLuint) attribLocation );
}
delete name;
return locationMap;
}
SharedLocationMappings ShaderProgram::getFragmentDataLocations()
{
SharedLocationMappings locationMap = SharedLocationMappings( new LocationMappings() );
ACGL::Utils::error() << " ShaderProgram::getFragmentDataLocations is not implemented -> missing OpenGL API" << std::endl;
return locationMap;
}
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment