Commit d97edad4 authored by Robert Menzel's avatar Robert Menzel

added reloading of imported sub-shaders (could be faster)

parent 7def3797
......@@ -47,6 +47,13 @@ public:
// =================================================================================================== \/
protected:
GLenum mType;
struct ImportedShader {
std::string fileName;
Base::FileHelpers::FileModificationTime modificatonTime;
};
std::vector< ImportedShader > mImportedShaders; // in case the shader imports additional shaders files
};
} // OpenGL
......
......@@ -28,6 +28,30 @@
namespace ACGL{
namespace OpenGL{
class ShaderParser
{
public:
ShaderParser( const std::string &_filename );
std::vector< std::string > getSources() const { return mSources; }
std::string getFileNamesPrintable() const;
//! the imported sources don't count the original file!
unsigned int getNumberOfImportedFiles() const { return mSourceFileNames.size()-1; }
//! 0 == original file
std::string getFileName( unsigned int i ) const { return mSourceFileNames[i]; }
private:
void readin( const std::string &_filename );
bool lineContainsVersion( const std::string &line, unsigned int &version);
bool lineContainsImport( const std::string &line, std::string &filename);
std::vector< std::string > mSources;
std::vector< std::string > mSourceFileNames; // holds at least one filename
unsigned int mMaxVersion;
};
class Shader
{
ACGL_NOT_COPYABLE(Shader)
......@@ -65,6 +89,7 @@ public:
// ==================================================================================================== \/
public:
bool setFromFile (const std::string &_filename);
bool setFromFile (const ShaderParser &_sp);
bool setSource (const std::string &_source, bool _checkForCompileErrors = true);
bool setSources (const std::vector<std::string> &_sources, bool _checkForCompileErrors = true );
......@@ -85,25 +110,6 @@ protected:
GLenum mType;
};
class ShaderParser
{
public:
ShaderParser( const std::string &_filename );
std::vector< std::string > getSources() { return mSources; }
std::string getFileNamesPrintable();
private:
void readin( const std::string &_filename );
bool lineContainsVersion( const std::string &line, unsigned int &version);
bool lineContainsImport( const std::string &line, std::string &filename);
std::vector< std::string > mSources;
std::vector< std::string > mSourceFileNames;
unsigned int mMaxVersion;
};
ACGL_SMARTPOINTER_TYPEDEFS(Shader)
......
......@@ -22,24 +22,56 @@ SharedShader ShaderControlFile::create(void)
}
SharedShader shader(new Shader(mType));
if (shader->setFromFile(mFullFilePath))
ShaderParser sp( mFullFilePath );
if (shader->setFromFile( sp )) {
unsigned int importedSourcesCount = sp.getNumberOfImportedFiles();
mImportedShaders.reserve( importedSourcesCount );
for (unsigned int i = 1; i <= importedSourcesCount; ++i) {
ImportedShader is;
is.fileName = sp.getFileName( i );
is.modificatonTime = FileHelpers::getFileModificationTime( is.fileName );
mImportedShaders.push_back( is );
}
return shader;
}
return SharedShader();
}
bool ShaderControlFile::update(SharedShader& shader)
{
if(fileIsUpToDate())
return false;
bool shaderIsUpToDate = fileIsUpToDate();
for (unsigned int i = 0; i < mImportedShaders.size(); ++i) {
if ( Base::FileHelpers::getFileModificationTime(mImportedShaders[i].fileName) != mImportedShaders[i].modificatonTime ) {
// imported shader changed
shaderIsUpToDate = false;
break; // one changed imported shader is enough to justify a full shader reload
}
}
if (shaderIsUpToDate) {
return false; // false means nothing was updated
}
{ // try to compile the source in another shader, only proceed if that worked!
Shader dummy( shader->getType() );
if (!dummy.setFromFile(mFullFilePath)) {
ShaderParser sp( mFullFilePath );
if (!dummy.setFromFile( sp )) {
// we had a shader compile error, update the timestamp to prevent a second try
// of compiling the exact same (non-working) shader again
updateFileModificationTime();
return false;
} else {
// the newly loaded base shader might import other subshaders!
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.modificatonTime = FileHelpers::getFileModificationTime( is.fileName );
mImportedShaders.push_back( is );
}
}
}
......
......@@ -54,26 +54,29 @@ bool Shader::setFromFileNoImportParsing(const std::string& _filename)
return !compileErrors; // return true iff there were no errors
}
bool Shader::setFromFile(const std::string& _filename)
bool Shader::setFromFile(const ShaderParser &_sp)
{
ShaderParser sp( _filename );
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();
......@@ -228,7 +231,7 @@ bool ShaderParser::lineContainsImport( const std::string &line, std::string &fil
return false;
}
std::string ShaderParser::getFileNamesPrintable()
std::string ShaderParser::getFileNamesPrintable() const
{
std::string rString;
for (size_t i = 0; i < mSourceFileNames.size(); ++i) {
......
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