当前位置: 首页 > 知识库问答 >
问题:

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

司空海荣
2023-03-14

我正在尝试使用“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个答案

昝浩阔
2023-03-14

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);

 类似资料:
  • 我总是只画一个纹理,选择0纹理单位 选择其他纹理单元的标准是什么? 我的意思是:如果我必须处理多个纹理,我应该选择哪个单元?我是openGL的初学者,我想知道我是否可以使用相同的0纹理单元来制作所有的图形纹理。有多少个纹理单元?如果有N个纹理单元,我最多可以使用N个纹理吗?

  • 使用一个纹理贴图集 如果你正在处理一个很大的,很复杂的游戏,你想要找到一种快速有效的方式来从雪碧图创建精灵。纹理贴图集 就会显得很有用处,一个纹理贴图集就是一个JSON数据文件,它包含了匹配的PNG雪碧图的子图像的大小和位置。如果你使用了纹理贴图集,那么想要显示一个子图像只需要知道它的名字就行了。你可以任意的排序你的排版,JSON文件会保持他们的大小和位置不变。这非常方便,因为这意味着图片的位置和

  • 问题内容: 我有两个Java.io.File对象file1和file2。我想将内容从file1复制到file2。有没有一种标准的方法可以执行此操作,而无需创建必须读取文件1并写入文件2的方法 问题答案: 不,没有内置方法可以做到这一点。与您要完成的工作最接近的是from 的方法,如下所示: 并且不要忘记处理异常并在一个块中关闭所有内容。

  • 如何为一个纹理阵列创建多个采样器 到目前为止,我一直依赖OpenGL来确定声明的sampler是指我与绑定的纹理数组。 我尝试在片段着色器中指定两个采样器,但片段着色器出现编译错误: 我没想到这会起作用,但是,我不确定片段着色器编译器是否检查采样器是否分配了纹理,所以可能是其他问题。 我尝试生成和绑定采样器对象,但我仍然得到一个片段着色器错误: 我想坚持使用OpenGL的较低版本,有可能吗?非常感

  • 问题内容: 我需要遍历for循环的每次迭代的值集,但仅对于第一次迭代,它可以正常工作。此后返回。 我很清楚这种行为。 一种解决方案是在for循环中调用方法,因此对于每个for循环迭代,都会对其进行初始化。但这是非常无效的方法,因为它是独立的。 我尝试了此方法,但由于它仅包含参考,因此也无法正常工作。 有什么方法可以将迭代器复制到另一个或其他更好的方法中? 问题答案: An 是可能的最小API,可以

  • 在openGL中,可以将一个纹理绑定到两个(或多个)不同的统一采样器吗?使用两种不同的纹理进行渲染时,如下所示: 着色器: 客户: 但当我尝试将一个纹理对象绑定到两个不同的纹理单元时,似乎第一个绑定的单元保持未绑定状态: 当然,可以为两个采样器设置相同的单位,但有时我还想为不同的纹理使用着色器,而不仅仅是为两个采样器设置相同的纹理对象。 这个解决方案实际上运行得很好,但它不符合我所描述的需求。也可