156 lines
3.8 KiB
C++
156 lines
3.8 KiB
C++
#include "shader.h"
|
|
#include "define.h"
|
|
#include "tool.h"
|
|
#include <iostream>
|
|
#include <cassert>
|
|
|
|
#ifndef WINDOWS
|
|
|
|
bool Shader::Load(const std::string& vertFile, const std::string& fragFile, bool verbose)
|
|
{
|
|
std::string fragmentShader;
|
|
std::string vertexShader;
|
|
|
|
if(!Tool::LoadTextFile(vertFile, vertexShader))
|
|
{
|
|
if(verbose)
|
|
std::cout << "Failed to load " << vertFile << std::endl;
|
|
return false;
|
|
}
|
|
|
|
if(!Tool::LoadTextFile(fragFile, fragmentShader))
|
|
{
|
|
if(verbose)
|
|
std::cout << "Failed to load " << fragFile << std::endl;
|
|
return false;
|
|
}
|
|
|
|
const char * my_fragment_shader_source = fragmentShader.c_str();
|
|
const char * my_vertex_shader_source = vertexShader.c_str();
|
|
|
|
//std::cout << fragmentShader << std::endl;
|
|
//std::cout << vertexShader << std::endl;
|
|
|
|
m_program = glCreateProgram();
|
|
CHECK_GL_ERROR();
|
|
assert(glIsProgram(m_program));
|
|
|
|
m_vertexShader = glCreateShader(GL_VERTEX_SHADER_ARB);
|
|
CHECK_GL_ERROR();
|
|
assert(glIsShader(m_vertexShader));
|
|
|
|
m_fragmentShader = glCreateShader(GL_FRAGMENT_SHADER_ARB);
|
|
CHECK_GL_ERROR();
|
|
assert(glIsShader(m_fragmentShader));
|
|
|
|
// Load Shader Sources
|
|
glShaderSource(m_vertexShader, 1, (const GLchar**)&my_vertex_shader_source, NULL);
|
|
CHECK_GL_ERROR();
|
|
glShaderSource(m_fragmentShader, 1, (const GLchar**)&my_fragment_shader_source, NULL);
|
|
CHECK_GL_ERROR();
|
|
|
|
// Compile The Shaders
|
|
if(verbose)
|
|
std::cout << "Compiling vertex shader (" << vertFile << ")..." << std::endl;
|
|
glCompileShader(m_vertexShader);
|
|
if(!CheckShaderError(m_vertexShader, verbose))
|
|
return false;
|
|
|
|
if(verbose)
|
|
std::cout << "Compiling fragment shader (" << fragFile << ")..." << std::endl;
|
|
glCompileShader(m_fragmentShader);
|
|
if(!CheckShaderError(m_fragmentShader, verbose))
|
|
return false;
|
|
|
|
// Attach The Shader Objects To The Program Object
|
|
glAttachShader(m_program, m_vertexShader);
|
|
CHECK_GL_ERROR();
|
|
glAttachShader(m_program, m_fragmentShader);
|
|
CHECK_GL_ERROR();
|
|
|
|
// Link The Program Object
|
|
glLinkProgram(m_program);
|
|
//if(!CheckProgramError(m_program, verbose))
|
|
// return false;
|
|
CheckProgramError(m_program, true, verbose);
|
|
CHECK_GL_ERROR();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
void Shader::Use() const
|
|
{
|
|
glUseProgram(m_program);
|
|
}
|
|
|
|
GLint Shader::BindIntUniform(const std::string& name) const
|
|
{
|
|
return glGetUniformLocation(m_program, name.c_str());
|
|
}
|
|
|
|
void Shader::UpdateIntUniform(GLint name, GLint value) const
|
|
{
|
|
glUniform1i(name, value);
|
|
}
|
|
|
|
void Shader::UpdateFloatUniform(GLint name, GLfloat value) const
|
|
{
|
|
glUniform1f(name, value);
|
|
}
|
|
|
|
void Shader::Disable()
|
|
{
|
|
glUseProgram(0);
|
|
}
|
|
|
|
bool Shader::CheckShaderError(GLenum shader, bool verbose)
|
|
{
|
|
GLint compileOk;
|
|
|
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileOk);
|
|
if(verbose && !compileOk)
|
|
{
|
|
int maxLength;
|
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
|
|
|
|
char* infoLog = new char[maxLength];
|
|
|
|
glGetShaderInfoLog(shader, maxLength, &maxLength, infoLog);
|
|
|
|
std::cout << infoLog << std::endl;
|
|
delete [] infoLog;
|
|
return false;
|
|
}
|
|
|
|
return compileOk;
|
|
}
|
|
|
|
bool Shader::CheckProgramError(GLenum program, bool showWarning, bool verbose)
|
|
{
|
|
GLint compileOk;
|
|
|
|
glGetProgramiv(program, GL_LINK_STATUS, &compileOk);
|
|
CHECK_GL_ERROR();
|
|
if(verbose && (showWarning || !compileOk))
|
|
{
|
|
int maxLength;
|
|
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
|
|
CHECK_GL_ERROR();
|
|
|
|
char* infoLog = new char[maxLength + 1];
|
|
|
|
glGetProgramInfoLog(program, maxLength, &maxLength, infoLog);
|
|
CHECK_GL_ERROR();
|
|
|
|
infoLog[maxLength] = 0;
|
|
|
|
std::cout << infoLog << std::endl;
|
|
delete [] infoLog;
|
|
}
|
|
|
|
return compileOk;
|
|
}
|
|
|
|
#endif
|