• Advertisement
Sign in to follow this  

Strange behaviour of FBOs

This topic is 3983 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm developing a fluid dynamics program for my dissertation and I'm getting some strange artifacts with FBOs. Here's the original glCopyTexSubImage2D screenshot: Original Here's the FBO version: FBO The shaders are all the same and nothing except the FBO code has been changed. I'm rendering onto a screen quad, which has a seam diagonally across the screen. This happened on all the computers I tested it on, various hardware configurations and graphics cards, both ATI and nVidia. Any ideas what might be going wrong here? Thanks for your help. :)

Share this post


Link to post
Share on other sites
Advertisement
I'm also using glCopyTexSubImage2D to copy the framebuffer into a texture and it works correctly in my case. Maybe you can post how you set up your fbo?!

Share this post


Link to post
Share on other sites
It's pretty much identical to the tutorial here on gamedev.net. FBOs are relatively simple to set up. I don't understand why the texture could be tearing, that's all. I do get about 5 FPS increase using FBOs but if it causes tearing, I can't use it for my simulation. :(

Any other ideas, if you can point out what you think it might be, I'll post the specific code for that area of my program. I'd rather not post the entire program source code, it's rather large.

Share this post


Link to post
Share on other sites
If you showed the code where you're setting up the FBO and your calls while rendering we might find some small mistakes, from your explanation I can't see why the texture should be tearing, FBOs work fine for me.

Share this post


Link to post
Share on other sites
Ok here's the setup. I've got 4 FBOs, one for each texture in my fluid code:


// Setup FBOs

glGenFramebuffersEXT( 4, g_FBO );

glGenRenderbuffersEXT( 4, g_DepthRenderBuffer );

// g_FBO[FLUID_2D_VELOCITY]
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_FBO[FLUID_2D_VELOCITY] );
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, g_DepthRenderBuffer[0] );
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, g_arrnTextureResolution[0], g_arrnTextureResolution[1] );
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, g_DepthRenderBuffer[0] );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_Texture[FLUID_2D_VELOCITY], 0 );

// g_FBO[FLUID_2D_PRESSURE]
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_FBO[FLUID_2D_PRESSURE] );
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, g_DepthRenderBuffer[1] );
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, g_arrnTextureResolution[0], g_arrnTextureResolution[1] );
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, g_DepthRenderBuffer[1] );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_Texture[FLUID_2D_PRESSURE], 0 );

// g_FBO[FLUID_2D_DIVERGENCE]
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_FBO[FLUID_2D_DIVERGENCE] );
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, g_DepthRenderBuffer[2] );
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, g_arrnTextureResolution[0], g_arrnTextureResolution[1] );
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, g_DepthRenderBuffer[2] );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_Texture[FLUID_2D_DIVERGENCE], 0 );

// g_FBO[FLUID_2D_BOUNDARY]
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_FBO[FLUID_2D_BOUNDARY] );
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, g_DepthRenderBuffer[3] );
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, g_arrnTextureResolution[0], g_arrnTextureResolution[1] );
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, g_DepthRenderBuffer[3] );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_Texture[FLUID_2D_BOUNDARY], 0 );

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );


I do several rendering passes involving using the textures as inputs to their own shaders by rendering to texture. For example:



glViewport( 0, 0, g_arrnTextureResolution[0], g_arrnTextureResolution[1] );

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_FBO[FLUID_2D_VELOCITY] );

if( ex_bSupportVertexShaders && ex_bSupportFragmentShaders )
{
//---------------------------------------------------------------------------------------------------
// Setup uniforms
//---------------------------------------------------------------------------------------------------

g_AdvectShader.EnableShader();

// Standard uniforms
g_AdvectShader.SetUniform1f( string( "g_fTimeStep" ), ex_fTimeDelta );

g_AdvectShader.SetUniform1n( string( "g_spActiveTexture" ), 0 );
g_AdvectShader.SetUniform1n( string( "g_spVelocityTexture" ), 0 );

g_AdvectShader.SetUniform1f( string( "g_fRdx" ), fRdx );
g_AdvectShader.SetUniform1f( string( "g_fFluidWidth" ), static_cast < float > ( g_arrnTextureResolution[0] ) );

//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
}

RenderQuad( ex_nHalfScreenWidth, ex_nHalfScreenHeight );

if( ex_bSupportVertexShaders && ex_bSupportFragmentShaders )
{
g_AdvectShader.DisableShader();
}

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );

// Clear the screen
glClear( GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT );



Thanks for your help on this. :)

Share this post


Link to post
Share on other sites
Quote:
I do several rendering passes involving using the textures as inputs to their own shaders by rendering to texture.


Are you reading from an FBO's texture and then trying to write back to the same FBO? If so, you might want to look up FBO ping-pong methods.

Share this post


Link to post
Share on other sites
Yeah that's more or less what I'm doing, I'll go take a look at that. Thanks.

Edit: Or maybe not. Basically, I need the output of a shader pass to feed back into the next shader pass. In other words, the output from the shader pass will become the input (as a texture) for the next shader pass. I'm not sure whether this counts as ping-ponging. Can you explain it a bit?

Share this post


Link to post
Share on other sites
Well I've given that a try but it didn't seem to work. Any other suggestions? I really need FBOs for this project so I need to get this fixed.

Thanks for your assistance.

Share this post


Link to post
Share on other sites
In an article in the Game Developer Magazine their mentioned that one should avoid using glTexCopy and glCopyTexImage when modifying the contents of a texture when they are also used as rendering destinations.

Would that be the case in your implementation?

Share this post


Link to post
Share on other sites
This is an invalid order of operations

TexA INPUT-> Shader OUTPUT-> TexA

A correct (ping pong one) is:

TexA INPUT-> Shader OUTPUT-> TexB INPUT-> Shader OUTPUT-> TexA

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement