Qt3D Window 和两层、视口、图层过滤器等

Qt3D Window and two layers, viewports, layerfilters, etc

我想编写一个 Qt3DWindow,其中有两个 QLayer-s、QLayerFilter-s、QViewport-s 等。我需要这个,因为我想以通常的方式呈现 QViewport 1 中的实体,并且 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)

如果我理解正确,您希望两个视口相互重叠绘制(即不在左右两边),而第一个绘制所有普通实体,第二个绘制始终可见的实体。

首先,我认为您不需要视口。如果存在 none,Qt 默认为矩形 (0, 0, 1, 1),但我对此不确定。

实际问题是这一行

self.clearBuffers_2.setBuffers(Qt3DRender.QClearBuffers.AllBuffers)

因为在这里您也删除了颜色缓冲区,这会删除第一个视口渲染的所有内容。尝试将其设置为 Qt3DRender.QClearBuffers.DepthBuffer。这只会清除您的深度 buffer.The 第二个视口的实体将绘制在第一个视口的渲染之上。