This commit is contained in:
163
include/renderer/gl_renderer.hpp
Normal file
163
include/renderer/gl_renderer.hpp
Normal file
@@ -0,0 +1,163 @@
|
||||
#pragma once
|
||||
|
||||
#include "components/camera.hpp"
|
||||
#include "components/lights.hpp"
|
||||
#include "graphics/opengl/buffer.hpp"
|
||||
#include "graphics/opengl/framebuffer.hpp"
|
||||
#include "graphics/opengl/program.hpp"
|
||||
#include "graphics/opengl/vertex_array.hpp"
|
||||
#include "maths/transform.hpp"
|
||||
#include "resources/material.hpp"
|
||||
#include "resources/model.hpp"
|
||||
#include "resources/primitive.hpp"
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <array>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace kuiper
|
||||
{
|
||||
|
||||
namespace gl
|
||||
{
|
||||
static constexpr std::size_t MAX_NUM_LIGHTS = 100;
|
||||
static constexpr std::size_t LIGHT_SSBO_INIT_SIZE = 1000;
|
||||
static constexpr std::uint32_t NUM_CLUSTERS_X = 12;
|
||||
static constexpr std::uint32_t NUM_CLUSTERS_Y = 12;
|
||||
static constexpr std::uint32_t NUM_CLUSTERS_Z = 24;
|
||||
static constexpr std::uint32_t NUM_CLUSTERS = NUM_CLUSTERS_X * NUM_CLUSTERS_Y * NUM_CLUSTERS_Z;
|
||||
static constexpr std::uint32_t LOCAL_SIZE = 128;
|
||||
static constexpr float NEAR_Z_DEPTH = 0.1f;
|
||||
static constexpr float FAR_Z_DEPTH = std::numeric_limits<std::uint16_t>::max();
|
||||
|
||||
struct gl_state {
|
||||
// Vertex & element buffers
|
||||
vertex_array::s_ptr vao {nullptr};
|
||||
buffer::s_ptr vertex_buffer {nullptr};
|
||||
buffer::s_ptr index_buffer {nullptr};
|
||||
|
||||
// Indirect & model matrix buffer
|
||||
|
||||
buffer::s_ptr indirect_buffer {nullptr};
|
||||
buffer::s_ptr matrix_buffer {nullptr};
|
||||
|
||||
// Shaders
|
||||
program::s_ptr pbr_shader {nullptr};
|
||||
program::s_ptr clustering_shader {nullptr};
|
||||
program::s_ptr light_culling_shader {nullptr};
|
||||
|
||||
// Lighting buffers
|
||||
buffer::s_ptr cluster_buffer {nullptr};
|
||||
buffer::s_ptr lights_buffer {nullptr};
|
||||
|
||||
// Configuration
|
||||
std::uint32_t max_texture_units {32};
|
||||
std::vector<std::int32_t> texture_unit_slots {};
|
||||
};
|
||||
|
||||
struct renderer_metrics {
|
||||
std::size_t n_vertices {};
|
||||
std::size_t n_indices {};
|
||||
std::size_t n_draw_cmds {};
|
||||
std::size_t n_matrices {};
|
||||
std::size_t n_materials {};
|
||||
std::size_t n_lights {};
|
||||
};
|
||||
|
||||
class renderer {
|
||||
public:
|
||||
using vertex_t = vertex;
|
||||
using index_t = std::uint32_t;
|
||||
|
||||
struct draw_elements_indirect_cmd {
|
||||
std::uint32_t count {0};
|
||||
std::uint32_t instance_count {0};
|
||||
std::uint32_t first_index {0};
|
||||
std::uint32_t base_vertex {0};
|
||||
std::uint32_t base_instance {0};
|
||||
};
|
||||
|
||||
struct alignas(4) render_matrices {
|
||||
glm::mat4 model_matrix;
|
||||
glm::mat3 normal_matrix;
|
||||
};
|
||||
|
||||
struct alignas(16) cluster {
|
||||
glm::vec4 min_point;
|
||||
glm::vec4 max_point;
|
||||
std::uint32_t count;
|
||||
std::uint32_t light_indices[MAX_NUM_LIGHTS];
|
||||
};
|
||||
|
||||
struct alignas(16) point_light {
|
||||
glm::vec4 position;
|
||||
glm::vec4 colour;
|
||||
float intensity;
|
||||
float radius;
|
||||
};
|
||||
|
||||
private:
|
||||
using vertex_storage_t = std::vector<vertex_t>;
|
||||
using index_storage_t = std::vector<index_t>;
|
||||
using draw_cmd_storage_t = std::vector<draw_elements_indirect_cmd>;
|
||||
using matrix_storage_t = std::vector<render_matrices>;
|
||||
using material_storage_t = std::vector<resource::material>;
|
||||
using light_storage_t = std::vector<point_light>;
|
||||
|
||||
public:
|
||||
renderer(gl_state&& state)
|
||||
: m_state(std::move(state)) {}
|
||||
~renderer() = default;
|
||||
|
||||
renderer(const renderer&) = delete;
|
||||
renderer& operator=(const renderer&) = delete;
|
||||
renderer(renderer&&) noexcept = delete;
|
||||
renderer& operator=(renderer&&) noexcept = delete;
|
||||
|
||||
static renderer init();
|
||||
|
||||
void render(const framebuffer::s_ptr& framebuffer,
|
||||
const glm::vec3& cam_pos,
|
||||
const component::camera_props& cam_props) noexcept;
|
||||
void flush() noexcept;
|
||||
renderer_metrics metrics() const noexcept;
|
||||
|
||||
void draw_model(const resource::model& model, const maths::transform_euler& transform);
|
||||
void draw_mesh(const resource::mesh& mesh,
|
||||
const std::vector<resource::material>& materials,
|
||||
const glm::mat4& transform);
|
||||
void draw_primitive(const resource::primitive& primitive,
|
||||
const resource::material& material,
|
||||
const maths::transform_euler& transform);
|
||||
void draw_primitive(const resource::primitive& primitive,
|
||||
const resource::material& material,
|
||||
const glm::mat4& transform);
|
||||
void add_light(const glm::vec3& pos, const component::point_light& light) noexcept;
|
||||
|
||||
private:
|
||||
void update_and_upload() noexcept;
|
||||
|
||||
private:
|
||||
gl_state m_state {};
|
||||
|
||||
vertex_storage_t m_vertices {};
|
||||
index_storage_t m_indices {};
|
||||
draw_cmd_storage_t m_draw_cmds {};
|
||||
matrix_storage_t m_matrices {};
|
||||
material_storage_t m_materials {};
|
||||
light_storage_t m_lights {};
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} // namespace kuiper
|
||||
Reference in New Issue
Block a user