aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp108
-rw-r--r--src/utils.cpp108
-rw-r--r--src/vk-renderer.cpp160
-rw-r--r--src/window.cpp21
4 files changed, 239 insertions, 158 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 0176fdf..03db2ab 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -4,13 +4,9 @@
#include <cstdio>
#include <cassert>
-#include "vk-renderer.hpp"
#include "thirdparty/renderdoc.h"
-#include "vec3.hpp"
-#include "material.hpp"
-#include "sphere.hpp"
-#include "camera.hpp"
+#include "vk-renderer.hpp"
#include "utils.hpp"
#include "defines.hpp"
@@ -22,62 +18,6 @@
#endif
-color ground_color { 1.0, 1.0, 1.0 };
-color sky_color { 0.5, 0.7, 1.0 };
-
-void 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;
-
- for (int a = -11; a < 11; a++) {
- for (int b = -11; b < 11; 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 };
-}
-
int main() {
RENDERDOC_API_1_1_2 *rdoc_api = NULL;
@@ -107,49 +47,9 @@ int main() {
const uint32_t width = 400;
const uint32_t height = width / aspect_ratio;
- const uint32_t samples_per_pixel = 1;
- 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 = {},
-
- .max_bounce = max_depth,
- .samples_per_pixel = samples_per_pixel,
- .width = width,
- .height = height
- };
-
- // Random numbers pools
- for (size_t rand_number_index = 0; rand_number_index < 1000; rand_number_index += 2) {
- inputs.random_offset[rand_number_index] = randd();
- inputs.random_offset[rand_number_index + 1] = randd();
- }
-
- for (size_t rand_number_index = 0; rand_number_index < 1000; rand_number_index += 2) {
- vec3 random_unit_disk = random_in_unit_disk();
- inputs.random_disk[rand_number_index] = random_unit_disk.x;
- inputs.random_disk[rand_number_index + 1] = random_unit_disk.y;
- }
-
- for (size_t rand_number_index = 0; rand_number_index < 1000; rand_number_index++) {
- inputs.random_in_sphere[rand_number_index] = random_in_unit_sphere();
- }
-
- // World hittable objects
- random_scene(inputs.spheres);
-
window wnd { width , height };
+
+ auto inputs = create_inputs(width, height);
vkrenderer renderer { wnd, inputs };
while(wnd.isOpen) {
@@ -162,7 +62,7 @@ int main() {
if(rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL);
auto start = std::chrono::high_resolution_clock::now();
- renderer.compute(width, height);
+ renderer.compute();
auto end = std::chrono::high_resolution_clock::now();
std::cerr << "Image generation took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms" << std::endl;
diff --git a/src/utils.cpp b/src/utils.cpp
index e7aef1d..9fb5872 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -4,6 +4,8 @@
#include <cstring>
#include <iostream>
+#include "material.hpp"
+
std::vector<uint8_t> get_shader_code(const char* path) {
FILE* f = fopen(path, "rb");
@@ -29,3 +31,109 @@ std::vector<uint8_t> get_shader_code(const char* path) {
return shader_code;
}
+
+color ground_color { 1.0, 1.0, 1.0 };
+color sky_color { 0.5, 0.7, 1.0 };
+
+void 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;
+
+ for (int a = -11; a < 11; a++) {
+ for (int b = -11; b < 11; 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 };
+}
+
+struct input_data create_inputs(uint32_t width, uint32_t height) {
+ // Image dimensions
+ // const float aspect_ratio = 16.0 / 9.0;
+ const float aspect_ratio = 1;
+
+ const uint32_t samples_per_pixel = 1;
+ 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 = {},
+
+ .max_bounce = max_depth,
+ .samples_per_pixel = samples_per_pixel,
+ .width = width,
+ .height = height
+ };
+
+ // Random numbers pools
+ for (size_t rand_number_index = 0; rand_number_index < 1000; rand_number_index += 2) {
+ inputs.random_offset[rand_number_index] = randd();
+ inputs.random_offset[rand_number_index + 1] = randd();
+ }
+
+ for (size_t rand_number_index = 0; rand_number_index < 1000; rand_number_index += 2) {
+ vec3 random_unit_disk = random_in_unit_disk();
+ inputs.random_disk[rand_number_index] = random_unit_disk.x;
+ inputs.random_disk[rand_number_index + 1] = random_unit_disk.y;
+ }
+
+ for (size_t rand_number_index = 0; rand_number_index < 1000; rand_number_index++) {
+ inputs.random_in_sphere[rand_number_index] = random_in_unit_sphere();
+ }
+
+ // World hittable objects
+ random_scene(inputs.spheres);
+
+ return inputs;
+}
diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp
index 0a374e1..d5511a9 100644
--- a/src/vk-renderer.cpp
+++ b/src/vk-renderer.cpp
@@ -19,28 +19,32 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(VkDebugUtilsMessageSeverityFlagBits
return VK_FALSE;
}
-vkrenderer::vkrenderer(window& wnd, const input_data& inputs) {
+vkrenderer::vkrenderer(window& wnd, const input_data& inputs)
+ : wnd(wnd) {
load_vulkan();
create_instance();
- create_surface(wnd);
+ create_surface();
create_device();
- create_swapchain(wnd);
create_pipeline();
+ create_swapchain();
create_memory_allocator();
create_command_buffers();
create_descriptor_set();
create_fences();
create_semaphores();
+ create_input_buffer(inputs);
- update_sets(inputs);
+ update_descriptors_buffer();
+ update_descriptors_image();
}
-void vkrenderer::compute(size_t width, size_t height) {
+void vkrenderer::compute() {
VKRESULT(vkWaitForFences(device, 1, &submission_fences[frame_index], VK_TRUE, UINT64_MAX))
VKRESULT(vkResetFences(device, 1, &submission_fences[frame_index]))
- VKRESULT(vkAcquireNextImageKHR(device, swapchain, UINT64_MAX, acquire_semaphores[frame_index], VK_NULL_HANDLE, &current_image_index))
+ auto acquire_result = vkAcquireNextImageKHR(device, swapchain, UINT64_MAX, acquire_semaphores[frame_index], VK_NULL_HANDLE, &current_image_index);
+ handle_swapchain_result(acquire_result);
VkCommandBufferBeginInfo cmd_buf_begin_info = {};
cmd_buf_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
@@ -86,7 +90,7 @@ void vkrenderer::compute(size_t width, size_t height) {
vkCmdBindPipeline(command_buffers[frame_index], VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipeline);
- vkCmdDispatch(command_buffers[frame_index], width / 8, height / 8, 1);
+ vkCmdDispatch(command_buffers[frame_index], wnd.width / 8, wnd.height / 8, 1);
VkImageMemoryBarrier general_to_present_barrier = {};
general_to_present_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@@ -140,13 +144,26 @@ void vkrenderer::compute(size_t width, size_t height) {
present_info.pImageIndices = &current_image_index;
present_info.pResults = nullptr;
- VKRESULT(vkQueuePresentKHR(compute_queue, &present_info))
+ auto present_result = vkQueuePresentKHR(compute_queue, &present_info);
+ handle_swapchain_result(present_result);
VKRESULT(vkWaitForFences(device, 1, &submission_fences[frame_index], VK_TRUE, UINT64_MAX))
frame_index = ++frame_index % swapchain_images_count;
}
+void vkrenderer::recreate_swapchain() {
+ VKRESULT(vkWaitForFences(device, 1, &submission_fences[frame_index], VK_TRUE, UINT64_MAX))
+
+ destroy_swapchain();
+
+ create_surface();
+
+ create_swapchain();
+
+ update_descriptors_image();
+}
+
void vkrenderer::create_instance() {
VkApplicationInfo app_info = {};
@@ -209,7 +226,11 @@ void vkrenderer::create_debugger() {
))
}
-void vkrenderer::create_surface(window& wnd) {
+void vkrenderer::create_surface() {
+ if (platform_surface != VK_NULL_HANDLE) {
+ vkDestroySurfaceKHR(instance, platform_surface, nullptr);
+ }
+
#if defined(LINUX)
VkXcbSurfaceCreateInfoKHR create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
@@ -267,9 +288,9 @@ void vkrenderer::create_device() {
std::cerr << "Device ready" << std::endl;
}
-void vkrenderer::create_swapchain(window& wnd) {
+void vkrenderer::create_swapchain() {
VkBool32 queue_support_presentation = VK_FALSE;
- VKRESULT(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, compute_queue_index, platform_surface, &queue_support_presentation));
+ VKRESULT(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, compute_queue_index, platform_surface, &queue_support_presentation))
VkSurfaceCapabilitiesKHR caps;
VKRESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, platform_surface, &caps))
@@ -304,10 +325,11 @@ void vkrenderer::create_swapchain(window& wnd) {
create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR;
create_info.clipped = VK_TRUE;
- create_info.oldSwapchain = VK_NULL_HANDLE;
+ create_info.oldSwapchain = swapchain;
VKRESULT(vkCreateSwapchainKHR(device, &create_info, nullptr, &swapchain))
+
swapchain_images_count = 0;
VKRESULT(vkGetSwapchainImagesKHR(device, swapchain, (uint32_t*)&swapchain_images_count, VK_NULL_HANDLE))
@@ -520,6 +542,37 @@ void vkrenderer::create_semaphores() {
}
}
+void vkrenderer::create_input_buffer(const input_data& inputs) {
+ // Create and fill input data buffer
+ VkBufferCreateInfo buffer_info = { };
+ buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ buffer_info.size = sizeof(inputs);
+ buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
+
+ VmaAllocationCreateInfo alloc_create_info = {};
+ alloc_create_info.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
+
+ VmaAllocation allocation;
+ vmaCreateBuffer(allocator, &buffer_info, &alloc_create_info, &compute_shader_buffer, &allocation, nullptr);
+
+ vmaMapMemory(allocator, allocation, (void**) &mapped_data);
+ std::memcpy(mapped_data, &inputs, sizeof(inputs));
+}
+
+
+void vkrenderer::destroy_swapchain() {
+ if (swapchain != VK_NULL_HANDLE) {
+ for (auto view: swapchain_images_views) {
+ vkDestroyImageView(device, view, nullptr);
+ }
+
+ swapchain_images_views.clear();
+ swapchain_images.clear();
+
+ vkDestroySwapchainKHR(device, swapchain, nullptr);
+ }
+}
+
void vkrenderer::select_physical_device() {
uint32_t physical_devices_count = 0;
vkEnumeratePhysicalDevices(instance, &physical_devices_count, nullptr);
@@ -553,25 +606,9 @@ void vkrenderer::select_compute_queue() {
exit(1);
}
-void vkrenderer::update_sets(const input_data& inputs) {
- // Create and fill input data buffer
- VkBufferCreateInfo buffer_info = { };
- buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
- buffer_info.size = sizeof(inputs);
- buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
-
- VmaAllocationCreateInfo alloc_create_info = {};
- alloc_create_info.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
-
- VmaAllocation allocation;
- vmaCreateBuffer(allocator, &buffer_info, &alloc_create_info, &compute_shader_buffer, &allocation, nullptr);
-
- vmaMapMemory(allocator, allocation, (void**) &mapped_data);
- std::memcpy(mapped_data, &inputs, sizeof(inputs));
-
+void vkrenderer::update_descriptors_buffer() {
std::vector<VkDescriptorBufferInfo> descriptors_buf_info { swapchain_images_count };
- std::vector<VkDescriptorImageInfo> descriptors_image_info { swapchain_images_count };
- std::vector<VkWriteDescriptorSet> write_descriptors { swapchain_images_count * 2 };
+ std::vector<VkWriteDescriptorSet> write_descriptors { swapchain_images_count };
for (size_t set_index = 0; set_index < swapchain_images_count; set_index++) {
// Update uniform buffer descriptor
@@ -579,34 +616,51 @@ void vkrenderer::update_sets(const input_data& inputs) {
descriptors_buf_info[set_index].offset = 0;
descriptors_buf_info[set_index].range = VK_WHOLE_SIZE;
- write_descriptors[set_index * 2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- write_descriptors[set_index * 2].pNext = nullptr;
- write_descriptors[set_index * 2].dstSet = compute_shader_sets[set_index];
- write_descriptors[set_index * 2].dstBinding = 0;
- write_descriptors[set_index * 2].dstArrayElement = 0;
- write_descriptors[set_index * 2].descriptorCount = 1;
- write_descriptors[set_index * 2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
- write_descriptors[set_index * 2].pImageInfo = VK_NULL_HANDLE;
- write_descriptors[set_index * 2].pBufferInfo = &descriptors_buf_info[set_index];
- write_descriptors[set_index * 2].pTexelBufferView = VK_NULL_HANDLE;
+ write_descriptors[set_index].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ write_descriptors[set_index].pNext = nullptr;
+ write_descriptors[set_index].dstSet = compute_shader_sets[set_index];
+ write_descriptors[set_index].dstBinding = 0;
+ write_descriptors[set_index].dstArrayElement = 0;
+ write_descriptors[set_index].descriptorCount = 1;
+ write_descriptors[set_index].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ write_descriptors[set_index].pImageInfo = VK_NULL_HANDLE;
+ write_descriptors[set_index].pBufferInfo = &descriptors_buf_info[set_index];
+ write_descriptors[set_index].pTexelBufferView = VK_NULL_HANDLE;
+ }
+
+ vkUpdateDescriptorSets(device, write_descriptors.size(), write_descriptors.data(), 0, nullptr);
+}
+void vkrenderer::update_descriptors_image() {
+ std::vector<VkDescriptorImageInfo> descriptors_image_info { swapchain_images_count };
+ std::vector<VkWriteDescriptorSet> write_descriptors { swapchain_images_count };
+ for (size_t set_index = 0; set_index < swapchain_images_count; set_index++) {
// Update storage image descriptor
- descriptors_image_info[set_index].sampler = VK_NULL_HANDLE;
- descriptors_image_info[set_index].imageView = swapchain_images_views[set_index];
- descriptors_image_info[set_index].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
+ descriptors_image_info[set_index].sampler = VK_NULL_HANDLE;
+ descriptors_image_info[set_index].imageView = swapchain_images_views[set_index];
+ descriptors_image_info[set_index].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
- write_descriptors[set_index * 2 + 1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- write_descriptors[set_index * 2 + 1].pNext = nullptr;
- write_descriptors[set_index * 2 + 1].dstSet = compute_shader_sets[set_index];
- write_descriptors[set_index * 2 + 1].dstBinding = 1;
- write_descriptors[set_index * 2 + 1].dstArrayElement = 0;
- write_descriptors[set_index * 2 + 1].descriptorCount = 1;
- write_descriptors[set_index * 2 + 1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
- write_descriptors[set_index * 2 + 1].pImageInfo = &descriptors_image_info[set_index];
- write_descriptors[set_index * 2 + 1].pBufferInfo = VK_NULL_HANDLE;
- write_descriptors[set_index * 2 + 1].pTexelBufferView = VK_NULL_HANDLE;
+ write_descriptors[set_index].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ write_descriptors[set_index].pNext = nullptr;
+ write_descriptors[set_index].dstSet = compute_shader_sets[set_index];
+ write_descriptors[set_index].dstBinding = 1;
+ write_descriptors[set_index].dstArrayElement = 0;
+ write_descriptors[set_index].descriptorCount = 1;
+ write_descriptors[set_index].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+ write_descriptors[set_index].pImageInfo = &descriptors_image_info[set_index];
+ write_descriptors[set_index].pBufferInfo = VK_NULL_HANDLE;
+ write_descriptors[set_index].pTexelBufferView = VK_NULL_HANDLE;
}
vkUpdateDescriptorSets(device, write_descriptors.size(), write_descriptors.data(), 0, nullptr);
}
+
+void vkrenderer::handle_swapchain_result(VkResult function_result) {
+ switch(function_result) {
+ case VK_ERROR_OUT_OF_DATE_KHR:
+ return recreate_swapchain();
+ default:
+ return;
+ }
+}
diff --git a/src/window.cpp b/src/window.cpp
index 489473b..7662295 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -1,4 +1,6 @@
#include "window.hpp"
+#include "vk-renderer.hpp"
+#include "utils.hpp"
#ifdef LINUX
window::window(uint32_t width, uint32_t height)
@@ -87,7 +89,7 @@ window::window(uint32_t width, uint32_t height)
void window::poll_events() {
MSG msg = {};
- while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
+ while (PeekMessage(&msg, win_handle, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
@@ -95,6 +97,23 @@ void window::poll_events() {
LRESULT window::message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) {
switch(umsg) {
+ case WM_QUIT: {
+ isOpen = false;
+ break;
+ }
+ case WM_SIZE: {
+ RECT rect;
+ if(GetWindowRect(hwnd, &rect))
+ {
+ width = rect.right - rect.left;
+ height = rect.bottom - rect.top;
+ }
+
+ if (renderer != nullptr) {
+ renderer->recreate_swapchain();
+ break;
+ }
+ }
default:
return DefWindowProc(hwnd, umsg, wparam, lparam);
}