OpenGL Es渲染相机画面问题记录

24 阅读2分钟

问题记录

问题1、错误码(16进制) 0x3002

执行eglMakeCurrent的时候产生了这个问题,这个错误码在openGL内部是 EGL_BAD_ACCESS,经过排查已经发现了问题的原因。

根本原因在于OpenGL的上下文只能被一个线程持有。我的OpenGl的渲染是新开了一个线程之前,我这边初始化openGL的上下文的时候已经执行过eglMakeCurrent导致了openGL的上下文被初始化的线程持有了。

有两个解决方案,第一个方案删除外部的eglMakeCurrent逻辑,将glCreateShader和glCreateProgram的逻辑迁移到渲染线程,第二个方案是外面初始化openGL上下文的shader和program之后执行一遍释放上下文。代码示例如下

// 这里绑定上下文
if (!eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_)) {
    OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG, "eglMakeCurrent Error = %{public}x", eglGetError());
    releaseEglDisplay();
    return false;
}

// 创建shader和program
m_program = CreateProgram(VERTEX_SHADER_YUV, FRAGMENT_SHADER_YUV);
if (m_program == 0) {
    OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG, "CreateProgram Error");
    releaseEglDisplay();
    return false;
}

// 这里释放上下文
if (!eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
    OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, LOG_TAG, "eglMakeCurrent unbind Error = 0x{public}x", eglGetError());
    releaseEglDisplay();
    return false;
}

问题二:渲染图片旋转了90度

UV纹理的坐标绘制存在问题,要调整一下UV的坐标

原UV坐标

// 修改前
static float fragment[] = {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};

// 修改后
static float fragment[] = {
    1.0f, 0.0f, 
    1.0f, 1.0f,  
    0.0f, 0.0f, 
    0.0f, 1.0f,
};

问题三:渲染图片出现了镜像

顶点坐标存在问题

// 修改前
    static float ver[] = {1.0f, -1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f};


    // 修改后
    static float ver[] = {-1.0f, -1.0f, 0.0f,
                      1.0f, -1.0f, 0.0f, 
                      -1.0f, 1.0f, 0.0f,
                      1.0f, 1.0f, 0.0f};

问题四:矩形只渲染了一半

修改关键

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 是三角带不是三角形

问题五: 错误码(16进制) 0x0502

GL_INVALID_OPERATION              0x0502

这个问题出现在我这边的原因是我初始化上下文的时候忘记属性列表了

// 修改前
eglContext_ = eglCreateContext(eglDisplay_, eglConfig_, EGL_NO_CONTEXT, nullptr);

// 修改后
const EGLint CONTEXT_ATTRIBS[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
eglContext_ = eglCreateContext(eglDisplay_, eglConfig_, EGL_NO_CONTEXT, CONTEXT_ATTRIBS);