2014-04-22 8 views
11

Ich genieße Qt3D verwenden, aber alle die Beispiele, die ich für sie zu sehen sind voll Fensteranwendungen. Was ich aus den Beispielen nicht verstehen kann ist, wie man ein qt3d Renderfenster zu einer normalen qt gui Anwendung hinzufügt.Wie rende ich in Qt3D in einer Standard-GUI-Anwendung?

Im Grunde, was ich will, ist ein wenig Rendering-Widget für meine QT5 Gui-Anwendung.

Ich habe in Qtgl Widget sieht, aber ich mag wirklich die Szene Management-Fähigkeiten von Qt3D verwenden.

Wie kann ich machen als Sub-Fenster innerhalb eines qt Gui Fenster?

Ist das möglich?

aktualisieren

So habe ich das meinem mainwindow.cpp Es lose aus dieser http://blog.qt.digia.com/blog/2013/02/19/introducing-qwidgetcreatewindowcontainer/

basiert
LoadModelView *view = new LoadModelView(); //Crashes on this. Will not compile with 
              // LoadModelView(this) 

    QWidget *container = QWidget::createWindowContainer(view); 
    container->setFocusPolicy(Qt::TabFocus); 

    ui->gridLayout->addWidget(container); 

das Recht scheint.

meine load_model.cpp beginnt wie folgt aus:

#include "qglmaterialcollection.h" 
#include "qglmaterial.h" 
#include "qglscenenode.h" 
#include "qgllightmodel.h" 
#include "qglabstractscene.h" 
#include <QtGui/qmatrix4x4.h> 

#include <QPropertyAnimation> 
#include <QtCore/qmath.h> 

#define DEGREE_TO_RAD (3.1415926/180.0) 

LoadModelView::LoadModelView(QWindow *parent) 
    : QGLView(parent) 
    , m_pSTLScene(0) 

{ 
    loadModels(); 

    camera()->setCenter(QVector3D(0, 0, 0)); 
    camera()->setEye(QVector3D(0, 4, 10)); 
} 
LoadModelView::~LoadModelView() 
{ 

    delete m_pSTLScene; 
} 

void LoadModelView::paintGL(QGLPainter *painter) 
{ 
    QMatrix4x4 stlWorld; 
    stlWorld.setToIdentity(); 
    stlWorld.scale(0.1); 
    stlWorld.translate(QVector3D(2.0,0.0,0.0)); 

    painter->setStandardEffect(QGL::LitMaterial); 
    painter->setFaceColor(QGL::AllFaces,QColor(170,202,0)); 

    painter->modelViewMatrix() = camera()->modelViewMatrix() * stlWorld; 

    m_pSTLScene->mainNode()->draw(painter); 
} 

void FixNodesRecursive(int matIndex, QGLSceneNode* pNode) 
{ 
    if (pNode) { 
     pNode->setMaterialIndex(matIndex); 
     // pNode->setEffect(QGL::FlatReplaceTexture2D); 
     foreach (QGLSceneNode* pCh, pNode->children()) { 
      FixNodesRecursive(matIndex, pCh); 
     } 
    } 
} 

void LoadModelView::loadModels() 
{ 
    { 
     m_pSTLScene = QGLAbstractScene::loadScene(QLatin1String(":/models/Sheep.stl"), QString(),"CorrectNormals CorrectAcute"); 
     Q_ASSERT(m_pSTLScene!=0); 
     QGLMaterial *mat = new QGLMaterial; 
     mat->setAmbientColor(QColor(170,202,0)); 
     mat->setDiffuseColor(QColor(170,202,0)); 
     mat->setShininess(128); 

     QGLSceneNode* pSTLSceneRoot = m_pSTLScene->mainNode(); 
     int matIndex = pSTLSceneRoot->palette()->addMaterial(mat); 
     pSTLSceneRoot->setMaterialIndex(matIndex); 
     pSTLSceneRoot->setEffect(QGL::FlatReplaceTexture2D); 
     FixNodesRecursive(matIndex,pSTLSceneRoot); 

    } 

} 

Es stürzt mit: Diese Anwendung die Laufzeit es auf eine ungewöhnliche Art und Weise zu beenden angefordert hat.

und in der Anwendungsausgabe qt: Ungültige Parameter C Laufzeit-Funktion übergeben.

EDIT Added der Rest der Klasse in Frage

merke ich, dass ich im Beispiel bin Anpassung http://doc.qt.digia.com/qt-quick3d-snapshot/qt3d-penguin-main-cpp.html das Fenster mit den Worten initialisiert wird:

LoadModelView view; 

jedoch sagen

LoadModelView *view = new LoadModelView(this) 

Abstürze

Antwort

5

Sie QGLView Klasse Unterklasse kann die QGLWidget mit Unterstützung für 3D-Ansicht erweitert:

class GLView : public QGLView 
{ 
    Q_OBJECT 

public: 
    GLView(QWidget *parent = 0); 
    ~GLView(); 

protected: 
    void initializeGL(QGLPainter *painter); 
    void paintGL(QGLPainter *painter); 

private: 
    QGLAbstractScene *m_scene; 
    QGLSceneNode *m_rootNode; 
}; 

