vulkan-guidelines.md 4.7 KB
Newer Older
S
shegangbin 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# Vulkan开发指导

## 场景介绍

Vulkan是一套用来做2D和3D渲染的图形应用程序接口,其中创建VkSurfaceKHR对象是一个非常关键的步骤,在OpenHarmony中,VkSurfaceKHR会对接到OHNativeWindow模块功能,实现Buffer轮转。

在OpenHarmony中,需要通过OHNativeWindow来创建VkSurfaceKHR对象,而OHNativeWindow需要从XComponent中获取,所以此场景下需要配合XComponent模块和NativeWindow模块一起使用。

## 接口说明

| 接口名 | 描述 | 
| -------- | -------- |
| vkCreateSurfaceOHOS (VkInstance instance, const VkSurfaceCreateInfoOHOS\* pCreateInfo, const VkAllocationCallbacks\* pAllocator, VkSurfaceKHR\* pSurface) | 创建VkSurfaceKHR对象。 | 

更多的接口说明请参考[Vulkan](../reference/native-lib/third_party_vulkan/vulkan-symbol.md)

## 开发步骤

以下步骤说明了如何在OpenHarmony平台创建一个VkSurfaceKHR对象。

S
shegangbin 已提交
21 22 23 24 25 26 27 28 29
**添加动态链接库**

CMakeLists.txt中添加以下lib。
```txt
libace_ndk.z.so
libnative_window.so
libvulkan.so
```

S
shegangbin 已提交
30 31 32 33 34 35 36 37 38 39 40
**头文件**
```c++
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <native_window/external_window.h>
#include <vulkan/vulkan.h>
```

1. **首先需要创建一个Vulkan实例**
    ```c++
    VkInstance instance = VK_NULL_HANDLE;

S
shegangbin 已提交
41 42 43 44 45
    VkApplicationInfo appInfo = {};
    appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    appInfo.pApplicationName = "vulkanExample";
    appInfo.pEngineName = "vulkanExample";
    appInfo.apiVersion = VK_API_VERSION_1_3;
S
shegangbin 已提交
46
    
S
shegangbin 已提交
47 48 49 50
    VkInstanceCreateInfo instanceCreateInfo = {};
    instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instanceCreateInfo.pNext = NULL;
    instanceCreateInfo.pApplicationInfo = &appInfo;
S
shegangbin 已提交
51

S
shegangbin 已提交
52
    std::vector<const char*> instanceExtensions = {
S
shegangbin 已提交
53
        VK_KHR_SURFACE_EXTENSION_NAME,
S
shegangbin 已提交
54
        VK_OHOS_SURFACE_EXTENSION_NAME // OpenHarmony平台的Surface扩展
S
shegangbin 已提交
55
    };
S
shegangbin 已提交
56
    instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(instanceExtensions.size());
S
shegangbin 已提交
57 58 59 60 61 62
    instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data();

    vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
    ```

2. **获取OHNativeWindow**
S
shegangbin 已提交
63
    OHNativeWindow需要从XComponent组件中获取,下面提供一份从XComponent组件中获取OHNativeWindow的代码示例,XComponent模块的具体使用方法请参考[XComponent模块的介绍文档](../ui/arkts-common-components-xcomponent.md)[XComponent开发指导](xcomponent-guidelines.md)
S
shegangbin 已提交
64 65 66 67 68 69 70
    1. ets/pages/Index.ets中增加一个XComponent组件
    ```ts
    XComponent({
        id: 'xcomponentId',
        type: 'surface',
        libraryname: 'entry'
    })
S
shegangbin 已提交
71 72 73
    .margin({ bottom: 20 })
    .width(360)
    .height(360)
S
shegangbin 已提交
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
    ```
    2. 从XComponent组件中获取OHNativeWindow
    ```c++
    // XComponent在创建Suface时的回调函数
    void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
        // 在回调函数里可以拿到OHNativeWindow
        OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
    }

    EXTERN_C_START
    static napi_value Init(napi_env env, napi_value exports)
    {
        napi_property_descriptor desc[] = {
            { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }
        };
        napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);

        // 声明一个XComponent的Callback
        OH_NativeXComponent_Callback callback;
        // 注册OnSurfaceCreated回调函数
        callback.OnSurfaceCreated = OnSurfaceCreatedCB;
        
        char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
        uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
        napi_value exportInstance = nullptr;
        OH_NativeXComponent *nativeXComponent = nullptr;
        // 获取nativeXComponent
        napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
        napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent));
        // 将callback注册给nativeXComponent
        OH_NativeXComponent_RegisterCallback(nativeXComponent, &callback);
        
        return exports;
    }
    ```

3. **创建VkSurfaceKHR对象**
    ```c++
S
shegangbin 已提交
112 113 114 115 116 117 118 119
    VkSurfaceKHR surface = VK_NULL_HANDLE;
    VkSurfaceCreateInfoOHOS surfaceCreateInfo = {};
    surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_SURFACE_CREATE_INFO_OHOS;
    surfaceCreateInfo.window = nativeWindow; // 这里的nativeWindow就是从上一步骤OnSurfaceCreatedCB回调函数中拿到的
    int err = vkCreateSurfaceOHOS(instance, &surfaceCreateInfo, NULL, &surface);
    if (err != VK_SUCCESS) {
        std::cout << "Could not create surface!" << std::endl;
    }
S
shegangbin 已提交
120 121
    ```
后续更多vulkan的用法请参考[Vulkan官方网站](https://www.vulkan.org/)