Added a depth image
This commit is contained in:
parent
86257df3e8
commit
f418ccabbc
@ -25,6 +25,8 @@
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
// Custom headers
|
||||
//#include "callbacks.h"
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
// Normal header
|
||||
|
||||
// Current progress
|
||||
// 3 - Graphics Pipeline - Doing mesh buffers
|
||||
// 3 - Graphics Pipeline - Doing depth image creation in swapchain init
|
||||
|
||||
#include "descriptors.h" // Required for public interface custom allocator
|
||||
#include "Common/Types.h"
|
||||
@ -14,6 +14,7 @@
|
||||
#include <vulkan/vulkan_core.h>
|
||||
#include "imgui.h" // For types
|
||||
#include "imgui_memory_editor.h" // For mem edit
|
||||
#include "loader.h" // For MeshAsset
|
||||
|
||||
struct FrameData {
|
||||
VkCommandPool _commandPool;
|
||||
@ -83,6 +84,7 @@ class Engine {
|
||||
|
||||
// Draw resources
|
||||
AllocatedImage _drawImage;
|
||||
AllocatedImage _depthImage; // Depth testing
|
||||
VkExtent2D _drawExtent;
|
||||
|
||||
// Descriptor Sets
|
||||
@ -131,7 +133,7 @@ class Engine {
|
||||
|
||||
// Model
|
||||
std::string _modelPath { "models/basicmesh.glb" };
|
||||
|
||||
std::vector<std::shared_ptr<MeshAsset>> testMeshes;
|
||||
|
||||
void parseConfig(
|
||||
int gpuIndex,
|
||||
@ -152,6 +154,11 @@ class Engine {
|
||||
|
||||
// Public functions (for CLI args)
|
||||
void getAvailableGPU();
|
||||
// Meshes
|
||||
GPUMeshBuffers uploadMesh(
|
||||
std::span<uint32_t> indices,
|
||||
std::span<Vertex> vertices
|
||||
);
|
||||
|
||||
private:
|
||||
using enum LogModule;
|
||||
@ -183,12 +190,6 @@ class Engine {
|
||||
const AllocatedBuffer& buffer
|
||||
);
|
||||
|
||||
// Meshes
|
||||
GPUMeshBuffers uploadMesh(
|
||||
std::span<uint32_t> indices,
|
||||
std::span<Vertex> vertices
|
||||
);
|
||||
|
||||
// Random functions
|
||||
void createSwapchain(
|
||||
uint32_t width,
|
||||
@ -442,6 +443,12 @@ void Engine::draw() {
|
||||
VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||
);
|
||||
vkutil::transitionImage(
|
||||
cmd,
|
||||
_depthImage.image,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL
|
||||
);
|
||||
|
||||
drawGeometry(cmd);
|
||||
|
||||
@ -647,8 +654,6 @@ void Engine::initVulkan() {
|
||||
|
||||
if(_gpuIndex < 0) {
|
||||
// No overwrite, use VKB
|
||||
|
||||
|
||||
// Use vkBootstrap to select the GPU
|
||||
vkb::PhysicalDeviceSelector selector { vkbInst };
|
||||
vkb::PhysicalDevice physicalDevice = selector
|
||||
@ -728,7 +733,7 @@ void Engine::initVulkan() {
|
||||
_graphicsQueueFamily = queueFamily.value();
|
||||
|
||||
|
||||
// 3. Créer le device logique
|
||||
// Create logical device
|
||||
float queuePriority = 1.0f;
|
||||
VkDeviceQueueCreateInfo queueCreateInfo{};
|
||||
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
@ -743,13 +748,14 @@ void Engine::initVulkan() {
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||
};
|
||||
|
||||
VkDeviceCreateInfo deviceCreateInfo{};
|
||||
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
deviceCreateInfo.pNext = &features13;
|
||||
deviceCreateInfo.queueCreateInfoCount = 1;
|
||||
deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
|
||||
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
|
||||
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
|
||||
VkDeviceCreateInfo deviceCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
||||
.pNext = &features13,
|
||||
.queueCreateInfoCount = 1,
|
||||
.pQueueCreateInfos = &queueCreateInfo,
|
||||
.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size()),
|
||||
.ppEnabledExtensionNames = deviceExtensions.data()
|
||||
};
|
||||
|
||||
if (vkCreateDevice(_choosenGPU, &deviceCreateInfo, nullptr, &_device) != VK_SUCCESS) {
|
||||
throw std::runtime_error("[Engine:Error] Failed to create Vulkan device !");
|
||||
@ -758,11 +764,12 @@ void Engine::initVulkan() {
|
||||
vkGetDeviceQueue(_device, _graphicsQueueFamily, 0, &_graphicsQueue);
|
||||
}
|
||||
|
||||
VmaAllocatorCreateInfo allocatorInfo = {};
|
||||
allocatorInfo.physicalDevice = _choosenGPU;
|
||||
allocatorInfo.device = _device;
|
||||
allocatorInfo.instance = _instance;
|
||||
allocatorInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
|
||||
VmaAllocatorCreateInfo allocatorInfo = {
|
||||
.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT,
|
||||
.physicalDevice = _choosenGPU,
|
||||
.device = _device,
|
||||
.instance = _instance
|
||||
};
|
||||
|
||||
vmaCreateAllocator(&allocatorInfo, &_allocator);
|
||||
|
||||
@ -798,7 +805,6 @@ void Engine::initSwapchain() {
|
||||
};
|
||||
|
||||
// Hardcoding draw format to a 32 bit float
|
||||
|
||||
_drawImage.imageFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
_drawImage.imageExtent = drawImageExtent;
|
||||
|
||||
@ -850,8 +856,51 @@ void Engine::initSwapchain() {
|
||||
)
|
||||
);
|
||||
|
||||
// Add to deletion queues
|
||||
// Depth image
|
||||
_depthImage.imageFormat = VK_FORMAT_D32_SFLOAT;
|
||||
_depthImage.imageExtent = drawImageExtent;
|
||||
VkImageUsageFlags depthImageUsages {};
|
||||
depthImageUsages |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
|
||||
VkImageCreateInfo dImgInfo {
|
||||
vkinit::imageCreateInfo(
|
||||
_depthImage.imageFormat,
|
||||
depthImageUsages,
|
||||
drawImageExtent
|
||||
)
|
||||
};
|
||||
|
||||
// Allocate and create the image
|
||||
vmaCreateImage(
|
||||
_allocator,
|
||||
&dImgInfo,
|
||||
&rImgAllocInfo,
|
||||
&_depthImage.image,
|
||||
&_depthImage.allocation,
|
||||
nullptr
|
||||
);
|
||||
|
||||
// Build an image view for the draw image (used for rendering)
|
||||
VkImageViewCreateInfo dViewInfo {
|
||||
vkinit::imageViewCreateInfo(
|
||||
_depthImage.imageFormat,
|
||||
_depthImage.image,
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT
|
||||
)
|
||||
};
|
||||
|
||||
VK_CHECK(
|
||||
vkCreateImageView(
|
||||
_device,
|
||||
&dViewInfo,
|
||||
nullptr,
|
||||
&_depthImage.imageView
|
||||
)
|
||||
);
|
||||
|
||||
// Add to deletion queue
|
||||
_mainDeletionQueue.pushFunction([this]() {
|
||||
// Draw image
|
||||
vkDestroyImageView(
|
||||
_device,
|
||||
_drawImage.imageView,
|
||||
@ -862,6 +911,18 @@ void Engine::initSwapchain() {
|
||||
_drawImage.image,
|
||||
_drawImage.allocation
|
||||
);
|
||||
// Depth image
|
||||
vkDestroyImageView(
|
||||
_device,
|
||||
_depthImage.imageView,
|
||||
nullptr
|
||||
);
|
||||
|
||||
vmaDestroyImage(
|
||||
_allocator,
|
||||
_depthImage.image,
|
||||
_depthImage.allocation
|
||||
);
|
||||
});
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -1057,6 +1118,127 @@ void Engine::initDescriptors(){
|
||||
#endif
|
||||
}
|
||||
|
||||
void Engine::initImgui() {
|
||||
#ifdef DEBUG
|
||||
fmt::println("[Engine:Init] Initializing ImGui...");
|
||||
#endif
|
||||
// Oversized descriptor pool for IMGUI, from the official tutorial
|
||||
// Ajust for optimization, or needs
|
||||
|
||||
VkDescriptorPoolSize poolSizes[] = {
|
||||
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 }
|
||||
};
|
||||
|
||||
VkDescriptorPoolCreateInfo poolInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||
.maxSets = 1000,
|
||||
.poolSizeCount = (uint32_t)std::size(poolSizes),
|
||||
.pPoolSizes = poolSizes
|
||||
};
|
||||
|
||||
VkDescriptorPool imguiPool;
|
||||
VK_CHECK(
|
||||
vkCreateDescriptorPool(
|
||||
_device,
|
||||
&poolInfo,
|
||||
nullptr,
|
||||
&imguiPool
|
||||
);
|
||||
);
|
||||
|
||||
// Init IMGUI
|
||||
ImGui::CreateContext();
|
||||
|
||||
// Config
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
// Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
// Viewports
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
|
||||
// Init backends
|
||||
ImGui_ImplGlfw_InitForVulkan(
|
||||
window,
|
||||
true
|
||||
);
|
||||
|
||||
ImGui_ImplVulkan_InitInfo initInfo {
|
||||
.Instance = _instance,
|
||||
.PhysicalDevice = _choosenGPU,
|
||||
.Device = _device,
|
||||
.Queue = _graphicsQueue,
|
||||
.DescriptorPool = imguiPool,
|
||||
.MinImageCount = 3,
|
||||
.ImageCount = 3,
|
||||
.PipelineInfoMain = {
|
||||
.MSAASamples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.PipelineRenderingCreateInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachmentFormats = &_swapchainImageFormat
|
||||
}
|
||||
},
|
||||
.UseDynamicRendering = true
|
||||
};
|
||||
|
||||
ImGui_ImplVulkan_Init(&initInfo);
|
||||
|
||||
// Create a sampler for Viewport rendering
|
||||
VkSamplerCreateInfo samplerInfo = {};
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.anisotropyEnable = VK_FALSE;
|
||||
samplerInfo.maxAnisotropy = 1.0f;
|
||||
|
||||
VK_CHECK(vkCreateSampler(_device, &samplerInfo, nullptr, &_viewportSampler));
|
||||
|
||||
// Register the draw image as a texture for ImGui
|
||||
_viewportTextureID = ImGui_ImplVulkan_AddTexture(
|
||||
_viewportSampler,
|
||||
_drawImage.imageView,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
);
|
||||
|
||||
_mainDeletionQueue.pushFunction([this, imguiPool]() {
|
||||
ImGui_ImplVulkan_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
vkDestroyDescriptorPool(
|
||||
_device,
|
||||
imguiPool,
|
||||
nullptr
|
||||
);
|
||||
vkDestroySampler(
|
||||
_device,
|
||||
_viewportSampler,
|
||||
nullptr
|
||||
);
|
||||
});
|
||||
#ifdef DEBUG
|
||||
fmt::println("[Engine:Init] ImGui initialized !");
|
||||
#endif
|
||||
}
|
||||
|
||||
//=================
|
||||
//=== Pipelines ===
|
||||
//=================
|
||||
|
||||
void Engine::initPipelines() {
|
||||
#ifdef DEBUG
|
||||
_logger.logRAM(ENGINE, EINIT, "Initializing pipelines...");
|
||||
@ -1290,7 +1472,8 @@ void Engine::initTrianglePipeline() {
|
||||
|
||||
// Connect the image format we will draw into, from draw image
|
||||
pipelineBuilder.setColorAttachmentFormat(_drawImage.imageFormat);
|
||||
pipelineBuilder.setDepthFormat(VK_FORMAT_UNDEFINED);
|
||||
pipelineBuilder.setDepthFormat(_depthImage.imageFormat); // Why ?
|
||||
// Because validation errors, now it's the same format
|
||||
|
||||
// Finally build the pipeline
|
||||
_trianglePipeline = pipelineBuilder.buildPipeline(_device);
|
||||
@ -1357,11 +1540,20 @@ void Engine::initMeshPipeline() {
|
||||
// No blending
|
||||
pipelineBuilder.disableBlending();
|
||||
|
||||
pipelineBuilder.disableDepthtest();
|
||||
pipelineBuilder.enableDepthtest(
|
||||
true,
|
||||
VK_COMPARE_OP_GREATER_OR_EQUAL
|
||||
/*
|
||||
Greater or equal because
|
||||
0 is far and 1 is near, so
|
||||
render the pixels if the current value (depth)
|
||||
is greater than the value on the depth image
|
||||
*/
|
||||
);
|
||||
|
||||
// Connect the image format we will draw into, from draw image
|
||||
pipelineBuilder.setColorAttachmentFormat(_drawImage.imageFormat);
|
||||
pipelineBuilder.setDepthFormat(VK_FORMAT_UNDEFINED);
|
||||
pipelineBuilder.setDepthFormat(_depthImage.imageFormat);
|
||||
|
||||
// Finally build the pipeline
|
||||
_meshPipeline = pipelineBuilder.buildPipeline(_device);
|
||||
@ -1377,129 +1569,9 @@ void Engine::initMeshPipeline() {
|
||||
|
||||
#ifdef DEBUG
|
||||
_logger.logRAM(ENGINE, EINIT, "Mesh pipeline initialized !");
|
||||
std::cout << "sizeof(GPUDrawPushConstants) = " << sizeof(GPUDrawPushConstants) << std::endl;
|
||||
std::cout << "offsetof(GPUDrawPushConstants, worldMatrix) = " << offsetof(GPUDrawPushConstants, worldMatrix) << std::endl;
|
||||
std::cout << "offsetof(GPUDrawPushConstants, vertexBuffer) = " << offsetof(GPUDrawPushConstants, vertexBuffer) << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Engine::initImgui() {
|
||||
#ifdef DEBUG
|
||||
fmt::println("[Engine:Init] Initializing ImGui...");
|
||||
#endif
|
||||
// Oversized descriptor pool for IMGUI, from the official tutorial
|
||||
// Ajust for optimization, or needs
|
||||
|
||||
VkDescriptorPoolSize poolSizes[] = {
|
||||
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 }
|
||||
};
|
||||
|
||||
VkDescriptorPoolCreateInfo poolInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||
.maxSets = 1000,
|
||||
.poolSizeCount = (uint32_t)std::size(poolSizes),
|
||||
.pPoolSizes = poolSizes
|
||||
};
|
||||
|
||||
VkDescriptorPool imguiPool;
|
||||
VK_CHECK(
|
||||
vkCreateDescriptorPool(
|
||||
_device,
|
||||
&poolInfo,
|
||||
nullptr,
|
||||
&imguiPool
|
||||
);
|
||||
);
|
||||
|
||||
// Init IMGUI
|
||||
ImGui::CreateContext();
|
||||
|
||||
// Config
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
// Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
// Viewports
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
|
||||
// Init backends
|
||||
ImGui_ImplGlfw_InitForVulkan(
|
||||
window,
|
||||
true
|
||||
);
|
||||
|
||||
ImGui_ImplVulkan_InitInfo initInfo {
|
||||
.Instance = _instance,
|
||||
.PhysicalDevice = _choosenGPU,
|
||||
.Device = _device,
|
||||
.Queue = _graphicsQueue,
|
||||
.DescriptorPool = imguiPool,
|
||||
.MinImageCount = 3,
|
||||
.ImageCount = 3,
|
||||
.PipelineInfoMain = {
|
||||
.MSAASamples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.PipelineRenderingCreateInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachmentFormats = &_swapchainImageFormat
|
||||
}
|
||||
},
|
||||
.UseDynamicRendering = true
|
||||
};
|
||||
|
||||
ImGui_ImplVulkan_Init(&initInfo);
|
||||
|
||||
// Create a sampler for Viewport rendering
|
||||
VkSamplerCreateInfo samplerInfo = {};
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.anisotropyEnable = VK_FALSE;
|
||||
samplerInfo.maxAnisotropy = 1.0f;
|
||||
|
||||
VK_CHECK(vkCreateSampler(_device, &samplerInfo, nullptr, &_viewportSampler));
|
||||
|
||||
// Register the draw image as a texture for ImGui
|
||||
_viewportTextureID = ImGui_ImplVulkan_AddTexture(
|
||||
_viewportSampler,
|
||||
_drawImage.imageView,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
);
|
||||
|
||||
_mainDeletionQueue.pushFunction([this, imguiPool]() {
|
||||
ImGui_ImplVulkan_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
vkDestroyDescriptorPool(
|
||||
_device,
|
||||
imguiPool,
|
||||
nullptr
|
||||
);
|
||||
vkDestroySampler(
|
||||
_device,
|
||||
_viewportSampler,
|
||||
nullptr
|
||||
);
|
||||
});
|
||||
#ifdef DEBUG
|
||||
fmt::println("[Engine:Init] ImGui initialized !");
|
||||
#endif
|
||||
}
|
||||
|
||||
//====================================
|
||||
//=== Allocation-related Functions ===
|
||||
//====================================
|
||||
@ -1680,21 +1752,16 @@ void Engine::initDefaultData() {
|
||||
rectVertices
|
||||
);
|
||||
|
||||
// Delete the rectangle data on engine shutdown
|
||||
// Load the mesh
|
||||
testMeshes = loadGltfMeshes(this, _modelPath).value();
|
||||
|
||||
// Delete the default data on engine shutdown
|
||||
_mainDeletionQueue.pushFunction([this](){
|
||||
destroyBuffer(rectangle.indexBuffer);
|
||||
destroyBuffer(rectangle.vertexBuffer);
|
||||
});
|
||||
#ifdef DEBUG
|
||||
_logger.logRAM(ENGINE, EINIT, "Default data created !");
|
||||
for (size_t i = 0; i < rectIndices.size(); i++) {
|
||||
fmt::println(
|
||||
"index[{}] = {} ({:#x})",
|
||||
i,
|
||||
rectIndices[i],
|
||||
rectIndices[i]
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1774,6 +1841,11 @@ void Engine::buildImgui() {
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
// Depth image
|
||||
// Todo
|
||||
// But follows the same logic as viewport,
|
||||
// but does not resize dynamicly
|
||||
|
||||
// Shader control
|
||||
if(ImGui::Begin("Background Shader control")) {
|
||||
ComputeEffect& selected = backgroundEffects[currentBackgroundEffect];
|
||||
@ -1910,9 +1982,29 @@ void Engine::drawGeometry(
|
||||
uint32_t width = _drawExtent.width;
|
||||
uint32_t height = _drawExtent.height;
|
||||
// Begin rendering
|
||||
VkRenderingAttachmentInfo colorAttachment = vkinit::attachmentInfo(_drawImage.imageView, nullptr, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
// Some info structs
|
||||
VkRenderingAttachmentInfo colorAttachment {
|
||||
vkinit::attachmentInfo(
|
||||
_drawImage.imageView,
|
||||
nullptr,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||
)
|
||||
};
|
||||
VkRenderingAttachmentInfo depthAttachement {
|
||||
vkinit::depthAttachmentInfo(
|
||||
_depthImage.imageView,
|
||||
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL
|
||||
)
|
||||
};
|
||||
|
||||
VkRenderingInfo renderInfo {
|
||||
vkinit::renderingInfo(
|
||||
_drawExtent,
|
||||
&colorAttachment,
|
||||
&depthAttachement
|
||||
)
|
||||
};
|
||||
|
||||
VkRenderingInfo renderInfo = vkinit::renderingInfo(_drawExtent, &colorAttachment, nullptr);
|
||||
vkCmdBeginRendering(cmd, &renderInfo);
|
||||
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, _trianglePipeline);
|
||||
@ -1971,8 +2063,50 @@ void Engine::drawGeometry(
|
||||
VK_INDEX_TYPE_UINT32
|
||||
);
|
||||
|
||||
// Draw the rectangle
|
||||
vkCmdDrawIndexed(cmd, 6, 1, 0, 0, 0);
|
||||
|
||||
// Now the model
|
||||
// Correct the matrix
|
||||
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 the Y direction
|
||||
//projection[1][1] *= -1;
|
||||
//pushConstants.worldMatrix = projection * view;
|
||||
|
||||
pushConstants.vertexBuffer = testMeshes[2]->meshBuffers.vertexBufferAddress;
|
||||
vkCmdPushConstants(
|
||||
cmd,
|
||||
_meshPipelineLayout,
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0,
|
||||
sizeof(GPUDrawPushConstants),
|
||||
&pushConstants
|
||||
);
|
||||
vkCmdBindIndexBuffer(
|
||||
cmd,
|
||||
testMeshes[2]->meshBuffers.indexBuffer.buffer,
|
||||
0,
|
||||
VK_INDEX_TYPE_UINT32
|
||||
);
|
||||
|
||||
vkCmdDrawIndexed(
|
||||
cmd,
|
||||
testMeshes[2]->surfaces[0].count,
|
||||
1,
|
||||
testMeshes[2]->surfaces[0].startIndex,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
vkCmdEndRendering(cmd);
|
||||
}
|
||||
|
||||
@ -2187,6 +2321,7 @@ void Engine::resizeRenderImage(uint32_t width, uint32_t height) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// CLI functions
|
||||
void Engine::getAvailableGPU() {
|
||||
// Creates a temporary Vulkan Instance
|
||||
// Largely copied from initVulkan function
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define INITIALIZERS_H
|
||||
// Normal header
|
||||
#include "Common/Types.h"
|
||||
#include "simdjson.h"
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace vkinit {
|
||||
@ -64,6 +65,11 @@ namespace vkinit {
|
||||
VkImageLayout layout /*= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL*/
|
||||
);
|
||||
|
||||
VkRenderingAttachmentInfo depthAttachmentInfo(
|
||||
VkImageView view,
|
||||
VkImageLayout layout
|
||||
);
|
||||
|
||||
VkRenderingInfo renderingInfo(
|
||||
VkExtent2D renderExtent,
|
||||
VkRenderingAttachmentInfo* colorAttachment,
|
||||
@ -289,6 +295,27 @@ namespace vkinit {
|
||||
return colorAttachment;
|
||||
}
|
||||
|
||||
VkRenderingAttachmentInfo depthAttachmentInfo(
|
||||
VkImageView view,
|
||||
VkImageLayout layout
|
||||
) {
|
||||
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,
|
||||
.clearValue = {
|
||||
.depthStencil = {
|
||||
.depth = 0.0f
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return depthAttachment;
|
||||
}
|
||||
|
||||
VkRenderingInfo renderingInfo(
|
||||
VkExtent2D renderExtent,
|
||||
VkRenderingAttachmentInfo* colorAttachment,
|
||||
|
||||
@ -37,11 +37,14 @@ class Engine;
|
||||
#include <fastgltf/glm_element_traits.hpp>
|
||||
#include <fastgltf/tools.hpp>
|
||||
|
||||
constexpr bool OverrideColors = true;
|
||||
|
||||
std::optional<std::vector<std::shared_ptr<MeshAsset>>> loadGltfMeshes(
|
||||
Engine* engine,
|
||||
std::filesystem::path filePath
|
||||
) {
|
||||
// Todo:
|
||||
// Use util functions for attributes
|
||||
auto& logger = engine->_logger; // Uses the main logger
|
||||
logger.logAll(LogModule::ENGINE, LogLevel::EINFO, "Loading GLTF: {}", filePath.string());
|
||||
|
||||
@ -86,27 +89,107 @@ std::optional<std::vector<std::shared_ptr<MeshAsset>>> loadGltfMeshes(
|
||||
In the official docs, it is stated we can get direct
|
||||
references to the Asset class, using pointers (->)
|
||||
For exemple with buffers: asset->buffers
|
||||
|
||||
But the guide is using asset.meshes ?
|
||||
We'll need to validate if it's a real class member
|
||||
|
||||
Then, foreach meshes in the file, he creates a temporary mesh,
|
||||
that he will fill with the model data.
|
||||
|
||||
He assign the model name from the big chunk (we'll call it the Origin)
|
||||
|
||||
He does some cleaning, to not merge meshes by error.
|
||||
|
||||
And...uh..another loop.
|
||||
|
||||
This time, it's using mesh.primitives, which is the iterator of the first loop.
|
||||
It creates a new GeoSurface, foreach "primitives" ?
|
||||
|
||||
|
||||
*/
|
||||
for(fastgltf::Mesh& mesh : gltf.meshes) { // Perhaps error ?
|
||||
MeshAsset newmesh;
|
||||
|
||||
newmesh.name = mesh.name;
|
||||
|
||||
// Clear the arrays for memory optimizations
|
||||
indices.clear();
|
||||
vertices.clear();
|
||||
|
||||
for(auto&& p : mesh.primitives) { // 100% Error, use pointers ig ?
|
||||
GeoSurface newSurface;
|
||||
newSurface.startIndex = (uint32_t)indices.size();
|
||||
newSurface.count = (uint32_t)gltf.accessors[p.indicesAccessor.value()].count;
|
||||
|
||||
size_t initialVTX = vertices.size();
|
||||
|
||||
// -- Indices --
|
||||
{
|
||||
fastgltf::Accessor& indexAccessor = gltf.accessors[p.indicesAccessor.value()];
|
||||
indices.reserve(indices.size() + indexAccessor.count); // Memory alloc ig ?
|
||||
|
||||
fastgltf::iterateAccessor<std::uint32_t>(gltf, indexAccessor,
|
||||
[&](std::uint32_t idx) {
|
||||
indices.push_back(idx + initialVTX);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// -- Vertex Positions --
|
||||
{
|
||||
auto posIt = p.findAttribute("POSITION");
|
||||
if (posIt == p.attributes.end()) {
|
||||
logger.logFatal(LogModule::ENGINE, "Primitive without POSITION attribute");
|
||||
return std::nullopt;
|
||||
}
|
||||
fastgltf::Accessor& posAccessor = gltf.accessors[posIt->accessorIndex];
|
||||
vertices.resize(vertices.size() + posAccessor.count);
|
||||
|
||||
fastgltf::iterateAccessorWithIndex<glm::vec3>(gltf, posAccessor,
|
||||
[&](glm::vec3 v, size_t index) {
|
||||
Vertex newvtx;
|
||||
newvtx.position = v;
|
||||
newvtx.normal = { 1.0f, 0.0f, 0.0f };
|
||||
newvtx.color = glm::vec4(1.0f);
|
||||
newvtx.uv_x = 0.0f;
|
||||
newvtx.uv_y = 0.0f;
|
||||
vertices[initialVTX + index] = newvtx;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// --- Normals ---
|
||||
if (auto normals = p.findAttribute("NORMAL"); normals != p.attributes.end()) {
|
||||
fastgltf::iterateAccessorWithIndex<glm::vec3>(gltf, gltf.accessors[normals->accessorIndex],
|
||||
[&](glm::vec3 v, size_t index) {
|
||||
vertices[initialVTX + index].normal = v;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// --- UVs ---
|
||||
if (auto uv = p.findAttribute("TEXCOORD_0"); uv != p.attributes.end()) {
|
||||
fastgltf::iterateAccessorWithIndex<glm::vec2>(gltf, gltf.accessors[uv->accessorIndex],
|
||||
[&](glm::vec2 v, size_t index) {
|
||||
vertices[initialVTX + index].uv_x = v.x;
|
||||
vertices[initialVTX + index].uv_y = v.y;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// --- Vertex Colors ---
|
||||
if (auto colors = p.findAttribute("COLOR_0"); colors != p.attributes.end()) {
|
||||
fastgltf::iterateAccessorWithIndex<glm::vec4>(gltf, gltf.accessors[colors->accessorIndex],
|
||||
[&](glm::vec4 v, size_t index) {
|
||||
vertices[initialVTX + index].color = v;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
newmesh.surfaces.push_back(newSurface);
|
||||
}
|
||||
|
||||
// Display vertex normals
|
||||
if (OverrideColors) {
|
||||
for (Vertex& vtx : vertices) {
|
||||
vtx.color = glm::vec4(vtx.normal, 1.0f);
|
||||
}
|
||||
}
|
||||
newmesh.meshBuffers = engine->uploadMesh(indices, vertices);
|
||||
meshes.emplace_back(std::make_shared<MeshAsset>(std::move(newmesh)));
|
||||
}
|
||||
|
||||
|
||||
// Debug things
|
||||
#ifdef DEBUG
|
||||
if(fastgltf::validate(load.get()) != fastgltf::Error::None) {
|
||||
logger.logFatal(LogModule::ENGINE, "gltf file is not up to spec !");
|
||||
}
|
||||
#endif
|
||||
|
||||
return meshes;
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
/*
|
||||
Todo:
|
||||
Create a temporary struct, to have the correct structure
|
||||
then copy it to the class member
|
||||
*/
|
||||
#ifndef PIPELINES_H
|
||||
#define PIPELINES_H
|
||||
// Normal header
|
||||
@ -69,6 +74,10 @@ class PipelineBuilder {
|
||||
);
|
||||
|
||||
void disableDepthtest();
|
||||
void enableDepthtest(
|
||||
bool depthWriteEnable,
|
||||
VkCompareOp op
|
||||
);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -358,5 +367,20 @@ void PipelineBuilder::disableDepthtest() {
|
||||
_depthStencil.maxDepthBounds = 1.0f;
|
||||
}
|
||||
|
||||
void PipelineBuilder::enableDepthtest(
|
||||
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;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user