鸿蒙Harmony开发实战案例:使用OpenGL绘制3D图形

XComponent控件常用于相机预览流的显示和游戏画面的绘制,在OpenHarmony上,可以配合Native Window创建OpenGL开发环境,并最终将OpenGL绘制的图形显示到XComponent控件。本文将采用"Native C++"模板,调用OpenGL ES图形库绘制3D图形(三棱锥),并将结果渲染到页面的XComponent控件中进行展示。同时,还可以在屏幕上通过触摸滑动手势对三棱锥进行旋转,最终得到不同角度的图形并显示到页面。

效果展示

首页 滑动屏幕旋转变换

3d-graphic-index.png

3d-graphic-rotate.png

环境要求

  • 本示例仅支持在标准系统上运行。

  • 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)版本为例。

    3d-graphic-creat-project.png

    (2)开发环境配置完成后,创建工程(模板选择“Native C++”),选择eTS语言开发。

  • 应用调测工程创建完成后,选择使用真机进行调测。

    (1)将搭载OpenHarmony标准系统的开发板与电脑连接。

    (2)点击File> Project Structure... > Project>SigningConfigs界面勾选“Automatically generate signature”,等待自动签名完成即可,最后点击“OK”。如下图所示:

    3d-graphic-creat-signature.png

    (3)在编辑窗口右上角的工具栏,点击"运行"按钮运行。

    3d-graphic-run.png

2、源码结构

  • 代码结构分析,整个工程的代码结构如下:

    3d-graphic-creat-code-struct.png

  • 文件说明如下:

    .
    └── 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[] &
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值