QT-opengl实现点云读取和显示

来源:互联网 发布:天刀功力算法 编辑:程序博客网 时间:2024/06/09 17:53
先说一件小事——自己被上了一课。
今天被外面的人委托做一个点云拼接,用到pcl库,拼接的效果奇差,无论怎么修改参数都不行。
然后人家发给我一块完整的点云给我看。
我气不打一处来,说这块点云一定是扫描出来的,不是拼接的。
人家立刻就说,这实际上是用空间特征进行配准做出来的。
我变得哑口无言——我太自大了,我以为自己弄不出的东西别人也弄不出。
也许我被这种自大的心态蒙蔽了很久,但是我不想就这样止步不前。
其实这个世界上有很多更先进的算法,自己做的东西也只是如同灰尘一般渺小。
也只有无数灰尘聚集在一起才有这遮蔽天空的能力。
也只有认可别人的成果自己才能进步,对吧?



好,我们来看一下今天要展示的东西:

这一次主要实现了

1.点云的读取与显示

2.相机可以进行简单旋转,旋转速度可以渐渐变慢

3.绘制立方体,加载纹理,鼠标右键与中键控制是否启用光照、融合。

4.利用opencv从摄像头中读取影像,转化为QT格式作为立方体的背景


h文件和Cpp文件链接如下:
http://download.csdn.net/download/qq_30547073/9977413

