diff --git a/main.cpp b/main.cpp index a198114..69562c7 100644 --- a/main.cpp +++ b/main.cpp @@ -28,6 +28,11 @@ struct bounding_box float height; }; +struct uniform +{ + glm::mat4 transform; +}; + bounding_box player; float velocityX = 1.0f; float velocityY = 0.50f; @@ -156,11 +161,11 @@ std::vector convert_quad_to_triangles(std::vector vertices) return vertices; } -glm::mat2 rotate(float angle) +glm::mat4 rotate(float angle) { float c = glm::cos(glm::radians(angle)); float s = glm::sin(glm::radians(angle)); - glm::mat2 transform({c, s}, {-s, c}); + glm::mat4 transform({c, s, 0.0f, 0.0f}, {-s, c, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 1.0f}); return transform; } @@ -170,9 +175,9 @@ glm::mat2 scale(glm::vec2 scale) return transform; } -glm::mat3 move(glm::vec2 pos) +glm::mat4 move(glm::vec2 pos) { - glm::mat3 transform({1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {pos.x, pos.y, 1.0f}); + glm::mat4 transform({1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}, {pos.x, pos.y, 0.0f, 1.0f}); return transform; } @@ -204,6 +209,35 @@ void simple_physics_step(float t) player.y = player.y + (velocityY * t); } +std::pair create_buffer(const vk::Device &device, vk::PhysicalDevice selected_physical_device, vk::BufferUsageFlagBits usage, size_t size) +{ + vk::BufferCreateInfo buffer_info = vk::BufferCreateInfo(vk::BufferCreateFlags(), size, usage, vk::SharingMode::eExclusive); + vk::Buffer vertex_buffer = device.createBuffer(buffer_info); + VkMemoryRequirements memory_requirements; + vkGetBufferMemoryRequirements(device, vertex_buffer, &memory_requirements); + vk::PhysicalDeviceMemoryProperties memory_properties = selected_physical_device.getMemoryProperties(); + + int propierty_index = -1; + for (int i = 0; i < memory_properties.memoryTypeCount; i++) + { + if (memory_properties.memoryTypes[i].propertyFlags & vk::MemoryPropertyFlags(vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent)) + { + propierty_index = i; + break; + } + } + if (propierty_index == -1) + { + throw std::runtime_error("Didnt find a suitable memory"); + } + + vk::MemoryAllocateInfo alloc_info = vk::MemoryAllocateInfo(memory_requirements.size, propierty_index); + + vk::DeviceMemory vertex_buffer_memory = device.allocateMemory(alloc_info); + device.bindBufferMemory(vertex_buffer, vertex_buffer_memory, 0); + return std::make_pair(vertex_buffer_memory, vertex_buffer); +} + int main() { using clock = std::chrono::system_clock; @@ -393,9 +427,27 @@ int main() color_blend_info.attachmentCount = 1; color_blend_info.pAttachments = &color_blend_attachment; + vk::DescriptorSetLayoutBinding descriptor_binding; + descriptor_binding.binding = 0; + descriptor_binding.descriptorCount = 1; + descriptor_binding.descriptorType = vk::DescriptorType::eUniformBuffer; + descriptor_binding.stageFlags = vk::ShaderStageFlagBits::eVertex; + + vk::DescriptorSetLayoutCreateInfo descriptor_layout_info(vk::DescriptorSetLayoutCreateFlags(), 1, &descriptor_binding); + vk::DescriptorSetLayout descriptor_layout = device.createDescriptorSetLayout(descriptor_layout_info); + vk::PipelineLayoutCreateInfo layout_info = {}; + layout_info.setLayoutCount = 1; + layout_info.pSetLayouts = &descriptor_layout; vk::PipelineLayout pipeline_layout = device.createPipelineLayout(layout_info); + uniform u{}; + u.transform = glm::mat4(1.0f); + auto rec = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eUniformBuffer, sizeof(uniform)); + vk::DeviceMemory uniform_buffer_data = rec.first; + vk::Buffer uniform_buffer = rec.second; + char *uniform_data = (char *)device.mapMemory(uniform_buffer_data, 0, sizeof(uniform)); + memcpy(uniform_data, &u, sizeof(uniform)); vk::AttachmentDescription color_attachment = vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), format.format, vk::SampleCountFlagBits::e1, @@ -468,42 +520,11 @@ int main() {{-0.1f, 0.1f}, {0.0f, 0.0f, 1.0f}} }; vertices = convert_quad_to_triangles(vertices); - glm::mat2 transform = scale({1.0, 1.0}) * rotate(0.0f); - glm::vec2 movement = {0.0f, 0.0f}; - - for (auto &[position, color] : vertices) - { - position = position + movement; - position = transform * position; - } - - vk::BufferCreateInfo buffer_info = vk::BufferCreateInfo(vk::BufferCreateFlags(), sizeof(vertices[0]) * vertices.size(), vk::BufferUsageFlagBits::eVertexBuffer, vk::SharingMode::eExclusive); - vk::Buffer vertex_buffer = device.createBuffer(buffer_info); - VkMemoryRequirements memory_requirements; - vkGetBufferMemoryRequirements(device, vertex_buffer, &memory_requirements); - vk::PhysicalDeviceMemoryProperties memory_propierties = selected_physical_device.getMemoryProperties(); - - int propierty_index = -1; - for (int i = 0; i < memory_propierties.memoryTypeCount; i++) - { - if (memory_propierties.memoryTypes[i].propertyFlags & vk::MemoryPropertyFlags(vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent)) - { - propierty_index = i; - break; - } - } - if (propierty_index == -1) - { - throw std::runtime_error("Didnt find a suitable memory"); - } - - vk::MemoryAllocateInfo alloc_info = vk::MemoryAllocateInfo(memory_requirements.size, propierty_index); - - vk::DeviceMemory vertex_buffer_memory = device.allocateMemory(alloc_info); - device.bindBufferMemory(vertex_buffer, vertex_buffer_memory, 0); - - char *data = (char *)device.mapMemory(vertex_buffer_memory, 0, buffer_info.size); - memcpy(data, vertices.data(), buffer_info.size); + auto ret = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eVertexBuffer, sizeof(vertices[0]) * vertices.size()); + vk::DeviceMemory vertex_buffer_memory = ret.first; + vk::Buffer vertex_buffer = ret.second; + char *data = (char *)device.mapMemory(vertex_buffer_memory, 0, sizeof(vertices[0]) * vertices.size()); + memcpy(data, vertices.data(), sizeof(vertices[0]) * vertices.size()); vk::CommandPoolCreateInfo command_pool_info = {}; @@ -515,6 +536,35 @@ int main() vk::CommandBufferLevel::ePrimary, 1); auto command_buffers = device.allocateCommandBuffers(cmd_alloc_info); + vk::DescriptorPoolSize descriptor_pool_size(vk::DescriptorType::eUniformBuffer, sizeof(uniform)); + vk::DescriptorPoolCreateInfo descriptor_pool_info; + descriptor_pool_info.maxSets = 1; + descriptor_pool_info.poolSizeCount = 1; + descriptor_pool_info.pPoolSizes = &descriptor_pool_size; + + vk::DescriptorPool descriptor_pool = device.createDescriptorPool(descriptor_pool_info); + + vk::DescriptorSetAllocateInfo descriptor_set_allocate_info; + descriptor_set_allocate_info.descriptorPool = descriptor_pool; + descriptor_set_allocate_info.descriptorSetCount = 1; + descriptor_set_allocate_info.pSetLayouts = &descriptor_layout; + + auto descriptor_sets = device.allocateDescriptorSets(descriptor_set_allocate_info); + vk::DescriptorSet descriptor_set = descriptor_sets[0]; + + vk::DescriptorBufferInfo descriptor_buffer_info; + descriptor_buffer_info.buffer = uniform_buffer; + descriptor_buffer_info.offset = 0; + descriptor_buffer_info.range = sizeof(uniform); + + vk::WriteDescriptorSet write_descriptor; + write_descriptor.descriptorCount = 1; + write_descriptor.descriptorType = vk::DescriptorType::eUniformBuffer; + write_descriptor.dstBinding = 0; + write_descriptor.dstArrayElement = 0; + write_descriptor.dstSet = descriptor_set; + write_descriptor.pBufferInfo = &descriptor_buffer_info; + device.updateDescriptorSets(write_descriptor, nullptr); vk::SemaphoreCreateInfo semaphore_info = vk::SemaphoreCreateInfo(); vk::FenceCreateInfo fence_info = vk::FenceCreateInfo(); @@ -551,13 +601,11 @@ int main() auto time_elapsed = clock::now() - before; simple_physics_step(std::chrono::duration_cast>(time_elapsed).count()); before = clock::now(); - for (int i = 0; i < vertices.size(); i++) - { - render_vertices[i].position = vertices[i].position * rotate(angle); - render_vertices[i].position = glm::vec2(move({player.x, player.y}) * glm::vec3(render_vertices[i].position, 1.0f)); - } + u.transform = move({player.x, player.y}) * rotate(angle); + memcpy(uniform_data, &u, sizeof(uniform)); + angle -= 1.0f; - memcpy(data, render_vertices.data(), buffer_info.size); + memcpy(data, render_vertices.data(), sizeof(vertices[0]) * vertices.size()); vk::CommandBufferBeginInfo begin_info = {}; @@ -571,7 +619,7 @@ int main() command_buffers[0].bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); //command_buffers[0].setViewport(0, viewport); //command_buffers[0].setScissor(0, scissor); - + command_buffers[0].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline_layout, 0, descriptor_sets, nullptr); command_buffers[0].bindVertexBuffers(0, 1, &vertex_buffer, &offset); command_buffers[0].draw(vertices.size(), 1, 0, 0); command_buffers[0].endRenderPass(); @@ -607,6 +655,8 @@ int main() //phy_thread.join(); device.unmapMemory(vertex_buffer_memory); device.waitIdle(); + device.destroyDescriptorPool(descriptor_pool); + device.destroyDescriptorSetLayout(descriptor_layout); device.destroyBuffer(vertex_buffer); device.freeMemory(vertex_buffer_memory); for (auto &framebuffer: framebuffers) diff --git a/shaders/vertex.vert b/shaders/vertex.vert index 71b74b4..0ff624b 100644 --- a/shaders/vertex.vert +++ b/shaders/vertex.vert @@ -3,6 +3,10 @@ // x -> -1 (left) 1(right) // y -> -1 (top) 1(bottom) +layout(binding = 0) uniform un{ + mat4 transform; +} trans; + layout(location = 0) in vec2 in_position; layout(location = 1) in vec3 in_color; @@ -10,6 +14,6 @@ layout(location = 0) out vec3 frag_color; void main() { - gl_Position = vec4(in_position, 0.0, 1.0); + gl_Position = trans.transform * vec4(in_position, 0.0, 1.0); frag_color = in_color; } \ No newline at end of file