RenderManager in AppState

Hello,
In an appstate class I create a pre-view viewport with the renderManager from the main class. One frame later I attempt to remove the viewport with the render manager. Yet it appears the pre-view is never removed.
In the appstate I get the renderManager with this:

[java]
public void initialize(AppStateManager stateManager, Application app) {
initialized = true;
this.mainClass = app;
this.renderManager = mainClass.getRenderManager();
[/java]

I then create the pre-view like such:

[java]
ViewPort vp1 = renderManager.createPreView(“View1”, cam1);
[/java]

And finally I attempt to remove it:
[java]
renderManager.removePreView(aforementioned_viewport);
[/java]

I can tell that it is not being removed properly for two reasons:
a) The framerates are much much lower than expected
b) On the stats view it shows frame buffers for (F) and (S)

While in other programs which accomplish this task correctly these two values are always 0.
I believe the problem is due to the renderManager being accessed through the appstate and not the class which extends simpleApplication because as I mentioned before I have programs where I use the renderManager in this way in the class that extends simpleApplication and everything runs as expected.
tl;dr I have to remove a preview in an apostate with renderManager yet it appears that the preview is not being removed.

Thanks for any help.

ViewPort vp1 = renderManager.createPreView(“View1″, cam1);
renderManager.removePreView(aforementioned_viewport);

vp1 versus aforementioned_viewport

…not enough code provided to help.

How you get the render manager does not matter. It’s the same object.

@pspeed said: ViewPort vp1 = renderManager.createPreView(“View1″, cam1); renderManager.removePreView(aforementioned_viewport);

vp1 versus aforementioned_viewport

…not enough code provided to help.

How you get the render manager does not matter. It’s the same object.

Hmm well that is all the code I can think of that would be relevant. I should have said that the viewport is removed and created in the update() method of the apostate; if that matters.

So I think the main problem is that I am removing the viewports the next frame because when I remove them during the iteration of the update loop where they are created it works fine (but this can’t be done due to corruption problems) if it helps anything here is some simplified code:
[java]
public void update(float tpf) {
for(int i = 0; i<QuadMesh.list.size(); i++){

			 if(quadQueue.size() &gt; i){	 
			    		QuadMesh curQ = quadQueue.get(i);
			    		curQ.childrenViewPorts[0].clearScenes();
			    		curQ.childrenViewPorts[1].clearScenes();
			    		curQ.childrenViewPorts[2].clearScenes();
			    		curQ.childrenViewPorts[3].clearScenes(); 
                                      // ViewPorts removed one frame later...each parent quad contains the viewports of it's children
			    		renderManager.removePreView(curQ.childrenViewPorts[0]);
			    		renderManager.removePreView(curQ.childrenViewPorts[1]);
			    		renderManager.removePreView(curQ.childrenViewPorts[2]);
			    		renderManager.removePreView(curQ.childrenViewPorts[3]);

			    		quadQueue.remove(i);
				} 
		    if(view &gt;= distance &amp;&amp; !q.hasChildren &amp;&amp; q.width &gt; (min_size)){					
			    	ViewPort vp1 = renderManager.createPreView("View1", c1);
			    	ViewPort vp2 = renderManager.createPreView("View2", c1);
			    	ViewPort vp3 = renderManager.createPreView("View3", c1);
			    	ViewPort vp4 = renderManager.createPreView("View4", c1);
			    	ViewPort[] childrenViewPorts = new ViewPort[4];
			    	childrenViewPorts[0] = vp1;
			    	childrenViewPorts[1] = vp2;
			    	childrenViewPorts[2] = vp3;
			    	childrenViewPorts[3] = vp4;
			    	q.childrenViewPorts = childrenViewPorts;
                                   //viewports are created
                                   //viewports are passed to Heightmap class where they are used to capture a full screen quad containing elevation            data
                                                //attach new quads and remove parent quad
					    rootNode.attachChild(q1.mesh);
					    rootNode.attachChild(q2.mesh);
					    rootNode.attachChild(q3.mesh);
					    rootNode.attachChild(q4.mesh);
					   
					    rootNode.detachChild(q.mesh); 
		    }   
		    } }

[/java]
If more code is needed I will be happy to oblige. Thank you.

What makes you believe that they aren’t getting removed?

I add and remove viewports all the time without issue… which is why I suggested showing us more than a handful of lines of code. Or you could put together a simple test case illustrating the problem… and then when there is no problem you could trace back to your app and see what’s different.

See, in your original example you showed creating a viewport and storing it in a local variable and then you should removing the viewport with “some completely different and fictitious” variable… which is what made me question that maybe we aren’t seeing enough to help. For example, what if that second variable is really pointing to the wrong viewport? We can’t see the code so we can’t help you.

All I can say with certainty is that removing a viewport will remove the viewport.

@pspeed said: What makes you believe that they aren't getting removed?

