15

私は Qt3D の使用を楽しんでいますが、Qt3D の例はすべてフル ウィンドウ アプリケーションです。例から理解できないのは、qt3d レンダリング ウィンドウを通常の qt GUI アプリケーションに追加する方法です。

基本的に、Qt5 GUI アプリケーション用の小さなレンダリング ウィジェットが必要です。

Qtgl ウィジェットを調べましたが、Qt3D のシーン管理機能を本当に使いたいです。

qt Guiウィンドウ内のサブウィンドウとしてレンダリングするにはどうすればよいですか?

これは可能ですか?

アップデート

だから私はこれを私のMainWindow.cppに追加しまし

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);

これは正しいようです。

私のload_model.cppは次のように始まります:

#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);
    }
}

次のようにクラッシュします。

このアプリケーションは、異常な方法で終了するようランタイムに要求しました。

また、qt アプリケーションの出力では次のようになります。

C ランタイム関数に無効なパラメーターが渡されました。

編集問題の残りのクラスを追加しました

この例では、 https://github.com/Distrotech/qt3d/blob/master/tutorials/qt3d/penguin/main.cppを適応させていることに気付きました:

LoadModelView view;

ただし、と言うと

LoadModelView *view = new LoadModelView(this)

クラッシュ

4

2 に答える 2

8

3D 表示をサポートする QGLWidget を拡張する QGLView クラスをサブクラス化できます。

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 では、関数 QWidget::createWindowContainer() が導入されました。既存の QWindow の QWidget ラッパーを作成し、QWidget ベースのアプリケーション内に存在できるようにする関数。QWidget で QWindow を作成する QWidget::createWindowContainer を使用できます。これにより、Widget-Layouts に QWindow サブクラスを配置できます。このようにして、ウィジェット内に QGLView を埋め込むことができます。

于 2014-04-23T09:14:25.383 に答える