Changing the background image work at random times only

Hello there!

I am programming a really simple program in panda3d (python) and I am facing some pretty strange issues.

At some point of my code, I need to change the image that’s being displayed in the background. For that purpose, I’m calling the following function:

def loadBackground(self, imagepath):
        ''' Load a background image behind the models '''

        # We use a special trick of Panda3D: by default we have two 2D renderers: render2d and render2dp, the two being equivalent. We can then use render2d for front rendering (like modelName), and render2dp for background rendering.
        self.background = OnscreenImage(parent=render2dp, image=imagepath) # Load an image object
        base.cam2dp.node().getDisplayRegion(0).setSort(-20) # Force the rendering to render the background image first (so that it will be put to the bottom of the scene since other models will be necessarily drawn on top)

Which I obtained from this post

The function itself is called from this other function:

def changeWindow(self):
        
        self.loadBackground("img/ejes/"+self.ejes[self.lap]+".jpg")
        
        props = WindowProperties() 
        props.setSize(self.w[self.lap], self.h[self.lap]) 
        self.win.requestProperties(props)
        self.cam.set_y(self.distcam[self.lap])

The problem: it only works sometimes. Without changing anything in the code. Sometimes it changes the image, sometimes it doesn’t. It seems to be completely random. In the main loop, I need to change the background image 3 times. Sometimes it works well both the 3 times. Sometimes none. So strange.

Any help will be greatly appreciated. I am completely lost with this issue.

Thanks in advance!

I’m guessing that the problem is that you’re not actually removing the current OnscreenImage when you instate a new one. As a result you end up with two (or more) OnscreenImages located at the same position, z-fighting to be rendered.

I’d suggest that, instead of creating a new OnscreenImage with each new call to “loadBackground”, you create a single Onscreen image prior to the first use of that method and then, in said method, change the image shown by that single OnscreenImage.

By the way, you could perhaps create a backdrop image without messing with your display regions if you parent your OnscreenImage to the main camera (instead of render2d), place it an appropriate distance away, and then put it into the “background” culling-bin.

This might call for a bit more work in keeping its size the same, admittedly.

1 Like

Whoa!! Thank you very much, that was it!!

In case anyone else needs the code anytime, here’s my final implementation:

def __init__(self):

        # Stuff
        self.osiBg = OnscreenImage(parent=render2dp, image="img/ejes/"+self.ejes[self.lap]+".jpg")
        self.background =  self.osiBg
        base.cam2dp.node().getDisplayRegion(0).setSort(-20)
        # Stuff


def loadBackground(self, imagepath):
        self.osiBg.configure(image=imagepath)

You broke the record of fastest problem solving in a forum! lol

1 Like

Hahah, I happened to be around! And it’s my pleasure. :slight_smile:

1 Like