下面就是代码了,首先是CPP文件,很长啊抱歉:
#include "qscarletopenglinterface.h"
#include<QOpenGLShaderProgram>
#include<QDebug>
#include<QKeyEvent>
#include<QGLFormat>
#include<QImage>
#include<QString>
#include<QMessageBox>
#include<glut.h>
//=====Eigen
#include<Eigen/Core>
#include<Eigen/Dense>
//=====std
#include<vector>
#include<fstream>
#include<iostream>
#include<string>
//========opencv
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace Eigen;
using namespace std;
//Qt5  OpenGL 1~4 的版本的接口自己封装了,所以很多第三方库的 gl 函数在 Qt 编译环境下都无法 link 
qScarletOpenglInterface::qScarletOpenglInterface(QWidget*parent)
    :QOpenGLWidget(parent)
{
}
//这里定义了三个数组,它们描述的是和光源有关的信息
//如果没有环境光,未被漫射光照到的地方会变得十分黑暗。
//第二行有关lightDiffuse的代码使我们生成最亮的漫射光。所有的参数值都取成最大值1.0。它将照在我们木板箱的前面,看起来挺好。
GLfloat lightAmbient[4] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat lightDiffuse[4] = { 0.5, 0.0, 1.0, 1.0 };
GLfloat lightPosition[4] = { 0.0, 0.0, 2.0, 1.0 };
GLuint fogMode[3] = { GL_EXP, GL_EXP2, GL_LINEAR };
GLfloat fogColor[4] = { 0.618, 0.0, 0.1, 1.0};
GLfloat BGColor[4] = { 0.0, 0.0, 0.0, 1.0};
int stdstrToi(std::string NumStr)
{
    std::stringstream stream(NumStr);
    int int_temp;
    stream >> int_temp;
    return int_temp;
}
double stdstrTod(std::string NumStr)//三个重载函数
{
    std::stringstream stream(NumStr);
    double double_temp;
    stream >> double_temp;
    return double_temp;
}
std::vector<std::string> StrSplit(std::string str, std::string pattern)//又来了,分割字符串
{
    std::string::size_type pos;
    std::vector<std::string> result;
    str += pattern;//扩展字符串以方便操作
    int size = str.size();
    for (int i = 0; i<size; i++)
    {
        pos = str.find(pattern, i);
        if (pos<size)
        {
            std::string s = str.substr(i, pos - i);
            result.push_back(s);
            i = pos + pattern.size() - 1;
        }
    }
    return result;
}
void qScarletOpenglInterface::Start()
{
    qDebug()<<"QOpengl Start!";
    setWindowTitle(tr("opengl demo"));
    fullscreen=false;//不全屏
    if (fullscreen)
        showFullScreen();
    rTri = 0.0;
    rQuad = 0.0;
    xRot =yRot=zRot =0.0;
    zoom = -10.0;//-5.0
    xSpeed = ySpeed = 0.0;
    filter = 0;
    ligtht = false;
    blend = false;
    fogFilter = 0;
    //下面是增强现实
    //cam.open(0);
    //clk.start(30);
    //QObject::connect(&clk, SIGNAL(timeout()), this, SLOT(updateWindow()));
}
void qScarletOpenglInterface::InitialOrigion()
{
    try
    {
        m_camera.open(0);
    }
    catch(...)
    {
        m_camera.open(1);
    }
    glEnable( GL_TEXTURE_2D );
    glShadeModel(GL_SMOOTH);
    glClearColor( 0.618, 0.0, 0.1, 0.5 );//红绿蓝
    glClearDepth(1.0);//设置深度缓存
    glEnable(GL_DEPTH_TEST);//启用深度测试。
    glDepthFunc(GL_LEQUAL);//所作深度测试的类型。
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);//真正精细的透视修正。这一行告诉OpenGL我们希望进行最好的透视修正。这会十分轻微的影响性能。
    glMatrixMode(GL_MODELVIEW);
    glLightfv( GL_LIGHT1, GL_AMBIENT, lightAmbient );
    glLightfv( GL_LIGHT1, GL_DIFFUSE, lightDiffuse );
    glLightfv( GL_LIGHT1, GL_POSITION, lightPosition );
    glEnable( GL_LIGHT1 );
    glColor4f( 1.0, 1.0, 1.0, 0.5 );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE );
    glEnable( GL_BLEND );
    glDisable( GL_DEPTH_TEST );
    glLoadIdentity();
    gluLookAt(0, 0, 3, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);      //设置照相机位置
    //glTranslatef(ptsCen.x,ptsCen.y,ptsCen.z);
    glRotatef(thetaX, 1, 0, 0);
    glRotatef(thetaY, 0, 1, 0);
    glScalef(scaleFactor, scaleFactor, scaleFactor);
    glTranslatef(-px, -py, -pz);
}
void qScarletOpenglInterface::InitialFog()//烟雾程序初始化
{
    loadGLTextures();
    glEnable( GL_TEXTURE_2D );
    glShadeModel( GL_SMOOTH );
    //0.618, 0.0, 0.1, 0.5
    glClearColor( fogColor[0],fogColor[1],fogColor[2],fogColor[3]);
    glClearDepth( 1.0 );
    glEnable( GL_DEPTH_TEST );
    glDepthFunc( GL_LEQUAL );
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
    glLightfv( GL_LIGHT1, GL_AMBIENT, lightAmbient );
    glLightfv( GL_LIGHT1, GL_DIFFUSE, lightDiffuse );
    glLightfv( GL_LIGHT1, GL_POSITION, lightPosition );
    glEnable( GL_LIGHT1 );
    glFogi( GL_FOG_MODE, fogMode[fogFilter] );
    glFogfv( GL_FOG_COLOR, fogColor );//设定了雾的颜色
    glFogf( GL_FOG_DENSITY, 0.35 );//确定了雾的密度,增大这个数值雾将会变的更浓,减小它雾将会变的更淡
    glHint( GL_FOG_HINT, GL_NICEST );//
    //GK_DONT_CARE:让OPENGL自己来确定雾的渲染方式,每顶点或是每像素。
    //GL_NICEST:对每一像素进行雾的渲染,它看起来极棒
    glFogf( GL_FOG_END, 5.0 );//确定了雾的开始初离屏幕有多近。
    glEnable(GL_FOG);
}
void qScarletOpenglInterface::InitialAugmentedReality()//增强现实
{
    qDebug()<<"QOpengl AugmentedReality Start!";
    //loadGLTextures_AugmentedReality();//加载图片文件
    glEnable(GL_TEXTURE_2D);//启用纹理
    glShadeModel(GL_SMOOTH);
    glClearColor(0, 0, 0.0, 0.0);
    glClearDepth(1.0);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
void qScarletOpenglInterface::initializeGL()
{
    //为当前环境初始化Opengl函数
    initializeOpenGLFunctions();
    Start();
    InitialOrigion();//光照和纹理还有融合
    //InitialFog();
    //InitialAugmentedReality();//所有的增强现实模块放到了另一个窗体中
}
void qScarletOpenglInterface::loadGLTextures()
{
    QImage tex, buf;
    //logo/box.png  logo/Scarletogo3.png
    if (!buf.load(":/logo/logo/Scarletogo3.png"))
    //if (!buf.load(":/logo/logo/box.png"))
    {
        qWarning( "Could not read image file, using single-color instead." );
        QImage dummy( 128, 128, QImage::Format_RGB32 );//Format_RGB32 Format_RGB888
        dummy.fill( Qt::green);
        buf = dummy;//如果载入不成功,自动生成一个128*128的32位色的绿色图片。
    }
    tex = QGLWidget::convertToGLFormat( buf );
    glGenTextures( 3, &m_texture[0] );
    glBindTexture( GL_TEXTURE_2D, m_texture[0] );
    glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
        GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
    glBindTexture( GL_TEXTURE_2D, m_texture[1] );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
                  GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );
    glBindTexture( GL_TEXTURE_2D, m_texture[2] );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
    gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, tex.width(), tex.height(), GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );
}
void DrawBackGround(cv::VideoCapture m_camera,GLuint m_texturFrame)
{
    Mat frame1;
    m_camera >> frame1;
    cvtColor(frame1, frame1, CV_BGR2RGB);
    QImage tex_frame, buf_frame;
    //我们有两种方式生成纹理
    buf_frame = QImage((const unsigned char*)frame1.data, frame1.cols, frame1.rows, frame1.cols * frame1.channels(), QImage::Format_RGB888);
    tex_frame = QGLWidget::convertToGLFormat(buf_frame);
    glGenTextures(1, &m_texturFrame);//对应图片的纹理定义
    glBindTexture(GL_TEXTURE_2D, m_texturFrame);//进行纹理绑定
    glTexImage2D(GL_TEXTURE_2D, 0, 3, tex_frame.width(), tex_frame.height(), 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, tex_frame.bits());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glLoadIdentity();//重置坐标系至屏幕中央
    glTranslatef(3.2f, -0.6f, -100);//讲显示背景沿Z轴向后移动足够距离,防止遮挡渲染物体
    glScalef(8.35f,8.35f,1.0f);//平移 放大 实现窗口填充-
    glBindTexture(GL_TEXTURE_2D, m_texturFrame);//绑定纹理
    glBegin(GL_QUADS);//绘制图形接口,与glEnd()对应
    glTexCoord2f(0.0, 0.0); glVertex3f(-6, -4.5, 0);//
    glTexCoord2f(1.0, 0.0); glVertex3f(6, -4.5, 0);
    glTexCoord2f(1.0, 1.0); glVertex3f(6, 4.5, 0);
    glTexCoord2f(0.0, 1.0); glVertex3f(-6, 4.5, 0);
    glDeleteTextures(1, &m_texturFrame);//及时释放不然会占用很多内存空间使电脑卡死
    glEnd();
}
void DrawCub()
{
    glNormal3f( 0.0, 0.0, 1.0 );//设置外边界
    glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0,  1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0, -1.0,  1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0,  1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0,  1.0,  1.0 );
    glNormal3f( 0.0, 0.0, -1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0,  1.0, -1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f(  1.0,  1.0, -1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f(  1.0, -1.0, -1.0 );
    glNormal3f( 0.0, 1.0, 0.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0,  1.0, -1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0,  1.0,  1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0,  1.0,  1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0, -1.0 );
    glNormal3f( 0.0, -1.0, 0.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0, -1.0, -1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f(  1.0, -1.0, -1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f(  1.0, -1.0,  1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0,  1.0 );
    glNormal3f( 1.0, 0.0, 0.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0, -1.0, -1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0, -1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f(  1.0,  1.0,  1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f(  1.0, -1.0,  1.0 );
    glNormal3f( -1.0, 0.0, 0.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0,  1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0,  1.0,  1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0,  1.0, -1.0 );
}
void DrawCloud(std::vector<PointCloud> m_TenRabbit)//十倍兔
{
    for(int i=0;i<m_TenRabbit.size();i++)
    {
        PointCloud OneP =m_TenRabbit[i];
        GLdouble x =OneP.x*10;
        GLdouble y =OneP.y*10;
        GLdouble z =OneP.z*10;
        glVertex3d(x,y,z);
    }
}
void qScarletOpenglInterface::ReadAndShowCloud(QString Q_FileName)
{
    ifDrawTenRabbit = false;
    //只针对兔子数据
    std::string SelectedCloudPath = Q_FileName.toStdString();
    std::cout<<SelectedCloudPath<<std::endl;
    ifstream CloudReader(SelectedCloudPath);
    if(!CloudReader)
    {
        cout<<"ReadCloudFileToGLWrong!";
        return;
    }
    PointCloud OnePoint;
    while(!CloudReader.eof())
    {
        std::string Line;
        getline(CloudReader,Line);
        std::vector<std::string> StrVec = StrSplit(Line, std::string(" "));
        OnePoint.x = stdstrTod(StrVec[0]);
        OnePoint.y = stdstrTod(StrVec[1]);
        OnePoint.z = stdstrTod(StrVec[2]);
//        OnePoint.r = stdstrTod(StrVec[3]);
//        OnePoint.g = stdstrTod(StrVec[4]);
//        OnePoint.b = stdstrTod(StrVec[5]);
        OnePoint.r = 0;
        OnePoint.g = 255;
        OnePoint.b = 126;
        m_TenRabbit.push_back(OnePoint);
    }
    CloudReader.close();
    OnePoint=m_TenRabbit[0];
    cout<<OnePoint.x<<" "<<OnePoint.y<<" "<<OnePoint.z<<" "<<OnePoint.r<<" "<<OnePoint.g<<" "<<OnePoint.b<<endl;
    OnePoint=m_TenRabbit[m_TenRabbit.size()-1];
    cout<<OnePoint.x<<" "<<OnePoint.y<<" "<<OnePoint.z<<" "<<OnePoint.r<<" "<<OnePoint.g<<" "<<OnePoint.b<<endl;
    ifDrawTenRabbit = true;
    QMessageBox myMessageBox(
                QMessageBox::Information,tr("ReadCloud OK!"),
                tr("Cloud is already read!"),
                QMessageBox::Yes);
    int ExecIndex =myMessageBox.exec();
}
void qScarletOpenglInterface::paintGL_TextureAndLight()
{
    //loadGLTextures();
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    //DrawBackGround(m_camera, m_texturFrame);//绘制背景======
    glLoadIdentity();   
    glTranslatef(  0.0,  0.0, zoom );
    glRotatef( xRot,  1.0,  0.0,  0.0 );
    glRotatef( yRot,  0.0,  1.0,  0.0 );
    glBindTexture( GL_TEXTURE_2D, m_texture[filter] );
    glBegin( GL_QUADS );//绘制立方体===============
    DrawCub();
    glEnd();
    if(ifDrawTenRabbit == true)
    {
        glBegin( GL_POINTS );
        //DrawCloud(m_TenRabbit);//绘制十倍兔===============
        glEnd();
    }
    //这里绘制正方体的方法,上一章已经讲解过了。
    //将xRot和yRot的旋转值分别增加xSpeed和ySpeed个单位。xSpeed和ySpeed的值越大,立方体转得就越快。
    xRot += xSpeed;
    yRot += ySpeed;
    SetAirShutDown(0.025);
    glLoadIdentity();
    //你每次paint的时候都要调用
    if ( !ligtht )//是否光照
    {
      glDisable( GL_LIGHTING );
    }
    else
    {
      glEnable( GL_LIGHTING );
    }
    if ( blend )//是否融合
    {
      glEnable( GL_BLEND );
      glDisable( GL_DEPTH_TEST );
    }
    else
    {
      glDisable( GL_BLEND );
      glEnable( GL_DEPTH_TEST );
    }
}
void qScarletOpenglInterface::SetAirShutDown(double airShutDown)//空气阻尼降低速度
{
    if(xSpeed>0)
    {
        xSpeed-=airShutDown;
        if(xSpeed<=0)
            xSpeed =0;
    }
    else if(xSpeed <0)
    {
        xSpeed+=airShutDown;
        if(xSpeed>=0)
            xSpeed =0;
    }
    if(ySpeed>0)
    {
        ySpeed-=airShutDown;
        if(ySpeed<=0)
            ySpeed =0;
    }
    else if(ySpeed <0)
    {
        ySpeed+=airShutDown;
        if(ySpeed>=0)
            ySpeed =0;
    }
}
void qScarletOpenglInterface::paintGL_Fog()//绘制雾
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glLoadIdentity();
    glTranslatef(  0.0,  0.0, zoom );
    glRotatef( xRot,  1.0,  0.0,  0.0 );
    glRotatef( yRot,  0.0,  1.0,  0.0 );
    glBindTexture( GL_TEXTURE_2D, m_texture[filter] );
    glBegin( GL_QUADS );
    glNormal3f( 0.0, 0.0, 1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0,  1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0, -1.0,  1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0,  1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0,  1.0,  1.0 );
    glNormal3f( 0.0, 0.0, -1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0,  1.0, -1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f(  1.0,  1.0, -1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f(  1.0, -1.0, -1.0 );
    glNormal3f( 0.0, 1.0, 0.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0,  1.0, -1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0,  1.0,  1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0,  1.0,  1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0, -1.0 );
    glNormal3f( 0.0, -1.0, 0.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0, -1.0, -1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f(  1.0, -1.0, -1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f(  1.0, -1.0,  1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0,  1.0 );
    glNormal3f( 1.0, 0.0, 0.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0, -1.0, -1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0, -1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f(  1.0,  1.0,  1.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f(  1.0, -1.0,  1.0 );
    glNormal3f( -1.0, 0.0, 0.0 );
    glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0,  1.0 );
    glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0,  1.0,  1.0 );
    glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0,  1.0, -1.0 );
    glEnd();
     //这里绘制正方体的方法,上一章已经讲解过了。
    xRot += xSpeed;
    yRot += ySpeed;
    SetAirShutDown(0.025);
    glLoadIdentity();
}
void qScarletOpenglInterface::paintGL()//不会自动调用paintGL的
{
    //Paint_DrawPoint();
    //paintGL_RotateTriQuad();
   // paintGL_RotatePyramid();
    //paintGL_DrawCloud();
    //paintGL_Texture();//绘制纹理
    //paintGL_Star();
    paintGL_TextureAndLight();//光照和纹理还有融合
    //paintGL_Fog();//绘制烟雾和box
    //paintGL_AugmentedReality();//绘制增强现实
    update();
}
void qScarletOpenglInterface::ResizeGL_Origion(int width ,int height)//改变大小
{
    if(0 == height)
    {
        height = 1; //防止height为0
    }
    loadGLTextures();
    glEnable( GL_TEXTURE_2D );
    glShadeModel( GL_SMOOTH );
    glClearColor(  fogColor[0],fogColor[1],fogColor[2],fogColor[3] );
    glClearDepth( 1.0 );
    glEnable( GL_DEPTH_TEST );
    glDepthFunc( GL_LEQUAL );
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
    glViewport(0, 0, (GLint)width, (GLint)height);//重置当前的视口(Viewport)。
    glLightfv( GL_LIGHT1, GL_AMBIENT, lightAmbient );
    glLightfv( GL_LIGHT1, GL_DIFFUSE, lightDiffuse );
    glLightfv( GL_LIGHT1, GL_POSITION, lightPosition );
    glEnable( GL_LIGHT1 );
    glMatrixMode(GL_PROJECTION);//选择投影矩阵。
    glLoadIdentity();//重置投影矩阵。
    //gluPerspective(25.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0);//不会用就先别用
    GLdouble aspectRatio = (GLfloat)width/(GLfloat)height;
    GLdouble zNear = 0.1;
    GLdouble zFar = 100.0;
    GLdouble rFov = 45.0 * 3.14159265 / 180.0;
    glFrustum( -zNear * tan( rFov / 2.0 ) * aspectRatio,
               zNear * tan( rFov / 2.0 ) * aspectRatio,
               -zNear * tan( rFov / 2.0 ),
               zNear * tan( rFov / 2.0 ),
               zNear, zFar );
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
void qScarletOpenglInterface::ResizeFog()
{
}
void qScarletOpenglInterface::ResizeGL_AugmentedReality(int width ,int height)//增强现实改变大小
{
}
void qScarletOpenglInterface::resizeGL(int width ,int height)
{
    ResizeGL_Origion(width,height);
    //ResizeFog();
    //ResizeGL_AugmentedReality(width,height);
}
//各种事件=============
void qScarletOpenglInterface::mousePressEvent(QMouseEvent *e)
{
    if(e->button() == Qt::LeftButton)
    {
        qDebug()<<"GL_LeftmousePress!";
        last = e->globalPos();
    }
    else if(e->button() == Qt::RightButton)
    {
        qDebug()<<"GL_RightMousePress!";
        ligtht = !ligtht;
        update();
    }
    else
    {
        qDebug()<<"GL_MiddleMousePress!";
        blend = !blend;
    }
}
void qScarletOpenglInterface::mouseMoveEvent(QMouseEvent *e)
{
    qDebug()<<"GL_mouseMove!";
    int dx = e->globalX()-last.x();
    int dy = e->globalY()-last.y();
    ySpeed  +=(double)dx/60.0/3.0;//逆时针旋转速度增加
    xSpeed +=(double)dy/60.0/3.0;
    //move(x()+dx,y()+dy);
    last = e->globalPos();
}
void qScarletOpenglInterface::mouseReleaseEvent(QMouseEvent *e)//鼠标释放
{
    //int dx = e->globalX() - last.x();
    //int dy = e->globalY() - last.y();
    last = e->globalPos();
}
void qScarletOpenglInterface::wheelEvent(QWheelEvent *e)
{
//    当鼠标滑轮在滚动时用于返回滑动的距离,该值等于鼠标旋转角度的8倍。正数值表示滑轮相对于用户在向前滑动,
//    相反,负数值表示滑轮相对于用户是向后滑动的。
    int mydelta = e->delta();
    double ZoomSlowDown =2.5;
    zoom += (double)mydelta/8.0/15.0/ZoomSlowDown;
}
然后是头文件,当然头文件就少很多了

#ifndef QSCARLETOPENGLINTERFACE_H
#define QSCARLETOPENGLINTERFACE_H
#include<QOpenGLWidget>
#include<QOpenGLFunctions>
#include<QOpenGLShaderProgram>
#include<QOpenGLBuffer>
#include<QPoint>
#include<Eigen/Core>
#include<Eigen/Dense>
#include<QTimer>
#include<vector>
//========opencv
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
typedef struct
{
    int ID;
    double x,y,z;
    double r,g,b;
}PointCloud;
typedef struct
{
  int r, g, b;
  GLfloat dist;
  GLfloat angle;
}stars;
const GLuint num = 50;
#define MIN_LENGTH 35
class qScarletOpenglInterface:public QOpenGLWidget,protected QOpenGLFunctions
{
    Q_OBJECT
public:
    explicit qScarletOpenglInterface(QWidget* parent =0);
    void ReadAndShowCloud(QString);
protected:
    //三个重载函数
    void initializeGL();
    void paintGL();
    void resizeGL(int ,int );
    QPoint last;
    void wheelEvent(QWheelEvent *);
    void mousePressEvent(QMouseEvent *);
    void mouseMoveEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *e);
private:
    bool fullscreen;//用来保存窗口是否处于全屏状态的变量。
    //====================几个paint实例
    GLfloat rTri;//用于三角形的角度
    GLfloat rQuad;//用于四边形的角度
    void Start();
    void InitialOrigion();
    void InitialFog();//烟雾程序初始化
    void InitialAugmentedReality();//增强现实
    void paintGL_RotateTriQuad();
    void paintGL_RotatePyramid();//绕自身旋转的金字塔
    void paintGL_Texture();//绘制纹理
    void paintGL_TextureAndLight();
    void paintGL_Fog();//绘制雾
    void ResizeGL_Origion(int width ,int height);//改变大小
    void ResizeFog();
    void ResizeGL_AugmentedReality(int width ,int height);//增强现实改变大小
    void loadGLTextures();//纹理映射,读取纹理
    void SetAirShutDown(double);//空气阻尼降低速度
    GLfloat xRot,yRot,zRot;
    GLuint m_texture[3];
    GLuint m_texturFrame; 
    GLfloat zoom;//光照等
    GLfloat xSpeed,ySpeed;
    GLuint filter;
    cv::VideoCapture m_camera;
    bool ligtht;
    bool blend;   
    QOpenGLShaderProgram * program;//这个作为着色器程序
    QOpenGLBuffer vbo;
    float xs, ys, zs, px, py, pz;
    float thetaX = 0.0, thetaY = 0.0, scaleFactor = 1.0;
    std::vector<PointCloud> m_TenRabbit;//测试点云
    bool ifDrawTenRabbit = false;
    //绘制点
    void Initial_DrawPoint();
    void Resize_DrawPoint();
    void Paint_DrawPoint();
};
//======================在这里准备放置一个官方logo例子==================
#endif // QSCARLETOPENGLINTERFACE_H


原创粉丝点击