提问者:小点点

opengl es 3 glBlitFramebuffer-将一个纹理复制到另一个纹理


我正在尝试使用“gl BlitFrameBuffer”将一个纹理复制到另一个纹理中,我正在处理来自android NDK-Samples的经典开放式gl示例hello-gl2。我改变了着色器,以支持纹理,我可以正确地渲染一个纹理三角形。我还更改了在Java端请求的opengl es版本,以便请求opengl-es3,并且我更新了Cmakelists文件以链接正确的库。调用glBlitFramebuffer(0,0,tw,th,0,0,tw,th,GL_COLOR_BUFFER_BIT,GL_LINEAR);后,我得到了blitTexture glBlitFramebuffer()glError(0x502)错误的。其根本原因是什么?

我使用的代码:

生成纹理:

void createTexture(GLuint &tex, int width, int height, int r){
    int rowlen = width * 3;
    unsigned char buf[width*3*height];
    for (int i=0; i<rowlen; i+=3)
        for (int j=0; j<height; j++) {
            int col = ((int (i/(3*r))) + (int (j/r)))%2;
            buf[i+j*rowlen] = buf[i+1+j*rowlen] = buf[i+2+j*rowlen] = col * 255;
        }
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, buf);
    // set the texture wrapping/filtering options (on the currently bound texture object)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    LOGI("DEBUG C++ Texture created [%d]", tex);
}

要设置FrameBuffer,请执行以下操作:

bool SetupFramebuffer(GLuint tex, int width, int height)
{
    if (fb == 0)
    {
        glGenFramebuffers(1, &fb);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                               GL_TEXTURE_2D, tex, 0);

        GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

        if (status != GL_FRAMEBUFFER_COMPLETE)
        {
            LOGE("Incomplete frame buffer object!");
            return false;
        }

        LOGI("Created FBO %d for texture %d.",
             fb, tex);
    }

    return true;
}

在setupGraphics函数中构建纹理数组:

    createTexture(tex, tw, th, 6);
    for (int i = 0; i<25; i++) createTexture(aniTex[i], tw, th, 3+i);
    SetupFramebuffer(tex, tw, th);

最后blit framebuffer:

void blitTexture() {
    static int time = 0;
    glBindFramebuffer(GL_FRAMEBUFFER, fb);
    checkGlError("blitTexture glBindFramebuffer");

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
                           GL_TEXTURE_2D, aniTex[time], 0);
    checkGlError("blitTexture glFramebufferTexture2D");
    glReadBuffer(GL_COLOR_ATTACHMENT1);
    checkGlError("blitTexture glReadBuffer");
    glDrawBuffers(1, attachment);
    checkGlError("blitTexture glDrawBuffers");


    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (status != GL_FRAMEBUFFER_COMPLETE) LOGE("Incomplete frame buffer object!");

    glBlitFramebuffer(0,0,tw, th, 0, 0, tw, th, GL_COLOR_BUFFER_BIT, GL_LINEAR);
    checkGlError("blitTexture glBlitFramebuffer");
    int samples;
    glGetFramebufferParameteriv(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, &samples);
    LOGI("SAMPLES draw buffer %d", samples);
    time = ++time%25;
}

完整的项目可以在这里找到:https://github.com/andrewbloom/blitframeBufferExample


共1个答案

匿名用户

glblitframebuffer是一种复制操作,将数据从一个framebuffer复制到另一个framebuffer。
必须将源framebuffer绑定到目标gl_read_framebuffer并将目标framebuffer绑定到目标gl_draw_framebuffer(请参阅glbindframebuffer):

glBindFramebuffer(GL_READ_FRAMEBUFFER, frambuffer_1);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frambuffer_2);
glBlitFramebuffer(0,0,tw,th, 0,0,tw,th, GL_COLOR_BUFFER_BIT, GL_LINEAR);