A weird bug? Why is there no spatial depth in my 3D scene?
-
I want to use
Qt3D
withinQt5.7
to plot a 3D scene (a chemical molecule) which I want to rotate.
The problem is that my 3D objects are not displayed according to their spatial positioning. The last createdQEntity
is always in the foreground, regardless of how I rotate the camera.
In the minimum working example below, theQEntity
smallGreenSphere
is always in the foreground even though it is spatially positioned behindbigRedSphere
in the default view specified in the camera settings.
To rephrase the problem: My 3D scene has no depth.Please note that
smallGreenSphere
is instantiated afterbigRedSphere
in themain.cpp
file shown below:#include <QGuiApplication> #include <Qt3DCore> #include <Qt3DRender> #include <Qt3DExtras> Qt3DCore::QEntity* createTestScene() { Qt3DCore::QEntity* root = new Qt3DCore::QEntity; Qt3DCore::QEntity* bigRedSphere = new Qt3DCore::QEntity(root); Qt3DCore::QEntity* smallGreenSphere = new Qt3DCore::QEntity(root); Qt3DExtras::QSphereMesh* bigMesh = new Qt3DExtras::QSphereMesh; bigMesh->setRadius(5); bigMesh->setRings(100); bigMesh->setSlices(20); Qt3DExtras::QSphereMesh* smallMesh = new Qt3DExtras::QSphereMesh; smallMesh->setRadius(2); smallMesh->setRings(100); smallMesh->setSlices(20); Qt3DExtras::QPhongMaterial* redMaterial = new Qt3DExtras::QPhongMaterial; redMaterial->setSpecular(Qt::white); redMaterial->setShininess(10); redMaterial->setAmbient(Qt::red); Qt3DExtras::QPhongMaterial* greenMaterial = new Qt3DExtras::QPhongMaterial; greenMaterial->setSpecular(Qt::white); greenMaterial->setShininess(10); greenMaterial->setAmbient(Qt::green); Qt3DCore::QTransform* transform = new Qt3DCore::QTransform; transform->setTranslation(QVector3D(0,0,10)); bigRedSphere->addComponent(redMaterial); bigRedSphere->addComponent(bigMesh); smallGreenSphere->addComponent(greenMaterial); smallGreenSphere->addComponent(smallMesh); smallGreenSphere->addComponent(transform); return root; } int main(int argc, char* argv[]) { QGuiApplication app(argc, argv); Qt3DExtras::Qt3DWindow view; Qt3DCore::QEntity* scene = createTestScene(); // camera Qt3DRender::QCamera *camera = view.camera(); camera->lens()->setPerspectiveProjection(45, 16./9., 0.1,1000.); camera->setPosition(QVector3D(30., 0, 60.)); camera->setViewCenter(QVector3D(0, 0, 0)); // manipulator Qt3DExtras::QOrbitCameraController* manipulator = new Qt3DExtras::QOrbitCameraController(scene); manipulator->setLinearSpeed(50); manipulator->setLookSpeed(180); manipulator->setCamera(camera); view.setRootEntity(scene); view.show(); return app.exec(); }
This results in the following scene:
Please note that I did not rotate anything manually and that this is the output of the code above.If I now swap the order of instantiation in
createTestScene()
byQt3DCore::QEntity* smallGreenSphere = new Qt3DCore::QEntity(root); Qt3DCore::QEntity* bigRedSphere = new Qt3DCore::QEntity(root);
so that
bigRedSphere
is now instantiated aftersmallGreenSphere
, thebigRedSphere
is always in the foreground and the resulting scene (again without manual rotation) looks like this:This proves that the order of instantiation determines what sphere is displayed in the foreground.
How can I obtain the correct 3D view regardless of the order of instantiation? Do I have to use some different rendering technique?
Thanks in advance for your help and please consider that I am new to Qt, Qt3D, and rendering in your answer. -
@kshegunov No! The images I am showing just the result of swapping the order of instantiation of the entities. To rephrase my problem: there is no depth in the scene. Furthermore, the spheres do not intersect each other if I understood you correctly. The small one has a radius of 2, the large has a radius of 5, and their centers have a distance of 10 => they do not intersect.
What I am actually trying to do is plotting large molecules in ball-and-stick representation and the lastly created atoms are always in the foreground of the scene.
As I tried to explain above: there is a different outcome if I create the sphere in a different order.
So if I writeQt3DCore::QEntity* redBigSphere = new Qt3DCore::QEntity(root); Qt3DCore::QEntity* smallGreenSphere = new Qt3DCore::QEntity(root);
instead of
Qt3DCore::QEntity* smallGreenSphere = new Qt3DCore::QEntity(root); Qt3DCore::QEntity* redBigSphere = new Qt3DCore::QEntity(root);
the scene looks differently. In both cases manual rotation of the scene makes this problem more obvious.
Please, try to compile my example and see for yourself. If you do so, please rotate the scene by 180°. I am going crazy over this. It must be either something extremely dumb what I am doing wrong or I need to understand something more advanced of what I am not aware. I tried to figure this out the last two days but without success. I also tried to compile the example from http://doc.qt.io/qt-5/qt3d-deferred-renderer-cpp-example.html example but somehow some files (e.g. the
main.cpp
) seem to be missing. I am really trying hard. Help is really greatly appreciated. -
Swapping the order of instantiation did not change what I saw. One is still in front of the other, because relative to the angle you've set it is in front. If I move the camera it's clearly visible that it's a side look to the scene, and as the angle (compared to the axis connecting both spheres) increases it's obvious they're separated by a distance. Your example code works fine for me.
-
@Finn said in A Qt3D beginners question: Why is there no depth in my 3D scene?:
It did not change what you saw?
Nope, not a bit.
Really, what is wrong with my Qt3D ??
Probably nothing. If I had to hazard a guess you had object files left over from another build while testing. Try a full rebuild between the instantiation swaps and I'm sure you'd be convinced there's no problem.
-
@kshegunov I can really exclude this. I reproduced this very often before I made the efforts to post this. Also now I am reproducing it. Furthermore, if I rotate the orbit view by ~180° around the z-axis manually with the mouse, it still does not change the fact that the lastly instantiated sphere is still in front. Therefore, it is not possible that I am just confusing the sphere positions here. While doing the rotation around the z-axis, the
smallGreenSphere
changes its size as it should do because it is not in the ViewCenter but, as already said, the spatial depth is wrong. The lastly createdQEntity
is always in the foreground and the other objects are behind it.
Of course, I experience this also with the ball-and-stick molecules which I originally want to visualize. This applies also to QCylinders and whatsoever.Maybe I found a weird bug here?
-
Hi,
I cannot reproduce this problem, either.
I remember, though, I had similar issues using QPhongAlphaMaterial when I tested Qt3D. For the time being(?), we stay with QOpenGLWindow, as it has no known bugs and most important to us produces no 13% CPU load (in release version) with just two cubes to show.
-Michael. -
@Finn said in A weird bug? Why is there no spatial depth in my 3D scene?:
Maybe I found a weird bug here?
It is possible.You can take a peek here to see if something's known.
What's your OS and how did you install Qt3D? -
@kshegunov My OS is ubuntu 16.04 LTS and I got Qt 5.7 via the
qt-unified-x64-2.03-1-online.run
executable. In the terminal, I went into my Qt directory
/home/<username>/Qt/5.7/Src
where I just entered./configure make sudo make install
When wanted to compile a
Qt3D
example, I got some linking errors saying something about missingQt3D
libraries (which I cannot recall anymore). I could solve this by entering the following which I found in some forum:sudo apt-get install libfontconfig1-dev libfreetype6-dev libx11-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libx11-xcb-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync0-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-xinerama0-de
Maybe this is the origin of my problems?
Should I consider reinstallingQt
completely and what would be the cleanest way to do it? Thanks a lot for your help. -
@Finn said in A weird bug? Why is there no spatial depth in my 3D scene?:
Maybe this is the origin of my problems?
It's certainly possble.
sudo make install
Why do that? Your distro already provides a Qt release so my suspicion is there are some files (partially) overwritten. What I suggest is to reinstall you distro's Qt (by means of the package manager), then to configure the Qt you downloaded with a prefix (don't forget to
make clean
before doing the configure, or even to delete the whole folder and recreate it through the Qt installer), e.g.:./configure -prefix /opt/Qt-5.7
make
and then it's safe tomake install
, because the files will go to/opt/Qt-5.7
.
Then you can configure a kit in creator (assuming this is what you use) that will use this version of Qt (in/opt/Qt-5.7
). -
@kshegunov No, I completely reinstalled everything to the folder
/opt/Qt-5.7
by following your instructions and those in the tutorial (https://wiki.qt.io/Install_Qt_5_on_Ubuntu). Before, I deleted everything but the result is the same. So far I usedCLion2016
and now I also tried theQtCreator
- still the same outcome.I also added some axes (x=red, y=green, z=blue), which are instantiated after the spheres.
Other ideas?
main.cpp
#include <QGuiApplication> #include <Qt3DCore> #include <Qt3DRender> #include <Qt3DExtras> Qt3DCore::QEntity* createTestScene() { Qt3DCore::QEntity* root = new Qt3DCore::QEntity; Qt3DCore::QEntity* smallGreenSphere = new Qt3DCore::QEntity(root); Qt3DCore::QEntity* bigRedSphere = new Qt3DCore::QEntity(root); Qt3DExtras::QSphereMesh* bigMesh = new Qt3DExtras::QSphereMesh; bigMesh->setRadius(5); bigMesh->setRings(100); bigMesh->setSlices(20); Qt3DExtras::QSphereMesh* smallMesh = new Qt3DExtras::QSphereMesh; smallMesh->setRadius(2); smallMesh->setRings(100); smallMesh->setSlices(20); Qt3DExtras::QPhongMaterial* redMaterial = new Qt3DExtras::QPhongMaterial; redMaterial->setSpecular(Qt::white); redMaterial->setShininess(10); redMaterial->setAmbient(Qt::red); Qt3DExtras::QPhongMaterial* greenMaterial = new Qt3DExtras::QPhongMaterial; greenMaterial->setSpecular(Qt::white); greenMaterial->setShininess(10); greenMaterial->setAmbient(Qt::green); Qt3DCore::QTransform* transform = new Qt3DCore::QTransform; transform->setTranslation(QVector3D(0,0,10)); bigRedSphere->addComponent(redMaterial); bigRedSphere->addComponent(bigMesh); smallGreenSphere->addComponent(greenMaterial); smallGreenSphere->addComponent(smallMesh); smallGreenSphere->addComponent(transform); Qt3DCore::QEntity* xaxis = new Qt3DCore::QEntity(root); Qt3DCore::QEntity* yaxis = new Qt3DCore::QEntity(root); Qt3DCore::QEntity* zaxis = new Qt3DCore::QEntity(root); Qt3DExtras::QCylinderMesh* cylinderMesh = new Qt3DExtras::QCylinderMesh; cylinderMesh->setRadius(0.2); cylinderMesh->setLength(20); cylinderMesh->setRings(100); cylinderMesh->setSlices(20); Qt3DExtras::QPhongMaterial* blueMaterial = new Qt3DExtras::QPhongMaterial; blueMaterial->setSpecular(Qt::white); blueMaterial->setShininess(10); blueMaterial->setAmbient(Qt::blue); double pi = 3.14159265359; Qt3DCore::QTransform* xTransform = new Qt3DCore::QTransform(); xTransform->setTranslation(QVector3D(10,0,0)); xTransform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(0,0,1),90)); Qt3DCore::QTransform* yTransform = new Qt3DCore::QTransform(); yTransform->setTranslation(QVector3D(0,10,0)); Qt3DCore::QTransform* zTransform = new Qt3DCore::QTransform(); zTransform->setTranslation(QVector3D(0,0,10)); zTransform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1,0,0),90)); xaxis->addComponent(cylinderMesh); xaxis->addComponent(redMaterial); xaxis->addComponent(xTransform); yaxis->addComponent(cylinderMesh); yaxis->addComponent(greenMaterial); yaxis->addComponent(yTransform); zaxis->addComponent(cylinderMesh); zaxis->addComponent(blueMaterial); zaxis->addComponent(zTransform); return root; } int main(int argc, char* argv[]) { QGuiApplication app(argc, argv); Qt3DExtras::Qt3DWindow view; Qt3DCore::QEntity* scene = createTestScene(); // camera Qt3DRender::QCamera *camera = view.camera(); camera->lens()->setPerspectiveProjection(45, 16./9., 0.1,1000.); camera->setPosition(QVector3D(45,15,45)); camera->setViewCenter(QVector3D(0, 0, 0)); // manipulator Qt3DExtras::QOrbitCameraController* manipulator = new Qt3DExtras::QOrbitCameraController(scene); manipulator->setLinearSpeed(50); manipulator->setLookSpeed(180); manipulator->setCamera(camera); view.setRootEntity(scene); view.show(); return app.exec(); }
CMakeLists.txt
cmake_minimum_required(VERSION 3.2) project(QtCreatorTest) find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets 3DCore 3DExtras 3DRender 3DInput ) add_executable("${PROJECT_NAME}_main" main.cpp) target_link_libraries("${PROJECT_NAME}_main" Qt5::Core Qt5::Gui Qt5::Widgets Qt5::3DCore Qt5::3DExtras Qt5::3DRender Qt5::3DInput )
-
@Finn
This is really strange. I ran your code and it works perfectly fine for me (I use qmake with a kit for Qt 5.7 though). Here's what I see:
And my project file is absolutely standard:
QT += core gui 3dcore 3drender 3dextras TARGET = balls-test TEMPLATE = app SOURCES += main.cpp
[Edit: Fixed broken link]
-
Honestly, I'd be surprised if there was a difference between using
cmake
andqmake
. And to be completely frank I don't know what might be the cause of the problem. My current best advice is to either bring the question to the mailing list, where hopefully one of the developers of Qt3D will pick it up (but after you check there's no open bugs on this), or try and wait for some other suggestion from other of our members here.Kind regards.
-
I tried it on my private MacBook Pro with MacOS Sierra 10.12.1 and installed Qt5 via
brew install qt5
. The result is still the same. What on earth can be the reason that it is working for you guys and not for me? Do I need some other libraries or build options? -
Sorry, as a noobie, I can't offer any insight, but I ran the code, and I'm getting the same as Finn. I'm on Qt 5.7 on Win 10.
Could it be CPU or GPU related? I'm on a 6coreAMD machine.
-
@Ian-Bray Thank you for your reply, this was very helpful! I would suggest that someone more experienced than me should report this as a bug.