XComponent控件常用于相机预览流的显示和游戏画面的绘制,在OpenHarmony上,可以配合Native Window创建OpenGL开发环境,并最终将OpenGL绘制的图形显示到XComponent控件。本文将采用"Native C++"模板,调用OpenGL ES图形库绘制3D图形(三棱锥),并将结果渲染到页面的XComponent控件中进行展示。同时,还可以在屏幕上通过触摸滑动手势对三棱锥进行旋转,最终得到不同角度的图形并显示到页面。
效果展示
首页 | 滑动屏幕旋转变换 |
---|---|
|
|
环境要求
-
本示例仅支持在标准系统上运行。
-
IDE:DevEco Studio 3.1 Beta2
-
SDK:Ohos_sdk_public 3.2.11.9 (API Version 9 Release)
点击领取→纯血鸿蒙Next全套最新学习资料 希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!
开发步骤
1、环境搭建
我们首先要完成应用开发环境的搭建,本示例运行DAYU200开发板上。
-
搭建应用开发环境
说明:
为确保运行效果,本案例以使用DevEco Studio 3.1 Beta2 SDK:API9 (3.2.11.9)版本为例。
(2)开发环境配置完成后,创建工程(模板选择“Native C++”),选择eTS语言开发。
-
应用调测工程创建完成后,选择使用真机进行调测。
(1)将搭载OpenHarmony标准系统的开发板与电脑连接。
(2)点击File> Project Structure... > Project>SigningConfigs界面勾选“Automatically generate signature”,等待自动签名完成即可,最后点击“OK”。如下图所示:
(3)在编辑窗口右上角的工具栏,点击"运行"按钮运行。
2、源码结构
-
代码结构分析,整个工程的代码结构如下:
-
文件说明如下:
. └── main ├── cpp │ ├── app_napi.cpp //C++与ArkTS中XComponent控件交互的napi接口实现 │ ├── CMakeLists.txt //CMake规则配置文件,NAPI C/C++代码编译需要配置该文件 │ ├── include │ │ ├── app_napi.h │ │ ├── tetrahedron.h //三棱锥类实现头文件 │ │ └── util │ ├── module.cpp //NAPI模块注册 │ ├── napi_manager.cpp │ ├── napi_util.cpp │ ├── tetrahedron.cpp //三棱锥的绘制OpenGL实现 │ └── type │ └── libentry ├── ets │ ├── entryability │ │ └── EntryAbility.ts │ └── pages │ └── Index.ets //主页面 ├── module.json5 └── resources //资源文件目录 ├── base │ ├── element │ ├── media │ └── profile ├── en_US │ └── element ├── rawfile └── zh_CN └── element
3、绘制流程
- 3D绘制函数调用流程如下:
- 在Tetrahedron类的Update方法中使用GLES3库着色器绘制,最终通过ArkUI的XComponent组件显示,流程如下:
4、C++(OpenGL)实现
C++端方法源码是工程的entry/src/main/cpp/tetrahedron.cpp文件。
-
注册模块先定义一个模块,在entry/src/main/cpp/module.cpp文件中,对应结构体类型为napi_module,模块定义好后,调用NAPI提供的模块注册函数napi_module_register(napi_module* mod)注册到系统中;
/* * Napi Module define */ static napi_module appNapiModule = { .nm_version = 1, .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = Init, .nm_modname = "tetrahedron_napi", .nm_priv = ((void*)0), .reserved = { 0 }, }; /* * Module register function */ extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&appNapiModule); }
-
调用OpenGL相关图形API绘制三棱锥
(1)初始化
int32_t Tetrahedron::Init(void *window, int32_t width, int32_t height) { window_ = window; width_ = width; height_ = height; LOGI("Init window = %{public}p, w = %{public}d, h = %{public}d.", window, width, height); mEglWindow = reinterpret_cast<EGLNativeWindowType>(window); // 1. create sharedcontext mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (mEGLDisplay == EGL_NO_DISPLAY) { LOGE("unable to get EGL display."); return -1; } EGLint eglMajVers, eglMinVers; if (!eglInitialize(mEGLDisplay, &eglMajVers, &eglMinVers)) { mEGLDisplay = EGL_NO_DISPLAY; LOGE("unable to initialize display"); return -1; } int version = 3; mEGLConfig = getConfig(version, mEGLDisplay); if (mEGLConfig == nullptr) { LOGE("GLContextInit config ERROR"); return -1; } // 2. Create EGL Surface from Native Window EGLint winAttribs[] = {EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR, EGL_NONE}; if (mEglWindow) { mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mEglWindow, winAttribs); if (mEGLSurface == nullptr) { LOGE("eglCreateContext eglSurface is null"); return -1; } } // 3. Create EGLContext from int attrib3_list[] &