Hello Vulkan(二)| 图形渲染新技术Vulkan Drawing


回顾 
上一期技术分享中,已经讲述了关于Vulkan的前世今生,以及和OpenGL相比的不同点也放出第一个Vulkan的sample工程以供大家学习使用。当然,如果在学习过程中有任何问题,可以随时留言给我们,也欢迎大家移步至我们刚上线的开发者社区中交流和分享。
这一期将会给大家带来关于Vulkan基础的图形绘制方面内容,如何使用Vulkan绘制一些基础图形,以及渲染流程又是什么样的?
 Vulkan图形拓扑 – 图元装配描述
图元装配描述,即对输入的顶点,到底构成什么图形,比如直线、三角形等,进行设置。介绍下Vulkan支持的主要图形拓扑:
VK_PRIMITIVE_TOPOLOGY_POINT_LIST: 点集VK_PRIMITIVE_TOPOLOGY_LINE_LIST: 线集VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: 连续线VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:三角形集合VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:连续三角形
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:呈扇形的三角形集合
 
Typedef enum VkPrimitiveTopology
{
VK_PRIMITIVE_TOPOLOGY_POINT_LIST
VK_PRIMITIVE_TOPOLOGY_LINE_LIST
VK_PRIMITIVE_TOPOLOGY_LINE_STRIP
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY
VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY
VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
} VkPrimitiveTopology;
观察下对于VkPrimitiveTopology的类型定义,不难看出,其实和OpenGL类似,出入并不是很大。
顶点描述模块
还记得上一期最后放出来的Vulkan渲染管线Pipeline吗?不记得的话,我们再看一遍。

在每条Pipeline,需要确定本条管线接收怎样的模型顶点数据。我们以绘制一个正方体为例:
 
首先我们对正方体顶点进行从0-7编号,参考如下代码: 
struct vertex{ glm::vec3 position; glm::vec3 normal; glm::vec3 color; glm::vec2 texCoord;};#endifstruct vertex VertexData[ ] ={ // triangle 0-2-3: // vertex #0: { { -1., -1., -1. }, { 0., 0., -1. }, { 0., 0., 0. }, { 1., 0. } }, // vertex #2: { { -1., 1., -1. }, { 0., 0., -1. }, { 0., 1., 0. }, { 1., 1. } }, // vertex #3: { { 1., 1., -1. }, { 0., 0., -1. }, { 1., 1., 0. }, { 0., 1. } }, … };
我们剖析下Sample里这段代码,对于vertex #0,第一行的{ -1., -1., -1. },是v0的position,也就是x坐标是-1,y坐标是-1,z坐标是-1。第二行的{  0.,  0., -1. },是表面normal向量,表明了指向正方体的背面。第三行的{  0.,  0.,  0. },是颜色,表示颜色是黑色的。最后一行的{  1., 0. },代表的则是纹理坐标,即S-T坐标,S等于1,T等于0。依次可以类推vertex #2和vertex#3,并且v0、v2、v3一起组成了三角形0-2-3,也就是组成正方体6个面的12个三角形之一,只需要告诉系统运用三角形的图型拓扑即可。这些数据会以流的形式按顺序进行排列,并告诉着色器shader,那么如何让shader也能知道我们在这里定义的vertex结构体里position、normal、color、texCoord的顺序的呢?这个后续会讲述,这里我们只需要知道顶点流的一个流程即可。 
 
GPU装载
因为调用的是三角形的图元拓扑,所以Vulkan每次抓取单位是3。这就是绘制的过程,这些结构体数组的数据流会被送入Vulkan,如果我们把它们都装入CPU内存,
就会造成极大的浪费,所以我们装入GPU内存,那我们如何实现呢?
参考下面的方法:
InitMyVertexDataBuffer( sizeof(VertexData), OUT &MyVertexDataBuffer ); //createFillDataBuffer( MyVertexDataBuffer, (void *) VertexData ); //fillVkResultInitMyVertexDataBuffer( IN VkDeviceSize size, OUT MyBuffer * pMyBuffer ) { VkResult result;result = InitDataBuffer( size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, pMyBuffer ); return result; } VkResultInitDataBuffer( VkDeviceSize size, VkBufferUsageFlags usage, OUT MyBuffer * pMyBuffer ) { VkResult result = VK_SUCCESS; VkBufferCreateInfo vbci; vbci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; vbci.pNext = nullptr;vbci.flags = 0;vbci.size = pMyBuffer->size = size; vbci.usage = usage;vbci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; vbci.queueFamilyIndexCount = 0; vbci.pQueueFamilyIndices = (const uint32_t *)nullptr;result = vkCreateBuffer ( LogicalDevice, IN &vbci, PALLOCATOR, OUT &pMyBuffer->buffer ); VkMemoryRequirements vmr;vkGetBufferMemoryRequirements( LogicalDevice, IN pMyBuffer->buffer, OUT &vmr ); VkMemoryAllocateInfo vmai;vmai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; vmai.pNext = nullptr;vmai.allocationSize = vmr.size;vmai.memoryTypeIndex = FindMemoryThatIsHostVisible( ); VkDeviceMemory vdm;result = vkAllocateMemory( LogicalDevice, IN &vmai, PALLOCATOR, OUT &vdm ); pMyBuffer->vdm = vdm; result = vkBindBufferMemory( LogicalDevice, pMyBuffer->buffer, IN vdm, 0 ); return result; }
绘制
以上这个过程就是创建databuffer的过程。这里我们要确保我们在shader中数据格式完全匹配我们在CPU里期初定义的:
 
调用下面代码进行顶点绑定,以及告诉Command Buffer绘制哪些顶点进行绘制:
VkBuffer buffers[1] = { MyVertexDataBuffer.buffer };VkDeviceSize offsets[1] = { 0 };vkCmdBindVertexBuffers( CommandBuffers[nextImageIndex], 0, 1, buffers, offsets ); vkCmdDrawIndexed( commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
到这儿我们就绘制出一个带有不同颜色顶点的立方体:
 
加上纹理映射后的效果:
 
其实这一期关于Vulkan绘制的内容,大多是对之前放出的Sample工程的详细讲解,从顶点定义,到创建GPU内存,到绘制等步骤,这些确实是非常枯燥,但是对于想学习Vulkan后续教程是必不可缺的一部分。
欢迎大家关注虹图AI开放平台公众号,后台留言交流,也欢迎大家移步至我们刚上线的开发者社区中交流和分享。
关于Vulkan以及shader相关的实践内容,我们会在本系列后续内容中继续与大家分享。(虹图人像人体中美颜SDK部分是基于Vulkan进行开发封装的,性能极致,对开发者更加友好,十行之内完成一个简单的demo,点击【阅读原文】可查看详情。)
 敬请期待~
到顶部