Commit c5a33101 authored by Robert Menzel's avatar Robert Menzel
Browse files

refactored shader type detection, added compute shader detection

parent 8efc265e
...@@ -41,6 +41,12 @@ namespace FileHelpers ...@@ -41,6 +41,12 @@ namespace FileHelpers
*/ */
bool stringEndsWith( const std::string &theString, const std::string &theEnding ); bool stringEndsWith( const std::string &theString, const std::string &theEnding );
/*
* Returns the lowercase fileending if the filename has a '.' in it, otherwise
* an empty string.
*/
std::string getFileEnding( const std::string &_fileName );
/* /*
* Checks if a string begins with a certain prefix. * Checks if a string begins with a certain prefix.
*/ */
......
...@@ -31,14 +31,6 @@ namespace OpenGL{ ...@@ -31,14 +31,6 @@ namespace OpenGL{
class ShaderProgramControlFiles : public Resource::MultiFileController<ShaderProgram> class ShaderProgramControlFiles : public Resource::MultiFileController<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 \/ // ============================================================================================ CONSTRUCTORS \/
// ========================================================================================================= \/ // ========================================================================================================= \/
......
...@@ -46,8 +46,40 @@ uint32_t getOpenGLMajorVersionNumber(); ...@@ -46,8 +46,40 @@ uint32_t getOpenGLMajorVersionNumber();
// returns the combined version number as 10*major + minor for easy comparing // returns the combined version number as 10*major + minor for easy comparing
uint32_t getOpenGLVersionNumber(); uint32_t getOpenGLVersionNumber();
// query support for specific shader stages:
bool doesSupportGeometryShader(); bool doesSupportGeometryShader();
bool doesSupportTessellationShader(); bool doesSupportTessellationShader();
bool doesSupportComputeShader();
struct ShaderEndings
{
const char *ending;
GLenum type;
};
const ShaderEndings sShaderEndings[ ] = {
{"vsh", GL_VERTEX_SHADER},
{"vert", GL_VERTEX_SHADER},
{"tcsh", GL_TESS_CONTROL_SHADER},
{"tcs", GL_TESS_CONTROL_SHADER},
{"tesh", GL_TESS_EVALUATION_SHADER},
{"tes", GL_TESS_EVALUATION_SHADER},
{"gsh", GL_GEOMETRY_SHADER},
{"geo", GL_GEOMETRY_SHADER},
{"fsh", GL_FRAGMENT_SHADER},
{"frag", GL_FRAGMENT_SHADER},
{"csh", GL_COMPUTE_SHADER},
{"cs", GL_COMPUTE_SHADER}
};
// returns the GL_TESS_CONTROL_SHADER GL_TESS_EVALUATION_SHADER GL_GEOMETRY_SHADER GL_COMPUTE_SHADER
// GL_VERTEX_SHADER GL_FRAGMENT_SHADER or GL_INVALID_VALUE in case the shadertype was not detected
// if _ignoreUnsupportedShaderTypes is true, types unsupported by the current runtime will return
// an GL_INVALID_ENUM also.
GLenum getShaderTypeByFileEnding( const std::string _fileName, bool _ignoreUnsupportedShaderTypes = true );
// looks up the enum and gives a human readable version
const GLubyte* acglShaderTypeString( GLenum _shaderType );
// for every OpenGL error enum this will return a human readable version of it // for every OpenGL error enum this will return a human readable version of it
// similar to gluErrorString, but that function is not available on all plattforms // similar to gluErrorString, but that function is not available on all plattforms
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include <cstdio> // fopen etc. #include <cstdio> // fopen etc.
#include <string> #include <string>
#include <algorithm> // transform
#include <cctype> // tolower
#include <vector> #include <vector>
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
...@@ -59,6 +61,18 @@ namespace FileHelpers ...@@ -59,6 +61,18 @@ namespace FileHelpers
return false; return false;
} }
std::string getFileEnding( const std::string &_fileName )
{
size_t lastDot = _fileName.rfind('.');
if (lastDot == std::string::npos) {
return "";
}
std::string ending = _fileName.substr( lastDot+1, _fileName.size() );
std::transform(ending.begin(), ending.end(), ending.begin(), ::tolower);
return ending;
}
/* /*
bool stringBeginsWith( const std::string &theString, const std::string &thePrefix ) bool stringBeginsWith( const std::string &theString, const std::string &thePrefix )
{ {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <ACGL/OpenGL/Controller/ShaderControlFile.hh> #include <ACGL/OpenGL/Controller/ShaderControlFile.hh>
#include <ACGL/Base/StringOperations.hh> #include <ACGL/Base/StringOperations.hh>
#include <ACGL/OpenGL/Tools.hh>
using namespace ACGL::Base; using namespace ACGL::Base;
using namespace ACGL::OpenGL; using namespace ACGL::OpenGL;
...@@ -14,37 +15,14 @@ SharedShader ShaderControlFile::create(void) ...@@ -14,37 +15,14 @@ SharedShader ShaderControlFile::create(void)
{ {
updateFileModificationTime(); updateFileModificationTime();
if(mType == GL_INVALID_ENUM) if (mType == GL_INVALID_ENUM)
{ {
std::string filename; mType = ACGL::OpenGL::getShaderTypeByFileEnding( mFilename );
std::string extension; if (mType == GL_INVALID_ENUM) return SharedShader();
if(!StringOperations::splitFileExtension(mFilename, filename, extension))
return SharedShader();
if(extension == "vsh")
mType = GL_VERTEX_SHADER;
else if(extension == "fsh")
mType = GL_FRAGMENT_SHADER;
#if (ACGL_OPENGL_VERSION >= 43)
else if(extension == "csh")
mType = GL_COMPUTE_SHADER;
#endif
#if (ACGL_OPENGL_VERSION >= 40)
else if(extension == "tcsh")
mType = GL_TESS_CONTROL_SHADER;
else if(extension == "tesh")
mType = GL_TESS_EVALUATION_SHADER;
#endif
#if (ACGL_OPENGL_VERSION >= 32)
else if(extension == "gsh")
mType = GL_GEOMETRY_SHADER;
#endif
else
return SharedShader();
} }
SharedShader shader(new Shader(mType)); SharedShader shader(new Shader(mType));
if(shader->setFromFile(mFullFilePath)) if (shader->setFromFile(mFullFilePath))
return shader; return shader;
return SharedShader(); return SharedShader();
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <ACGL/OpenGL/Controller/ShaderProgramControlFiles.hh> #include <ACGL/OpenGL/Controller/ShaderProgramControlFiles.hh>
#include <ACGL/OpenGL/Controller/ShaderControlFile.hh> #include <ACGL/OpenGL/Controller/ShaderControlFile.hh>
#include <ACGL/OpenGL/Tools.hh>
#include <ACGL/Resource/FileManager.hh> #include <ACGL/Resource/FileManager.hh>
#include <ACGL/OpenGL/Managers.hh> #include <ACGL/OpenGL/Managers.hh>
#include <ACGL/Base/Settings.hh> #include <ACGL/Base/Settings.hh>
...@@ -17,37 +18,11 @@ ...@@ -17,37 +18,11 @@
using namespace ACGL::Base; using namespace ACGL::Base;
using namespace ACGL::OpenGL; using namespace ACGL::OpenGL;
#ifndef ACGL_OPENGL_ES
#if (ACGL_OPENGL_VERSION >= 43)
const unsigned int ShaderProgramControlFiles::sShaderEndingsSize = 9;
#else
const unsigned int ShaderProgramControlFiles::sShaderEndingsSize = 8;
#endif
#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},
#if (ACGL_OPENGL_VERSION >= 43)
{"csh", GL_COMPUTE_SHADER},
#endif
#endif
{"vsh", GL_VERTEX_SHADER},
{"vert", GL_VERTEX_SHADER},
{"fsh", GL_FRAGMENT_SHADER},
{"frag", GL_FRAGMENT_SHADER}
};
ShaderProgramControlFiles& ShaderProgramControlFiles::autoFiles(const std::string &_fileName) ShaderProgramControlFiles& ShaderProgramControlFiles::autoFiles(const std::string &_fileName)
{ {
//Utils::debug() << "autoFiles: " << _fileName << std::endl; //Utils::debug() << "autoFiles: " << _fileName << std::endl;
std::string baseFileName = _fileName + "."; std::string baseFileName = _fileName + ".";
for (unsigned int ending = 0; ending < sShaderEndingsSize; ++ending) for (unsigned int ending = 0; ending < sizeof(sShaderEndings) / sizeof(ShaderEndings); ++ending)
{ {
std::string fileName = baseFileName + sShaderEndings[ending].ending; std::string fileName = baseFileName + sShaderEndings[ending].ending;
if ( FileHelpers::fileExists( mBasePath + fileName ) ) if ( FileHelpers::fileExists( mBasePath + fileName ) )
...@@ -71,14 +46,7 @@ SharedShaderProgram ShaderProgramControlFiles::create(void) ...@@ -71,14 +46,7 @@ SharedShaderProgram ShaderProgramControlFiles::create(void)
if ( mShaderType[file] == GL_INVALID_VALUE ) { if ( mShaderType[file] == GL_INVALID_VALUE ) {
// guess the shader type: // guess the shader type:
for (unsigned int ending = 0; ending < sShaderEndingsSize; ++ending) mShaderType[file] = ACGL::OpenGL::getShaderTypeByFileEnding( mFileNames[file] );
{
if ( FileHelpers::stringEndsWith( mFileNames[file], sShaderEndings[ending].ending ) )
{
mShaderType[file] = sShaderEndings[ending].type;
continue;
}
}
} }
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <ACGL/ACGL.hh> #include <ACGL/ACGL.hh>
#include <ACGL/OpenGL/Tools.hh> #include <ACGL/OpenGL/Tools.hh>
#include <ACGL/Base/FileHelpers.hh>
namespace ACGL{ namespace ACGL{
namespace OpenGL{ namespace OpenGL{
...@@ -14,7 +15,7 @@ namespace OpenGL{ ...@@ -14,7 +15,7 @@ namespace OpenGL{
// This is a "private" function that should not be called from outside of this file. // This is a "private" function that should not be called from outside of this file.
// //
// glGetIntegerv(GL_MAJOR_VERSION... and glGetIntegerv(GL_MINOR_VERSION... are great, but // glGetIntegerv(GL_MAJOR_VERSION... and glGetIntegerv(GL_MINOR_VERSION... are great, but
// require OpenGL 3.0 and are not supported on ES :-( so the VERSION string has to get parsed... // require OpenGL 3.0 and are not supported on ES 2 :-( so the VERSION string has to get parsed...
// //
// OpenGL spec: // OpenGL spec:
// The VERSION ... strings are laid out as follows: // The VERSION ... strings are laid out as follows:
...@@ -104,6 +105,60 @@ bool doesSupportTessellationShader() ...@@ -104,6 +105,60 @@ bool doesSupportTessellationShader()
#endif #endif
} }
bool doesSupportComputeShader()
{
#ifdef ACGL_OPENGL_ES
return false;
#else
# if defined(ACGL_USE_GLEW)
return ( GLEW_ARB_compute_shader || (getOpenGLVersionNumber() >= 43));
# else
return (getOpenGLVersionNumber() >= 43);
# endif
#endif
}
GLenum getShaderTypeByFileEnding( const std::string _fileName, bool _ignoreUnsupportedShaderTypes )
{
std::string fileEnding = ACGL::Base::FileHelpers::getFileEnding( _fileName );
if( fileEnding.size() == 0 ) return GL_INVALID_ENUM;
GLenum foundType = GL_INVALID_ENUM;
// guess the shader type:
for (unsigned int ending = 0; ending < sizeof(sShaderEndings) / sizeof(ShaderEndings); ++ending)
{
if ( fileEnding == sShaderEndings[ending].ending )
{
foundType = sShaderEndings[ending].type;
break;
}
}
if (_ignoreUnsupportedShaderTypes) {
if (foundType == GL_GEOMETRY_SHADER && !doesSupportGeometryShader() ) return GL_INVALID_ENUM;
if (foundType == GL_TESS_CONTROL_SHADER && !doesSupportTessellationShader()) return GL_INVALID_ENUM;
if (foundType == GL_TESS_EVALUATION_SHADER && !doesSupportTessellationShader()) return GL_INVALID_ENUM;
if (foundType == GL_COMPUTE_SHADER && !doesSupportComputeShader() ) return GL_INVALID_ENUM;
}
return foundType;
}
const GLubyte* acglShaderTypeString( GLenum _shaderType )
{
if (_shaderType == GL_VERTEX_SHADER) { return (GLubyte*) "vertex shader"; }
else if (_shaderType == GL_TESS_CONTROL_SHADER) { return (GLubyte*) "tessellation control shader"; }
else if (_shaderType == GL_TESS_EVALUATION_SHADER) { return (GLubyte*) "tessellation evaluation shader"; }
else if (_shaderType == GL_GEOMETRY_SHADER) { return (GLubyte*) "geometry shader"; }
else if (_shaderType == GL_FRAGMENT_SHADER) { return (GLubyte*) "fragment shader"; }
else if (_shaderType == GL_COMPUTE_SHADER) { return (GLubyte*) "compute shader"; }
else {
return (GLubyte*) "unknown shader type";
}
}
const GLubyte* acglErrorString( GLenum _errorCode ) const GLubyte* acglErrorString( GLenum _errorCode )
{ {
// no gluErrorString on iOS, problems on visual studio... // no gluErrorString on iOS, problems on visual studio...
......
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