Q: Qt3D - [c++] Apply QMaterial on a loaded obj file
-
Hi!
I imported a simple obj-file with the SceneLoader.
The object is purposely visible multiple times inside the 3D Window, but I would like to apply individual colors (red or blue) on them. Best case would also be a alpha parameter, as QPhongAlphaMaterial is supposed to be capable. Is there any chance of applying a QMaterial* ?Unfortunately, no effect of transparency, or individual colors from applied material types (I tried all of the popular ones) is spottable, all the objects are black (but shaded from the white light source).
Please help. This is my code:
Qt3DRender::QMaterial *objectMaterial = getAnyQMaterial(); Qt3DCore::QEntity *entity = new Qt3DCore::QEntity(root); Qt3DRender::QSceneLoader *loader = new Qt3DRender::QSceneLoader(root); QObject::connect(loader, &Qt3DRender::QSceneLoader::statusChanged, [loader, objectMaterial](Qt3DRender::QSceneLoader::Status s) { if (s == Qt3DRender::QSceneLoader::Ready) { QVector<Qt3DCore::QEntity*> entities = loader->entities(); if (entities.size() > 0) { for (int e = 0; e < entities.size(); e++) { entities[e]->components().clear(); entities[e]->addComponent(objectMaterial); entities[e]->setEnabled(true); } } } }); loader->setSource(QUrl::fromLocalFile("Resources/Objects/pyramid.obj")); entity->addComponent(objectMaterial); entity->addComponent(loader);
-
I am very happy now. All the materials work.
There were two problems:1.) Never reuse material references. Always create a new material which apply to the individual object.
2.) The assignment of materials don't work recursively. As in http://man.hubwiz.com/docset/Qt_5.docset/Contents/Resources/Documents/doc.qt.io/qt-5/qt3drender-qsceneloader.html, it needs to traverse through the complete entities-tree of the loader, eg. with the SceneWalker, referenced here: https://code.qt.io/cgit/qt/qt3d.git/tree/tests/manual/assimp-cpp/main.cpp and assign the material to all entities found.
Code here:
void SceneWalker::walk(Qt3DCore::QEntity *ent, int depth) { // get entity in entities ... // apply material to entity // call walk recursively } void Scene::loadAndApply() { QPhongAlphaMaterial *_material= new QPhongAlphaMaterial; _material->setDiffuse(QColor(100,100,200)); [...] SceneWalker *sceneWalker = new SceneWalker(_material); QObject::connect(loader, &Qt3DRender::QSceneLoader::statusChanged, [sceneWalker, loader](Qt3DRender::QSceneLoader::Status status) { if (status = Qt3DRender::QSceneLoader::Ready) sceneWalker->onStatusChanged(loader); } entity->addComponent(loader); }
best regards