summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--glsl/shader_2d.frag.glsl2
-rw-r--r--glsl/shader_2d.vert.glsl9
-rw-r--r--src/vk/graphics_pipeline_2d.cpp187
-rw-r--r--src/vk/graphics_pipeline_2d.hpp9
-rw-r--r--src/vk/sprite.cpp2
-rw-r--r--src/vk/uniform_buffer.hpp5
-rw-r--r--test/src/main.rb2
7 files changed, 198 insertions, 18 deletions
diff --git a/glsl/shader_2d.frag.glsl b/glsl/shader_2d.frag.glsl
index 1edbbbb..54ab1be 100644
--- a/glsl/shader_2d.frag.glsl
+++ b/glsl/shader_2d.frag.glsl
@@ -21,7 +21,7 @@ layout(location = 0) in vec2 in_texture_coord;
layout(location = 0) out vec4 out_color;
-layout(set = 0, binding = 1) uniform sampler2D texture_sampler;
+layout(set = 1, binding = 1) uniform sampler2D texture_sampler;
void
main()
diff --git a/glsl/shader_2d.vert.glsl b/glsl/shader_2d.vert.glsl
index 6e8ac59..b053fec 100644
--- a/glsl/shader_2d.vert.glsl
+++ b/glsl/shader_2d.vert.glsl
@@ -21,7 +21,12 @@ layout(location = 0) in vec2 in_texture_coord;
layout(location = 0) out vec2 out_texture_coord;
-layout(set = 0, binding = 0) uniform UBOSpritePositions
+layout(set = 0, binding = 0) uniform UBOProjection
+{
+ mat4 proj;
+} ubo_projection;
+
+layout(set = 1, binding = 0) uniform UBOSpritePositions
{
vec4 positions[128];
} ubo_sprite_positions;
@@ -49,5 +54,5 @@ main()
coordinate = vec2(position.z, position.w);
break;
}
- gl_Position = vec4(coordinate, 0.0, 1.0);
+ gl_Position = ubo_projection.proj * vec4(coordinate, 0.0, 1.0);
}
diff --git a/src/vk/graphics_pipeline_2d.cpp b/src/vk/graphics_pipeline_2d.cpp
index e8fd002..bc519d9 100644
--- a/src/vk/graphics_pipeline_2d.cpp
+++ b/src/vk/graphics_pipeline_2d.cpp
@@ -25,7 +25,44 @@ namespace
{
void
-load_descriptor_set_layout_image_sprites(void *obj)
+load_descriptor_set_layout_projection(void *obj)
+{
+ auto self = static_cast<VK::GraphicsPipeline2D*>(obj);
+
+ std::array<VkDescriptorSetLayoutBinding, 1> layout_bindings{};
+
+ layout_bindings[0].binding = 0;
+ layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ layout_bindings[0].descriptorCount = 1;
+ layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
+ layout_bindings[0].pImmutableSamplers = nullptr;
+
+ VkDescriptorSetLayoutCreateInfo layout_info{};
+ layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+ layout_info.pNext = nullptr;
+ layout_info.flags = 0;
+ layout_info.bindingCount = static_cast<uint32_t>(layout_bindings.size());
+ layout_info.pBindings = layout_bindings.data();
+
+ if(vkCreateDescriptorSetLayout(
+ cg_core.vk_device_with_swapchain->device, &layout_info, nullptr,
+ &self->descriptor_set_layout_projection) != VK_SUCCESS)
+ throw CommandError{
+ "Failed to create Vulkan descriptor set layout for projection."};
+}
+
+void
+unload_descriptor_set_layout_projection(void *obj)
+{
+ auto self = static_cast<VK::GraphicsPipeline2D*>(obj);
+
+ vkDestroyDescriptorSetLayout(
+ cg_core.vk_device_with_swapchain->device,
+ self->descriptor_set_layout_projection, nullptr);
+}
+
+void
+load_descriptor_set_layout_sprite(void *obj)
{
auto self = static_cast<VK::GraphicsPipeline2D*>(obj);
@@ -53,19 +90,19 @@ load_descriptor_set_layout_image_sprites(void *obj)
if(vkCreateDescriptorSetLayout(
cg_core.vk_device_with_swapchain->device, &layout_info, nullptr,
- &self->descriptor_set_layout_sprites) != VK_SUCCESS)
+ &self->descriptor_set_layout_sprite) != VK_SUCCESS)
throw CommandError{
- "Failed to create Vulkan descriptor set layout for model instance."};
+ "Failed to create Vulkan descriptor set layout for sprites."};
}
void
-unload_descriptor_set_layout_image_sprites(void *obj)
+unload_descriptor_set_layout_sprite(void *obj)
{
auto self = static_cast<VK::GraphicsPipeline2D*>(obj);
vkDestroyDescriptorSetLayout(
cg_core.vk_device_with_swapchain->device,
- self->descriptor_set_layout_sprites, nullptr);
+ self->descriptor_set_layout_sprite, nullptr);
}
void
@@ -73,8 +110,9 @@ load_pipeline_layout(void *obj)
{
auto self = static_cast<VK::GraphicsPipeline2D*>(obj);
- std::array<VkDescriptorSetLayout, 1> set_layouts{
- self->descriptor_set_layout_sprites
+ std::array<VkDescriptorSetLayout, 2> set_layouts{
+ self->descriptor_set_layout_projection,
+ self->descriptor_set_layout_sprite
};
VkPipelineLayoutCreateInfo pipeline_layout_info{};
@@ -100,6 +138,122 @@ unload_pipeline_layout(void *obj)
}
void
+load_projection_uniform_buffer(void *obj)
+{
+ auto self = static_cast<VK::GraphicsPipeline2D*>(obj);
+
+ try
+ {
+ self->ub_projection.reserve(cg_core.vk_swapchain->images_count);
+ for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++)
+ self->ub_projection.emplace_back(
+ cg_core.vk_device_with_swapchain, sizeof(VK::UBOProjection));
+ }
+ catch(const std::exception& e)
+ {
+ throw CommandError{e.what()};
+ }
+}
+
+void
+unload_projection_uniform_buffer(void *obj)
+{
+ auto self = static_cast<VK::GraphicsPipeline2D*>(obj);
+
+ self->ub_projection.clear();
+}
+
+void
+load_descriptor_pool(void *obj)
+{
+ auto self = static_cast<VK::GraphicsPipeline2D*>(obj);
+
+ VkDescriptorPoolSize descriptor_pool_size{};
+ descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ descriptor_pool_size.descriptorCount = self->ub_projection.size();
+
+ VkDescriptorPoolCreateInfo pool_info{};
+ pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+ pool_info.pNext = nullptr;
+ pool_info.flags = 0;
+ pool_info.maxSets = self->ub_projection.size();
+ pool_info.poolSizeCount = 1;
+ pool_info.pPoolSizes = &descriptor_pool_size;
+
+ if(vkCreateDescriptorPool(
+ cg_core.vk_device_with_swapchain->device,
+ &pool_info, nullptr, &self->descriptor_pool) != VK_SUCCESS)
+ throw CommandError{"Failed to create a Vulkan descriptor pool."};
+}
+
+void
+unload_descriptor_pool(void *obj)
+{
+ auto self = static_cast<VK::GraphicsPipeline2D*>(obj);
+
+ vkDestroyDescriptorPool(
+ cg_core.vk_device_with_swapchain->device, self->descriptor_pool, nullptr);
+}
+
+void
+load_projection_descriptor_sets(void *obj)
+{
+ auto self = static_cast<VK::GraphicsPipeline2D*>(obj);
+
+ std::vector<VkDescriptorSetLayout> layouts(
+ self->ub_projection.size(),
+ self->descriptor_set_layout_projection);
+
+ VkDescriptorSetAllocateInfo alloc_info{};
+ alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+ alloc_info.descriptorPool = self->descriptor_pool;
+ alloc_info.descriptorSetCount = layouts.size();
+ alloc_info.pSetLayouts = layouts.data();
+
+ self->projection_descriptor_sets.resize(layouts.size());
+ if(vkAllocateDescriptorSets(
+ cg_core.vk_device_with_swapchain->device, &alloc_info,
+ self->projection_descriptor_sets.data()) != VK_SUCCESS)
+ throw CommandError{"Failed to create Vulkan projection descriptor sets."};
+}
+
+void
+load_resources_to_descriptor_sets(void *obj)
+{
+ auto self = static_cast<VK::GraphicsPipeline2D*>(obj);
+
+ for(auto i{0}; i < self->ub_projection.size(); i++)
+ {
+ VkDescriptorBufferInfo projection_info{};
+ projection_info.buffer = self->ub_projection[i].buffer;
+ projection_info.offset = 0;
+ projection_info.range = sizeof(VK::UBOProjection);
+
+ std::array<VkWriteDescriptorSet, 1> write_descriptors{};
+ write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ write_descriptors[0].dstSet = self->projection_descriptor_sets[i];
+ write_descriptors[0].dstBinding = 0;
+ write_descriptors[0].dstArrayElement = 0;
+ write_descriptors[0].descriptorCount = 1;
+ write_descriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ write_descriptors[0].pBufferInfo = &projection_info;
+ write_descriptors[0].pImageInfo = nullptr;
+ write_descriptors[0].pTexelBufferView = nullptr;
+
+ vkUpdateDescriptorSets(
+ cg_core.vk_device_with_swapchain->device, write_descriptors.size(),
+ write_descriptors.data(), 0, nullptr);
+
+ VK::UBOProjection ubo_projection;
+ ubo_projection.proj = glm::ortho(
+ 0.0f, static_cast<float>(cg_core.game_width),
+ 0.0f, static_cast<float>(cg_core.game_height),
+ 0.0f, 100.0f);
+ self->ub_projection[i].copy_data(&ubo_projection);
+ }
+}
+
+void
load_render_pass(void *obj)
{
auto self = static_cast<VK::GraphicsPipeline2D*>(obj);
@@ -393,9 +547,15 @@ unload_pipeline(void *obj)
}
const CommandChain loader{
- {&load_descriptor_set_layout_image_sprites,
- &unload_descriptor_set_layout_image_sprites},
+ {&load_descriptor_set_layout_projection,
+ &unload_descriptor_set_layout_projection},
+ {&load_descriptor_set_layout_sprite, &unload_descriptor_set_layout_sprite},
{&load_pipeline_layout, &unload_pipeline_layout},
+ {&load_projection_uniform_buffer, &unload_projection_uniform_buffer},
+ {&load_descriptor_pool, &unload_descriptor_pool},
+ // By destroying the pool the sets are also destroyed.
+ {&load_projection_descriptor_sets, nullptr},
+ {&load_resources_to_descriptor_sets, nullptr},
{&load_render_pass, &unload_render_pass},
{&load_framebuffer, &unload_framebuffer},
{&load_pipeline, &unload_pipeline}
@@ -436,7 +596,7 @@ GraphicsPipeline2D::draw(
render_pass_begin.pClearValues = nullptr;
vkCmdBeginRenderPass(
- draw_command_buffer, &render_pass_begin,VK_SUBPASS_CONTENTS_INLINE);
+ draw_command_buffer, &render_pass_begin,VK_SUBPASS_CONTENTS_INLINE);
VkViewport vk_viewport{};
vk_viewport.width = static_cast<float>(cg_core.screen_width);
@@ -457,12 +617,15 @@ GraphicsPipeline2D::draw(
{
// Commands
{
+ std::array<VkDescriptorSet, 2> vk_descriptor_sets{
+ this->projection_descriptor_sets[image_index],
+ sprite->descriptor_sets[image_index]};
VkDeviceSize offsets[]{0};
vkCmdBindDescriptorSets(
draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
- this->pipeline_layout, 0, 1, &sprite->descriptor_sets[image_index],
- 0, nullptr);
+ this->pipeline_layout, 0, vk_descriptor_sets.size(),
+ vk_descriptor_sets.data(), 0, nullptr);
vkCmdBindPipeline(
draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
this->graphic_pipeline);
diff --git a/src/vk/graphics_pipeline_2d.hpp b/src/vk/graphics_pipeline_2d.hpp
index f6a1b47..dc122be 100644
--- a/src/vk/graphics_pipeline_2d.hpp
+++ b/src/vk/graphics_pipeline_2d.hpp
@@ -27,9 +27,16 @@ namespace VK
struct GraphicsPipeline2D
{
- VkDescriptorSetLayout descriptor_set_layout_sprites;
+ VkDescriptorSetLayout descriptor_set_layout_projection;
+ VkDescriptorSetLayout descriptor_set_layout_sprite;
VkPipelineLayout pipeline_layout;
+ // FIXME: if this vector get resized, it will cause a segmentation fault!
+ std::vector<UniformBuffer> ub_projection;
+
+ VkDescriptorPool descriptor_pool;
+ std::vector<VkDescriptorSet> projection_descriptor_sets;
+
VkRenderPass render_pass;
std::vector<VkFramebuffer> swapchain_framebuffers;
VkPipeline graphic_pipeline;
diff --git a/src/vk/sprite.cpp b/src/vk/sprite.cpp
index e00fcbe..a7b65d7 100644
--- a/src/vk/sprite.cpp
+++ b/src/vk/sprite.cpp
@@ -137,7 +137,7 @@ load_descriptor_sets(void *obj)
std::vector<VkDescriptorSetLayout> layouts(
cg_core.vk_swapchain->images_count,
- cg_core.vk_graphics_pipeline_2d->descriptor_set_layout_sprites);
+ cg_core.vk_graphics_pipeline_2d->descriptor_set_layout_sprite);
VkDescriptorSetAllocateInfo alloc_info{};
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
diff --git a/src/vk/uniform_buffer.hpp b/src/vk/uniform_buffer.hpp
index 50759b8..2cee9ff 100644
--- a/src/vk/uniform_buffer.hpp
+++ b/src/vk/uniform_buffer.hpp
@@ -31,6 +31,11 @@ struct UBOSpritePositions
glm::vec4 positions[128];
};
+struct UBOProjection
+{
+ glm::mat4 proj;
+};
+
struct UBOModelInstance
{
glm::mat4 instances[128];
diff --git a/test/src/main.rb b/test/src/main.rb
index 6ac0dde..b153a50 100644
--- a/test/src/main.rb
+++ b/test/src/main.rb
@@ -68,7 +68,7 @@ end
def quit() = CandyGear.quit();
def tick()
- $sprite.draw(-1.0, -1.0, -0.70, -0.5);
+ $sprite.draw(1.0, 1.0, 101.0, 101.0);
$instances_rotation.rotate(0.0, BOX_ROTATION_SPEED);
$instances.each do |i|
$model.draw(i, $instances_rotation);