QGLWidget有2种渲染模式

时间:2013-05-16 16:37:42

标签: qt opengl opencv qglwidget

我在Qt中有一个OpenGL小部件(继承自QGLWidget),有2种渲染模式:

  1. 呈现默认多维数据集(#define CUBE_MODE 0)。
  2. 呈现opencv图像(#define IMAGE_MODE 1)。
  3. 我有一个公共方法来设置要渲染的模式(void setRenderMode(int mode)) 我还有一个包含2个项目的组合框:Cube和Image。

    我希望当我单击组合框中的项目(例如多维数据集)时,openGL小部件显示多维数据集,当我单击其他项目(图像)时,小组件显示图像。所以我使用插槽/信号系统来做到这一点。

    窗口正确启动,并显示立方体,但是当我切换到图像时,窗口小部件不显示图像,当我尝试返回到立方体项目时,它没有。 (当我在没有组合框的情况下单独使用时,2种模式可以正常工作。)

    以下是我的代码片段:

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
    {
    ui -> setupUi(this);
    
    openglWidget = new GLWidget();
    openglWidget->setRenderMode(0);
    
    
    ui->verticalLayout->addWidget(openglWidget);
    
    connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(showModel(int)));
    
    }
    
    void MainWindow::showModel(int index)
    {
    switch(index)
    {
    case 0:
        openglWidget->setRenderMode(0);     
        break;
    
    case 1:
        openglWidget->setRenderMode(1);
    
        break;
    }
    }
    

    paintGL方法是:

    void GLWidget::paintGL()
    {
    
    makeCurrent();
    
    if( !mSceneChanged )
        return;
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    switch( mPaintMode )
    {
    case POINT_CLOUD_MODE:
    {
        renderPointCloud();
    }
    break;
    
    case IMAGE_MODE:
        renderImage();
        break;
    
    default:
        renderDefaultCube();
    }
    
    }
    

    更新

    渲染图像代码:

    void GLWidget::renderImage()
    {
    makeCurrent();
    
    glClear (GL_COLOR_BUFFER_BIT);
    
    glDisable(GL_DEPTH_TEST);
    
    if (!mImage.isNull())
    {
        glLoadIdentity();
    
        glPushMatrix();
        {
            int imW = mImage.width();
            int imH = mImage.height();
    
            bool resized = false;
    
            if( imW != this->size().width() &&
                    imH != this->size().height() )
            {
                mImage = mImage.scaled( this->size(),
                                        Qt::KeepAspectRatio,
                                        Qt::FastTransformation );
    
                resized = true;
            }
    
            //Centering image in draw area
            int posX = (this->size().width()-imW)/2;
            int posY = (this->size().height()-imH)/2;
    
            glRasterPos2i( posX, posY );
            //Centering image in draw area
    
            glDrawPixels( mImage.width(), mImage.height(),
                          GL_RGBA, GL_UNSIGNED_BYTE, mImage.bits());
    
            if( resized)
            {
                imW = mImage.width();
                imH = mImage.height();
    
    
            }
        }
        glPopMatrix();
    
    
        glFlush();
    }
    
    glEnable(GL_DEPTH_TEST);
    
    }
    

    和setFrame方法:

    void GLWidget::setFrameImage(Mat img )
    {
    if( !img.data )
    {
        qDebug( "Warning: No Image to be set");
        return;
    }
    
    if( img.channels() == 3)
        mImage = QImage((const unsigned char*)(img.data), img.cols, img.rows,
                        img.step, QImage::Format_RGB888);
    else if( img.channels() == 1)
        mImage = QImage((const unsigned char*)(img.data), img.cols, img.rows,
                        img.step, QImage::Format_Indexed8);
    else
        return;
    
    mImage = QGLWidget::convertToGLFormat(mImage);
    
    mSceneChanged = true;
    
    updateGL();
    }
    

    更新#2

    我将paintGL修改为:

    void GLWidget::paintGL()
    {
    
    makeCurrent();
    
    if( !mSceneChanged )
    return;
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    switch( mPaintMode )
    {
    case CUBE_MODE:
    {
    renderDefaultCube();
    }
    break;
    
    case IMAGE_MODE:
    renderImage();
    break;
    
    
    }
    
    }
    

    当我设置openglWidget - > setRenderMode(0);我只能看到立方体,但当我点击组合框上的图像项目时,我看不到任何东西,反之亦然,当我设置openglWidget - > setRenderMode(1)。

    更新#3 :完整的源代码

    GLWidget.h

    #include <map>
    #include <string>
    
    #include <QtOpenGL/QGLWidget>
    #include <QtOpenGL/QtOpenGL>
    
    #include <GL/glut.h>
    #include <GL/gl.h>
    #include <GL/glu.h>
    
    
    #include <opencv2/core/core.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/highgui/highgui.hpp>
    
    #include "rk_geometry.h"
    
    
    
     using namespace std;
     using namespace cv;
    
    
     #define CUBE_MODE 0
     #define IMAGE_MODE 1
    
     #define PLANE_XY 0
     #define PLANE_XZ 1
     #define PLANE_YZ 2
    
    
     class GLWidget : public QGLWidget
     {
     Q_OBJECT
    
     public:
     GLWidget(QWidget *parent = 0);
    
    
    
     protected:
     void        initializeGL(); 
     void        paintGL(); 
     void        mousePressEvent(QMouseEvent *event);    
     void        mouseMoveEvent(QMouseEvent *event);     
     void        keyPressEvent ( QKeyEvent * event );    
     void        resizeGL(int width, int height);        
    
    
     void        renderImage();          
     void        renderDefaultCube();    
    
     private:
     void        drawAxis();     
     void        drawGridXY();  
     void        drawGridXZ();  
     void        drawGridYZ();   
     void        drawCameraTargetSphere(); 
     void        drawCloudBox( cloud_rgb_t::Ptr cloud, int r, int g, int b);
    
    
    
     public slots:
     void        doPitch(double angle);  
     void        doRoll(double angle);  
     void        doYaw(double angle);   
    
     void        updateScene(); 
    
     void        setRenderMode( int renderMode );    
    
     void        setFrameImage( Mat img );
    
     void        resetView( bool update=false );
     void        topView(); 
    
     bool        showCameraTarget( bool show=true);      
     bool        showGrid( int idx, bool show=true );    
     bool        showBoxes(bool show=true);              
    
    
    
     private:
     float       mZoom;                 
    
     rkGeom::CPoint position;            
     rkGeom::CVector forward;           
     rkGeom::CVector up;                 
     rkGeom::CVector right;              
    
     int         mPtSize;               
    
     QColor      qtBlack;              
    
     QPoint      lastPos;                
    
    
    
     bool        mShowGrid[3];          
     bool        mDrawBoxes;             
    
     int         mPaintMode;            
    
     QImage      mImage;                 
    
    
     bool        mShowCameraTarget;    
    
    
    
    
    
     };
    

    GLWidget.cpp

      #include "GLWidget.h"
    
    
    
        #define MIN_CAM_DIST 0.25f  
        #define MOV_STEP     0.05f  
    
        GLWidget::GLWidget(QWidget *parent) :
        QGLWidget(QGLFormat(QGL::SampleBuffers), parent),
        position(0,0,0),
        forward(0, 0, -1),
        up(0, 1, 0),
        right(1, 0, 0)
        {
        mZoom = MIN_CAM_DIST;
        mDrawBoxes = false;
    
        qtBlack = QColor::fromRgb(0, 0, 0);
    
    
        mPaintMode = -1;
    
        setFocusPolicy( Qt::ClickFocus );
    
        mShowCameraTarget = true;
    
        mPtSize = 1;
    
        mShowGrid[0] = true;
        mShowGrid[1] = false;
        mShowGrid[2] = false;
    
        resetView(false);
        }
    
    
        void GLWidget::initializeGL()
        {
    
        makeCurrent();
        qglClearColor(qtBlack.darker());
    
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_CULL_FACE);
        glEnable(GL_TEXTURE_2D);
        glShadeModel(GL_SMOOTH);
    
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glEnable(GL_BLEND);
    
    
        }
    
        void GLWidget::resizeGL(int width, int height)
        {
    
        makeCurrent();
        glViewport(0, 0, (GLint)width, (GLint)height);
    
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
    
        if( mPaintMode == CUBE_MODE )
            gluPerspective( 60.0, double(width)/height, 0.01, 200000 );
        else if( mPaintMode == IMAGE_MODE )
            glOrtho(0, width, 0, height, 0, 1);     
    
    
    
        glMatrixMode(GL_MODELVIEW);
    
        }
    
        void GLWidget::paintGL()
        {
    
        makeCurrent();
    
    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        switch( mPaintMode )
        {
        case CUBE_MODE:
        {
    
            renderDefaultCube();
        }
        break;
    
        case IMAGE_MODE:
            renderImage();
            break;
    
    
        }
    
        }
    
        void GLWidget::mousePressEvent(QMouseEvent *event)
        {
        if( mPaintMode == IMAGE_MODE )
            return;
    
        lastPos = event->pos();
        }
    
        void GLWidget::mouseMoveEvent(QMouseEvent *event)
        {
        if( mPaintMode == IMAGE_MODE )
            return;
    
        float dx = (float)(event->x() - lastPos.x());
        float dy = (float)(event->y() - lastPos.y());
    
    
        if (event->buttons() & Qt::LeftButton)
        {
            doPitch( DEG2RAD(dy));
            doYaw( DEG2RAD(-dx));
    
            updateGL();
        }
        else if (event->buttons() & Qt::RightButton)
        {
    
            mZoom += dx*0.1;
    
            if( mZoom < MIN_CAM_DIST )
                mZoom = MIN_CAM_DIST;
    
            updateGL();
        }
    
        else if (event ->buttons() & Qt::MidButton)
        {
            if (dx > 0)
                position.z += 100;
    
            if (dx < 0)
                position.z -= 100;
    
    
    
            updateGL();
        }
    
        lastPos = event->pos();
        }
    
        void GLWidget::keyPressEvent ( QKeyEvent * event )
        {
        float dx, dy, dz;
        dx = dy = dz = 0.0f;
    
    
    
        if ( event->key() == Qt::Key_A ) 
        {
            doRoll(DEG2RAD(1));
        } else if ( event->key() == Qt::Key_D ) 
        {
            doRoll(DEG2RAD(-1));
        }
        else if ( event->key() == Qt::Key_Up ) 
        {
            position += MOV_STEP*forward;
        }else if ( event->key() == Qt::Key_Down ) 
        {
            position -= MOV_STEP*forward;
        }
        else if ( event->key() == Qt::Key_Left ) 
        {
            position -= MOV_STEP*right;
        }
        else if ( event->key() == Qt::Key_Right ) 
        {
            position += MOV_STEP*right;
        }
        else if ( event->key() == Qt::Key_Home ) 
        {
            position.z += MOV_STEP;
        }
        else if ( event->key() == Qt::Key_End )
        {
            position.z -= MOV_STEP;
        }
        else if ( event->key() == Qt::Key_PageUp )
        {
            position.y += MOV_STEP;
        }
        else if ( event->key() == Qt::Key_PageDown )
        {
            position.y -= MOV_STEP;
        }
        else if ( event->key() == Qt::Key_Minus ) 
        {
            mPtSize--;
            if( mPtSize<1 )
                mPtSize=1;
        }
        else if ( event->key() == Qt::Key_Plus ) 
        {
            mPtSize++;
            if( mPtSize>10 )
                mPtSize=10;
        }
    
        updateGL();
        }
    
        void GLWidget::doPitch(double angle)
        {
        forward = unit(forward * cos(angle) + up * sin(angle));
        up = right.cross(forward);
        }
    
        void GLWidget::doRoll(double angle)
        {
        right = unit(right * cos(angle) + up * sin(angle));
        up = right.cross(forward);
        }
    
        void GLWidget::doYaw(double angle)
        {
        right = unit(right * cos(angle) + forward * sin(angle));
        forward = up.cross(right);
        }
    
    void GLWidget::updateScene()
    {
        if( this->isVisible() )
            updateGL();
    }
    
    void GLWidget::setRenderMode( int renderMode )
    {
        mPaintMode = renderMode;
        updateGL();
    }
    
    void GLWidget::renderDefaultCube()
    {
        makeCurrent();
    
    
        static const int coords[5][4][3] =
        {
            { { +1, -1, -1 }, { -1, -1, -1 }, { -1, +1, -1 }, { +1, +1, -1 } },
            { { +1, -1,  0 }, { -1, -1,  0 }, { -1, +1,  0 }, { +1, +1,  0 } },
            { { +1, -1, +1 }, { -1, -1, +1 }, { -1, +1, +1 }, { +1, +1, +1 } },
            { {  0, -1, -1 }, { +1,  0, -1 }, {  0, +1, -1 }, { -1,  0, -1 } },
            { {  0, -1, +1 }, { +1,  0, +1 }, {  0, +1, +1 }, { -1,  0, +1 } }
        };
    
        glPointSize(mPtSize);
    
    
        glScalef(0.01f,0.01f,0.01f);
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    
    
        gluLookAt(  position.x-mZoom*forward.i, position.y-mZoom*forward.j, position.z-mZoom*forward.k,
                    position.x, position.y, position.z,
                    up.i, up.j, up.k);
    
    
        glPushMatrix();
        glColor3ub( 0, 255, 0 );
    
        glBegin(GL_POINTS);
        for (int i = 0; i < 5; ++i)
        {
            for (int j = 0; j < 4; ++j)
            {
                glVertex3d(coords[i][j][0], coords[i][j][1], coords[i][j][2]);
            }
    
        }
        glEnd();
    
        glPopMatrix();
    
        glPointSize(mPtSize);
    
    
    
    }
    
    
    void GLWidget::drawCameraTargetSphere()
    {
        glColor4f( 0.8,0.8,0.8,0.3);
        glPushMatrix();
        glTranslatef( position.x, position.y, position.z );
        static GLUquadric* quad = gluNewQuadric();
    
        gluSphere( quad, 0.025f, 16, 16 );
        glPopMatrix();
    }
    
    
    void GLWidget::renderImage()
    {
        makeCurrent();
    
        glClear (GL_COLOR_BUFFER_BIT);
    
        glDisable(GL_DEPTH_TEST);
    
        if (!mImage.isNull())
        {
            glLoadIdentity();
    
            glPushMatrix();
            {
                int imW = mImage.width();
                int imH = mImage.height();
    
                bool resized = false;
    
                if( imW != this->size().width() &&
                        imH != this->size().height() )
                {
                    mImage = mImage.scaled( this->size(),
                                            Qt::KeepAspectRatio,
                                            Qt::FastTransformation );
    
                    resized = true;
                }
    
    
                int posX = (this->size().width()-imW)/2;
                int posY = (this->size().height()-imH)/2;
    
                glRasterPos2i( posX, posY );
    
    
                glDrawPixels( mImage.width(), mImage.height(),
                              GL_RGBA, GL_UNSIGNED_BYTE, mImage.bits());
    
                if( resized)
                {
                    imW = mImage.width();
                    imH = mImage.height();
    
    
                }
            }
            glPopMatrix();
    
    
            glFlush();
        }
    
        glEnable(GL_DEPTH_TEST);
    
    
    
    }
    
    void GLWidget::setFrameImage(Mat img )
    {
        if( !img.data )
        {
            qDebug( "Warning: No Image to be set");
            return;
        }
    
        if( img.channels() == 3)
            mImage = QImage((const unsigned char*)(img.data), img.cols, img.rows,
                            img.step, QImage::Format_RGB888);
        else if( img.channels() == 1)
            mImage = QImage((const unsigned char*)(img.data), img.cols, img.rows,
                            img.step, QImage::Format_Indexed8);
        else
            return;
    
        mImage = QGLWidget::convertToGLFormat(mImage);
    
    
    
        updateGL();
    }
    
    
    
    void GLWidget::resetView( bool update )
    {
        position.x = -0.311778;
        position.y = 0.242323;
        position.z = 0.441647;
    
        forward.i = 0.284576;
        forward.j = -0.414646;
        forward.k = 0.864341;
    
        up.i = -0.020237;
        up.j = -0.904017;
        up.k = -0.427017;
    
        right.i = 0.95844;
        right.j = 0.104027;
        right.k = -0.265653;
    
        mZoom = MIN_CAM_DIST;
    
    
        if( update )
            updateGL();
    }
    
    void GLWidget::topView()
    {
        position.x = position.y = 0;
        position.z = 5.0;
    
        forward.i = 0;
        forward.j = 0;
        forward.k = -1;
        up.i = 0;
        up.j = 1;
        up.k = 0;
        right.i = 1;
        right.j = 0;
        right.k = 0;
    
        mZoom = MIN_CAM_DIST;
    
    
        updateGL();
    }
    
    void GLWidget::drawAxis()
    {
        float limit = 10.0f;
        float limitAxe = 0.3f;
    
        glLineWidth( 1.0 );
        glBegin( GL_LINES );
        {
    
            glColor4f( 0.20, 0.20, 0.20, 0.5 );
    
            glVertex3f( -limit, 0, 0 );
            glVertex3f( 0, 0, 0 );
            glVertex3f( limitAxe, 0, 0 );
            glVertex3f( limit, 0, 0 );
    
            glVertex3f( 0, -limit,  0 );
            glVertex3f( 0, 0, 0 );
            glVertex3f( 0, limitAxe, 0 );
            glVertex3f( 0, limit,  0 );
    
            glVertex3f( 0, 0, -limit );
            glVertex3f( 0, 0, 0 );
            glVertex3f( 0, 0, limitAxe );
            glVertex3f( 0, 0, limit  );
        }
        glEnd();
    
        glLineWidth( 3.0 );
        glBegin( GL_LINES );
        {
    
            glColor4f( 1.0, 0, 0, 0.5 );
            glVertex3f( 0, 0, 0 );
            glVertex3f( limitAxe, 0, 0 );
    
            glColor4f( 0, 1.0, 0, 0.5 );
            glVertex3f( 0, 0, 0 );
            glVertex3f( 0, limitAxe, 0 );
    
            glColor4f( 0, 0, 1.0, 0.5 );
            glVertex3f( 0, 0, 0 );
            glVertex3f( 0, 0, limitAxe );
        }
        glEnd();
    }
    
    
    void GLWidget::drawGridXY()
    {
        float limit = 10.0f;
        float gridSize = 1.0f;
    
        glColor4f( 0.4,0.4,0.4,0.5);
        float x = -limit;
        float y = -limit;
    
        glLineWidth( 1.0 );
    
        glBegin( GL_LINES );
        {
            while( x<=limit )
            {
                while( y<=limit )
                {
                    if( y!=0  )
                    {
                        glVertex3f( -limit, y, 0  );
                        glVertex3f( limit, y, 0 );
                    }
    
                    y+=gridSize;
                }
    
                if( x!=0 )
                {
                    glVertex3f( x, -limit, 0 );
                    glVertex3f( x, limit, 0 );
                }
    
                x+=gridSize;
            }
        }
        glEnd();
    }
    
    void GLWidget::drawGridXZ()
    {
        float limit = 10.0f;
        float gridSize = 1.0f;
    
        glColor4f( 0.4,0.4,0.4,0.5);
        float x = -limit;
        float z = -limit;
    
        glLineWidth( 1.0 );
    
        glBegin( GL_LINES );
        {
            while( x<=limit )
            {
                while( z<=limit )
                {
                    if( z!=0  )
                    {
                        glVertex3f( -limit, 0, z  );
                        glVertex3f( limit, 0, z );
                    }
    
                    z+=gridSize;
                }
    
                if( x!=0 )
                {
                    glVertex3f( x, 0, -limit  );
                    glVertex3f( x, 0, limit  );
                }
    
                x+=gridSize;
            }
        }
        glEnd();
    }
    
    void GLWidget::drawGridYZ()
    {
        float limit = 10.0f;
        float gridSize = 1.0f;
    
        glColor4f( 0.4,0.4,0.4,0.5);
        float y = -limit;
        float z = -limit;
    
        glLineWidth( 1.0 );
    
        glBegin( GL_LINES );
        {
            while( y<=limit )
            {
                while( z<=limit )
                {
                    if( z!=0  )
                    {
                        glVertex3f( 0, -limit, z  );
                        glVertex3f( 0, limit, z );
                    }
    
                    z+=gridSize;
                }
    
                if( y!=0 )
                {
                    glVertex3f( 0, y, -limit  );
                    glVertex3f( 0, y, limit  );
                }
    
                y+=gridSize;
            }
        }
        glEnd();
    }
    
    bool GLWidget::showGrid( int idx, bool show )
    {
        bool old = mShowGrid[idx];
        mShowGrid[idx] = show;
    
        updateGL();
    
        return old;
    }
    
    bool GLWidget::showCameraTarget( bool show )
    {
        bool old=mShowCameraTarget;
        mShowCameraTarget = show;
    
        updateGL();
    
        return old;
    }
    
    bool GLWidget::showBoxes(bool show/*=true*/)
    {
        bool old=mDrawBoxes;
        mDrawBoxes=show;
    
        updateGL();
    
        return old;
    }
    

    rk_geometry.h

    #include <cmath>
    
    namespace rkGeom
    {
    
    class CPoint;
    class CVector;
    
    inline bool equal(double x, double y, double epsilon = 0.000001) {
        return fabs(x - y) <= epsilon;
    }
    
    // A class for 3-D Vectors.
    //
    //   v.i, v.j, v.k              Components of vector v
    //   Vector(i, j, k)            Construct from components
    //   Vector(p)                  Construct from a point
    //   u + v, u += v              Vector addition
    //   u - v, u -= v              Vector subtraction
    //   -v                         <0, 0, 0> - v
    //   u.dot(v)                   Dot product of u and v
    //   u.cross(v)                 Cross product of u and v
    //   v * c, c * v, v *= c       Multiplication of a vector and a scalar
    //   v / c, v /= c              Division of a vector by a scalar
    //   v.magnitude()              The length of v
    //   unit(v)                    The vector of length 1 in the direction of v
    //   normalize(v)               Changes v to unit(v)
    //   cosine(u, v)               The cosine of the angle from u to v
    
    
    class CVector
    {
    public:
        double i, j, k;
        CVector(double i = 0, double j = 0, double k = 0): i(i), j(j), k(k) {}
        CVector(CPoint p);
        CVector operator +(CVector v) {return CVector(i + v.i, j + v.j, k + v.k);}
        CVector& operator +=(CVector v) {i += v.i; j += v.j; k += v.k; return *this;}
        CVector operator -(CVector v) {return CVector(i - v.i, j - v.j, k - v.k);}
        CVector& operator -=(CVector v) {i -= v.i; j -= v.j; k -= v.k; return *this;}
        CVector operator -() {return CVector(-i, -j, -k);}
        double dot(CVector v) {return i * v.i + j * v.j + k * v.k;}
        CVector cross(CVector);
        CVector operator *(double c) {return CVector(i * c, j * c, k * c);}
        friend CVector operator *(double c, CVector v) {return v * c;}
        CVector& operator *=(CVector v) {i *= v.i; j *= v.j; k *= v.k; return *this;}
        CVector operator /(double c) {return CVector(i / c, j / c, k / c);}
        CVector& operator /=(double c) {i /= c; j /= c; k /= c; return *this;}
        double magnitude() {return sqrt(this->dot(*this));}
        friend CVector unit(CVector v) {return v / v.magnitude();}
        friend void normalize(CVector& v) {v /= v.magnitude();}
        friend double cosine(CVector u, CVector v) {return unit(u).dot(unit(v));}
    
    };
    
    // A class for 3-D Points.
    //
    //   p.x, p.y, p.z              Components (coordinates) of point p
    //   p + v, p += v              Add a point to a vector
    //   p - q                      The vector from q to p
    //   p.distanceTo(q)            The distance between p and q
    //   p.distanceTo(P)            The distance between p and the plane P
    
    class CPoint
    {
    public:
        double x, y, z;
        CPoint(double x = 0, double y = 0, double z = 0): x(x), y(y), z(z) {}
        CPoint operator +(CVector v) {return CPoint(x + v.i, y + v.j, z + v.k);}
        CPoint& operator +=(CVector v) {x += v.i; y += v.j; z += v.k; return *this;}
        CPoint& operator -=(CVector v) {x -= v.i; y -= v.j; z -= v.k; return *this;}
        CVector operator -(CPoint p) {return CVector(x - p.x, y - p.y, z - p.z);}
        double distanceTo(CPoint p) {return (p - *this).magnitude();}
    
    };
    
    
    
    inline CVector::CVector(CPoint p): i(p.x), j(p.y), k(p.z) {
    }
    
    inline CVector CVector::cross(CVector v) {
        return CVector(j * v.k - k * v.j, k * v.i - i * v.k, i * v.j - j * v.i);
    }
    
    }
    

    MainWindow.h

    #include <QMainWindow>
    #include "GLWidget.h"
    
    #include <math.h>
    
    
    #include <QComboBox>
    
    
    
    
    namespace Ui {
        class MainWindow;
    }
    
    class MainWindow :public QMainWindow
    {
        Q_OBJECT
    
        public :
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    
        public slots :
        void showModel(int index);
    
    
        private :
        Ui::MainWindow *ui;
        GLWidget *openglWidget1;
    
    
    
    };
    

    MainWindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
    {
        ui -> setupUi(this);
    
        openglWidget1 = new GLWidget();
        openglWidget1->setRenderMode(0);
    
    
    
        ui->verticalLayout->addWidget(openglWidget1);
    
        connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(showModel(int)));
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::showModel(int index)
    {
        switch(index)
        {
        case 0:
            {
    
            openglWidget1->setRenderMode(0);
    
    
            openglWidget1->updateGL();
    
    
    
            }
            break;
    
        case 1:
            {
    
    
            openglWidget1->setRenderMode(1);
            openglWidget1->setFrameImage(cv::imread("D:/Test switching/build/wireframe.jpg"));
            openglWidget1->updateGL();
    
    
    
    
            }
            break;
        }
    }
    

    ui_mainwindow.h

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>800</width>
        <height>600</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <layout class="QGridLayout" name="gridLayout">
        <item row="2" column="0">
         <widget class="QPushButton" name="pushButton">
          <property name="text">
           <string>Start</string>
          </property>
         </widget>
        </item>
        <item row="0" column="0">
         <layout class="QVBoxLayout" name="verticalLayout"/>
        </item>
        <item row="1" column="0">
         <widget class="QComboBox" name="comboBox">
          <item>
           <property name="text">
            <string>Cube</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Image</string>
           </property>
          </item>
         </widget>
        </item>
       </layout>
      </widget>
     </widget>
     <resources/>
     <connections/>
    </ui>
    

    的main.cpp

    #include <qapplication.h>
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include "mainwindow.h"
    
    int main(int argc, char **argv)
    {
        QApplication app(argc, argv);
        MainWindow w;
    
    
        w.show();
    
        return app.exec();
    }
    

    CMakeLists

    cmake_minimum_required(VERSION 2.6)
    
    PROJECT(test)
    
    FIND_PACKAGE(Qt4 REQUIRED)
    INCLUDE(${QT_USE_FILE})
    ADD_DEFINITIONS(${QT_DEFINITIONS})
    
    FIND_PACKAGE(OpenCV REQUIRED)
    
    SET(test_HEADERS GLWidget.h mainWindow.h)
    SET(test_SOURCES GLWidget.cpp mainwindow.cpp main.cpp)
    SET(test_FORMS mainwindow.ui)
    
    QT4_WRAP_UI(test_FORMS_HEADERS ${test_FORMS})
    QT4_WRAP_CPP(test_HEADERS_MOC ${test_HEADERS})
    ADD_EXECUTABLE(test ${test_SOURCES} ${test_FORMS_HEADERS} ${test_HEADERS_MOC})
    
    TARGET_LINK_LIBRARIES(test ${QT_LIBRARIES} ${OpenCV_LIBRARIES})
    

1 个答案:

答案 0 :(得分:1)

更改渲染模式后调用updateGL以重新绘制窗口,反映状态的变化。

更新

也可以在从paintGL返回后将QGLWidget设置为自动缓冲交换,或者在paintGL结束时手动调用SwapBuffers。

更新2

paintGL中的这个块

if( !mSceneChanged )
    return;

不属于那里。必须重新绘制窗口小部件,不仅要在场景发生更改的情况下,还要在窗口调整大小后,如果前面的窗口移开或者窗口最小化然后恢复。当paintGL被调用时,那么它是有原因的,原因是必须绘制事物。取消这个过早地违背了目的。所以删除那个不属于那里的测试。