Preparando a imagem de textura
Agora estamos prontos para copiar os dados do staging buffer para a imagem de textura na função addTextureImage
. Primeiro, precisamos fazer a transição do layout da imagem de textura para VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
. Fazemos isso utilizando nossa função transitionImageLayout
:
transitionImageLayout(
m_object->textureImage,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
);
Como a imagem foi criada com o layout VK_IMAGE_LAYOUT_UNDEFINED
, precisamos especificar isso como o layout antigo. Podemos fazer isso porque não nos importamos com seu conteúdo antes de executar a operação de cópia.
Em seguida, precisamos executar a operação de cópia dos dados do buffer para a imagem. Para isso, usamos a função copyBufferToImage
:
copyBufferToImage(
stagingBuffer, m_object->textureImage,
static_cast<uint32_t>(image.width()),
static_cast<uint32_t>(image.height())
);
Precisamos agora de uma última transição para podermos fazer a amostragem da imagem de textura no shader:
transitionImageLayout(
m_object->textureImage,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
);
Indicamos isso através do uso do sinalizador VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
.
Liberando os recursos de imagem
Concluímos a função addTextureImage
limpando o staging buffer e sua memória no final:
...
m_deviceFunctions->vkDestroyBuffer(
device, stagingBuffer,
nullptr
);
m_deviceFunctions->vkFreeMemory(
device,
stagingBufferMemory,
nullptr
);
A imagem de textura do objeto 3D deve ser destruída na função releaseObjectResources
. A memória que está vinculada a um objeto de imagem pode ser liberada uma vez que a imagem não é mais usada, portanto, vamos liberá-la depois que a imagem foi destruída:
void Renderer::releaseObjectResources() {
...
if (m_object->textureImage) {
m_deviceFunctions->vkDestroyImage(
device, m_object->textureImage,
nullptr
);
m_object->textureImage = VK_NULL_HANDLE;
}
if (m_object->textureImageMemory) {
m_deviceFunctions->vkFreeMemory(
device,
m_object->textureImageMemory,
nullptr
);
m_object->textureImageMemory = VK_NULL_HANDLE;
}
}