/* * CPlayerRenderer.cpp * $Id: CPlayerRenderer.cpp,v 1.2 2001/11/15 16:54:51 guenth Exp $ * * Copyright (C) 1999, 2000 Markus Janich, Michael Meissner * * 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. * */ // Description : Implementation of the example renderer /** documentation stuff @author Michael Meissner @version 0.0 //see cvs docu */ // Own //////// #include "CPlayerRenderer.h" // Qt /////// #include #include #include #include // only for the menu #include // only for the menu // System /////////// #include #include // defines //////////// #define SELECT_BUF_SIZE 512 // Function : CPlayerRenderer // Parameters : // Purpose : // Comments : CPlayerRenderer::CPlayerRenderer(QGLViewer *pViewer) : QObject() /******************************************************************/ { int i; m_pViewer = pViewer; for (i=0; i<12; i++) m_afSelected[i] = false; m_fLeftButtonPressed = m_fMiddleButtonPressed = m_fRightButtonPressed = false; m_cSphereCenter[0] = CP3D(0.0, 0.0, 1.0); m_cSphereCenter[1] = CP3D(-1.0, 0.0, 0.0); m_cSphereCenter[2] = CP3D(1.0, 0.0, 0.0); m_cSphereCenter[3] = CP3D(0.0, 0.0, -2.5); m_cSphereCenter[4] = CP3D(0.0, -3.0, 0.0); m_cSphereCenter[5] = CP3D(-3.5, 0.0, 0.0); m_cSphereCenter[6] = CP3D(0.0, 0.0, -1.0); m_cSphereCenter[7] = CP3D(0.0, 1.0, 0.0); m_cSphereCenter[8] = CP3D(0.0,-1.0, 0.0); m_cSphereCenter[9] = CP3D(0.0, 0.0, 2.5); m_cSphereCenter[10] = CP3D(0.0, 3.0, 0.0); m_cSphereCenter[11] = CP3D(3.5, 0.0, 0.0); MakeGlList(); return; } // Function : ~CPlayerRenderer // Parameters : // Purpose : // Comments : CPlayerRenderer::~CPlayerRenderer() /**************************************************************/ { glDeleteLists(m_glDispList, 1); } // Function : MakeGlList // Parameters : // Purpose : // Comments : void CPlayerRenderer::MakeGlList() /**************************************************************/ { m_pViewer->makeCurrent(); // generate display list for bounding box /////////////////////////////////////////// if (glIsList(m_glDispList)) glDeleteLists(m_glDispList, 1); m_glDispList = glGenLists(1); glNewList(m_glDispList, GL_COMPILE); glLineWidth(1.5); // Determine bounding box /////////////////////////// CP3D LowerLeft = m_pViewer->getCamera().getBoundingBox().getLowerLeft(); CP3D UpperRight = m_pViewer->getCamera().getBoundingBox().getUpperRight(); // Draw box ///////////// glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINE_LOOP); glVertex3f(LowerLeft[0], LowerLeft[1], LowerLeft[2]); glVertex3f(UpperRight[0], LowerLeft[1], LowerLeft[2]); glVertex3f(UpperRight[0], UpperRight[1], LowerLeft[2]); glVertex3f(LowerLeft[0], UpperRight[1], LowerLeft[2]); glEnd(); glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINE_LOOP); glVertex3f(LowerLeft[0], LowerLeft[1], UpperRight[2]); glVertex3f(UpperRight[0], LowerLeft[1], UpperRight[2]); glVertex3f(UpperRight[0], UpperRight[1], UpperRight[2]); glVertex3f(LowerLeft[0], UpperRight[1], UpperRight[2]); glEnd(); glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINES); glVertex3f(LowerLeft[0], LowerLeft[1], LowerLeft[2]); glVertex3f(LowerLeft[0], LowerLeft[1], UpperRight[2]); glEnd(); glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINES); glVertex3f(UpperRight[0], LowerLeft[1], LowerLeft[2]); glVertex3f(UpperRight[0], LowerLeft[1], UpperRight[2]); glEnd(); glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINES); glVertex3f(UpperRight[0], UpperRight[1], LowerLeft[2]); glVertex3f(UpperRight[0], UpperRight[1], UpperRight[2]); glEnd(); glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINES); glVertex3f(LowerLeft[0], UpperRight[1], LowerLeft[2]); glVertex3f(LowerLeft[0], UpperRight[1], UpperRight[2]); glEnd(); glEndList(); return; } // Function : renderScene // Parameters : ... // Purpose : // Comments : void CPlayerRenderer::renderScene(void) /**************************************************************/ { float mat_specular[] = { .72, .8, .93, 1.0 }; // render bounding box ///////////////////////// glCallList(m_glDispList); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glLineWidth(1.5); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 128.0); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); if(m_afSelected[0]) glColor3f(1.0, 1.0, 1.0); else glColor3f(.5, .5, 1.0); glLoadName(1); // assign name '1' which will reply in selectionmode renderSolidSphere(m_cSphereCenter[0], 1.0,16,16); if(m_afSelected[1]) glColor3f(1.0, 1.0, 1.0); else glColor3f(1.0, 0.0, 0.0); glLoadName(2); // assign name '2' which will reply in selectionmode renderSolidSphere(m_cSphereCenter[1], 1.0,16,16); if(m_afSelected[2]) glColor3f(1.0, 1.0, 1.0); else glColor3f(0.0, 1.0, 0.0); glLoadName(3); // assign name '3' which will reply in selectionmode renderSolidSphere(m_cSphereCenter[2], 1.0,16,16); if(m_afSelected[3]) glColor3f(1.0, 1.0, 1.0); else glColor3f(0.0, 1.0, 1.0); glLoadName(4); // assign name '4' which will reply in selectionmode renderSolidSphere(m_cSphereCenter[3], 0.5,8,8); if(m_afSelected[4]) glColor3f(1.0, 1.0, 1.0); else glColor3f(1.0, 0.0, 1.0); glLoadName(5); // assign name '5' which will reply in selectionmode renderSolidSphere(m_cSphereCenter[4], 0.5,8,8); if(m_afSelected[5]) glColor3f(1.0, 1.0, 1.0); else glColor3f(1.0, 1.0, 0.0); glLoadName(6); // assign name '6' which will reply in selectionmode renderSolidSphere(m_cSphereCenter[5], 0.5,8,8); glDisable(GL_LIGHT0); glDisable(GL_LIGHTING); if(m_afSelected[6]) glColor3f(1.0, 1.0, 1.0); else glColor3f(1.0, 1.0, 0.0); glLoadName(7); // assign name '7' which will reply in selectionmode renderWireSphere(m_cSphereCenter[6], 1.0,16,16); if(m_afSelected[7]) glColor3f(1.0, 1.0, 1.0); else glColor3f(0.0, 0.0, 1.0); glLoadName(8); // assign name '8' which will reply in selectionmode renderWireSphere(m_cSphereCenter[7], 1.0,16,16); if(m_afSelected[8]) glColor3f(1.0, 1.0, 1.0); else glColor3f(1.0, 0.0, 1.0); glLoadName(9); // assign name '9' which will reply in selectionmode renderWireSphere(m_cSphereCenter[8], 1.0,16,16); if(m_afSelected[9]) glColor3f(1.0, 1.0, 1.0); else glColor3f(1.0, 0.0, 0.0); glLoadName(10); // assign name '10' which will reply in selectionmode renderWireSphere(m_cSphereCenter[9], 0.5,16,16,1.0); if(m_afSelected[10]) glColor3f(1.0, 1.0, 1.0); else glColor3f(0.0, 1.0, 0.0); glLoadName(11); // assign name '11' which will reply in selectionmode renderWireSphere(m_cSphereCenter[10], 0.5,16,16,1.0); if(m_afSelected[11]) glColor3f(1.0, 1.0, 1.0); else glColor3f(0.0, 0.0, 1.0); glLoadName(12); // assign name '12' which will reply in selectionmode renderWireSphere(m_cSphereCenter[11], 0.5,16,16,1.0); return; } // Function : renderSolidSphere // Parameters : ... // Purpose : // Comments : void CPlayerRenderer::renderSolidSphere(const CP3D &cCenter, float radius, int n1,int n2,float lw) /**************************************************************/ { static GLUquadricObj *quadObj; static int entry = 0; int sphere_slices = n1; int sphere_stacks = n2; glEnable(GL_COLOR_MATERIAL); glPushMatrix(); glTranslatef(cCenter.getX(), cCenter.getY(), cCenter.getZ()); quadObj = gluNewQuadric (); if (!entry) { gluQuadricDrawStyle (quadObj, (GLenum)GLU_FILL); gluQuadricOrientation(quadObj, (GLenum)GLU_OUTSIDE); gluQuadricNormals (quadObj, (GLenum)GLU_SMOOTH); } gluSphere (quadObj, radius, sphere_slices, sphere_stacks); gluDeleteQuadric(quadObj); glPopMatrix(); glDisable(GL_COLOR_MATERIAL); return; } // Function : renderWireSphere // Parameters : ... // Purpose : // Comments : void CPlayerRenderer::renderWireSphere(const CP3D &cCenter, float radius, int n1,int n2,float lw) /**************************************************************/ { static GLUquadricObj *quadObj; static int entry = 0; int sphere_slices = n1; int sphere_stacks = n2; glLineWidth(lw); glEnable(GL_COLOR_MATERIAL); glPushMatrix(); glTranslatef(cCenter.getX(), cCenter.getY(), cCenter.getZ()); quadObj = gluNewQuadric (); if (!entry) { gluQuadricDrawStyle (quadObj, (GLenum)GLU_LINE); gluQuadricOrientation(quadObj, (GLenum)GLU_OUTSIDE); gluQuadricNormals (quadObj, (GLenum)GLU_SMOOTH); } gluSphere (quadObj, radius, sphere_slices, sphere_stacks); gluDeleteQuadric(quadObj); glPopMatrix(); glDisable(GL_COLOR_MATERIAL); return; } // Function : sltCatchKey // Parameters : int nTmp // Purpose : // Comments : void CPlayerRenderer::sltCatchKey(int nTmp) /**************************************************************/ { cout << "CPlayerRenderer: Caught the signal! It is a " << nTmp; cout << " (ascii)" << endl; return; } // Function : sltResetSelection // Parameters : // Purpose : Slot to reset selection // Comments : void CPlayerRenderer::sltResetSelection() /**************************************************************/ { int i; for (i=0; i<12; i++) m_afSelected[i] = false; m_pViewer->sltUpdateView(); return; } // Function : sltInitializeGL // Parameters : // Purpose : Set up the OpenGL rendering state // Comments : void CPlayerRenderer::sltInitializeGL() /**************************************************************/ { m_pViewer->makeCurrent(); glClearColor(0.0, 0.0, 0.0, 0.0); // Let OpenGL clear to black glShadeModel(GL_FLAT); // enable flat shading glMatrixMode(GL_MODELVIEW); return; } // Function : sltResizeGL // Parameters : // Purpose : // Comments : if something special should be done after resizing void CPlayerRenderer::sltResizeGL(int w, int h) /**************************************************************/ { return; } // Function : sltPaintGL // Parameters : // Purpose : Slot for paint "events" // Comments : Actual openGL commands for drawing box are performed void CPlayerRenderer::sltPaintGL() /**************************************************************/ { // now render your own stuff ////////////////////////////// renderScene(); return; } // Function : sltManageSelection // Parameters : // Purpose : // Comments : void CPlayerRenderer::sltManageSelection(QMouseEvent *pqEvent) /**************************************************************/ { GLuint selectBuf[SELECT_BUF_SIZE]; // HARD coded limit!!! GLint hits; GLint viewport[4]; double ardVVolume[6]; unsigned int nChosen; // 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(); if(m_fLeftButtonPressed) { // 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); renderScene(); glPopMatrix(); glFlush(); hits = glRenderMode(GL_RENDER); nChosen = processHits(hits, selectBuf); if(nChosen>0) m_afSelected[nChosen-1] = m_afSelected[nChosen-1] ? false : true; m_pViewer->sltUpdateView(); } return; } // Function : processHits // Parameters : // Purpose : processHits prints out the contents of the selection array // Comments : GLuint CPlayerRenderer::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; jbutton() == LeftButton ) { m_fLeftButtonPressed = false; } if ( pqEvent->button() == MidButton ) { m_fMiddleButtonPressed = false; } if ( pqEvent->button() == RightButton ) { m_fRightButtonPressed = false; } } // Function : sltManageMove // Parameters : // Purpose : // Comments : void CPlayerRenderer::sltManageMove(QMouseEvent *pqEvent) /**************************************************************/ { int i, nDiffX, nDiffY; float rfDistance, rfTransX, rfTransY, rfVTan, rfHTan; CCamera *pCamera; CP3D cNewCenter; if(m_fMiddleButtonPressed) { nDiffX = pqEvent->x() - m_nMousePosX; nDiffY = m_nMousePosY - pqEvent->y(); pCamera = m_pViewer->getCameraPtr(); // save mouse position //////////////////////// m_nMousePosX = pqEvent->x(); m_nMousePosY = pqEvent->y(); // now do the move ///////////////////// for(i=0; i<12; i++) { if(m_afSelected[i]) { // calculations just heuristic. Don't really try to understand it. rfDistance = (m_cSphereCenter[i] - pCamera->getEyePos()).getNorm(); rfVTan = tan(pCamera->getFovy()/360.0*M_PI); rfHTan = tan((pCamera->getFovy()*pCamera->getRatio()) / 360.0 * M_PI); rfTransX = (rfHTan * float(nDiffX)) / m_pViewer->getDrawArea()->width() * rfDistance * 2.1; rfTransY = (rfVTan * float(nDiffY)) / m_pViewer->getDrawArea()->height() * rfDistance * 2.1; cNewCenter = m_cSphereCenter[i] + pCamera->getViewRight() * rfTransX + pCamera->getViewUp() * rfTransY; if(pCamera->getBoundingBox().isInside(cNewCenter)) m_cSphereCenter[i] = cNewCenter; } } m_pViewer->sltUpdateView(); } return; }