Browse Source

Depth test.

master
Draklaw 4 years ago
parent
commit
7213c85fdf
  1. 1
      CMakeLists.txt
  2. 2
      shaders/shader.geom
  3. 11
      shaders/shader.vert
  4. 219
      src/Renderer.cpp
  5. 4
      src/Renderer.h
  6. 17
      src/VkExpe.cpp
  7. 4
      src/core/math.cpp
  8. 8
      src/core/utils.h
  9. 124
      src/vk/Image.cpp
  10. 66
      src/vk/Image.h

1
CMakeLists.txt

@ -48,6 +48,7 @@ add_executable(vk_expe
src/vk/Pipeline.cpp
src/vk/Memory.cpp
src/vk/Buffer.cpp
src/vk/Image.cpp
src/vk/ImageView.cpp
src/vk/DescriptorSetLayout.cpp
src/vk/PipelineLayout.cpp

2
shaders/shader.geom

@ -43,7 +43,7 @@ void main() {
vec2 v0 = p0 - p2;
vec2 v1 = p1 - p2;
out_edge_dist[i] = determinant(mat2(v0, v1)) / length(v1);
out_edge_dist[i] = abs(determinant(mat2(v0, v1))) / length(v1);
EmitVertex();
}

11
shaders/shader.vert

@ -18,11 +18,12 @@ layout(location = 1) out vec3 out_normal;
layout(location = 2) out vec3 out_color;
void main() {
float lod = clamp(
2.0 * dot(transpose(uniforms.scene_from_model)[0].xyz, in_position) + 0.5,
0.0, 1.0
);
vec3 position = mix(in_position2, in_position, lod);
// float lod = clamp(
// 2.0 * dot(transpose(uniforms.scene_from_model)[0].xyz, in_position) + 0.5,
// 0.0, 1.0
// );
// vec3 position = mix(in_position2, in_position, lod);
vec3 position = in_position;
out_position =
uniforms.projection_from_scene *
uniforms.scene_from_model *

219
src/Renderer.cpp

@ -59,35 +59,31 @@ std::array<VkVertexInputAttributeDescription, 4> vertex_attributes_description()
std::vector<Vertex> vertices = {
// {{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}},
// {{0.5f, -0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}},
// {{-0.5f, 0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}},
// {{0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}},
{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {1.0f, 0.0f, 0.0f}},
{{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {1.0f, 0.0f, 0.0f}},
{{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {1.0f, 0.0f, 0.0f}},
{{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {1.0f, 0.0f, 0.0f}},
// {{-0.5f, -0.5f, 0.5f}, {0.0f, 1.0f, 1.0f}},
// {{0.5f, -0.5f, 0.5f}, {1.0f, 0.0f, 1.0f}},
// {{-0.5f, 0.5f, 0.5f}, {1.0f, 1.0f, 0.0f}},
// {{0.5f, 0.5f, 0.5f}, {0.2f, 0.2f, 0.2f}},
{{0.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
{{0.0f, -1.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
{{0.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
{{0.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
{{-1.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
{{ 1.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
{{-1.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
{{ 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
};
std::vector<uint32_t> indices = {
// 0, 1, 2,
// 2, 1, 3,
// 1, 5, 3,
// 3, 5, 7,
// 5, 4, 7,
// 7, 4, 6,
0, 1, 2,
2, 1, 3,
// 4, 0, 6,
// 6, 0, 2,
4, 5, 6,
6, 5, 7,
// 0, 4, 1,
// 1, 4, 5,
// 2, 3, 6,
// 6, 3, 7,
8, 9, 10,
10, 9, 11,
};
struct Uniforms {
@ -102,43 +98,43 @@ Renderer::Renderer() {
m_swapchain.register_creation_callback(
std::bind(&Renderer::create_swapchain_objects, this));
auto const subdiv_count = 4;
// auto const subdiv_count = 4;
vertices.resize(6 * Cell::vertex_count(subdiv_count));
indices.resize(6 * 3 * Cell::triangle_count(subdiv_count));
// vertices.resize(6 * Cell::vertex_count(subdiv_count));
// indices.resize(6 * 3 * Cell::triangle_count(subdiv_count));
Vector3AV positions(
vertices.size(), vertices.data(),
sizeof(Vertex), offsetof(Vertex, position)
);
// Vector3AV positions(
// vertices.size(), vertices.data(),
// sizeof(Vertex), offsetof(Vertex, position)
// );
Vector3AV positions2(
vertices.size(), vertices.data(),
sizeof(Vertex), offsetof(Vertex, position2)
);
// Vector3AV positions2(
// vertices.size(), vertices.data(),
// sizeof(Vertex), offsetof(Vertex, position2)
// );
Vector3AV normals(
vertices.size(), vertices.data(),
sizeof(Vertex), offsetof(Vertex, normal)
);
// Vector3AV normals(
// vertices.size(), vertices.data(),
// sizeof(Vertex), offsetof(Vertex, normal)
// );
Vector3AV colors(
vertices.size(), vertices.data(),
sizeof(Vertex), offsetof(Vertex, color)
);
// Vector3AV colors(
// vertices.size(), vertices.data(),
// sizeof(Vertex), offsetof(Vertex, color)
// );
TriangleAV triangles(
indices.size() / 3,
indices.data()
);
// TriangleAV triangles(
// indices.size() / 3,
// indices.data()
// );
Planet planet;
planet.build_mesh(positions, positions2, normals, triangles, subdiv_count);
// Planet planet;
// planet.build_mesh(positions, positions2, normals, triangles, subdiv_count);
for (size_t vertex_index = 0; vertex_index < vertices.size(); vertex_index += 1) {
colors[vertex_index] =
positions[vertex_index] / 2.0f + Vector3::Constant(0.5f);
}
// for (size_t vertex_index = 0; vertex_index < vertices.size(); vertex_index += 1) {
// colors[vertex_index] =
// positions[vertex_index] / 2.0f + Vector3::Constant(0.5f);
// }
// for(size_t vi = 0; vi < vertices.size(); vi += 1)
// logger.debug() << "v" << vi << ": "
@ -315,7 +311,8 @@ void Renderer::create_pipeline_layout() {
}
void Renderer::create_render_pass() {
VkAttachmentDescription color_attachment {
VkAttachmentDescription attachments[] {
{
.format = m_context.surface_format().format,
.samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
@ -324,32 +321,54 @@ void Renderer::create_render_pass() {
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
},
{
.format = VK_FORMAT_X8_D24_UNORM_PACK32,
.samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
},
};
VkAttachmentReference color_attachment_ref = {
VkAttachmentReference color_attachment_ref {
.attachment = 0,
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
VkAttachmentReference depth_attachment_ref {
.attachment = 1,
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
VkSubpassDescription subpass {
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
.colorAttachmentCount = 1,
.pColorAttachments = &color_attachment_ref,
.pDepthStencilAttachment = &depth_attachment_ref,
};
VkSubpassDependency subpass_dep = {
.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_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStageMask =
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dstAccessMask =
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
};
VkRenderPassCreateInfo render_pass_info {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
.attachmentCount = 1,
.pAttachments = &color_attachment,
.attachmentCount = uint32_t(std::extent_v<typeof(attachments)>),
.pAttachments = attachments,
.subpassCount = 1,
.pSubpasses = &subpass,
.dependencyCount = 1,
@ -478,8 +497,8 @@ void Renderer::create_graphic_pipeline() {
.depthClampEnable = VK_FALSE,
.rasterizerDiscardEnable = VK_FALSE,
.polygonMode = VK_POLYGON_MODE_FILL,
// .cullMode = VK_CULL_MODE_NONE,
.cullMode = VK_CULL_MODE_BACK_BIT,
.cullMode = VK_CULL_MODE_NONE,
// .cullMode = VK_CULL_MODE_BACK_BIT,
.frontFace = VK_FRONT_FACE_CLOCKWISE,
.depthBiasEnable = VK_FALSE,
.depthBiasConstantFactor = 0.0f,
@ -498,6 +517,13 @@ void Renderer::create_graphic_pipeline() {
.alphaToOneEnable = VK_FALSE,
};
VkPipelineDepthStencilStateCreateInfo depth_stencil_info {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
.depthTestEnable = VK_TRUE,
.depthWriteEnable = VK_TRUE,
.depthCompareOp = VK_COMPARE_OP_LESS,
};
VkPipelineColorBlendAttachmentState color_blend_attachment {
.blendEnable = VK_FALSE,
.srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
@ -531,7 +557,7 @@ void Renderer::create_graphic_pipeline() {
.pViewportState = &viewport_info,
.pRasterizationState = &rasterization_info,
.pMultisampleState = &multisample_info,
.pDepthStencilState = nullptr,
.pDepthStencilState = &depth_stencil_info,
.pColorBlendState = &color_blend_info,
.pDynamicState = nullptr,
.layout = m_pipeline_layout,
@ -549,6 +575,7 @@ void Renderer::initialize_image_states(size_t image_index) {
auto& image_states = m_image_states[image_index];
image_states.m_image_index = image_index;
create_depth_buffer(image_states);
create_framebuffer(image_states);
create_uniform_buffer(image_states);
@ -562,12 +589,63 @@ void Renderer::initialize_image_states(size_t image_index) {
}
void Renderer::create_depth_buffer(ImageStates& image_states)
{
image_states.m_depth_buffer = vk::Image(
m_context,
VkImageCreateInfo {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.imageType = VK_IMAGE_TYPE_2D,
.format = VK_FORMAT_X8_D24_UNORM_PACK32,
.extent = {
m_swapchain.extent().width,
m_swapchain.extent().height,
1
},
.mipLevels = 1,
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
},
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
);
image_states.m_depth_buffer_view = vk::ImageView(
m_context,
VkImageViewCreateInfo {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = image_states.m_depth_buffer,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = VK_FORMAT_X8_D24_UNORM_PACK32,
.components = {
.r = VK_COMPONENT_SWIZZLE_R,
.g = VK_COMPONENT_SWIZZLE_G,
.b = VK_COMPONENT_SWIZZLE_B,
.a = VK_COMPONENT_SWIZZLE_A,
},
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
}
}
);
}
void Renderer::create_framebuffer(ImageStates& image_states) {
auto view = m_swapchain.image_view(image_states.m_image_index);
VkImageView views[] {
m_swapchain.image_view(image_states.m_image_index),
image_states.m_depth_buffer_view,
};
image_states.m_framebuffer = vk::Framebuffer(
m_context,
m_render_pass,
&view,
views,
m_swapchain.extent()
);
}
@ -661,10 +739,17 @@ void Renderer::create_command_buffer(ImageStates& image_states) {
) != VK_SUCCESS)
throw std::runtime_error("failed to begin command buffer");
VkClearValue clear_color = {
VkClearValue clear_values[] = {
{
.color = {
.float32 = { 0.0f, 0.0f, 0.0f, 1.0f }
}
},
{
.depthStencil = {
.depth = 1.0f,
}
},
};
VkRenderPassBeginInfo pass_info {
@ -675,8 +760,8 @@ void Renderer::create_command_buffer(ImageStates& image_states) {
.offset = { 0, 0 },
.extent = m_swapchain.extent(),
},
.clearValueCount = 1,
.pClearValues = &clear_color,
.clearValueCount = uint32_t(std::extent_v<typeof(clear_values)>),
.pClearValues = clear_values,
};
vkCmdBeginRenderPass(

4
src/Renderer.h

@ -8,6 +8,7 @@
#include <vk/DescriptorPool.h>
#include <vk/PipelineLayout.h>
#include <vk/DescriptorSetLayout.h>
#include <vk/Image.h>
#include <vk/Buffer.h>
#include <vk/Pipeline.h>
#include <vk/Framebuffer.h>
@ -81,6 +82,7 @@ private:
void initialize_image_states(size_t image_index);
void create_depth_buffer(ImageStates& image_states);
void create_framebuffer(ImageStates& image_states);
void create_uniform_buffer(ImageStates& image_states);
@ -119,6 +121,8 @@ private:
struct ImageStates {
size_t m_image_index;
vk::Image m_depth_buffer;
vk::ImageView m_depth_buffer_view;
vk::Framebuffer m_framebuffer;
vk::Buffer m_uniform_buffer;

17
src/VkExpe.cpp

@ -70,9 +70,22 @@ void VkExpe::run() {
auto last_time = std::chrono::high_resolution_clock::now();
SDL_Event event;
// SDL_Event event;
std::vector<SDL_Event> events;
events.reserve(128);
while(m_running) {
while(SDL_PollEvent(&event)) {
SDL_PumpEvents();
int event_count = SDL_PeepEvents(nullptr, 0, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
if(event_count < 0) {
logger.error() << SDL_GetError();
break;
}
events.resize(event_count);
SDL_PeepEvents(events.data(), event_count, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
for(const auto& event: events) {
switch(event.type) {
case SDL_QUIT:
m_running = false;

4
src/core/math.cpp

@ -11,12 +11,12 @@ Eigen::Matrix4f projection_matrix(float x_min, float x_max, float y_min, float y
auto const dy = y_max - y_min;
auto const dz = z_max - z_min;
auto const pz = z_max * z_min;
auto const sz = z_max / dz;
return (Eigen::Matrix4f() <<
2.0f * z_min / dx, 0.0f, -cx / dx, 0.0f,
0.0f, 2.0f * z_min / dy, -cy / dy, 0.0f,
0.0f, 0.0f, cz / dz, -2.0f * pz / dz,
0.0f, 0.0f, sz, (1 - sz) * z_max,
0.0f, 0.0f, 1.0f, 0.0f
).finished();
}

8
src/core/utils.h

@ -65,10 +65,10 @@ public:
assert((size == 0 && m_data == nullptr) || (size != 0 && m_data != nullptr));
}
Array(T* item)
: m_size(1)
, m_data(item)
{}
// Array(T* item)
// : m_size(1)
// , m_data(item)
// {}
template<size_t Size>
Array(T (&array)[Size])

124
src/vk/Image.cpp

@ -0,0 +1,124 @@
// Copyright 2022 Simon Boyé
#include <vk/Image.h>
#include <vk/Context.h>
#include <cassert>
namespace vk {
Image::Image() noexcept {
}
Image::Image(Context& context, VkImageCreateInfo create_info)
: Wrapper(context)
{
assert(m_context);
if(vkCreateImage(
context.device(),
&create_info,
nullptr,
&m_image
) != VK_SUCCESS)
throw std::runtime_error("failed to create image");
}
Image::Image(Context& context, VkImageCreateInfo create_info, VkMemoryPropertyFlags memory_properties)
: Image(context, create_info)
{
allocate_and_bind_memory(memory_properties);
}
Image::Image(Image&& other) noexcept
{
swap(other);
}
Image::~Image() noexcept {
if(!is_null())
destroy();
}
Image& Image::operator=(Image&& other) noexcept {
swap(other);
if(other)
other.destroy();
return *this;
}
VkMemoryRequirements Image::memory_requirements() const noexcept {
assert(!is_null());
assert(*m_context);
VkMemoryRequirements memory_requirements;
vkGetImageMemoryRequirements(
m_context->device(),
m_image,
&memory_requirements
);
return memory_requirements;
}
void Image::bind_memory(const MemoryBlock& memory_block, VkDeviceSize offset) {
assert(!is_null());
assert(*m_context);
assert(memory_block);
// m_memory = std::move(memory_block);
if(vkBindImageMemory(
m_context->device(),
m_image,
memory_block.device_memory(),
memory_block.offset() + offset
) != VK_SUCCESS)
throw std::runtime_error("failed to bind image memory");
}
void Image::bind_memory(MemoryBlock&& memory_block) {
bind_memory(memory_block);
m_memory = std::move(memory_block);
}
void Image::allocate_and_bind_memory(VkMemoryPropertyFlags memory_properties) {
assert(!is_null());
assert(*m_context);
const auto memory_requirements = this->memory_requirements();
m_memory = m_context->allocator().allocate(
memory_requirements.size,
memory_requirements.memoryTypeBits,
memory_properties
);
bind_memory(m_memory);
}
void Image::destroy() noexcept {
assert(!is_null());
assert(m_context);
if(m_memory) {
m_memory.free();
m_memory = MemoryBlock();
}
vkDestroyImage(
m_context->device(),
m_image,
nullptr
);
m_context = nullptr;
m_image = VK_NULL_HANDLE;
}
}

66
src/vk/Image.h

@ -0,0 +1,66 @@
// Copyright 2022 Simon Boyé
#pragma once
#include <vk/forward.h>
#include <vk/Wrapper.h>
#include <vk/Memory.h>
#include <vulkan/vulkan.h>
namespace vk {
class Image: public Wrapper {
public:
Image() noexcept;
Image(Context& context, VkImageCreateInfo create_info);
Image(Context& context, VkImageCreateInfo create_info, VkMemoryPropertyFlags memory_properties);
Image(const Image&) = default;
Image(Image&& other) noexcept;
~Image() noexcept;
Image& operator=(const Image&) = default;
Image& operator=(Image&& other) noexcept;
explicit inline operator bool() const noexcept {
return !is_null();
}
inline bool is_null() const noexcept {
return m_image == VK_NULL_HANDLE;
}
inline operator VkImage() noexcept {
return m_image;
}
inline VkImage image() noexcept {
return m_image;
}
VkMemoryRequirements memory_requirements() const noexcept;
void bind_memory(const MemoryBlock& memory_block, VkDeviceSize offset=0);
void bind_memory(MemoryBlock&& memory_block);
void allocate_and_bind_memory(VkMemoryPropertyFlags memory_properties);
inline void swap(Image& other) noexcept {
using std::swap;
Wrapper::swap(other);
swap(m_image, other.m_image);
}
friend inline void swap(Image& image_0, Image& image_1) noexcept {
image_0.swap(image_1);
}
void destroy() noexcept;
private:
VkImage m_image = VK_NULL_HANDLE;
MemoryBlock m_memory;
};
}
Loading…
Cancel
Save