• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Vulkan开发指导
2
3<!--Kit: ArkGraphics 2D-->
4<!--Subsystem: Graphic-->
5<!--Owner: @andrew1993-->
6<!--Designer: @ext4FAT1-->
7<!--Tester: @nobuggers-->
8<!--Adviser: @ge-yafang-->
9
10## 场景介绍
11
12Vulkan是一套用来做2D和3D渲染的图形应用程序接口,其中创建VkSurfaceKHR对象是一个非常关键的步骤,在OpenHarmony中,VkSurfaceKHR会对接到OHNativeWindow模块功能,实现Buffer轮转。
13
14在OpenHarmony中,需要通过OHNativeWindow来创建VkSurfaceKHR对象,而OHNativeWindow需要从XComponent中获取,所以此场景下需要配合XComponent模块和NativeWindow模块一起使用。
15
16## 接口说明
17
18| 接口名                                                       | 描述                   |
19| ------------------------------------------------------------ | ---------------------- |
20| vkCreateSurfaceOHOS (VkInstance instance, const VkSurfaceCreateInfoOHOS\* pCreateInfo, const VkAllocationCallbacks\* pAllocator, VkSurfaceKHR\* pSurface) | 创建VkSurfaceKHR对象。 |
21
22更多的接口说明请参考[Vulkan](vulkan.md)。
23
24## 开发步骤
25
26以下步骤说明了如何创建一个VkSurfaceKHR对象。
27
28首先,使用平台扩展的接口,需要定义一个宏`VK_USE_PLATFORM_OHOS`,我们在CMakeLists.txt定义这个宏。
29
30```txt
31ADD_DEFINITIONS(-DVK_USE_PLATFORM_OHOS=1)
32```
33
34**添加动态链接库**
35
36CMakeLists.txt中添加以下lib。
37
38```txt
39libace_ndk.z.so
40libnative_window.so
41libvulkan.so
42```
43
44> **说明:**
45>
46> 在程序中通过dlopen函数链接libvulkan.so动态库时不需要在CMake中增加依赖,否则会导致符号冲突。
47
48**头文件**
49
50```c++
51#include <ace/xcomponent/native_interface_xcomponent.h>
52#include <native_window/external_window.h>
53#include <vulkan/vulkan.h>
54```
55
561. **首先需要创建一个Vulkan实例**。
57
58   ```c++
59   VkInstance instance = VK_NULL_HANDLE;
60
61   VkApplicationInfo appInfo = {};
62   appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
63   appInfo.pApplicationName = "vulkanExample";
64   appInfo.pEngineName = "vulkanExample";
65   appInfo.apiVersion = VK_API_VERSION_1_3;
66
67   VkInstanceCreateInfo instanceCreateInfo = {};
68   instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
69   instanceCreateInfo.pNext = NULL;
70   instanceCreateInfo.pApplicationInfo = &appInfo;
71
72   std::vector<const char *> instanceExtensions = {
73       VK_KHR_SURFACE_EXTENSION_NAME,
74       VK_OHOS_SURFACE_EXTENSION_NAME // Surface扩展
75   };
76   instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(instanceExtensions.size());
77   instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data();
78
79   vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
80   ```
81
822. **获取OHNativeWindow**。
83
84   OHNativeWindow需要从XComponent组件中获取,下面提供一份从XComponent组件中获取OHNativeWindow的代码示例,XComponent模块的具体使用方法请参考[XComponent模块的介绍文档](../../ui/napi-xcomponent-guidelines.md)。
85
86   1. ets/pages/Index.ets中增加一个XComponent组件。
87
88      ```ts
89      XComponent({
90          id: 'xcomponentId',
91          type: 'surface',
92          libraryname: 'entry'
93      })
94      .margin({ bottom: 20 })
95      .width(360)
96      .height(360)
97      ```
98
99   2. 从XComponent组件中获取OHNativeWindow。
100
101      ```c++
102      // XComponent在创建Suface时的回调函数
103      void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
104          // 在回调函数里可以拿到OHNativeWindow
105          OHNativeWindow *nativeWindow = static_cast<OHNativeWindow *>(window);
106      }
107
108      static napi_value Init(napi_env env, napi_value exports) {
109          napi_property_descriptor desc[] = {{"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr}};
110          napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
111
112          napi_value exportInstance = nullptr;
113          OH_NativeXComponent *nativeXComponent = nullptr;
114          // 获取nativeXComponent
115          napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
116          napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent));
117          // 获取XComponentId
118          char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
119          uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
120          OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize);
121
122          // 声明一个XComponent的Callback
123          OH_NativeXComponent_Callback callback;
124          // 注册OnSurfaceCreated回调函数
125          callback.OnSurfaceCreated = OnSurfaceCreatedCB;
126          // 将callback注册给nativeXComponent
127          OH_NativeXComponent_RegisterCallback(nativeXComponent, &callback);
128
129          return exports;
130      }
131      ```
132
1333. **创建VkSurfaceKHR对象**。
134
135   ```c++
136   VkSurfaceKHR surface = VK_NULL_HANDLE;
137   VkSurfaceCreateInfoOHOS surfaceCreateInfo = {};
138   surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_SURFACE_CREATE_INFO_OHOS;
139   surfaceCreateInfo.window = nativeWindow; // 这里的nativeWindow就是从上一步骤OnSurfaceCreatedCB回调函数中拿到的
140   int err = vkCreateSurfaceOHOS(instance, &surfaceCreateInfo, NULL, &surface);
141   if (err != VK_SUCCESS) {
142       // Create Surface Failed.
143   }
144   ```
145
146## 相关实例
147
148针对Vulkan的使用,具体可见以下相关实例:
149
150- [XComponent组件对接Vulkan(API11)](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkVulkan)
151
152后续更多vulkan的用法请参考[Vulkan官方网站](https://www.vulkan.org/)