Vulkan 开发(十):Vulkan 窗口表面(Surface)

图片

 

Vulkan 系列文章:

1. 开篇,Vulkan 概述

2. Vulkan 实例

3. Vulkan 物理设备

4. Vulkan 设备队列

5. Vulkan 逻辑设备

6. Vulkan 内存管理

7. Vulkan 缓存

8. Vulkan 图像

9. Vulkan 图像视图


窗口表面

Vulkan 是一个平台无关的图形 API ,这意味着它不能直接与特定的窗口系统(如 Windows、Linux 或 macOS 的窗口系统)交互。

为了解决这个问题,Vulkan 引入了窗口系统集成(Window System Integration,WSI)机制,使得 Vulkan 应用程序可以与不同操作系统的窗口系统(如 Windows 的 Win32、Linux 的 X11 或 Wayland、Android 的 ANativeWindow 等)进行交互。

这些机制允许 Vulkan 应用程序在窗口系统中创建和管理表面(Surface),并与图形硬件交换图像(Swapchain)

VK_KHR_surface是 WSI 的核心扩展(instance 扩展),是 Vulkan 中用于表示渲染表面的对象,它是一个平台无关的抽象类型,用于封装与窗口系统相关的表面信息,通过这个对象,Vulkan 可以将渲染结果输出到窗口上。

创建窗口表面

VkSurfaceKHR对象是平台无关的,但是创建 VkSurfaceKHR对象时,不同的操作系统(窗口系统)需要使用不同的 API 。

图片

 

如 Android 系统使用 vkCreateAndroidSurfaceKHR, Windows 系统使用 vkCreateWin32SurfaceKHR 。

另外,在创建 Vulkan 实例的时候需要提前设置好相应的扩展:

1std::vector<const char*> instance_extensions;
2instance_extensions.push_back("VK_KHR_surface");
3instance_extensions.push_back("VK_KHR_android_surface");//Android
4//如果是 WIndow 平台使用 VK_KHR_win32_surface

本文主要涉及 Vulkan 移动开发在 Android 端的应用(其他平台流程相似),Android 系统创建窗口表面 VkSurfaceKHR流程:

  1. 确定支持VK_KHR_android_surface扩展:检查物理设备是否支持该扩展。

  2. 定义ANativeWindow:获取Android的ANativeWindow对象,这是Vulkan在Android上创建表面的必要条件。

  3. 创建VkSurfaceKHR:使用vkCreateAndroidSurfaceKHR函数创建Vulkan表面。

在Android平台上创建Vulkan窗口表面的代码示例:

 1#include <vulkan/vulkan.h>
 2#include <vulkan/vulkan_android.h>
 3#include <android/native_window.h>
 4#include <android/native_window_jni.h>
 5
 6// 需要在 Android 应用程序的某处获取到 ANativeWindow 对象,通常在 Activity 或 SurfaceView 中
 7extern ANativeWindow* window; // 这个 window 对象应该是从 Java 层传递过来的
 8
 9// 检查物理设备是否支持 VK_KHR_android_surface 扩展
10bool isExtensionSupported(const char* extensionName, const std::vector<VkExtensionProperties>& availableExtensions) {
11    for (const auto& extension : availableExtensions) {
12        if (strcmp(extension.extensionName, extensionName) == 0) {
13            return true;
14        }
15    }
16    return false;
17}
18
19// 获取物理设备支持的扩展
20uint32_t extensionCount = 0;
21vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &extensionCount, nullptr);
22std::vector<VkExtensionProperties> availableExtensions(extensionCount);
23vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &extensionCount, availableExtensions.data());
24
25if (!isExtensionSupported(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, availableExtensions)) {
26    throw std::runtime_error("VK_KHR_android_surface extension not supported");
27}
28
29// 创建 VkAndroidSurfaceCreateInfoKHR 结构体并初始化
30VkAndroidSurfaceCreateInfoKHR createInfo = {};
31createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
32createInfo.pNext = nullptr;
33createInfo.flags = 0;
34createInfo.window = window; // 指向 ANativeWindow 对象的指针
35
36VkSurfaceKHR surface;
37VkResult result = vkCreateAndroidSurfaceKHR(instance, &createInfo, nullptr, &surface);
38
39if (result != VK_SUCCESS) {
40    throw std::runtime_error("failed to create Vulkan surface");
41}
42
43// 现在 surface 对象可以在 Vulkan 渲染管线中使用

其中,在Android应用程序中添加ANativeWindow对象,你需要获取ANativeWindow对象,通常是在 Activity 或 SurfaceView 中通过 JNI 从 Java 层传递过来。例如:

1// 在 Java 代码中
2public native void setNativeWindow(Surface surface);
3
4// 在 C++ 代码中
5extern "C" JNIEXPORT void JNICALL Java_com_example_app_NativeLib_setNativeWindow(JNIEnv* env, jobject obj, jobject surface) {
6    ANativeWindow* window = ANativeWindow_fromSurface(env, surface);
7    // 将 window 存储在一个全局变量中,以便稍后使用
8}
技术交流

进技术交流群/获取源码,添加我的微信:Byte-Flow

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

字节流动

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值