Depth test.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 *
|
||||
|
||||
241
src/Renderer.cpp
241
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,
|
||||
0, 1, 2,
|
||||
2, 1, 3,
|
||||
|
||||
// 1, 5, 3,
|
||||
// 3, 5, 7,
|
||||
4, 5, 6,
|
||||
6, 5, 7,
|
||||
|
||||
// 5, 4, 7,
|
||||
// 7, 4, 6,
|
||||
|
||||
// 4, 0, 6,
|
||||
// 6, 0, 2,
|
||||
|
||||
// 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,41 +311,64 @@ void Renderer::create_pipeline_layout() {
|
||||
}
|
||||
|
||||
void Renderer::create_render_pass() {
|
||||
VkAttachmentDescription color_attachment {
|
||||
.format = m_context.surface_format().format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
VkAttachmentDescription attachments[] {
|
||||
{
|
||||
.format = m_context.surface_format().format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.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 = {
|
||||
.color = {
|
||||
.float32 = { 0.0f, 0.0f, 0.0f, 1.0f }
|
||||
}
|
||||
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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -11,13 +11,13 @@ 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, 1.0f, 0.0f
|
||||
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, sz, (1 - sz) * z_max,
|
||||
0.0f, 0.0f, 1.0f, 0.0f
|
||||
).finished();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
Normal file
124
src/vk/Image.cpp
Normal file
@@ -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
Normal file
66
src/vk/Image.h
Normal file
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user