diff --git a/meson.build b/meson.build index 21cf34e..9383111 100644 --- a/meson.build +++ b/meson.build @@ -15,7 +15,6 @@ cpp_args=[ '-Wno-unused-parameter', '-Wno-unused-function', '-Wno-unused-variable', - '-Wno-unused-but-set-variable', '-Wno-conversion', '-Wno-missing-field-initializers' ] diff --git a/vk_engine.cpp b/vk_engine.cpp index 2561548..ed4fe8f 100644 --- a/vk_engine.cpp +++ b/vk_engine.cpp @@ -1,6 +1,4 @@ -#define GLM_ENABLE_EXPERIMENTAL 1 -#include -#include "vk_engine.h" +#include "vk_engine.h" #include "vk_images.h" #include "vk_pipelines.h" #include @@ -60,11 +58,6 @@ void VulkanEngine::cleanup() _frames[i]._deletionQueue.flush(); } - for(auto& mesh : testMeshes) { - destroy_buffer(mesh->meshBuffers.indexBuffer); - destroy_buffer(mesh->meshBuffers.vertexBuffer); - } - _mainDeletionQueue.flush(); destroy_swapchain(); @@ -152,21 +145,14 @@ void VulkanEngine::draw() draw_background(t.cmd); - vkutil::transition_image(t.cmd, _drawImage.image, - VK_IMAGE_LAYOUT_GENERAL, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - - vkutil::transition_image(t.cmd, _depthImage.image, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); - - // ZED: why does removing this make the monkey work? - vkutil::transition_image(t.cmd, _drawImage.image, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + vkutil::transition_image(t.cmd, _drawImage.image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); draw_geometry(t.cmd); + // ZED: ? + vkutil::transition_image(t.cmd, _drawImage.image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + // ZED: ? vkutil::transition_image(t.cmd, _swapchainImages[t.swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); @@ -187,17 +173,14 @@ void VulkanEngine::draw() commit_transaction(t); } - void VulkanEngine::draw_geometry(VkCommandBuffer cmd) { - auto colorAttachment = vkinit::attachment_info(_drawImage.imageView, nullptr, VK_IMAGE_LAYOUT_GENERAL); - auto depthAttachment = vkinit::depth_attachment_info(_depthImage.imageView, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); + VkRenderingAttachmentInfo colorAttachment = vkinit::attachment_info(_drawImage.imageView, nullptr, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - // ZED: this changed from _drawExtent to _windowExtent. Why? - auto renderInfo = vkinit::rendering_info(_windowExtent, &colorAttachment, &depthAttachment); + VkRenderingInfo renderInfo = vkinit::rendering_info(_drawExtent, &colorAttachment, nullptr); vkCmdBeginRendering(cmd, &renderInfo); - vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, _meshPipeline); + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, _trianglePipeline); VkViewport viewport{ .x = 0, @@ -217,25 +200,28 @@ void VulkanEngine::draw_geometry(VkCommandBuffer cmd) vkCmdSetScissor(cmd, 0, 1, &scissor); - GPUDrawPushConstants push_constants{}; + vkCmdDraw(cmd, 3, 1, 0, 0); + + // draw rectangle + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, _meshPipeline); + + GPUDrawPushConstants push_constants{ + .worldMatrix = glm::mat4{ 1.0f }, + .vertexBuffer = rectangle.vertexBufferAddress, + }; vkCmdPushConstants(cmd, _meshPipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(GPUDrawPushConstants), &push_constants); + vkCmdBindIndexBuffer(cmd, rectangle.indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32); + + vkCmdDrawIndexed(cmd, 6, 1, 0, 0, 0); + // draw monkey size_t model_idx = 2; // 0 cube; 1 sphere; 2 monkey push_constants.vertexBuffer = testMeshes[model_idx]->meshBuffers.vertexBufferAddress; - glm::mat4 view = glm::translate(glm::vec3{0, 0, -5}); - // camera projection - glm::mat4 projection = glm::perspective(glm::radians(70.0f), (float)_drawExtent.width / (float)_drawExtent.height, 10000.0f, 0.1f); - - // invert Y direction on projection matrix so that we are smaller to opengl and gltf axis - projection[1][1] *= -1; - - push_constants.worldMatrix = projection * view; - vkCmdPushConstants(cmd, _meshPipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, @@ -406,30 +392,10 @@ void VulkanEngine::init_swapchain() { VK_CHECK(vkCreateImageView(_device, &rview_info, nullptr, &_drawImage.imageView)); - - // add depth image - _depthImage.imageFormat = VK_FORMAT_D32_SFLOAT; - _depthImage.imageExtent = drawImageExtent; - VkImageUsageFlags depthImageUsages{}; - depthImageUsages |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - - VkImageCreateInfo dimg_info = vkinit::image_create_info(_depthImage.imageFormat, depthImageUsages, drawImageExtent); - - vmaCreateImage(_allocator, &dimg_info, &rimg_allocinfo, &_depthImage.image, &_depthImage.allocation, nullptr); - - VkImageViewCreateInfo dview_info = vkinit::imageview_create_info(_depthImage.imageFormat, _depthImage.image, VK_IMAGE_ASPECT_DEPTH_BIT); - - VK_CHECK(vkCreateImageView(_device, &dview_info, nullptr, &_depthImage.imageView)); - - - //add to deletion queues _mainDeletionQueue.push_function([=, this]() { vkDestroyImageView(_device, _drawImage.imageView, nullptr); vmaDestroyImage(_allocator, _drawImage.image, _drawImage.allocation); - - vkDestroyImageView(_device, _depthImage.imageView, nullptr); - vmaDestroyImage(_allocator, _depthImage.image, _depthImage.allocation); }); } @@ -537,6 +503,7 @@ void VulkanEngine::init_descriptors() { void VulkanEngine::init_pipelines() { init_background_pipelines(); + init_triangle_pipelines(); init_mesh_pipeline(); init_shaders(); } @@ -679,11 +646,9 @@ void VulkanEngine::init_mesh_pipeline() pipelineBuilder.set_cull_mode(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE); pipelineBuilder.set_multisampling_none(); pipelineBuilder.disable_blending(); - - pipelineBuilder.enable_depthtest(true, VK_COMPARE_OP_GREATER_OR_EQUAL); - + pipelineBuilder.disable_depthtest(); pipelineBuilder.set_color_attachment_format(_drawImage.imageFormat); - pipelineBuilder.set_depth_format(_depthImage.imageFormat); + pipelineBuilder.set_depth_format(VK_FORMAT_UNDEFINED); _meshPipeline = pipelineBuilder.build_pipeline(_device); vkDestroyShaderModule(_device, triangleFragShader, nullptr); @@ -696,6 +661,53 @@ void VulkanEngine::init_mesh_pipeline() } +void VulkanEngine::init_triangle_pipelines() +{ + VkShaderModule triangleFragShader; + + if(!vkutil::load_shader_module("colored_triangle.frag.spv",_device, &triangleFragShader)) { + std::print("Error when building the triangle fragment shaders module"); + } else { + std::print("Triangle fragment shader successfully loaded"); + } + + VkShaderModule triangleVertexShader; + if(!vkutil::load_shader_module("colored_triangle.vert.spv", _device, &triangleVertexShader)) { + std::println("Error when building the triangle, vertex shader module"); + } else { + std::println("Triangle vertex shader successfully loaded"); + } + + VkPipelineLayoutCreateInfo pipeline_layout_info = vkinit::pipeline_layout_create_info(); + + VK_CHECK(vkCreatePipelineLayout(_device, &pipeline_layout_info, nullptr, &_trianglePipelineLayout)); + + PipelineBuilder pipelineBuilder; + + pipelineBuilder._pipelineLayout = _trianglePipelineLayout; + pipelineBuilder.set_shaders(triangleVertexShader, triangleFragShader); + pipelineBuilder.set_input_topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); + pipelineBuilder.set_polygon_mode(VK_POLYGON_MODE_FILL); + pipelineBuilder.set_cull_mode(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE); + pipelineBuilder.set_multisampling_none(); + pipelineBuilder.disable_blending(); + pipelineBuilder.disable_depthtest(); + + // connect the image format we will drw into, from draw image + pipelineBuilder.set_color_attachment_format(_drawImage.imageFormat); + pipelineBuilder.set_depth_format(VK_FORMAT_UNDEFINED); + + _trianglePipeline = pipelineBuilder.build_pipeline(_device); + + vkDestroyShaderModule(_device, triangleFragShader, nullptr); + vkDestroyShaderModule(_device, triangleVertexShader, nullptr); + + _mainDeletionQueue.push_function([&]() { + vkDestroyPipelineLayout(_device, _trianglePipelineLayout, nullptr); + vkDestroyPipeline(_device, _trianglePipeline, nullptr); + }); +} + AllocatedBuffer VulkanEngine::create_buffer(size_t allocSize, VkBufferUsageFlags usage, VmaMemoryUsage memoryUsage) { @@ -784,8 +796,37 @@ GPUMeshBuffers VulkanEngine::uploadMesh(std::span indices, std::span rect_vertices; + + rect_vertices[0].position = {0.5,-0.5, 0}; + rect_vertices[1].position = {0.5,0.5, 0}; + rect_vertices[2].position = {-0.5,-0.5, 0}; + rect_vertices[3].position = {-0.5,0.5, 0}; + + rect_vertices[0].color = {0,0, 0,1}; + rect_vertices[1].color = { 0.5,0.5,0.5 ,1}; + rect_vertices[2].color = { 1,0, 0,1 }; + rect_vertices[3].color = { 0,1, 0,1 }; + + std::array rect_indices; + + rect_indices[0] = 0; + rect_indices[1] = 1; + rect_indices[2] = 2; + + rect_indices[3] = 2; + rect_indices[4] = 1; + rect_indices[5] = 3; + + rectangle = uploadMesh(rect_indices, rect_vertices); + auto basicmesh = loadGltfMeshes(this, "./basicmesh.glb"); assert(basicmesh != std::nullopt && "Failed to load basicmesh.glb"); testMeshes = *basicmesh; + + _mainDeletionQueue.push_function([&](){ + destroy_buffer(rectangle.indexBuffer); + destroy_buffer(rectangle.vertexBuffer); + }); } diff --git a/vk_engine.h b/vk_engine.h index fdd79b4..1875146 100644 --- a/vk_engine.h +++ b/vk_engine.h @@ -67,10 +67,10 @@ public: std::vector _swapchainImageViews; VkExtent2D _swapchainExtent; + // VMA stuff VmaAllocator _allocator; - // frames/command buffer unsigned int _frameNumber = 0; FrameData _frames[FRAME_OVERLAP]; @@ -84,7 +84,6 @@ public: // draw resources AllocatedImage _drawImage; - AllocatedImage _depthImage; VkExtent2D _drawExtent; // internal data @@ -101,6 +100,7 @@ public: VkPipelineLayout _meshPipelineLayout; VkPipeline _meshPipeline; + GPUMeshBuffers rectangle; std::vector> testMeshes; // ZED's REFACTOR @@ -136,6 +136,7 @@ private: void init_pipelines(); void init_background_pipelines(); void init_shaders(); + void init_triangle_pipelines(); void init_mesh_pipeline(); void init_default_data(); diff --git a/vk_initializers.cpp b/vk_initializers.cpp index 6641f6a..b54c78c 100644 --- a/vk_initializers.cpp +++ b/vk_initializers.cpp @@ -143,26 +143,6 @@ VkRenderingAttachmentInfo vkinit::attachment_info( } -VkRenderingAttachmentInfo vkinit::depth_attachment_info( -VkImageView view, VkImageLayout layout /*= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL*/) -{ - - VkRenderingAttachmentInfo depthAttachment{ - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .pNext = nullptr, - - .imageView = view, - .imageLayout = layout, - .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - }; - - depthAttachment.clearValue.depthStencil.depth = 0.0f; - - return depthAttachment; -} - - VkRenderingInfo vkinit::rendering_info(VkExtent2D renderExtent, VkRenderingAttachmentInfo* colorAttachment, VkRenderingAttachmentInfo* depthAttachment) { diff --git a/vk_initializers.h b/vk_initializers.h index 30caa42..3cec09a 100644 --- a/vk_initializers.h +++ b/vk_initializers.h @@ -39,7 +39,5 @@ namespace vkinit { VkPipelineShaderStageCreateInfo pipeline_shader_stage_create_info(VkShaderStageFlagBits stage, VkShaderModule shader, const char* entry="main"); VkPipelineLayoutCreateInfo pipeline_layout_create_info(); - -VkRenderingAttachmentInfo depth_attachment_info(VkImageView view, VkImageLayout layout= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); } diff --git a/vk_loader.cpp b/vk_loader.cpp index dcebbb8..8d077d1 100644 --- a/vk_loader.cpp +++ b/vk_loader.cpp @@ -11,112 +11,125 @@ #include #include -constexpr bool OverrideColors = true; - std::optional>> loadGltfMeshes(VulkanEngine* engine, std::filesystem::path filePath) { - std::print("Loading GLTF {}", filePath.string()); +//> openmesh + std::cout << "\nLoading GLTF: " << filePath << std::endl; - fastgltf::GltfDataBuffer data{}; - data.loadFromFile(filePath); + fastgltf::GltfDataBuffer data; + data.loadFromFile(filePath); - constexpr auto gltfOptions = fastgltf::Options::LoadGLBBuffers | fastgltf::Options::LoadExternalBuffers; + constexpr auto gltfOptions = fastgltf::Options::LoadGLBBuffers + | fastgltf::Options::LoadExternalBuffers; - fastgltf::Asset gltf; - fastgltf::Parser parser{}; + fastgltf::Asset gltf; + fastgltf::Parser parser {}; - if(auto load = parser.loadBinaryGLTF(&data, filePath.parent_path(), gltfOptions)) { - gltf = std::move(load.get()); - } else { - std::print("Failed to load glTF: {}\n", fastgltf::to_underlying(load.error())); - } + auto load = parser.loadBinaryGLTF(&data, filePath.parent_path(), gltfOptions); + if (load) { + gltf = std::move(load.get()); + } else { + std::print("Failed to load glTF: {} \n", fastgltf::to_underlying(load.error())); + return {}; + } +//< openmesh +//> loadmesh + std::vector> meshes; - std::vector> meshes; + // use the same vectors for all meshes so that the memory doesnt reallocate as + // often + std::vector indices; + std::vector vertices; + for (fastgltf::Mesh& mesh : gltf.meshes) { + MeshAsset newmesh; - std::vector indices; - std::vector vertices; + newmesh.name = mesh.name; - for(fastgltf::Mesh& mesh : gltf.meshes) { - auto newmesh = std::make_shared(); - newmesh->name = mesh.name; + // clear the mesh arrays each mesh, we dont want to merge them by error + indices.clear(); + vertices.clear(); - indices.clear(); - vertices.clear(); + for (auto&& p : mesh.primitives) { + GeoSurface newSurface; + newSurface.startIndex = (uint32_t)indices.size(); + newSurface.count = (uint32_t)gltf.accessors[p.indicesAccessor.value()].count; - for(auto&& p : mesh.primitives) { - // have to do this here because p.indicesAccessor changes...for reasons - newmesh->surfaces.emplace_back( - (uint32_t)indices.size(), - (uint32_t)gltf.accessors[p.indicesAccessor.value()].count); + size_t initial_vtx = vertices.size(); - size_t initial_vtx = vertices.size(); + // load indexes + { + fastgltf::Accessor& indexaccessor = gltf.accessors[p.indicesAccessor.value()]; + indices.reserve(indices.size() + indexaccessor.count); - // load indexes - { - fastgltf::Accessor& indexaccessor = gltf.accessors[p.indicesAccessor.value()]; - indices.reserve(indices.size() + indexaccessor.count); - fastgltf::iterateAccessor(gltf, indexaccessor, - [&](std::uint32_t idx) { - indices.emplace_back(idx + initial_vtx); - }); - } + fastgltf::iterateAccessor(gltf, indexaccessor, + [&](std::uint32_t idx) { + indices.push_back(idx + initial_vtx); + }); + } - // load vertex positions - { - fastgltf::Accessor& posAccessor = gltf.accessors[p.findAttribute("POSITION")->second]; - vertices.resize(vertices.size() + posAccessor.count); + // load vertex positions + { + fastgltf::Accessor& posAccessor = gltf.accessors[p.findAttribute("POSITION")->second]; + vertices.resize(vertices.size() + posAccessor.count); - fastgltf::iterateAccessorWithIndex(gltf, posAccessor, - [&](glm::vec3 v, size_t index) { - vertices[initial_vtx + index] = { - .position = v, - .uv_x = 0, - .normal = { 1, 0, 0 }, - .uv_y = 0, - .color = glm::vec4 { 1.0f}, - }; - }); - } + fastgltf::iterateAccessorWithIndex(gltf, posAccessor, + [&](glm::vec3 v, size_t index) { + Vertex newvtx; + newvtx.position = v; + newvtx.normal = { 1, 0, 0 }; + newvtx.color = glm::vec4 { 1.f }; + newvtx.uv_x = 0; + newvtx.uv_y = 0; + vertices[initial_vtx + index] = newvtx; + }); + } - // load vertex normals - auto normals = p.findAttribute("NORMAL"); - if(normals != p.attributes.end()) { - fastgltf::iterateAccessorWithIndex(gltf, gltf.accessors[(*normals).second], - [&](glm::vec3 v, size_t index) { - vertices[initial_vtx + index].normal = v; - }); - } + // load vertex normals + auto normals = p.findAttribute("NORMAL"); + if (normals != p.attributes.end()) { - // load UVs - auto uv = p.findAttribute("TEXCOORD_0"); - if(uv != p.attributes.end()) { - fastgltf::iterateAccessorWithIndex(gltf, gltf.accessors[(*uv).second], - [&](glm::vec2 v, size_t index) { - vertices[initial_vtx + index].uv_x = v.x; - vertices[initial_vtx + index].uv_y = v.y; - }); - } + fastgltf::iterateAccessorWithIndex(gltf, gltf.accessors[(*normals).second], + [&](glm::vec3 v, size_t index) { + vertices[initial_vtx + index].normal = v; + }); + } - // load vertex colors - auto colors = p.findAttribute("COLOR_0"); - if(colors != p.attributes.end()) { - fastgltf::iterateAccessorWithIndex(gltf, gltf.accessors[(*colors).second], - [&](glm::vec4 v, size_t index) { - vertices[initial_vtx + index].color = v; - }); - } + // load UVs + auto uv = p.findAttribute("TEXCOORD_0"); + if (uv != p.attributes.end()) { + + fastgltf::iterateAccessorWithIndex(gltf, gltf.accessors[(*uv).second], + [&](glm::vec2 v, size_t index) { + vertices[initial_vtx + index].uv_x = v.x; + vertices[initial_vtx + index].uv_y = v.y; + }); + } + + // load vertex colors + auto colors = p.findAttribute("COLOR_0"); + if (colors != p.attributes.end()) { + + fastgltf::iterateAccessorWithIndex(gltf, gltf.accessors[(*colors).second], + [&](glm::vec4 v, size_t index) { + vertices[initial_vtx + index].color = v; + }); + } + newmesh.surfaces.push_back(newSurface); + } + + // display the vertex normals + constexpr bool OverrideColors = true; + if (OverrideColors) { + for (Vertex& vtx : vertices) { + vtx.color = glm::vec4(vtx.normal, 1.f); + } + } + newmesh.meshBuffers = engine->uploadMesh(indices, vertices); + + meshes.emplace_back(std::make_shared(std::move(newmesh))); } - if(OverrideColors) { - for(Vertex& vtx : vertices) { - vtx.color = glm::vec4(vtx.normal, 1.0f); - } - } + return meshes; - newmesh->meshBuffers = engine->uploadMesh(indices, vertices); - - meshes.emplace_back(newmesh); - } - - return meshes; +//< loadmesh } diff --git a/vk_pipelines.cpp b/vk_pipelines.cpp index dd47fa3..b7b3c8d 100644 --- a/vk_pipelines.cpp +++ b/vk_pipelines.cpp @@ -202,15 +202,3 @@ void PipelineBuilder::disable_depthtest() _depthStencil.minDepthBounds = 0.0f; _depthStencil.maxDepthBounds = 1.0f; } - -void PipelineBuilder::enable_depthtest(bool depthWriteEnable, VkCompareOp op) { - _depthStencil.depthTestEnable = VK_TRUE; - _depthStencil.depthWriteEnable = depthWriteEnable; - _depthStencil.depthCompareOp = op; - _depthStencil.depthBoundsTestEnable = VK_FALSE; - _depthStencil.stencilTestEnable = VK_FALSE; - _depthStencil.front = {}; - _depthStencil.back = {}; - _depthStencil.minDepthBounds = 0.0f; - _depthStencil.maxDepthBounds = 1.0f; -} diff --git a/vk_pipelines.h b/vk_pipelines.h index 782eafe..16b4067 100644 --- a/vk_pipelines.h +++ b/vk_pipelines.h @@ -31,7 +31,6 @@ class PipelineBuilder { void set_color_attachment_format(VkFormat format); void set_depth_format(VkFormat format); void disable_depthtest(); - void enable_depthtest(bool depthWriteEnable, VkCompareOp op); }; namespace vkutil {