Commit 3db02023 authored by Philip Trettner's avatar Philip Trettner
Browse files

introduced shader factory concept to ShaderCreator and ShaderProgramCreator

parent 93285159
......@@ -21,6 +21,8 @@
#include <ACGL/OpenGL/Objects/Shader.hh>
#include <ACGL/OpenGL/GL.hh>
#include <ACGL/OpenGL/Creator/ShaderParserFactory.hh>
namespace ACGL{
namespace OpenGL{
......@@ -32,7 +34,8 @@ class ShaderCreator : public Resource::SingleFileBasedCreator<Shader>
public:
ShaderCreator(const std::string& _filename)
: Resource::SingleFileBasedCreator<Shader>(_filename, Base::Settings::the()->getFullShaderPath()),
mType(GL_INVALID_ENUM)
mType(GL_INVALID_ENUM),
mShaderParserFactory(std::make_shared<ShaderParserFactory>())
{}
virtual ~ShaderCreator() {}
......@@ -44,6 +47,13 @@ public:
ShaderCreator& setResourceName(const std::string &_resourceName) { mResourceName = _resourceName; return *this; }
//
// Override shader processing
//
/// Sets the shader parser factory
inline ShaderCreator& shaderParserFacoty(SharedShaderParserFactory const& _factory) { mShaderParserFactory = _factory; return *this; }
// ===================================================================================================== \/
// ============================================================================================ OVERRIDE \/
// ===================================================================================================== \/
......@@ -57,6 +67,8 @@ public:
protected:
GLenum mType;
SharedShaderParserFactory mShaderParserFactory;
struct ImportedShader {
std::string fileName;
Utils::FileHelpers::FileModificationTime modificatonTime;
......
/***********************************************************************
* Copyright 2011-2013 Computer Graphics Group RWTH Aachen University. *
* All rights reserved. *
* Distributed under the terms of the MIT License (see LICENSE.TXT). *
**********************************************************************/
#pragma once
#include <ACGL/ACGL.hh>
#include <ACGL/Resource/MultiFileBasedCreator.hh>
#include <ACGL/Resource/SingleFileBasedCreator.hh>
#include <ACGL/OpenGL/Objects/ShaderProgram.hh>
#include <ACGL/OpenGL/GL.hh>
#include <ACGL/Base/Settings.hh>
#include <vector>
#include <ACGL/OpenGL/Data/LocationMappings.hh>
namespace ACGL{
namespace OpenGL{
/**
* @brief Factory for shader parser
*
* This can be used in in the shader program creator to create post-processes for shader
*/
class ShaderParserFactory
{
ACGL_NOT_COPYABLE(ShaderParserFactory)
public:
ShaderParserFactory() { }
virtual ~ShaderParserFactory() { }
/**
* @brief creates a Parser for a given source file
* @param _filename filename of the shader that is going to be compiled
* @return a new ShaderParser instance
*
* Returns the a default shader parse that is able to include other shader
* Override this function to create your own functionality
*/
virtual SharedShaderParser createParser(std::string const& _filename);
};
ACGL_SMARTPOINTER_TYPEDEFS(ShaderParserFactory)
} // OpenGL
} // ACGL
......@@ -25,6 +25,8 @@
#include <vector>
#include <ACGL/OpenGL/Data/LocationMappings.hh>
#include <ACGL/OpenGL/Creator/ShaderParserFactory.hh>
namespace ACGL{
namespace OpenGL{
......@@ -42,7 +44,8 @@ public:
mShaderType(),
mAttributeLocations(new LocationMappings),
mFragmentDataLocations(new LocationMappings),
mUniformBufferLocations(new LocationMappings)
mUniformBufferLocations(new LocationMappings),
mShaderParserFactory(std::make_shared<ShaderParserFactory>())
{
// the base path is only needed for updating the time stamps, as the shaders itself get loaded via ShaderCreators
// which itself will add the base path! (read: mFileNames will _NOT_ store the base path!)
......@@ -68,6 +71,13 @@ public:
public:
ShaderProgramCreator& setResourceName(const std::string &_resourceName) { mResourceName = _resourceName; return *this; }
//
// Override shader processing
//
/// Sets the shader parser factory
inline ShaderProgramCreator& shaderParserFacoty(SharedShaderParserFactory const& _factory) { mShaderParserFactory = _factory; return *this; }
//
// Adding files:
//
......@@ -144,6 +154,8 @@ protected:
SharedLocationMappings mFragmentDataLocations;
SharedLocationMappings mUniformBufferLocations;
SharedShaderParserFactory mShaderParserFactory;
private:
// set attribute, UBO & fragdata locations and links the program
bool setBindings(SharedShaderProgram &_shaderProgram);
......
......@@ -30,8 +30,11 @@ namespace OpenGL{
class ShaderParser
{
ACGL_NOT_COPYABLE(ShaderParser)
public:
ShaderParser( const std::string &_filename );
virtual ~ShaderParser() { }
std::vector< std::string > getSources() const { return mSources; }
std::string getFileNamesPrintable() const;
......@@ -51,6 +54,7 @@ private:
std::vector< std::string > mSourceFileNames; // holds at least one filename
unsigned int mMaxVersion;
};
ACGL_SMARTPOINTER_TYPEDEFS(ShaderParser)
class Shader
{
......@@ -88,8 +92,7 @@ public:
// ============================================================================================ METHODS \/
// ==================================================================================================== \/
public:
bool setFromFile (const std::string &_filename);
bool setFromFile (const ShaderParser &_sp);
bool setFromFile (SharedShaderParser const& _sp);
bool setSource (const std::string &_source, bool _checkForCompileErrors = true);
bool setSources (const std::vector<std::string> &_sources, bool _checkForCompileErrors = true );
......
......@@ -22,13 +22,13 @@ SharedShader ShaderCreator::create()
}
SharedShader shader(new Shader(mType));
ShaderParser sp( mFullFilePath );
SharedShaderParser sp( mShaderParserFactory->createParser( mFullFilePath ) );
if (shader->setFromFile( sp )) {
unsigned int importedSourcesCount = sp.getNumberOfImportedFiles();
unsigned int importedSourcesCount = sp->getNumberOfImportedFiles();
mImportedShaders.reserve( importedSourcesCount );
for (unsigned int i = 1; i <= importedSourcesCount; ++i) {
ImportedShader is;
is.fileName = sp.getFileName( i );
is.fileName = sp->getFileName( i );
is.modificatonTime = FileHelpers::getFileModificationTime( is.fileName );
mImportedShaders.push_back( is );
}
......@@ -54,7 +54,7 @@ bool ShaderCreator::update(SharedShader& shader)
{ // try to compile the source in another shader, only proceed if that worked!
Shader dummy( shader->getType() );
ShaderParser sp( mFullFilePath );
SharedShaderParser sp( mShaderParserFactory->createParser( mFullFilePath ) );
if (!dummy.setFromFile( sp )) {
// we had a shader compile error, update the timestamp to prevent a second try
......@@ -63,12 +63,12 @@ bool ShaderCreator::update(SharedShader& shader)
return false;
} else {
// the newly loaded base shader might import other subshaders!
unsigned int importedSourcesCount = sp.getNumberOfImportedFiles();
unsigned int importedSourcesCount = sp->getNumberOfImportedFiles();
mImportedShaders.clear();
mImportedShaders.reserve( importedSourcesCount );
for (unsigned int i = 1; i <= importedSourcesCount; ++i) {
ImportedShader is;
is.fileName = sp.getFileName( i );
is.fileName = sp->getFileName( i );
is.modificatonTime = FileHelpers::getFileModificationTime( is.fileName );
mImportedShaders.push_back( is );
}
......@@ -76,7 +76,10 @@ bool ShaderCreator::update(SharedShader& shader)
}
// it worked, so load the source in "our" shader:
shader->setFromFile(mFullFilePath);
{
SharedShaderParser sp( mShaderParserFactory->createParser( mFullFilePath ) );
shader->setFromFile(sp);
}
updateFileModificationTime();
return true;
......
/***********************************************************************
* Copyright 2011-2012 Computer Graphics Group RWTH Aachen University. *
* All rights reserved. *
* Distributed under the terms of the MIT License (see LICENSE.TXT). *
**********************************************************************/
#include <ACGL/OpenGL/Creator/ShaderParserFactory.hh>
#include <sstream>
#include <algorithm>
using namespace ACGL::Utils;
using namespace ACGL::Base;
using namespace ACGL::OpenGL;
SharedShaderParser ShaderParserFactory::createParser(const std::string &_filename)
{
return std::make_shared<ShaderParser>(_filename);
}
......@@ -83,7 +83,7 @@ SharedShaderProgram ShaderProgramCreator::create()
// attach shader
if ( mShaderType[i] != GL_INVALID_VALUE ) {
ConstSharedShader shader = ShaderFileManager::the()->get(ShaderCreator( mFileNames[i] ).type( mShaderType[i] ));
ConstSharedShader shader = ShaderFileManager::the()->get(ShaderCreator( mFileNames[i] ).type( mShaderType[i] ).shaderParserFacoty(mShaderParserFactory) );
if ( shader ) {
shaderProgram->attachShader( shader );
} else {
......
......@@ -53,29 +53,23 @@ bool Shader::setFromFileNoImportParsing(const std::string& _filename)
return !compileErrors; // return true iff there were no errors
}
bool Shader::setFromFile(const ShaderParser &_sp)
bool Shader::setFromFile(SharedShaderParser const& _sp)
{
bool compileErrors = true;
if ( setSources( _sp.getSources(), false) ) { // don't check for errors, we will do that on our own:
if ( setSources( _sp->getSources(), false) ) { // don't check for errors, we will do that on our own:
std::string compileLog;
getCompileLog( compileLog, compileErrors );
if (compileLog.size() > 0) {
if (compileErrors) {
error() << "\nIn files: \n" << _sp.getFileNamesPrintable() << compileLog << "\n" << std::endl;
error() << "\nIn files: \n" << _sp->getFileNamesPrintable() << compileLog << "\n" << std::endl;
} else {
warning() << "\nIn files: \n" << _sp.getFileNamesPrintable() << compileLog << "\n" << std::endl;
warning() << "\nIn files: \n" << _sp->getFileNamesPrintable() << compileLog << "\n" << std::endl;
}
}
}
return !compileErrors; // return true iff there were no errors
}
bool Shader::setFromFile(const std::string& _filename)
{
ShaderParser sp( _filename );
return setFromFile( sp );
}
bool Shader::setSource(const std::string& _source, bool _checkForCompileErrors)
{
const char *pProgramString = _source.c_str();
......
Supports Markdown
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