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 和两层、视口、层过滤器等的主要内容,如果未能解决你的问题,请参考以下文章

PADS布两层板

C ++中的Qt3d输入

Qt3d用c ++输入

QT3D Multiview - 小部件中的单一视图

多线程设计模式:第五篇 - Future模式和两阶段终止模式

神经网络(无隐藏层)与逻辑回归?