/* * QSceneTreeRenderer.h * $Id: QSceneTreeRenderer.cpp,v 1.13 2002/04/03 11:00:16 jhirche Exp $ * * Copyright (C) 2001 Richard Guenther, Markus Janich * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * As a special exception to the GPL, the QGLViewer authors (Markus * Janich, Michael Meissner, Richard Guenther, Alexander Buck and Thomas * Woerner) give permission to link this program with Qt (non-)commercial * edition, and distribute the resulting executable, without including * the source code for the Qt (non-)commercial edition in the source * distribution. * */ // Qt /////// #include // Own //////// #include "QSceneTreeRenderer.h" QSceneTreeRenderer::QSceneTreeRenderer(QGLViewer *pViewer) : QObject(), QSceneTreeNode(), m_pViewer(pViewer) /*************************************************************/ { m_fNeedUpdate = false; m_pTimer = NULL; } QSceneTreeRenderer::~QSceneTreeRenderer() /*************************************************************/ { /* m_pTimer automagically gets destroyed after this */ } void QSceneTreeRenderer::sltPollUpdate() /*************************************************************/ { if (!m_fNeedUpdate) return; m_fNeedUpdate = false; /* somehow trigger an sltPaintGL() signal is the follwing ok? */ m_pViewer->sltUpdateView(); } void QSceneTreeRenderer::requestUpdate() /*************************************************************/ { m_fNeedUpdate = true; if (m_pTimer) return; /* Install a timer routine that polls on this flag * and will issue an update and clear the flag. */ m_pTimer = new QTimer(this); connect(m_pTimer, SIGNAL(timeout()), SLOT(sltPollUpdate())); m_pTimer->start(1000/20 /* 20 fps */, FALSE); } void QSceneTreeRenderer::sltInitializeGL() /*************************************************************/ { /* Do we need this? -- At least we should provide a sane default. */ m_pViewer->makeCurrent(); glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel( GL_SMOOTH ); // enable smooth shading glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* add other stuff */ } void QSceneTreeRenderer::traverseTree(int &nId, QSceneTreeNode *node) { /* Check, if this node is hidded. */ if ((node->getViewingMode() == QSceneTreeNode::hidden)||(node->getViewingMode() == QSceneTreeNode::disabled)) return; /* Apply matrix, if available. */ if (node->getTransformation()) { glPushMatrix(); glMultMatrixd(((CMat4D *)node->getTransformation())->getArray()); } QSceneTreeDrawable *pObj; if ((pObj = dynamic_cast(node))) { glLoadName(nId++); pObj->draw(); } const CList &children = node->getChildrenList(); CListContainer *pContainer = children.getFirst(); while (pContainer) { QSceneTreeNode *pNode; if ((pNode = dynamic_cast(pContainer->getObject()))) traverseTree(nId, pNode); pContainer = pContainer->getNext(); } /* Redo matrix apply. */ if (node->getTransformation()) glPopMatrix(); } void QSceneTreeRenderer::sltPaintGL() /*************************************************************/ { m_pViewer->makeCurrent(); glMatrixMode(GL_MODELVIEW); /* Traverse the scene tree, apply the matrices and call * draw() methods of QSceneTreeDrawable objects. */ /* We cannot use generic traversors as they dont provide a * walk-up hook for popping the matrix. */ int nId=1; traverseTree(nId, this); } // Function : sltManageSelection // Parameters : // Purpose : // Comments : void QSceneTreeRenderer::sltManageSelection(QMouseEvent *pqEvent) /**********************************************************************/ { GLuint selectBuf[SELECT_BUF_SIZE]; // HARD coded limit!!! GLint hits; GLint viewport[4]; double ardVVolume[6]; // Save state of mouse buttons //////////////////////////////// if ( pqEvent->button() == LeftButton ) { m_fLeftButtonPressed = true; } if ( pqEvent->button() == MidButton ) { m_fMiddleButtonPressed = true; } if ( pqEvent->button() == RightButton ) { m_fRightButtonPressed = true; } // save mouse position //////////////////////// m_nMousePosX = pqEvent->x(); m_nMousePosY = pqEvent->y(); // get camera data //////////////////// m_pViewer->getCameraPtr()->getVVolume(ardVVolume); m_pViewer->makeCurrent(); glGetIntegerv(GL_VIEWPORT, viewport); glSelectBuffer(SELECT_BUF_SIZE, selectBuf); glRenderMode(GL_SELECT); glInitNames(); glPushName(0); glPushMatrix(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // create 10x10 pixel picking region near cursor location. //////////////////////////////////////////////////////////// gluPickMatrix((GLdouble) m_nMousePosX, (GLdouble) (viewport[3] - m_nMousePosY), 5.0, 5.0, viewport); if (m_pViewer->getProjectionMode() == QGLViewer::perspective) glFrustum(ardVVolume[0], ardVVolume[1], ardVVolume[2], ardVVolume[3], ardVVolume[4], ardVVolume[5]); else glOrtho(ardVVolume[0], ardVVolume[1], ardVVolume[2], ardVVolume[3], ardVVolume[4], ardVVolume[5]); glMatrixMode(GL_MODELVIEW); sltPaintGL(); // render scene in selection mode glPopMatrix(); glFlush(); hits = glRenderMode(GL_RENDER); m_nChosen = processHits(hits, selectBuf); m_pViewer->sltUpdateView(); return; } // Function : sltManageRelease // Parameters : // Purpose : // Comments : void QSceneTreeRenderer::sltManageRelease(QMouseEvent *pqEvent) /**********************************************************************/ { // Save state of mouse buttons //////////////////////////////// if ( pqEvent->button() == LeftButton ) { m_fLeftButtonPressed = false; } if ( pqEvent->button() == MidButton ) { m_fMiddleButtonPressed = false; } if ( pqEvent->button() == RightButton ) { m_fRightButtonPressed = false; } } // Function : sltManageMove // Parameters : // Purpose : // Comments : void QSceneTreeRenderer::sltManageMove(QMouseEvent *pqEvent) /**********************************************************************/ { } // Function : processHits // Parameters : // Purpose : processHits prints out the contents of the selection array // Comments : GLuint QSceneTreeRenderer::processHits(GLint hits, GLuint buffer[]) /********************************************************************/ { unsigned int i, j; GLuint names, nChosen, *ptr; float rfZValue, rfZ1; if(hits != 0) { nChosen = 1; rfZValue = (float)*(buffer+1)/0x7fffffff; cout << "Number of hits is = " << hits << endl; cout << "Now show all hits!" << endl; ptr = (GLuint *) buffer; for (i=0; i= rfZ1) { rfZValue = rfZ1; nChosen = *ptr; } for (j=0; j