I add and remove viewports all the time without issue… which is why I suggested showing us more than a handful of lines of code. Or you could put together a simple test case illustrating the problem… and then when there is no problem you could trace back to your app and see what’s different.

I believe they are not getting removed because when I successfully remove them in another program or when I remove them in the same iteration of the update loop where they are created the FrameBuffers(F) and FrameBufffers(S) remain at zero. When I remove them in the code presented above these numbers continues to escalate and does not decrease.

I did what you said and made a test program and encountered the same issue.
Here is the relevant code for that program
[java]
public class Test extends AbstractAppState{
private SimpleApplication app;
private Geometry geo;
private AssetManager assetManager;
private TestObject to;
private Camera cam;
private Node rootNode;
@Override
public void initialize(AppStateManager stateManager, Application app) {
cam = new Camera(64,64);
cam.setLocation(new Vector3f (0,0,1));
cam.lookAt(new Vector3f(0,0,0), Vector3f.UNIT_Y);
super.initialize(stateManager, app);
this.app = (SimpleApplication)app;
this.assetManager = app.getAssetManager();
Quad q = new Quad(64,64);
geo = new Geometry(“Quad”,q);
Material mat = new Material(assetManager, “GroundFromAtmosphere.j3md”);
geo.setMaterial(mat);
ViewPort vp = app.getRenderManager().createPreView(“View1”, cam);
//to is a simple object that contains a geometry and a viewport
to = new TestObject(vp, geo);
this.rootNode = (Node)app.getViewPort().getScenes().get(0);
rootNode.attachChild(to.geo);
}

   @Override
    public void cleanup() {
      super.cleanup();

    }
 
    @Override
    public void setEnabled(boolean enabled) {
      super.setEnabled(enabled);
    }
 
    int c = 0;
    @Override
    public void update(float tpf) {
     if(c == 5001){
    	 System.out.println(5001);
    	 app.getRenderManager().removePreView( to.vp );
    	 c = 0;
     }else if(c == 5000){
    	 System.out.println(5000);
    	 ViewPort vp = app.getRenderManager().createPreView("View", cam);
    	 //getTexture() simply creates a texture with a framebuffer object and the provided viewport
    	 Texture2D tex = CreateTexture.getTexture(vp, assetManager, tpf);
    	 to.geo.getMaterial().setTexture("color", tex);
     }
     c++;
    }
 
}

[/java]

When c gets to 5001 the stats shown for FrameBuffers(F) and FrameBuffers(S) do not go back to zero so I believe the same “issue” is occurring with this program.
I am at a loss here so thank you for your time.

EDIT: I seem to have deleted this line:

[java]
to.vp = vp;
[/java]

located below the create of “vp”

@okelly4408 said: //getTexture() simply creates a texture with a framebuffer object and the provided viewport Texture2D tex = CreateTexture.getTexture(vp, assetManager, tpf);

So you create all these framebuffers and then never release them? I wonder if that’s why the framebuffer count keeps growing.

@pspeed said: So you create all these framebuffers and then never release them? I wonder if that's why the framebuffer count keeps growing.
And yet when I use the same method in another other program it doesn't grow. I wonder why.

[java]
Texture2D hm1 = getHeightMap1(viewPort1, itexSize, new Vector2f(quad.index1 * (scale * ftexSize), quad.index2 * (scale * ftexSize)), scale, quad);

public Texture2D getHeightMap1(ViewPort vp, float TEXTURE_SIZE, Vector2f index, float scale, QuadN currQuad){
Texture2D hm = new Texture2D(itexSize, itexSize, Format.RGBA32F);
FrameBuffer fbo = new FrameBuffer(itexSize, itexSize, 1);
fbo.setColorTexture(hm);
vp.setOutputFrameBuffer(fbo);

ge1 = new Geometry(“Mesh”,q);
ge1.setMaterial(noiseMaterial);
vp.attachScene(ge1);
if(vp.isEnabled()){
ge1.updateGeometricState();
}
return hm;
}

[/java]

Does the count grow indefinitely until the program crashes?

I mean, the code is only two clicks away and you can see that there isn’t much to it. Removing a view really just removes it from the list. Perhaps in your other test cases, the output frame buffer is never actually used so the native side stuff is never created before you let it disappear as garbage.

…where as it will take potentially much longer to collect the used buffers until you run low on memory.

@pspeed said: Does the count grow indefinitely until the program crashes?

I mean, the code is only two clicks away and you can see that there isn’t much to it. Removing a view really just removes it from the list. Perhaps in your other test cases, the output frame buffer is never actually used so the native side stuff is never created before you let it disappear as garbage.

…where as it will take potentially much longer to collect the used buffers until you run low on memory.


Yes, the count grows into the 100s until it levels out into single digit framerates. How would the output framebuffer never be used if I am able to render a texture with it? I think I just have to keep removing things until it functions correctly and then just work from there…
I appreciate all of your help, thanks.

