This commit is contained in:
60
include/graphics/opengl/buffer.hpp
Normal file
60
include/graphics/opengl/buffer.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
||||
namespace kuiper
|
||||
{
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
class buffer {
|
||||
public:
|
||||
using s_ptr = std::shared_ptr<buffer>;
|
||||
|
||||
explicit buffer(GLuint id, GLenum target)
|
||||
: m_id(id), m_target(target) {}
|
||||
~buffer() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
buffer(const buffer& other) = delete;
|
||||
buffer& operator=(const buffer& other) = delete;
|
||||
buffer(buffer&& other) noexcept = default;
|
||||
buffer& operator=(buffer&& other) noexcept = default;
|
||||
|
||||
static s_ptr make(GLenum target) noexcept;
|
||||
|
||||
public:
|
||||
GLuint id() const noexcept {
|
||||
return m_id;
|
||||
}
|
||||
|
||||
std::size_t size() const noexcept {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
void destroy() noexcept;
|
||||
void bind() const noexcept;
|
||||
void bind_to_location(std::uint32_t location) const noexcept;
|
||||
void upload(GLenum usage, std::size_t size, const void* data) noexcept;
|
||||
void update(std::size_t offset, std::size_t size, const void* data) noexcept;
|
||||
void set_vertex_attrib(std::uint32_t index,
|
||||
std::size_t size,
|
||||
GLenum type,
|
||||
std::size_t stride,
|
||||
std::size_t offset,
|
||||
bool normalised = false) noexcept;
|
||||
|
||||
private:
|
||||
GLuint m_id {0};
|
||||
GLenum m_target {0};
|
||||
std::size_t m_size {0};
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} // namespace kuiper
|
||||
79
include/graphics/opengl/framebuffer.hpp
Normal file
79
include/graphics/opengl/framebuffer.hpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
|
||||
#include "graphics/opengl/texture.hpp"
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace kuiper
|
||||
{
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
class framebuffer {
|
||||
public:
|
||||
using s_ptr = std::shared_ptr<framebuffer>;
|
||||
|
||||
// OpenGL mandates at least 8 colour buffers
|
||||
static constexpr std::uint32_t max_colour_attachments = 8;
|
||||
using col_tex_storage = std::array<texture::s_ptr, max_colour_attachments>;
|
||||
|
||||
explicit framebuffer(GLuint id)
|
||||
: m_id(id) {}
|
||||
~framebuffer() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
framebuffer(const framebuffer& other) = delete;
|
||||
framebuffer& operator=(const framebuffer& other) = delete;
|
||||
framebuffer(framebuffer&& other) noexcept = default;
|
||||
framebuffer& operator=(framebuffer&& other) noexcept = default;
|
||||
|
||||
static s_ptr make() noexcept;
|
||||
static s_ptr make_default(std::uint32_t width, std::uint32_t height) noexcept;
|
||||
|
||||
public:
|
||||
void destroy() noexcept;
|
||||
|
||||
void bind() const noexcept;
|
||||
|
||||
void resize(std::uint32_t width, std::uint32_t height) noexcept;
|
||||
|
||||
GLuint id() const noexcept {
|
||||
return m_id;
|
||||
}
|
||||
|
||||
const col_tex_storage& colour_tex() const noexcept {
|
||||
return m_colour_texs;
|
||||
}
|
||||
|
||||
const texture::s_ptr& depth_tex() const noexcept {
|
||||
return m_depth_tex;
|
||||
}
|
||||
|
||||
glm::u32vec2 dimensions() const noexcept {
|
||||
return {m_width, m_height};
|
||||
}
|
||||
|
||||
// Attach a colour texture to the framebuffer, optionally at a given attachment point. Takes ownership of `tex`.
|
||||
void attach_colour(texture::s_ptr&& tex, std::uint32_t attachment_point = 0) noexcept;
|
||||
// Attach a depth AND stencil texture to the framebuffer. Takes ownership of `tex`.
|
||||
void attach_depth(texture::s_ptr&& tex) noexcept;
|
||||
|
||||
private:
|
||||
GLuint m_id {0};
|
||||
col_tex_storage m_colour_texs {};
|
||||
texture::s_ptr m_depth_tex {nullptr};
|
||||
std::uint32_t m_width {0};
|
||||
std::uint32_t m_height {0};
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} // namespace kuiper
|
||||
70
include/graphics/opengl/program.hpp
Normal file
70
include/graphics/opengl/program.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include "glm/ext/vector_float3.hpp"
|
||||
#include "graphics/opengl/shader.hpp"
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <glm/mat3x3.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
|
||||
namespace kuiper
|
||||
{
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
class program {
|
||||
public:
|
||||
using s_ptr = std::shared_ptr<program>;
|
||||
|
||||
explicit program(GLuint id)
|
||||
: m_id(id) {}
|
||||
~program() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
program(const program& other) = delete;
|
||||
program& operator=(const program& other) = delete;
|
||||
program(program&& other) noexcept = default;
|
||||
program& operator=(program&& other) noexcept = default;
|
||||
|
||||
static s_ptr make() noexcept;
|
||||
static s_ptr from_shaders(std::initializer_list<shader::s_ptr> shaders);
|
||||
|
||||
public:
|
||||
GLuint id() const noexcept {
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void destroy() noexcept;
|
||||
void use() const noexcept;
|
||||
void attach_shader(const shader::s_ptr& shader) noexcept;
|
||||
bool link() noexcept;
|
||||
|
||||
// Uniforms
|
||||
|
||||
GLint uniform_location(const char* name) const noexcept;
|
||||
void set_uint(const char* uniform, std::uint32_t value) noexcept;
|
||||
void set_int(const char* uniform, std::int32_t value) noexcept;
|
||||
void set_int_array(const char* uniform, const std::int32_t* value_arr, std::size_t len) noexcept;
|
||||
void set_float(const char* uniform, float value) noexcept;
|
||||
void set_vec3(const char* uniform, const glm::vec3& value) noexcept;
|
||||
void set_uvec3(const char* uniform, const glm::uvec3& value) noexcept;
|
||||
void set_uvec2(const char* uniform, const glm::uvec2& value) noexcept;
|
||||
void set_mat3(const char* uniform, const glm::mat3& value) noexcept;
|
||||
void set_mat4(const char* uniform, const glm::mat4& value) noexcept;
|
||||
|
||||
private:
|
||||
GLuint m_id {0};
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} // namespace kuiper
|
||||
74
include/graphics/opengl/render_context.hpp
Normal file
74
include/graphics/opengl/render_context.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include "graphics/opengl/framebuffer.hpp"
|
||||
|
||||
#include <glad/gl.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace kuiper
|
||||
{
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
void initialise();
|
||||
|
||||
void dump_hardware_info();
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
void debug_callback(GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
GLsizei length,
|
||||
const GLchar* message,
|
||||
const void* userParam) noexcept;
|
||||
#endif
|
||||
|
||||
class render_context {
|
||||
public:
|
||||
/// Binds a framebuffer to the renderer pipeline
|
||||
static void bind_framebuffer(const framebuffer::s_ptr& fb) noexcept;
|
||||
|
||||
/// Binds the default framebuffer
|
||||
static void bind_default_framebuffer() noexcept;
|
||||
|
||||
/// Set the viewport size over the currently bound framebuffer
|
||||
static void set_viewport_size(std::uint32_t width, std::uint32_t height) noexcept;
|
||||
|
||||
/// Enables an OpenGL feature
|
||||
static void enable_feature(GLenum feature) noexcept;
|
||||
|
||||
/// Disables an OpenGL feature
|
||||
static void disable_feature(GLenum feature) noexcept;
|
||||
|
||||
template<typename T>
|
||||
static T get(GLenum param) noexcept {
|
||||
T ret {};
|
||||
|
||||
if constexpr (std::is_same<T, GLint>::value) {
|
||||
glGetIntegerv(param, &ret);
|
||||
} else if constexpr (std::is_same<T, GLint64>::value) {
|
||||
glGetInteger64v(param, &ret);
|
||||
} else if constexpr (std::is_same<T, GLfloat>::value) {
|
||||
glGetFloatv(param, &ret);
|
||||
} else if constexpr (std::is_same<T, GLdouble>::value) {
|
||||
glGetDoublev(param, &ret);
|
||||
} else if constexpr (std::is_same<T, GLboolean>::value) {
|
||||
glGetBooleanv(param, &ret);
|
||||
} else {
|
||||
static_assert(!"non-exhaustive if-constexpr!");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static constexpr const char* GLSL_VERSION = "#version 460 core";
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} // namespace kuiper
|
||||
57
include/graphics/opengl/shader.hpp
Normal file
57
include/graphics/opengl/shader.hpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
|
||||
namespace kuiper
|
||||
{
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
enum class shader_type : std::uint8_t {
|
||||
none = 0,
|
||||
vertex,
|
||||
fragment,
|
||||
compute
|
||||
};
|
||||
|
||||
class shader {
|
||||
public:
|
||||
using s_ptr = std::shared_ptr<shader>;
|
||||
|
||||
explicit shader(GLuint id, GLenum type)
|
||||
: m_id(id), m_type(type) {}
|
||||
~shader() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
shader(const shader& other) = delete;
|
||||
shader& operator=(const shader& other) = delete;
|
||||
shader(shader&& other) noexcept = default;
|
||||
shader& operator=(shader&& other) noexcept = default;
|
||||
|
||||
static s_ptr make(shader_type type) noexcept;
|
||||
static s_ptr from_path(const std::filesystem::path& shader_path, shader_type type = shader_type::none) noexcept;
|
||||
static s_ptr from_source(std::string_view source, shader_type type) noexcept;
|
||||
|
||||
public:
|
||||
void destroy() noexcept;
|
||||
void attach_source(std::string_view source) noexcept;
|
||||
void compile() noexcept;
|
||||
GLuint id() const noexcept {
|
||||
return m_id;
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint m_id {0};
|
||||
GLenum m_type {0};
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} // namespace kuiper
|
||||
97
include/graphics/opengl/texture.hpp
Normal file
97
include/graphics/opengl/texture.hpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
|
||||
namespace kuiper
|
||||
{
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
enum class texture_type : std::uint8_t {
|
||||
none = 0,
|
||||
tex_2d
|
||||
};
|
||||
|
||||
class texture {
|
||||
public:
|
||||
using s_ptr = std::shared_ptr<texture>;
|
||||
|
||||
explicit texture(GLuint id, GLenum target)
|
||||
: m_id(id), m_target(target) {}
|
||||
~texture() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
texture(const texture& other) = delete;
|
||||
texture& operator=(const texture& other) = delete;
|
||||
texture(texture&& other) noexcept = default;
|
||||
texture& operator=(texture&& other) noexcept = default;
|
||||
|
||||
/// Makes a new, uninitialised texture
|
||||
static s_ptr make(texture_type type = texture_type::tex_2d) noexcept;
|
||||
/// Makes a placeholder 4x4 texture
|
||||
static s_ptr make_placeholder() noexcept;
|
||||
/// Makes a texture from a path to an encoded image
|
||||
static s_ptr from_image_path(const std::filesystem::path& image_path, bool flip_y = true) noexcept;
|
||||
/// Makes a texture from a pointer to encoded image data
|
||||
static s_ptr from_image_data(const std::uint8_t* buffer, std::size_t length, bool flip_y = true) noexcept;
|
||||
|
||||
public:
|
||||
/// Explicitly delete the OpenGL texture object
|
||||
void destroy() noexcept;
|
||||
/// Bind the texture
|
||||
void bind() noexcept;
|
||||
/// Upload image data to the texture object on the GPU
|
||||
void upload(
|
||||
GLint internal_fmt, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data) noexcept;
|
||||
/// Resize underlying texture buffer
|
||||
void resize(std::uint32_t width, std::uint32_t height) noexcept;
|
||||
/// Set a texture parameter
|
||||
void set_param(GLenum name, GLint param) noexcept;
|
||||
/// Generate texture mipmaps
|
||||
void gen_mipmaps() noexcept;
|
||||
|
||||
/// Get the dimensions of the texture
|
||||
glm::uvec2 dimensions() const noexcept {
|
||||
return {m_width, m_height};
|
||||
}
|
||||
|
||||
GLint internal_format() const noexcept {
|
||||
return m_internal_fmt;
|
||||
}
|
||||
|
||||
GLenum pixel_format() const noexcept {
|
||||
return m_pixel_fmt;
|
||||
}
|
||||
|
||||
GLenum pixel_type() const noexcept {
|
||||
return m_pixel_type;
|
||||
}
|
||||
|
||||
/// Get the internal OpenGL object name
|
||||
GLuint id() const noexcept {
|
||||
return m_id;
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint m_id {0};
|
||||
GLenum m_target {0};
|
||||
std::uint32_t m_width {0};
|
||||
std::uint32_t m_height {0};
|
||||
GLint m_internal_fmt {0};
|
||||
GLenum m_pixel_fmt {0};
|
||||
GLenum m_pixel_type {0};
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} // namespace kuiper
|
||||
74
include/graphics/opengl/texture_array.hpp
Normal file
74
include/graphics/opengl/texture_array.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace kuiper
|
||||
{
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
class texture_array {
|
||||
public:
|
||||
using s_ptr = std::shared_ptr<texture_array>;
|
||||
|
||||
explicit texture_array(GLuint id, GLenum target)
|
||||
: m_id(id), m_target(target) {}
|
||||
~texture_array() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
texture_array(const texture_array& other) = delete;
|
||||
texture_array& operator=(const texture_array& other) = delete;
|
||||
texture_array(texture_array&& other) noexcept = default;
|
||||
texture_array& operator=(texture_array&& other) noexcept = default;
|
||||
|
||||
static s_ptr make(GLenum target) noexcept;
|
||||
|
||||
public:
|
||||
void destroy() noexcept;
|
||||
void bind(std::uint32_t unit = 0) const noexcept;
|
||||
void set_storage(GLenum internal_fmt, std::uint32_t width, std::uint32_t height, std::uint32_t depth) noexcept;
|
||||
void upload(std::uint32_t x_offset,
|
||||
std::uint32_t y_offset,
|
||||
std::uint32_t z_offset,
|
||||
std::uint32_t width,
|
||||
std::uint32_t height,
|
||||
std::uint32_t depth,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
const void* data,
|
||||
std::uint32_t mip_level = 0) noexcept;
|
||||
void set_param(GLenum name, GLint param) noexcept;
|
||||
void gen_mipmaps() noexcept;
|
||||
|
||||
glm::uvec3 dimensions() const noexcept {
|
||||
return {m_width, m_height, m_depth};
|
||||
}
|
||||
|
||||
GLuint id() const noexcept {
|
||||
return m_id;
|
||||
}
|
||||
|
||||
GLenum internal_format() const noexcept {
|
||||
return m_internal_fmt;
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint m_id {0};
|
||||
GLenum m_target {0};
|
||||
GLenum m_internal_fmt {0};
|
||||
std::uint32_t m_width {0};
|
||||
std::uint32_t m_height {0};
|
||||
std::uint32_t m_depth {0};
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} // namespace kuiper
|
||||
48
include/graphics/opengl/vertex_array.hpp
Normal file
48
include/graphics/opengl/vertex_array.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace kuiper
|
||||
{
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
class vertex_array {
|
||||
public:
|
||||
using s_ptr = std::shared_ptr<vertex_array>;
|
||||
|
||||
explicit vertex_array(GLuint id)
|
||||
: m_id(id) {}
|
||||
~vertex_array() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
vertex_array(const vertex_array& other) = delete;
|
||||
vertex_array& operator=(const vertex_array& other) = delete;
|
||||
vertex_array(vertex_array&& other) noexcept = default;
|
||||
vertex_array& operator=(vertex_array&& other) noexcept = default;
|
||||
|
||||
static s_ptr make() noexcept;
|
||||
|
||||
public:
|
||||
GLuint id() const noexcept {
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void destroy() noexcept;
|
||||
void bind() const noexcept;
|
||||
void enable_attrib(std::uint32_t index) noexcept;
|
||||
void disable_attrib(std::uint32_t index) noexcept;
|
||||
void set_attrib_divisor(std::uint32_t attrib, std::uint32_t divisor) noexcept;
|
||||
void set_binding_divisor(std::uint32_t binding, std::uint32_t divisor) noexcept;
|
||||
|
||||
private:
|
||||
GLuint m_id {0};
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} // namespace kuiper
|
||||
Reference in New Issue
Block a user