Commit c3a088af authored by Robert Menzel's avatar Robert Menzel

ShaderProgramControlFiles is now a superset of the auto files controler with more features

parent 5c209f7d
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
#ifndef ACGL_OPENGL_CONTROLLER_SHADERPROGRAMCONTROLAUTOFILES_HH
#define ACGL_OPENGL_CONTROLLER_SHADERPROGRAMCONTROLAUTOFILES_HH
#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 ShaderProgramControlAutoFiles : public Resource::FileController<ShaderProgram>
{
// ========================================================================================================= \/
// ============================================================================================ CONSTRUCTORS \/
// ========================================================================================================= \/
public:
ShaderProgramControlAutoFiles(const std::string& _filename)
: Resource::FileController<ShaderProgram>(_filename),
mAttributeLocations(),
mFragmentDataLocations()
{}
virtual ~ShaderProgramControlAutoFiles(void) {}
// ==================================================================================================== \/
// ============================================================================================ METHODS \/
// ==================================================================================================== \/
public:
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 \/
// ===================================================================================================== \/
public:
virtual SharedShaderProgram create(void);
virtual bool update(SharedShaderProgram& shaderProgram);
// =================================================================================================== \/
// ============================================================================================ FIELDS \/
// =================================================================================================== \/
protected:
std::vector<std::string> mAttributeLocations;
std::vector<std::string> mFragmentDataLocations;
};
} // OpenGL
} // ACGL
#endif // ACGL_OPENGL_CONTROLLER_SHADERPROGRAMCONTROLAUTOFILES_HH
......@@ -27,28 +27,55 @@ namespace OpenGL{
class ShaderProgramControlFiles : public Resource::FileController<ShaderProgram>
{
struct ShaderEndings
{
const char *ending;
GLenum type;
};
static const unsigned int sShaderEndingsSize; // size of the array sShaderEndings
static const ShaderEndings sShaderEndings[]; // all supported endings (see .cc file)
// ========================================================================================================= \/
// ============================================================================================ CONSTRUCTORS \/
// ========================================================================================================= \/
public:
//! the filename will also be the name of the resource
ShaderProgramControlFiles(const std::string& _fileName)
//! If the filename has a dot in it (or _type is set), it will be treated as a single file, otherwise all
//! files starting with that string will be used.
ShaderProgramControlFiles(const std::string& _fileName, GLenum _type = GL_INVALID_VALUE )
: Resource::FileController<ShaderProgram>(_fileName),
mShaderType(),
mAttributeLocations(),
mFragmentDataLocations()
{
if ( _type != GL_INVALID_VALUE ) {
andFile( _fileName, _type );
return;
}
// only add the first name if it is a valid file name
if ( _fileName.find( "." ) != std::string::npos )
if ( _fileName.find( "." ) != std::string::npos ) {
andFile( _fileName );
} else {
autoFiles( _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; }
//! adds a single file, the shader type will be guessed by the ending:
inline ShaderProgramControlFiles& andFile (const std::string &_fileName) { mFileName.push_back( _fileName ); mShaderType.push_back( GL_INVALID_VALUE ); return *this; }
//! adds a single file, the shader type is explicitly given and must be one of:
//! GL_VERTEX_SHADER, GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER, GL_GEOMETRY_SHADER, GL_FRAGMENT_SHADER
inline ShaderProgramControlFiles& andFile (const std::string &_fileName, GLenum _type) { mFileName.push_back( _fileName ); mShaderType.push_back( _type ); return *this; }
//! adds all files begining with the given name, the shader type will be guessed by the ending:
ShaderProgramControlFiles& autoFiles (const std::string &_fileName);
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; }
......
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
#include <ACGL/OpenGL/Controller/ShaderProgramControlAutoFiles.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 ShaderProgramControlAutoFiles::create(void)
{
SharedShaderProgram shaderProgram(new ShaderProgram());
if(ConstSharedShader shader = ShaderFileManager::the()->get(ShaderControlFile(mFilename + ".vsh").type(GL_VERTEX_SHADER)))
shaderProgram->attachShader(shader);
#ifndef ACGL_OPENGL_ES
// this shader types are not defined for ES
bool tessellationControlShaderPresent = FileHelpers::fileExists(Base::Settings::the()->getFullShaderPath() + mFilename + ".tcsh");
bool tessellationEvaluationShaderPresent = FileHelpers::fileExists(Base::Settings::the()->getFullShaderPath() + mFilename + ".tesh");
if (OpenGL::doesSupportTessellationShader()) {
if(tessellationControlShaderPresent && tessellationEvaluationShaderPresent) {
// both tessellation stages are present -> load them
if(ConstSharedShader shader = ShaderFileManager::the()->get(ShaderControlFile(mFilename + ".tcsh").type(GL_TESS_CONTROL_SHADER)))
shaderProgram->attachShader(shader);
if(ConstSharedShader shader = ShaderFileManager::the()->get(ShaderControlFile(mFilename + ".tesh").type(GL_TESS_EVALUATION_SHADER)))
shaderProgram->attachShader(shader);
} else {
if (tessellationControlShaderPresent || tessellationEvaluationShaderPresent) {
// only ONE tessellation stage is present -> somethings wrong
ACGL::Utils::warning() << "only one of two tessellation shaders are present - ignored" << std::endl;
}
}
} else if (tessellationControlShaderPresent || tessellationEvaluationShaderPresent) {
ACGL::Utils::warning() << "tessellation shader present but hardware doesn't support those - ignored" << std::endl;
}
bool geometryShaderPresent = FileHelpers::fileExists(Base::Settings::the()->getFullShaderPath() + mFilename + ".gsh");
if (OpenGL::doesSupportGeometryShader()) {
if(geometryShaderPresent)
if(ConstSharedShader shader = ShaderFileManager::the()->get(ShaderControlFile(mFilename + ".gsh").type(GL_GEOMETRY_SHADER)))
shaderProgram->attachShader(shader);
} else if (geometryShaderPresent) {
ACGL::Utils::warning() << "geometry shader present but hardware doesn't support it - ignored" << std::endl;
}
#endif
if(ConstSharedShader shader = ShaderFileManager::the()->get(ShaderControlFile(mFilename + ".fsh").type(GL_FRAGMENT_SHADER)))
shaderProgram->attachShader(shader);
#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);
#endif
if(shaderProgram->link())
return shaderProgram;
return SharedShaderProgram();
}
bool ShaderProgramControlAutoFiles::update(SharedShaderProgram& shaderProgram)
{
bool update = false;
update |= ShaderFileManager::the()->update(mFilename + ".vsh");
update |= ShaderFileManager::the()->update(mFilename + ".fsh");
#ifndef ACGL_OPENGL_ES
if (OpenGL::doesSupportGeometryShader()) {
update |= ShaderFileManager::the()->update(mFilename + ".gsh");
}
if (OpenGL::doesSupportTessellationShader()) {
update |= ShaderFileManager::the()->update(mFilename + ".tcsh");
update |= ShaderFileManager::the()->update(mFilename + ".tesh");
}
#endif
if(update)
return shaderProgram->link();
return false;
}
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// Copyright (c) 2011, 2012 Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
......@@ -13,29 +13,61 @@
using namespace ACGL::Base;
using namespace ACGL::OpenGL;
#ifndef ACGL_OPENGL_ES
const unsigned int ShaderProgramControlFiles::sShaderEndingsSize = 8;
#else
const unsigned int ShaderProgramControlFiles::sShaderEndingsSize = 4;
#endif
const ShaderProgramControlFiles::ShaderEndings ShaderProgramControlFiles::sShaderEndings[ ShaderProgramControlFiles::sShaderEndingsSize ] = {
#ifndef ACGL_OPENGL_ES
{"tcsh", GL_TESS_CONTROL_SHADER},
{"tesh", GL_TESS_EVALUATION_SHADER},
{"gsh", GL_GEOMETRY_SHADER},
{"geo", GL_GEOMETRY_SHADER},
#endif
{"vsh", GL_VERTEX_SHADER},
{"vert", GL_VERTEX_SHADER},
{"fsh", GL_FRAGMENT_SHADER},
{"frag", GL_FRAGMENT_SHADER}
};
ShaderProgramControlFiles& ShaderProgramControlFiles::autoFiles(const std::string &_fileName)
{
Utils::debug() << "autoFiles: " << _fileName << std::endl;
std::string baseFileName = Base::Settings::the()->getFullShaderPath() + _fileName + ".";
for (unsigned int ending = 0; ending < sShaderEndingsSize; ++ending)
{
std::string fileName = baseFileName + sShaderEndings[ending].ending;
if ( FileHelpers::fileExists(fileName) )
{
mFileName.push_back( _fileName +"."+sShaderEndings[ending].ending ); // DON'T store a version with the full shader path
mShaderType.push_back( sShaderEndings[ending].type );
//Utils::debug() << "autoFiles: added " << fileName << " - type: " << sShaderEndings[ending].ending << std::endl;
}
}
return *this;
}
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;
// some of the files have correct types already, some not yet -> try to guess the rest
for (std::vector<std::string>::size_type file = 0; file < numberOfFiles; ++file) {
if ( mShaderType[file] == GL_INVALID_VALUE ) {
// guess the shader type:
for (unsigned int ending = 0; ending < sShaderEndingsSize; ++ending)
{
if ( FileHelpers::stringEndsWith( mFileName[file], sShaderEndings[ending].ending ) )
{
mShaderType[file] = sShaderEndings[ending].type;
continue;
}
}
}
}
......@@ -79,10 +111,10 @@ SharedShaderProgram ShaderProgramControlFiles::create(void)
setBindings( shaderProgram );
if(shaderProgram->link())
if (shaderProgram->link()) {
return shaderProgram;
return SharedShaderProgram();
}
return SharedShaderProgram(); // linking failed
}
void ShaderProgramControlFiles::setBindings(SharedShaderProgram &_shaderProgram)
......
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