Vulkan API — урок 27. Фреймбуферы (+листинг)

Мы много раз говорили о фрейбуферах ранее и настраивали render pass с расчетом на один фреймбуфер с тем же форматом, что и изображения в swap chain, но ведь фактически мы его еще не создали.

Вложения, определенные во время создания render pass, теперь занесем в VkFramebuffer. Фреймбуферы ссылаются на все объекты VkImageView, которые представляют собой вложения. В нашем случае это будет лишь color attachment. Однако, изображение, которое мы хотим использовать в качестве вложения для представления, зависит от того, какое изображение вернет swap chain, на наш запрос. Это значит, что необходимо создать фреймбуфер для всех изображений в swap chain и использовать тот, который соответствует нужному изображению.

С этой целью создадим еще один std::vector для хранения фреймбуферов:

std::vector<VDeleter<VkFramebuffer>> swapChainFramebuffers;

Затем создаем объекты для данного массива в новой функции createFramebuffers, вызываемой из initVulkan сразу после создания конвейера:

void initVulkan() {
    createInstance();
    setupDebugCallback();
    createSurface();
    pickPhysicalDevice();
    createLogicalDevice();
    createSwapChain();
    createImageViews();
    createRenderPass();
    createGraphicsPipeline();
    createFramebuffers();
}

...

void createFramebuffers() {

}

Начнем с изменения размера контейнера, что бы он вмещал все фреймбуферы:

void createFramebuffers() {
    swapChainFramebuffers.resize(swapChainImageViews.size(), VDeleter<VkFramebuffer>{device, vkDestroyFramebuffer});
}

Далее пройдемся по image views и создадим из них фреймбуферы:

for (size_t i = 0; i < swapChainImageViews.size(); i++) {
    VkImageView attachments[] = {
        swapChainImageViews[i]
    };

    VkFramebufferCreateInfo framebufferInfo = {};
    framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
    framebufferInfo.renderPass = renderPass;
    framebufferInfo.attachmentCount = 1;
    framebufferInfo.pAttachments = attachments;
    framebufferInfo.width = swapChainExtent.width;
    framebufferInfo.height = swapChainExtent.height;
    framebufferInfo.layers = 1;

    if (vkCreateFramebuffer(device, &framebufferInfo, nullptr, swapChainFramebuffers[i].replace()) != VK_SUCCESS) {
        throw std::runtime_error("failed to create framebuffer!");
    }
}

Как думаю уже понятно – создание фреймбуферов достаточно прямолинейно. Сначала указываем с каким renderPass фреймбуфер должен быть совместим. Вы можете использовать фреймбуфер только с render pass, что примерно означает, что они используют одинаковое количество и типы вложений.

Параметры attachmentCount и pAttachments определяют VkImageView объекты, которые должны быть связаны с соответствующим описанием вложений в  render pass массива pAttachments.

Теперь у нас есть все необходимые объекты для рендеринга, осталось рассказать только о командах отрисовки.

Листинг.

Main Admin

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *