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