在不同的帧缓冲区之间交换

时间:2017-01-11 12:54:00

标签: opengl

我正在尝试创建一个场景,我渲染两个完全不同的纹理并在它们之间交换,以表示游戏中的不同状态。是否可以将纹理渲染到帧缓冲区A,然后将完全不同的纹理渲染到帧缓冲区B.然后可以在这些帧之间来回切换,例如,如果将帧缓冲区A渲染到屏幕上,那么帧缓冲区B的内容存储在内存中,直到它们被选中。只给出有用的答案。

1 个答案:

答案 0 :(得分:0)

虽然这种特殊情况可能会以各种方式处理,具体取决于你需要在它们上呈现的内容,但帧缓冲纹理之间的交换并不罕见,它可以很好地用于制作例如使用乒乓帧缓冲区的高斯模糊后期处理效果,如以下文章中所述:https://learnopengl.com/#!Advanced-Lighting/Bloom

其中一个可能的解决方案是需要创建两个屏幕外帧缓冲区,以便稍后显示在主帧缓冲区上

//this renderbuffer provides DEPTH ONLY - change to include stencilBuffer
function createFramebufferA() {
    var FBO_A = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_A);

    var FBO_A_texture = gl.createTexture();

    gl.bindTexture(gl.TEXTURE_2D, FBO_A_texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, screen.width, screen.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);

    var renderbuffer = gl.createRenderbuffer();
    gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
    gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, screen.width, screen.height);

    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer);

    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, FBO_A_texture, 0);

    gl.bindTexture(gl.TEXTURE_2D, null);
    gl.bindRenderbuffer(gl.RENDERBUFFER, null);
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);

    return FBO_A;
}

稍后您在这些帧缓冲区上完成渲染后,您可以设置绑定到主帧缓冲区的快速着色器程序,以显示填充整个屏幕的四边形并输出这些帧缓冲区纹理的内容< / p>

gl.bindFramebuffer(gl.FRAMEBUFFER, null); //we're now drawing inside main framebuffer
gl.useProgram(PostProcessProgram);        //this program displays a quad that fills the entire screen and takes a texture as uniform

/* ... after binding the VBO and attribute pointers ... */

// this condition decides whether we're going to display the content
// of framebuffer A or framebuffer B
if(certain_condition)  
    gl.bindTexture(gl.TEXTURE_2D, FBO_A_texture);
else
    gl.bindTexture(gl.TEXTURE_2D, FBO_B_texture);

gl.activeTexture(gl.TEXTURE0);
gl.uniform1i(PostProcessProgram.texture, 0);

//drawing one of either framebuffer's texture
gl.drawArrays(gl.TRIANGLES, 0, 6);

如果您担心性能,请记住,使用多个帧缓冲区并不罕见,有时必须实现某些后期处理效果或延迟着色等技术。