aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2022-08-08 23:38:19 +0200
committerladevieq <ladevie.quentin@gmail.com>2022-08-08 23:38:19 +0200
commitd78200b71b259b87f401b24906385af4e2553fbe (patch)
treea3f50e975303896063f49c069752bd1be774e766
parent45247b737b1527fbeffac2c68a41e71c565d86a8 (diff)
Refactored gltf imported and mesh management
-rw-r--r--.clangd2
-rw-r--r--include/gltf.hpp48
-rw-r--r--include/mesh.hpp93
-rw-r--r--include/primitive-renderpass.hpp4
-rw-r--r--include/scene.hpp3
-rw-r--r--include/vk-renderer.hpp58
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/bvh.cpp6
-rw-r--r--src/gltf.cpp214
-rw-r--r--src/main.cpp394
-rw-r--r--src/mesh.cpp45
-rw-r--r--src/primitive-renderpass.cpp4
-rw-r--r--src/scene.cpp116
-rw-r--r--src/vk-renderer.cpp38
14 files changed, 554 insertions, 472 deletions
diff --git a/.clangd b/.clangd
index 885e6a6..db45fe5 100644
--- a/.clangd
+++ b/.clangd
@@ -2,6 +2,6 @@ Diagnostics:
UnusedIncludes: Strict
ClangTidy:
Add: [performance*, modernize*, readability*, bugprone*]
- Remove: [modernize-avoid-c-arrays, modernize-use-trailing-return-type, readability-identifier-length, readability-uppercase-literal-suffix]
+ Remove: [modernize-avoid-c-arrays, modernize-use-trailing-return-type, readability-identifier-length, readability-uppercase-literal-suffix, readability-braces-around-statements]
InlayHints:
Enabled: Yes
diff --git a/include/gltf.hpp b/include/gltf.hpp
index 66fb6ec..2886dea 100644
--- a/include/gltf.hpp
+++ b/include/gltf.hpp
@@ -2,56 +2,48 @@
#define __GLTF_HPP_
#include <vector>
-#include <optional>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
#include "material.hpp"
-
-struct mesh_part {
- std::vector<uint16_t> indices;
- std::vector<float> positions;
- std::vector<float> normals;
- std::vector<float> uvs;
- material mat;
- uint32_t triangles_count = 0;
- uint32_t vertices_count = 0;
-};
-
-struct mesh {
- std::vector<mesh_part> parts;
- uint32_t triangles_count = 0;
- uint32_t vertices_count = 0;
-};
+#include "mesh.hpp"
struct node {
std::vector<node> children;
- std::optional<mesh> mesh;
+ Mesh* mesh = nullptr;
};
namespace std::filesystem {
class path;
}
-class vkrenderer;
class gltf {
public:
- static node load(std::filesystem::path &path, std::string &filename, vkrenderer &renderer);
+ gltf(const std::filesystem::path &filepath);
+
+ node root_node;
+
+private:
+
+ void load_node(uint32_t index, node &parent);
+
+ void load_meshes();
- private:
- static void load_node(json &gltf_json, uint32_t index, node &parent, std::vector<mesh> &meshes);
+ Mesh::submesh load_primitive(const json &primitive);
- static std::vector<mesh> load_meshes(
- json &gltf_json, std::vector<std::vector<uint8_t>> &buffers_content, std::vector<material> &materials);
+ Mesh::attribute load_attribute(uint32_t accessor_index);
- static std::vector<texture> load_textures(json &gltf_json, std::filesystem::path &path, vkrenderer &renderer);
+ void load_textures(const std::filesystem::path &path);
- static std::vector<material> load_materials(json &gltf_json, std::vector<texture> &textures);
+ void load_materials();
- static mesh_part load_primitive(json &gltf_json, json &primitive,
- std::vector<std::vector<uint8_t>> &buffers_content, std::vector<material> &materials);
+ json gltf_json;
+ std::vector<Mesh> meshes;
+ std::vector<material> materials;
+ std::vector<texture> textures;
+ std::vector<std::vector<uint8_t>> buffers;
};
#endif
diff --git a/include/mesh.hpp b/include/mesh.hpp
new file mode 100644
index 0000000..34f2df8
--- /dev/null
+++ b/include/mesh.hpp
@@ -0,0 +1,93 @@
+#pragma once
+
+#include <cstdint>
+#include <vector>
+#include <array>
+
+#include "vk-renderer.hpp"
+
+enum ATTRIBUTE_TYPE {
+ POSITION,
+ NORMAL,
+ TANGENT,
+ UV_0,
+ MAX_ATTRIBUTE,
+};
+
+struct material;
+
+class Mesh {
+ struct submesh_info {
+ uint32_t vertex_offset;
+ uint32_t index_offset;
+ size_t element_count;
+ uint32_t mat_id;
+ };
+
+public:
+ struct mesh_instance {
+ const Mesh& mesh;
+ // transform a transform matrice for the instance
+ };
+
+ struct attribute {
+ uint8_t* data = nullptr;
+ size_t length = 0;
+ };
+
+ struct submesh {
+ attribute indices;
+ std::array<attribute, ATTRIBUTE_TYPE::MAX_ATTRIBUTE> attributes;
+ uint32_t vertex_count = 0;
+ uint32_t index_count = 0;
+ // material& mat;
+ };
+
+ Mesh() = default;
+
+ [[nodiscard]] mesh_instance instantiate () const;
+
+ void add_submesh(const submesh& submesh);
+
+ static inline uint32_t attribute_components(enum ATTRIBUTE_TYPE attribute_type) {
+ switch(attribute_type) {
+ case ATTRIBUTE_TYPE::POSITION:
+ case ATTRIBUTE_TYPE::NORMAL:
+ return 3;
+ case ATTRIBUTE_TYPE::UV_0:
+ return 2;
+ default:
+ return 0;
+ }
+ }
+
+ static inline size_t attribute_size(enum ATTRIBUTE_TYPE attribute_type) {
+ return sizeof(float) * attribute_components(attribute_type);
+ }
+
+ [[nodiscard]] inline uint32_t triangle_count() const { return index_count / 3; };
+ [[nodiscard]] inline uint32_t vertices_count() const { return vertex_count; };
+
+
+ static void register_mesh(const Mesh& mesh);
+
+private:
+
+ uint32_t vertex_count;
+ uint32_t index_count;
+
+ std::array<std::vector<float>, ATTRIBUTE_TYPE::MAX_ATTRIBUTE> attributes;
+ std::vector<uint16_t> indices;
+
+ std::vector<submesh_info> submeshes;
+
+ struct gpu_mesh {
+ std::array<Buffer*, ATTRIBUTE_TYPE::MAX_ATTRIBUTE> attributes;
+ Buffer* indices;
+ Buffer* submeshes;
+ };
+
+ // allocate gpu mesh upon instanciation
+ // static std::vector<gpu_mesh> gpu_meshes;
+ // static std::vector<transform> instances;
+};
diff --git a/include/primitive-renderpass.hpp b/include/primitive-renderpass.hpp
index 4d90d3c..95562fe 100644
--- a/include/primitive-renderpass.hpp
+++ b/include/primitive-renderpass.hpp
@@ -52,9 +52,7 @@ class PrimitiveRenderpass : public Renderpass {
class Primitive {
public:
- Primitive(vkapi& api, PrimitiveRenderpass& render_pass)
- : api(api), primitive_render_pass(render_pass)
- {};
+ Primitive(PrimitiveRenderpass& render_pass);
void set_pipeline(const char* shader_name);
diff --git a/include/scene.hpp b/include/scene.hpp
index a2db2e8..78b90b7 100644
--- a/include/scene.hpp
+++ b/include/scene.hpp
@@ -6,7 +6,6 @@
#include "camera.hpp"
class Buffer;
-class vkrenderer;
class scene {
struct metadata {
@@ -30,7 +29,7 @@ class scene {
// void random_scene();
public:
- scene(const camera& cam, uint32_t width, uint32_t height, vkrenderer& renderer);
+ scene(const camera& cam, uint32_t width, uint32_t height);
metadata meta;
diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp
index deee33b..827445f 100644
--- a/include/vk-renderer.hpp
+++ b/include/vk-renderer.hpp
@@ -1,6 +1,7 @@
#ifndef __VK_RENDERER_HPP_
#define __VK_RENDERER_HPP_
+#include <cstdint>
#include <vector>
#include "vk-context.hpp"
@@ -31,17 +32,15 @@ class vkrenderer {
void update_image(Texture* texture, void* data);
- void update_buffer(Buffer* buffer, void* data, off_t offset, size_t size);
+ static Buffer* create_buffer(size_t size);
- Buffer* create_buffer(size_t size, bool isStatic);
+ static Buffer* create_index_buffer(size_t size);
- Buffer* create_index_buffer(size_t size, bool isStatic);
+ static Texture* create_2d_texture(size_t width, size_t height, VkFormat format);
- Texture* create_2d_texture(size_t width, size_t height, VkFormat format);
+ static void destroy_2d_texture(Texture* texture);
- void destroy_2d_texture(Texture* texture);
-
- Sampler* create_sampler(VkFilter filter, VkSamplerAddressMode address_mode);
+ static Sampler* create_sampler(VkFilter filter, VkSamplerAddressMode address_mode);
ComputeRenderpass* create_compute_renderpass();
@@ -59,9 +58,9 @@ class vkrenderer {
static constexpr uint32_t virtual_frames_count = 2;
- vkcontext context;
+ static vkcontext context;
- vkapi api;
+ static vkapi api;
private:
@@ -110,15 +109,46 @@ class Sampler {
class Buffer {
public:
- Buffer(size_t size, bool isStatic)
- : size(size), isStatic(isStatic) {}
+ Buffer(size_t size);
+
+ ~Buffer() {
+ vkrenderer::api.destroy_buffer(device_buffer);
+ }
+
+ void write(void* data, off_t alloc_offset, size_t data_size) const {
+ auto api_buffer = vkrenderer::api.get_buffer(device_buffer);
+
+ std::memcpy((uint8_t*)api_buffer.device_ptr + alloc_offset, data, data_size);
+ }
handle device_buffer;
- size_t size;
- size_t element_size;
+ size_t buffer_size;
+};
+
+class RingBuffer {
+ public:
+ RingBuffer(size_t size)
+ : buffer_size(size) {}
+
+ [[nodiscard]]bool alloc(size_t alloc_size) const {
+ return ptr + alloc_size > buffer_size;
+ }
+
+ void write(void* data, off_t alloc_offset, size_t data_size) const {
+ auto api_buffer = vkrenderer::api.get_buffer(device_buffer);
+
+ std::memcpy((uint8_t*)api_buffer.device_ptr + alloc_offset, data, data_size);
+ }
+
+ void reset() {
+ ptr = 0;
+ }
+
+ handle device_buffer;
- bool isStatic;
+ size_t buffer_size;
+ off_t ptr;
};
#endif // !__VK_RENDERER_HPP_
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a890be3..b56a871 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,6 +28,7 @@ add_executable(
compute-renderpass.cpp
primitive-renderpass.cpp
bvh.cpp
+ mesh.cpp
# ${Tracy_SOURCE_DIR}/TracyClient.cpp
)
diff --git a/src/bvh.cpp b/src/bvh.cpp
index 80f141d..9d0b4b8 100644
--- a/src/bvh.cpp
+++ b/src/bvh.cpp
@@ -1,5 +1,7 @@
#include "bvh.hpp"
+#include <cassert>
+
#include <algorithm>
#include <iostream>
@@ -45,6 +47,8 @@
bvh::bvh(std::vector<triangle>& triangles, std::vector<packed_bvh_node>& packed_nodes)
:triangles(triangles) {
+
+ assert(!triangles.empty());
packed_nodes.resize(2 * triangles.size() - 1);
temp_nodes = std::vector<temp_node>(2 * triangles.size() - 1);
leafs = std::vector<temp_node>(triangles.size());
@@ -125,7 +129,7 @@ int32_t bvh::traverse_depth_first_ordered(std::vector<bvh_node>& nodes, int32_t
if (next_id != -1) {
return traverse_depth_first_ordered(nodes, id, next_id);
}
- } else if (nodes[id].primitive_id != -1 && nodes[id].next_id != -1) {
+ } else if (nodes[id].next_id != -1) {
std::cout << "\t " << parent_id << " -> " << id << ";\n";
return nodes[id].next_id;
} else {
diff --git a/src/gltf.cpp b/src/gltf.cpp
index 7c1e26c..8f266f2 100644
--- a/src/gltf.cpp
+++ b/src/gltf.cpp
@@ -1,7 +1,6 @@
#include "gltf.hpp"
#include <fstream>
-#include <cstring>
#include <filesystem>
#define STB_IMAGE_IMPLEMENTATION
@@ -10,110 +9,137 @@
#include "vk-renderer.hpp"
#include "utils.hpp"
-node gltf::load(std::filesystem::path &path, std::string &filename, vkrenderer &renderer) {
- std::fstream f { path / filename };
- json gltf_json;
+gltf::gltf(const std::filesystem::path &filepath) {
+ auto parent_path = filepath.parent_path();
+ std::fstream f { filepath };
f >> gltf_json;
auto& scene = gltf_json["scenes"][0];
- auto &buffers = gltf_json["buffers"];
- auto buffers_content = std::vector<std::vector<uint8_t>>(buffers.size());
- for (size_t buffer_index{0}; buffer_index < buffers.size(); buffer_index++) {
- auto& buffer = buffers[buffer_index];
- auto buffer_path = path / buffer["uri"].get<std::string>();
- buffers_content[buffer_index] = read_file(buffer_path.string().c_str());
+ auto &gltf_buffers = gltf_json["buffers"];
+ buffers.reserve(gltf_buffers.size());
+ for (auto& gltf_buffer : gltf_buffers) {
+ auto buffer_path = parent_path / gltf_buffer["uri"].get<std::string>();
+ buffers.emplace_back(read_file(buffer_path.string().c_str()));
}
- auto textures = load_textures(gltf_json, path, renderer);
- auto materials = load_materials(gltf_json, textures);
+ load_textures(parent_path);
+ load_materials();
- auto meshes = load_meshes(gltf_json, buffers_content, materials);
+ load_meshes();
- node root_node;
auto& root_children = scene["nodes"];
uint32_t root_children_count = scene["nodes"].size();
root_node.children.resize(root_children_count);
for (size_t child_index = 0; child_index < root_children_count; child_index++) {
- load_node(gltf_json, root_children[child_index].get<uint32_t>(), root_node.children[child_index], meshes);
+ load_node(root_children[child_index].get<uint32_t>(), root_node.children[child_index]);
}
f.close();
-
- return root_node;
}
-void gltf::load_node(json &gltf_json, uint32_t index, node &parent, std::vector<mesh> &meshes) {
- auto &gltf_node = gltf_json["nodes"][index];
+void gltf::load_node(uint32_t index, node &parent) {
+ const auto &gltf_node = gltf_json["nodes"][index];
if (gltf_node.contains("children")) {
- auto &children = gltf_node["children"];
+ const auto &children = gltf_node["children"];
uint32_t children_count = gltf_node["children"];
parent.children.resize(children_count);
for (size_t child_index = 0; child_index < children_count; child_index++) {
- load_node(gltf_json, children[child_index].get<uint32_t>(), parent.children[child_index], meshes);
+ load_node(children[child_index].get<uint32_t>(), parent.children[child_index]);
}
}
- if (gltf_node.contains("mesh")) { parent.mesh = std::make_optional(meshes[gltf_node["mesh"].get<uint32_t>()]); }
+ if (gltf_node.contains("mesh")) {
+ parent.mesh = &meshes[gltf_node["mesh"].get<uint32_t>()];
+ }
}
-std::vector<mesh> gltf::load_meshes(
- json &gltf_json, std::vector<std::vector<uint8_t>> &buffers_content, std::vector<material> &materials) {
- auto &gltf_meshes = gltf_json["meshes"];
+void gltf::load_meshes() {
+ const auto &gltf_meshes = gltf_json["meshes"];
auto meshes_count = gltf_meshes.size();
- std::vector<mesh> meshes{meshes_count};
+ meshes.resize(meshes_count);
for (size_t mesh_index = 0; mesh_index < meshes_count; mesh_index++) {
- auto &gltf_mesh = gltf_meshes[mesh_index];
- auto &primitives = gltf_mesh["primitives"];
- auto &mesh = meshes[mesh_index];
+ auto& mesh = meshes[mesh_index];
+ const auto &primitives = gltf_meshes[mesh_index]["primitives"];
- for (auto &primitive : primitives) {
- auto part = load_primitive(gltf_json, primitive, buffers_content, materials);
- mesh.vertices_count += part.vertices_count;
- mesh.triangles_count += part.triangles_count;
- mesh.parts.emplace_back(std::move(part));
+ for (const auto &primitive : primitives) {
+ mesh.add_submesh(load_primitive(primitive));
}
+
+ Mesh::register_mesh(mesh);
+ }
+}
+
+Mesh::submesh gltf::load_primitive(const json &primitive) {
+ Mesh::submesh submesh;
+
+ submesh.indices = load_attribute(primitive["indices"]);
+ submesh.attributes[ATTRIBUTE_TYPE::POSITION] = load_attribute(primitive["attributes"]["POSITION"]);
+
+ if (primitive["attributes"].contains("NORMAL")) {
+ submesh.attributes[ATTRIBUTE_TYPE::POSITION] = load_attribute(primitive["attributes"]["NORMAL"]);
+ }
+
+ if (primitive["attributes"].contains("TEXCOORD_0")) {
+ submesh.attributes[ATTRIBUTE_TYPE::POSITION] = load_attribute(primitive["attributes"]["TEXCOORD_0"]);
}
- return meshes;
+ submesh.index_count = gltf_json["accessors"][primitive["indices"].get<uint32_t>()]["count"].get<uint32_t>();
+ submesh.vertex_count = gltf_json["accessors"][primitive["attributes"]["POSITION"].get<uint32_t>()]["count"].get<uint32_t>();
+ // submesh.mat = materials[gltf_primitive["material"].get<uint32_t>()];
+
+ return submesh;
}
-std::vector<texture> gltf::load_textures(json &gltf_json, std::filesystem::path &path, vkrenderer &renderer) {
- auto &gltf_images = gltf_json["images"];
+Mesh::attribute gltf::load_attribute(uint32_t accessor_index) {
+ auto view_index = gltf_json["accessors"][accessor_index]["bufferView"].get<uint32_t>();
+ const auto &view = gltf_json["bufferViews"][view_index];
+ auto offset = view["byteOffset"].get<off_t>();
+ auto &buffer = buffers[view["buffer"].get<uint32_t>()];
+
+ return {
+ &buffer[offset],
+ view["byteLength"].get<size_t>()
+ };
+}
+
+void gltf::load_textures(const std::filesystem::path &path) {
+ const auto &gltf_images = gltf_json["images"];
auto images_count = gltf_images.size();
std::vector<Texture *> images{images_count};
for (size_t image_index = 0; image_index < images_count; image_index++) {
- auto &gltf_image = gltf_images[image_index];
- int x, y, n;
+ const auto &gltf_image = gltf_images[image_index];
+ int x;
+ int y;
+ int n;
auto filepath = (path / gltf_image["uri"].get<std::string>()).string();
unsigned char *data = stbi_load(filepath.c_str(), &x, &y, &n, 4);
- auto *img = renderer.create_2d_texture(static_cast<uint32_t>(x), static_cast<uint32_t>(y), VK_FORMAT_R8G8B8A8_UNORM);
+ auto *img = vkrenderer::create_2d_texture(static_cast<uint32_t>(x), static_cast<uint32_t>(y), VK_FORMAT_R8G8B8A8_UNORM);
- renderer.update_image(img, data);
+ // renderer.update_image(img, data);
stbi_image_free(data);
images[image_index] = img;
}
- auto &gltf_samplers = gltf_json["samplers"];
+ const auto &gltf_samplers = gltf_json["samplers"];
auto samplers_count = gltf_samplers.size();
std::vector<Sampler *> samplers{samplers_count};
for (size_t sampler_index = 0; sampler_index < samplers_count; sampler_index++) {
- samplers[sampler_index] = renderer.create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT);
+ samplers[sampler_index] = vkrenderer::create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT);
}
- auto& api = renderer.api;
- auto &gltf_textures = gltf_json["textures"];
+ const auto &gltf_textures = gltf_json["textures"];
auto textures_count = gltf_textures.size();
- std::vector<texture> textures{textures_count};
+ textures.resize(textures_count);
for (size_t texture_index = 0; texture_index < textures_count; texture_index++) {
auto gltf_texture = gltf_textures[texture_index];
@@ -121,35 +147,33 @@ std::vector<texture> gltf::load_textures(json &gltf_json, std::filesystem::path
auto image_index = gltf_texture["source"].get<uint32_t>();
auto &image = images[image_index];
- uint32_t image_id = api.get_image(image->device_image).bindless_sampled_index;
+ uint32_t image_id = vkrenderer::api.get_image(image->device_image).bindless_sampled_index;
uint32_t sampler_id = 0;
if (gltf_texture.contains("sampler")) {
auto sampler_index = gltf_texture["sampler"].get<uint32_t>();
auto &sampler = samplers[sampler_index];
- sampler_id = api.get_sampler(sampler->device_sampler).bindless_index;
+ sampler_id = vkrenderer::api.get_sampler(sampler->device_sampler).bindless_index;
}
textures[texture_index] =
texture{.image_id = image_id, .sampler_id = sampler_id};
}
-
- return textures;
}
-std::vector<material> gltf::load_materials(json &gltf_json, std::vector<texture> &textures) {
- auto &gltf_materials = gltf_json["materials"];
+void gltf::load_materials() {
+ const auto &gltf_materials = gltf_json["materials"];
auto materials_count = gltf_materials.size();
- std::vector<material> materials{materials_count};
+ materials.resize(materials_count);
for (size_t material_index = 0; material_index < materials_count; material_index++) {
- auto &gltf_material = gltf_materials[material_index];
+ const auto &gltf_material = gltf_materials[material_index];
auto &material = materials[material_index];
if (gltf_material.contains("pbrMetallicRoughness")) {
- auto &pbr_params = gltf_material["pbrMetallicRoughness"];
+ const auto &pbr_params = gltf_material["pbrMetallicRoughness"];
if (pbr_params.contains("baseColorFactor")) {
- auto &base_color = pbr_params["baseColorFactor"];
+ const auto &base_color = pbr_params["baseColorFactor"];
material.base_color.v[0] = base_color[0].get<float>();
material.base_color.v[1] = base_color[1].get<float>();
material.base_color.v[2] = base_color[2].get<float>();
@@ -181,82 +205,4 @@ std::vector<material> gltf::load_materials(json &gltf_json, std::vector<texture>
}
}
}
-
- return materials;
-}
-
-mesh_part gltf::load_primitive(json &gltf_json, json &primitive, std::vector<std::vector<uint8_t>> &buffers_content,
- std::vector<material> &materials) {
- auto part = mesh_part();
- auto &accessors = gltf_json["accessors"];
-
- {
- auto indices_accessor_index = primitive["indices"].get<uint32_t>();
- auto indices_view_index = accessors[indices_accessor_index]["bufferView"].get<uint32_t>();
- auto &indices_view = gltf_json["bufferViews"][indices_view_index];
-
- auto indices_buffer_index = indices_view["buffer"].get<uint32_t>();
- auto indices_offset = indices_view["byteOffset"].get<size_t>();
- auto indices_length = indices_view["byteLength"].get<size_t>();
-
- auto &indices_buffer = buffers_content[indices_buffer_index];
- auto *indices_start = reinterpret_cast<uint16_t *>(indices_buffer.data() + indices_offset);
-
- part.indices.resize(indices_length / sizeof(uint16_t));
- std::memcpy(part.indices.data(), indices_start, indices_length);
- }
-
- {
- auto positions_accessor_index = primitive["attributes"]["POSITION"].get<uint32_t>();
- auto positions_view_index = accessors[positions_accessor_index]["bufferView"].get<uint32_t>();
- auto &positions_view = gltf_json["bufferViews"][positions_view_index];
-
- auto positions_buffer_index = positions_view["buffer"].get<uint32_t>();
- auto positions_offset = positions_view["byteOffset"].get<size_t>();
- auto positions_length = positions_view["byteLength"].get<size_t>();
-
- auto &positions_buffer = buffers_content[positions_buffer_index];
- auto *positions_start = reinterpret_cast<float *>(positions_buffer.data() + positions_offset);
-
- part.positions.resize(positions_length / sizeof(float));
- std::memcpy(part.positions.data(), positions_start, positions_length);
- }
-
- {
- auto normals_accessor_index = primitive["attributes"]["NORMAL"].get<uint32_t>();
- auto normals_view_index = accessors[normals_accessor_index]["bufferView"].get<uint32_t>();
- auto &normals_view = gltf_json["bufferViews"][normals_view_index];
-
- auto normals_buffer_index = normals_view["buffer"].get<uint32_t>();
- auto normals_offset = normals_view["byteOffset"].get<size_t>();
- auto normals_length = normals_view["byteLength"].get<size_t>();
-
- auto &normals_buffer = buffers_content[normals_buffer_index];
- auto *normals_start = reinterpret_cast<float *>(normals_buffer.data() + normals_offset);
-
- part.normals.resize(normals_length / sizeof(float));
- std::memcpy(part.normals.data(), normals_start, normals_length);
- }
-
- {
- auto uvs_accessor_index = primitive["attributes"]["TEXCOORD_0"].get<uint32_t>();
- auto uvs_view_index = accessors[uvs_accessor_index]["bufferView"].get<uint32_t>();
- auto &uvs_view = gltf_json["bufferViews"][uvs_view_index];
-
- auto uvs_buffer_index = uvs_view["buffer"].get<uint32_t>();
- auto uvs_offset = uvs_view["byteOffset"].get<size_t>();
- auto uvs_length = uvs_view["byteLength"].get<size_t>();
-
- auto &uvs_buffer = buffers_content[uvs_buffer_index];
- auto *uvs_start = reinterpret_cast<float *>(uvs_buffer.data() + uvs_offset);
-
- part.uvs.resize(uvs_length / sizeof(float));
- std::memcpy(part.uvs.data(), uvs_start, uvs_length);
- }
-
- part.mat = materials[primitive["material"].get<uint32_t>()];
- part.vertices_count = part.positions.size() / 3;
- part.triangles_count = part.indices.size() / 3;
-
- return part;
}
diff --git a/src/main.cpp b/src/main.cpp
index 1d7a2ae..2f53dd6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -30,8 +30,152 @@ struct VkVertex {
uint32_t padding[3];
};
-int main() {
-#ifdef ENABLE_RENDERDOC
+void update_ui(scene& main_scene, float delta_time) {
+ ImGui::NewFrame();
+
+ ImGui::SetNextWindowPos({0.f, 0.f});
+ ImGui::SetNextWindowSize({0.f, 0.f});
+ ImGui::Begin("Debug", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar);
+
+ ImGui::Text("frame per second %u\n", static_cast<uint32_t>(1000.f / delta_time));
+ ImGui::Text("frame time %f ms\n", delta_time);
+ ImGui::Text("frame count %u\n", main_scene.meta.sample_index);
+
+ if (ImGui::Checkbox("depth of field", (bool*)&main_scene.meta.enable_dof)) {
+ main_scene.meta.sample_index = 1;
+ }
+
+ ImGui::SliderInt("max bounces", (int32_t *)&main_scene.meta.max_bounce, 1, 250);
+ ImGui::SliderInt("min bounces", (int32_t *)&main_scene.meta.min_bounce, 1, main_scene.meta.max_bounce);
+ if (ImGui::SliderInt("downscale factor", (int32_t *)&main_scene.meta.downscale_factor, 1, 32)) {
+ main_scene.meta.sample_index = 1;
+ }
+
+ if (ImGui::Checkbox("debug bvh", (bool *)&main_scene.meta.debug_bvh)) {
+ main_scene.meta.sample_index = 1;
+ }
+
+ ImGui::End();
+ bool open = true;
+ ImGui::ShowDemoWindow(&open);
+
+ ImGui::EndFrame();
+
+ ImGui::Render();
+}
+
+void render(scene& main_scene, vkrenderer& renderer) {
+ // To start a frame capture, call StartFrameCapture.
+ // You can specify NULL, NULL for the device to capture on if you have only
+ // one device and either no windows at all or only one window, and it will
+ // capture from that device. See the documentation below for a longer
+ // explanation if(rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL);
+
+ main_scene.scene_buffer->write(&main_scene.meta, 0, sizeof(main_scene.meta));
+
+
+ // ImDrawData* draw_data = ImGui::GetDrawData();
+
+ // ui_pass->set_viewport(0.f, 0.f, (float)draw_data->DisplaySize.x, (float)draw_data->DisplaySize.y);
+
+ // auto previous_size = ui_primitives.size();
+ // auto commands_count = 0U;
+
+ // for (int32_t draw_list_index = 0; draw_list_index < draw_data->CmdListsCount; draw_list_index++) {
+ // commands_count += draw_data->CmdLists[draw_list_index]->CmdBuffer.size();
+ // }
+
+ // if (ui_primitives.size() < commands_count) {
+ // ui_primitives.resize(commands_count);
+
+ // for (size_t index = previous_size; index < ui_primitives.size(); index++) {
+ // ui_primitives[index] = renderer.create_primitive(*ui_pass);
+ // ui_primitives[index]->set_pipeline(ui_shader_name);
+ // ui_primitives[index]->set_constant_offset(64);
+ // ui_primitives[index]->set_constant(32, ui_texture);
+ // ui_primitives[index]->set_constant(36, ui_texture_sampler);
+ // }
+ // }
+
+ // float scale[] {
+ // 2.f / draw_data->DisplaySize.x,
+ // 2.f / draw_data->DisplaySize.y,
+ // };
+ // float translate[] {
+ // -1.f - draw_data->DisplayPos.x * (2.f / draw_data->DisplaySize.x),
+ // -1.f - draw_data->DisplayPos.y * (2.f / draw_data->DisplaySize.y),
+ // };
+
+ // if (!ui_vertex_buffer || ui_vertex_buffer->size < draw_data->TotalVtxCount * sizeof(VkVertex)) {
+ // ui_vertex_buffer = renderer.create_buffer(draw_data->TotalVtxCount * sizeof(VkVertex), false);
+
+ // for (auto& primitive : ui_primitives) {
+ // primitive->set_constant(0, ui_vertex_buffer);
+ // }
+ // }
+
+ // if (!ui_index_buffer || ui_index_buffer->size < draw_data->TotalIdxCount * sizeof(ImDrawIdx)) {
+ // ui_index_buffer = renderer.create_index_buffer(draw_data->TotalIdxCount * sizeof(ImDrawIdx), false);
+
+ // for (auto& primitive : ui_primitives) {
+ // primitive->set_index_buffer(ui_index_buffer);
+ // }
+ // }
+
+ // off_t vertex_buffer_offset = 0;
+ // off_t index_buffer_offset = 0;
+ // std::vector<VkVertex> vertices;
+ // uint32_t draw_call_index = 0;
+ // for (int32_t draw_list_index = 0; draw_list_index < draw_data->CmdListsCount; draw_list_index++) {
+ // auto& vertex_buffer = draw_data->CmdLists[draw_list_index]->VtxBuffer;
+ // auto& index_buffer = draw_data->CmdLists[draw_list_index]->IdxBuffer;
+ // vertices.resize(vertex_buffer.size());
+
+ // for (int32_t vert_index = 0; vert_index < vertex_buffer.Size; vert_index++) {
+ // vertices[vert_index] = *((VkVertex*)&vertex_buffer[vert_index]);
+ // }
+
+ // renderer.update_buffer(ui_vertex_buffer, vertices.data(), vertex_buffer_offset * sizeof(VkVertex), vertices.size() * sizeof(VkVertex));
+ // renderer.update_buffer(ui_index_buffer, index_buffer.Data, index_buffer_offset * sizeof(ImDrawIdx), index_buffer.size() * sizeof(ImDrawIdx));
+
+ // ImDrawList* draw_list = draw_data->CmdLists[draw_list_index];
+ // for (auto& draw_cmd: draw_list->CmdBuffer) {
+ // auto& current_primitive = ui_primitives[draw_call_index];
+ // current_primitive->set_constant(8, (uint64_t*)&scale);
+ // current_primitive->set_constant(16, (uint64_t*)&translate);
+
+ // ImVec2 pos = draw_data->DisplayPos;
+ // current_primitive->set_scissor(
+ // (int32_t)draw_cmd.ClipRect.x - pos.x,
+ // (int32_t)draw_cmd.ClipRect.y - pos.y,
+ // (uint32_t)draw_cmd.ClipRect.z - pos.x,
+ // (uint32_t)draw_cmd.ClipRect.w - pos.y
+ // );
+
+ // current_primitive->set_draw_info(
+ // draw_cmd.ElemCount,
+ // index_buffer_offset + draw_cmd.IdxOffset,
+ // vertex_buffer_offset + draw_cmd.VtxOffset
+ // );
+
+ // ui_pass->add_primitive(current_primitive);
+ // draw_call_index++;
+ // }
+
+ // vertex_buffer_offset += vertex_buffer.Size;
+ // index_buffer_offset += index_buffer.Size;
+ // }
+
+ // ui_pass->set_color_attachment(0, renderer.back_buffer());
+
+ renderer.render();
+
+ main_scene.meta.sample_index++;
+}
+
+
+#if defined(ENABLE_RENDERDOC)
+RENDERDOC_API_1_1_2 enable_renderdoc() {
RENDERDOC_API_1_1_2 *rdoc_api = nullptr;
#ifdef WINDOWS
@@ -52,7 +196,16 @@ int main() {
assert(ret == 1);
}
#endif
-#endif // ENABLE_RENDERDOC
+
+ return rdoc_api;
+}
+#endif
+
+int main() {
+
+#if defined(ENABLE_RENDERDOC)
+ auto* rdoc_api = enable_renderdoc();
+#endif
const float aspect_ratio = 16.0 / 9.0;
const auto width = 400;
@@ -70,14 +223,15 @@ int main() {
const auto v_fov = 90.f;
const auto aperture = 0.1f;
const auto focus_distance = 10.f;
- auto cam = camera(position, target, v_fov, aspect_ratio, aperture, focus_distance);
vkrenderer renderer { wnd };
ImGui::CreateContext();
ImGuiIO &io = ImGui::GetIO();
+ io.DisplaySize.x = (float)width;
+ io.DisplaySize.y = (float)height;
- auto main_scene = scene(cam, width, height, renderer);
+ auto main_scene = scene(camera(position, target, v_fov, aspect_ratio, aperture, focus_distance), width, height);
auto *raytracing_pass = renderer.create_compute_renderpass();
raytracing_pass->set_pipeline("compute");
@@ -106,8 +260,9 @@ int main() {
raytracing_pass->set_pipeline("compute");
});
- auto *accumulation_texture = renderer.create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
- auto *output_texture = renderer.create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
+ auto *accumulation_texture = vkrenderer::create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
+ auto *output_texture = vkrenderer::create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
+ raytracing_pass->set_constant(0, main_scene.scene_buffer);
raytracing_pass->set_constant(8, main_scene.bvh_buffer);
raytracing_pass->set_constant(16, main_scene.indices_buffer);
raytracing_pass->set_constant(24, main_scene.positions_buffer);
@@ -116,29 +271,27 @@ int main() {
raytracing_pass->set_constant(48, main_scene.materials_buffer);
raytracing_pass->set_dispatch_size(width / 8 + 1, height / 8 + 1, 1);
- uint8_t *pixels = nullptr;
- int atlas_width, atlas_height;
- io.Fonts->GetTexDataAsRGBA32(&pixels, &atlas_width, &atlas_height);
- auto *ui_texture = renderer.create_2d_texture(atlas_width, atlas_height, VK_FORMAT_R8G8B8A8_UNORM);
- io.Fonts->SetTexID((void *)&ui_texture);
+ // uint8_t *pixels = nullptr;
+ // int atlas_width, atlas_height;
+ // io.Fonts->GetTexDataAsRGBA32(&pixels, &atlas_width, &atlas_height);
+ // auto *ui_texture = renderer.create_2d_texture(atlas_width, atlas_height, VK_FORMAT_R8G8B8A8_UNORM);
+ // io.Fonts->SetTexID((void *)&ui_texture);
- renderer.update_image(ui_texture, pixels);
- auto ui_texture_sampler = renderer.create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
+ // renderer.update_image(ui_texture, pixels);
+ // auto ui_texture_sampler = renderer.create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
- Buffer* ui_vertex_buffer = nullptr;
- Buffer* ui_index_buffer = nullptr;
+ // Buffer* ui_vertex_buffer = nullptr;
+ // Buffer* ui_index_buffer = nullptr;
- std::vector<Primitive*> ui_primitives;
- auto ui_pass = renderer.create_primitive_renderpass();
- ui_pass->set_viewport(0.f, 0.f, (float)width, (float)height);
- ui_pass->add_color_attachment(renderer.back_buffer_format());
- ui_pass->finalize_render_pass();
+ // const char* ui_shader_name = "ui";
+ // std::vector<Primitive*> ui_primitives;
+ // auto ui_pass = renderer.create_primitive_renderpass();
+ // ui_pass->set_viewport(0.f, 0.f, (float)width, (float)height);
+ // ui_pass->add_color_attachment(renderer.back_buffer_format());
+ // ui_pass->finalize_render_pass();
auto can_render = true;
- io.DisplaySize.x = (float)width;
- io.DisplaySize.y = (float)height;
-
while (wnd.isOpen) {
end = std::chrono::high_resolution_clock::now();
@@ -168,10 +321,10 @@ int main() {
renderer.recreate_swapchain();
main_scene.meta.cam.set_aspect_ratio((float)event.width / (float)event.height);
- renderer.destroy_2d_texture(accumulation_texture);
- renderer.destroy_2d_texture(output_texture);
- accumulation_texture = renderer.create_2d_texture(event.width, event.height, VK_FORMAT_R32G32B32A32_SFLOAT);
- output_texture = renderer.create_2d_texture(event.width, event.height, VK_FORMAT_R32G32B32A32_SFLOAT);
+ vkrenderer::destroy_2d_texture(accumulation_texture);
+ vkrenderer::destroy_2d_texture(output_texture);
+ accumulation_texture = vkrenderer::create_2d_texture(event.width, event.height, VK_FORMAT_R32G32B32A32_SFLOAT);
+ output_texture = vkrenderer::create_2d_texture(event.width, event.height, VK_FORMAT_R32G32B32A32_SFLOAT);
raytracing_pass->set_dispatch_size(event.width / 8 + 1, event.height / 8 + 1, 1);
}
@@ -252,194 +405,17 @@ int main() {
wnd.events.clear();
- // GUI
- ImGui::NewFrame();
-
- ImGui::SetNextWindowPos({0.f, 0.f});
- ImGui::SetNextWindowSize({0.f, 0.f});
- ImGui::Begin("Debug", nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar);
-
- ImGui::Text("frame per second %u\n", static_cast<uint32_t>(1000.f / delta_time));
- ImGui::Text("frame time %f ms\n", delta_time);
- ImGui::Text("frame count %u\n", main_scene.meta.sample_index);
-
- if (ImGui::Checkbox("depth of field", (bool *)&main_scene.meta.enable_dof)) {
- main_scene.meta.sample_index = 1;
- }
-
- ImGui::SliderInt("max bounces", (int32_t *)&main_scene.meta.max_bounce, 1, 250);
- ImGui::SliderInt("min bounces", (int32_t *)&main_scene.meta.min_bounce, 1, main_scene.meta.max_bounce);
- if (ImGui::SliderInt("downscale factor", (int32_t *)&main_scene.meta.downscale_factor, 1, 32)) {
- main_scene.meta.sample_index = 1;
- }
-
- if (ImGui::Checkbox("debug bvh", (bool *)&main_scene.meta.debug_bvh)) { main_scene.meta.sample_index = 1; }
+ raytracing_pass->set_ouput_texture(output_texture);
+ raytracing_pass->set_constant(60, accumulation_texture);
- ImGui::End();
-
- ImGui::EndFrame();
-
- // To start a frame capture, call StartFrameCapture.
- // You can specify NULL, NULL for the device to capture on if you have only one device and
- // either no windows at all or only one window, and it will capture from that device.
- // See the documentation below for a longer explanation
- // if(rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL);
-
- // renderer.ui();
+ update_ui(main_scene, delta_time);
if (can_render) {
- ImGui::NewFrame();
-
- // ImGui::SetNextWindowPos({0.f, 0.f});
- // ImGui::SetNextWindowSize({0.f, 0.f});
- // ImGui::Begin("Debug", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar);
-
- // ImGui::Text("frame per second %u\n", static_cast<uint32_t>(1000.f / delta_time));
- // ImGui::Text("frame time %f ms\n", delta_time);
- // ImGui::Text("frame count %u\n", main_scene.meta.sample_index);
-
- // if (ImGui::Checkbox("depth of field", (bool*)&main_scene.meta.enable_dof)) {
- // main_scene.meta.sample_index = 1;
- // }
-
- // ImGui::SliderInt("max bounces", (int32_t *)&main_scene.meta.max_bounce, 1, 250);
- // ImGui::SliderInt("min bounces", (int32_t *)&main_scene.meta.min_bounce, 1, main_scene.meta.max_bounce);
- // if (ImGui::SliderInt("downscale factor", (int32_t *)&main_scene.meta.downscale_factor, 1, 32)) {
- // main_scene.meta.sample_index = 1;
- // }
-
- // if (ImGui::Checkbox("debug bvh", (bool *)&main_scene.meta.debug_bvh)) {
- // main_scene.meta.sample_index = 1;
- // }
-
- // ImGui::End();
- bool open = true;
- ImGui::ShowDemoWindow(&open);
-
- ImGui::EndFrame();
-
- ImGui::Render();
-
- // To start a frame capture, call StartFrameCapture.
- // You can specify NULL, NULL for the device to capture on if you have only
- // one device and either no windows at all or only one window, and it will
- // capture from that device. See the documentation below for a longer
- // explanation if(rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL);
-
- renderer.update_buffer(main_scene.scene_buffer, &main_scene.meta, 0, sizeof(main_scene.meta));
-
- raytracing_pass->set_ouput_texture(output_texture);
- raytracing_pass->set_constant(0, main_scene.scene_buffer);
- raytracing_pass->set_constant(60, accumulation_texture);
-
-
- ImDrawData* draw_data = ImGui::GetDrawData();
-
- ui_pass->set_viewport(0.f, 0.f, (float)draw_data->DisplaySize.x, (float)draw_data->DisplaySize.y);
-
- auto previous_size = ui_primitives.size();
- auto commands_count = 0U;
-
- for (int32_t draw_list_index = 0; draw_list_index < draw_data->CmdListsCount; draw_list_index++) {
- commands_count += draw_data->CmdLists[draw_list_index]->CmdBuffer.size();
- }
-
- if (ui_primitives.size() < commands_count) {
- ui_primitives.resize(commands_count);
-
- for (size_t index = previous_size; index < ui_primitives.size(); index++) {
- ui_primitives[index] = renderer.create_primitive(*ui_pass);
- ui_primitives[index]->set_pipeline("ui");
- ui_primitives[index]->set_constant_offset(64);
- ui_primitives[index]->set_constant(32, ui_texture);
- ui_primitives[index]->set_constant(36, ui_texture_sampler);
- }
- }
-
- float scale[] {
- 2.f / draw_data->DisplaySize.x,
- 2.f / draw_data->DisplaySize.y,
- };
- float translate[] {
- -1.f - draw_data->DisplayPos.x * (2.f / draw_data->DisplaySize.x),
- -1.f - draw_data->DisplayPos.y * (2.f / draw_data->DisplaySize.y),
- };
-
- if (!ui_vertex_buffer || ui_vertex_buffer->size < draw_data->TotalVtxCount * sizeof(VkVertex)) {
- ui_vertex_buffer = renderer.create_buffer(draw_data->TotalVtxCount * sizeof(VkVertex), false);
-
- for (auto& primitive : ui_primitives) {
- primitive->set_constant(0, ui_vertex_buffer);
- }
- }
-
- if (!ui_index_buffer || ui_index_buffer->size < draw_data->TotalIdxCount * sizeof(ImDrawIdx)) {
- ui_index_buffer = renderer.create_index_buffer(draw_data->TotalIdxCount * sizeof(ImDrawIdx), false);
-
- for (auto& primitive : ui_primitives) {
- primitive->set_index_buffer(ui_index_buffer);
- }
- }
-
- off_t vertex_buffer_offset = 0;
- off_t index_buffer_offset = 0;
- std::vector<VkVertex> vertices;
- uint32_t draw_call_index = 0;
- for (int32_t draw_list_index = 0; draw_list_index < draw_data->CmdListsCount; draw_list_index++) {
- auto& vertex_buffer = draw_data->CmdLists[draw_list_index]->VtxBuffer;
- auto& index_buffer = draw_data->CmdLists[draw_list_index]->IdxBuffer;
- vertices.resize(vertex_buffer.size());
-
- for (int32_t vert_index = 0; vert_index < vertex_buffer.Size; vert_index++) {
- vertices[vert_index] = *((VkVertex*)&vertex_buffer[vert_index]);
- }
-
- renderer.update_buffer(ui_vertex_buffer, vertices.data(), vertex_buffer_offset * sizeof(VkVertex), vertices.size() * sizeof(VkVertex));
- renderer.update_buffer(ui_index_buffer, index_buffer.Data, index_buffer_offset * sizeof(ImDrawIdx), index_buffer.size() * sizeof(ImDrawIdx));
-
- ImDrawList* draw_list = draw_data->CmdLists[draw_list_index];
- for (auto& draw_cmd: draw_list->CmdBuffer) {
- auto& current_primitive = ui_primitives[draw_call_index];
- current_primitive->set_constant(8, reinterpret_cast<uint64_t*>(&scale));
- current_primitive->set_constant(16, reinterpret_cast<uint64_t*>(&translate));
-
- ImVec2 pos = draw_data->DisplayPos;
- current_primitive->set_scissor(
- (int32_t)draw_cmd.ClipRect.x - pos.x,
- (int32_t)draw_cmd.ClipRect.y - pos.y,
- (uint32_t)draw_cmd.ClipRect.z - pos.x,
- (uint32_t)draw_cmd.ClipRect.w - pos.y
- );
-
- current_primitive->set_draw_info(
- draw_cmd.ElemCount,
- index_buffer_offset + draw_cmd.IdxOffset,
- vertex_buffer_offset + draw_cmd.VtxOffset
- );
-
- ui_pass->add_primitive(current_primitive);
- draw_call_index++;
- }
-
- vertex_buffer_offset += vertex_buffer.Size;
- index_buffer_offset += index_buffer.Size;
- }
-
- renderer.begin_frame();
-
- ui_pass->set_color_attachment(0, renderer.back_buffer());
-
- renderer.render();
- renderer.finish_frame();
-
- main_scene.meta.sample_index++;
+ render(main_scene, renderer);
std::swap(output_texture, accumulation_texture);
}
- // stop the capture
- // if(rdoc_api) rdoc_api->EndFrameCapture(NULL, NULL);
-
frame_count++;
}
diff --git a/src/mesh.cpp b/src/mesh.cpp
new file mode 100644
index 0000000..c9b5358
--- /dev/null
+++ b/src/mesh.cpp
@@ -0,0 +1,45 @@
+#include "mesh.hpp"
+
+static std::vector<Mesh> meshes {};
+
+void Mesh::add_submesh(const submesh& submesh) {
+ auto position_components = attribute_components(ATTRIBUTE_TYPE::POSITION);
+ submeshes.emplace_back(submesh_info {
+ (uint32_t)attributes[ATTRIBUTE_TYPE::POSITION].size() / position_components,
+ (uint32_t)indices.size(),
+ submesh.index_count,
+ 0
+ });
+
+ {
+ auto indices_off = indices.size();
+ indices.resize(indices_off + submesh.index_count);
+ std::memcpy(&indices[indices_off], submesh.indices.data, submesh.indices.length);
+ }
+
+ for (uint32_t attribute_index { ATTRIBUTE_TYPE::POSITION }; attribute_index < ATTRIBUTE_TYPE::MAX_ATTRIBUTE; attribute_index++) {
+ const auto& submesh_attribute = submesh.attributes[attribute_index];
+ if (submesh_attribute.data == nullptr) continue;
+
+ auto& mesh_attribute = attributes[attribute_index];
+ auto attribute_off = mesh_attribute.size();
+ auto element_components = attribute_components(static_cast<ATTRIBUTE_TYPE>(attribute_index));
+ auto elements_count = submesh.vertex_count * element_components;
+
+ mesh_attribute.resize(attribute_off + elements_count);
+ std::memcpy(&mesh_attribute[attribute_off], submesh_attribute.data, submesh_attribute.length);
+ }
+
+ vertex_count += submesh.vertex_count;
+ index_count += submesh.index_count;
+}
+
+[[nodiscard]] Mesh::mesh_instance Mesh::instantiate () const {
+ return {
+ *this
+ };
+}
+
+void Mesh::register_mesh(const Mesh& mesh) {
+ meshes.emplace_back(mesh);
+}
diff --git a/src/primitive-renderpass.cpp b/src/primitive-renderpass.cpp
index acedcdf..316cf6d 100644
--- a/src/primitive-renderpass.cpp
+++ b/src/primitive-renderpass.cpp
@@ -3,6 +3,10 @@
#include "vulkan-loader.hpp"
+Primitive::Primitive(PrimitiveRenderpass& render_pass)
+ : api(vkrenderer::api), primitive_render_pass(render_pass)
+ {};
+
void Primitive::set_pipeline(const char* shader_name) {
std::vector<VkDynamicState> dynamic_states {
VK_DYNAMIC_STATE_VIEWPORT,
diff --git a/src/scene.cpp b/src/scene.cpp
index dc6c8a1..990e00e 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -61,7 +61,7 @@
scene::metadata::metadata(const camera &cam, uint32_t width, uint32_t height)
: cam(cam), width(width), height(height) {}
-scene::scene(const camera& cam, uint32_t width, uint32_t height, vkrenderer& renderer)
+scene::scene(const camera& cam, uint32_t width, uint32_t height)
:meta(cam, width, height){
// Geometry & BVH
@@ -72,89 +72,85 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height, vkrenderer& ren
std::vector<material> materials;
std::vector<packed_bvh_node> packed_nodes;
- // auto bistro_interior_path = std::filesystem::path("../models/BistroInterior");
- // auto bistro_interior_filename = std::string("BistroInterior.gltf");
- // auto root_node = gltf::load(bistro_interior_path, bistro_interior_filename, renderer);
-
- auto sponza_path = std::filesystem::path("../models/sponza");
- auto sponza_filename = std::string("Sponza.gltf");
- auto root_node = gltf::load(sponza_path, sponza_filename, renderer);
+ // auto root_node = gltf::load("../models/BistroInterior", "BistroInterior.gltf");
+ auto model = gltf("../models/sponza/Sponza.gltf");
std::vector<triangle> triangles;
- size_t triangles_offset = 0;
- size_t vertices_offset = 0;
- std::queue<node> nodes_to_load {};
- nodes_to_load.push(root_node);
+ // size_t triangles_offset = 0;
+ // size_t vertices_offset = 0;
+ // std::queue<node> nodes_to_load {};
+ // nodes_to_load.push(model.root_node);
- while(!nodes_to_load.empty()) {
- auto &node = nodes_to_load.front();
+ // while(!nodes_to_load.empty()) {
+ // auto &node = nodes_to_load.front();
- if (node.mesh) {
- auto &mesh = node.mesh.value();
+ // if (node.mesh != nullptr) {
+ // auto &mesh = node.mesh.value();
- indices.resize(indices.size() + (size_t)mesh.triangles_count * 3);
- positions.resize(positions.size() + (size_t)mesh.vertices_count * 3);
- normals.resize(normals.size() + (size_t)mesh.vertices_count * 3);
- uvs.resize(uvs.size() + (size_t)mesh.vertices_count * 2);
+ // indices.resize(indices.size() + (size_t)mesh.triangle_count() * 3);
+ // positions.resize(positions.size() + (size_t)mesh.vertex_count() * 3);
+ // normals.resize(normals.size() + (size_t)mesh.vertex_count() * 3);
+ // uvs.resize(uvs.size() + (size_t)mesh.vertex_count() * 2);
- for (auto& mesh_part: mesh.parts) {
- std::memcpy(positions.data() + vertices_offset * 3, mesh_part.positions.data(), mesh_part.positions.size() * sizeof(float));
- std::memcpy(normals.data() + vertices_offset * 3, mesh_part.normals.data(), mesh_part.normals.size() * sizeof(float));
- std::memcpy(uvs.data() + vertices_offset * 2, mesh_part.uvs.data(), mesh_part.uvs.size() * sizeof(float));
+ // for (auto& mesh_part: mesh.parts) {
+ // std::memcpy(positions.data() + vertices_offset * 3, mesh_part.positions.data(), mesh_part.positions.size() * sizeof(float));
+ // std::memcpy(normals.data() + vertices_offset * 3, mesh_part.normals.data(), mesh_part.normals.size() * sizeof(float));
+ // std::memcpy(uvs.data() + vertices_offset * 2, mesh_part.uvs.data(), mesh_part.uvs.size() * sizeof(float));
- for (size_t i = 0; i < mesh_part.indices.size(); i += 3) {
- size_t i1 = mesh_part.indices[i];
- size_t i2 = mesh_part.indices[i + 1];
- size_t i3 = mesh_part.indices[i + 2];
+ // for (size_t i = 0; i < mesh_part.indices.size(); i += 3) {
+ // size_t i1 = mesh_part.indices[i];
+ // size_t i2 = mesh_part.indices[i + 1];
+ // size_t i3 = mesh_part.indices[i + 2];
- auto p1 = vec3(mesh_part.positions[i1 * 3], mesh_part.positions[i1 * 3 + 1], mesh_part.positions[i1 * 3 + 2]);
- auto p2 = vec3(mesh_part.positions[i2 * 3], mesh_part.positions[i2 * 3 + 1], mesh_part.positions[i2 * 3 + 2]);
- auto p3 = vec3(mesh_part.positions[i3 * 3], mesh_part.positions[i3 * 3 + 1], mesh_part.positions[i3 * 3 + 2]);
+ // auto p1 = vec3(mesh_part.positions[i1 * 3], mesh_part.positions[i1 * 3 + 1], mesh_part.positions[i1 * 3 + 2]);
+ // auto p2 = vec3(mesh_part.positions[i2 * 3], mesh_part.positions[i2 * 3 + 1], mesh_part.positions[i2 * 3 + 2]);
+ // auto p3 = vec3(mesh_part.positions[i3 * 3], mesh_part.positions[i3 * 3 + 1], mesh_part.positions[i3 * 3 + 2]);
- indices[triangles_offset * 3 + i] = (i1 + vertices_offset) | (0xff000000 & (materials.size() << 8));
- indices[triangles_offset * 3 + i + 1] = (i2 + vertices_offset) | (0xff000000 & (materials.size() << 16));
- indices[triangles_offset * 3 + i + 2] = (i3 + vertices_offset) | (0xff000000 & (materials.size() << 24));
+ // indices[triangles_offset * 3 + i] = (i1 + vertices_offset) | (0xff000000 & (materials.size() << 8));
+ // indices[triangles_offset * 3 + i + 1] = (i2 + vertices_offset) | (0xff000000 & (materials.size() << 16));
+ // indices[triangles_offset * 3 + i + 2] = (i3 + vertices_offset) | (0xff000000 & (materials.size() << 24));
- triangles.emplace_back(p1, p2, p3);
- materials.push_back(mesh_part.mat);
- }
+ // triangles.emplace_back(p1, p2, p3);
+ // materials.push_back(mesh_part.mat);
+ // }
- triangles_offset += mesh_part.triangles_count;
- vertices_offset += mesh_part.vertices_count;
- }
- }
+ // triangles_offset += mesh_part.triangles_count;
+ // vertices_offset += mesh_part.vertices_count;
+ // }
+ // }
- for (auto &new_node: node.children) {
- nodes_to_load.push(new_node);
- }
+ // for (auto &new_node: node.children) {
+ // nodes_to_load.push(new_node);
+ // }
- nodes_to_load.pop();
- }
+ // nodes_to_load.pop();
+ // }
// random_scene();
bvh builder(triangles, packed_nodes);
// bvh builder(spheres, packed_nodes);
- scene_buffer = renderer.create_buffer(sizeof(meta), false);
- renderer.update_buffer(scene_buffer, &meta, 0, sizeof(meta));
+ scene_buffer = vkrenderer::create_buffer(sizeof(meta) * vkrenderer::virtual_frames_count);
+ // TODO: Write to correct offset
+ // vkrenderer::update_buffer(scene_buffer, &meta, 0, sizeof(meta));
- indices_buffer = renderer.create_buffer(indices.size() * sizeof(indices[0]), true);
- renderer.update_buffer(indices_buffer, indices.data(), 0, indices.size() * sizeof(indices[0]));
+ indices_buffer = vkrenderer::create_buffer(indices.size() * sizeof(indices[0]));
+ indices_buffer->write(indices.data(), 0, indices.size() * sizeof(indices[0]));
- positions_buffer = renderer.create_buffer(positions.size() * sizeof(positions[0]), true);
- renderer.update_buffer(positions_buffer, positions.data(), 0, positions.size() * sizeof(positions[0]));
+ positions_buffer = vkrenderer::create_buffer(positions.size() * sizeof(positions[0]));
+ positions_buffer->write(positions.data(), 0, positions.size() * sizeof(positions[0]));
- normals_buffer = renderer.create_buffer(normals.size() * sizeof(normals[0]), true);
- renderer.update_buffer(normals_buffer, normals.data(), 0, normals.size() * sizeof(normals[0]));
+ normals_buffer = vkrenderer::create_buffer(normals.size() * sizeof(normals[0]));
+ normals_buffer->write(normals.data(), 0, normals.size() * sizeof(normals[0]));
- uvs_buffer = renderer.create_buffer(uvs.size() * sizeof(uvs[0]), true);
- renderer.update_buffer(uvs_buffer, uvs.data(), 0, uvs.size() * sizeof(uvs[0]));
+ uvs_buffer = vkrenderer::create_buffer(uvs.size() * sizeof(uvs[0]));
+ uvs_buffer->write(uvs.data(), 0, uvs.size() * sizeof(uvs[0]));
- bvh_buffer = renderer.create_buffer(packed_nodes.size() * sizeof(packed_nodes[0]), true);
- renderer.update_buffer(bvh_buffer, packed_nodes.data(), 0, packed_nodes.size() * sizeof(packed_nodes[0]));
+ bvh_buffer = vkrenderer::create_buffer(packed_nodes.size() * sizeof(packed_nodes[0]));
+ bvh_buffer->write(packed_nodes.data(), 0, packed_nodes.size() * sizeof(packed_nodes[0]));
- materials_buffer = renderer.create_buffer(materials.size() * sizeof(materials[0]), true);
- renderer.update_buffer(materials_buffer, materials.data(), 0, materials.size() * sizeof(materials[0]));
+ materials_buffer = vkrenderer::create_buffer(materials.size() * sizeof(materials[0]));
+ materials_buffer->write(materials.data(), 0, materials.size() * sizeof(materials[0]));
}
diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp
index ed7129c..189ac33 100644
--- a/src/vk-renderer.cpp
+++ b/src/vk-renderer.cpp
@@ -18,8 +18,10 @@
#define VKRESULT(result) result;
#endif
-vkrenderer::vkrenderer(window& wnd)
- : api(context) {
+vkcontext vkrenderer::context = vkcontext();
+vkapi vkrenderer::api = vkapi(vkrenderer::context);
+
+vkrenderer::vkrenderer(window& wnd) {
platform_surface = api.create_surface(wnd);
swapchain = api.create_swapchain(
platform_surface,
@@ -158,27 +160,18 @@ void vkrenderer::update_image(Texture* texture, void* data) {
VKRESULT(vkWaitForFences(context.device, 1, &submission_fences[virtual_frame_index], VK_TRUE, UINT64_MAX))
}
-void vkrenderer::update_buffer(Buffer* buffer, void* data, off_t offset, size_t size) {
- auto device_buffer = api.get_buffer(buffer->device_buffer);
-
- size_t dynamic_offset = buffer->isStatic ? 0 : buffer->size * virtual_frame_index;
-
- std::memcpy((uint8_t*)device_buffer.device_ptr + dynamic_offset + offset, data, size);
-}
-
-
-Buffer* vkrenderer::create_buffer(size_t size, bool isStatic) {
- auto* buffer = new Buffer(size, isStatic);
+Buffer* vkrenderer::create_buffer(size_t size) {
+ auto* buffer = new Buffer(size);
- buffer->device_buffer = api.create_buffer(isStatic ? size : size * virtual_frames_count, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
+ buffer->device_buffer = api.create_buffer(size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
return buffer;
}
-Buffer* vkrenderer::create_index_buffer(size_t size, bool isStatic) {
- auto* buffer = new Buffer(size, isStatic);
+Buffer* vkrenderer::create_index_buffer(size_t size) {
+ auto* buffer = new Buffer(size);
- buffer->device_buffer = api.create_buffer(isStatic ? size : size * virtual_frames_count, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
+ buffer->device_buffer = api.create_buffer(size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
return buffer;
}
@@ -221,11 +214,11 @@ PrimitiveRenderpass* vkrenderer::create_primitive_renderpass() {
}
Primitive* vkrenderer::create_primitive(PrimitiveRenderpass& primitive_render_pass) {
- return new Primitive(api, primitive_render_pass);
+ return new Primitive(primitive_render_pass);
}
void vkrenderer::render() {
- // begin_frame();
+ begin_frame();
auto* cmd_buf = command_buffers[virtual_frame_index];
@@ -246,5 +239,10 @@ void vkrenderer::render() {
api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, swapchain.images[swapchain_image_index]);
- // finish_frame();
+ finish_frame();
}
+
+Buffer::Buffer(size_t size)
+ : buffer_size(size) {
+ device_buffer = vkrenderer::api.create_buffer(size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
+ }