SQCSimulator2023/SQCSim2021/shader.cpp
2021-10-11 11:37:58 -04:00

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