Qt3D : How to display text on the 3D Window screen? - c++

How does one display text on the 3D window screen? I know they a text2D entity module, but thats for displaying text in 3D next to the objects. I want to know if I can display 2D text on the screen.
Im using C++ so would like to know if this possible in C++ and not qml thanks.

There is QText2DEntity class for allowing the creation of a 2D text in 3D space.
#include <QApplication>
#include <QGuiApplication>
#include <Qt3DExtras>
#include <Qt3DRender/qcamera.h>
#include <Qt3DCore/qentity.h>
#include <Qt3DRender/qcameralens.h>
#include <QtWidgets/QWidget>
#include <QtWidgets/QHBoxLayout>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
auto *view = new Qt3DExtras::Qt3DWindow;
view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f)));
auto *container = QWidget::createWindowContainer(view);
auto screenSize = view->screen()->size();
container->setMinimumSize(QSize(200, 100));
container->setMaximumSize(screenSize);
auto *widget = new QWidget;
auto *hLayout = new QHBoxLayout(widget);
hLayout->addWidget(container, 1);
auto *input = new Qt3DInput::QInputAspect;
view->registerAspect(input);
// Root entity
auto *rootEntity = new Qt3DCore::QEntity();
// Camera
auto *cameraEntity = view->camera();
cameraEntity->lens()->setPerspectiveProjection(45.0f, 16.0f/7.0f, 0.1f, 1000.0f);
cameraEntity->setPosition(QVector3D(0, 10.0f, 20.0f));
cameraEntity->setUpVector(QVector3D(0, 1, 0));
cameraEntity->setViewCenter(QVector3D(0, 0, 0));
//light
auto *lightEntity = new Qt3DCore::QEntity(rootEntity);
auto *light = new Qt3DRender::QPointLight(lightEntity);
light->setColor("white");
light->setIntensity(1);
lightEntity->addComponent(light);
auto *lightTransform = new Qt3DCore::QTransform(lightEntity);
lightTransform->setTranslation(cameraEntity->position());
lightEntity->addComponent(lightTransform);
// For camera controls
auto *camController = new Qt3DExtras::QOrbitCameraController (rootEntity);
camController->setCamera(cameraEntity);
// Set root object of the scene
view->setRootEntity(rootEntity);
auto *text2dTransform = new Qt3DCore::QTransform;
text2dTransform->setScale(0.125f);
text2dTransform->setTranslation(QVector3D(-5, 0, 5));
auto *text2d = new Qt3DExtras::QText2DEntity(rootEntity);
text2d->setFont(QFont("monospace"));
text2d->setHeight(20);
text2d->setWidth(100);
text2d->setText("A");
text2d->setColor(Qt::yellow);
text2d->addComponent(text2dTransform);
widget->show();
widget->resize(1200, 800);
return a.exec();
}

Parisa has already provided a nice solution, I'll just post here mine here in case you are looking for something which allows to draw UI-like text:
Like stated in the comments, either draw a rectangular surface on top of everything using orthographic projection mode (similar to my Qt3DBackground example, just draw the texture last and make it transparent).
Or instead use my Qt3D Widget which allows to add Qt's widgets onto Qt3D. This way, you can draw your scene and use a simple QLabel on top.

Related

Using several transforms in one Entity

Tried to create simple program showing torus with lighting. Everything works, but have this problem with light position.
When trying to create new transform for light after creating torus light's transform is being used for new torus position, instead of light.
Tried to change values and move addComponent, but no result.
Here's photo of result
Here's my entire code.
#include <QGuiApplication>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QTorusMesh>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QPointLight>
Qt3DCore::QEntity *createScene();
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Qt3DExtras::Qt3DWindow view;
Qt3DCore::QEntity *rootEntity = createScene();
Qt3DRender::QCamera *camera =view.camera();
camera->lens()->setPerspectiveProjection(60,(float)view.width()/view.height(),0.1f,1000.0f);
camera->setPosition(QVector3D(0.0f,0.0f,40.0f));
camera->setViewCenter(QVector3D(0.0f,0.0f,0.0f));
view.setRootEntity(rootEntity);
view.show();
return app.exec();
}
Qt3DCore::QEntity *createScene()
{
Qt3DCore::QEntity *resultEntity = new Qt3DCore::QEntity;
Qt3DExtras::QTorusMesh *torusMesh = new Qt3DExtras::QTorusMesh(resultEntity);
torusMesh->setRadius(15.0f);
torusMesh->setMinorRadius(6.0f);
torusMesh->setSlices(16);
torusMesh->setRings(32);
Qt3DExtras::QPhongMaterial *torusMaterial = new Qt3DExtras::QPhongMaterial(resultEntity);
Qt3DCore::QTransform *torusTransform = new Qt3DCore::QTransform(resultEntity);
resultEntity->addComponent(torusMesh);
resultEntity->addComponent(torusMaterial);
resultEntity->addComponent(torusTransform);
Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(resultEntity);
Qt3DRender::QPointLight *pointLight = new Qt3DRender::QPointLight(lightEntity);
Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(resultEntity);
lightTransform->setTranslation(QVector3D(0.0f,0.0f,30.0f));
resultEntity->addComponent(pointLight);
resultEntity->addComponent(lightTransform);
return resultEntity;
}

