Shadows and buffers

Hello, I have a problem when I try to use shadows and buffers contemporaneously. I have the following code (here there are code and assets if you want to reproduce):

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import Spotlight

class World( DirectObject ):

  def __init__( self ):
    base.disableMouse()
    camera.setPos( 0, -20, 2 )
    self.accept( 'mouse1', self.destroyAndCreate )
    render.setShaderAuto()
    self.create()

  def create( self ):
    self.rootNode = render.attachNewNode( 'rootNode' )

    self.light = self.rootNode.attachNewNode( Spotlight( 'Spot' ) )
    self.lightNode = self.light.node()
    self.lightNode.setShadowCaster( True, 1024, 1024 )
    self.light.setPos( -20, -20, 20 )
    self.light.lookAt( 0,0,0 )
    self.rootNode.setLight( self.light )

    loader.loadModel( 'teapot' ).reparentTo( self.rootNode )

    self.buffer = base.win.makeTextureBuffer( 'Buffer', 512, 512 )
    self.camNP = base.makeCamera( self.buffer )
    self.camNP.reparentTo( self.rootNode )

  def destroy( self ):
    self.lightNode.setShadowCaster( False )
    self.rootNode.removeNode()
    base.graphicsEngine.removeWindow( self.buffer )

  def destroyAndCreate( self ):
    self.destroy()
    self.create()

w = World()
run()

This is a simple program which shows the problem. This shows a teapot and when the user clicks it should reload the scene. The problem is that at the beginning the illumination works, but, after the click, the teapot becomes completely black. My objective is to get the illumination working also after the destruction and recreation of the scene.

Another strange thing is that, when I click, on the console it prints the character d.

Note that if I remove the shadows or the buffer (the buffer in this example is useless, but in my larger application I need it) it works.

Where am I wrong? Thank you!

Hello, excuse me if I come back to this, but I’m still stuck and I can’t progress with my entire game. :cry: I’m “investigating” the problem, and really I can’t see a solution.

I’ve enabled the view of the buffers with:

base.bufferViewer.enable( 1 )

and the behaviour is strange. At the beginning there are two buffers: the first one is completely gray (this should be the texture buffer), and the second one is white (this should be the shadows one). When I destroy and recreate the scene, I have three buffers: one of them is gray, the others are white. It seems that I can’t remove the shadow buffer. But this isn’t a leak: if I destroy the scene again, I’ve three buffers again. I can’t explain this myself. :cry:

I don’t know if this is related to my main problem, but at least is another information, potentially useful. Can anyone see what’s happening? Very thanks!

This is a bit of a bug in terms that disabling the shadowCaster and removing the light from the scenegraph doesn’t destroy the backbuffer that the light is rendering to.

The really easy work around is not not destroy the light buffer after it’s been created.

For instance if you put a

    for v in base.graphicsEngine.getWindows():
        print v.getName()

in your create call you’ll see multiple “Spot” buffers getting created.

If truly want to disable spot light buffers your going to have to dive into shaders a bit and manage your own shadow map buffers.

Thank you Bei! My conviction was that I was doing some mistakes during the “buffers-cleaning” phase. Ok, I’ll maintain the light buffer: no problem about this, I only needed to know if this is the right approach. Thanks!