显式处理窗口大小改变
尽管许多驱动程序会在窗口大小改变后触发VK_ERROR_OUT_OF_DATE_KHR信息,但这种触发并不可靠,所以我们最好添加一些代码来显式地在窗口大小改变时重建交换链。我们添加一个新的变量来标记窗口大小是否发生改变:
std::vector<VkFence> inFlightFences;
size_t currentFrame = 0;
bool framebufferResized = false;
修改drawFrame函数,检测我们加入的标记:
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR ||
framebufferResized) {
framebufferResized = false;
recreateSwapChain();
} else if (result != VK_SUCCESS) {
...
}
使用glfwSetFramebufferSizeCallback函数设置处理窗口大小改变的回调函数:
void initWindow() {
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
glfwSetFramebufferSizeCallback(window, framebufferResizeCallback);
}
static void framebufferResizeCallback(GLFWwindow* window, int width, int height) {
}
需要注意代码中,我们定义framebufferResizeCallback为静态函数,这样才能将其用作回调函数。 framebufferResizeCallback回调函数有一个GLFWwindow类型的参数,我们可以使用这一参数来引用GLFW窗口。GLFW允许我们将任意的指针使用glfwSetWindowUserPointer函数存储在GLFW窗口相关的数据中:
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
glfwSetWindowUserPointer(window, this);
glfwSetFramebufferSizeCallback(window, framebufferResizeCallback);
我们可以通过glfwGetWindowUserPointer函数获取使用glfwSetWindowUserPointer函数存储的指针,在这里我们使用它们来存储应用程序类的this指针:
static void framebufferResizeCallback(GLFWwindow* window, int width, int height) {
auto app = reinterpret_cast<HelloTriangleApplication*>(glfwGetWindowUserPointer(window));
app->framebufferResized = true;
}
现在编译运行程序,改变应用程序窗口大小,观察帧缓冲是否随着窗口大小改变而被正确地重新设置。