您的位置:首页 > 编程语言 > Qt开发

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

2017-09-13 21:03 211 查看
先说一件小事——自己被上了一课。
今天被外面的人委托做一个点云拼接,用到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


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: