move transformations to the gpu
This commit is contained in:
parent
187d62edd3
commit
bc7db2106a
2 changed files with 102 additions and 48 deletions
144
main.cpp
144
main.cpp
|
@ -28,6 +28,11 @@ struct bounding_box
|
||||||
float height;
|
float height;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct uniform
|
||||||
|
{
|
||||||
|
glm::mat4 transform;
|
||||||
|
};
|
||||||
|
|
||||||
bounding_box player;
|
bounding_box player;
|
||||||
float velocityX = 1.0f;
|
float velocityX = 1.0f;
|
||||||
float velocityY = 0.50f;
|
float velocityY = 0.50f;
|
||||||
|
@ -156,11 +161,11 @@ std::vector<vertex> convert_quad_to_triangles(std::vector<vertex> vertices)
|
||||||
return vertices;
|
return vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat2 rotate(float angle)
|
glm::mat4 rotate(float angle)
|
||||||
{
|
{
|
||||||
float c = glm::cos(glm::radians(angle));
|
float c = glm::cos(glm::radians(angle));
|
||||||
float s = glm::sin(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;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,9 +175,9 @@ glm::mat2 scale(glm::vec2 scale)
|
||||||
return transform;
|
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;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +209,35 @@ void simple_physics_step(float t)
|
||||||
player.y = player.y + (velocityY * t);
|
player.y = player.y + (velocityY * t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<vk::DeviceMemory, vk::Buffer> 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()
|
int main()
|
||||||
{
|
{
|
||||||
using clock = std::chrono::system_clock;
|
using clock = std::chrono::system_clock;
|
||||||
|
@ -393,9 +427,27 @@ int main()
|
||||||
color_blend_info.attachmentCount = 1;
|
color_blend_info.attachmentCount = 1;
|
||||||
color_blend_info.pAttachments = &color_blend_attachment;
|
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 = {};
|
vk::PipelineLayoutCreateInfo layout_info = {};
|
||||||
|
layout_info.setLayoutCount = 1;
|
||||||
|
layout_info.pSetLayouts = &descriptor_layout;
|
||||||
vk::PipelineLayout pipeline_layout = device.createPipelineLayout(layout_info);
|
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(),
|
vk::AttachmentDescription color_attachment = vk::AttachmentDescription(vk::AttachmentDescriptionFlags(),
|
||||||
format.format, vk::SampleCountFlagBits::e1,
|
format.format, vk::SampleCountFlagBits::e1,
|
||||||
|
@ -468,42 +520,11 @@ int main()
|
||||||
{{-0.1f, 0.1f}, {0.0f, 0.0f, 1.0f}}
|
{{-0.1f, 0.1f}, {0.0f, 0.0f, 1.0f}}
|
||||||
};
|
};
|
||||||
vertices = convert_quad_to_triangles(vertices);
|
vertices = convert_quad_to_triangles(vertices);
|
||||||
glm::mat2 transform = scale({1.0, 1.0}) * rotate(0.0f);
|
auto ret = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eVertexBuffer, sizeof(vertices[0]) * vertices.size());
|
||||||
glm::vec2 movement = {0.0f, 0.0f};
|
vk::DeviceMemory vertex_buffer_memory = ret.first;
|
||||||
|
vk::Buffer vertex_buffer = ret.second;
|
||||||
for (auto &[position, color] : vertices)
|
char *data = (char *)device.mapMemory(vertex_buffer_memory, 0, sizeof(vertices[0]) * vertices.size());
|
||||||
{
|
memcpy(data, vertices.data(), sizeof(vertices[0]) * vertices.size());
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
vk::CommandPoolCreateInfo command_pool_info = {};
|
vk::CommandPoolCreateInfo command_pool_info = {};
|
||||||
|
@ -515,6 +536,35 @@ int main()
|
||||||
vk::CommandBufferLevel::ePrimary,
|
vk::CommandBufferLevel::ePrimary,
|
||||||
1);
|
1);
|
||||||
auto command_buffers = device.allocateCommandBuffers(cmd_alloc_info);
|
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::SemaphoreCreateInfo semaphore_info = vk::SemaphoreCreateInfo();
|
||||||
vk::FenceCreateInfo fence_info = vk::FenceCreateInfo();
|
vk::FenceCreateInfo fence_info = vk::FenceCreateInfo();
|
||||||
|
@ -551,13 +601,11 @@ int main()
|
||||||
auto time_elapsed = clock::now() - before;
|
auto time_elapsed = clock::now() - before;
|
||||||
simple_physics_step(std::chrono::duration_cast<std::chrono::duration<float>>(time_elapsed).count());
|
simple_physics_step(std::chrono::duration_cast<std::chrono::duration<float>>(time_elapsed).count());
|
||||||
before = clock::now();
|
before = clock::now();
|
||||||
for (int i = 0; i < vertices.size(); i++)
|
u.transform = move({player.x, player.y}) * rotate(angle);
|
||||||
{
|
memcpy(uniform_data, &u, sizeof(uniform));
|
||||||
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));
|
|
||||||
}
|
|
||||||
angle -= 1.0f;
|
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 = {};
|
vk::CommandBufferBeginInfo begin_info = {};
|
||||||
|
@ -571,7 +619,7 @@ int main()
|
||||||
command_buffers[0].bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
|
command_buffers[0].bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
|
||||||
//command_buffers[0].setViewport(0, viewport);
|
//command_buffers[0].setViewport(0, viewport);
|
||||||
//command_buffers[0].setScissor(0, scissor);
|
//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].bindVertexBuffers(0, 1, &vertex_buffer, &offset);
|
||||||
command_buffers[0].draw(vertices.size(), 1, 0, 0);
|
command_buffers[0].draw(vertices.size(), 1, 0, 0);
|
||||||
command_buffers[0].endRenderPass();
|
command_buffers[0].endRenderPass();
|
||||||
|
@ -607,6 +655,8 @@ int main()
|
||||||
//phy_thread.join();
|
//phy_thread.join();
|
||||||
device.unmapMemory(vertex_buffer_memory);
|
device.unmapMemory(vertex_buffer_memory);
|
||||||
device.waitIdle();
|
device.waitIdle();
|
||||||
|
device.destroyDescriptorPool(descriptor_pool);
|
||||||
|
device.destroyDescriptorSetLayout(descriptor_layout);
|
||||||
device.destroyBuffer(vertex_buffer);
|
device.destroyBuffer(vertex_buffer);
|
||||||
device.freeMemory(vertex_buffer_memory);
|
device.freeMemory(vertex_buffer_memory);
|
||||||
for (auto &framebuffer: framebuffers)
|
for (auto &framebuffer: framebuffers)
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
// x -> -1 (left) 1(right)
|
// x -> -1 (left) 1(right)
|
||||||
// y -> -1 (top) 1(bottom)
|
// y -> -1 (top) 1(bottom)
|
||||||
|
|
||||||
|
layout(binding = 0) uniform un{
|
||||||
|
mat4 transform;
|
||||||
|
} trans;
|
||||||
|
|
||||||
layout(location = 0) in vec2 in_position;
|
layout(location = 0) in vec2 in_position;
|
||||||
layout(location = 1) in vec3 in_color;
|
layout(location = 1) in vec3 in_color;
|
||||||
|
|
||||||
|
@ -10,6 +14,6 @@ layout(location = 0) out vec3 frag_color;
|
||||||
|
|
||||||
void main()
|
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;
|
frag_color = in_color;
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue