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