Commit 8435787d authored by Robert Menzel's avatar Robert Menzel

added new ShaderProgramControlFiles, fixed minor ShaderProgramControlAutoFiles bug

* ShaderProgramControlFiles is similar to ShaderProgramControlAutoFiles but the files
  have to be named explicitly which makes it possible to share some shaders for different
  ShaderPrograms.
* Both ShaderProgram controllers share some code, this should get reduced by refactoring.
* ShaderProgramControlAutoFiles had a copy&paste bug
parent 26717eef
......@@ -34,7 +34,7 @@ namespace FileHelpers
* Checks if a string ends with a certain ending. Can be used to check for fileendings:
* if (stringEndsWith( "foobar.txt", ".txt" )) cout << "textfile";
*/
//bool stringEndsWith( const std::string &theString, const std::string &theEnding );
bool stringEndsWith( const std::string &theString, const std::string &theEnding );
/*
* Checks if a string begins with a certain prefix.
......
......@@ -25,6 +25,7 @@
#include <ACGL/OpenGL/Controller/RenderObjectControl.hh>
#include <ACGL/OpenGL/Controller/ShaderControlFile.hh>
#include <ACGL/OpenGL/Controller/ShaderProgramControlAutoFiles.hh>
#include <ACGL/OpenGL/Controller/ShaderProgramControlFiles.hh>
#include <ACGL/OpenGL/Controller/ShaderProgramObjectControl.hh>
#include <ACGL/OpenGL/Controller/TextureControl.hh>
#include <ACGL/OpenGL/Controller/TextureControlFileJPG.hh>
......
......@@ -34,8 +34,8 @@ public:
// ============================================================================================ METHODS \/
// ==================================================================================================== \/
public:
inline ShaderProgramControlAutoFiles& attributeLocation (const std::string& _attributeName) { mAttributeLocations.push_back(_attributeName); return *this; }
inline ShaderProgramControlAutoFiles& fragmentDataLocation (const std::string& _fragmentDataName) { mAttributeLocations.push_back(_fragmentDataName); return *this; }
inline ShaderProgramControlAutoFiles& attributeLocation (const std::string& _attributeName) { mAttributeLocations.push_back(_attributeName); return *this; }
inline ShaderProgramControlAutoFiles& fragmentDataLocation (const std::string& _fragmentDataName) { mFragmentDataLocations.push_back(_fragmentDataName); return *this; }
// ===================================================================================================== \/
// ============================================================================================ OVERRIDE \/
......
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
#ifndef ACGL_OPENGL_CONTROLLER_SHADERPROGRAMCONTROLFILES_HH
#define ACGL_OPENGL_CONTROLLER_SHADERPROGRAMCONTROLFILES_HH
/*
* Used to create a ShaderProgram from a given set of file names:
* e.g.:
* SharedShaderProgram prog = ShaderProgramControlFiles("file.vsh").andFile("foobar.fsh").create();
*
* The shadertype will be guessed by the extensions.
*/
#include <ACGL/ACGL.hh>
#include <ACGL/Resource/FileController.hh>
#include <ACGL/OpenGL/Objects/ShaderProgram.hh>
#include <ACGL/OpenGL/GL.hh>
#include <vector>
namespace ACGL{
namespace OpenGL{
class ShaderProgramControlFiles : public Resource::FileController<ShaderProgram>
{
// ========================================================================================================= \/
// ============================================================================================ CONSTRUCTORS \/
// ========================================================================================================= \/
public:
//! the filename will also be the name of the resource
ShaderProgramControlFiles(const std::string& _fileName)
: Resource::FileController<ShaderProgram>(_fileName),
mShaderType(),
mAttributeLocations(),
mFragmentDataLocations()
{
// only add the first name if it is a valid file name
if ( _fileName.find( "." ) != std::string::npos )
andFile( _fileName );
}
virtual ~ShaderProgramControlFiles(void) {}
// ==================================================================================================== \/
// ============================================================================================ METHODS \/
// ==================================================================================================== \/
public:
inline ShaderProgramControlFiles& andFile (const std::string &_fileName) { mFileName.push_back( _fileName ); mShaderType.push_back( GL_INVALID_VALUE ); return *this; }
inline ShaderProgramControlFiles& attributeLocation (const std::string &_attributeName) { mAttributeLocations.push_back(_attributeName); return *this; }
inline ShaderProgramControlFiles& fragmentDataLocation (const std::string &_fragmentDataName) { mFragmentDataLocations.push_back(_fragmentDataName); return *this; }
// ===================================================================================================== \/
// ============================================================================================ OVERRIDE \/
// ===================================================================================================== \/
public:
virtual SharedShaderProgram create(void);
virtual bool update(SharedShaderProgram &_shaderProgram);
// =================================================================================================== \/
// ============================================================================================ FIELDS \/
// =================================================================================================== \/
protected:
std::vector<GLenum> mShaderType;
std::vector<std::string> mFileName;
std::vector<std::string> mAttributeLocations;
std::vector<std::string> mFragmentDataLocations;
private:
// set attribute & fragdata locations prior to shader program linking
void setBindings(SharedShaderProgram &_shaderProgram);
};
} // OpenGL
} // ACGL
#endif // ACGL_OPENGL_CONTROLLER_SHADERPROGRAMCONTROLFILES_HH
......@@ -41,7 +41,7 @@ namespace FileHelpers
// if the file was not readable we will return a NULL pointer
return content;
}
*/
bool stringEndsWith( const std::string &theString, const std::string &theEnding )
......@@ -58,6 +58,7 @@ namespace FileHelpers
return false;
}
/*
bool stringBeginsWith( const std::string &theString, const std::string &thePrefix )
{
int32_t stringLenght = theString.size();
......
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
#include <ACGL/OpenGL/Controller/ShaderProgramControlFiles.hh>
#include <ACGL/OpenGL/Controller/ShaderControlFile.hh>
#include <ACGL/Resource/FileManager.hh>
#include <ACGL/OpenGL/Managers.hh>
#include <ACGL/Base/Settings.hh>
#include <ACGL/Base/FileHelpers.hh>
using namespace ACGL::Base;
using namespace ACGL::OpenGL;
SharedShaderProgram ShaderProgramControlFiles::create(void)
{
SharedShaderProgram shaderProgram(new ShaderProgram());
std::vector<std::string>::size_type numberOfFiles = mFileName.size();
for (std::vector<std::string>::size_type i = 0; i < numberOfFiles; ++i) {
//mShaderType.push_back( GL_INVALID_VALUE );
// guess shader type based on the file extension:
if ( FileHelpers::stringEndsWith(mFileName[i], ".vsh") ) {
mShaderType[i] = GL_VERTEX_SHADER;
#ifndef ACGL_OPENGL_ES
// this shader types are not defined for ES
} else if ( FileHelpers::stringEndsWith(mFileName[i], ".tcsh") ) {
mShaderType[i] = GL_TESS_CONTROL_SHADER;
} else if ( FileHelpers::stringEndsWith(mFileName[i], ".tesh") ) {
mShaderType[i] = GL_TESS_EVALUATION_SHADER;
} else if ( FileHelpers::stringEndsWith(mFileName[i], ".gsh") ) {
mShaderType[i] = GL_GEOMETRY_SHADER;
#endif // OpenGL ES
} else if ( FileHelpers::stringEndsWith(mFileName[i], ".fsh") ) {
mShaderType[i] = GL_FRAGMENT_SHADER;
}
}
for (std::vector<std::string>::size_type i = 0; i < numberOfFiles; ++i) {
# ifdef ACGL_CHECK_CRITICAL_GL_ERRORS
// check for problems:
if ( mShaderType[i] == GL_INVALID_VALUE ) {
Utils::error() << "file extension of file " << mFileName[i] << " not recognized - ignored" << std::endl;
}
if (! FileHelpers::fileExists( Settings::the()->getFullShaderPath() + mFileName[i] ) ) {
Utils::warning() << "file " << mFileName[i] << " does not exist - ignored" << std::endl;
mShaderType[i] = GL_INVALID_VALUE;
}
if ( (mShaderType[i] == GL_GEOMETRY_SHADER) && !OpenGL::doesSupportGeometryShader() ) {
Utils::error() << "file " << mFileName[i] << " ignored, hardware does not support geometry shader" << std::endl;
mShaderType[i] = GL_INVALID_VALUE;
}
if ( ((mShaderType[i] == GL_TESS_CONTROL_SHADER) || (mShaderType[i] == GL_TESS_EVALUATION_SHADER))
&& !OpenGL::doesSupportTessellationShader() ) {
Utils::error() << "file " << mFileName[i] << " ignored, hardware does not support tessellation shader" << std::endl;
mShaderType[i] = GL_INVALID_VALUE;
}
# endif // critical checks
// attach shader
if ( mShaderType[i] != GL_INVALID_VALUE ) {
ConstSharedShader shader = ShaderFileManager::the()->get(ShaderControlFile( mFileName[i] ).type( mShaderType[i] ));
if ( shader ) {
shaderProgram->attachShader( shader );
} else {
# ifdef ACGL_CHECK_CRITICAL_GL_ERRORS
Utils::error() << "could not attach shader " << mFileName[i] << std::endl;
# endif // critical checks
}
}
}
setBindings( shaderProgram );
if(shaderProgram->link())
return shaderProgram;
return SharedShaderProgram();
}
void ShaderProgramControlFiles::setBindings(SharedShaderProgram &_shaderProgram)
{
#if (ACGL_OPENGL_VERSION >= 30)
for (std::vector<std::string>::size_type i = 0; i < mAttributeLocations.size(); ++i) {
_shaderProgram->bindAttributeLocation(mAttributeLocations[i], i);
}
for (std::vector<std::string>::size_type i = 0; i < mFragmentDataLocations.size(); ++i) {
_shaderProgram->bindFragmentDataLocation(mFragmentDataLocations[i], i);
}
#else
if ( (mAttributeLocations.size() > 0) && (mFragmentDataLocations.size() > 0) ) {
Utils::error() << "can't set explicit attribute/fragdata locations on OpenGL < 3.0 " << std::endl;
}
#endif
}
bool ShaderProgramControlFiles::update(SharedShaderProgram &_shaderProgram)
{
bool update = false;
for (std::vector<std::string>::size_type i = 0; i < mFileName.size(); ++i) {
if ( mShaderType[i] != GL_INVALID_VALUE ) {
update |= ShaderFileManager::the()->update( mFileName[i] );
}
}
setBindings( _shaderProgram );
if (update)
return _shaderProgram->link();
return false;
}
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