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); }
/*! 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; }
/*! 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; }
/*! 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; }