Criando o uniform buffer
Na próxima seção, especificaremos o buffer que contém os dados do UBO para o shader, mas precisamos criar esse buffer primeiro. Vamos copiar novos dados para o uniform buffer a cada quadro, então não faz sentido ter um staging buffer. Isso apenas adicionaria uma sobrecarga extra nesse caso e provavelmente degradaria o desempenho em vez de melhorá-lo.
Adicionamos novos membros de estrutura em Object3D
para armazenar o uniform buffer e o identificar do objeto de memória associado a ele:
VkBuffer uniformBuffer = VK_NULL_HANDLE;
VkDeviceMemory uniformBufferMemory = VK_NULL_HANDLE;
Em seguida, criamos uma nova função chamada createUniformBuffer
e chamamos-a no final de initObject
antes de addTextureImage
. Essa função alocará o uniform buffer usando nossa função auxiliar createBuffer
:
void Renderer::initObject() {
...
createUniformBuffer();
addTextureImage(":/textures/texture.png");
}
void Renderer::createUniformBuffer() {
VkDeviceSize uniformBufferSize = sizeof(UniformBufferObject);
createBuffer(
uniformBufferSize,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
m_window->hostVisibleMemoryIndex(),
m_object->uniformBuffer,
m_object->uniformBufferMemory
);
}
Criaremos uma outra função que atualizará o buffer aplicando uma transformação a cada quadro, portanto, não usaremos vkMapMemory
aqui. Os dados do tipo uniform
serão usados para todas as chamadas de desenho, portanto, o buffer que os contém só deve ser destruído quando pararmos de renderizar o objeto 3D:
void Renderer::releaseObjectResources() {
...
if (m_object->uniformBuffer) {
m_deviceFunctions->vkDestroyBuffer(device, m_object->uniformBuffer, nullptr);
m_object->uniformBuffer = VK_NULL_HANDLE;
}
if (m_object->vertexBufferMemory) {
m_deviceFunctions->vkFreeMemory(device, m_object->uniformBufferMemory, nullptr);
m_object->uniformBufferMemory = VK_NULL_HANDLE;
}
}