[Interest] [QT3D] How Do I render multiple QEntities in different QViewports in C++?

Sean Harmer sean.harmer at kdab.com
Sat Apr 30 19:55:35 CEST 2016


Hi,

There's two things you need to consider:

1) The scene graph - the Entities that you wish to draw.
2) The framegraph - specifies the algorithm used to draw the scene graph

I assume from your screenshot that you are more or less happy with defining 
QEntity's to construct your scene graph. If you wish some entities to be drawn 
in one part of the window (viewport) and the others in another viewport then 
we need some way of saying "select this set of entities but not that set".

One way of doing this is by using a QLayer component attached to your entities 
that says which layer that entity is part of. This is just like layers 
photoshop, gimp, blender etc. Create a QLayer, give it a name, and aggregate 
it onto your QEntity as you do the other components (mesh, transform and 
material).

Doing this doesn't change anything in the rendering on it's own. To affect the 
change we also need to modify the framegraph. To do this, make sure the 
concept of the framegraph is clear in your mind. Have a read of:

https://www.kdab.com/qt3d-2-0-framegraph/

Each leaf node, corresponds to a portion of your overall scene. To keep things 
simple, lets only consider the viewports and layer filters you will need. You 
will need other things in the framegraph too (rendersurfaceselector (if using 
5.7), camera selector, technique selector etc). The parts of the framegraph 
concerned with viewports and layers will look something like this:

Root (e.g. TechniqueSelector)
|- Viewport [left half of window]
    |- LayerFilter [names="layer1"] (*)
|- Viewport [right half of window]
    |- LayerFilter [names="layer2"] (**)

Where:

(*) <-- draws entities on "layer1" in left viewport
(**) <-- draws entities on "layer2" in right viewport

If you then want to use different cameras in the different viewports then you 
can include a QCameraSelector node in each sub-tree.

Root (e.g. TechniqueSelector)
|- Viewport [left half of window]
    |- CameraSelector [camera1]
        |- LayerFilter [names="layer1"] (*)
|- Viewport [right half of window]
    |- CameraSelector [camera2]
        |- LayerFilter [names="layer2"] (**)

Where:

(*) <-- draws entities on "layer1" in left viewport using "camera1"
(**) <-- draws entities on "layer2" in right viewport using "camera2"

Hopefully that makes sense. In the future, I hope we can provide tooling and 
perhaps higher level ways of building custom framegraphs. The framegraph is 
hugely powerful as it totally allows changing the rendering algorithm at 
runtime without having to touch low level C++ graphics code. However, it is a 
bit tricky to get to grips with at first.

Cheers,

Sean

