Improved shader:getWarnings() to return shader compiler warnings as well as shader program linker and usage warnings

This commit is contained in:
Alex Szpakowski
2013-04-06 14:02:24 -03:00
parent 7e658861d7
commit cfe6014b68
2 changed files with 46 additions and 19 deletions
+40 -19
View File
@@ -97,17 +97,17 @@ Shader::~Shader()
GLuint Shader::compileCode(ShaderType type, const std::string &code) GLuint Shader::compileCode(ShaderType type, const std::string &code)
{ {
GLenum glshadertype; GLenum glshadertype;
const char *shadertypename = NULL; const char *shadertypestr = NULL;
switch (type) switch (type)
{ {
case TYPE_VERTEX: case TYPE_VERTEX:
glshadertype = GL_VERTEX_SHADER; glshadertype = GL_VERTEX_SHADER;
shadertypename = "vertex"; shadertypestr = "vertex";
break; break;
case TYPE_PIXEL: case TYPE_PIXEL:
glshadertype = GL_FRAGMENT_SHADER; glshadertype = GL_FRAGMENT_SHADER;
shadertypename = "pixel"; shadertypestr = "pixel";
break; break;
default: default:
throw love::Exception("Cannot create shader object: unknown shader type."); throw love::Exception("Cannot create shader object: unknown shader type.");
@@ -124,9 +124,9 @@ GLuint Shader::compileCode(ShaderType type, const std::string &code)
GLenum err = glGetError(); GLenum err = glGetError();
if (err == GL_INVALID_ENUM) // invalid or unsupported shader type if (err == GL_INVALID_ENUM) // invalid or unsupported shader type
throw love::Exception("Cannot create %s shader object: %s shaders not supported.", shadertypename, shadertypename); throw love::Exception("Cannot create %s shader object: %s shaders not supported.", shadertypestr, shadertypestr);
else // other errors should only happen between glBegin() and glEnd() else // other errors should only happen between glBegin() and glEnd()
throw love::Exception("Cannot create %s shader object.", shadertypename); throw love::Exception("Cannot create %s shader object.", shadertypestr);
} }
const char *src = code.c_str(); const char *src = code.c_str();
@@ -135,23 +135,26 @@ GLuint Shader::compileCode(ShaderType type, const std::string &code)
glCompileShader(shaderid); glCompileShader(shaderid);
// Get any warnings the shader compiler may have produced
GLint infologlen;
glGetShaderiv(shaderid, GL_INFO_LOG_LENGTH, &infologlen);
GLchar *infolog = new GLchar[infologlen + 1];
glGetShaderInfoLog(shaderid, infologlen, NULL, infolog);
// Save any warnings for later querying
if (infologlen > 0)
shaderWarnings[type] = shadertypestr + std::string(" shader:\n") + infolog;
delete[] infolog;
GLint status; GLint status;
glGetShaderiv(shaderid, GL_COMPILE_STATUS, &status); glGetShaderiv(shaderid, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) if (status == GL_FALSE)
{ {
GLint infologlen; throw love::Exception("Cannot compile %s shader code:\n%s",
glGetShaderiv(shaderid, GL_INFO_LOG_LENGTH, &infologlen); shadertypestr, shaderWarnings[type].c_str());
GLchar *errorlog = new GLchar[infologlen + 1];
glGetShaderInfoLog(shaderid, infologlen, NULL, errorlog);
std::string tmp(errorlog);
delete[] errorlog;
glDeleteShader(shaderid);
throw love::Exception("Cannot compile %s shader code:\n%s", shadertypename, tmp.c_str());
} }
return shaderid; return shaderid;
@@ -177,7 +180,7 @@ void Shader::createProgram(const std::vector<GLuint> &shaderids)
if (status == GL_FALSE) if (status == GL_FALSE)
{ {
std::string warnings = getWarnings(); std::string warnings = getProgramWarnings();
glDeleteProgram(program); glDeleteProgram(program);
throw love::Exception("Cannot link shader program object:\n%s", warnings.c_str()); throw love::Exception("Cannot link shader program object:\n%s", warnings.c_str());
@@ -236,12 +239,15 @@ void Shader::unloadVolatile()
// same with uniform location list // same with uniform location list
uniforms.clear(); uniforms.clear();
shaderWarnings.clear();
} }
std::string Shader::getWarnings() const std::string Shader::getProgramWarnings() const
{ {
GLint strlen, nullpos; GLint strlen, nullpos;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &strlen); glGetProgramiv(program, GL_INFO_LOG_LENGTH, &strlen);
char *tempstr = new char[strlen+1]; char *tempstr = new char[strlen+1];
// be extra sure that the error string will be 0-terminated // be extra sure that the error string will be 0-terminated
memset(tempstr, '\0', strlen+1); memset(tempstr, '\0', strlen+1);
@@ -250,6 +256,21 @@ std::string Shader::getWarnings() const
std::string warnings(tempstr); std::string warnings(tempstr);
delete[] tempstr; delete[] tempstr;
return warnings;
}
std::string Shader::getWarnings() const
{
std::string warnings;
// Get the individual shader stage warnings
std::map<ShaderType, std::string>::const_iterator it;
for (it = shaderWarnings.begin(); it != shaderWarnings.end(); ++it)
warnings += it->second;
warnings += getProgramWarnings();
return warnings; return warnings;
} }
+6
View File
@@ -133,9 +133,15 @@ private:
void sendTexture(const std::string &name, GLuint texture); void sendTexture(const std::string &name, GLuint texture);
// Get any warnings or errors generated only by the shader program object.
std::string getProgramWarnings() const;
// List of all shader code attached to this Shader // List of all shader code attached to this Shader
ShaderSources shaderSources; ShaderSources shaderSources;
// Shader compiler warning strings for individual shader stages.
std::map<ShaderType, std::string> shaderWarnings;
GLuint program; // volatile GLuint program; // volatile
// Uniform location buffer map // Uniform location buffer map