Qt3D Window 和两层、视口、层过滤器等
Posted
技术标签:
【中文标题】Qt3D Window 和两层、视口、层过滤器等【英文标题】:Qt3D Window and two layers, viewports, layerfilters, etc 【发布时间】:2018-09-28 12:33:02 【问题描述】:我想编写一个Qt3DWindow
,我将有两个QLayer
-s、QLayerFilter
-s、QViewport
-s 等。我需要这个,因为我想在QViewport
@ 中呈现实体987654326@ 以通常的方式和 QViewport
2
中的实体始终可见(即使它们实际上在实体 1
后面)。
这是我的代码:
class Window(Qt3DExtras.Qt3DWindow):
def __init__(self):
super().__init__()
self.root_entity = Qt3DCore.QEntity()
self.entity_1 = Qt3DCore.QEntity(self.root_entity)
self.entity_2 = Qt3DCore.QEntity(self.root_entity)
self.setRootEntity(self.root_entity)
# some other code
self.surselector = Qt3DRender.QRenderSurfaceSelector()
self.surselector.setSurface(self)
# Viewport 1
self.viewport_1 = Qt3DRender.QViewport(self.surselector)
self.layerfilter_1 = Qt3DRender.QLayerFilter(self.viewport_1)
self.layer_1 = Qt3DRender.QLayer(self.entity_1)
self.entity_1.addComponent(self.layer_1)
self.layer_1.setRecursive(True)
self.layerfilter_1.addLayer(self.layer_1)
self.cameraSelector_1 = Qt3DRender.QCameraSelector(self.layerfilter_1)
self.clearBuffers_1 = Qt3DRender.QClearBuffers(self.cameraSelector_1)
self.cameraSelector_1.setCamera(self.camera())
self.clearBuffers_1.setBuffers(Qt3DRender.QClearBuffers.AllBuffers)
# Viewport 2
self.viewport_2 = Qt3DRender.QViewport(self.surselector)
self.layerfilter_2 = Qt3DRender.QLayerFilter(self.viewport_2)
self.layer_2 = Qt3DRender.QLayer(self.entity_2)
self.entity_2.addComponent(self.layer_2)
self.layer_2.setRecursive(True)
self.layerfilter_2.addLayer(self.layer_2)
self.cameraSelector_2 = Qt3DRender.QCameraSelector(self.layerfilter_2)
self.clearBuffers_2 = Qt3DRender.QClearBuffers(self.cameraSelector_2)
self.cameraSelector_2.setCamera(self.camera())
# The line below causes that no entity appears
self.clearBuffers_2.setBuffers(Qt3DRender.QClearBuffers.AllBuffers)
# The code below is what make viewport 2 / layer 2 / layerfilter 2 different from view port 1 / etc.
self.rendstate_2 = Qt3DRender.QRenderStateSet(self.clearBuffers_2)
self.rendstate_2.setParent(self.clearBuffers_2)
depth = Qt3DRender.QDepthTest()
depth.setDepthFunction(Qt3DRender.QDepthTest.LessOrEqual)
self.rendstate_2.addRenderState(depth)
self.setActiveFrameGraph(self.surselector)
【问题讨论】:
请在代码上方更清楚地说明您的问题,以便人们轻松找到它。现在问你的问题:你是在某处设置视口的矩形吗?我在代码中看不到它。默认矩形是(0, 0, 1, 1)
,即整个屏幕,所以我假设第二个分支会擦除所有内容。
我还将清除缓冲区向上移动到视口下方,以便即使在其中一个分支中没有要渲染的对象时它们也会被清除(可能不是这种情况,因为您正在渲染相同的对象两次,但仍然如此)。
不,我没有设置 viewports 的矩形,因为我使用的是默认矩形 - 正如你提到的 QRectF(0, 0, 1, 1)
。我希望两个 viewports' 都使用整个屏幕。但我只能看到第二个 viewport 和第二个 entity。
但这没有意义。你想让它们相互叠加吗?如果您想让它们彼此相邻(我假设),那么您必须将矩形设置为(0, 0, 0.5, 1)
和(0.5, 0, 1, 1)
之类的东西。这样左视口覆盖左半边,右视口覆盖右半边。当然你只看到第二个实体!因为第二个视口的分支有一个清晰的缓冲区节点,并且覆盖了整个屏幕! IE。它会删除所有内容,然后呈现自己。
是的,我希望它们相互叠加。所以我希望第二个实体被绘制在第一个实体之上。
【参考方案1】:
如果我理解正确,您希望两个视口相互重叠(即不在左右半边),而第一个绘制所有正常实体,第二个绘制始终可见的实体。
首先,我认为您不需要视口。如果不存在,Qt 会将其默认为矩形 (0, 0, 1, 1)
,但我不确定。
实际问题是这一行
self.clearBuffers_2.setBuffers(Qt3DRender.QClearBuffers.AllBuffers)
因为在这里您也删除了颜色缓冲区,这会删除第一个视口渲染的所有内容。尝试将其设置为Qt3DRender.QClearBuffers.DepthBuffer
。这只会清除您的深度缓冲区。第二个视口的实体将绘制在第一个视口的渲染之上。
【讨论】:
谢谢!是的,Qt 默认 viewport 为矩形QRectF(0, 0, 1, 1)
。使用相同的 viewport 时,它的工作原理相同 - 第二个实体始终可见。
但现在我有另一个问题:当我翻译第二个实体的实体时,第一个实体会隐藏然后不时再次显示(例如闪烁)。
Woops 对你的问题感到困惑一秒钟,打算在这里发表评论:我想你应该发布一个关于这个问题的新问题,因为原来的问题已经解决了。不幸的是,我不知道这种闪烁是从哪里来的,但我在特定环境中也经历过。
目前我无法为这个 blinking 问题创建一个最小示例。 @Florian Blume:您在什么样的环境中遇到过这个问题?以上是关于Qt3D Window 和两层、视口、层过滤器等的主要内容,如果未能解决你的问题,请参考以下文章