I recently posted about an issue that I had with nested DirectScrolledFrames flickering. Well, giving it more thought, I decided to attempt re-implementing what I had in mind with simple DirectFrames instead. I did this, and it worked fairly well, I think–and the implementation feels less clunky, and perhaps has fewer unexpected side-effects, than doing this with DirectScrolledFrames.
However, I do still want the various regions of this new class to be clipped, as they were when they were the canvases DirectScrolledFrames.
Hunting around a little, it seems that DirectScrolledFrame may use a “ScissorEffect” to implement its clipping. I tried using one myself–and it works!
Except that the frames in question flicker horribly. :/
Based on some testing, it looks like the problem may have to do with the way that I’m going about updating the ScissorEffect, via overriding “DirectGuiWidget.setFrameSize”: If I simply create two nested frames and change their frame-sizes over time, updating their ScissorEffects as I do, I see no flickering. If instead I create a simple class that overrides “setFrameSize” and applies the ScissorEffect there, I see flickering.
What might be the problem here?
Here is a simple test-program that demonstrates the issue (on my machine, at least). You should see two nested squares. The outer one should grow–and flicker as it does.
from direct.gui.DirectGui import DirectFrame
from panda3d.core import ScissorEffect, Vec3
from direct.task import Task
from direct.showbase import ShowBase as showBase
class Mew(DirectFrame):
def __init__(self, parent = None, **kwargs):
optiondefs = (
('frameSize', (-0.5, 0.5, -0.5, 0.5), self.setFrameSize),
)
self.defineoptions(kwargs, optiondefs)
DirectFrame.__init__(self, parent)
self.initialiseoptions(Mew)
def setFrameSize(self, fClearFrame = 0):
frameSize = self["frameSize"]
self.clearEffect(ScissorEffect)
self.setScissor(Vec3(frameSize[0], 0, frameSize[2]),
Vec3(frameSize[1], 0, frameSize[2]),
Vec3(frameSize[0], 0, frameSize[3]),
Vec3(frameSize[1], 0, frameSize[3]),
)
DirectFrame.setFrameSize(self, fClearFrame)
class Game(showBase.ShowBase):
def __init__(self):
showBase.ShowBase.__init__(self)
self.accept("escape", self.userExit)
self.frame = Mew(frameColor = (0, 0.2, 1, 1))
self.frame2 = Mew(parent = self.frame, frameColor = (0, 1, 0, 1), frameSize = (-0.1, 0.1, -0.1, 0.1))
self.updateTask = taskMgr.add(self.update, "update")
def update(self, task):
dt = globalClock.getDt()
frameSize = self.frame["frameSize"]
frameSize = (frameSize[0] - 0.1*dt, frameSize[1] + 0.1*dt, frameSize[2] - 0.1*dt, frameSize[3] + 0.1*dt)
self.frame["frameSize"] = frameSize
return Task.cont
app = Game()
app.run()