How to clean up render-to-texture?

There is this snippet in the manual for creating a render-to-texture:

mybuffer = base.win.makeTextureBuffer("My Buffer", 512, 512)
mytexture = mybuffer.getTexture()
mybuffer.setSort(-100)
mycamera = base.makeCamera(mybuffer)
myscene = NodePath("My Scene")
mycamera.node().setScene(myscene)

Then I can assign mytexture to geometry as desired, e.g.

mymodel = loader.loadModel("...")
mymodel.setTexture(mytexture)

Once I have no more use for mytexture and nothing is currently using it (e.g. I did mymodel.removeNode()), what should I do to completely clean up the particular render-to-texture setup behind it?

Use base.closeWindow to close the buffer.

Unfortunatelly I didn’t get that. If I try something like base.closeWindow(mybuffer) I get the error:

...
  File "/usr/share/panda3d/direct/showbase/ShowBase.py", line 650, in closeWindow
    self.winList.remove(win)
ValueError: list.remove(x): x not in list

On the forum I found references to base.closeWindow only in the context of quitting the game cleanly.

Am I perhaps doing something conceptually wrong here? I wanted to have a render-to-texture created whenever a certain effect is triggered, and destroyed when the effect is done. There may be zero, one or several of these effects running at any given moment.

Sorry, the correct line is this:

base.graphicsEngine.removeWindow(mybuffer)

You can find examples of temporary render-to-texture set-ups in direct/(src/)showbase/ShowBase.py, for instance in the method saveCubeMap.

That works, thanks.

On the other hand… I’ve now tried this in one case where so far I reused one and the same buffer, and after a number of creations/destructions, the frame rate starts to drop off. While when I try it in a standalone toy case, creations/destructions go on indefinitely without any drop in frame rate. Is it possible that the buffer does not get removed due to some active reference, and how could I check that (like getting a list of existing buffers)?

I’ve run into this issue before, too, where a buffer seems to be hanging around longer than it should. It’s possible to track it down using Python’s existing reference-count debugging tools, but it’s tedious.

It might be easier just to re-use the same buffer every time, instead of closing and reopening buffers.

David

This might be of interest, its a queueing based texture renderer that reuses buffers: https://github.com/Craig-Macomber/Panda3D-Terrain-System/blob/master/textureRenderer.py

I’ve used it to render thousands of textures in a run, so I’m pretty sure it doesn’t leak, though I haven’t stress tested it recently.