The only code I was showing that “worked” was removing it on the same frame that it was being added, ie: it could never have been rendered to.

I have trouble commenting on code that I can’t see because the assumption is already that there is something wrong with the code or you wouldn’t be here. If you knew what was wrong with it then you also wouldn’t be here. Not to put too harsh a point on it but… Therefore, something must be wrong with it that you haven’t seen so we cannot trust your descriptions… only the code is fact.

This is one big reason we push to see code and test cases. “All of my code is fine but it’s still broken” doesn’t really help us because the statement is probably half wrong no matter how you look at it.

@pspeed said: The only code I was showing that "worked" was removing it on the same frame that it was being added, ie: it could never have been rendered to.

I have trouble commenting on code that I can’t see because the assumption is already that there is something wrong with the code or you wouldn’t be here. If you knew what was wrong with it then you also wouldn’t be here. Not to put too harsh a point on it but… Therefore, something must be wrong with it that you haven’t seen so we cannot trust your descriptions… only the code is fact.

This is one big reason we push to see code and test cases. “All of my code is fine but it’s still broken” doesn’t really help us because the statement is probably half wrong no matter how you look at it.


The code that showed that worked

@okelly4408 said: And yet when I use the same method in another other program it doesn't grow. I wonder why.

[java]
Texture2D hm1 = getHeightMap1(viewPort1, itexSize, new Vector2f(quad.index1 * (scale * ftexSize), quad.index2 * (scale * ftexSize)), scale, quad);

public Texture2D getHeightMap1(ViewPort vp, float TEXTURE_SIZE, Vector2f index, float scale, QuadN currQuad){
Texture2D hm = new Texture2D(itexSize, itexSize, Format.RGBA32F);
FrameBuffer fbo = new FrameBuffer(itexSize, itexSize, 1);
fbo.setColorTexture(hm);
vp.setOutputFrameBuffer(fbo);

ge1 = new Geometry(“Mesh”,q);
ge1.setMaterial(noiseMaterial);
vp.attachScene(ge1);
if(vp.isEnabled()){
ge1.updateGeometricState();
}
return hm;
}

[/java]


this code, has the viewport being removed the next frame not the frame that the texture was rendered.
I understand the issue with the code and the sharing of it…there’s just a lot of it so selecting the pieces that are relevant is tough. I can upload all of my code if that would help?
Also, something I just noticed, the framebuffer count in (F) and (S) grow to high levels yet they always return to around 20-24. I’m not too sure why…
Here you can take a look yourself (ignore graphical problems):

@pspeed said: The only code I was showing that "worked" was removing it on the same frame that it was being added, ie: it could never have been rendered to.

I have trouble commenting on code that I can’t see because the assumption is already that there is something wrong with the code or you wouldn’t be here. If you knew what was wrong with it then you also wouldn’t be here. Not to put too harsh a point on it but… Therefore, something must be wrong with it that you haven’t seen so we cannot trust your descriptions… only the code is fact.

This is one big reason we push to see code and test cases. “All of my code is fine but it’s still broken” doesn’t really help us because the statement is probably half wrong no matter how you look at it.


So I think I fixed it. Instead of accessing the viewport through the quad object I just get it with renderManager.getPreViews().get(n)
so I replaced this code:
[java]
if(quadQueue.size() > i){
QuadMesh curQ = quadQueue.get(i);
curQ.childrenViewPorts[0].clearScenes();
curQ.childrenViewPorts[1].clearScenes();
curQ.childrenViewPorts[2].clearScenes();
curQ.childrenViewPorts[3].clearScenes();
// ViewPorts removed one frame later…each parent quad contains the viewports of it’s children
renderManager.removePreView(curQ.childrenViewPorts[0]);
renderManager.removePreView(curQ.childrenViewPorts[1]);
renderManager.removePreView(curQ.childrenViewPorts[2]);
renderManager.removePreView(curQ.childrenViewPorts[3]);

                        quadQueue.remove(i);
                }

[/java]

With this:

[java]
if(app.getRenderManager().getPreViews().size() > i){
app.getRenderer().deleteFrameBuffer( app.getRenderManager().getPreViews().get(i).getOutputFrameBuffer());
app.getRenderManager().getPreViews().get(i).clearScenes();
app.getRenderManager().removePreView(app.getRenderManager().getPreViews().get(i));
}
[/java]
Which seems to work.
I should have tried this earlier.
Well, again, I appreciate the time you spent on this.

Yes, well now you are also deleting the framebuffer… which would explain why the frame buffers are getting removed.

Otherwise, if this fixed it then it is a sign that your quad is keeping track of the wrong ViewPort references which was one of my suspicions from my first response asking to see the code that tracks this. Though that’s also something that one trip in the debugger or a few printlns could also show.

Anyway, glad you got it working.