先说一件小事——自己被上了一课。
今天被外面的人委托做一个点云拼接,用到pcl库,拼接的效果奇差,无论怎么修改参数都不行。
然后人家发给我一块完整的点云给我看。
我气不打一处来,说这块点云一定是扫描出来的,不是拼接的。
人家立刻就说,这实际上是用空间特征进行配准做出来的。
我变得哑口无言——我太自大了,我以为自己弄不出的东西别人也弄不出。
也许我被这种自大的心态蒙蔽了很久,但是我不想就这样止步不前。
其实这个世界上有很多更先进的算法,自己做的东西也只是如同灰尘一般渺小。
也只有无数灰尘聚集在一起才有这遮蔽天空的能力。
也只有认可别人的成果自己才能进步,对吧?
然后是头文件,当然头文件就少很多了
今天被外面的人委托做一个点云拼接,用到pcl库,拼接的效果奇差,无论怎么修改参数都不行。
然后人家发给我一块完整的点云给我看。
我气不打一处来,说这块点云一定是扫描出来的,不是拼接的。
人家立刻就说,这实际上是用空间特征进行配准做出来的。
我变得哑口无言——我太自大了,我以为自己弄不出的东西别人也弄不出。
也许我被这种自大的心态蒙蔽了很久,但是我不想就这样止步不前。
其实这个世界上有很多更先进的算法,自己做的东西也只是如同灰尘一般渺小。
也只有无数灰尘聚集在一起才有这遮蔽天空的能力。
也只有认可别人的成果自己才能进步,对吧?
好,我们来看一下今天要展示的东西:
这一次主要实现了
1.点云的读取与显示
2.相机可以进行简单旋转,旋转速度可以渐渐变慢
3.绘制立方体,加载纹理,鼠标右键与中键控制是否启用光照、融合。
4.利用opencv从摄像头中读取影像,转化为QT格式作为立方体的背景
h文件和Cpp文件链接如下:
http://download.youkuaiyun.com/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