src/qvgui/qvglcanvas.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00024 
00025 #include <qvgui/qvglcanvas.h>
00026 #include <qvip/qvipp/qvipp.h>
00027 #include <qvmath/qvmatrixalgebra.h>
00028 #include <QMouseEvent>
00029 #include <qvcore/qvdefines.h>
00030 
00031 #define GL_VIEW_ASPECT   1.333
00032 
00033 QVGLCanvas::QVGLCanvas(const QString &title, QWidget* parent):
00034         QGLWidget(parent), maxwide(2.0), cx(0.0), cy(0.0), cz(0.0),
00035         trackballQuat(QVQuaternion::trackball(0.0, 0.0, 0.0, 0.0)),
00036         zoom(45), pressedleft(FALSE), pressedright(FALSE)
00037         {
00038         resize(400,(int)(400/GL_VIEW_ASPECT));
00039         setWindowTitle(title);
00040         show();
00041         }
00042 
00043 QVGLCanvas::~QVGLCanvas ()
00044         {
00045         // FIXME: is it needed?: makeCurrent(); 
00046         }
00047 
00051 void QVGLCanvas::linkModelMatrix(QVWorker &worker, const QString &matrixPropertyName, const QString &objectName)
00052         {
00054         worker.linkProperty(matrixPropertyName, this, objectName + " matrix", QVWorker::AsynchronousLink);
00055 
00057         QObject::connect(&worker, SIGNAL(endIteration()), this, SLOT(updateGL()));
00058         }
00059 
00060 void QVGLCanvas::add(const QV3DModel &model, const QString &name)
00061         {
00062         addProperty<QV3DModel>(name, inputFlag | outputFlag, model, name + " 3d object model");
00063         addProperty<QVMatrix>(name + " matrix", inputFlag | outputFlag, QVMatrix::identity(4), name + " 3d location matrix");
00064         }
00065 
00066 void QVGLCanvas::initializeGL()
00067         {
00068         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00069 
00070         glDisable(GL_CULL_FACE);
00071         glEnable(GL_DEPTH_TEST);
00072         
00073         glEnable(GL_DITHER);
00074         glShadeModel(GL_SMOOTH);
00075         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
00076         glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
00077         
00078         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
00079         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
00080         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
00081 
00082         glEnable(GL_DEPTH_TEST);
00083         glEnable(GL_CULL_FACE);
00084         glEnable(GL_TEXTURE_2D);
00085 
00086         init();
00087         }
00088 
00089 void QVGLCanvas::drawModels()
00090         {
00091         readInputProperties();
00092 
00093         glScaled((GLdouble)1/maxwide,(GLdouble)1/maxwide,(GLdouble)1/maxwide);
00094 
00095         foreach(QString name, getPropertyListByType<QV3DModel>())
00096                 {
00097                 QV3DModel model = getPropertyValue<QV3DModel>(name);
00098                 QVMatrix matrix = getPropertyValue<QVMatrix>(name + " matrix");
00099 
00100                 //std::cout << "maxwide = " << maxwide << std::endl;
00101                 //std::cout << "Matrix = " << matrix << std::endl;
00102                 //std::cout << "Model: '" << qPrintable(name) << "'." << std::endl;
00103                 if (matrix.getCols() == 4 && matrix.getRows() == 4)
00104                         {
00105                         glPushMatrix();
00106 
00108                         GLfloat m[4][4];
00109                         QVMatrix M = pseudoInverse(matrix);
00110 
00111                         for (int i=0; i <4; i++)
00112                                 for (int j=0; j <4; j++)
00113                                         m[i][j] = matrix(i,j);
00114 
00115                         for (int i=0; i <3; i++)
00116                                 { m[3][i] = 0; m[i][3] = 0; }
00117 
00118                         glTranslated(-M(0,3), -M(1,3), -M(2,3));
00119 
00120                         glMultMatrixf(&m[0][0]);
00121                         
00122                         model.paint(*this);
00123                         glPopMatrix();
00124 
00125                         glFlush();
00126                         }
00127                 else
00128                         model.paint(*this);
00129                 }
00130         }
00131 
00132 void QVGLCanvas::paintGL()
00133         {
00134         glMatrixMode(GL_PROJECTION);
00135 
00136         glLoadIdentity();
00137         gluPerspective(zoom,(float)size().width()/(float)size().height(),1,100);
00138         glMatrixMode(GL_MODELVIEW);
00139 
00140         glLoadIdentity();
00141         
00142         glTranslatef(0,0,-4); 
00143         glScaled((GLdouble)1/maxwide,(GLdouble)1/maxwide,(GLdouble)1/maxwide);
00144 
00145 
00146         GLfloat m[4][4];
00147         QVMatrix M(trackballQuat);
00148 
00149         for (int i=0; i <4; i++)
00150                 for (int j=0; j <4; j++)
00151                         m[i][j] = M(i,j);
00152 
00153         glMultMatrixf(&m[0][0]);
00154         
00155         glRotatef(270,1,0,0); 
00156         
00157         glTranslatef(-cx,-cy,-cz); 
00158 
00159         glClearColor(.5, .5, .75, 1.0);
00160         glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00161 
00162         drawModels();
00163 
00164         display();
00165         }
00166 
00167 void QVGLCanvas::resizeGL( int w, int h )
00168         {
00169         glViewport(0,0,w,h); 
00170         reshape(w,h);
00171 
00172         drawModels();
00173         }
00174 
00178 
00179 void QVGLCanvas::mousePressEvent(QMouseEvent *event)
00180 {
00181     beginx = event->x();
00182     beginy = event->y();
00183     if(event->button() == Qt::LeftButton) {
00184         pressedleft = TRUE;
00185     } else if(event->button() == Qt::RightButton) {
00186         pressedright = TRUE;
00187     }
00188 }
00189 
00190 void QVGLCanvas::mouseReleaseEvent(QMouseEvent *event)
00191 {
00192     if(event->button() == Qt::LeftButton) {
00193         pressedleft = FALSE;
00194     } else if(event->button() == Qt::RightButton) {
00195         pressedright = FALSE;
00196     }
00197 }
00198 
00199 void QVGLCanvas::mouseMoveEvent(QMouseEvent *event)
00200 {
00201     int x,y;
00202 
00203     x = (int) event->x();
00204     y = (int) event->y();
00205 
00206     if (pressedleft) {
00207         QVQuaternion spinQuat = QVQuaternion::trackball(
00208                         (2.0*beginx - size().width())   / size().width(),
00209                         (size().height() - 2.0*beginy)  / size().height(),
00210                         (2.0*x - size().width())        / size().width(),
00211                         (size().height() - 2.0*y)       / size().height());
00212 
00213         trackballQuat = spinQuat * trackballQuat;
00214         updateGL();
00215     }
00216 
00217     if (pressedright) {
00218         /* zooming drag */
00219         //printf("MouseMove right button\n");
00220         zoom += ((y - beginy) / size().height()) * 40;
00221         if (zoom < 5) zoom = 5;
00222         if (zoom > 120) zoom = 120;
00223         /* zoom has changed, redraw  */
00224         updateGL();
00225     }
00226     beginx = x;
00227     beginy = y;
00228 }
00229 
00230 void QVGLCanvas::wheelEvent(QWheelEvent *event)
00231 {
00232     /* zooming wheel */
00233     zoom -= event->delta()/32;
00234     if (zoom < 5) zoom = 5;
00235     if (zoom > 120) zoom = 120;
00236     /* zoom has changed, redraw  */
00237     updateGL();
00238 }
00239 
00240 
00241 
00242 void QVGLCanvas::keyPressEvent(QKeyEvent *event)
00243 {
00244     //printf("KeyPress\n");
00245     switch(event->key()) {
00246       case Qt::Key_Left:
00247         cx -= maxwide/20;
00248         break;
00249       case Qt::Key_Right:
00250         cx += maxwide/20;
00251         break;
00252       case Qt::Key_Up:
00253         cy += maxwide/20;
00254         break;
00255       case Qt::Key_Down:
00256         cy -= maxwide/20;
00257         break;
00258       case Qt::Key_PageUp:
00259         cz += maxwide/20;
00260         break;
00261       case Qt::Key_PageDown:
00262         cz -= maxwide/20;
00263         break;
00264     }
00265     /* Ha cambiado el centro, redibujar: */
00266     updateGL();
00267 }
00268 
00269 void QVGLCanvas::closeEvent(QCloseEvent * event)
00270 {
00271         Q_UNUSED(event);
00272     emit closed();
00273 }
00274 
00276 
00277 int nearest_gl_texture_size(int v)
00278         {
00279         int n = 0, last = 0;
00280         for (int s = 0; s < 32; ++s)
00281                 {
00282                 if (((v>>s) & 1) == 1)
00283                         {
00284                         n++;
00285                         last = s;
00286                         }
00287                 }
00288 
00289         if (n > 1)
00290                 return 1 << (last+1);
00291         return 1 << last;
00292         }
00293 
00294 GLuint QVGLCanvas::bindTexture(const QVImage<uChar,3> &image, GLenum target)
00295         {
00296         const uInt cols = image.getCols(), rows = image.getRows(), step = image.getStep();
00297         bool clean = false;
00298 
00299         // Scale the pixmap if needed. GL textures needs to have the
00300         // dimensions 2^n+2(border) x 2^m+2(border).
00301         int textureImage_w = nearest_gl_texture_size(cols);
00302         int textureImage_h = nearest_gl_texture_size(rows);
00303 
00304         QVImage<uChar,3> textureImage(textureImage_w, textureImage_h);
00305         Resize(image, textureImage);
00306 
00307         GLuint textureImage_id;
00308         glGenTextures(1, &textureImage_id);
00309         glBindTexture(target, textureImage_id);
00310         glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00311         glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
00312         glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
00313         glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00314         glTexImage2D(target, 0, GL_RGB, textureImage_w, textureImage_h, 0, GL_BGR, GL_UNSIGNED_BYTE, textureImage.getReadData());
00315 
00316         return textureImage_id;
00317         }

Generated on Thu Jul 17 17:23:28 2008 for QVision by  doxygen 1.5.3