From d78200b71b259b87f401b24906385af4e2553fbe Mon Sep 17 00:00:00 2001 From: ladevieq Date: Mon, 8 Aug 2022 23:38:19 +0200 Subject: Refactored gltf imported and mesh management --- src/CMakeLists.txt | 1 + src/bvh.cpp | 6 +- src/gltf.cpp | 216 +++++++++--------------- src/main.cpp | 394 ++++++++++++++++++++----------------------- src/mesh.cpp | 45 +++++ src/primitive-renderpass.cpp | 4 + src/scene.cpp | 116 ++++++------- src/vk-renderer.cpp | 38 ++--- 8 files changed, 395 insertions(+), 425 deletions(-) create mode 100644 src/mesh.cpp (limited to 'src') 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 + #include #include @@ -45,6 +47,8 @@ bvh::bvh(std::vector& triangles, std::vector& packed_nodes) :triangles(triangles) { + + assert(!triangles.empty()); packed_nodes.resize(2 * triangles.size() - 1); temp_nodes = std::vector(2 * triangles.size() - 1); leafs = std::vector(triangles.size()); @@ -125,7 +129,7 @@ int32_t bvh::traverse_depth_first_ordered(std::vector& 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 -#include #include #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>(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(); - 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(); + 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(), root_node.children[child_index], meshes); + load_node(root_children[child_index].get(), root_node.children[child_index]); } f.close(); - - return root_node; } -void gltf::load_node(json &gltf_json, uint32_t index, node &parent, std::vector &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(), parent.children[child_index], meshes); + load_node(children[child_index].get(), parent.children[child_index]); } } - if (gltf_node.contains("mesh")) { parent.mesh = std::make_optional(meshes[gltf_node["mesh"].get()]); } + if (gltf_node.contains("mesh")) { + parent.mesh = &meshes[gltf_node["mesh"].get()]; + } } -std::vector gltf::load_meshes( - json &gltf_json, std::vector> &buffers_content, std::vector &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 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]; - - 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)); + auto& mesh = meshes[mesh_index]; + const auto &primitives = gltf_meshes[mesh_index]["primitives"]; + + 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()]["count"].get(); + submesh.vertex_count = gltf_json["accessors"][primitive["attributes"]["POSITION"].get()]["count"].get(); + // submesh.mat = materials[gltf_primitive["material"].get()]; + + return submesh; } -std::vector 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(); + const auto &view = gltf_json["bufferViews"][view_index]; + auto offset = view["byteOffset"].get(); + auto &buffer = buffers[view["buffer"].get()]; + + return { + &buffer[offset], + view["byteLength"].get() + }; +} + +void gltf::load_textures(const std::filesystem::path &path) { + const auto &gltf_images = gltf_json["images"]; auto images_count = gltf_images.size(); std::vector 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()).string(); unsigned char *data = stbi_load(filepath.c_str(), &x, &y, &n, 4); - auto *img = renderer.create_2d_texture(static_cast(x), static_cast(y), VK_FORMAT_R8G8B8A8_UNORM); + auto *img = vkrenderer::create_2d_texture(static_cast(x), static_cast(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 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 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 gltf::load_textures(json &gltf_json, std::filesystem::path auto image_index = gltf_texture["source"].get(); 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(); 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 gltf::load_materials(json &gltf_json, std::vector &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 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(); material.base_color.v[1] = base_color[1].get(); material.base_color.v[2] = base_color[2].get(); @@ -181,82 +205,4 @@ std::vector gltf::load_materials(json &gltf_json, std::vector } } } - - return materials; -} - -mesh_part gltf::load_primitive(json &gltf_json, json &primitive, std::vector> &buffers_content, - std::vector &materials) { - auto part = mesh_part(); - auto &accessors = gltf_json["accessors"]; - - { - auto indices_accessor_index = primitive["indices"].get(); - auto indices_view_index = accessors[indices_accessor_index]["bufferView"].get(); - auto &indices_view = gltf_json["bufferViews"][indices_view_index]; - - auto indices_buffer_index = indices_view["buffer"].get(); - auto indices_offset = indices_view["byteOffset"].get(); - auto indices_length = indices_view["byteLength"].get(); - - auto &indices_buffer = buffers_content[indices_buffer_index]; - auto *indices_start = reinterpret_cast(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(); - auto positions_view_index = accessors[positions_accessor_index]["bufferView"].get(); - auto &positions_view = gltf_json["bufferViews"][positions_view_index]; - - auto positions_buffer_index = positions_view["buffer"].get(); - auto positions_offset = positions_view["byteOffset"].get(); - auto positions_length = positions_view["byteLength"].get(); - - auto &positions_buffer = buffers_content[positions_buffer_index]; - auto *positions_start = reinterpret_cast(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(); - auto normals_view_index = accessors[normals_accessor_index]["bufferView"].get(); - auto &normals_view = gltf_json["bufferViews"][normals_view_index]; - - auto normals_buffer_index = normals_view["buffer"].get(); - auto normals_offset = normals_view["byteOffset"].get(); - auto normals_length = normals_view["byteLength"].get(); - - auto &normals_buffer = buffers_content[normals_buffer_index]; - auto *normals_start = reinterpret_cast(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(); - auto uvs_view_index = accessors[uvs_accessor_index]["bufferView"].get(); - auto &uvs_view = gltf_json["bufferViews"][uvs_view_index]; - - auto uvs_buffer_index = uvs_view["buffer"].get(); - auto uvs_offset = uvs_view["byteOffset"].get(); - auto uvs_length = uvs_view["byteLength"].get(); - - auto &uvs_buffer = buffers_content[uvs_buffer_index]; - auto *uvs_start = reinterpret_cast(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()]; - 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(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 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 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 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); + raytracing_pass->set_ouput_texture(output_texture); + raytracing_pass->set_constant(60, accumulation_texture); - ImGui::Text("frame per second %u\n", static_cast(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(); - - 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(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 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(&scale)); - current_primitive->set_constant(16, reinterpret_cast(&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 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_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 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 materials; std::vector 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 triangles; - size_t triangles_offset = 0; - size_t vertices_offset = 0; - std::queue nodes_to_load {}; - nodes_to_load.push(root_node); + // size_t triangles_offset = 0; + // size_t vertices_offset = 0; + // std::queue 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); + } -- cgit v1.3