Reputation: 65
I am attempting to create a scenario where I render two completely different textures and swap between them, to represent different states in a game. Is it possible to render textures to framebuffer A, and then completely different textures to framebuffer B. Is then possible to switch back and forth between these frames, so for instance if framebuffer A is being rendered onto the screen, then the contents of framebuffer B are stored in memory until they are selected. Give only helpful answers.
Upvotes: 1
Views: 911
Reputation: 168
Although this particular scenario may be handled in various way depending on what you exactly need to render on them, swapping between framebuffer textures is not uncommon practice and it can serve well the purpose of making e.g. gaussian blur post process effects with the use of ping-pong framebuffers as explained in the following article: https://learnopengl.com/#!Advanced-Lighting/Bloom
One of the possible solution would then require the creation of two offscreen framebuffers to be later displayed on the main framebuffer
//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;
}
Later on after you've finished rendering on those framebuffers you could setup a quick shader program bound to the main framebuffer to display a quad that fills the entire screen and outputs the content of those framebuffer's texture
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);
If you're worried about performance, keep in mind that using multiple framebuffers is not uncommon and at times is mandatory to achieve certain post process effects or tecniques such as deferred shading.
Upvotes: 1