Files
tanks-reborn/source/render/renderer.hpp

116 lines
3.0 KiB
C++

#ifndef TANKS_RENDER_HPP
#define TANKS_RENDER_HPP
#include "game/model.hpp"
#include "render/context.hpp"
#include "render/shader_compiler.hpp"
#include "ui/display.hpp"
#include "vuk/extra/ImGuiIntegration.hpp"
#include <functional>
#include <limits>
#include <random>
#include <unordered_map>
namespace trb::render {
struct mesh_transforms {
std::uint32_t id;
std::vector<glm::mat4> transforms;
};
struct request {
private:
std::vector<mesh_transforms> meshes = {};
std::optional<mesh_transforms> current_mesh = std::nullopt;
std::vector<std::vector<glm::vec3>> lines;
std::vector<glm::vec3> circles;
public:
request() = default;
request add_mesh(std::uint32_t render_id);
request with_transform(glm::mat4 transform);
request commit();
request add_lines(std::span<const glm::vec3> line_vertices,
glm::vec3 color = glm::vec3(0.0f, 0.0f, 1.0f));
request add_circle(glm::vec2 pos, float radius);
[[nodiscard]] std::span<const mesh_transforms>
requested_meshes() const noexcept;
[[nodiscard]] std::vector<std::span<const glm::vec3>> requested_lines() const;
[[nodiscard]] std::span<const glm::vec3> requested_circles() const;
};
class renderer {
public:
struct loaded_mesh {
vuk::Unique<vuk::Buffer> vertices;
vuk::Unique<vuk::Buffer> indices;
vuk::Unique<vuk::Image> albedo;
vuk::Unique<vuk::ImageView> albedo_view;
glm::mat4 transform;
std::uint32_t index_count;
};
private:
render::shader_compiler compiler =
render::shader_compiler(std::filesystem::path("../assets/shaders"));
render::context context;
std::mt19937_64 rng;
std::uniform_int_distribution<std::uint32_t> id_dist =
std::uniform_int_distribution<std::uint32_t>(
0, std::numeric_limits<std::uint32_t>::max());
std::unordered_map<std::uint32_t, loaded_mesh> registered_meshes;
vuk::extra::ImGuiData imgui_data;
[[nodiscard]] std::uint32_t next_mesh_id();
[[nodiscard]] vuk::PipelineBaseCreateInfo
create_compute_pipeline(std::string_view comp_module,
std::string_view comp_entry);
[[nodiscard]] vuk::PipelineBaseCreateInfo create_graphics_pipeline(
std::string_view vs_module, std::string_view vs_entry,
std::string_view fs_module, std::string_view fs_entry);
[[nodiscard]] vuk::PipelineBaseCreateInfo
create_graphics_pipeline(std::string_view module);
void create_pipelines();
[[nodiscard]] vuk::Value<vuk::ImageAttachment> get_swap_target();
struct vuk_frame_resources {
vuk::Allocator allocator;
vuk::Value<vuk::ImageAttachment> swap_target;
};
[[nodiscard]] vuk_frame_resources get_next_frame_resources();
public:
explicit renderer(ui::display *display);
void render(request req, glm::mat4 view, glm::mat4 projection);
[[nodiscard]] std::uint32_t register_mesh(const game::mesh_node &mesh,
const game::texture_source &albedo);
void do_ui(const std::function<void()> &cb);
};
} // namespace trb::render
#endif