There is a known bug with the FilterManager where the scene gets messed-up after resizing a window, now to counter this I’m calling FilterManager.cleanup() and setup the filters anew after every ‘window-event’. It works but it fires when the window is moved, when the window loses or gains focus, when it’s minimized or maximized (to my surprise when the window is closed and the program terminated) and also when it is resized. I only care for the later, because the shaders need to be compiled and there’s some spam in the terminal when that happens (with glsl)…and a bit of framelag.
Is there a way to tell what the last ‘window-event’ was? I couldn’t find anything about it in the docs. I’m looking for something more elegant then storing the window size and checking if it changed.
No, there isn’t. The right thing to do is compare the buffer size to the window size every time window-event is called - since you want them to match up. You don’t need to store the old window size yourself.
I match the buffer size to the window (and also supply a shader input with that size - it’s for fxaa, but not important), so that’s good and ok. But I also destroy and recreate the whole thing when the window is not resized but just moved - that’s what I wanted to avoid.
I think I need to store the old size just to compare it with the new size. If the size is the same I don’t need to recreate the buffer, the event that was triggered must have been a move, mini/maximize or focus event not a window-resize-event. Or am I missing something again?
The goal is to make the buffer size match up with the window size, right? So in window-event, can’t you compare the two, see if they don’t match, and if so, recreate the buffer with the same size as the window size?
Alternatively, have you tried the GraphicsPipe.BF_resizable flag?
Yes… and, then no.
The goal was to make the buffer size match up with the window size, and that works. But as a side effect the buffer was recreated on OTHER window-events (like when the window was moved BUT NOT RESIZED) I wanted to avoid this unnecessary buffer recreating in an elegant way.
It’s a small thing, not that important
Got it working like this:
from panda3d.core import *
import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from direct.filter.FilterManager import FilterManager
class Thing (DirectObject):
def __init__(self):
self.winsize=[0,0]
self.fxaaManager=FilterManager(base.win, base.cam)
self.accept( 'window-event', self.windowEventHandler)
def makeFXAA(self, manager=None, span_max=8.0, reduce_mul=8.0, subpixel_shift=4.0):
wp=base.win.getProperties()
winX = wp.getXSize()
winY = wp.getYSize()
tex = Texture()
if manager==None:
manager = FilterManager(base.win, base.cam)
quad = manager.renderSceneInto(colortex=tex)
quad.setShader(Shader.load(Shader.SLGLSL, "shaders/fxaa_v.glsl", "shaders/fxaa_f.glsl"))
quad.setShaderInput("tex0", tex)
quad.setShaderInput("rt_w",winX)
quad.setShaderInput("rt_h",winY)
quad.setShaderInput("FXAA_SPAN_MAX" , span_max)
quad.setShaderInput("FXAA_REDUCE_MUL", 1.0/reduce_mul)
quad.setShaderInput("FXAA_SUBPIX_SHIFT", 1.0/subpixel_shift)
return manager
def windowEventHandler( self, window=None ):
if window is not None: # window is none if panda3d is not started
wp=window.getProperties()
newsize=[wp.getXSize(),wp.getYSize()]
if self.winsize!=newsize:
#resizing the window breaks the filter manager, so I just make a new one
self.fxaaManager.cleanup()
self.fxaaManager=self.makeFXAA(self.fxaaManager)
self.winsize=newsize
app=Thing()
run()