Hello Guest

FBO Rendering Issue

  • 6 Replies
  • 6079 Views
FBO Rendering Issue
« on: February 11, 2012, 21:44:31 »
Hello,

I have create a frame buffer object with the following code. However, when I bind it, I cannot draw to the texture at all (not even change the color with glClear). Absolutely nothing happens. What am I missing?

Here is how I generate the FBO:

Code: [Select]
                // Generate the fbo
int fbo = EXTFramebufferObject.glGenFramebuffersEXT();

GLErrorCheck();

// Attach a texture to render to
int texture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);

GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);

// The null at the end must be cast to tell javac which overload to use,
// even though the last parameter (for the different overloads) isn't even used
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer)null);

// Unbind texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

GLErrorCheck();

// Bind the fbo for use
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, fbo);

EXTFramebufferObject.glFramebufferTexture2DEXT(
EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT,
GL11.GL_TEXTURE_2D, texture, 0); // The 0 is for mip map levels, we aren't using any

GLErrorCheck();

// Attach a depth buffer render buffer if desired
if(depthBuffer)
{
int depthRenBuff = EXTFramebufferObject.glGenRenderbuffersEXT();

// Bind it so we can set it up
EXTFramebufferObject.glBindRenderbufferEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, depthRenBuff);

// Set up the depth buffer
EXTFramebufferObject.glRenderbufferStorageEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, GL11.GL_DEPTH_COMPONENT, width, height);

// Attach the dpeth buffer
EXTFramebufferObject.glFramebufferRenderbufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_DEPTH_ATTACHMENT_EXT, EXTFramebufferObject.GL_RENDERBUFFER_EXT, depthRenBuff);

GLErrorCheck();
}

// Check
if(EXTFramebufferObject.glCheckFramebufferStatusEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT) != EXTFramebufferObject.GL_FRAMEBUFFER_COMPLETE_EXT)
throw new Error("Could not create FBO!");

// An fbo has its own viewport, so lets set it
GL11.glViewport(0, 0, width, height);

// Unbind
EXTFramebufferObject.glBindRenderbufferEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, 0);
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);

GLErrorCheck();

Binding it:

Code: [Select]
                // Unbind textures
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, fbo);

// Save view port information, since this will in almost all cases change (states are shared with main context)
GL11.glPushAttrib(GL11.GL_VIEWPORT_BIT | GL11.GL_COLOR_BUFFER_BIT);

Unbinding:

Code: [Select]
                // Finish all operations so can use texture
GL11.glFlush();

// Restore saved information for main rendering context
GL11.glPopAttrib();

// Unbind
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);

After the FBO is bound I do the following:

Code: [Select]
                // Create the view port for this render texture
GL11.glViewport(0, 0, m_width, m_height);
                GL11.glClearColor(0.5f, 0.2f, 0.8f, 1.0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

After unbinding the FBO, I bind the texture that went with it and draw a quad, but it is plain white every time.

Re: FBO Rendering Issue
« Reply #1 on: February 13, 2012, 13:59:06 »
Without all of your code, it's hard to tell what the problem is, but I don't see that you are enabling texturing (which would explain why everything appears white). Make sure you call GL11.glEnable(GL11.GL_TEXTURE_2D).
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

Re: FBO Rendering Issue
« Reply #2 on: February 13, 2012, 21:42:00 »
Here is a complete and minimal code example that produces this problem:

Code: [Select]
public static void main(String[] args)
{
try
{
    Display.setDisplayMode(new DisplayMode(800, 600));
    Display.create();
    Display.setVSyncEnabled(true);
}
catch(LWJGLException e)
{
    e.printStackTrace();
    System.exit(0);
}

// Requirements
if(!GLContext.getCapabilities().GL_EXT_framebuffer_object)
throw new Error("FBOs not supported! Get a better computer!");

// Defaults
GL11.glEnable(GL11.GL_TEXTURE_2D);

GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

GL11.glDisable(GL11.GL_DEPTH_BUFFER_BIT);

// Set up orthographic projection for 2D
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 800, 0, 600, -100, 100);
GL11.glMatrixMode(GL11.GL_MODELVIEW);

// Create a FBO
// Generate the fbo
int fbo = EXTFramebufferObject.glGenFramebuffersEXT();

// Attach a texture to render to
int texture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);

GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);

// The null at the end must be cast to tell javac which overload to use,
// even though the last parameter (for the different overloads) isn't even used
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, 800, 600, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer)null);

// Unbind texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

// Bind the fbo for use
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, fbo);

EXTFramebufferObject.glFramebufferTexture2DEXT(
EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT,
GL11.GL_TEXTURE_2D, texture, 0); // The 0 is for mip map levels, we aren't using any

// Check
if(EXTFramebufferObject.glCheckFramebufferStatusEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT) != EXTFramebufferObject.GL_FRAMEBUFFER_COMPLETE_EXT)
throw new Error("Could not create FBO!");

// An fbo has its own viewport, so lets set it
GL11.glViewport(0, 0, 800, 600);

// Unbind
EXTFramebufferObject.glBindRenderbufferEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, 0);
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);

// Game loop
while(!Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
{
GL11.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

// --------------------- Render to the FBO ----------------------

// Unbind textures
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, fbo);

// Save view port information
GL11.glPushAttrib(GL11.GL_VIEWPORT_BIT);

// Clear the FBO to a color
GL11.glClearColor(0.5f, 0.3f, 0.3f, 1.0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

// Finish all operations so can use texture
GL11.glFlush();

// Restore saved information for main rendering context
GL11.glPopAttrib();

// Unbind the FBO
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);

// ------------------ Render FBO to the screen -----------------------

// Draw a quad with the FBO on it
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);

GL11.glBegin(GL11.GL_QUADS);

GL11.glTexCoord2f(0.0f, 0.0f); GL11.glVertex2f(200.0f, 200.0f);
GL11.glTexCoord2f(1.0f, 0.0f); GL11.glVertex2f(600.0f, 200.0f);
GL11.glTexCoord2f(1.0f, 1.0f); GL11.glVertex2f(600.0f, 600.0f);
GL11.glTexCoord2f(0.0f, 1.0f); GL11.glVertex2f(200.0f, 600.0f);

GL11.glEnd();

Display.update();
}
}

The FBO does not change from a plain white texture, so I assume it is never really rendering to it.

Re: FBO Rendering Issue
« Reply #3 on: February 20, 2012, 19:32:45 »
Bump

Re: FBO Rendering Issue
« Reply #4 on: February 24, 2012, 23:05:17 »
Bump

*

Offline spasi

  • *****
  • 2169
    • WebHotelier
Re: FBO Rendering Issue
« Reply #5 on: February 25, 2012, 23:10:51 »
Code: [Select]
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
You need to set GL_TEXTURE_MIN_FILTER to GL_LINEAR instead of GL_LINEAR_MIPMAP_LINEAR. You're only defining a single mip map level in the texture.

Code: [Select]
GL11.glDisable(GL11.GL_DEPTH_BUFFER_BIT);
Unrelated to your problem, but this line causes a GL error. You probably meant GL_DEPTH_TEST. There are a few options to catch errors like these while developing your app:

- Always put a Util.checkGLError(); in your main loop. That's the simplest solution, but it won't give you the error source.
- Use LWJGL's debug jar, which performs an error check after every GL call. This will give you the exact error source, but it will affect performance.
- Use the ARB_debug_output extension (or AMD_debug_output). This is the preferred way and it's very simple to enable:

Code: [Select]
Display.create(new PixelFormat(), new ContextAttribs(4, 2).withProfileCompatibility(true).withDebug(true));
...
if ( GLContext.getCapabilities().GL_ARB_debug_output )
ARBDebugOutput.glDebugMessageCallbackARB(new ARBDebugOutputCallback());
else if ( GLContext.getCapabilities().GL_AMD_debug_output )
AMDDebugOutput.glDebugMessageCallbackAMD(new AMDDebugOutputCallback());

Re: FBO Rendering Issue
« Reply #6 on: February 26, 2012, 20:44:20 »
Thank you very much! It was indeed the mipmap setting. Thanks for the advice on debugging!