예제 #1
0
void ModelReader::render( QGLPainter* painter )
{
    painter->modelViewMatrix().push();
    painter->modelViewMatrix().translate( m_translation );
    painter->modelViewMatrix().rotate( m_quaternion );
    if( !m_z_up )
    {
        painter->modelViewMatrix().rotate( 180, 1, 0, 0 );
    }
    if( m_plyLoader )
    {
        m_plyLoader->draw( painter );
    }
    else
    {
        QGLSceneNode* node = m_scene->mainNode();
    //     painter->setStandardEffect( QGL::LitMaterial ); // no effect ?
        node->draw(painter);
    }
    painter->modelViewMatrix().pop();
    if( !m_label.empty() )
    {
        drawLabel( painter, m_translation );
    }
}
예제 #2
0
StereoView::StereoView(QWidget *parent)
    : QGLView(parent)
{
    scene = new QGLSceneNode(this);

    QGLSceneNode *teapot;
    QGLSceneNode *cube;

    {
        QGLBuilder builder;
        builder << QGLTeapot();
        teapot = builder.finalizedSceneNode();
    }

    {
        QGLBuilder builder;
        builder.newSection(QGL::Faceted);
        builder << QGLCube(1.0f);
        cube = builder.finalizedSceneNode();
    }

    cube->setPosition(QVector3D(-1.0f, 0.0f, 2.0f));
    scene->addNode(teapot);
    scene->addNode(cube);

    QGLMaterial *china = new QGLMaterial(this);
    china->setAmbientColor(QColor(192, 150, 128));
    china->setSpecularColor(QColor(60, 60, 60));
    china->setShininess(128);
    scene->setMaterial(china);
    scene->setEffect(QGL::LitMaterial);

    camera()->setEye(QVector3D(0.0f, 0.0f, 15.0f));
    camera()->setEyeSeparation(0.2f);
}
예제 #3
0
void tst_QGLRender::values()
{
    QGLSceneNode node;   // by default has QGL::FlatColor
    QGLSceneNode node2;
    QSharedPointer<QGLMaterialCollection> pal(new QGLMaterialCollection());
    node.setPalette(pal);
    node2.setPalette(pal);
    node2.setEffect(QGL::LitMaterial);

    QGLRenderState s;
    QGLRenderOrder order(&node, s);
    QGLRenderOrder other(&node2, s);
    QGLRenderOrderComparator cmp;
    QVERIFY(!cmp.isEqualTo(other, order));
    QVERIFY(cmp.isLessThan(order, other));

    QGLRenderState state;
    QGLMaterial *mat = new QGLMaterial;
    mat->setAmbientColor(Qt::blue);
    int ix = pal->addMaterial(mat);
    QGLSceneNode node3;
    node3.setPalette(pal);
    node3.setMaterialIndex(ix);
    node3.setEffect(QGL::LitMaterial);
    state.updateFrom(&node3);
    QGLRenderOrder other2(&node, state);
    QVERIFY(other2.effectiveHasEffect());
    QCOMPARE(other2.effectiveMaterial(), mat);
    QCOMPARE(other2.effectiveStandardEffect(), QGL::LitMaterial);
    QCOMPARE(other2.effectiveUserEffect(), (QGLAbstractEffect*)0);
    QVERIFY(cmp.isLessThan(order, other2));
    QVERIFY(cmp.isLessThan(other, other2));
}
예제 #4
0
void tst_QGLRender::create()
{
    QGLSceneNode node;
    QGLSceneNode node2;
    QSharedPointer<QGLMaterialCollection> pal(new QGLMaterialCollection());
    node.setPalette(pal);
    node2.setPalette(pal);

    QGLRenderState s;
    QGLRenderOrder order(&node, s);
    QGLRenderOrder other(order);     // copy constructor
    QCOMPARE(order.node(), &node);
    QCOMPARE(order.node(), other.node());
    QGLRenderOrderComparator cmp;
    QVERIFY(cmp.isEqualTo(order, other));          // operator==

    QGLRenderOrder other2(&node2, s);
    QVERIFY(cmp.isEqualTo(other2, order));  // same because nodes have same values
    other2 = order;                  // operator=
    QVERIFY(cmp.isEqualTo(other2, order));  // same again

    QGLRenderState state0;
    QGLRenderOrder other3(&node2, state0);
    QVERIFY(cmp.isEqualTo(other2, other3));
}
예제 #5
0
/*!
    Creates a new scene node that is a child of the current node and,
    makes it the current node.  A pointer to the new node is returned.
    The previous current node is saved on a stack and it may
    be made current again by calling popNode().

    \sa popNode(), newNode()
*/
QGLSceneNode *QGLBuilder::pushNode()
{
    if (dptr->currentSection == 0)
        newSection();  // calls newNode()
    QGLSceneNode *parentNode = dptr->currentNode;
    dptr->nodeStack.append(parentNode);
    dptr->currentNode = new QGLSceneNode(parentNode);
    dptr->currentNode->setStart(dptr->currentSection->indexCount());
    dptr->currentNode->setPalette(parentNode->palette());
    return dptr->currentNode;
}
예제 #6
0
/*!
    Removes the node from the top of the stack, makes a copy of it, and
    makes the copy current.

    If the stack is empty, behaviour is undefined.  In debug mode, calling
    this function when the stack is empty will cause an assert.

    A pointer to the new current node is returned.

    The node is set to reference the geometry starting from the next
    vertex created, such that QGLSceneNode::start() will return the
    index of this next vertex.

    \sa pushNode(), newNode()
*/
QGLSceneNode *QGLBuilder::popNode()
{
    if (dptr->currentSection == 0)
        newSection();  // calls newNode()
    int cnt = dptr->currentSection->indexCount();
    QGLSceneNode *s = dptr->nodeStack.takeLast();  // assert here
    QGLSceneNode *parentNode = dptr->rootNode;
    if (dptr->nodeStack.count() > 0)
        parentNode = dptr->nodeStack.last();
    dptr->currentNode = s->cloneNoChildren(parentNode);
    dptr->currentNode->setStart(cnt);
    dptr->currentNode->setCount(0);
    dptr->currentNode->setPalette(parentNode->palette());
    if (dptr->nodeStack.count() == 0)
        dptr->currentSection->addNode(dptr->currentNode);
    return dptr->currentNode;
}
예제 #7
0
/*!
    Creates a new QGLSceneNode and makes it current.  A pointer to the new
    node is returned.  The node is added into the scene at the same level
    as the currentNode().

    The node is set to reference the geometry starting from the next
    vertex created, such that currentNode()->start() will return the
    index of this next vertex.

    \sa newSection()
*/
QGLSceneNode *QGLBuilder::newNode()
{
    if (dptr->currentSection == 0)
    {
        newSection();  // calls newNode()
        return dptr->currentNode;
    }
    QGLSceneNode *parentNode = dptr->rootNode;
    if (dptr->nodeStack.count() > 0)
        parentNode = dptr->nodeStack.last();
    dptr->currentNode = new QGLSceneNode(parentNode);
    dptr->currentNode->setPalette(parentNode->palette());
    dptr->currentNode->setStart(dptr->currentSection->indexCount());
    if (dptr->nodeStack.count() == 0)
        dptr->currentSection->addNode(dptr->currentNode);
    return dptr->currentNode;
}
CylinderView::CylinderView(QWindow *parent)
    : QGLView(parent)
{
    QGLBuilder builder;
    // Evil hack: it is not possible to just call glClearColor on any device
    // but it is possible to have a huge, dark SkyBox. Without this hack the
    // cylinder floats over a transparent background, displaying the contents
    // of the last app
    builder << QGL::Smooth << QGLCube(1000.0f);


    // Add the cylinder
    builder << QGL::Smooth << QGLCylinder(2.0, 1.5, 2.0, 36, 3, true, true);

    QGLMaterial *matLid = new QGLMaterial;
    matLid->setAmbientColor(Qt::gray);
    matLid->setDiffuseColor(Qt::gray);
    QUrl urlLid;
    urlLid.setPath(QLatin1String(":/latte.png"));
    urlLid.setScheme(QLatin1String("file"));
    matLid->setTextureUrl(urlLid);

    QGLMaterial *matSides = new QGLMaterial;
    matSides->setColor(QColor(170, 202, 0));
    QUrl urlSides;
    urlSides.setPath(QLatin1String(":/cupTexture.png"));
    urlSides.setScheme(QLatin1String("file"));
    matSides->setTextureUrl(urlSides);

    QGLSceneNode *root = builder.sceneNode();

    QGLSceneNode *lid = root->findChild<QGLSceneNode *>("Cylinder Top");
    int lidMat = root->palette()->addMaterial(matLid);
    lid->setMaterialIndex(lidMat);
    lid->setEffect(QGL::LitDecalTexture2D);

    QGLSceneNode *sides = root->findChild<QGLSceneNode *>("Cylinder Sides");
    int sideMat = root->palette()->addMaterial(matSides);
    sides->setMaterialIndex(sideMat);
    sides->setEffect(QGL::LitDecalTexture2D);

    cylinder = builder.finalizedSceneNode();

    QGLMaterial *mat = new QGLMaterial;
    mat->setAmbientColor(Qt::gray);
    mat->setDiffuseColor(Qt::gray);
    cylinder->setMaterial(mat);
    cylinder->setEffect(QGL::LitMaterial);
}
예제 #9
0
void tst_QGLRender::repo()
{
    QGLSceneNode node;   // by default has QGL::FlatColor
    QGLSceneNode node2;
    QSharedPointer<QGLMaterialCollection> pal(new QGLMaterialCollection());
    node.setPalette(pal);
    node2.setPalette(pal);
    node2.setEffect(QGL::LitDecalTexture2D);

    QGLRenderState s;
    QGLRenderOrder order(&node, s);
    QGLRenderOrder other(&node2, s);
    QGLRenderOrder order2(&node, s);
    QGLRenderOrderComparator cmp;
    QVERIFY(!cmp.isEqualTo(other, order));
    QVERIFY(cmp.isLessThan(order, other));
    QVERIFY(cmp.isEqualTo(order2, order));
    QCOMPARE(order2.node(), order.node());
}
예제 #10
0
void CubeMesh::createGeometry() {
    QGLSceneNode* geometry;
    QGLBuilder builder;
    builder.newSection(QGL::NoSmoothing);

    QGeometryData quad;
//    QVector3DArray vertices = {
//        0.0, 0.0, 0.0,
//        0.0, 0.0, 1.0
//    };
//    quad.appendVertexArray();

    geometry = builder.finalizedSceneNode();
    geometry->setParent(this);
    if (!d->sceneSet)
    {
        setScene(new CubeScene(d->topNode));
        d->sceneSet = true;
    }
}
예제 #11
0
/*!
  Constructor, the material collection and indexes of 10 materials are given
  to access the materials for each digit.
*/
ScoreDigit::ScoreDigit(QGLMaterialCollection *materialCollection,
                       int materialIndex,
                       const QVector3D &pos,
                       QGLSceneNode *parent)
    : QGLSceneNode(parent)
{
    QGLBuilder builder;
    builder.addPane(0.7f);
    QGLSceneNode *rootNode = builder.finalizedSceneNode();

    addNode(rootNode->children()[0]->clone(this));

    delete rootNode;
    rootNode = 0;

    setPosition(pos);
    setPalette(materialCollection);
    setMaterialIndex(materialIndex);
    setEffect(QGL::FlatReplaceTexture2D);

    // Hide the digit at start
    setValue(-1);
}
예제 #12
0
/* Creates an individual randomly positioned ball */
QGLSceneNode *ModelBall::createNode(QGLMaterial *material) {
    const float defaultSize = 1.0;
    const float positionX = -1.5;
    const float positionY = 40.0;
    const float randomPositionScale = 1000.0;
    QGLBuilder builder;
    QGLSceneNode *node;
    builder.newNode();
    builder << QGLSphere(defaultSize);
    node = builder.finalizedSceneNode();
    node->setMaterial(material);
    node->setEffect(QGL::LitMaterial);
    QGraphicsTranslation3D *trans = new QGraphicsTranslation3D();
    node->addTransform(trans);
    QGraphicsTranslation3D *transStart = new QGraphicsTranslation3D();
    QVector3D *randomStart = new QVector3D(positionX +
                                           randomPosition()/randomPositionScale,
                                           positionY +
                                           randomPosition()/randomPositionScale,
                                           randomPosition()/randomPositionScale);
    transStart->setTranslate(*randomStart);
    node->addTransform(transStart);
    return node;
}
예제 #13
0
/*!
    \internal
*/
void SphereMesh::createGeometry()
{
    // We cache a maximum of 10 levels of detail for lod animations.
    // Create a new geometry node for this level of detail if necessary.
    QGLSceneNode *geometry = d->lodGeometry.value(d->lod, 0);
    if (!geometry) {
        QGLBuilder builder;
        builder.newSection(QGL::Faceted);
        builder << QGLSphere(2.0f, d->lod);
        geometry = builder.finalizedSceneNode();
        geometry->setParent(this);
        d->lodGeometry.insert(d->lod, geometry);
    }
    Q_ASSERT_X(geometry != 0, Q_FUNC_INFO, "Could not create/find geometry!");
    if (d->currentSphere != geometry)
    {
        if (d->currentSphere)
            d->topNode->removeNode(d->currentSphere);
        d->topNode->addNode(geometry);
        d->currentSphere = geometry;
    }

    // Set the radius as a scale on the modelview transformation.
    // This way, we don't have to regenerate the geometry every
    // frame if the radius is being animated.
    if (d->radius != 1.0f)
    {
        if (!d->scale)
        {
            d->scale = new QGraphicsScale3D(d->topNode);
            d->topNode->addTransform(d->scale);
        }
        if (d->scale->scale().x() != d->radius)
        {
            d->scale->setScale(QVector3D(d->radius, d->radius, d->radius));
        }
    }
    else
    {
        // If there is already a scale set it to be the identity scale.
        // This case is optimised for in QGraphicsScale.  Removing it from
        // the transform list is too expensive, especially if the size is
        // being animated, and the next frame will recreate it.
        if (d->scale)
            d->scale->setScale(QVector3D(1, 1, 1));
    }

    // Also rotate the geometry into the correct axis orientation.
    const QVector3D Y_AXIS = QVector3D(0, 1, 0);  // for Qt::XAxis we rotate around Y
    const QVector3D X_AXIS = QVector3D(1, 0, 0);  // for Qt::YAxis we rotate around X
    if (d->axis != Qt::ZAxis && !d->rot)
    {
        d->rot = new QGraphicsRotation3D(d->topNode);
        d->topNode->addTransform(d->rot);
    }
    if (d->axis == Qt::XAxis && d->rot->axis().y() != Y_AXIS.y())
    {
        d->rot->setAxis(Y_AXIS);
        d->rot->setAngle(90.0f);
    }
    else if (d->axis == Qt::YAxis && d->rot->axis().x() != X_AXIS.x())
    {
        d->rot->setAxis(X_AXIS);
        d->rot->setAngle(-90.0f);
    }
    else if (d->axis == Qt::ZAxis && d->rot && d->rot->angle() != 0.0f)
    {
        d->rot->setAngle(0.0f);
        d->rot->setAxis(QVector3D(0, 0, 0));
    }

    if (!d->sceneSet)
    {
        setScene(new SphereScene(d->topNode));
        d->sceneSet = true;
    }
}
예제 #14
0
/*!
    \internal
*/
void CapsuleMesh::createGeometry(bool bForce)
{
    // Create a new geometry node for this level of detail if necessary.
    QGLSceneNode *geometry = 0;
    QMap<int, QGLSceneNode *>::iterator It = d->lodGeometry.find(d->lod);
    if (It != d->lodGeometry.end())
        geometry = *It;
    if (geometry && bForce) {
        if (d->currentCapsule)
            d->topNode->removeNode(d->currentCapsule);
        d->currentCapsule = 0;
        d->lodGeometry.erase(It);
        geometry->setParent(0);
        delete geometry;
        geometry = 0;
    }
    if (!geometry) {
        QGLBuilder builder;

        // For the cylinder
        int facets = 4 * (1 << d->lod);
        int layers =     (1 << d->lod) - 1;

        // For the spheres
        int divisions = d->lod;

        // Sanity check - the height of the capsule must not be less than its
        // diameter.  A minimal capsule is a sphere - where diameter == height.
        if (d->length < 2.0f * d->radius)
        {
            qWarning() << "Length of capsule must exceed its diameter"
                          << " - correcting length.";
            d->length = 2.0f * d->radius;
        }

        float diameter = d->radius+d->radius;
        float cylinderHeight = d->length - diameter;
        float offset = cylinderHeight/2.0f;

        builder << QGL::Faceted;
        QGLSceneNode *s = 0;
        s = builder.newNode();
        s->setObjectName(QLatin1String("Cylinder"));
        builder << QGLCylinder(diameter, diameter, cylinderHeight,
                               facets, layers, false, false);

        s = builder.newNode();
        s->setObjectName(QLatin1String("LeftEndCap"));
        builder << QGLDome(diameter, divisions, false);
        QMatrix4x4 translateMatrix;
        translateMatrix.setToIdentity();
        translateMatrix.rotate(180.0f, 0.0f, 1.0f, 0.0f);
        translateMatrix.translate(0.0f, 0.0f, offset);
        builder.currentNode()->setLocalTransform(translateMatrix);

        s = builder.newNode();
        s->setObjectName(QLatin1String("RightEndCap"));
        builder << QGLDome(diameter, divisions, false);
        translateMatrix.setToIdentity();
        translateMatrix.translate(0.0f, 0.0f, offset);
        builder.currentNode()->setLocalTransform(translateMatrix);

        geometry = builder.finalizedSceneNode();
        geometry->setParent(this);

        d->lodGeometry.insert(d->lod, geometry);
    }
    Q_ASSERT_X(geometry != 0, Q_FUNC_INFO, "Could not create/find geometry!");
    if (d->currentCapsule != geometry)
    {
        if (d->currentCapsule)
            d->topNode->removeNode(d->currentCapsule);
        d->topNode->addNode(geometry);
        d->currentCapsule = geometry;
    }

    if (!d->sceneSet)
    {
        setScene(new CapsuleScene(d->topNode));
        d->sceneSet = true;
    }
}
예제 #15
0
void tst_QGLRender::sequence()
{
    QSKIP("QWidget: Cannot create a QWidget when no GUI is being used");
    QSharedPointer<QGLMaterialCollection> palette(new QGLMaterialCollection());

    // create a yellow lit material
    QGLMaterial *mat = new QGLMaterial;
    mat->setAmbientColor(Qt::yellow);
    int ix0 = palette->addMaterial(mat);

    // create a blue lit material
    mat = new QGLMaterial;
    mat->setAmbientColor(Qt::blue);
    int ix1 = palette->addMaterial(mat);

    // create a grey textured material
    int tx0;
    {
        QImage uv(1024, 1024, QImage::Format_ARGB32);
        uv.fill(qRgba(196, 196, 196, 196));
        mat = new QGLMaterial;
        mat->setAmbientColor(Qt::gray);
        QGLTexture2D *tex = new QGLTexture2D;
        tex->setImage(uv);
        mat->setTexture(tex);
        tx0 = palette->addMaterial(mat);
    }

    QGLSceneNode *scene = new QGLSceneNode;
    scene->setPalette(palette);
    QGLSceneNode *node = 0;
    QGLSceneNode *prim;
    {
        QGLBuilder builder(palette);
        QVector3D a(-1.0f, -1.0f, 0.0f);
        QVector3D b(1.0f, -1.0f, 0.0f);
        QVector3D c(1.0f, 1.0f, 0.0f);
        QGeometryData p;
        p.appendVertex(a, b, c);
        p.generateTextureCoordinates();
        builder.addTriangles(p);
        prim = builder.currentNode();
        prim->setMaterialIndex(ix0);
        builder.newSection();
        QVector3D d(-1.2f, -1.2f, 0.0f);
        QVector3D e(1.2f, -1.2f, 0.0f);
        QVector3D f(1.2f, 1.2f, 0.0f);
        QVector3D g(-1.2f, 1.2f, 0.0f);
        QGeometryData q;
        q.appendVertex(d, e, f, g);
        q.generateTextureCoordinates();
        builder.addQuads(q);
        prim = builder.currentNode();
        prim->setMaterialIndex(ix1);
        node = builder.finalizedSceneNode();
    }

    scene->addNode(node);
    QGLSceneNode *cl = prim->clone(scene);
    cl->setMaterialIndex(tx0);
    cl->setEffect(QGL::LitDecalTexture2D);

    TestView widget(scene);
    if (!widget.context()->isValid())
        QSKIP("GL Implementation not valid");

    TestPainter *ptr = new TestPainter(&widget);

    widget.paintGL(ptr);

    QList<int> starts = ptr->starts();
    QList<int> counts = ptr->counts();
    QCOMPARE(starts.at(0), 0);
    QCOMPARE(counts.at(0), 3);
    QCOMPARE(starts.at(1), 3);
    QCOMPARE(counts.at(1), 6);
}
예제 #16
0
coordinates::coordinates( float size, float thickness ):
    m_node( new QGLSceneNode() )
{
    QGLBuilder builder;
    builder << QGLCylinder( thickness, thickness, size, 12 );
    QGLSceneNode* cylinder = builder.finalizedSceneNode();
    cylinder->setPosition( QVector3D( 0, 0, 0.5 * size ) );
    cylinder->setEffect( QGL::LitMaterial );

    QGLBuilder arrowBuilder;
    arrowBuilder << QGLCylinder( 0.01, 2 * thickness, size / 3, 12 );
    QGLSceneNode* arrow = arrowBuilder.finalizedSceneNode();
    arrow->setPosition( QVector3D( 0, 0, size ) );
    arrow->setEffect( QGL::LitMaterial );
    
    
    QGLSceneNode* x = new QGLSceneNode( m_node );
    x->addNode(cylinder);
    QMatrix4x4 matrix;
    QQuaternion q = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f);
    matrix.rotate( q );
    x->setLocalTransform( matrix );
    QGLSceneNode* xArrow = new QGLSceneNode( m_node );
    xArrow->addNode( arrow );
    xArrow->setLocalTransform( matrix );
    QGLMaterial* xMaterial = new QGLMaterial;
    xMaterial->setDiffuseColor( QColor( 255, 0, 0, 128 ) );
    x->setMaterial( xMaterial );
    xArrow->setMaterial( xMaterial );
    
    QGLSceneNode* y = new QGLSceneNode( m_node );
    y->addNode(cylinder);
    q = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -90.0f);
    matrix.rotate( q );
    y->setLocalTransform( matrix );
    QGLSceneNode* yArrow = new QGLSceneNode( m_node );
    yArrow->addNode( arrow );
    yArrow->setLocalTransform( matrix );
    QGLMaterial* yMaterial = new QGLMaterial;
    yMaterial->setDiffuseColor(Qt::green);
    y->setMaterial( yMaterial );
    QGLMaterial* yArrowMaterial = new QGLMaterial;
    yArrowMaterial->setDiffuseColor( QColor( 0, 255, 0, 128 ) );
    yArrow->setMaterial( yArrowMaterial );
    
    QGLSceneNode* z = new QGLSceneNode( m_node );
    z->addNode(cylinder);
    QGLSceneNode* zArrow = new QGLSceneNode( m_node );
    zArrow->addNode( arrow );
    QGLMaterial* zMaterial = new QGLMaterial;
    zMaterial->setDiffuseColor(Qt::blue);
    z->setMaterial( zMaterial );
    QGLMaterial* zArrowMaterial = new QGLMaterial;
    zArrowMaterial->setDiffuseColor( QColor( 0, 0, 255, 128 ) );
    zArrow->setMaterial( zArrowMaterial );
}