initial commit
All checks were successful
Build (Arch Linux) / build (push) Successful in 3m10s

This commit is contained in:
2025-04-16 01:58:29 +01:00
commit a8d8b9b9ab
116 changed files with 106633 additions and 0 deletions

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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