How to load and display a blender .obj source file scene using Qt 3D libraries

I'm trying to load a .obj source file from blender, and display it, LibertStatue.obj is the .obj file which is located in the same folder as the main.cpp file below. When I run this code, I get blank window which I think is supposed to show a statue of liberty, and a command prompt that says QObject::connect(opneglcontext, unknown) Invalid nullptr parameter.
I'm using Qt Creator on linux Xubuntu.
I downloaded the .obj file of statue of liberty from here : https://free3d.com/3d-model/statue-of-liberty-73656.html.
#include <QGuiApplication>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QOrbitCameraController>
#include <Qt3DRender>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QUrl data = QUrl::fromLocalFile("LibertStatue.obj");
Qt3DExtras::Qt3DWindow view;
Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity;
Qt3DCore::QEntity *flyingwedge = new Qt3DCore::QEntity(rootEntity);
Qt3DExtras::QPhongMaterial *material = new Qt3DExtras::QPhongMaterial();
material->setDiffuse(QColor(254, 254, 254));
Qt3DRender::QMesh *flyingwedgeMesh = new Qt3DRender::QMesh;
flyingwedgeMesh->setMeshName("FlyingWedge");
flyingwedgeMesh->setSource(data);
flyingwedge->addComponent(flyingwedgeMesh);
flyingwedge->addComponent(material);
Qt3DRender::QCamera *camera = view.camera();
camera->lens()->setPerspectiveProjection(40.0f, 16.0f/9.0f, 0.1f, 1000.0f);
camera->setPosition(QVector3D(0, 0, 40.0f));
camera->setViewCenter(QVector3D(0, 0, 0));
Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity);
Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
light->setColor("white");
light->setIntensity(0.8f);
lightEntity->addComponent(light);
Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);
lightTransform->setTranslation(QVector3D(60, 0, 40.0f));
lightEntity->addComponent(lightTransform);
Qt3DExtras::QOrbitCameraController *camController = new Qt3DExtras::QOrbitCameraController(rootEntity);
camController->setCamera(camera);
view.setRootEntity(rootEntity);
view.show();
return app.exec();
}
The problem is the setMeshName call. The documentation for the QMesh C++ class is misleading: setMeshName is not for setting a name to the QMesh object, but for selecting which geometry from the OBJ file you want to load. Its actual behavior is explained in the documentation of the corresponding QML type.
So you have two options: just remove the setMeshName call, or pass the actual name of the geometry, which you can find out by opening the OBJ file with a text editor.
Inspecting your code it looks to me that the Qt3Dwindow cannot be displayed standalone and the creation of a window container is needed to display the Qt3DWindow inside of a Widget (QFrame).
A typical Qt3D application I use for testing looks as follows:
#include <QApplication>
#include <QDebug>
#include <QFrame>
#include <QVBoxLayout>
#include <QWidget>
#include <QTimer>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QCameraLens>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QOrbitCameraController>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/QSphereMesh>
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
auto view = new Qt3DExtras::Qt3DWindow();
auto rootEntity = new Qt3DCore::QEntity();
view->setRootEntity(rootEntity);
auto camera = view->camera();
camera->lens()->setPerspectiveProjection(45.0f, 1., 0.1f, 10000.0f);
camera->setPosition(QVector3D(0, 0, 5));
camera->setUpVector(QVector3D(0, 1, 0));
camera->setViewCenter(QVector3D(0, 0, 0));
auto camController = new Qt3DExtras::QOrbitCameraController(rootEntity);
camController->setCamera(camera);
auto sphereMat = new Qt3DExtras::QDiffuseSpecularMaterial;
sphereMat->setDiffuse(QColor(Qt::blue));
auto mesh = new Qt3DExtras::QSphereMesh();
mesh->setRadius(1);
auto sphereEntity = new Qt3DCore::QEntity(rootEntity);
sphereEntity->addComponent(mesh);
sphereEntity->addComponent(sphereMat);
auto container = QWidget::createWindowContainer(view);
QFrame frame;
frame.setLayout(new QVBoxLayout);
frame.layout()->addWidget(container);
frame.resize(QSize(400, 300));
QTimer::singleShot(100, [&]() {
camera->viewAll();
});
frame.show();
return a.exec();
}

