OpenGL多帧缓冲区VS仅使用一个帧缓冲区重新绑定颜色附件

webghufk  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(242)

如果我们希望每帧都得到前一帧的纹理,我们可以使用两个FBO,并做这样的事情:

uint fbos[2];
uint textures[2];

// attach...
for(int i = 0; i < 2; i++)
{
    // ...
    glBindFrameBuffer(GL_FRAMEBUFFER, fbos[i]);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[i]);

    // ...
}

// every frame

int i = frame % 2;
glBindFramebuffer(GL_FRAMEBUFFER, fbos[i]);
glBindTexture(GL_TEXTURE_2D, textures[1-i]);
draw();

但我们也可以只使用一个FBO:

// every frame

GLuint frambuffer; glGenFramebuffers(1, &framebuffer);

// init...
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[i]);

glBindTexture(GL_TEXTURE_2D, textures[1-i]);
draw();

glDeleteFramebuffers(1, &framebuffer);

使用第二种方法更简单,因为当我们创建一个新的后期效果时,我们不需要创建一个新的FBO。那么,这样做是否明智呢?

TL; DR;是否建议每帧调用glFramebufferTexture2D()并创建一个FBO?

o75abkj4

o75abkj41#

如果你想要前一帧的数据,那么使用像素缓冲对象将是一个非常快的解决方案。
创建两个像素缓冲区对象,并以此方式获取数据。

glReadBuffer(GL_COLOR_ATTACHMENT0);
w_writeIndex = (w_writeIndex + 1) % 2;
w_readIndex = (w_readIndex + 1) % 2;
glBindBuffer(GL_PIXEL_PACK_BUFFER, w_pbo[w_writeIndex]);
// copy from framebuffer to PBO asynchronously. it will be ready in the NEXT frame
glReadPixels(0, 0, SCR_WIDTH, SCR_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
// now read other PBO which should be already in CPU memory
glBindBuffer(GL_PIXEL_PACK_BUFFER, w_pbo[w_readIndex]);
unsigned char* previousFrameData = (unsigned char*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);

相关问题