On Thursday 28 April 2016 13:34:58 Pierre Chicoine wrote:
> Dear Sirs
> 
> First: Thank you for Qt3d. The KDAB people are heroes in my book.
> 
> I have two problems in C++ Qt3D.
> 
> 1. I am having a difficult time figuring out how to render QEntities into
> separate QViewports. All my 3d objects draw to the first QViewport, the
> rest are black. I have read all your articles and comments everywhere on
> the Internet that I can find and I am basically confused.
> 
> Is there a c++ example that would show multiple viewports with distinct
> separate QEntities? I can't seem to duplicate The QML example multiviewport
> in my code. What classes would get me there?
> 
> 2. Also I'm also confused about QNodes and QEntitys and their
> relationships. Maybe it's the use of Qt3d version 1 that is messing me up .
> I use to have a scene node and all the entities would hang off of one scene
> node for each scene. But that doesn't seem to work in version 2. Or do I
> use the  addComponent on a QFrameGraph instead of a node? Or do I hang
> Entities off of a viewport?
> 
> Attached is a pic of my progress which draws all the objects into the same
> viewport. The window tiles 2 windows properly but I only draw to one
> viewport, the second or third stay black. The code here is what I repeat in
> each scene class. It's a bit of a mess thrown together to test Qt3D classes
> because I don't understand the relationships between all the Qt3D classes
> used to place objects in a viewport.
> 
> 
>  Qt3DCore::QCamera *cameraEntity = new Qt3DCore::QCamera( pParentNode);
> 
>  cameraEntity->setObjectName(QStringLiteral("cameraEntity"));
> 
>  cameraEntity->setProjectionType(Qt3DCore::QCameraLens::PerspectiveProjectio
> n);
> 
>  cameraEntity->setAspectRatio(1024 / 768);
> 
>  cameraEntity->setUpVector(QVector3D(0.0f, 1.0f, 0.0f));
> 
>  cameraEntity->setViewCenter(QVector3D(0.0f, 3.5f, 0.0f));
> 
>  //cameraEntity->lens()->setPerspectiveProjection(60.0f, 16.0f/9.0f,
> 0.1f, 1000.0f);
> 
> 
>  if(pScenesSet) // if it's a scene then we want to set it where they want it
> 
>   cameraEntity->setPosition(QVector3D(pScenesSet->CamXPos - 20,
> pScenesSet->CamYPos + 80, pScenesSet->CamZPos));
> 
>  else // so it's a schematic
> 
>   cameraEntity->setPosition(QVector3D(-20, 65, 180));
> 
> 
>  theApp->input->setCamera(cameraEntity); // not sure about this
> relationship??
> 
> 
>  // FrameGraph
> 
>  pQFrameGraph = new Qt3DRender::QFrameGraph();
> 
>  pQTechniqueFilter = new Qt3DRender::QTechniqueFilter();
> 
>  pQViewport = new Qt3DRender::QViewport(pQTechniqueFilter);
> 
>  Qt3DRender::QClearBuffer *clearBuffer = new
> Qt3DRender::QClearBuffer(pQViewport);
> 
>  Qt3DRender::QCameraSelector *cameraSelector = new
> Qt3DRender::QCameraSelector(clearBuffer);
> 
>  Qt3DRender::QRenderPassFilter * pQRenderPassFilter = new
> Qt3DRender::QRenderPassFilter(cameraSelector);
> 
>  Qt3DRender::QRenderTargetSelector * m_gBufferTargetSelector = new
> Qt3DRender::QRenderTargetSelector(pQTechniqueFilter);
> 
> //  Qt3DRender::QLayerFilter * m_sceneFilter = new
> Qt3DRender::QLayerFilter(theApp->pCThreeDWindow);
> 
>  // TechiqueFilter and renderPassFilter are not implement yet
> 
>  pQViewport->setRect(QRectF(0, 0, 1, 1));
> 
>  clearBuffer->setBuffers(Qt3DRender::QClearBuffer::ColorDepthBuffer);
> 
>  pQFrameGraph->setActiveFrameGraph(pQTechniqueFilter);
> 
>  // Setting the pQFrameGraph
> 
> 
>  // I add a framegraph component to: class CThreeDWindow : public
> Qt3DCore::QEntity
> 
>  // public:
> 
>  // CThreeDWindow(Qt3DCore::QNode *parent = 0);
> 
> 
>  theApp->pCThreeDWindow->addComponent(pQFrameGraph);
> 
> 
>  if(pScenesSet) // if it's a scene then we want to set it where they want it
> 
>   pQViewport->setClearColor(QColor(pScenesSet->BackRed,
> pScenesSet->BackGreen, pScenesSet->BackBlue));
> 
>  else
> 
>   pQViewport->setClearColor(QColor(0, 0, 0));
> 
> 
>  cameraSelector->setCamera(cameraEntity);
> 
>  //m_gBufferTargetSelector->setTarget(m_sceneFilter);
> 
> 
> 
> Any help would be appreciated.
> 
> Thank you

--
Dr Sean Harmer | sean.harmer at kdab.com | Managing Director UK
Klarälvdalens Datakonsult AB, a KDAB Group company
Tel. UK +44 (0)1625 809908, Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-independent software solutions



More information about the Interest mailing list