Browse Source

Add depth testing.

master
Amber 2 years ago
parent
commit
d8f9b574b1
  1. 112
      src/main.c
  2. 4
      src/vertex_simple.vert

112
src/main.c

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
#define GLFW_INCLUDE_VULKAN
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <GLFW/glfw3.h>
#include <vulkan/vulkan.h>
@ -95,6 +96,10 @@ typedef struct ApplicationState { @@ -95,6 +96,10 @@ typedef struct ApplicationState {
VkDeviceMemory texture_image_memory;
VkImageView texture_image_view;
VkSampler texture_sampler;
VkImage depth_image;
VkDeviceMemory depth_image_memory;
VkImageView depth_image_view;
} ApplicationState;
typedef struct QueueFamilyIndices {
@ -105,20 +110,27 @@ typedef struct QueueFamilyIndices { @@ -105,20 +110,27 @@ typedef struct QueueFamilyIndices {
} QueueFamilyIndices;
typedef struct Vertex {
vec2 position;
vec3 position;
vec3 color;
vec2 tex_coord;
} Vertex;
const Vertex vertices[] = {
{{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}},
{{0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
{{0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
{{-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}
{{-0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
{{0.5f, -0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
{{0.5f, 0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
{{-0.5f, 0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}},
{{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
{{0.5f, -0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
{{0.5f, 0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
{{-0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}
};
const uint16_t indices[] = {
0, 1, 2, 2, 3, 0
0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4
};
typedef struct UBO {
@ -643,6 +655,16 @@ void create_render_pass(ApplicationState* state) { @@ -643,6 +655,16 @@ void create_render_pass(ApplicationState* state) {
//images to be presented
color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
VkAttachmentDescription depth_attachment = {0};
depth_attachment.format = VK_FORMAT_D32_SFLOAT;
depth_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depth_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depth_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depth_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
depth_attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
//there may be multiple subpasses, subpasses depend on the previous framebuffer contents
//they can be used for things sych as postprocessing
//every subpass references one or more attachment
@ -650,18 +672,24 @@ void create_render_pass(ApplicationState* state) { @@ -650,18 +672,24 @@ void create_render_pass(ApplicationState* state) {
color_attachment_reference.attachment = 0;
color_attachment_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference depth_attachment_reference = {0};
depth_attachment_reference.attachment = 1;
depth_attachment_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
//now we create the subpass
//layout(location = 0) out vec4 outColor;
VkSubpassDescription subpass = {0};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &color_attachment_reference;
subpass.pDepthStencilAttachment = &depth_attachment_reference;
VkAttachmentDescription attachments[2] = {color_attachment, depth_attachment};
//let's create the render pass
VkRenderPassCreateInfo render_pass_info = {0};
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
render_pass_info.attachmentCount = 1;
render_pass_info.pAttachments = &color_attachment;
render_pass_info.attachmentCount = ARRSIZE(attachments);
render_pass_info.pAttachments = attachments;
render_pass_info.subpassCount = 1;
render_pass_info.pSubpasses = &subpass;
@ -680,11 +708,11 @@ void create_render_pass(ApplicationState* state) { @@ -680,11 +708,11 @@ void create_render_pass(ApplicationState* state) {
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
//wait on the color attachment
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.srcAccessMask = 0;
//the part of the subpass when the attachment is written has to wait
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
render_pass_info.dependencyCount = 1;
render_pass_info.pDependencies = &dependency;
@ -786,7 +814,7 @@ void create_graphics_pipeline(ApplicationState* state) { @@ -786,7 +814,7 @@ void create_graphics_pipeline(ApplicationState* state) {
//We have position and color, so we need two descriptions
VkVertexInputAttributeDescription attribute_description[3] = {
{.binding = 0, .location = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = offsetof(Vertex, position)},
{.binding = 0, .location = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = offsetof(Vertex, position)},
{.binding = 0, .location = 1, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = offsetof(Vertex, color)},
{.binding = 0, .location = 2, .format = VK_FORMAT_R32G32_SFLOAT, .offset = offsetof(Vertex, tex_coord)},
};
@ -891,6 +919,16 @@ void create_graphics_pipeline(ApplicationState* state) { @@ -891,6 +919,16 @@ void create_graphics_pipeline(ApplicationState* state) {
printf("created pipeline layout\n");
VkPipelineDepthStencilStateCreateInfo depth_stencil = {0};
depth_stencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depth_stencil.depthTestEnable = VK_TRUE;
depth_stencil.depthWriteEnable = VK_TRUE;
depth_stencil.depthCompareOp = VK_COMPARE_OP_LESS;
depth_stencil.depthBoundsTestEnable = VK_FALSE;
depth_stencil.minDepthBounds = 0.0f; // Optional
depth_stencil.maxDepthBounds = 1.0f; // Optional
depth_stencil.stencilTestEnable = VK_FALSE;
VkGraphicsPipelineCreateInfo pipeline_info = {0};
pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
//shaders
@ -905,6 +943,7 @@ void create_graphics_pipeline(ApplicationState* state) { @@ -905,6 +943,7 @@ void create_graphics_pipeline(ApplicationState* state) {
pipeline_info.pDepthStencilState = NULL; // Optional
pipeline_info.pColorBlendState = &color_blending;
pipeline_info.pDynamicState = &dynamic_state;
pipeline_info.pDepthStencilState = &depth_stencil;
pipeline_info.layout = state->pipeline_layout;
pipeline_info.renderPass = state->render_pass;
@ -931,13 +970,14 @@ void create_framebuffers(ApplicationState* state) { @@ -931,13 +970,14 @@ void create_framebuffers(ApplicationState* state) {
for (int i = 0; i < state->swapchain_image_count; i++) {
printf("creating framebuffer %x\n", i);
VkImageView attachments[] = {
state->swapchain_image_views[i]
state->swapchain_image_views[i],
state->depth_image_view
};
VkFramebufferCreateInfo framebuffer_info = {0};
framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebuffer_info.renderPass = state->render_pass;
framebuffer_info.attachmentCount = 1;
framebuffer_info.attachmentCount = ARRSIZE(attachments);
framebuffer_info.pAttachments = attachments;
framebuffer_info.width = state->swapchain_extent.width;
framebuffer_info.height = state->swapchain_extent.height;
@ -1136,7 +1176,7 @@ void create_image(ApplicationState* state, uint32_t width, uint32_t height, VkFo @@ -1136,7 +1176,7 @@ void create_image(ApplicationState* state, uint32_t width, uint32_t height, VkFo
}
VkMemoryRequirements mem_req;
vkGetImageMemoryRequirements(state->device, state->texture_image, &mem_req);
vkGetImageMemoryRequirements(state->device, *image, &mem_req);
VkMemoryAllocateInfo alloc_info = {0};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
@ -1224,6 +1264,27 @@ void copy_buffer_to_image(ApplicationState* state, VkBuffer to_copy, VkImage ima @@ -1224,6 +1264,27 @@ void copy_buffer_to_image(ApplicationState* state, VkBuffer to_copy, VkImage ima
end_single_time_commands(state, buffer);
}
void create_depth_resources(ApplicationState* state) {
create_image(state, state->swapchain_extent.width, state->swapchain_extent.height, VK_FORMAT_D32_SFLOAT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
&state->depth_image, &state->depth_image_memory);
VkImageViewCreateInfo view_info = {0};
view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
view_info.image = state->depth_image;
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_info.format = VK_FORMAT_D32_SFLOAT;
view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
view_info.subresourceRange.baseMipLevel = 0;
view_info.subresourceRange.levelCount = 1;
view_info.subresourceRange.baseArrayLayer = 0;
view_info.subresourceRange.layerCount = 1;
if (vkCreateImageView(state->device, &view_info, NULL, &state->depth_image_view) != VK_SUCCESS) {
printf("failed to create texture image view\n");
exit(1);
}
}
void create_texture_image(ApplicationState* state) {
int width, height, channels;
stbi_uc* pixels = stbi_load("../src/res/texture.jpg", &width, &height, &channels, STBI_rgb_alpha);
@ -1420,9 +1481,17 @@ void record_command_buffer(ApplicationState* state, VkCommandBuffer command_buff @@ -1420,9 +1481,17 @@ void record_command_buffer(ApplicationState* state, VkCommandBuffer command_buff
render_pass_info.renderArea.offset.y = 0;
render_pass_info.renderArea.extent = state->swapchain_extent;
VkClearValue clearColor = {0};
render_pass_info.clearValueCount = 1;
render_pass_info.pClearValues = &clearColor;
VkClearValue clear_color = {0};
VkClearValue stencil_clear;
stencil_clear.depthStencil.depth = 1.0f;
stencil_clear.depthStencil.stencil = 0;
VkClearValue clear_values[2];
clear_values[0] = clear_color;
clear_values[1] = stencil_clear;
render_pass_info.clearValueCount = ARRSIZE(clear_values);
render_pass_info.pClearValues = clear_values;
//can also be VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS to execute command stored in secondary buffers
vkCmdBeginRenderPass(command_buffer, &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
@ -1496,8 +1565,9 @@ void init_vulkan(ApplicationState* state) { @@ -1496,8 +1565,9 @@ void init_vulkan(ApplicationState* state) {
create_render_pass(state);
create_descriptor_set_layout(state);
create_graphics_pipeline(state);
create_framebuffers(state);
create_command_pool(state);
create_depth_resources(state);
create_framebuffers(state);
create_texture_image(state);
create_texture_image_view(state);
create_texture_image_sampler(state);
@ -1512,6 +1582,7 @@ void init_vulkan(ApplicationState* state) { @@ -1512,6 +1582,7 @@ void init_vulkan(ApplicationState* state) {
void update_uniform_buffer(ApplicationState* state, uint32_t current_frame) {
uint64_t time = clock() / (CLOCKS_PER_SEC / 1000);
time = 0;
UBO ubo = {0};
glm_mat4_identity(ubo.model);
@ -1626,6 +1697,9 @@ void terminate(ApplicationState* state) { @@ -1626,6 +1697,9 @@ void terminate(ApplicationState* state) {
vkDestroyImageView(state->device, state->texture_image_view, NULL);
vkDestroyImage(state->device, state->texture_image, NULL);
vkFreeMemory(state->device, state->texture_image_memory, NULL);
vkDestroyImageView(state->device, state->depth_image_view, NULL);
vkDestroyImage(state->device, state->depth_image, NULL);
vkFreeMemory(state->device, state->depth_image_memory, NULL);
vkDestroySwapchainKHR(state->device, state->swapchain, NULL);
vkDestroyDevice(state->device, NULL);

4
src/vertex_simple.vert

@ -6,7 +6,7 @@ layout(binding = 0) uniform UBO { @@ -6,7 +6,7 @@ layout(binding = 0) uniform UBO {
mat4 proj;
} ubo;
layout(location = 0) in vec2 inPosition;
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec2 inTexCoord;
@ -14,7 +14,7 @@ layout(location = 0) out vec3 fragColor; @@ -14,7 +14,7 @@ layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTexCoord;
void main() {
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0);
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
fragColor = inColor;
fragTexCoord = inTexCoord;
}

Loading…
Cancel
Save