Hi all,
I have made an application that renders images off screen to a texture. User interaction can trigger a new render, but the time interval can be great, there fore I want to kill the off screen renderer, a new renderer is then created when triggered by the user. Now all of that works fine. BUT.
When ever I close the off screen renderer I remove all processors and expect the rest to be GC’ed.
[java]
ViewPort.removeProcessor( this );
RenderManager.removePreView( ViewPort );
[/java]
However, that is not the case, every time there is an off screen rendering queue, I am adding one framebuffer to my stack ( judging from the number in the standard fps display ), that is never removed - over time this is killing my frame rate, I have ( artificially ) created and destroyed 250 off screen scene, which grinds the FPS from 100+ down to <20. I have found that the only line of code that actually removes a framebuffer is:
[java]
renderManager.getRenderer().deleteFrameBuffer(offBuffer);
[/java]
While this removes the framebuffer, next time an off screen scene is created i get the following error:
java.lang.IllegalStateException: Framebuffer doesn’t have any renderbuffers attached.
My creation of the SceneProcessor is identical to the TestRenderToTexture example ( I based my implementation on that ) :
[java]
public Texture setupOffscreenView(){
Camera offCamera = new Camera(512, 512);
offView = renderManager.createPreView(“Offscreen View”, offCamera);
offView.setClearFlags(true, true, true);
offView.setBackgroundColor(ColorRGBA.DarkGray);
// create offscreen framebuffer
FrameBuffer offBuffer = new FrameBuffer(512, 512, 1);
//setup framebuffer’s cam
offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f);
offCamera.setLocation(new Vector3f(0f, 0f, -5f));
offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
//setup framebuffer’s texture
Texture2D offTex = new Texture2D(512, 512, Format.RGBA8);
offTex.setMinFilter(Texture.MinFilter.Trilinear);
offTex.setMagFilter(Texture.MagFilter.Bilinear);
//setup framebuffer to use texture
offBuffer.setDepthBuffer(Format.Depth);
offBuffer.setColorTexture(offTex);
//set viewport to render to offscreen framebuffer
offView.setOutputFrameBuffer(offBuffer);
// setup framebuffer’s scene
Box boxMesh = new Box(Vector3f.ZERO, 1,1,1);
Material material = assetManager.loadMaterial(“Interface/Logo/Logo.j3m”);
offBox = new Geometry(“box”, boxMesh);
offBox.setMaterial(material);
// attach the scene to the viewport to be rendered
offView.attachScene(offBox);
return offTex;
}
[/java]
My issues are very similar to:
http://hub.jmonkeyengine.org/groups/graphics/forum/topic/once-again-render-to-texture-fbo
But I find no help in that thread, it seems unresolved…
Oh, I just found that not my destroy() method is not called for all offscreen scenes for some reason… Let me just investigate that first…
Sorry, I have a bad habit of suspecting black magic and wizardry every time things doesn’t work… I will close this thread again if my suspicion is confirmed.
You may want to set the offView framebuffer to null after you’re done with it. It won’t be referenced by anything and should be GC’d. Maybe /shrug
I haven’t specifically done this, as I usually am borrowing a viewport and rendering to a framebuffer and then setting it back to the scene framebuffer… but I’m not seeing what you have happening when doing this… so that might do it.
Hi,
I have solved the issue, the problem was that some of my renderers were started with an empty queue, and therefor never started rendering, and there for never reached it’s end triggering my destroy() method… Sorry, no black magic after all.
And thank you for the tip @t0neg0d. I had one remaining framebuffer that was not GC’ed,
[java]
ViewPort.setOutputFrameBuffer( null );
FrameBuffer = null;
[/java]
Cleared that issue.
Cheers!