Shader: Throw on compile/link error, and print info logs

Also let go of the startup debug prints when compiling.
The engine will now tell us properly which shader fails
at which part.
This commit is contained in:
Jonas Kulla 2013-12-30 01:38:10 +01:00
parent 680e407a38
commit f2d2a1886f
2 changed files with 77 additions and 39 deletions

View File

@ -22,11 +22,12 @@
#include "shader.h" #include "shader.h"
#include "sharedstate.h" #include "sharedstate.h"
#include "glstate.h" #include "glstate.h"
#include "debugwriter.h" #include "exception.h"
#include <glew.h> #include <glew.h>
#include <assert.h> #include <assert.h>
#include <iostream>
#include "../sprite.frag.xxd" #include "../sprite.frag.xxd"
#include "../hue.frag.xxd" #include "../hue.frag.xxd"
@ -50,16 +51,36 @@
#endif #endif
#define INIT_SHADER(vert, frag) \ #define INIT_SHADER(vert, frag, name) \
{ \ { \
Shader::init(shader_##vert##_vert, shader_##vert##_vert_len, shader_##frag##_frag, shader_##frag##_frag_len); \ Shader::init(shader_##vert##_vert, shader_##vert##_vert_len, shader_##frag##_frag, shader_##frag##_frag_len, \
Debug() << " From:" << #vert ".vert" << #frag ".frag"; \ #vert, #frag, #name); \
} }
#define COMP(shader) Debug() << "--- Compiling " #shader
#define GET_U(name) u_##name = glGetUniformLocation(program, #name) #define GET_U(name) u_##name = glGetUniformLocation(program, #name)
static void printShaderLog(GLuint shader)
{
GLint logLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
std::string log(logLength, '\0');
glGetShaderInfoLog(shader, log.size(), 0, &log[0]);
std::clog << "Shader log:\n" << log;
}
static void printProgramLog(GLuint program)
{
GLint logLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
std::string log(logLength, '\0');
glGetProgramInfoLog(program, log.size(), 0, &log[0]);
std::clog << "Program log:\n" << log;
}
Shader::Shader() Shader::Shader()
{ {
vertShader = glCreateShader(GL_VERTEX_SHADER); vertShader = glCreateShader(GL_VERTEX_SHADER);
@ -88,7 +109,9 @@ void Shader::unbind()
} }
void Shader::init(const unsigned char *vert, int vertSize, void Shader::init(const unsigned char *vert, int vertSize,
const unsigned char *frag, int fragSize) const unsigned char *frag, int fragSize,
const char *vertName, const char *fragName,
const char *programName)
{ {
GLint success; GLint success;
@ -97,14 +120,28 @@ void Shader::init(const unsigned char *vert, int vertSize,
glCompileShader(vertShader); glCompileShader(vertShader);
glGetObjectParameterivARB(vertShader, GL_COMPILE_STATUS, &success); glGetObjectParameterivARB(vertShader, GL_COMPILE_STATUS, &success);
assert(success); // FIXME should really throw here instead
if (!success)
{
printShaderLog(vertShader);
throw Exception(Exception::MKXPError,
"GLSL: An error occured while compiling vertex shader '%s' in program '%s'",
vertName, programName);
}
/* Compile fragment shader */ /* Compile fragment shader */
glShaderSource(fragShader, 1, (const GLchar**) &frag, (const GLint*) &fragSize); glShaderSource(fragShader, 1, (const GLchar**) &frag, (const GLint*) &fragSize);
glCompileShader(fragShader); glCompileShader(fragShader);
glGetObjectParameterivARB(fragShader, GL_COMPILE_STATUS, &success); glGetObjectParameterivARB(fragShader, GL_COMPILE_STATUS, &success);
assert(success);
if (!success)
{
printShaderLog(fragShader);
throw Exception(Exception::MKXPError,
"GLSL: An error occured while compiling fragment shader '%s' in program '%s'",
fragName, programName);
}
/* Link shader program */ /* Link shader program */
glAttachShader(program, vertShader); glAttachShader(program, vertShader);
@ -117,17 +154,26 @@ void Shader::init(const unsigned char *vert, int vertSize,
glLinkProgram(program); glLinkProgram(program);
glGetObjectParameterivARB(program, GL_LINK_STATUS, &success); glGetObjectParameterivARB(program, GL_LINK_STATUS, &success);
assert(success);
if (!success)
{
printProgramLog(program);
throw Exception(Exception::MKXPError,
"GLSL: An error occured while linking program '%s' (vertex '%s', fragment '%s')",
programName, vertName, fragName);
}
} }
void Shader::initFromFile(const char *_vertFile, const char *_fragFile) void Shader::initFromFile(const char *_vertFile, const char *_fragFile,
const char *programName)
{ {
std::string vertContents, fragContents; std::string vertContents, fragContents;
readFile(_vertFile, vertContents); readFile(_vertFile, vertContents);
readFile(_fragFile, fragContents); readFile(_fragFile, fragContents);
init((const unsigned char*) vertContents.c_str(), vertContents.size(), init((const unsigned char*) vertContents.c_str(), vertContents.size(),
(const unsigned char*) fragContents.c_str(), fragContents.size()); (const unsigned char*) fragContents.c_str(), fragContents.size(),
_vertFile, _fragFile, programName);
} }
void Shader::setVec4Uniform(GLint location, const Vec4 &vec) void Shader::setVec4Uniform(GLint location, const Vec4 &vec)
@ -190,8 +236,7 @@ void ShaderBase::setTranslation(const Vec2i &value)
SimpleShader::SimpleShader() SimpleShader::SimpleShader()
{ {
COMP(SimpleShader); INIT_SHADER(simple, simple, SimpleShader);
INIT_SHADER(simple, simple);
ShaderBase::init(); ShaderBase::init();
@ -206,8 +251,7 @@ void SimpleShader::setTexOffsetX(int value)
SimpleColorShader::SimpleColorShader() SimpleColorShader::SimpleColorShader()
{ {
COMP(SimpleColorShader); INIT_SHADER(simpleColor, simpleColor, SimpleColorShader);
INIT_SHADER(simpleColor, simpleColor);
ShaderBase::init(); ShaderBase::init();
} }
@ -215,8 +259,7 @@ SimpleColorShader::SimpleColorShader()
SimpleAlphaShader::SimpleAlphaShader() SimpleAlphaShader::SimpleAlphaShader()
{ {
COMP(SimpleAlphaShader); INIT_SHADER(simpleColor, simpleAlpha, SimpleAlphaShader);
INIT_SHADER(simpleColor, simpleAlpha);
ShaderBase::init(); ShaderBase::init();
} }
@ -224,8 +267,7 @@ SimpleAlphaShader::SimpleAlphaShader()
SimpleSpriteShader::SimpleSpriteShader() SimpleSpriteShader::SimpleSpriteShader()
{ {
COMP(SimpleSpriteShader); INIT_SHADER(sprite, simple, SimpleSpriteShader);
INIT_SHADER(sprite, simple);
ShaderBase::init(); ShaderBase::init();
@ -240,8 +282,7 @@ void SimpleSpriteShader::setSpriteMat(const float value[16])
TransShader::TransShader() TransShader::TransShader()
{ {
COMP(TransShader); INIT_SHADER(simple, trans, TransShader);
INIT_SHADER(simple, trans);
ShaderBase::init(); ShaderBase::init();
@ -280,8 +321,7 @@ void TransShader::setVague(float value)
SimpleTransShader::SimpleTransShader() SimpleTransShader::SimpleTransShader()
{ {
COMP(SimpleTransShader); INIT_SHADER(simple, transSimple, SimpleTransShader);
INIT_SHADER(simple, transSimple);
ShaderBase::init(); ShaderBase::init();
@ -308,8 +348,7 @@ void SimpleTransShader::setProg(float value)
SpriteShader::SpriteShader() SpriteShader::SpriteShader()
{ {
COMP(SpriteShader); INIT_SHADER(sprite, sprite, SpriteShader);
INIT_SHADER(sprite, sprite);
ShaderBase::init(); ShaderBase::init();
@ -354,8 +393,7 @@ void SpriteShader::setBushOpacity(float value)
PlaneShader::PlaneShader() PlaneShader::PlaneShader()
{ {
COMP(PlaneShader); INIT_SHADER(simple, plane, PlaneShader);
INIT_SHADER(simple, plane);
ShaderBase::init(); ShaderBase::init();
@ -388,8 +426,7 @@ void PlaneShader::setOpacity(float value)
FlashMapShader::FlashMapShader() FlashMapShader::FlashMapShader()
{ {
COMP(FlashMapShader); INIT_SHADER(simpleColor, flashMap, FlashMapShader);
INIT_SHADER(simpleColor, flashMap);
ShaderBase::init(); ShaderBase::init();
@ -404,8 +441,7 @@ void FlashMapShader::setAlpha(float value)
HueShader::HueShader() HueShader::HueShader()
{ {
COMP(HueShader); INIT_SHADER(simple, hue, HueShader);
INIT_SHADER(simple, hue);
ShaderBase::init(); ShaderBase::init();
@ -428,7 +464,7 @@ void HueShader::setInputTexture(TEX::ID tex)
SimpleMatrixShader::SimpleMatrixShader() SimpleMatrixShader::SimpleMatrixShader()
{ {
INIT_SHADER(simpleMatrix, simpleAlpha); INIT_SHADER(simpleMatrix, simpleAlpha, SimpleMatrixShader);
ShaderBase::init(); ShaderBase::init();
@ -443,14 +479,14 @@ void SimpleMatrixShader::setMatrix(const float value[16])
BlurShader::HPass::HPass() BlurShader::HPass::HPass()
{ {
INIT_SHADER(blurH, blur); INIT_SHADER(blurH, blur, BlurShader::HPass);
ShaderBase::init(); ShaderBase::init();
} }
BlurShader::VPass::VPass() BlurShader::VPass::VPass()
{ {
INIT_SHADER(blurV, blur); INIT_SHADER(blurV, blur, BlurShader::VPass);
ShaderBase::init(); ShaderBase::init();
} }
@ -460,8 +496,7 @@ BlurShader::VPass::VPass()
BltShader::BltShader() BltShader::BltShader()
{ {
COMP(BltShader); INIT_SHADER(simple, bitmapBlit, BltShader);
INIT_SHADER(simple, bitmapBlit);
ShaderBase::init(); ShaderBase::init();

View File

@ -44,8 +44,11 @@ protected:
~Shader(); ~Shader();
void init(const unsigned char *vert, int vertSize, void init(const unsigned char *vert, int vertSize,
const unsigned char *frag, int fragSize); const unsigned char *frag, int fragSize,
void initFromFile(const char *vertFile, const char *fragFile); const char *vertName, const char *fragName,
const char *programName);
void initFromFile(const char *vertFile, const char *fragFile,
const char *programName);
static void setVec4Uniform(GLint location, const Vec4 &vec); static void setVec4Uniform(GLint location, const Vec4 &vec);
static void setTexUniform(GLint location, unsigned unitIndex, TEX::ID texture); static void setTexUniform(GLint location, unsigned unitIndex, TEX::ID texture);