#include "ComputeShader.hpp" ComputeShader::ComputeShader(std::string &shader_filename) { load(shader_filename); } ComputeShader::~ComputeShader() { release(); } GLuint ComputeShader::get_program() const { return m_program; } bool ComputeShader::load(std::string shader_filename) { m_shader_filename = shader_filename; std::ifstream input_file(m_shader_filename); if(!input_file){ std::cout << "Can't open " << shader_filename << std::endl; return false; } std::ostringstream string_stream; string_stream << input_file.rdbuf(); m_shader_source = string_stream.str(); return true; } bool ComputeShader::compile() { m_shader = glCreateShader(GL_COMPUTE_SHADER); const GLchar *source_cstr = (const GLchar *)m_shader_source.c_str(); glShaderSource(m_shader, 1, &source_cstr, NULL); glCompileShader(m_shader); GLint is_compiled = 0; glGetShaderiv(m_shader, GL_COMPILE_STATUS, &is_compiled); if(is_compiled == GL_FALSE) { GLint max_length = 0; glGetShaderiv(m_shader, GL_INFO_LOG_LENGTH, &max_length); std::vector error_log(max_length); glGetShaderInfoLog(m_shader, max_length, &max_length, &error_log[0]); std::cout << (char *)error_log.data() << std::endl; glDeleteShader(m_shader); return false; } m_program = glCreateProgram(); glAttachShader(m_program, m_shader); glLinkProgram(m_program); GLint is_linked = 0; glGetProgramiv(m_program, GL_LINK_STATUS, &is_linked); if(is_linked == GL_FALSE) { GLint max_length = 0; glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &max_length); std::vector error_log(max_length); glGetProgramInfoLog(m_program, max_length, &max_length, &error_log[0]); std::cout << (char *)error_log.data() << std::endl; glDeleteProgram(m_program); return false; } glDetachShader(m_program, m_shader); return true; } void ComputeShader::activate() { glUseProgram(m_program); } void ComputeShader::deactivate() { glUseProgram(0); } void ComputeShader::execute(int n) { glDispatchCompute(n/32 + (n % 32 ? 1 : 0), 1, 1); } void ComputeShader::wait() { glMemoryBarrier( GL_ALL_BARRIER_BITS ); } bool ComputeShader::release() { if(m_shader != 0){ glDeleteShader(m_shader); m_shader = 0; } if(m_program != 0){ glDeleteProgram(m_program); m_program = 0; } return true; } bool ComputeShader::set_uniform(char const *name, int value) { GLint location = glGetUniformLocation(m_program, name); if(location == -1){ std::cout << "Uniform " << name << " not found in program." << std::endl; return false; } glUniform1i(location, value); return true; } bool ComputeShader::set_uniform(char const *name, float value) { GLint location = glGetUniformLocation(m_program, name); if(location == -1){ std::cout << "Uniform " << name << " not found in program." << std::endl; return false; } glUniform1f(location, value); return true; }