鸿蒙OpenHarmony【OpenGL ES】标准库ArkTS API

OpenGL 是一种跨平台的图形 API,用于为 3D 图形处理硬件指定标准的软件接口。[OpenGL ES]是 OpenGL 规范的一种形式,适用于嵌入式设备。HarmonyOS 现已支持 OpenGL ES 3.2。

支持的能力

OpenGL ES 3.2

标准库中导出的符号列表

[native api中导出的OpenGL ES 3.2符号列表]

引入OpenGL能力

如果开发者需要使用OpenGL的相关能力,需要添加相关动态链接库和头文件。

添加动态链接库

CMakeLists.txt中添加以下lib。

libace_ndk.z.so
libace_napi.z.so
libGLESv3.so
libEGL.so

头文件

#include <ace/xcomponent/native_interface_xcomponent.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglplatform.h>
#include <GLES3/gl3.h>

OpenGL ES扩展接口

  • OpenGL ES扩展接口的官方参考文档:[OpenGL ES扩展接口]
  • 开发者可以调用glGetString查询芯片厂商支持的扩展接口,调用之前务必初始化上下文,具体示例如下:
EGLDisplay display;
EGLConfig config;
EGLContext context;
EGLSurface surface;
EGLint majorVersion;
EGLint minorVersion;
EGLNativeWindowType win;
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, &majorVersion, &minorVersion);
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, &majorVersion, &minorVersion);
EGLint attribs[] = {
    EGL_RENDERABLE_TYPE,
    EGL_OPENGL_ES2_BIT,
    EGL_BLUE_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_RED_SIZE, 8,
    EGL_NONE
};
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
context = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);
surface = eglCreatePbufferSurface(display, config, NULL);
eglMakeCurrent(display, surface, surface, context);

char *strTest = new char[1024];
strTest = (char *)glGetString(GL_EXTENSIONS); // 返回值strTest中会列出所有的扩展接口,并且用空格分隔开
bool isHave = strTest.find("GL_OES_matrix_palette") != -1 ?
    true :
    false; // 查询是否有某个扩展接口,有则isHave为true,没有则为false

简单示例

#include <EGL/egl.h>
#include <GLES3/gl3.h>
#include <iostream>

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600

int main() {
    // 初始化 EGL
    EGLDisplay display;
    EGLConfig config;
    EGLContext context;
    EGLSurface surface;
    EGLint numConfigs;
    EGLint majorVersion;
    EGLint minorVersion;

    // 初始化 EGL Display
    display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    eglInitialize(display, &majorVersion, &minorVersion);

    // 配置 EGL
    EGLint attribs[] = {
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
        EGL_BLUE_SIZE, 6,
        EGL_GREEN_SIZE, 8,
        EGL_RED_SIZE, 8,
        EGL_NONE
    };
    eglChooseConfig(display, attribs, &config, 1, &numConfigs);

    // 创建 EGL Context
    EGLint contextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 3,
        EGL_NONE
    };

    // 创建 EGL Surface
    surface = eglCreateWindowSurface(display, config, nativeWindow, NULL);

    context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);

    // 绑定 EGL Context 和 Surface
    eglMakeCurrent(display, surface, surface, context);

    // 设置视口大小
    glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

    // 清除颜色缓冲
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // 定义顶点数据
    GLfloat vertices[] = {
        -0.5f, -0.5f, 0.0f,  // 左下角
         0.5f, -0.5f, 0.0f,  // 右下角
         0.0f,  0.5f, 0.0f   // 顶部
    };

    // 创建并绑定顶点缓冲对象
    GLuint VAO[0];
    GLuint VBO;
    glGenVertexArrays(1, VAO);
    glBindVertexArray(VAO[0]);
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // 创建着色器程序
    const char* vertexShaderSource = R"(
        #version 300 es
        precision mediump float;
        layout (location = 0) in vec3 aPos;
        void main() {
            gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
        }
    )";

    const char* fragmentShaderSource = R"(
        #version 300 es
        precision mediump float;
        out vec4 FragColor;
        void main() {
            FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
        }
    )";

    GLuint vertexShader, fragmentShader, shaderProgram;
    // 创建顶点着色器
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
    glCompileShader(vertexShader);

    // 创建片段着色器
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
    glCompileShader(fragmentShader);

    // 创建着色器程序
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    // 使用着色器程序
    glUseProgram(shaderProgram);

    // 绑定顶点数据
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    // 绘制三角形
    glDrawArrays(GL_TRIANGLES, 0, 3);

    // 交换缓冲区
    eglSwapBuffers(display, surface);

    // 清理
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    glDeleteBuffers(1, &VBO);

    // 等待退出
    std::cout << "Press Enter to exit..." << std::endl;
    std::cin.get();

    // 清理 EGL
    eglDestroyContext(display, context);
    eglDestroySurface(display, surface);
    eglTerminate(display);

    return 0;
}

该示例首先使用了EGL创建了渲染表面,EGL可以用于管理绘图表面(window surface只是一种类型,还有pbuffer、pixmap)。下面详细地解释下每个步骤。

使用eglGetDisplay连接渲染目标设备

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值