以《vulkan编程指南》为基础,学习vulkan编程,在20章,将顶点数据写入shader中,终于可以看到三角形了。此时,代码已写了近1000行,看起来有点头大。
根据之前学习OpenGL的经历,写十几行就可以看到三角形,对比起来,难易程度,不言而喻。
在这里不讨论OpenGL与vulkan的区别和优劣。只是想总结一下这段时间的学习成果。为何到了20章才开始总结,是想能绘制出三角形,形成一个完整的场景,然后再分析哪些是初始化时可完成的、哪些时是在渲染每帧的循环中完成的,好,正文开始。
从大方向的流程来说,
1、创建instance:
vulkan的程序启动时需要一个实例,即:VkInstance,通过实现例可以创建surface和device。所以vulkan程序的第一件事情就是创建实例。
2、创建surface:
通过窗口的HWND和实例VkInstance创建一个surface,陌生的概念,可以认为是需要绘制窗口。
3、创建逻辑设备device。
需要先检查可用的物理设备,创建出逻辑设备。后续的操作都是基于这个逻辑设备来进行的。
4、创建交换链swapchain:
相对天于OpenGL,是一个新概念,是一个连续帧缓冲区概念。OpenGL相对应的就是swapBuffer接口。同样,swapchain中至少有两个缓冲区,一个frameBuffer(screenBuffer),或叫frontBuffer,呈现到显卡输出的缓冲区。其余的都叫backBuffer。
5、创建RenderPass:
vulkan在渲染时,需要包含一个或多个子通道subPass,一般的例子使用一个就可以了,多通道一般是前向渲染或后处理等,多个subPass之前是有先后顺序的,前一个subPass的输出与后一个的SubPass的输入相关。
6、创建pipeline:
在pipeline中指定使用的shader,设定渲染的属性,比如:线定、绘制方式(面、线、点)、载剪面、背景色等等。
7、创建framebuffer:
根据swapchain中的缓冲区的数量,以及RenderPass创建相对应的frameBuffer。
8、创建commandPool:
根据队列在家族中的索引,创建出命令缓冲池。
9、创建commandBuffer:
从commandPool中申请一块内存,用于写命令。
10、创建同步对象SyncObject:
同步对象包含:VkSemaphore和VkFence。使用时可以使用一个或多个,或几种一起搭配使用。
在每一帧绘制时,先等待同步信号,在设备空闲时,重置信号,取下一个缓冲区的图像,将命令写入commandBuffer。
在beging与end之间调用draw,绘制三角形。
提交队列。
呈现。
完成绘制。
在窗口大小发生变化时,需要将与窗口大小相关的对象删除后重建。即将4至9创建的对象先进行删除,再创建。