OpenGL/OpenGL ES入门(二):EGL的介绍和使用(context上下文的创建和初始化)

一、简介

EGL 是渲染 API(如 OpenGL ES)和原生窗口系统之间的接口。

通常来说,OpenGL 是一个操作 GPU 的 API,它通过驱动向 GPU 发送相关指令,控制图形渲染管线状态机的运行状态,但是当涉及到与本地窗口系统进行交互时,就需要这么一个中间层,且它最好是与平台无关的。

因此 EGL 被设计出来,作为 OpenGL 和原生窗口系统之间的桥梁

二、功能

EGL API 是独立于 OpenGL ES 各版本标准的独立的一套 API。

2.1 主要作用:

  • 为 OpenGL 指令创建Context;
  • 绘制目标Surface;
  • 配置FrameBuffer属性;
  • Swap提交绘制结果等。

2.2 EGL提供如下机制:

  • 与设备原生窗口通信;
  • 查询绘制Surface的可用类型和配置;
  • 创建绘制surface;
  • 在OpenGL ES 3.0或其他渲染API之间同步渲染;
  • 管理纹理贴图等渲染资源

三、使用

3.1 检查错误的方法

EGL 中大部分函数成功时都是返回 EGL_TRUE,失败返回 EGL_FALSE

至于故障原因,需要调用如下函数获取:

EGLint eglGetError();

返回最近调用 EGL 函数的错误代码,如果返回 EGL_SUCCESS 说明没有错误。

3.2 创建。建立本地系统和OpenGL ES的连接

EGLDisplay eglGetDisplay(EGLNativeDisplayType displayId);

displayId 指定显示连接,一般使用默认的 EGL_DEFAULT_DISPLAY,即返回与默认原生窗口的连接。

相关错误码:

  • EGL_NO_DISPLAY :连接不可用

3.3 初始化

EGLBoolean eglInitialize(EGLDisplay display, // 创建步骤时返回的对象
                         EGLint *majorVersion, // 返回 EGL 主版本号
                         EGLint *minorVersion); // 返回 EGL 次版本号

相关错误码:

  • EGL_NO_DISPLAY ÿ
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的示例代码,可以通过使用 OpenGL ES 和 MediaCodec 将 RGB 图像转换为 MP4 视频: ```c++ #include <stdlib.h> #include <stdio.h> #include <EGL/egl.h> #include <GLES2/gl2.h> #include <media/NdkMediaCodec.h> #include <media/NdkMediaMuxer.h> int main() { // 初始化 EGL EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, 0, 0); // 创建 EGL 配置 EGLConfig eglConfig; EGLint numConfigs; EGLint configAttribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_NONE }; eglChooseConfig(display, configAttribs, &eglConfig, 1, &numConfigs); // 创建 EGL 上下文 EGLSurface surface = eglCreatePbufferSurface(display, eglConfig, NULL); EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLContext context = eglCreateContext(display, eglConfig, EGL_NO_CONTEXT, contextAttribs); eglMakeCurrent(display, surface, surface, context); // 创建 OpenGL ES 纹理 GLuint texId; glGenTextures(1, &texId); glBindTexture(GL_TEXTURE_2D, texId); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 640, 480, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); // 创建 MediaCodec 编码器 AMediaCodec *codec = AMediaCodec_createEncoderByType("video/avc"); AMediaFormat *format = AMediaFormat_new(); AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "video/avc"); AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, 2000000); AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, 30); AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT, 19); AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, 1); AMediaCodec_configure(codec, format, NULL, NULL, AMEDIACODEC_CONFIGURE_FLAG_ENCODE); AMediaCodec_start(codec); // 创建 MediaMuxer 封装器 AMediaMuxer *muxer = AMediaMuxer_new("/sdcard/test.mp4", AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4); // 循环编码每一帧图像 for (int i = 0; i < 300; i++) { // 渲染一帧图像到纹理 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, 640, 480); // 此处应该将 RGB 图像数据更新到纹理中 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 从纹理中获取图像数据 uint8_t *buf = (uint8_t*)malloc(640 * 480 * 3); glReadPixels(0, 0, 640, 480, GL_RGB, GL_UNSIGNED_BYTE, buf); // 将图像数据编码为 H.264 帧 AMediaCodecBufferInfo info; ssize_t bufIdx = AMediaCodec_dequeueInputBuffer(codec, -1); uint8_t *inputBuf = AMediaCodec_getInputBuffer(codec, bufIdx, NULL); memcpy(inputBuf, buf, 640 * 480 * 3); AMediaCodec_queueInputBuffer(codec, bufIdx, 0, 640 * 480 * 3, i * 1000000 / 30, 0); // 编码器输出 H.264 帧 ssize_t outIdx = AMediaCodec_dequeueOutputBuffer(codec, &info, 0); if (outIdx >= 0) { AMediaCodecBufferInfo info; uint8_t *outputBuf = AMediaCodec_getOutputBuffer(codec, outIdx, &info); AMediaMuxer_writeSampleData(muxer, 0, outputBuf, &info); AMediaCodec_releaseOutputBuffer(codec, outIdx, false); } free(buf); } // 停止并释放资源 AMediaCodec_stop(codec); AMediaCodec_delete(codec); AMediaFormat_delete(format); AMediaMuxer_stop(muxer); AMediaMuxer_delete(muxer); eglDestroyContext(display, context); eglDestroySurface(display, surface); eglTerminate(display); return 0; } ``` 以上代码仅供参考,实际实现过程可能需要根据具体情况进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值