SparrowRenderer/shader.cpp
2015-06-22 01:57:02 +02:00

96 lines
2.7 KiB
C++

#include "shader.h"
#include <glew/glew.h>
#include <QFile>
#include <QTextStream>
#include <iostream>
#include "glassert.h"
Shader::Shader(const QString &vertFilename, const QString &fragFilename)
{
program = glAssert(glCreateProgram());
GLuint vertexShaderId = createShader(vertFilename, GL_VERTEX_SHADER);
GLuint fragmentShaderId = createShader(fragFilename, GL_FRAGMENT_SHADER);
glAssert(glAttachShader(program, vertexShaderId));
glAssert(glAttachShader(program, fragmentShaderId));
glAssert(glBindAttribLocation(program, 0, "inPosition"));
glAssert(glBindAttribLocation(program, 1, "inNormal"));
glAssert(glBindAttribLocation(program, 2, "inTexCoord"));
glAssert(glLinkProgram(program));
// check errors
GLint linked;
glAssert(glGetProgramiv(program, GL_LINK_STATUS, &linked));
if (!linked) {
std::cerr << "Program not linked" << std::endl;
printProgramInfoLog(program);
program = 0;
}
}
QString Shader::fileToString(QString filename)
{
QFile f(filename);
if(!f.open(QFile::ReadOnly | QFile::Text))
return NULL;
QTextStream in(&f);
return in.readAll();
}
GLuint Shader::createShader(QString filename, GLenum shaderType)
{
QString source = fileToString(filename);
glAssert(GLuint shaderId = glCreateShader(shaderType));
const GLchar *data = (const GLchar *)source.constData();
glAssert(glShaderSource(shaderId, 1, &data, NULL));
glAssert(glCompileShader(shaderId));
// check errors
GLint compiled;
glAssert(glGetShaderiv(shaderId, GL_COMPILE_STATUS, &compiled));
if (!compiled) {
std::cerr << "[" << filename.toStdString() << "] Vertex shader not compiled : " << std::endl;
printShaderInfoLog(shaderId);
return 0;
}
else
return shaderId;
}
void Shader::printShaderInfoLog(GLuint shaderId)
{
int infoLogLen = 0;
int charsWritten = 0;
GLchar *infoLog;
glAssert(glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &infoLogLen));
if (infoLogLen > 0) {
infoLog = new GLchar[infoLogLen];
glAssert(glGetShaderInfoLog(shaderId, infoLogLen, &charsWritten, infoLog));
std::cerr << "InfoLog:" << std::endl << infoLog << std::endl;
delete [] infoLog;
}
}
void Shader::printProgramInfoLog(GLuint programId)
{
int infoLogLen = 0;
int charsWritten = 0;
GLchar *infoLog;
glAssert(glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLogLen));
if (infoLogLen > 0) {
infoLog = new GLchar[infoLogLen];
glAssert(glGetProgramInfoLog(programId, infoLogLen, &charsWritten, infoLog));
std::cerr << "InfoLog:" << std::endl << infoLog << std::endl;
delete [] infoLog;
}
}
GLuint Shader::getProgramId()
{
return program;
}