Qt3D Skeletal Animation

I am trying to convert the KDAB Qt3D QML Example https://github.com/KDAB/qt3d-examples/tree/master/animated-skinned-mesh to C++. I'm having a really hard time since the documentation is basically not useful!
Here is what I've programmed so far:
#include <QApplication>
#include <Qt3DCore>
#include <Qt3DRender>
#include <Qt3DExtras>
#include <Qt3DAnimation>
#include <QSkeletonLoader>
#include <QSkeletonMapping>
#include <QDebug>
Qt3DCore::QEntity *createScene()
{
Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity;
Qt3DRender::QMesh *mesh = new Qt3DRender::QMesh(rootEntity);
mesh->setSource(QUrl::fromLocalFile("D:/Robot/robot.gltf"));
Qt3DExtras::QPhongMaterial *meshMaterial = new Qt3DExtras::QPhongMaterial(rootEntity);
meshMaterial->setDiffuse(QColor(QRgb(0xa69929)));
Qt3DCore::QEntity *meshEntity = new Qt3DCore::QEntity(rootEntity);
Qt3DCore::QTransform *meshTransform = new Qt3DCore::QTransform(rootEntity);
meshEntity->addComponent(mesh);
meshEntity->addComponent(meshTransform);
meshEntity->addComponent(meshMaterial);
auto* animator = new Qt3DAnimation::QClipAnimator(meshEntity);
auto* clip = new Qt3DAnimation::QAnimationClipLoader(QUrl::fromLocalFile("D:/Robot/robot.gltf"), animator);
animator->setClip(clip);
Qt3DCore::QSkeletonLoader* skeletonLoader = new Qt3DCore::QSkeletonLoader(meshEntity);
skeletonLoader->setSource(QUrl::fromLocalFile("D:/Robot/robot.gltf"));
skeletonLoader->setCreateJointsEnabled(true);
Qt3DCore::QArmature *meshArmature = new Qt3DCore::QArmature;
meshArmature->setSkeleton(skeletonLoader);
meshEntity->addComponent(meshArmature);
Qt3DAnimation::QSkeletonMapping* skeletonMapping = new Qt3DAnimation::QSkeletonMapping(meshEntity);
skeletonMapping->setSkeleton(skeletonLoader);
Qt3DAnimation::QChannelMapper *m_channelMapper = new Qt3DAnimation::QChannelMapper;
m_channelMapper->addMapping(skeletonMapping);
animator->setLoopCount(Qt3DAnimation::QAbstractClipAnimator::Infinite);
animator->setChannelMapper(m_channelMapper);
animator->setRunning(true);
return rootEntity;
}
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
Qt3DExtras::Qt3DWindow view;
Qt3DCore::QEntity *scene = createScene();
Qt3DRender::QCamera *camera = view.camera();
camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
camera->setPosition(QVector3D(0, 0, 40.0f));
camera->setViewCenter(QVector3D(0, 0, 0));
Qt3DExtras::QOrbitCameraController *camController = new Qt3DExtras::QOrbitCameraController(scene);
camController->setLinearSpeed( 50.0f );
camController->setLookSpeed( 180.0f );
camController->setCamera(camera);
Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(scene);
Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
light->setColor("white");
light->setIntensity(1);
lightEntity->addComponent(light);
Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);
lightTransform->setTranslation(camera->position());
lightEntity->addComponent(lightTransform);
Qt3DCore::QEntity *lightEntity2 = new Qt3DCore::QEntity(scene);
Qt3DRender::QPointLight *light2 = new Qt3DRender::QPointLight(lightEntity2);
light2->setColor("yellow");
light2->setIntensity(1);
lightEntity2->addComponent(light2);
Qt3DCore::QTransform *lightTransform2 = new Qt3DCore::QTransform(lightEntity2);
lightTransform2->setTranslation(QVector3D(5.0f, 5.0f, -3.0f));
lightEntity2->addComponent(lightTransform2);
view.setRootEntity(scene);
view.defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f)));
view.registerAspect(new Qt3DAnimation::QAnimationAspect());
view.show();
return app.exec();
}
It is not throwing any runtime errors, and displays the robot mesh but it is not animating! The mesh is rendered with arms wide spread, to me it looks like the Armature is not applied to the mesh but I have no idea left what I could be doing wrong..... Btw, the QML example is running. Does anyone see a difference to the original QML that could be causing the problem?
EDIT: The file robot.gltf is the original file from the example!
you didn't add the animator to the meshEntity using addComponent

