115 lines
3.4 KiB
C++
115 lines
3.4 KiB
C++
#include "shader.h"
|
|
#include <glew/glew.h>
|
|
#include <QFile>
|
|
#include <QTextStream>
|
|
#include <iostream>
|
|
#include "glassert.h"
|
|
|
|
const std::string Shader::DEFAULT_VERT = "#version 330\nlayout(location = 0)in vec3 inPosition;\nvoid main(){gl_Position = vec4(inPosition, 1.0);}";
|
|
const std::string Shader::DEFAULT_FRAG = "#version 330\nlayout(location = 0)out vec4 outColor;\nvoid main(){outColor = vec4(1, 0, 0, 1);}";
|
|
|
|
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;
|
|
}
|
|
else
|
|
std::cout << "Shader successfully compiled" << std::endl;
|
|
|
|
glAssert(glDetachShader(program, vertexShaderId));
|
|
glAssert(glDetachShader(program, fragmentShaderId));
|
|
glAssert(glDeleteShader(vertexShaderId));
|
|
glAssert(glDeleteShader(fragmentShaderId));
|
|
}
|
|
|
|
Shader::~Shader()
|
|
{
|
|
bool ok;
|
|
glAssert(ok = glIsProgram(program))
|
|
if(ok)
|
|
glAssert(glDeleteProgram(program));
|
|
}
|
|
|
|
|
|
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.toStdString().c_str();
|
|
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;
|
|
}
|