使用OpengGLES2从帧缓冲区对象读取(角度)

时间:2017-08-15 20:08:07

标签: c++ uwp opengl-es-2.0

使用Angle编程UWP应用程序来运行OpenGL ES,我遇到了使用glReadPixels从帧缓冲区对象读取的基本操作问题。 从Visual Studio模板" OpenglES2应用程序(Android,iOS,Windows Universal)"开始,我可以将默认场景渲染检索到内存缓冲区中。

初始化:

void SimpleRenderer::InitFbo()
{
    int buf_size = tex_height*tex_width * 4;
    mReadBuf = new char[buf_size];
    memset(mReadBuf, 123, buf_size); // arbitrary value to detect changes
}

绘制功能:

void SimpleRenderer::Draw()
{

    // drawing calls here
    // (...)

    glReadPixels(0, 0, tex_width, tex_height, GL_RGBA, GL_UNSIGNED_BYTE, mReadBuf);
    // success : mReadBuf is updated with pixel values
}

但是如果我只创建一个帧缓冲对象,尝试在那里绘制并检索结果,glReadPixels不返回任何值,glError返回INVALID_FRAMEBUFFER_OPERATION

初始化:

void SimpleRenderer::InitFbo()
{
    glGenFramebuffers(1, &mRenderFbo);
    glGenTextures(1, &mRenderTexture);
    int buf_size = tex_height*tex_width * 4;
    char*buf = new char[buf_size];
    memset(buf, 255, buf_size);

    glBindTexture(GL_TEXTURE_2D, mRenderTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, 4,
            tex_width,
            tex_height,
            0, GL_RGBA, GL_UNSIGNED_BYTE,
            buf);

    glBindFramebuffer(GL_FRAMEBUFFER, mRenderFbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
            mRenderTexture, 0);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    delete[] buf;

    mReadBuf = new char[buf_size];
    memset(mReadBuf, 123, buf_size);
}

绘制功能:

void SimpleRenderer::Draw()
{
    glBindFramebuffer(GL_FRAMEBUFFER, mRenderFbo);

    // drawing calls here
    // (...)

    glReadPixels(0, 0, tex_width, tex_height, GL_RGBA, GL_UNSIGNED_BYTE, mReadBuf);

    // failure : mReadBuf is unchanged

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
由于下面的评论,

*编辑已解决。纹理的正确初始化是

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
    tex_width,
    tex_height,
    0, GL_RGBA, GL_UNSIGNED_BYTE,
    buf);

对于记录,在解决之前,我正在使用glCheckFramebufferStatus检查帧缓冲状态,该GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT返回View [] not found (View:/home/vagrant/Laravel/youtube/resources/views/emails/password/reset.blade.php)

1 个答案:

答案 0 :(得分:1)

OpenGL函数glTexImage2D的第3个参数指定纹理缓冲区的内部格式。

在方法SimpleRenderer::InitFbo中,您将4传递给内部格式,而内部格式不是有效参数。请改用GL_RGBA

glTexImage2D(GL_TEXTURE_2D, 0, 
        GL_RGBA,   // <-----------------------
        tex_width,
        tex_height,
        0, GL_RGBA, GL_UNSIGNED_BYTE,
        buf);

请注意,内部格式(在OpenGL ES 2.0中)的valide参数为GL_ALPHAGL_LUMINANCEGL_LUMINANCE_ALPHAGL_RGBGL_RGBA

如果您在调用glGetError后使用glTexImage2D,那么如果内部格式不是可接受的格式,则会生成GL_INVALID_VALUE。此外,如果纹理附加到帧缓冲区并且GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT导致glCheckFramebufferStatus错误,则会导致glReadPixels错误(使用INVALID_FRAMEBUFFER_OPERATION检查时)。