Disable Anti Aliasing in Qt3D

We are migrating from an older 3D engine to Qt 3D. In order to compare the older 3D engine with Qt3D I'm writing a small app, that compares both renderings side to side.
In order to make an automatic comparision more suitable I'm in need to deactive anti aliasing in Qt3D.
I think, that I have to modify the frame graph, but I have no idea, what is necessary to do this.
The following example app shows a simple Qt3D Scene with a sphere. Does anyone know how to perform the necessary changes in the default frame graph?
#include <QApplication>
#include <QVBoxLayout>
#include <QFrame>
#include <Qt3DRender/QCamera.h>
#include <Qt3DExtras/QSphereMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/qforwardrenderer.h>
#include <Qt3DExtras/Qt3DWindow.h>
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
auto view = new Qt3DExtras::Qt3DWindow();
auto frameGraph = view->defaultFrameGraph();
frameGraph->setClearColor(QColor(255,255,255));
// Disable Anti-Aliasing
// What is necessary here!
// ---------------------
auto rootEntity = new Qt3DCore::QEntity();
view->setRootEntity(rootEntity);
auto cameraEntity = view->camera();
cameraEntity->lens()->setPerspectiveProjection(45.0f, 1., 0.1f, 10000.0f);
cameraEntity->setPosition(QVector3D(5, 5, 5));
cameraEntity->setUpVector(QVector3D(0, 1, 0));
cameraEntity->setViewCenter(QVector3D(0, 0, 0));
auto mesh = new Qt3DExtras::QSphereMesh();
mesh->setRadius(1.);
auto meshMaterial = new Qt3DExtras::QDiffuseSpecularMaterial();
meshMaterial->setAlphaBlendingEnabled(true);
meshMaterial->setDiffuse(QColor(50, 50, 50));
meshMaterial->setAmbient(QColor(255, 255, 255));
meshMaterial->setSpecular(QColor(255,255,255));
meshMaterial->setShininess(100);
auto meshEntity = new Qt3DCore::QEntity(rootEntity);
meshEntity->addComponent(mesh);
meshEntity->addComponent(meshMaterial);
meshEntity->setEnabled(true);
auto container = QWidget::createWindowContainer(view);
QFrame frame;
frame.setLayout(new QVBoxLayout);
frame.layout()->addWidget(container);
frame.setFixedSize(500, 500);
frame.show();
return a.exec();
}
Have a look at the Qt Docs for multisampleantialiasing
There is some example code there.
EDIT: addendum
QML Scene3D has the following property
multisample : bool
true if a multisample render buffer is requested. By default
multisampling is enabled. If the OpenGL implementation has no support
for multisample renderbuffers or framebuffer blits, the request to use
multisampling is ignored. Note: Refrain from changing the value
frequently as it involves expensive and potentially slow
initialization of framebuffers and other OpenGL resources.
But there is no counterpart of Scene3D for the C++ world... Most QML classes have a counterpart for C++ by adding a "Q" in front of the name. But there is no QScene3D.
Remark about the usage of Qt3DExtras::Qt3DWindow
Qt3DWindow is derived from QWindow and was created to have solutions without the use of QWidgets. You can read more about the details in this post
If you want to add buttons, sliders, ets... in a later testing stage, I would advise using QML. You will get more flexibility from Qt3D compared to using C++ solely. It is even possible to mix C++ and QML: you can make your logic in C++ and register for usage in QML. So you get the best of both worlds. That is what I would do if I wanted to test the Qt3D capabilities thoroughly.
Happy coding!
If anyone stumbles across this, how I can enable/disable antialising in Qt3D is by setting the number of samples on the surface format:
QSurfaceFormat format;
format.setSamples(0); // Disables anti-aliasing
QSurfaceFormat::setDefaultFormat(format);
QSurfaceFormat format;
format.setSamples(4); // Enables 4x anti-aliasing
QSurfaceFormat::setDefaultFormat(format);
This has to happen before setting up Qt3D.
NB: This is for when you want to disable/enable antialiasing in a default Qt3D scene, i.e. where you don't render to a texture and then use it in a shader. If you want to do the latter, check out QMultiSampleAntiAliasing.
The following code disables the anti-aliasing, but is definitely not the correct way to do it. But, after all I got to a working solution. Setting setStereo(true) in the QSurfaceFormat disabled the anti-aliasing magically.
#include <QApplication>
#include <QVBoxLayout>
#include <QFrame>
#include <Qt3DRender/QCamera>
#include <Qt3DExtras/QSphereMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/qforwardrenderer>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DRender/QRenderSettings>
void depthFirstTraversal(const Qt3DRender::QFrameGraphNode* node, int depth) {
auto pad = QString(depth, QChar('\t'));
qDebug().noquote().nospace() << pad << node;
for (auto iter : node->children()) {
if (auto frameGraphNode = qobject_cast<Qt3DRender::QFrameGraphNode*>(iter)) {
depthFirstTraversal(frameGraphNode, depth + 1);
}
}
}
int main(int argc, char* argv[])
{
QSurfaceFormat format;
format.setStereo(true); // Disables anti-aliasing, but is definitely weird
QSurfaceFormat::setDefaultFormat(format);
QApplication a(argc, argv);
auto view = new Qt3DExtras::Qt3DWindow();
auto frameGraph = view->activeFrameGraph();
depthFirstTraversal(frameGraph, 0);
view->defaultFrameGraph()->setClearColor(QColor(255,255,255));
auto rootEntity = new Qt3DCore::QEntity();
view->setRootEntity(rootEntity);
auto cameraEntity = view->camera();
cameraEntity->lens()->setPerspectiveProjection(45.0f, 1., 0.1f, 10000.0f);
cameraEntity->setPosition(QVector3D(5, 5, 5));
cameraEntity->setUpVector(QVector3D(1, 1, 0));
cameraEntity->setViewCenter(QVector3D(0, 0, 0));
auto mesh = new Qt3DExtras::QSphereMesh();
mesh->setRadius(1.);
auto meshMaterial = new Qt3DExtras::QDiffuseSpecularMaterial();
meshMaterial->setAlphaBlendingEnabled(true);
meshMaterial->setDiffuse(QColor(50, 50, 50));
meshMaterial->setAmbient(QColor(255, 255, 255));
meshMaterial->setSpecular(QColor(255,255,255));
meshMaterial->setShininess(100);
auto meshEntity = new Qt3DCore::QEntity(rootEntity);
meshEntity->addComponent(mesh);
meshEntity->addComponent(meshMaterial);
meshEntity->setEnabled(true);
auto container = QWidget::createWindowContainer(view);
QFrame frame;
frame.setLayout(new QVBoxLayout);
frame.layout()->addWidget(container);
frame.setFixedSize(500, 500);
frame.show();
return a.exec();
}

