Vulkan 学习笔记 03
本章主要的目标是在imgui界面中显示图片,参考文献在最后有链接。主要的步骤是给需要显示的图片创建descriptor set,在显示图片的时候添加这个descriptor set,并且在最终imgui渲染录制绘制指令时,需要稍微修改运行逻辑,在实际调用vkCmdDrawIndexed
时,绑定对应的descriptor set,调用正确的贴图。
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline);
VkViewport viewport {};
viewport.width = ImGui::GetIO().DisplaySize.x;
viewport.height = ImGui::GetIO().DisplaySize.y;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vkCmdSetViewport(command_buffer, 0, 1, &viewport);
// UI scale and translate via push constants
m_push_const.scale = {2.0f / io.DisplaySize.x, 2.0f / io.DisplaySize.y};
m_push_const.translate = {-1.0f, -1.0f};
vkCmdPushConstants(command_buffer, m_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstantBlock), &m_push_const);
// Render commands
ImDrawData* main_draw_data = ImGui::GetDrawData();
int32_t vertex_offset = 0;
int32_t index_offset = 0;
if (main_draw_data->CmdListsCount > 0)
{
VkDeviceSize offsets[1] = {0};
vkCmdBindVertexBuffers(command_buffer, 0, 1, &m_vertex_buffer->buffer, offsets);
vkCmdBindIndexBuffer(command_buffer, m_index_buffer->buffer, 0, VK_INDEX_TYPE_UINT16);
for (int32_t i = 0; i < main_draw_data->CmdListsCount; i++)
{
const ImDrawList* cmd_list = main_draw_data->CmdLists[i];
for (int32_t j = 0; j < cmd_list->CmdBuffer.Size; j++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[j];
VkRect2D scissorRect;
VkDescriptorSet desc_set = (VkDescriptorSet)pcmd->TextureId;
if (sizeof(ImTextureID) < sizeof(ImU64))
{
// We don't support texture switches if ImTextureID hasn't been redefined to be 64-bit.
// Do a flaky check that other textures haven't been used.
desc_set = m_descriptor_set;
}
if (desc_set == VK_NULL_HANDLE)
{
desc_set = m_descriptor_set;
}
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, &desc_set, 0, nullptr);
scissorRect.offset.x = std::max((int32_t)(pcmd->ClipRect.x), 0);
scissorRect.offset.y = std::max((int32_t)(pcmd->ClipRect.y), 0);
scissorRect.extent.width = (uint32_t)(pcmd->ClipRect.z - pcmd->ClipRect.x);
scissorRect.extent.height = (uint32_t)(pcmd->ClipRect.w - pcmd->ClipRect.y);
vkCmdSetScissor(command_buffer, 0, 1, &scissorRect);
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, index_offset, vertex_offset, 0);
index_offset += pcmd->ElemCount;
}
vertex_offset += cmd_list->VtxBuffer.Size;
}
}
参考文献
1.Image Loading and Displaying Examples
2.How to render Vulkan’s scene to ImGui window