mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Attempt to add depth buffer
This commit is contained in:
parent
3df5cfbc02
commit
9e7c6e923d
@ -31,8 +31,8 @@ namespace engine {
|
||||
const gfx::DescriptorSetLayout* setZeroLayout;
|
||||
const gfx::DescriptorSet* setZero;
|
||||
struct SetZeroBuffer {
|
||||
glm::mat4 view;
|
||||
glm::mat4 proj;
|
||||
glm::vec2 myValue;
|
||||
};
|
||||
gfx::DescriptorBuffer* setZeroBuffer;
|
||||
};
|
||||
|
@ -2,12 +2,11 @@
|
||||
|
||||
layout( push_constant ) uniform Constants {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
} constants;
|
||||
|
||||
layout(set = 0, binding = 0) uniform SetZeroBuffer {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
vec2 myValue;
|
||||
} setZeroBuffer;
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
@ -16,7 +15,7 @@ layout(location = 2) in vec2 inUV;
|
||||
layout(location = 0) out vec2 fragUV;
|
||||
|
||||
void main() {
|
||||
mat4 myView = constants.view;
|
||||
mat4 myView = setZeroBuffer.view;
|
||||
myView[3] = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
vec4 pos = setZeroBuffer.proj * myView * constants.model * vec4(inPosition, 1.0);
|
||||
gl_Position = pos;
|
||||
|
@ -2,12 +2,11 @@
|
||||
|
||||
layout( push_constant ) uniform Constants {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
} constants;
|
||||
|
||||
layout(set = 0, binding = 0) uniform SetZeroBuffer {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
vec2 myValue;
|
||||
} setZeroBuffer;
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
@ -20,12 +19,12 @@ layout(location = 2) out vec2 fragUV;
|
||||
layout(location = 3) out vec3 fragLightPos;
|
||||
|
||||
void main() {
|
||||
gl_Position = setZeroBuffer.proj * constants.view * constants.model * vec4(inPosition, 1.0);
|
||||
gl_Position = setZeroBuffer.proj * setZeroBuffer.view * constants.model * vec4(inPosition, 1.0);
|
||||
|
||||
fragPos = vec3(constants.view * constants.model * vec4(inPosition, 1.0));
|
||||
fragNorm = mat3(transpose(inverse(constants.view * constants.model))) * inNorm;
|
||||
fragPos = vec3(setZeroBuffer.view * constants.model * vec4(inPosition, 1.0));
|
||||
fragNorm = mat3(transpose(inverse(setZeroBuffer.view * constants.model))) * inNorm;
|
||||
fragUV = inUV;
|
||||
|
||||
vec3 lightPos = vec3(2000.0, 2000.0, -2000.0);
|
||||
fragLightPos = vec3(constants.view * vec4(lightPos, 1.0));
|
||||
fragLightPos = vec3(setZeroBuffer.view * vec4(lightPos, 1.0));
|
||||
}
|
||||
|
@ -78,8 +78,8 @@ namespace engine {
|
||||
renderData.setZeroLayout = gfx()->createDescriptorSetLayout();
|
||||
renderData.setZero = gfx()->allocateDescriptorSet(renderData.setZeroLayout);
|
||||
RenderData::SetZeroBuffer initialData{
|
||||
.view = glm::mat4{1.0f},
|
||||
.proj = glm::perspectiveZO(glm::radians(70.0f), 1024.0f / 768.0f, 0.1f, 1000.0f),
|
||||
.myValue = { 0.0f, 1.0f }
|
||||
};
|
||||
renderData.setZeroBuffer = gfx()->createDescriptorBuffer(sizeof(RenderData::SetZeroBuffer), &initialData);
|
||||
gfx()->updateDescriptor(renderData.setZero, 0, renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer));
|
||||
|
@ -613,6 +613,7 @@ namespace engine {
|
||||
pimpl->allocator = createAllocator(pimpl->instance.instance, pimpl->device.device, pimpl->device.physicalDevice);
|
||||
|
||||
pimpl->swapchainInfo.device = pimpl->device.device;
|
||||
pimpl->swapchainInfo.allocator = pimpl->allocator;
|
||||
pimpl->swapchainInfo.physicalDevice = pimpl->device.physicalDevice;
|
||||
pimpl->swapchainInfo.surface = pimpl->surface;
|
||||
pimpl->swapchainInfo.window = pimpl->window;
|
||||
|
@ -47,11 +47,10 @@ namespace engine {
|
||||
const glm::mat4 projMatrix = glm::perspectiveZO(verticalFovRadians, m_viewportAspectRatio, m_camera.clipNear, m_camera.clipFar);
|
||||
|
||||
/* update SET 0 */
|
||||
RenderData::SetZeroBuffer uniform{};
|
||||
uniform.proj = projMatrix;
|
||||
uniform.myValue.x = 1.0f;
|
||||
m_value = glm::mod(m_value + ts, 1.0f);
|
||||
uniform.myValue.y = m_value;
|
||||
RenderData::SetZeroBuffer uniform{
|
||||
.view = viewMatrix,
|
||||
.proj = projMatrix
|
||||
};
|
||||
m_gfx->writeDescriptorBuffer(renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer), &uniform);
|
||||
|
||||
/* render all renderable entities */
|
||||
@ -69,11 +68,9 @@ namespace engine {
|
||||
|
||||
struct {
|
||||
glm::mat4 model;
|
||||
glm::mat4 view;
|
||||
} pushConsts{};
|
||||
|
||||
pushConsts.model = t->worldMatrix;
|
||||
pushConsts.view = viewMatrix;
|
||||
|
||||
m_gfx->cmdBindPipeline(renderData.drawBuffer, r->material->getShader()->getPipeline());
|
||||
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, r->material->getShader()->getPipeline(), renderData.setZero, 0);
|
||||
|
@ -5,10 +5,21 @@
|
||||
#include <cstring>
|
||||
#include <assert.h>
|
||||
|
||||
#include "log.hpp"
|
||||
|
||||
#include "device.h"
|
||||
|
||||
namespace engine {
|
||||
|
||||
static bool checkQueueFamilySupportsPresent(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t familyIndex)
|
||||
{
|
||||
VkBool32 supportsPresent;
|
||||
VkResult res;
|
||||
res = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, static_cast<uint32_t>(familyIndex), surface, &supportsPresent);
|
||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to check for queue family present support!");
|
||||
return supportsPresent;
|
||||
}
|
||||
|
||||
/* chooses a device, creates it, gets its function pointers, and creates command pools */
|
||||
Device createDevice(VkInstance instance, DeviceRequirements requirements, VkSurfaceKHR surface)
|
||||
{
|
||||
@ -209,22 +220,33 @@ namespace engine {
|
||||
for (size_t i = 0; i < queueFamilies.size(); i++) {
|
||||
VkQueueFamilyProperties p = queueFamilies[i];
|
||||
|
||||
if (p.queueCount < 2) continue; // need one queue for presenting and one-or-more for rendering
|
||||
if (p.queueCount < 2) continue; // ideally have one queue for presenting and at least one other for rendering
|
||||
|
||||
if (p.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||
VkBool32 supportsPresent;
|
||||
res = vkGetPhysicalDeviceSurfaceSupportKHR(d.physicalDevice, static_cast<uint32_t>(i), surface, &supportsPresent);
|
||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to check for queue family present support!");
|
||||
if (supportsPresent) {
|
||||
if (checkQueueFamilySupportsPresent(d.physicalDevice, surface, i)) {
|
||||
graphicsFamily = static_cast<uint32_t>(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (graphicsFamily == UINT32_MAX) throw std::runtime_error("Unable to find a graphics/present queue family!");
|
||||
if (graphicsFamily == UINT32_MAX) {
|
||||
for (size_t i = 0; i < queueFamilies.size(); i++) {
|
||||
VkQueueFamilyProperties p = queueFamilies[i];
|
||||
if (p.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||
if (checkQueueFamilySupportsPresent(d.physicalDevice, surface, i)) {
|
||||
graphicsFamily = static_cast<uint32_t>(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (graphicsFamily == UINT32_MAX) {
|
||||
throw std::runtime_error("Failed to find a graphics/present family!");
|
||||
}
|
||||
LOG_WARN("Failed to find ideal graphics/present queue family! Falling back to family #{}.", graphicsFamily);
|
||||
}
|
||||
|
||||
// find a transfer queue family (image layout transitions, buffer upload)
|
||||
uint32_t transferFamily = UINT32_MAX;
|
||||
// prefer a dedicated transfer queue family
|
||||
for (size_t i = 0; i < queueFamilies.size(); i++) {
|
||||
VkQueueFamilyProperties p = queueFamilies[i];
|
||||
if (((p.queueFlags & VK_QUEUE_TRANSFER_BIT) != 0) &&
|
||||
@ -234,7 +256,10 @@ namespace engine {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (transferFamily == UINT32_MAX) throw std::runtime_error("Unable to find a transfer queue family!");
|
||||
if (transferFamily == UINT32_MAX) {
|
||||
transferFamily = graphicsFamily;
|
||||
LOG_WARN("Failed to find a dedicated transfer queue family! Falling back to graphics family.");
|
||||
}
|
||||
|
||||
// queue priorities
|
||||
std::vector<float> graphicsQueuePriorities(queueFamilies[graphicsFamily].queueCount);
|
||||
@ -242,24 +267,26 @@ namespace engine {
|
||||
std::vector<float> transferQueuePriorities(queueFamilies[transferFamily].queueCount);
|
||||
std::fill(transferQueuePriorities.begin(), transferQueuePriorities.end(), 1.0f);
|
||||
|
||||
std::array<VkDeviceQueueCreateInfo, 2> queueCreateInfos{
|
||||
VkDeviceQueueCreateInfo{
|
||||
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos{};
|
||||
queueCreateInfos.push_back(VkDeviceQueueCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.queueFamilyIndex = graphicsFamily,
|
||||
.queueCount = queueFamilies[graphicsFamily].queueCount,
|
||||
.pQueuePriorities = graphicsQueuePriorities.data(),
|
||||
},
|
||||
VkDeviceQueueCreateInfo{
|
||||
.pQueuePriorities = graphicsQueuePriorities.data()
|
||||
});
|
||||
|
||||
if (transferFamily != graphicsFamily) {
|
||||
queueCreateInfos.push_back(VkDeviceQueueCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.queueFamilyIndex = transferFamily,
|
||||
.queueCount = queueFamilies[transferFamily].queueCount,
|
||||
.pQueuePriorities = transferQueuePriorities.data(),
|
||||
.pQueuePriorities = transferQueuePriorities.data()
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/* create device now */
|
||||
VkDeviceCreateInfo deviceCreateInfo{
|
||||
@ -282,15 +309,50 @@ namespace engine {
|
||||
|
||||
volkLoadDevice(d.device);
|
||||
|
||||
|
||||
if (transferFamily != graphicsFamily) {
|
||||
vkGetDeviceQueue(d.device, graphicsFamily, 0, &d.queues.presentQueue);
|
||||
if (queueFamilies[graphicsFamily].queueCount >= 2) {
|
||||
d.queues.drawQueues.resize(queueFamilies[graphicsFamily].queueCount - 1);
|
||||
for (uint32_t i = 0; i < d.queues.drawQueues.size(); i++) {
|
||||
vkGetDeviceQueue(d.device, graphicsFamily, i + 1, &d.queues.drawQueues[i]);
|
||||
}
|
||||
} else {
|
||||
d.queues.drawQueues.resize(1);
|
||||
d.queues.drawQueues[0] = d.queues.presentQueue;
|
||||
}
|
||||
d.queues.transferQueues.resize(queueFamilies[transferFamily].queueCount);
|
||||
for (uint32_t i = 0; i < d.queues.transferQueues.size(); i++) {
|
||||
vkGetDeviceQueue(d.device, transferFamily, i, &d.queues.transferQueues[i]);
|
||||
}
|
||||
} else {
|
||||
// same graphics family for graphics/present and transfer
|
||||
uint32_t queueCount = queueFamilies[graphicsFamily].queueCount;
|
||||
vkGetDeviceQueue(d.device, graphicsFamily, 0, &d.queues.presentQueue);
|
||||
if (queueCount >= 2) {
|
||||
d.queues.transferQueues.resize(1);
|
||||
vkGetDeviceQueue(d.device, graphicsFamily, 1, &d.queues.transferQueues[0]);
|
||||
// use the remaining queues for drawing
|
||||
if (queueCount >= 3) {
|
||||
d.queues.drawQueues.resize(queueCount - 2);
|
||||
for (uint32_t i = 0; i < queueCount - 2; i++) {
|
||||
vkGetDeviceQueue(d.device, graphicsFamily, i + 2, &d.queues.drawQueues[i]);
|
||||
}
|
||||
} else {
|
||||
// 2 queues available
|
||||
// present and drawing share a queue
|
||||
// transfer gets its own queue
|
||||
d.queues.drawQueues.resize(1);
|
||||
d.queues.drawQueues[0] = d.queues.presentQueue;
|
||||
}
|
||||
} else {
|
||||
// only 1 queue available :(
|
||||
d.queues.transferQueues.resize(1);
|
||||
d.queues.transferQueues[0] = d.queues.presentQueue;
|
||||
d.queues.drawQueues.resize(1);
|
||||
d.queues.drawQueues[0] = d.queues.presentQueue;
|
||||
}
|
||||
}
|
||||
|
||||
d.queues.presentAndDrawQueueFamily = graphicsFamily;
|
||||
d.queues.transferQueueFamily = transferFamily;
|
||||
|
@ -14,6 +14,7 @@ namespace engine {
|
||||
void createSwapchain(Swapchain* sc, const SwapchainInfo& info)
|
||||
{
|
||||
sc->device = info.device;
|
||||
sc->allocator = info.allocator;
|
||||
|
||||
LOG_INFO("Recreating swapchain!\n");
|
||||
|
||||
@ -129,6 +130,61 @@ namespace engine {
|
||||
vkDestroySwapchainKHR(info.device, scInfo.oldSwapchain, nullptr);
|
||||
}
|
||||
|
||||
{ /* create the depth buffer */
|
||||
|
||||
sc->depthStencil.format = VK_FORMAT_D32_SFLOAT;
|
||||
|
||||
if (sc->depthStencil.image != VK_NULL_HANDLE) {
|
||||
vkDestroyImageView(info.device, sc->depthStencil.view, nullptr);
|
||||
vmaDestroyImage(sc->allocator, sc->depthStencil.image, sc->depthStencil.allocation);
|
||||
}
|
||||
VkImageCreateInfo imageInfo{};
|
||||
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
imageInfo.pNext = nullptr;
|
||||
imageInfo.flags = 0;
|
||||
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
imageInfo.format = sc->depthStencil.format;
|
||||
imageInfo.extent.width = sc->extent.width;
|
||||
imageInfo.extent.height = sc->extent.height;
|
||||
imageInfo.mipLevels = 1;
|
||||
imageInfo.arrayLayers = 1;
|
||||
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
imageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
imageInfo.queueFamilyIndexCount = 0; // ignored
|
||||
imageInfo.pQueueFamilyIndices = nullptr; // ignored
|
||||
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
VmaAllocationCreateInfo allocInfo{};
|
||||
allocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
||||
allocInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
|
||||
allocInfo.priority = 1.0f;
|
||||
|
||||
res = vmaCreateImage(sc->allocator, &imageInfo, &allocInfo, &sc->depthStencil.image, &sc->depthStencil.allocation, nullptr);
|
||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create depth buffer image! Code: " + std::to_string(res));
|
||||
|
||||
VkImageViewCreateInfo viewInfo{};
|
||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewInfo.pNext = nullptr;
|
||||
viewInfo.flags = 0;
|
||||
viewInfo.image = sc->depthStencil.image;
|
||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
viewInfo.format = sc->depthStencil.format;
|
||||
viewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
viewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
viewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
viewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
viewInfo.subresourceRange.baseMipLevel = 0;
|
||||
viewInfo.subresourceRange.levelCount = 1;
|
||||
viewInfo.subresourceRange.baseArrayLayer = 0;
|
||||
viewInfo.subresourceRange.layerCount = 1;
|
||||
res = vkCreateImageView(info.device, &viewInfo, nullptr, &sc->depthStencil.view);
|
||||
assert(res == VK_SUCCESS);
|
||||
|
||||
}
|
||||
|
||||
/* create the render pass */
|
||||
if (sc->renderpass != VK_NULL_HANDLE) {
|
||||
vkDestroyRenderPass(sc->device, sc->renderpass, nullptr);
|
||||
@ -144,10 +200,26 @@ namespace engine {
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
||||
};
|
||||
VkAttachmentDescription depthStencilAttachment{
|
||||
.flags = 0,
|
||||
.format = sc->depthStencil.format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, // the depth buffer is not used after the fragment shader
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, // ignored
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, // ignored
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
||||
};
|
||||
std::array<VkAttachmentDescription, 2> attachments { colorAttachment, depthStencilAttachment };
|
||||
VkAttachmentReference colorAttachmentRef{
|
||||
.attachment = 0,
|
||||
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||
};
|
||||
VkAttachmentReference depthStencilAttachmentRef{
|
||||
.attachment = 1,
|
||||
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
||||
};
|
||||
VkSubpassDescription subpass{
|
||||
.flags = 0,
|
||||
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
@ -156,25 +228,25 @@ namespace engine {
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = &colorAttachmentRef,
|
||||
.pResolveAttachments = nullptr,
|
||||
.pDepthStencilAttachment = nullptr,
|
||||
.pDepthStencilAttachment = &depthStencilAttachmentRef,
|
||||
.preserveAttachmentCount = 0,
|
||||
.pPreserveAttachments = nullptr,
|
||||
};
|
||||
VkSubpassDependency dependency{
|
||||
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
||||
.dstSubpass = 0,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccessMask = 0,
|
||||
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dependencyFlags = 0
|
||||
};
|
||||
VkRenderPassCreateInfo renderPassInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.attachmentCount = 1,
|
||||
.pAttachments = &colorAttachment,
|
||||
.attachmentCount = attachments.size(),
|
||||
.pAttachments = attachments.data(),
|
||||
.subpassCount = 1,
|
||||
.pSubpasses = &subpass,
|
||||
.dependencyCount = 1,
|
||||
@ -194,9 +266,9 @@ namespace engine {
|
||||
/* create image view and framebuffer for each image */
|
||||
sc->images.resize(swapchainImageCount);
|
||||
for (uint32_t i = 0; i < swapchainImageCount; i++) {
|
||||
auto& [image, view, framebuffer] = sc->images.at(i);
|
||||
auto& [image, imageView, framebuffer] = sc->images.at(i);
|
||||
|
||||
if (view != VK_NULL_HANDLE) vkDestroyImageView(sc->device, view, nullptr);
|
||||
if (imageView != VK_NULL_HANDLE) vkDestroyImageView(sc->device, imageView, nullptr);
|
||||
if (framebuffer != VK_NULL_HANDLE) vkDestroyFramebuffer(sc->device, framebuffer, nullptr);
|
||||
|
||||
image = swapchainImages[i];
|
||||
@ -218,16 +290,20 @@ namespace engine {
|
||||
viewInfo.subresourceRange.levelCount = 1;
|
||||
viewInfo.subresourceRange.baseArrayLayer = 0;
|
||||
viewInfo.subresourceRange.layerCount = 1;
|
||||
VkResult res = vkCreateImageView(sc->device, &viewInfo, nullptr, &view);
|
||||
VkResult res = vkCreateImageView(sc->device, &viewInfo, nullptr, &imageView);
|
||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create image view from swapchain image!");
|
||||
|
||||
std::array<VkImageView, 2> attachments {
|
||||
imageView, sc->depthStencil.view
|
||||
};
|
||||
|
||||
VkFramebufferCreateInfo fbInfo{};
|
||||
fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
fbInfo.pNext = nullptr;
|
||||
fbInfo.flags = 0;
|
||||
fbInfo.renderPass = sc->renderpass;
|
||||
fbInfo.attachmentCount = 1;
|
||||
fbInfo.pAttachments = &view;
|
||||
fbInfo.attachmentCount = attachments.size();
|
||||
fbInfo.pAttachments = attachments.data();
|
||||
fbInfo.width = sc->extent.width;
|
||||
fbInfo.height = sc->extent.height;
|
||||
fbInfo.layers = 1;
|
||||
@ -246,6 +322,8 @@ namespace engine {
|
||||
vkDestroyImageView(sc.device, view, nullptr);
|
||||
}
|
||||
vkDestroyRenderPass(sc.device, sc.renderpass, nullptr);
|
||||
vkDestroyImageView(sc.device, sc.depthStencil.view, nullptr);
|
||||
vmaDestroyImage(sc.allocator, sc.depthStencil.image, sc.depthStencil.allocation);
|
||||
vkDestroySwapchainKHR(sc.device, sc.swapchain, nullptr);
|
||||
}
|
||||
|
||||
|
@ -1,22 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include <SDL2/SDL_vulkan.h>
|
||||
|
||||
#include <volk.h>
|
||||
|
||||
#include <vk_mem_alloc.h>
|
||||
|
||||
namespace engine {
|
||||
|
||||
struct Swapchain {
|
||||
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
|
||||
VkDevice device = VK_NULL_HANDLE; // the associated device
|
||||
VmaAllocator allocator = VK_NULL_HANDLE; // the associated allocator
|
||||
VkSurfaceFormatKHR surfaceFormat{};
|
||||
VkSurfaceCapabilitiesKHR surfaceCapabilities{};
|
||||
VkPresentModeKHR presentMode{};
|
||||
VkExtent2D extent{};
|
||||
VkRenderPass renderpass = VK_NULL_HANDLE;
|
||||
std::vector<std::tuple<VkImage, VkImageView, VkFramebuffer>> images{};
|
||||
struct DepthStencil {
|
||||
VkImage image = VK_NULL_HANDLE;
|
||||
VmaAllocation allocation = VK_NULL_HANDLE;
|
||||
VkImageView view = VK_NULL_HANDLE;
|
||||
VkFormat format{};
|
||||
} depthStencil{};
|
||||
};
|
||||
|
||||
struct SwapchainInfo {
|
||||
@ -24,6 +34,7 @@ namespace engine {
|
||||
VkPhysicalDevice physicalDevice;
|
||||
VkSurfaceKHR surface;
|
||||
SDL_Window* window;
|
||||
VmaAllocator allocator;
|
||||
bool vsync;
|
||||
bool waitForPresent;
|
||||
};
|
||||
|
@ -107,7 +107,7 @@ void playGame(bool enableFrameLimiter)
|
||||
/* cube */
|
||||
{
|
||||
uint32_t cube = myScene->createEntity("cube");
|
||||
myScene->getComponent<engine::TransformComponent>(cube)->position = glm::vec3{ -0.5f, -0.5f, -0.5f };
|
||||
myScene->getComponent<engine::TransformComponent>(cube)->position = glm::vec3{ -0.5f, -0.5f + 5.0f, -0.5f };
|
||||
auto cubeRenderable = myScene->addComponent<engine::RenderableComponent>(cube);
|
||||
cubeRenderable->material = std::make_shared<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.standard"));
|
||||
cubeRenderable->mesh = genCuboidMesh(app.gfx(), 1.0f, 1.0f, 1.0f, 1);
|
||||
|
Loading…
Reference in New Issue
Block a user