2D meshes in QT3D

It seems to me that Qt3D cannot render 2D meshes well. To see what I mean open the shadow map QML example and change the camera controller from FirstPersonCameraController to OrbitCameraController. Run the program and attempt to view the ground plane from below, you will see it disappear. So QT3D just renders 2D meshes from one side and makes them transparent from the other side.
How can I fix this? i.e. render 2D meshes from both sides?
EDIT: Now I know that I have to disable culling for the rendering to work. I came up to this point:
//'this' refers to Qt3DWindow
rootEntity->addComponent(this->renderSettings());
QCullFace *face = new QCullFace();
QRenderStateSet *stateSet = new QRenderStateSet(this->renderSettings()->activeFrameGraph());
QRenderSurfaceSelector *selector = new QRenderSurfaceSelector(this->renderSettings());
face->setMode(QCullFace::NoCulling);
stateSet->addRenderState(face);
selector->setSurface(this);
but this still doesn't seem to change anything. Am I missing something?
Here is a minimally working example:
main.cpp:
#include <QApplication>
#include "clickwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
GraphicsWindow graphicsWindow;
graphicsWindow.show();
return a.exec();
}
graphicswindow.h:
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
class GraphicsWindow : public Qt3DExtras::Qt3DWindow {
public:
GraphicsWindow();
void wheelEvent ( QWheelEvent * event ) override;
private:
Qt3DCore::QEntity *createScene();
Qt3DCore::QTransform *planeTransform;
};
graphicswindow.cpp:
#include "graphicswindow.h"
#include <QMouseEvent>
#include <Qt3DRender/QViewport>
#include <Qt3DRender/QClearBuffers>
#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/QRenderStateSet>
#include <Qt3DRender/QCullFace>
#include <Qt3DRender/QCameraSelector>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QMaterial>
#include <Qt3DExtras/QGoochMaterial>
#include <Qt3DExtras/QPlaneMesh>
#include <Qt3DRender/QDepthTest>
GraphicsWindow::GraphicsWindow() : Qt3DExtras::Qt3DWindow() {
Qt3DRender::QCamera *camera = this->camera();
camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
camera->setPosition(QVector3D(20.0, 20.0, 20.0f));
camera->setViewCenter(QVector3D(0, 0, 0));
Qt3DRender::QRenderSurfaceSelector *surfaceSelector = new Qt3DRender::QRenderSurfaceSelector;
surfaceSelector->setSurface(this);
Qt3DRender::QViewport *viewport = new Qt3DRender::QViewport(surfaceSelector);
viewport->setNormalizedRect(QRectF(0, 0, 1.0, 1.0));
Qt3DRender::QCameraSelector *cameraSelector = new Qt3DRender::QCameraSelector(viewport);
cameraSelector->setCamera(camera);
Qt3DRender::QClearBuffers *clearBuffers = new Qt3DRender::QClearBuffers(cameraSelector);
clearBuffers->setBuffers(Qt3DRender::QClearBuffers::ColorDepthBuffer);
clearBuffers->setClearColor(Qt::white);
Qt3DRender::QRenderStateSet *renderStateSet = new Qt3DRender::QRenderStateSet(clearBuffers);
Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace(renderStateSet);
cullFace->setMode(Qt3DRender::QCullFace::NoCulling);
renderStateSet->addRenderState(cullFace);
Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest;
depthTest->setDepthFunction(Qt3DRender::QDepthTest::Less);
renderStateSet->addRenderState(depthTest);
setActiveFrameGraph(surfaceSelector);
Qt3DCore::QEntity *root = createScene();
setRootEntity(root);
}
void GraphicsWindow::wheelEvent(QWheelEvent *event) {
planeTransform->setRotationZ(planeTransform->rotationZ() + event->delta() / 40.f);
}
Qt3DCore::QEntity* GraphicsWindow::createScene() { // Root entity
Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity;
Qt3DCore::QEntity *planeEntity = new Qt3DCore::QEntity(rootEntity);
Qt3DRender::QMaterial *meshMaterial = new Qt3DExtras::QGoochMaterial;
Qt3DExtras::QPlaneMesh *planeMesh = new Qt3DExtras::QPlaneMesh;
planeMesh->setHeight(10);
planeMesh->setWidth(10);
planeTransform = new Qt3DCore::QTransform;
planeEntity->addComponent(planeTransform);
planeEntity->addComponent(planeMesh);
planeEntity->addComponent(meshMaterial);
return rootEntity;
}
Keep in mind that the setActiveFramegraph function of the Qt3DWindow automatically adds the QRenderSettings returned by the renderSettings() function of the window on the frame graph node that you set as the active frame graph. If you are implementing your own 3D window or create and offscreen renderer you have to use QRenderSettings as the root node of your framegraph (the window sets its render settings as the parent of the root frame graph node that you set) and add the render settings to the actual root node, i.e. the node that is the parent of the frame graph and the scene graph.