使用 C++ 在 Qt3D 中创建多个视口时出现问题
Problem creating multiple viewports in Qt3D using C++
我正在尝试使用 C++ 设置具有多个视口的 Qt3DWindow。根据 documentation and the provided QML example,我需要做的就是创建一个框架图,其中一个主要的 QViewport 对象分支成几个 RenderView。第一个 RenderView 包含一个 QClearBuffers 对象,其余的包含平铺视口及其相应的相机选择器。因此,如果我想要 N 个视口,我需要创建 N+1 个 RenderView。
但是,如果我遵循该过程,主视口会显示某种“默认”视图,它出现在 window 的顶部,跨越所有视口。我不知道这个视图来自哪里,因为它不对应任何相机。 Here 是下面发布的代码的输出。
我找到了一个解决方案,但我对它不太满意,因为它感觉像是某种 hack:而不是从主视口创建 all RenderViews 分支,我附上一个 子视口到 ClearBuffers 对象本身。因此,对于 N 个视口,我有 N 个渲染视图而不是 N+1 个。我不太了解框架图的内部结构,所以我想知道这个解决方案是否只是从强迫症的角度来看是错误的,或者它实际上会在某些时候适得其反。
这是一个最小的示例,其中两个视口共享默认相机。如果我从 clearBuffers
而不是 mainViewPort
创建 viewPort1
或 viewPort2
分支,一切都按预期工作:
#include <QGuiApplication>
#include <Qt3DCore/QTransform>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QTorusMesh>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/QViewport>
#include <Qt3DRender/QClearBuffers>
#include <Qt3DRender/QCameraSelector>
Qt3DCore::QEntity *createScene()
{
// Root entity
auto rootEntity = new Qt3DCore::QEntity;
// Torus
auto torusEntity = new Qt3DCore::QEntity(rootEntity);
auto torusMesh = new Qt3DExtras::QTorusMesh;
torusMesh->setRadius(0.5f);
torusMesh->setMinorRadius(0.1f);
torusMesh->setRings(100);
torusMesh->setSlices(20);
auto torusTransform = new Qt3DCore::QTransform;
torusTransform->setScale3D(QVector3D(1.2f, 1.f, 0.8f));
torusTransform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), 45.0f));
torusEntity->addComponent(torusMesh);
torusEntity->addComponent(torusTransform);
torusEntity->addComponent(new Qt3DExtras::QPhongMaterial(rootEntity));
return rootEntity;
}
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
Qt3DExtras::Qt3DWindow view;
// Set camera transform
view.camera()->setPosition(QVector3D(0, 4.0f, 0));
view.camera()->setViewCenter(QVector3D(0, 0, 0));
// Framegraph root node
auto surfaceSelector = new Qt3DRender::QRenderSurfaceSelector();
auto mainViewPort = new Qt3DRender::QViewport(surfaceSelector);
// First RenderView: clear buffers
auto clearBuffers = new Qt3DRender::QClearBuffers(mainViewPort);
clearBuffers->setBuffers(Qt3DRender::QClearBuffers::ColorDepthBuffer);
clearBuffers->setClearColor(Qt::white);
// Second RenderView: left viewport
auto viewPort1 = new Qt3DRender::QViewport(mainViewPort);
viewPort1->setNormalizedRect(QRectF(0.0f, 0.0f, 0.5f, 1.0f));
auto cameraSelector1 = new Qt3DRender::QCameraSelector(viewPort1);
cameraSelector1->setCamera(view.camera());
// Third RenderView: right viewport
auto viewPort2 = new Qt3DRender::QViewport(mainViewPort);
viewPort2->setNormalizedRect(QRectF(0.5f, 0.0f, 0.5f, 1.0f));
auto cameraSelector2= new Qt3DRender::QCameraSelector(viewPort2);
cameraSelector2->setCamera(view.camera());
// Add framegraph and scenegraph to viewer
view.setActiveFrameGraph(surfaceSelector);
view.setRootEntity(createScene());
view.show();
return app.exec();
}
我仍然认为它在视口上绘制是一种错误,但您可以在框架图中放置一个 QNoDraw
节点作为 QClearBuffers
:
的子节点
auto noDraw = new Qt3DRender::QNoDraw(clearBuffers);
这解决了渲染问题。
我正在尝试使用 C++ 设置具有多个视口的 Qt3DWindow。根据 documentation and the provided QML example,我需要做的就是创建一个框架图,其中一个主要的 QViewport 对象分支成几个 RenderView。第一个 RenderView 包含一个 QClearBuffers 对象,其余的包含平铺视口及其相应的相机选择器。因此,如果我想要 N 个视口,我需要创建 N+1 个 RenderView。
但是,如果我遵循该过程,主视口会显示某种“默认”视图,它出现在 window 的顶部,跨越所有视口。我不知道这个视图来自哪里,因为它不对应任何相机。 Here 是下面发布的代码的输出。
我找到了一个解决方案,但我对它不太满意,因为它感觉像是某种 hack:而不是从主视口创建 all RenderViews 分支,我附上一个 子视口到 ClearBuffers 对象本身。因此,对于 N 个视口,我有 N 个渲染视图而不是 N+1 个。我不太了解框架图的内部结构,所以我想知道这个解决方案是否只是从强迫症的角度来看是错误的,或者它实际上会在某些时候适得其反。
这是一个最小的示例,其中两个视口共享默认相机。如果我从 clearBuffers
而不是 mainViewPort
创建 viewPort1
或 viewPort2
分支,一切都按预期工作:
#include <QGuiApplication>
#include <Qt3DCore/QTransform>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QTorusMesh>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/QViewport>
#include <Qt3DRender/QClearBuffers>
#include <Qt3DRender/QCameraSelector>
Qt3DCore::QEntity *createScene()
{
// Root entity
auto rootEntity = new Qt3DCore::QEntity;
// Torus
auto torusEntity = new Qt3DCore::QEntity(rootEntity);
auto torusMesh = new Qt3DExtras::QTorusMesh;
torusMesh->setRadius(0.5f);
torusMesh->setMinorRadius(0.1f);
torusMesh->setRings(100);
torusMesh->setSlices(20);
auto torusTransform = new Qt3DCore::QTransform;
torusTransform->setScale3D(QVector3D(1.2f, 1.f, 0.8f));
torusTransform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), 45.0f));
torusEntity->addComponent(torusMesh);
torusEntity->addComponent(torusTransform);
torusEntity->addComponent(new Qt3DExtras::QPhongMaterial(rootEntity));
return rootEntity;
}
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
Qt3DExtras::Qt3DWindow view;
// Set camera transform
view.camera()->setPosition(QVector3D(0, 4.0f, 0));
view.camera()->setViewCenter(QVector3D(0, 0, 0));
// Framegraph root node
auto surfaceSelector = new Qt3DRender::QRenderSurfaceSelector();
auto mainViewPort = new Qt3DRender::QViewport(surfaceSelector);
// First RenderView: clear buffers
auto clearBuffers = new Qt3DRender::QClearBuffers(mainViewPort);
clearBuffers->setBuffers(Qt3DRender::QClearBuffers::ColorDepthBuffer);
clearBuffers->setClearColor(Qt::white);
// Second RenderView: left viewport
auto viewPort1 = new Qt3DRender::QViewport(mainViewPort);
viewPort1->setNormalizedRect(QRectF(0.0f, 0.0f, 0.5f, 1.0f));
auto cameraSelector1 = new Qt3DRender::QCameraSelector(viewPort1);
cameraSelector1->setCamera(view.camera());
// Third RenderView: right viewport
auto viewPort2 = new Qt3DRender::QViewport(mainViewPort);
viewPort2->setNormalizedRect(QRectF(0.5f, 0.0f, 0.5f, 1.0f));
auto cameraSelector2= new Qt3DRender::QCameraSelector(viewPort2);
cameraSelector2->setCamera(view.camera());
// Add framegraph and scenegraph to viewer
view.setActiveFrameGraph(surfaceSelector);
view.setRootEntity(createScene());
view.show();
return app.exec();
}
我仍然认为它在视口上绘制是一种错误,但您可以在框架图中放置一个 QNoDraw
节点作为 QClearBuffers
:
auto noDraw = new Qt3DRender::QNoDraw(clearBuffers);
这解决了渲染问题。