diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d54f8b..63be47f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 3.13) project(inferno) +set(CMAKE_COMPILE_WARNING_AS_ERROR OFF) + # file(GLOB SRC "src/*.cpp" "src/graphics/*.cpp" "src/preview_renderer/*.cpp" "src/scene/*.cpp" "src/thirdparty/imgui/*.cpp" "src/preview_renderer/*.cpp") file(GLOB_RECURSE SRC "src/*.cpp") @@ -36,6 +38,13 @@ else() target_compile_options(inferno PRIVATE -g) target_compile_options(inferno PRIVATE -D_GLIBCXX_DEBUG) endif() + if (CMAKE_BUILD_TYPE MATCHES "Release") + target_compile_options(inferno PRIVATE -O3) + target_compile_options(inferno PRIVATE -march=native) + target_compile_options(inferno PRIVATE -DNDEBUG) + # allow warnings + target_compile_options(inferno PRIVATE -Wall) + endif() endif() # Compile shaders first.. diff --git a/src/graphics/device.hpp b/src/graphics/device.hpp index cf47af1..5a74ae5 100644 --- a/src/graphics/device.hpp +++ b/src/graphics/device.hpp @@ -6,7 +6,7 @@ namespace inferno::graphics { -#define VALIDATION_LAYERS_ENABLED 1 +// #define VALIDATION_LAYERS_ENABLED 1 #ifdef VALIDATION_LAYERS_ENABLED const std::vector VALIDATION_LAYERS = { "VK_LAYER_KHRONOS_validation", @@ -16,6 +16,7 @@ const std::vector VALIDATION_LAYERS = { const std::vector DEVICE_EXTENSIONS = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, + VK_EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_EXTENSION_NAME, }; struct VulkanRenderer; diff --git a/src/graphics/rendertarget.cpp b/src/graphics/rendertarget.cpp index 379f0f0..1afe173 100644 --- a/src/graphics/rendertarget.cpp +++ b/src/graphics/rendertarget.cpp @@ -129,30 +129,6 @@ void rendertarget_recreate(RenderTarget* target, VkExtent2D extent, VkFormat for target->Extent = extent; target->Format = format; - VkSamplerCreateInfo samplerInfo {}; - samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerInfo.magFilter = VK_FILTER_LINEAR; - samplerInfo.minFilter = VK_FILTER_LINEAR; - samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerInfo.anisotropyEnable = VK_FALSE; - samplerInfo.maxAnisotropy = 1.0f; - samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; - samplerInfo.unnormalizedCoordinates = VK_FALSE; - samplerInfo.compareEnable = VK_FALSE; - samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; - samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - samplerInfo.mipLodBias = 0.0f; - samplerInfo.minLod = 0.0f; - samplerInfo.maxLod = 0.0f; - - if (vkCreateSampler( - target->Device->VulkanDevice, &samplerInfo, nullptr, &target->Sampler) - != VK_SUCCESS) { - yolo::error("failed to create texture sampler!"); - } - target->TargetImage = new ImageAttachment(); create_image(target->Device, extent.width, extent.height, format, @@ -233,7 +209,14 @@ DynamicCPUTarget* dynamic_rendertarget_create( return target; } -void dynamic_rendertarget_cleanup(DynamicCPUTarget* target) { } +void dynamic_rendertarget_cleanup(DynamicCPUTarget* target) +{ + vkDestroyImageView(target->Device->VulkanDevice, target->ImageView, nullptr); + vkDestroyImage(target->Device->VulkanDevice, target->Image, nullptr); + vkFreeMemory(target->Device->VulkanDevice, target->Memory, nullptr); + vkDestroySampler(target->Device->VulkanDevice, target->Sampler, nullptr); + delete target; +} // TODO: We should do this with a double buffer but whatever void dynamic_rendertarget_update(DynamicCPUTarget* target, void* data, VkExtent2D size) @@ -283,4 +266,32 @@ void dynamic_rendertarget_update(DynamicCPUTarget* target, void* data, VkExtent2 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); } +void dynamic_rendertarget_recreate(DynamicCPUTarget* target, VkExtent2D extent) +{ + vkDestroyImageView(target->Device->VulkanDevice, target->ImageView, nullptr); + vkDestroyImage(target->Device->VulkanDevice, target->Image, nullptr); + vkFreeMemory(target->Device->VulkanDevice, target->Memory, nullptr); + + target->Extent = extent; + + // Create VkImage with Undefined + create_image(target->Device, extent.width, extent.height, target->Format, VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT + | VK_IMAGE_USAGE_SAMPLED_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->Image, target->Memory); + + target->ImageView + = create_image_view(target->Device, target->Image, target->Format, VK_IMAGE_ASPECT_COLOR_BIT); + + target->DescriptorSet = ImGui_ImplVulkan_AddTexture( + target->Sampler, target->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + // NOTE: This assumes that the image is in the UNDEFINED LAYOUT + // And also assumes that the cpu layout is floating point (4 bytes) and the image is + // RGBA + target->StagingBuffer = generic_buffer_create(target->Device, 0, + extent.width * extent.height * 4, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); +} + } diff --git a/src/graphics/rendertarget.hpp b/src/graphics/rendertarget.hpp index c3f45ad..377e4ad 100644 --- a/src/graphics/rendertarget.hpp +++ b/src/graphics/rendertarget.hpp @@ -67,4 +67,6 @@ void dynamic_rendertarget_cleanup(DynamicCPUTarget* target); void dynamic_rendertarget_update(DynamicCPUTarget* target, void* data, VkExtent2D size); +void dynamic_rendertarget_recreate(DynamicCPUTarget* target, VkExtent2D extent); + } diff --git a/src/graphics/vkrenderer.cpp b/src/graphics/vkrenderer.cpp index ceede56..d455030 100644 --- a/src/graphics/vkrenderer.cpp +++ b/src/graphics/vkrenderer.cpp @@ -204,9 +204,6 @@ void renderer_begin_pass( if (target == nullptr || target->TargetImage == nullptr) { yolo::error("Target image is null"); } - // print target details - yo::info("Target: {} {} {}", target->TargetImage->Image, target->TargetImage->Memory, - target->TargetImage->ImageView); VkImageMemoryBarrier imageMemoryBarrier {}; imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; diff --git a/src/inferno.cpp b/src/inferno.cpp index 8231697..bd0ca83 100644 --- a/src/inferno.cpp +++ b/src/inferno.cpp @@ -90,6 +90,7 @@ InfernoApp* inferno_create() app->Input = new InfernoInput; app->Scene = scene::scene_create(); app->MainTimer = inferno_timer_create(); + app->FrameCount = 0; graphics::camera_set_position(app->Scene->Camera, { 0.0f, 1.0f, 3.1f }); @@ -128,11 +129,11 @@ InfernoApp* inferno_create() // scene::scene_object_load(object, "res/sponza.obj"); scene::scene_object_load(object, "res/cornell-box.obj"); scene::scene_add_object(app->Scene, object); - - scene::SceneObject* lucy = scene::scene_object_create(app->Device); - scene::scene_object_load(lucy, "res/lucy.obj"); - scene::scene_object_optimize(lucy); - scene::scene_add_object(app->Scene, lucy); + // + // scene::SceneObject* lucy = scene::scene_object_create(app->Device); + // scene::scene_object_load(lucy, "res/lucy.obj"); + // scene::scene_object_optimize(lucy); + // scene::scene_add_object(app->Scene, lucy); app->RayRenderer = graphics::rayr_create(app->Renderer, app->Scene); @@ -352,6 +353,16 @@ int inferno_run(InfernoApp* app) } if (ImGui::Begin("Render")) { + // static ImVec2 lastViewport = { 0, 0 }; + // ImVec2 currentViewport = ImGui::GetWindowSize(); + // if (lastViewport.x != currentViewport.x + // || lastViewport.y != currentViewport.y) { + // graphics::camera_ray_set_viewport(scene::scene_get_camera(app->Scene), + // { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y }); + // graphics::rayr_set_viewport(app->RayRenderer, app->Scene->Camera); + // } + // lastViewport = currentViewport; + graphics::rayr_draw(app->RayRenderer); ImTextureID texture diff --git a/src/preview/renderer.cpp b/src/preview/renderer.cpp index 7d78214..04667ff 100644 --- a/src/preview/renderer.cpp +++ b/src/preview/renderer.cpp @@ -77,7 +77,6 @@ void preview_draw(PreviewRenderer* renderer, scene::Scene* scene) renderer->Viewport.extent, VK_FORMAT_R8G8B8A8_UNORM); } - yolo::info("Drawing preview"); graphics::renderer_begin_pass( renderer->Renderer, renderer->PreviewRenderTarget, renderer->Viewport); diff --git a/src/raytracing/object_tracer.cpp b/src/raytracing/object_tracer.cpp index ac727a3..3da0e83 100644 --- a/src/raytracing/object_tracer.cpp +++ b/src/raytracing/object_tracer.cpp @@ -50,12 +50,12 @@ HitInfo* object_ray_collide(scene::SceneObject* object, Ray* ray) const uint32_t* ind; const float* verts; const float* norms; - // mesh->getIndicies(&ind); - // mesh->getVerticies(&verts, &norms); + scene::mesh_get_indicies(mesh, &ind); + scene::mesh_get_verticies(mesh, &verts, &norms); float t = INFINITY; - int i ; - // for (int i = 0; i < mesh->getIndexCount(); i += 3) { + int i; + for (int i = 0; i < scene::mesh_get_index_count(mesh); i += 3) { uint32_t indexa = ind[i + 0]; uint32_t indexb = ind[i + 1]; uint32_t indexc = ind[i + 2]; @@ -72,7 +72,7 @@ HitInfo* object_ray_collide(scene::SceneObject* object, Ray* ray) t = temp_t; info->Distance = t; } - // } + } } return info; } diff --git a/src/raytracing/renderer.cpp b/src/raytracing/renderer.cpp index c73556e..85bf672 100644 --- a/src/raytracing/renderer.cpp +++ b/src/raytracing/renderer.cpp @@ -32,18 +32,21 @@ RayRenderer* rayr_create(VulkanRenderer* renderer, scene::Scene* scene) ray->Renderer = renderer; auto camera = scene::scene_get_camera(scene); - rayr_set_viewport(ray, camera); + ray->Viewport.offset.x = 0; + ray->Viewport.offset.y = 0; + ray->Viewport.extent.width = camera_ray_get_viewport(camera).x; + ray->Viewport.extent.height = camera_ray_get_viewport(camera).y; + ray->HasViewportChanged = true; + ray->RenderData = new glm::fvec4[ray->Viewport.extent.width * ray->Viewport.extent.height]; memset(ray->RenderData, 0, ray->Viewport.extent.width * ray->Viewport.extent.height * sizeof(glm::fvec4)); - // TODO: We need to upload RenderData to the GPU / maybe do a quad pass ? I think - // ImGui handels that - ray->RayRenderTarget = graphics::dynamic_rendertarget_create( renderer->Device, ray->Viewport.extent, VK_FORMAT_R32G32B32A32_SFLOAT); + rayr_set_viewport(ray, camera); return ray; } @@ -60,6 +63,16 @@ void rayr_set_viewport(RayRenderer* renderer, Camera* camera) renderer->Viewport.extent.width = viewport.x; renderer->Viewport.extent.height = viewport.y; renderer->HasViewportChanged = true; + + delete[] renderer->RenderData; + renderer->RenderData + = new glm::fvec4[renderer->Viewport.extent.width * renderer->Viewport.extent.height]; + memset(renderer->RenderData, 0, + renderer->Viewport.extent.width * renderer->Viewport.extent.height * sizeof(glm::fvec4)); + + // Now resize the rendertarget + graphics::dynamic_rendertarget_recreate( + renderer->RayRenderTarget, renderer->Viewport.extent); } DynamicCPUTarget* rayr_get_target(RayRenderer* renderer) @@ -72,7 +85,7 @@ glm::fvec4* rayr_get_render_data(RayRenderer* renderer) { return renderer->Rende void rayr_prepare(RayRenderer* renderer) { // TODO: This is TEMP - memset(renderer->RenderData, 0, + memset(renderer->RenderData, 1, renderer->Viewport.extent.width * renderer->Viewport.extent.height * sizeof(glm::fvec4)); @@ -97,7 +110,8 @@ void rayr_draw(RayRenderer* renderer) for (int x = 0; x < renderer->Viewport.extent.width; x++) { for (int y = 0; y < renderer->Viewport.extent.height; y++) { rays::Ray* ray = startRays.Field[x * renderer->Viewport.extent.height + y]; - renderer->RenderData[y * renderer->Viewport.extent.width + x] = glm::vec4(ray->Direction, 1.0); + renderer->RenderData[y * renderer->Viewport.extent.width + x] + = { ray->Direction.x, ray->Direction.y, ray->Direction.z, 1.0 }; // rays::HitInfo* closest_hit = nullptr; // // for (auto& obj : scene::scene_get_renderables(renderer->Scene)) { diff --git a/src/scene/mesh.cpp b/src/scene/mesh.cpp index 646bb86..12f1fc5 100644 --- a/src/scene/mesh.cpp +++ b/src/scene/mesh.cpp @@ -62,6 +62,8 @@ void mesh_process(Mesh* out, aiMesh* mesh) = glm::vec3(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z), }; + out->Positions.push_back(vertex.Position); + out->Normals.push_back(vertex.Normal); out->Verticies.push_back(vertex); } @@ -91,9 +93,10 @@ void mesh_ready(Mesh* mesh) yolo::debug("Mesh for preview ready..."); } -// TODO: Extract vertex and normal data from internal mesh uint32_t mesh_get_verticies(Mesh* mesh, const float** v, const float** n) { + *v = (float*)mesh->Positions.data(); + *n = (float*)mesh->Normals.data(); return mesh->Verticies.size(); } diff --git a/src/scene/mesh.hpp b/src/scene/mesh.hpp index 155184c..8812d7d 100644 --- a/src/scene/mesh.hpp +++ b/src/scene/mesh.hpp @@ -39,6 +39,10 @@ typedef struct Mesh { glm::mat4 ModelMatrix; std::vector Verticies; + + std::vector Positions; + std::vector Normals; + std::vector Indicies; graphics::Buffer* VertexBuffer;