[Vulkan教程]绘制一个三角形/图形管线基础/汇总(Conclusion)

现在,我们可以结合前几章中所有结构体和对象来创建图形管线。它们是:

  • 着色器阶段:定义图像管线可编程阶段的着色器模块
  • 固定功能状态:定义管线固定功能阶段的结构体,包括输入组装、光栅化、视口和颜色混合
  • 管线布局:着色器引用的可动态更新的uniformpush values
  • 渲染通道:管线阶段引用的附件和其用法

这些结合起来就可以完整定义图形管线的功能了,现在我们在createGraphicsPipeline函数末尾填充VkGraphicsPipelineCreateInfo结构体。记得要在vkDestroyShaderModule之前完成创建。

我们首先引用VkPipelineShaderStageCreateInfo结构体:

VkGraphicsPipelineCreateInfo pipelineInfo{};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineInfo.stageCount = 2;
pipelineInfo.pStages = shaderStages;

然后是固定功能状态:

pipelineInfo.pVertexInputState = &vertexInputInfo;
pipelineInfo.pInputAssemblyState = &inputAssembly;
pipelineInfo.pViewportState = &viewportState;
pipelineInfo.pRasterizationState = &rasterizer;
pipelineInfo.pMultisampleState = &multisampling;
pipelineInfo.pDepthStencilState = nullptr; // Optional
pipelineInfo.pColorBlendState = &colorBlending;
pipelineInfo.pDynamicState = nullptr; // Optional

然后是管线布局,注意这里是个句柄:

pipelineInfo.renderPass = renderPass;
pipelineInfo.subpass = 0;

最后,引用渲染通道和该图形管线要用的子通道的下标。该管线也可以使用其它渲染通道,但它们必须与renderPass兼容。兼容性描述在这里,我们不会在本教程中使用。

pipelineInfo.renderPass = renderPass;
pipelineInfo.subpass = 0;

还有两个参数basePipelineHandlebasePipelineIndex。Vulkan允许你从现有管线派生来创建新的图形管线。派生的目的是降低设置管线的成本,并且在拥有相同父亲的管线之间切换可以拥有更好的性能。我们可以通过basePipelineHandle指定现有管线,或通过basePipelineIndex引用一个即将通过索引创建的管线。我们现在只有一个管线,所以这里设置为null和无效索引。要使用这两个值还要在VkGraphicsPipelineCreateInfoflags上设置VK_PIPELINE_CREATE_DERIVATIVE_BIT

pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; // Optional
pipelineInfo.basePipelineIndex = -1; // Optional

接下来,创建一个成员变量来保存VkPipeline对象:

VkPipeline graphicsPipeline;

创建图形管线:

if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &graphicsPipeline) != VK_SUCCESS) {
    throw std::runtime_error("failed to create graphics pipeline!");
}

vkCreateGraphicsPipelines函数相比其它Vulkan的对象创建函数拥有更多的参数,其目的是为了同时创建多个管线对象。
其第二个参数可以传递一个VkPipelineCache对象,它可以让我们存储和重用管线创建相关的数据,甚至可以存储到文件以跨程序使用。它可以显著加快管线的创建。我们之后在管线缓存一章中在讨论它。

常见的绘图操作均需要图形管线,因此,它也应该在程序结束时销毁:

void cleanup() {
    vkDestroyPipeline(device, graphicsPipeline, nullptr);
    vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
    ...
}

现在,我们可以运行下程序,确保为了创建图形管线所做的这么多工作没有问题。我们已经非常接近能在屏幕上看到三角形了。接下来的几章,我们将从交换链图像创建真正的帧缓冲并准备绘制命令。

目录
上一节 绘制一个三角形/图形管线基础/渲染通道(Render passes)
下一节 绘制一个三角形/绘制/帧缓冲(Framebuffers)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值