FrameBuffer extension causes VM crash

hi

I’m trying to use the FrameBuffer extension to render a part of my scene to a texture. Unfortunately the VM crashes when I quit the app and I used render-to-texture. If r2t was not used with the same scene (and any other) the VM doesn’t crash. I didn’t find any tutorial, that clearly said, what to do and in what order. Well, it works the way I do it and it is fast and stable. It’s just the VM crash at app quit, that I cannot fix.

could please someone have a look at it and tell me, what I am doing wrong? It’s the setupRenderTarget() method (line #553).
http://xith3d.svn.sourceforge.net/viewvc/xith3d/trunk/src/org/xith3d/render/lwjgl/RenderPeerImpl.java?view=markup

Some tutorials said, I just had to call glBindFramebufferEXT before something has to be rendered to the texture (of course after I once and initially initialized the FBO). And some explicitly bound no texture before FBO binding.

Any help is very appreciated. Thanks in advance.

Marvin

EDIT: I’m using LWJGL 1.0 release and Linux AMD64 (64 bit Java). But I know, that it also crashes on some other user’s machine (Windows XP).

I have the same behaviour using JOGL, it bombs out in nvoglnt.dll under Windows XP with an NVidia 7950GT using xiths’ render to texture feature. I tried an old FBO demo I have and it does not crash. Maybe the renderloop does any FBO related work in the shutdown phase after the gl context is invalid.

It’s not , that I didn’t check that ;). There is no such code in the shutdown phase. I have also already tried to add some FBO cleanup code to the rendering system, but it didn’t help.

Could you maybe paste this working FBO demo code here?

Marvin

I would post the code, but it is not self contained. It uses FBO and Texture utility classes. Despite of that it does nothing special to clean the FBO, just stops the Animator before exit :confused:

How do you quit the application exactly? Are you using Display.destroy() and does the crash happen when doing so? If so, does it go away when using System.exit(0); instead? I’m having a similar problem with NVidia cards (not limited to FBO usage but it seems to increase the possibility), as you can see here: http://lwjgl.org/forum/index.php/topic,2411.0.html

Here is a selfcontained framebuffer test that works on my laptop with a ATI radeon 9700.


import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.EXTFramebufferObject.*;

public class PBOTest {
	public static void main(String args[]) throws Exception {
		try {
			Display.setDisplayMode(new DisplayMode(640, 480));
			Display.create();
			glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
			
			int TEX_WIDTH = 256;
			int TEX_HEIGHT = 256;
			
			boolean fboEnabled = GLContext.getCapabilities().GL_EXT_framebuffer_object;
			System.out.println("GL_EXT_framebuffer_object enabled="+fboEnabled);
			
			IntBuffer fboId = BufferUtils.createIntBuffer(1);
			glGenFramebuffersEXT(fboId);
			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId.get(0));
			
			// add depth buffer
			IntBuffer depthbufferId = BufferUtils.createIntBuffer(1);
			glGenRenderbuffersEXT(depthbufferId);
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbufferId.get(0));
			glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, TEX_WIDTH, TEX_HEIGHT);
			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthbufferId.get(0));
			
			// add a texture
			IntBuffer imgId = BufferUtils.createIntBuffer(1);
			glGenTextures(imgId);
			glBindTexture(GL_TEXTURE_2D, imgId.get(0));
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
			glGenerateMipmapEXT(GL_TEXTURE_2D);
			
			glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, imgId.get(0), 0);
			if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
				throw new RuntimeException("Framebuffer not complete");
			}
			
			while (!Display.isCloseRequested()) {
				glViewport(0, 0, 640, 480);
				glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
				glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
				glLoadIdentity();
				
				// render to texture 
				glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId.get(0));
				glClearColor(1.0f, 0.5f, 1.0f, 0.0f);
				glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
				glColor3f(0, 1, 0);
				drawQuad(-100, -100, 240, 280);
				glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);		

				// draw quad
				glColor3f(1, 1, 1);
				glEnable(GL_TEXTURE_2D);
				glBindTexture(GL_TEXTURE_2D, imgId.get(0));
				drawQuad(100, 100, 200, 200);
				glDisable(GL_TEXTURE_2D);
				
				Display.update();
				Thread.yield();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			Display.destroy();      
		}
	}
	
	private static void drawQuad(int x, int y, int width, int height) {
		glBegin(GL_QUADS);
		glTexCoord2f(0, 0);
		glVertex3f(x, y, 0);
		glTexCoord2f(1, 0);
		glVertex3f(x+width, y, 0);
		glTexCoord2f(1, 1);
		glVertex3f(x+width, y+height, 0);
		glTexCoord2f(0, 1);
		glVertex3f(x, y+height, 0);
		glEnd();
	}
}


Thanks for the answers.

I use Display.destroy() when the application quites and at the very end I use System.exit( 0 ). The VM crashes exactly with the Display.destroy() call. But when I leave it, it crashes anyway at some other line.

Thanks, Tom, for the example. I will try it out.

Marvin

I found the bug in my code. I forgot a ! in the if selection for "is the FBO already created. So the FBO was recreated each frame. It works now :).

Thanks for your help guys.

Marvin

Well, even if it works, I have to call some bindings each frame. It’s not enough to just call glBindFramebufferEXT each frame. No error, but the texture will remain empty.

You can click the link in the first posting and see lines 277-285, which are called each frame. Any idea, why this has to be done.

And another question. I cannot find any documentation (neither on opengl.org or in the lwjgl javadoc), what parameters I have to change to render some other buffer into the texture (like the stencilbuffer or depth buffer). Would be cool, if you could point me to some docu, where I can see that.

Marvin

This wiki has some info about that: http://lwjgl.org/wiki/doku.php/lwjgl/tutorials/opengl/basicfbo