鸿蒙5.0&next开发【Vulkan开发】Vulkan

场景介绍

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

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

接口说明

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

开发步骤

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

首先,使用平台扩展的接口,需要定义一个宏VK_USE_PLATFORM_OHOS,我们在CMakeLists.txt定义这个宏。

ADD_DEFINITIONS(-DVK_USE_PLATFORM_OHOS=1)

添加动态链接库

CMakeLists.txt中添加以下lib。

libace_ndk.z.so
libnative_window.so
libvulkan.so

说明

在程序中通过dlopen函数链接libvulkan.so动态库时不需要在CMake中增加依赖,否则会导致符号冲突。

头文件

#include <ace/xcomponent/native_interface_xcomponent.h>
#include <native_window/external_window.h>
#include <vulkan/vulkan.h>
  1. 首先需要创建一个Vulkan实例
VkInstance instance = VK_NULL_HANDLE;

VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "vulkanExample";
appInfo.pEngineName = "vulkanExample";
appInfo.apiVersion = VK_API_VERSION_1_3;

VkInstanceCreateInfo instanceCreateInfo = {};
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.pNext = NULL;
instanceCreateInfo.pApplicationInfo = &appInfo;

std::vector<const char *> instanceExtensions = {
    VK_KHR_SURFACE_EXTENSION_NAME,
    VK_OHOS_SURFACE_EXTENSION_NAME // Surface扩展
};
instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(instanceExtensions.size());
instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data();

vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
  1. 获取OHNativeWindow

    OHNativeWindow需要从XComponent组件中获取,下面提供一份从XComponent组件中获取OHNativeWindow的代码示例

  2. ets/pages/Index.ets中增加一个XComponent组件。

XComponent({
    id: 'xcomponentId',
    type: 'surface',
    libraryname: 'entry'
})
.margin({ bottom: 20 })
.width(360)
.height(360)
  1. 从XComponent组件中获取OHNativeWindow。
// XComponent在创建Suface时的回调函数
void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
    // 在回调函数里可以拿到OHNativeWindow
    OHNativeWindow *nativeWindow = static_cast<OHNativeWindow *>(window);
}

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);

    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));
    // 获取XComponentId
    char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
    uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
    OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize);

    // 声明一个XComponent的Callback
    OH_NativeXComponent_Callback callback;
    // 注册OnSurfaceCreated回调函数
    callback.OnSurfaceCreated = OnSurfaceCreatedCB;
    // 将callback注册给nativeXComponent
    OH_NativeXComponent_RegisterCallback(nativeXComponent, &callback);

    return exports;
}
  1. 创建VkSurfaceKHR对象
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) {
    // Create Surface Failed.
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值