Я пытаюсь создать прототип Qt3D, который может визуализировать объект, который содержит прозрачные объекты. Для этого мне нужно как-то включить QSortPolicy
с пользовательским графиком кадра. Я собрал несколько примеров, которые я нашел в интернете (к сожалению, примеров Qt3D C ++ не так много). Источник прототипа показан ниже. Проблема в том, что я добавляю QTorusMesh
и содержание QSceneLoader
до корневого объекта, но при визуализации будет показан только тор, объект (в данном случае обезьяна) не отображается, и я не знаю почему, а также как его отладить. Я сбросил все деревья (граф сцены и граф кадра) и не смог найти никаких несоответствий. Единственное, что я могу думать о том, что загруженному объекту как-то нужен другой рендер (QGeometryRenderer
) что нужно добавить к графу фреймов? Кто-то знает, что я делаю не так?
Примеры: Пользовательский график кадра, Сцена Уокер
#include <QGuiApplication>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DCore/QAspectEngine>
#include <Qt3DInput/QInputAspect>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DExtras/QOrbitCameraController>
#include <Qt3DExtras/QTorusMesh>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QRenderAspect>
#include <Qt3DRender/QSceneLoader>
#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/QClearBuffers>
#include <Qt3DRender/QLayerFilter>
#include <Qt3DRender/QViewport>
#include <Qt3DRender/QCameraSelector>
#include <Qt3DRender/QLayer>
#include <Qt3DRender/QRenderSettings>
class SceneWalker : public QObject
{
public:
SceneWalker(Qt3DRender::QSceneLoader* loader):
m_loader(loader)
{}
void onStatusChanged();
private:
void walkEntity(Qt3DCore::QEntity* e, int depth = 0);
Qt3DRender::QSceneLoader* m_loader;
};
void SceneWalker::onStatusChanged()
{
qDebug() << "Status changed:" << m_loader->status();
if (m_loader->status() != Qt3DRender::QSceneLoader::Ready)
return;
// The QSceneLoader instance is a component of an entity. The loaded scene
// tree is added under this entity.
QVector<Qt3DCore::QEntity*> entities = m_loader->entities();
// Technically there could be multiple entities referencing the scene loader
// but sharing is discouraged, and in our case there will be one anyhow.
if (entities.isEmpty())
return;
Qt3DCore::QEntity* root = entities[0];
// Print the tree.
walkEntity(root);
// To access a given node (like a named mesh in the scene), use QObject::findChild().
// The scene structure and names always depend on the asset.
Qt3DCore::QEntity* e = root->findChild<Qt3DCore::QEntity*>(QStringLiteral("PlanePropeller_mesh")); // toyplane.obj
if (e)
qDebug() << "Found propeller node" << e << "with components" << e->components();
}
void SceneWalker::walkEntity(Qt3DCore::QEntity* e, int depth)
{
Qt3DCore::QNodeVector nodes = e->childNodes();
for (int i = 0; i < nodes.count(); ++i)
{
Qt3DCore::QNode* node = nodes[i];
Qt3DCore::QEntity* entity = qobject_cast<Qt3DCore::QEntity*>(node);
if (entity)
{
QString indent;
indent.fill(' ', depth * 2);
qDebug().noquote() << indent << "Entity:" << entity << "Components:" << entity->components();
walkEntity(entity, depth + 1);
}
}
}
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
Qt3DExtras::Qt3DWindow* window = new Qt3DExtras::Qt3DWindow();
// Root
Qt3DCore::QEntity* rootEntity = new Qt3DCore::QEntity();
window->setRootEntity(rootEntity);
Qt3DRender::QRenderSurfaceSelector *renderSurfaceSelector = new Qt3DRender::QRenderSurfaceSelector();
renderSurfaceSelector->setSurface(window);
// clearing the buffers
Qt3DRender::QClearBuffers* clearBuffers = new Qt3DRender::QClearBuffers(renderSurfaceSelector);
clearBuffers->setBuffers(Qt3DRender::QClearBuffers::ColorDepthBuffer);
// Framegraph for objects
Qt3DRender::QLayerFilter* objectsLayerFilter = new Qt3DRender::QLayerFilter(renderSurfaceSelector);
Qt3DRender::QLayer* objectsLayer = new Qt3DRender::QLayer(objectsLayerFilter);
objectsLayerFilter->addLayer(objectsLayer);
Qt3DRender::QViewport* viewport = new Qt3DRender::QViewport(objectsLayer);
Qt3DRender::QCameraSelector* objectsCameraSelector = new Qt3DRender::QCameraSelector(viewport);
Qt3DRender::QCamera* objectsCamera = new Qt3DRender::QCamera(objectsCameraSelector);
objectsCamera->lens()->setPerspectiveProjection(45.f, 16.0f/9.0f, 0.01f, 1000.f);
objectsCamera->setPosition(QVector3D(0, 0, -10));
objectsCamera->setViewCenter(QVector3D(0, 0, 0));
objectsCamera->setUpVector(QVector3D(0, 1, 0));
objectsCameraSelector->setCamera(objectsCamera);
// Set the new framegraph
window->setActiveFrameGraph(renderSurfaceSelector);
window->renderSettings()->setRenderPolicy(Qt3DRender::QRenderSettings::Always);
// camera controls
Qt3DExtras::QOrbitCameraController* camController = new Qt3DExtras::QOrbitCameraController(rootEntity);
camController->setLinearSpeed(50.0f);
camController->setLookSpeed(180.0f);
camController->setCamera(objectsCamera);
// Torus
Qt3DCore::QEntity* torusEntity = new Qt3DCore::QEntity(rootEntity);
Qt3DExtras::QTorusMesh* torusMesh = new Qt3DExtras::QTorusMesh(torusEntity);
torusMesh->setSlices(50.0f);
torusMesh->setRings(50.0f);
torusMesh->setRadius(2.0f);
Qt3DExtras::QPhongMaterial* torusMaterial = new Qt3DExtras::QPhongMaterial(torusEntity);
torusMaterial->setAmbient(Qt::gray);
Qt3DCore::QTransform* torusTransform = new Qt3DCore::QTransform(torusEntity);
torusTransform->setTranslation(QVector3D(0.0f, 0.0f, 10.0f));
torusTransform->setRotationY(50.0f);
torusTransform->setScale(2.0f);
torusEntity->addComponent(torusTransform);
torusEntity->addComponent(torusMesh);
torusEntity->addComponent(torusMaterial);
torusEntity->addComponent(objectsLayer);
// Scene loader
Qt3DCore::QEntity* sceneLoaderEntity = new Qt3DCore::QEntity(rootEntity);
Qt3DRender::QSceneLoader* sceneLoader = new Qt3DRender::QSceneLoader(sceneLoaderEntity);
sceneLoader->setSource(QUrl::fromLocalFile("monkey.obj"));
// Transform
Qt3DCore::QTransform* sceneLoaderTransform = new Qt3DCore::QTransform(sceneLoaderEntity);
sceneLoaderTransform->setScale(2.0f);
sceneLoaderTransform->setTranslation(QVector3D(0.0f, 0.0f, 10.0f));
SceneWalker sceneWalker(sceneLoader);
QObject::connect(sceneLoader, &Qt3DRender::QSceneLoader::statusChanged, &sceneWalker, &SceneWalker::onStatusChanged);
sceneLoaderEntity->addComponent(sceneLoader);
sceneLoaderEntity->addComponent(sceneLoaderTransform);
sceneLoaderEntity->addComponent(objectsLayer);
window->show();
return app.exec();
}
Задача ещё не решена.
Других решений пока нет …