Vulkan 绘制显示设计

背景

众所周知,Vulkan是个跨平台的图形渲染API,为了友好地支持跨平台,Vulkan自然也抽象出了很多接口层去对接各个操作系统,抹平系统间的差异,Swap Chains即为WSI。

其本质上是一种图像队列,此队列会按顺序依次将队列中的若干图形显示在屏幕上。我们的应用程序需要获得这个队列中的图像,并在此图像中执行绘制操作,绘制完毕以后,将它重新放置到原来的队列中,类似Android的Graphic Buffer Queue。

swap chain 的常规作用是保障图形显示与幕刷新率同步。

Swap Chain Support

Vulkan支持的平台众多,也不是所有的平台都具备将(渲染出来的)图像直接显示在屏幕上的功能,有些以计算为目的应用是不需要把绘制的结果呈现给用户。所以显示相关的API并不是Vulkan核心API的一部分,而是通过扩展(extensions)的方式提供。

因此在查询到当前运行环境对 swap chain 的支持情况之后,你需要明确启用 VK_KHR_swapchain 所代表的设备扩展功能。注意,Vulkan头文件中提供了宏定义 VK_KHR_SWAPCHAIN_EXTENSION_NAME ,它定义了 VK_KHR_swapchain(一种swap chain的实现)。使用这个宏定义的优势在于,编译或(编辑)过程中编译器可以直接检查出拼写错误(如果直接使用字符串 "VK_KHR_swapchain" 则无法让编译器去检查拼写错误)。

Enabling device extensions

启动一个swap chain对象首先要启用 VK_KHR_swapchain 扩展。需要在设备创建过程中开启:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要使用Vulkan绘制一个三角形,需要经过以下步骤: 1. 创建一个Vulkan实例 2. 创建一个逻辑设备 3. 创建一个窗口表面 4. 创建一个交换链 5. 创建渲染通道和帧缓冲区 6. 创建着色器模块 7. 创建管线布局和管线 8. 分配顶点缓冲区 9. 开始绘制 下面是一个简单的示例代码,用于绘制一个三角形: ``` // 顶点数据 std::vector<Vertex> vertices = { { { 0.0f, -0.5f },{ 1.0f, 0.0f, 0.0f } }, { { 0.5f, 0.5f },{ 0.0f, 1.0f, 0.0f } }, { { -0.5f, 0.5f },{ 0.0f, 0.0f, 1.0f } } }; // 创建顶点缓冲区 VkBuffer vertexBuffer; VkDeviceMemory vertexBufferMemory; createBuffer(sizeof(vertices[0]) * vertices.size(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexBuffer, vertexBufferMemory); // 在CPU上填充顶点缓冲区 void* data; vkMapMemory(device, vertexBufferMemory, 0, sizeof(vertices[0]) * vertices.size(), 0, &data); memcpy(data, vertices.data(), sizeof(vertices[0]) * vertices.size()); vkUnmapMemory(device, vertexBufferMemory); // 创建渲染通道和帧缓冲区 VkRenderPass renderPass; createRenderPass(renderPass); VkFramebuffer framebuffer; createFramebuffer(framebuffer); // 创建着色器模块 VkShaderModule vertShaderModule; VkShaderModule fragShaderModule; createShaderModule("vert.spv", vertShaderModule); createShaderModule("frag.spv", fragShaderModule); // 创建管线布局和管线 VkPipelineLayout pipelineLayout; VkPipeline pipeline; createPipelineLayout(pipelineLayout); createPipeline(pipeline, pipelineLayout, renderPass, vertShaderModule, fragShaderModule); // 开始绘制 VkCommandBuffer commandBuffer = beginSingleTimeCommands(); VkClearValue clearColor = { 0.0f, 0.0f, 0.0f, 1.0f }; VkRenderPassBeginInfo renderPassInfo = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO }; renderPassInfo.renderPass = renderPass; renderPassInfo.framebuffer = framebuffer; renderPassInfo.renderArea.offset = { 0, 0 }; renderPassInfo.renderArea.extent = swapChainExtent; renderPassInfo.clearValueCount = 1; renderPassInfo.pClearValues = &clearColor; vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); VkBuffer vertexBuffers[] = { vertexBuffer }; VkDeviceSize offsets[] = { 0 }; vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets); vkCmdDraw(commandBuffer, 3, 1, 0, 0); vkCmdEndRenderPass(commandBuffer); endSingleTimeCommands(commandBuffer); ``` 这段代码中,我们首先创建一个包含三个顶点的顶点缓冲区,然后使用着色器模块、管线布局和管线来定义如何渲染这些顶点。最后,我们通过调用`vkCmdDraw`函数来绘制三角形。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值