@ -0,0 +1,123 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "gl/shader-object.hpp" | |||
#include <glad/glad.h> | |||
#include <stdexcept> | |||
namespace gl { | |||
static constexpr GLenum gl_shader_type_lut[] = | |||
{ | |||
GL_VERTEX_SHADER, | |||
GL_FRAGMENT_SHADER, | |||
GL_GEOMETRY_SHADER | |||
}; | |||
shader_object::shader_object(shader_stage stage): | |||
gl_shader_id(0), | |||
stage(stage), | |||
compiled(false) | |||
{ | |||
// Look up OpenGL shader type enumeration that corresponds to the given stage | |||
GLenum gl_shader_type = gl_shader_type_lut[static_cast<std::size_t>(stage)]; | |||
// Create an OpenGL shader object | |||
gl_shader_id = glCreateShader(gl_shader_type); | |||
// Handle OpenGL errors | |||
if (!gl_shader_id) | |||
{ | |||
throw std::runtime_error("An error occurred while creating an OpenGL shader object."); | |||
} | |||
} | |||
shader_object::~shader_object() | |||
{ | |||
// Flags the OpenGL shader object for deletion | |||
glDeleteShader(gl_shader_id); | |||
} | |||
void shader_object::source(const char* buffer, std::size_t size) | |||
{ | |||
// Replace OpenGL shader object source code | |||
GLint gl_length = size; | |||
glShaderSource(gl_shader_id, 1, &buffer, &gl_length); | |||
// Handle OpenGL errors | |||
switch (glGetError()) | |||
{ | |||
case GL_INVALID_VALUE: | |||
throw std::runtime_error("Shader object handle is not a value generated by OpenGL."); | |||
break; | |||
case GL_INVALID_OPERATION: | |||
throw std::runtime_error("Shader object handle is not a shader object."); | |||
break; | |||
} | |||
} | |||
bool shader_object::compile() | |||
{ | |||
// Compile OpenGL shader object | |||
glCompileShader(gl_shader_id); | |||
// Handle OpenGL errors | |||
switch (glGetError()) | |||
{ | |||
case GL_INVALID_VALUE: | |||
throw std::runtime_error("Shader object handle is not a value generated by OpenGL."); | |||
break; | |||
case GL_INVALID_OPERATION: | |||
throw std::runtime_error("Shader object handle is not a shader object."); | |||
break; | |||
} | |||
// Get OpenGL shader object compilation status | |||
GLint gl_compile_status; | |||
glGetShaderiv(gl_shader_id, GL_COMPILE_STATUS, &gl_compile_status); | |||
compiled = (gl_compile_status == GL_TRUE); | |||
// Get OpenGL shader object info log length | |||
GLint gl_info_log_length; | |||
glGetShaderiv(gl_shader_id, GL_INFO_LOG_LENGTH, &gl_info_log_length); | |||
if (gl_info_log_length > 0) | |||
{ | |||
// Resize string to accommodate OpenGL shader object info log | |||
info_log.resize(gl_info_log_length); | |||
// Read OpenGL shader object info log into string | |||
glGetShaderInfoLog(gl_shader_id, gl_info_log_length, &gl_info_log_length, info_log.data()); | |||
// Remove redundant null terminator from string | |||
info_log.pop_back(); | |||
} | |||
else | |||
{ | |||
// Empty info log | |||
info_log.clear(); | |||
} | |||
// Return compilation status | |||
return compiled; | |||
} | |||
} // namespace gl |
@ -0,0 +1,116 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_GL_SHADER_OBJECT_HPP | |||
#define ANTKEEPER_GL_SHADER_OBJECT_HPP | |||
#include "gl/shader-stage.hpp" | |||
#include <cstdlib> | |||
#include <string> | |||
namespace gl { | |||
class shader_program; | |||
/** | |||
* Shader object which can be compiled and linked to a shader program. | |||
* | |||
* @see gl::shader_program | |||
* @see gl::shader_stage | |||
*/ | |||
class shader_object | |||
{ | |||
public: | |||
/** | |||
* Creates an empty shader object for the specified shader stage. | |||
* | |||
* @param stage Shader stage in which this shader object will be used. | |||
* | |||
* @exception std::runtime_error An error occurred while creating an OpenGL shader object. | |||
*/ | |||
shader_object(shader_stage stage); | |||
/** | |||
* Destroys a shader object. | |||
*/ | |||
~shader_object(); | |||
/** | |||
* Replaces the source code of the shader object. | |||
* | |||
* @param buffer Buffer containing shader object source code. | |||
* @param size Size of the source code, in bytes. | |||
* | |||
* @exception std::runtime_error Shader object handle is not a value generated by OpenGL. | |||
* @exception std::runtime_error Shader object handle is not a shader object. | |||
*/ | |||
void source(const char* buffer, std::size_t size); | |||
/** | |||
* Compiles the shader object. | |||
* | |||
* @return `true` if the shader object was compiled successfully, `false` otherwise. If compilation fails, check the info log via shader_object::get_info_log() for more information. | |||
* | |||
* @exception std::runtime_error Shader object handle is not a value generated by OpenGL. | |||
* @exception std::runtime_error Shader object handle is not a shader object. | |||
* | |||
* @see shader_object::get_info_log() | |||
*/ | |||
bool compile(); | |||
/// Returns the shader stage of this shader object. | |||
shader_stage get_stage() const; | |||
/// Returns the shader object info log, which is updated when the shader is compiled. | |||
const std::string& get_info_log() const; | |||
/// Returns `true` if the shader object has been successfully compiled, `false` otherwise. | |||
bool was_compiled() const; | |||
shader_object(const shader_object&) = delete; | |||
shader_object& operator=(const shader_object&) = delete; | |||
private: | |||
friend class shader_program; | |||
unsigned int gl_shader_id; | |||
shader_stage stage; | |||
bool compiled; | |||
std::string info_log; | |||
}; | |||
inline shader_stage shader_object::get_stage() const | |||
{ | |||
return stage; | |||
} | |||
inline const std::string& shader_object::get_info_log() const | |||
{ | |||
return info_log; | |||
} | |||
inline bool shader_object::was_compiled() const | |||
{ | |||
return compiled; | |||
} | |||
} // namespace gl | |||
#endif // ANTKEEPER_GL_SHADER_OBJECT_HPP |
@ -1,72 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "gl/shader.hpp" | |||
#include <glad/glad.h> | |||
#include <stdexcept> | |||
namespace gl { | |||
static constexpr GLenum shader_type_lut[] = | |||
{ | |||
GL_VERTEX_SHADER, | |||
GL_FRAGMENT_SHADER, | |||
GL_GEOMETRY_SHADER | |||
}; | |||
shader::shader(shader_type type, const std::string& source): | |||
gl_shader_id(0), | |||
type(type) | |||
{ | |||
GLenum gl_shader_type = shader_type_lut[static_cast<std::size_t>(type)]; | |||
const char* source_c_str = source.c_str(); | |||
gl_shader_id = glCreateShader(gl_shader_type); | |||
glShaderSource(gl_shader_id, 1, &source_c_str, nullptr); | |||
glCompileShader(gl_shader_id); | |||
GLint status; | |||
glGetShaderiv(gl_shader_id, GL_COMPILE_STATUS, &status); | |||
if (status == GL_FALSE) | |||
{ | |||
throw std::runtime_error(get_info_log().c_str()); | |||
} | |||
} | |||
shader::~shader() | |||
{ | |||
glDeleteShader(gl_shader_id); | |||
} | |||
std::string shader::get_info_log() const | |||
{ | |||
GLint length; | |||
glGetShaderiv(gl_shader_id, GL_INFO_LOG_LENGTH, &length); | |||
if (length > 0) | |||
{ | |||
std::string log(length, '\0'); | |||
glGetShaderInfoLog(gl_shader_id, length, &length, &log[0]); | |||
return log; | |||
} | |||
return std::string(); | |||
} | |||
} // namespace gl |
@ -1,59 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_GL_SHADER_HPP | |||
#define ANTKEEPER_GL_SHADER_HPP | |||
#include <cstdlib> | |||
#include <string> | |||
namespace gl { | |||
enum class shader_type; | |||
class shader_program; | |||
class shader | |||
{ | |||
public: | |||
shader(shader_type type, const std::string& source); | |||
~shader(); | |||
shader(const shader&) = delete; | |||
shader& operator=(const shader&) = delete; | |||
shader_type get_type() const; | |||
private: | |||
friend class shader_program; | |||
std::string get_info_log() const; | |||
unsigned int gl_shader_id; | |||
shader_type type; | |||
}; | |||
inline shader_type shader::get_type() const | |||
{ | |||
return type; | |||
} | |||
} // namespace gl | |||
#endif // ANTKEEPER_GL_SHADER_HPP | |||