diff options
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 249 |
1 files changed, 186 insertions, 63 deletions
diff --git a/src/main.cpp b/src/main.cpp index 45e30a3..6dbfc50 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,45 +1,54 @@ -#include <iostream> +#include <cassert> #include <chrono> -#include <cstring> #include <cstdio> -#include <cassert> +#include <cstring> +#include <iostream> -#include "thirdparty/renderdoc.h" #include "imgui.h" +#include "thirdparty/renderdoc.h" #include "compute-renderpass.hpp" +#include "primitive-renderpass.hpp" +#include "defines.hpp" +#include "scene.hpp" #include "vk-renderer.hpp" #include "window.hpp" -#include "scene.hpp" -#include "defines.hpp" #if defined(LINUX) -#include <unistd.h> #include <dlfcn.h> +#include <unistd.h> #elif defined(WINDOWS) #include <Windows.h> #endif +struct VkVertex { + float x, y; + float u, v; + uint32_t color; + uint32_t padding[3]; +}; + int main() { RENDERDOC_API_1_1_2 *rdoc_api = NULL; #ifdef WINDOWS // At init, on windows - if(HMODULE mod = GetModuleHandleA("renderdoc.dll")) - { - pRENDERDOC_GetAPI RENDERDOC_GetAPI = - (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI"); - int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void **)&rdoc_api); - assert(ret == 1); + if (HMODULE mod = GetModuleHandleA("renderdoc.dll")) { + pRENDERDOC_GetAPI RENDERDOC_GetAPI = + (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI"); + int ret = + RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void **)&rdoc_api); + assert(ret == 1); } #elif defined(LINUX) // At init, on linux/android. // For android replace librenderdoc.so with libVkLayer_GLES_RenderDoc.so - if(void *mod = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD)) - { - pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI"); - int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void **)&rdoc_api); - assert(ret == 1); + if (void *mod = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD)) { + pRENDERDOC_GetAPI RENDERDOC_GetAPI = + (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI"); + int ret = + RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void **)&rdoc_api); + assert(ret == 1); } #endif @@ -48,21 +57,24 @@ int main() { uint32_t width = 400; uint32_t height = width / aspect_ratio; - window wnd { width , height }; + window wnd{width, height}; float delta_time = 0.f; uint64_t frame_count = 0; auto start = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now(); - point3 position = { 13.0, 2.0, -3.0 }; - point3 target = { 0.0, 0.0, 0.0 }; + point3 position = {13.0, 2.0, -3.0}; + point3 target = {0.0, 0.0, 0.0}; auto v_fov = 90; auto aperture = 0.1; auto focus_distance = 10; auto cam = camera(position, target, v_fov, (float)width / (float)height, aperture, focus_distance); - vkrenderer renderer { wnd }; + vkrenderer renderer{wnd}; + + ImGui::CreateContext(); + auto& io = ImGui::GetIO(); auto main_scene = scene(cam, width, height, renderer); @@ -70,8 +82,8 @@ int main() { auto raytracing_pass = renderer.create_compute_renderpass(); raytracing_pass->set_pipeline(raytracing_shader_name); - 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 = renderer.create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT); + auto *output_texture = renderer.create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT); 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); @@ -79,27 +91,43 @@ int main() { raytracing_pass->set_constant(40, main_scene.uvs_buffer); raytracing_pass->set_constant(48, main_scene.materials_buffer); + 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); + + Buffer* ui_vertex_buffer = nullptr; + Buffer* ui_index_buffer = nullptr; + + std::string 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; - ImGuiIO& io = ImGui::GetIO(); io.DisplaySize.x = (float)width; io.DisplaySize.y = (float)height; - while(wnd.isOpen) { + while (wnd.isOpen) { end = std::chrono::high_resolution_clock::now(); delta_time = std::chrono::duration<float, std::milli>(end - start).count(); start = std::chrono::high_resolution_clock::now(); - ImGuiIO& io = ImGui::GetIO(); io.DeltaTime = delta_time; wnd.poll_events(); - for (auto event: wnd.events) { - switch(event.type) { + for (auto event : wnd.events) { + switch (event.type) { case EVENT_TYPES::RESIZE: { width = event.width; height = event.height; @@ -133,7 +161,7 @@ int main() { move_speed *= 10.f; } - vec3 move_vec {}; + vec3 move_vec{}; switch (event.key) { case KEYS::W: { @@ -201,10 +229,7 @@ int main() { break; } case EVENT_TYPES::MOUSE_MOVE: { - io.MousePos = ImVec2 { - (float)event.x, - (float)event.y - }; + io.MousePos = ImVec2{(float)event.x, (float)event.y}; break; } default: @@ -215,51 +240,150 @@ int main() { wnd.events.clear(); // GUI - ImGui::NewFrame(); + 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::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); + // 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; - } + // 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; - } + // 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; - } + // if (ImGui::Checkbox("debug bvh", (bool *)&main_scene.meta.debug_bvh)) { + // main_scene.meta.sample_index = 1; + // } - ImGui::End(); + // ImGui::End(); + bool open = true; + ImGui:ImGui::ShowDemoWindow(&open); - ImGui::EndFrame(); + 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); + ImGui::Render(); - // renderer.ui(); + // 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); - if (can_render) { - std::memcpy(main_scene.scene_buffer->ptr(), &main_scene.meta, sizeof(main_scene.meta)); + 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 = 0; + + for (uint32_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 (uint32_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 (size_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; + } + + renderer.begin_frame(); + + ui_pass->set_color_attachment(0, renderer.back_buffer()); + renderer.render(); + renderer.finish_frame(); main_scene.meta.sample_index++; @@ -282,7 +406,6 @@ int main() { // write_color(std::cout, output_image[index]); // } - std::cerr << "Done !" << std::endl; return 0; |
