diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/main.cpp | 47 | ||||
| -rw-r--r-- | src/scene.cpp | 79 | ||||
| -rw-r--r-- | src/utils.cpp | 135 | ||||
| -rw-r--r-- | src/vk-api.cpp | 5 | ||||
| -rw-r--r-- | src/vk-renderer.cpp | 11 |
6 files changed, 122 insertions, 156 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 91cdf43..b2b34b6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,6 +21,7 @@ add_executable( vk-context.cpp vk-api.cpp window.cpp + scene.cpp ) if(UNIX AND NOT APPLE) diff --git a/src/main.cpp b/src/main.cpp index 68dd0ee..3678f2a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,7 +9,7 @@ #include "vk-renderer.hpp" #include "window.hpp" -#include "utils.hpp" +#include "scene.hpp" #include "defines.hpp" #if defined(LINUX) @@ -54,9 +54,12 @@ int main() { uint64_t frame_count = 0; auto start = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now(); - auto inputs = create_inputs(width, height); + auto main_scene = scene(width, height); auto can_render = true; - vkrenderer renderer { wnd, inputs }; + vkrenderer renderer { wnd, sizeof(main_scene) }; + + // Upload scene + std::memcpy(renderer.scene_buffer_ptr(), &main_scene, sizeof(main_scene)); ImGuiIO& io = ImGui::GetIO(); io.DisplaySize.x = (float)width; @@ -82,8 +85,8 @@ int main() { width = event.width; height = event.height; - ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->width = width; - ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->height = height; + ((scene*) renderer.scene_buffer_ptr())->width = width; + ((scene*) renderer.scene_buffer_ptr())->height = height; io.DisplaySize.x = (float)width; io.DisplaySize.y = (float)height; @@ -93,8 +96,8 @@ int main() { } else { can_render = true; renderer.recreate_swapchain(); - ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.set_aspect_ratio((float)event.width / (float)event.height); - ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->sample_index = 0; + ((scene*) renderer.scene_buffer_ptr())->cam.set_aspect_ratio((float)event.width / (float)event.height); + ((scene*) renderer.scene_buffer_ptr())->sample_index = 0; } reset_accumulation = true; @@ -111,44 +114,44 @@ int main() { switch (event.key) { case KEYS::W: { - move_vec = ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.forward.unit() * move_speed; + move_vec = ((scene*) renderer.scene_buffer_ptr())->cam.forward.unit() * move_speed; break; } case KEYS::S: { - move_vec = -((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.forward.unit() * move_speed; + move_vec = -((scene*) renderer.scene_buffer_ptr())->cam.forward.unit() * move_speed; break; } case KEYS::D: { - move_vec = ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.right.unit() * move_speed; + move_vec = ((scene*) renderer.scene_buffer_ptr())->cam.right.unit() * move_speed; break; } case KEYS::A: { - move_vec = -((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.right.unit() * move_speed; + move_vec = -((scene*) renderer.scene_buffer_ptr())->cam.right.unit() * move_speed; break; } case KEYS::E: { - ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.rotate_y(0.001f * delta_time); + ((scene*) renderer.scene_buffer_ptr())->cam.rotate_y(0.001f * delta_time); reset_accumulation = true; break; } case KEYS::Q: { - ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.rotate_y(-0.001f * delta_time); + ((scene*) renderer.scene_buffer_ptr())->cam.rotate_y(-0.001f * delta_time); reset_accumulation = true; break; } case KEYS::SPACE: { - move_vec = ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.up.unit() * move_speed; + move_vec = ((scene*) renderer.scene_buffer_ptr())->cam.up.unit() * move_speed; break; } case KEYS::CTRL: { - move_vec = -((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.up.unit() * move_speed; + move_vec = -((scene*) renderer.scene_buffer_ptr())->cam.up.unit() * move_speed; break; } default: break; } - ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->cam.move(move_vec); + ((scene*) renderer.scene_buffer_ptr())->cam.move(move_vec); if (!move_vec.near_zero()) { reset_accumulation = true; @@ -197,15 +200,15 @@ int main() { 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", ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->sample_index); + ImGui::Text("frame count %u\n", ((scene*) renderer.scene_buffer_ptr())->sample_index); - if (ImGui::Checkbox("depth of field", (bool*)&((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->enable_dof)) { + if (ImGui::Checkbox("depth of field", (bool*)&((scene*) renderer.scene_buffer_ptr())->enable_dof)) { reset_accumulation = true; } - ImGui::SliderInt("bounces", (int32_t*)&((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->max_bounce, 2, 250); + ImGui::SliderInt("bounces", (int32_t*)&((scene*) renderer.scene_buffer_ptr())->max_bounce, 2, 250); - if (ImGui::Checkbox("debug bvh", (bool*)&((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->debug_bvh)) { + if (ImGui::Checkbox("debug bvh", (bool*)&((scene*) renderer.scene_buffer_ptr())->debug_bvh)) { reset_accumulation = true; } @@ -223,13 +226,13 @@ int main() { renderer.begin_frame(); if (reset_accumulation) { - ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->sample_index = 0; + ((scene*) renderer.scene_buffer_ptr())->sample_index = 0; renderer.reset_accumulation(); } renderer.compute(width, height); - ((input_data*) renderer.compute_shader_buffer.alloc_info.pMappedData)->sample_index++; + ((scene*) renderer.scene_buffer_ptr())->sample_index++; renderer.ui(); diff --git a/src/scene.cpp b/src/scene.cpp new file mode 100644 index 0000000..68929d8 --- /dev/null +++ b/src/scene.cpp @@ -0,0 +1,79 @@ +#include "scene.hpp"
+
+#include "utils.hpp"
+
+// Return the number of instantiated spheres
+uint32_t scene::random_scene(sphere *world) {
+ material ground_material = { { 0.5, 0.5, 0.5 } };
+ ground_material.type = MATERIAL_TYPE::LAMBERTIAN;
+ world[0] = sphere{ { 0, -1000, 0 }, ground_material, 1000 };
+
+ uint32_t world_sphere_index = 1;
+
+ int32_t spheres_count = 11;
+ for (int a = -spheres_count; a < spheres_count; a++) {
+ for (int b = -spheres_count; b < spheres_count; b++) {
+ auto choose_mat = randd();
+ point3 center(a + 0.9 * randd(), 0.2, b + 0.9 * randd());
+
+ if ((center - point3{ 4, 0.2, 0 }).length() > 0.9) {
+ material sphere_material = {};
+
+ if (choose_mat < 0.8) {
+ // diffuse
+ sphere_material.albedo = color::random() * color::random();
+ sphere_material.type = MATERIAL_TYPE::LAMBERTIAN;
+ } else if (choose_mat < 0.95) {
+ // metal
+ sphere_material.albedo = color::random(0.5, 1);
+ sphere_material.fuzz = randd(0, 0.5);
+ sphere_material.type = MATERIAL_TYPE::METAL;
+ } else {
+ // glass
+ sphere_material.ior = 1.5;
+ sphere_material.type = MATERIAL_TYPE::DIELECTRIC;
+ }
+
+ world[world_sphere_index] = { center, sphere_material, 0.2 };
+ world_sphere_index++;
+ }
+ }
+ }
+
+ material material1 = {};
+ material1.ior = 1.5;
+ material1.type = MATERIAL_TYPE::DIELECTRIC;
+ world[world_sphere_index] = { { 0, 1, 0 }, material1, 1.0 };
+
+ material material2 = {};
+ material2.albedo = color{ 0.4, 0.2, 0.1 };
+ material2.type = MATERIAL_TYPE::LAMBERTIAN;
+ world[world_sphere_index + 1] = { { -4, 1, 0 }, material2, 1.0 };
+
+ material material3 = {};
+ material3.albedo = color{ 0.7, 0.6, 0.5 };
+ material3.fuzz = 0.0;
+ material3.type = MATERIAL_TYPE::METAL;
+ world[world_sphere_index + 2] = { { 4, 1, 0 }, material3, 1.0 };
+
+ material material4 = {};
+ material4.albedo = color{ 0.0, 0.0, 0.0 };
+ material4.emissive = color{ 1.0, 1.0, 1.0 } * 1000.0;
+ material4.fuzz = 0.0;
+ material4.type = MATERIAL_TYPE::EMISSIVE;
+ world[world_sphere_index + 3] = { { 2, 1.5, 2 }, material4, 0.5 };
+
+ return world_sphere_index + 4;
+}
+
+scene::scene(uint32_t width, uint32_t height)
+ :width(width), height(height), spheres_count(random_scene(spheres)),
+ cam({ 13.0, 2.0, 3.0 }, { 0.0, 0.0, 0.0 }, 20.0, (float)width / (float)height, 0.1, 10) {
+ bvh builder;
+ builder.build(spheres, spheres_count);
+ // builder.exporter();
+
+ for (uint32_t idx = 0; idx < builder.nodes.size(); idx++) {
+ nodes[idx] = builder.nodes[idx];
+ }
+}
diff --git a/src/utils.cpp b/src/utils.cpp index a46cd6b..6557ebc 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,26 +1,23 @@ #include "utils.hpp" -#include <cstdio> -#include <cstring> #include <iostream> #include "defines.hpp" -#include "material.hpp" -std::vector<uint8_t> get_shader_code(const char* path) { +std::vector<uint8_t> read_file(const char* path) { #if defined(WINDOWS) FILE* f = nullptr; errno_t err = fopen_s(&f, path, "rb"); if (err != 0) { - std::cerr << "Cannot open shader file !" << std::endl; + std::cerr << "Cannot open file !" << std::endl; return {}; } #elif defined(LINUX) FILE* f = fopen(path, "rb"); if (!f) { - std::cerr << "Cannot open shader file !" << std::endl; + std::cerr << "Cannot open file !" << std::endl; return {}; } #endif @@ -29,134 +26,20 @@ std::vector<uint8_t> get_shader_code(const char* path) { return {}; } - std::vector<uint8_t> shader_code(ftell(f)); + std::vector<uint8_t> file_content(ftell(f)); if (fseek(f, 0, SEEK_SET) != 0) { return {}; } - if (fread(shader_code.data(), sizeof(uint8_t), shader_code.size(), f) != shader_code.size()) { - std::cerr << "Reading shader code failed" << std::endl; + if (fread(file_content.data(), sizeof(uint8_t), file_content.size(), f) != file_content.size()) { + std::cerr << "Reading file content failed" << std::endl; return {}; } - return shader_code; + return file_content; } -std::vector<uint8_t> get_shader_code(std::string& path) { - return get_shader_code(path.c_str()); -} - -color ground_color { 1.0, 1.0, 1.0 }; -color sky_color { 0.5, 0.7, 1.0 }; - -// Return the number of instantiated spheres -uint32_t random_scene(sphere *world) { - material ground_material = { { 0.5, 0.5, 0.5 } }; - ground_material.type = MATERIAL_TYPE::LAMBERTIAN; - world[0] = sphere{ { 0, -1000, 0 }, ground_material, 1000 }; - - uint32_t world_sphere_index = 1; - - int32_t spheres_count = 11; - for (int a = -spheres_count; a < spheres_count; a++) { - for (int b = -spheres_count; b < spheres_count; b++) { - auto choose_mat = randd(); - point3 center(a + 0.9 * randd(), 0.2, b + 0.9 * randd()); - - if ((center - point3{ 4, 0.2, 0 }).length() > 0.9) { - material sphere_material = {}; - - if (choose_mat < 0.8) { - // diffuse - sphere_material.albedo = color::random() * color::random(); - sphere_material.type = MATERIAL_TYPE::LAMBERTIAN; - } else if (choose_mat < 0.95) { - // metal - sphere_material.albedo = color::random(0.5, 1); - sphere_material.fuzz = randd(0, 0.5); - sphere_material.type = MATERIAL_TYPE::METAL; - } else { - // glass - sphere_material.ior = 1.5; - sphere_material.type = MATERIAL_TYPE::DIELECTRIC; - } - - world[world_sphere_index] = { center, sphere_material, 0.2 }; - world_sphere_index++; - } - } - } - - material material1 = {}; - material1.ior = 1.5; - material1.type = MATERIAL_TYPE::DIELECTRIC; - world[world_sphere_index] = { { 0, 1, 0 }, material1, 1.0 }; - - material material2 = {}; - material2.albedo = color{ 0.4, 0.2, 0.1 }; - material2.type = MATERIAL_TYPE::LAMBERTIAN; - world[world_sphere_index + 1] = { { -4, 1, 0 }, material2, 1.0 }; - - material material3 = {}; - material3.albedo = color{ 0.7, 0.6, 0.5 }; - material3.fuzz = 0.0; - material3.type = MATERIAL_TYPE::METAL; - world[world_sphere_index + 2] = { { 4, 1, 0 }, material3, 1.0 }; - - material material4 = {}; - material4.albedo = color{ 0.0, 0.0, 0.0 }; - material4.emissive = color{ 1.0, 1.0, 1.0 } * 100000.0; - material4.fuzz = 0.0; - material4.type = MATERIAL_TYPE::EMISSIVE; - world[world_sphere_index + 3] = { { 2, 1.5, 2 }, material4, 0.5 }; - - return world_sphere_index + 4; -} - -struct input_data create_inputs(uint32_t width, uint32_t height) { - // Image dimensions - const float aspect_ratio = (float)width / (float) height; - - const uint32_t max_depth = 50; - - const vec3 camera_position{ 13.0, 2.0, 3.0 }; - const vec3 camera_target{ 0.0, 0.0, 0.0 }; - const float aperture = 0.1; - const float distance_to_focus = 10; - camera camera { camera_position, camera_target, 20.0, aspect_ratio, aperture, distance_to_focus }; - - struct input_data inputs = { - .sky_color = sky_color, - .ground_color = ground_color, - - .cam = camera, - - .spheres = {}, - .nodes = {}, - - .max_bounce = max_depth, - - .width = width, - .height = height, - - .sample_index = 0, - .enable_dof = true, - .debug_bvh = false, - }; - - // World hittable objects - uint32_t spheres_count = random_scene(inputs.spheres); - - inputs.spheres_count = spheres_count; - - bvh builder; - builder.build(inputs.spheres, spheres_count); - // builder.exporter(); - - for (uint32_t idx = 0; idx < builder.nodes.size(); idx++) { - inputs.nodes[idx] = builder.nodes[idx]; - } - - return inputs; +std::vector<uint8_t> read_file(std::string& path) { + return read_file(path.c_str()); } diff --git a/src/vk-api.cpp b/src/vk-api.cpp index 1d0c8a5..e5705fb 100644 --- a/src/vk-api.cpp +++ b/src/vk-api.cpp @@ -1,5 +1,6 @@ #include <cassert> #include <memory> +#include <iostream> #include "vk-api.hpp" #include "window.hpp" @@ -377,7 +378,7 @@ Pipeline vkapi::create_compute_pipeline(const char* shader_name, std::vector<VkD char shader_path[256] = {}; sprintf(shader_path, "%s%s%s", "./shaders/", shader_name, ".comp.spv"); - std::vector<uint8_t> shader_code = get_shader_code(shader_path); + std::vector<uint8_t> shader_code = read_file(shader_path); if (shader_code.size() == 0) { exit(1); } @@ -455,7 +456,7 @@ Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<Vk char shader_path[256] = {}; sprintf(shader_path, "%s%s%s%s", "./shaders/", shader_name, shader_stage_extension(stage_flag), ".spv"); - std::vector<uint8_t> shader_code = get_shader_code(shader_path); + std::vector<uint8_t> shader_code = read_file(shader_path); if (shader_code.size() == 0) { exit(1); } diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp index 8d074c5..caa27f8 100644 --- a/src/vk-renderer.cpp +++ b/src/vk-renderer.cpp @@ -7,7 +7,7 @@ #include "thirdparty/vk_mem_alloc.h" #include "defines.hpp" -#include "utils.hpp" +#include "scene.hpp" #include "window.hpp" #define VKRESULT(result) assert(result == VK_SUCCESS); @@ -24,7 +24,7 @@ struct UiTransforms { float translate_x, translate_y; }; -vkrenderer::vkrenderer(window& wnd, const input_data& inputs) { +vkrenderer::vkrenderer(window& wnd, size_t scene_buffer_size) { platform_surface = api.create_surface(wnd); swapchain = api.create_swapchain( platform_surface, @@ -93,11 +93,10 @@ vkrenderer::vkrenderer(window& wnd, const input_data& inputs) { execution_semaphores = api.create_semaphores(swapchain.image_count); acquire_semaphores = api.create_semaphores(swapchain.image_count); - compute_shader_buffer = api.create_buffer(sizeof(inputs), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); - std::memcpy(compute_shader_buffer.alloc_info.pMappedData, &inputs, sizeof(inputs)); + scene_buffer = api.create_buffer(scene_buffer_size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); for (size_t index = 0; index < swapchain.image_count; index++) { - api.update_descriptor_set_buffer(compute_shader_sets[index], compute_sets_bindings[0], compute_shader_buffer); + api.update_descriptor_set_buffer(compute_shader_sets[index], compute_sets_bindings[0], scene_buffer); } std::vector<VkFormat> attachments_format { swapchain.surface_format.format }; @@ -215,7 +214,7 @@ vkrenderer::vkrenderer(window& wnd, const input_data& inputs) { vkrenderer::~vkrenderer() { VKRESULT(vkWaitForFences(api.context.device, submission_fences.size(), submission_fences.data(), VK_TRUE, UINT64_MAX)) - api.destroy_buffer(compute_shader_buffer); + api.destroy_buffer(scene_buffer); api.destroy_fences(submission_fences); api.destroy_semaphores(execution_semaphores); api.destroy_semaphores(acquire_semaphores); |
