Commit 708174d6 authored by Robert Menzel's avatar Robert Menzel

Automatic consistent attribute location mappings possible

Example:
SharedLocationMappings globalLocationMappings = SharedLocationMappings( new LocationMappings );
// now the map could get set by hand, but thats not needed:
ShaderProgramFileManager::the()->get( ShaderProgramControlFiles("shader1").
                                      externAttributeLocations(globalLocationMappings) );
// will add all maps from the shader1 to the global map
ShaderProgramFileManager::the()->get( ShaderProgramControlFiles("shader2").
                                      externAttributeLocations(globalLocationMappings) );
// will add all maps from shader2, attributes already known will not get changed, no location collitions.

Reloading of the shaders due to changed files will automatically set the locations again.
parent ce03ceed
...@@ -74,7 +74,6 @@ public: ...@@ -74,7 +74,6 @@ public:
// ============================================================================================ METHODS \/ // ============================================================================================ METHODS \/
// ==================================================================================================== \/ // ==================================================================================================== \/
public: public:
//void addFile (const std::string &_fileName) {};
// //
// Adding files: // Adding files:
// //
...@@ -100,6 +99,10 @@ public: ...@@ -100,6 +99,10 @@ public:
//! adds a whole list of mappings //! adds a whole list of mappings
inline ShaderProgramControlFiles& attributeLocations (const SharedLocationMappings &_mapping) { mAttributeLocations->addLocations(_mapping); return *this; } inline ShaderProgramControlFiles& attributeLocations (const SharedLocationMappings &_mapping) { mAttributeLocations->addLocations(_mapping); return *this; }
//! links to the external mapping object, earlyer mapping definitions get ignored, following
//! mappings will also change the external object!
inline ShaderProgramControlFiles& externAttributeLocations (SharedLocationMappings _mapping) { mAttributeLocations = _mapping; return *this; }
// //
// Adding fragment output locations: // Adding fragment output locations:
// //
...@@ -122,7 +125,7 @@ public: ...@@ -122,7 +125,7 @@ public:
inline ShaderProgramControlFiles& uniformBufferLocation(const std::string &_uniformBufferName, GLuint _location){ mUniformBufferLocations->setLocation(_uniformBufferName,_location);return *this; } inline ShaderProgramControlFiles& uniformBufferLocation(const std::string &_uniformBufferName, GLuint _location){ mUniformBufferLocations->setLocation(_uniformBufferName,_location);return *this; }
//! adds a whole list of mappings //! adds a whole list of mappings
inline ShaderProgramControlFiles& uniformBufferLocations(const SharedLocationMappings &_mapping) { mUniformBufferLocations->addLocations(_mapping);return *this; } inline ShaderProgramControlFiles& uniformBufferLocations(SharedLocationMappings _mapping) { mUniformBufferLocations->addLocations(_mapping);return *this; }
// //
// Modifying the resource name: // Modifying the resource name:
...@@ -130,7 +133,6 @@ public: ...@@ -130,7 +133,6 @@ public:
// is often not useful. // is often not useful.
// //
inline ShaderProgramControlFiles& setResourceName(const std::string &_resourceName) { mResourceName = _resourceName; return *this; } inline ShaderProgramControlFiles& setResourceName(const std::string &_resourceName) { mResourceName = _resourceName; return *this; }
//virtual std::string getResourceName(void) const;// { return mResourceName; }
// ===================================================================================================== \/ // ===================================================================================================== \/
......
...@@ -69,14 +69,22 @@ public: ...@@ -69,14 +69,22 @@ public:
// ==================================================================================================== \/ // ==================================================================================================== \/
public: public:
//! Adds one location: //! Adds one location, if the name already exists, the location number gets changed:
void setLocation(const std::string& _name, GLuint _location); void setLocation(const std::string& _name, GLuint _location);
//! Adds one location, uses the next free integer as the location //! Adds one location, uses the next free integer as the location
//! this way the locations can get the number of the order they were added (if only this function gets used) //! this way the locations can get the number of the order they were added (if only this function gets used)
void setLocation(const std::string& _name); void setLocation(const std::string& _name);
//! adds all given locations: //! Adds all given locations via setLocation:
void setLocations( const ptr::shared_ptr<LocationMappings> &_other );
//! Adds one location, if the name is new! (otherwise keep the old one)
//! If the name is new and the location is free, use that, otherwise use a free location
//! Useful for merging -> uses as much info from the new location WITHOUT destroying and old information!
void addLocation( const std::string& _name, GLuint _location );
//! Adds all given locations via addLocation:
void addLocations( const ptr::shared_ptr<LocationMappings> &_other ); void addLocations( const ptr::shared_ptr<LocationMappings> &_other );
// ==================================================================================================== \/ // ==================================================================================================== \/
...@@ -92,6 +100,8 @@ public: ...@@ -92,6 +100,8 @@ public:
// ============================================================================================ FIELDS \/ // ============================================================================================ FIELDS \/
// =================================================================================================== \/ // =================================================================================================== \/
protected: protected:
//! returns the first unused location number
GLuint getFreeLocation();
LocationMap mMappings; LocationMap mMappings;
}; };
ACGL_SMARTPOINTER_TYPEDEFS(LocationMappings) ACGL_SMARTPOINTER_TYPEDEFS(LocationMappings)
......
...@@ -149,7 +149,7 @@ public: ...@@ -149,7 +149,7 @@ public:
inline GLint getAttributeLocation (const std::string& _nameInShader) const { return glGetAttribLocation (mObjectName, _nameInShader.c_str()); } 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()); } 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 _locationMappings
void setAttributeLocations( ConstSharedLocationMappings _locationMappings ); void setAttributeLocations( ConstSharedLocationMappings _locationMappings );
//! Get all attribute names with there locations: //! Get all attribute names with there locations:
SharedLocationMappings getAttributeLocations(); SharedLocationMappings getAttributeLocations();
......
...@@ -49,8 +49,6 @@ public: ...@@ -49,8 +49,6 @@ public:
//! a setter for a user-defined resourcename should be defined in derived classes //! a setter for a user-defined resourcename should be defined in derived classes
virtual std::string getResourceName(void) const virtual std::string getResourceName(void) const
{ {
// unless a name was set explicitly, set the 'filename' of this resource to the concatenation
// of the sorted list of filenames (most likely unique, but not guaranteed)
if (mResourceName == "") { if (mResourceName == "") {
std::vector<std::string> namesAlpha = mFileNames; std::vector<std::string> namesAlpha = mFileNames;
std::sort(namesAlpha.begin(), namesAlpha.end()); std::sort(namesAlpha.begin(), namesAlpha.end());
......
...@@ -121,10 +121,24 @@ SharedShaderProgram ShaderProgramControlFiles::create(void) ...@@ -121,10 +121,24 @@ SharedShaderProgram ShaderProgramControlFiles::create(void)
return shaderProgram; return shaderProgram;
} }
// program has to be linked before calling setBindings!
void ShaderProgramControlFiles::setBindings(SharedShaderProgram &_shaderProgram) void ShaderProgramControlFiles::setBindings(SharedShaderProgram &_shaderProgram)
{ {
# if (ACGL_OPENGL_VERSION >= 30) # if (ACGL_OPENGL_VERSION >= 30)
_shaderProgram->setFragmentDataLocations( mFragmentDataLocations ); // will relink on it's own _shaderProgram->setFragmentDataLocations( mFragmentDataLocations ); // will relink on it's own
SharedLocationMappings oldMap = _shaderProgram->getAttributeLocations();
Utils::debug() << "oldmap:"<<std::endl;
oldMap->printMapping();
Utils::debug() << "mAttributeLocations before:"<<std::endl;
mAttributeLocations->printMapping();
mAttributeLocations->addLocations( oldMap ); // add as many old locations as possible without destoying the location map
Utils::debug() << "mAttributeLocations after:"<<std::endl;
mAttributeLocations->printMapping();
_shaderProgram->setAttributeLocations( mAttributeLocations ); // will relink on it's own _shaderProgram->setAttributeLocations( mAttributeLocations ); // will relink on it's own
# else # else
if ( (mAttributeLocations->getSize() > 0) && (mFragmentDataLocations->getSize() > 0) ) { if ( (mAttributeLocations->getSize() > 0) && (mFragmentDataLocations->getSize() > 0) ) {
......
...@@ -52,7 +52,7 @@ void LocationMappings::setLocation(const std::string& _name) ...@@ -52,7 +52,7 @@ void LocationMappings::setLocation(const std::string& _name)
setLocation( _name, nextFreeLocation ); setLocation( _name, nextFreeLocation );
} }
void LocationMappings::addLocations( const SharedLocationMappings &_other ) void LocationMappings::setLocations( const SharedLocationMappings &_other )
{ {
LocationMap::const_iterator end = _other->mMappings.end(); LocationMap::const_iterator end = _other->mMappings.end();
for (LocationMap::const_iterator it = _other->mMappings.begin(); it != end; ++it) { for (LocationMap::const_iterator it = _other->mMappings.begin(); it != end; ++it) {
...@@ -60,6 +60,59 @@ void LocationMappings::addLocations( const SharedLocationMappings &_other ) ...@@ -60,6 +60,59 @@ void LocationMappings::addLocations( const SharedLocationMappings &_other )
} }
} }
void LocationMappings::addLocation( const std::string& _name, GLuint _location )
{
ACGL::Utils::message() << "addLocation( "<< _name<< ", "<<_location<<" )"<<std::endl;
LocationMap::const_iterator location = mMappings.find(_name);
if (location == mMappings.end()) {
// name did not exist jet
LocationMap::iterator it = mMappings.begin();
while (it != mMappings.end())
{
if (it->second == _location) {
// but the number is already taken, find a free one:
mMappings[_name] = getFreeLocation();
return;
}
++it;
}
// new name, new location, just add it:
mMappings[_name] = _location;
return;
}
// name is taken, ignore the new location, keep the old one
}
void LocationMappings::addLocations( const SharedLocationMappings &_other )
{
LocationMap::const_iterator end = _other->mMappings.end();
for (LocationMap::const_iterator it = _other->mMappings.begin(); it != end; ++it) {
addLocation( it->first, it->second );
}
}
GLuint LocationMappings::getFreeLocation()
{
LocationMap::iterator it = mMappings.begin();
GLuint unused = 0;
while (true) {
while (it != mMappings.end())
{
if (it->second == unused) {
// test next number from the beginning of the map:
unused++;
it = mMappings.begin();
} else {
++it;
}
}
// this number was not found in the map:
return unused;
}
}
void LocationMappings::printMapping() void LocationMappings::printMapping()
{ {
LocationMap::const_iterator end = mMappings.end(); LocationMap::const_iterator end = mMappings.end();
......
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