GLView::GLView(QWidget *parent) 
    : QGLView(parent) 
    , m_scene(0) 
    , m_rootNode(0) 
{ 
    // Viewing Volume 
    camera()->setFieldOfView(25); 
    camera()->setNearPlane(1); 
    camera()->setFarPlane(1000); 

    // Position of the camera 
    camera()->setEye(QVector3D(0, 3, 4)); 

    // Direction that the camera is pointing 
    camera()->setCenter(QVector3D(0, 3, 0)); 
} 

GLView::~GLView() 
{ 
    delete m_scene; 
} 

void GLView::initializeGL(QGLPainter *painter) 
{ 
    // Background color 
    painter->setClearColor(QColor(70, 70, 70)); 

    // Load the 3d model from the file 
    m_scene = QGLAbstractScene::loadScene("models/model1/simplemodel.obj"); 

    m_rootNode = m_scene->mainNode(); 
} 

void GLView::paintGL(QGLPainter *painter) 
{ 
    m_rootNode->draw(painter); 
} 

Qt 5.1 führt die Funktion QWidget :: createWindowContainer(). Eine Funktion, die einen QWidget-Wrapper für ein vorhandenes QWindow erstellt, damit es in einer QWidget-basierten Anwendung leben kann. Sie können QWidget :: createWindowContainer verwenden, der ein QWindow in einem QWidget erstellt. Dadurch können QWindow-Unterklassen in Widget-Layouts platziert werden. Auf diese Weise können Sie Ihre QGLView in ein Widget einbetten.

+0

Ich * denke * das mache ich schon. http://pastebin.com/tRi9BVwn Was ich fragen ist, wie bekomme ich dies in einem bereits vorhandenen Fenster Pop-up. Können Sie zeigen, wie Sie dies von mainwindow.cpp aus aufrufen? Wenn ich versuche, w.show und dann view.show hinzuzufügen, stürzt alles ab. Ich möchte ein normales Fenster mit Knöpfen etc ... und ein 3D-Render eingebettet unter den Tasten. – baordog

+0

https://qt-project.org/forums/viewthread/22465 Dieser Thread bekommt meine Frage. Antwortet auch nicht. – baordog

+0

Sie können QWidget :: createWindowContainer in Qt 5.1 verwenden. Ich habe die Antwort aktualisiert. – Nejat

0

So habe ich es auf Qt5.10 gemacht. Dieses Beispiel zeigt eine Szene mit einem Quader. Scene können Sie dann wie eine Schaltfläche oder so verwenden ... Um dies zu verwenden, fügen Sie QT += 3dextras zu Ihrer Projektdatei hinzu.

szene.h

#ifndef SCENE_H 
#define SCENE_H 

#include <QObject> 
#include <QWidget> 

class Scene 
     : public QWidget 
{ 
    Q_OBJECT 

private: 
    QWidget *container; 

public: 
    explicit Scene(QWidget *parent = nullptr); 

protected: 
    // reimplementation needed to handle resize events 
    // http://doc.qt.io/qt-5/qwidget.html#resizeEvent 
    void 
    resizeEvent (QResizeEvent * event); 

public slots: 
    void 
    resizeView(QSize size); 
}; 

#endif // SCENE_H 

Szene.cpp

#include "scene.h" 

#include <Qt3DExtras/Qt3DWindow> 
#include <Qt3DExtras/QForwardRenderer> 
#include <QQuaternion> 
#include <Qt3DCore/QEntity> 
#include <Qt3DCore/QTransform> 
#include <Qt3DRender/QCamera> 
#include <Qt3DExtras/QCuboidMesh> 
#include <Qt3DExtras/QPhongMaterial> 

Scene::Scene(QWidget *parent) 
    : QWidget(parent) 
{ 
    auto view = new Qt3DExtras::Qt3DWindow(); 

    // create a container for Qt3DWindow 
    container = createWindowContainer(view,this); 

    // background color 
    view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x575757))); 

    // Root entity 
    auto rootEntity = new Qt3DCore::QEntity(); 

    // Camera 
    auto camera = new Camera(rootEntity,view); 
    auto cameraEntity = view->camera(); 

    cameraEntity->setPosition(QVector3D(0, 0, 50.0f)); 
    cameraEntity->setUpVector(QVector3D(0, 1, 0)); 
    cameraEntity->setViewCenter(QVector3D(0, 0, 0)); 

    // Cuboid 
    auto cuboidMesh = new Qt3DExtras::QCuboidMesh(); 

    // CuboidMesh Transform 
    auto cuboidTransform = new Qt3DCore::QTransform(); 
    cuboidTransform->setScale(10.0f); 
    cuboidTransform->setTranslation(QVector3D(0.0f, 0.0f, 0.0f)); 
    cuboidTransform->setRotation(QQuaternion(1,1.5,1,0).normalized()); 

    auto cuboidMaterial = new Qt3DExtras::QPhongMaterial(); 
    cuboidMaterial->setDiffuse(QColor(QRgb(0x005FFF))); 

    // assamble entity 
    auto cuboidEntity = new Qt3DCore::QEntity(rootEntity); 
    cuboidEntity->addComponent(cuboidMesh); 
    cuboidEntity->addComponent(cuboidMaterial); 
    cuboidEntity->addComponent(cuboidTransform); 

    // Set root object of the scene 
    view->setRootEntity(rootEntity); 
} 

void 
Scene::resizeView(QSize size) 
{ 
    container->resize(size); 
} 

void 
Scene::resizeEvent (QResizeEvent * /*event*/) 
{ 
    resizeView(this->size()); 
} 
Verwandte Themen