一、实现功能
1、网格显示
2、坐标轴显示
3、鼠标操作旋转、平移、缩放
4、点云显示
之前写了一篇基于QGLWidget实现,此版本的功能接口基本保持一致,方便对比
QGLWidget与QOpenGLWidget的区别:
1、QGLWidget中是直接调用opengl指令,个人觉得比较方便,逻辑清晰,可以了解opengl底层的接口;
2、QOpenGLWidget是调用QOpenGLFunctions中封装接口,从Qt5.4开始,Qt推荐使用QOpenGLWidget和QOpenGL类。
二、实现效果
三、实现方法
细节待补充
完整代码
PointCloudOpenGLWidget.h
-
#ifndef BASEOPENGLWIDGET_H
-
#define BASEOPENGLWIDGET_H
-
-
#include <QOpenGLWidget>
-
#include <QOpenGLFunctions_3_3_Core>
-
#include <QOpenGLShaderProgram>
-
#include <QOpenGLTexture>
-
#include <QMouseEvent>
-
-
#include "opengllib_global.h"
-
-
class
OPENGLLIBSHARED_EXPORT PointCloudOpenGLWidget:
public QOpenGLWidget,
public QOpenGLFunctions_3_3_Core
-
{
-
Q_OBJECT
-
public:
-
PointCloudOpenGLWidget(QWidget *parent =
0);
-
~
PointCloudOpenGLWidget();
-
void updatePoints(const QVector<QVector3D> &points);
-
void loadCsvFile(const QString &path);
-
-
protected:
-
void initializeGL() override;
-
void paintGL() override;
-
void resizeGL(int width, int height) override;
-
-
void mousePressEvent(QMouseEvent *event) override;
-
void mouseMoveEvent(QMouseEvent *event) override;
-
void wheelEvent(QWheelEvent *event);
-
-
virtual unsigned int drawMeshline(float size, int count);
-
virtual void drawCooraxis(float length);
-
virtual unsigned int drawPointdata(std::vector<float> &pointVertexs);
-
-
protected:
-
QOpenGLShaderProgram m_shaderProgramMesh;
-
QOpenGLShaderProgram m_shaderProgramAxis;
-
QOpenGLShaderProgram m_shaderProgramPoint;
-
-
unsigned
int m_VBO_MeshLine;
-
unsigned
int m_VAO_MeshLine;
-
-
unsigned
int m_VBO_Axis;
-
unsigned
int m_VAO_Axis;
-
-
unsigned
int m_VBO_Point;
-
unsigned
int m_VAO_Point;
-
-
std::vector<
float> m_pointData;
-
unsigned
int m_pointCount;
-
-
unsigned
int m_vertexCount;
-
-
float m_xRotate;
-
float m_zRotate;
-
float m_xTrans;
-
float m_yTrans;
-
float m_zoom;
-
-
QPoint lastPos;
-
};
PointCloudOpenGLWidget.cpp
-
#include "PointCloudOpenGLWidget.h"
-
#include <QDebug>
-
-
PointCloudOpenGLWidget::
PointCloudOpenGLWidget(QWidget *parent)
-
:
QOpenGLWidget(parent)
-
{
-
m_xRotate =
-30.0;
-
m_zRotate =
100.0;
-
m_xTrans =
0.0;
-
m_yTrans =
0.0;
-
m_zoom =
45.0;
-
}
-
-
PointCloudOpenGLWidget::~
PointCloudOpenGLWidget()
-
{
-
makeCurrent();
-
glDeleteBuffers(
1, &m_VBO_MeshLine);
-
glDeleteVertexArrays(
1, &m_VAO_MeshLine);
-
-
glDeleteBuffers(
1, &m_VBO_Axis);
-
glDeleteVertexArrays(
1, &m_VAO_Axis);
-
-
glDeleteBuffers(
1, &m_VBO_Point);
-
glDeleteVertexArrays(
1, &m_VAO_Point);
-
-
m_shaderProgramMesh.
release();
-
m_shaderProgramAxis.
release();
-
m_shaderProgramPoint.
release();
-
-
doneCurrent();
-
qDebug() << __FUNCTION__;
-
}
-
-
void PointCloudOpenGLWidget::updatePoints(const QVector<QVector3D> &points)
-
{
-
m_pointData.
clear();
-
for(
auto vector3D : points)
-
{
-
m_pointData.
push_back(vector3D.
x());
-
m_pointData.
push_back(vector3D.
y());
-
m_pointData.
push_back(vector3D.
z());
-
m_pointData.
push_back(
1);
-
}
-
}
-
-
void PointCloudOpenGLWidget::loadCsvFile(const QString &path)
-
{
-
m_pointData.
clear();
-
QFile inFile(path);
-
if (inFile.
open(QIODevice::ReadOnly))
-
{
-
QTextStream stream_text(&inFile);
-
while (!stream_text.
atEnd())
-
{
-
QString line = stream_text.
readLine();
-
QStringList strSplit = line.
split(
",");
-
-
double x = strSplit.
value(
0).
toDouble();
-
double y = strSplit.
value(
1).
toDouble();
-
double z = strSplit.
value(
2).
toDouble();
-
m_pointData.
push_back(x);
-
m_pointData.
push_back(y);
-
m_pointData.
push_back(z);
-
m_pointData.
push_back(
1);
-
}
-
inFile.
close();
-
}
-
}
-
-
void PointCloudOpenGLWidget::initializeGL()
-
{
-
initializeOpenGLFunctions();
-
-
// enable depth_test
-
glEnable(GL_DEPTH_TEST);
-
-
// link meshline shaders vs文件为顶点着色器 fs为片段着色器
-
m_shaderProgramMesh.
addShaderFromSourceFile(QOpenGLShader::Vertex,
-
":/opengl/shader/shader_mesh.vs");
-
m_shaderProgramMesh.
addShaderFromSourceFile(QOpenGLShader::Fragment,
-
":/opengl/shader/shader_mesh.fs");
-
m_shaderProgramMesh.
link();
-
-
// link coordinate axis shaders
-
m_shaderProgramAxis.
addShaderFromSourceFile(QOpenGLShader::Vertex,
-
":/opengl/shader/shader_axis.vs");
-
m_shaderProgramAxis.
addShaderFromSourceFile(QOpenGLShader::Fragment,
-
":/opengl/shader/shader_axis.fs");
-
m_shaderProgramAxis.
link();
-
-
// link pointcloud shaders
-
m_shaderProgramPoint.
addShaderFromSourceFile(QOpenGLShader::Vertex,
-
":/opengl/shader/shader_point.vs");
-
m_shaderProgramPoint.
addShaderFromSourceFile(QOpenGLShader::Fragment,
-
":/opengl/shader/shader_point.fs");
-
m_shaderProgramPoint.
link();
-
-
m_vertexCount =
drawMeshline(
2.0,
16);
-
m_pointCount =
drawPointdata(m_pointData);
-
qDebug() <<
"point_count" << m_pointCount;
-
drawCooraxis(
4.0);
-
}
-
-
void PointCloudOpenGLWidget::paintGL()
-
{
-
glClearColor(
0.1f,
0.1f,
0.1f,
1.0f);
-
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-
/*
-
为了将坐标从一个坐标系转换到另一个坐标系,需要用到几个转换矩阵,
-
分别是模型(Model)、视图(View)、投影(Projection)三个矩阵。
-
*/
-
QMatrix4x4 projection, view, model;
-
//透视矩阵变换
-
projection.
perspective(m_zoom, (
float)
width() / (
float)
height(),
1.0f,
100.0f);
-
-
// eye:摄像机位置 center:摄像机看的点位 up:摄像机上方的朝向
-
view.
lookAt(
QVector3D(
0.0,
0.0,
50.0),
QVector3D(
0.0,
0.0,
1.0),
QVector3D(
0.0,
1.0,
0.0));
-
-
model.
translate(m_xTrans, m_yTrans,
0.0);
-
model.
rotate(m_xRotate,
1.0,
0.0,
0.0);
-
model.
rotate(m_zRotate,
0.0,
0.0,
1.0);
-
-
m_shaderProgramMesh.
bind();
-
m_shaderProgramMesh.
setUniformValue(
"projection", projection);
-
m_shaderProgramMesh.
setUniformValue(
"view", view);
-
m_shaderProgramMesh.
setUniformValue(
"model", model);
-
-
m_shaderProgramAxis.
bind();
-
m_shaderProgramAxis.
setUniformValue(
"projection", projection);
-
m_shaderProgramAxis.
setUniformValue(
"view", view);
-
m_shaderProgramAxis.
setUniformValue(
"model", model);
-
-
m_shaderProgramPoint.
bind();
-
m_shaderProgramPoint.
setUniformValue(
"projection", projection);
-
m_shaderProgramPoint.
setUniformValue(
"view", view);
-
m_shaderProgramPoint.
setUniformValue(
"model", model);
-
-
//画网格
-
m_shaderProgramMesh.
bind();
-
glBindVertexArray(m_VAO_MeshLine);
-
glLineWidth(
1.0f);
-
glDrawArrays(GL_LINES,
0, m_vertexCount);
-
-
//画坐标轴
-
m_shaderProgramAxis.
bind();
-
glBindVertexArray(m_VAO_Axis);
-
glLineWidth(
5.0f);
-
glDrawArrays(GL_LINES,
0,
6);
-
-
//画点云
-
m_shaderProgramPoint.
bind();
-
glBindVertexArray(m_VAO_Point);
-
glPointSize(
1.0f);
-
glDrawArrays(GL_POINTS,
0, m_pointCount);
-
}
-
-
void PointCloudOpenGLWidget::resizeGL(int width, int height)
-
{
-
glViewport(
0,
0, width, height);
-
}
-
-
void PointCloudOpenGLWidget::mousePressEvent(QMouseEvent *event)
-
{
-
lastPos = event->
pos();
-
}
-
-
void PointCloudOpenGLWidget::mouseMoveEvent(QMouseEvent *event)
-
{
-
int dx = event->
pos().
x() - lastPos.
x();
-
int dy = event->
pos().
y() - lastPos.
y();
-
if (event->
buttons() & Qt::LeftButton)
-
{
-
m_xRotate = m_xRotate +
0.3 * dy;
-
m_zRotate = m_zRotate +
0.3 * dx;
-
-
if (m_xRotate >
30.0f)
-
{
-
m_xRotate =
30.0f;
-
}
-
if (m_xRotate <
-120.0f)
-
{
-
m_xRotate =
-120.0f;
-
}
-
update();
-
}
-
else
if (event->
buttons() & Qt::MidButton)
-
{
-
m_xTrans = m_xTrans +
0.1 * dx;
-
m_yTrans = m_yTrans -
0.1 * dy;
-
update();
-
}
-
lastPos = event->
pos();
-
}
-
-
void PointCloudOpenGLWidget::wheelEvent(QWheelEvent *event)
-
{
-
auto scroll_offest = event->
angleDelta().
y() /
120;
-
m_zoom = m_zoom - (
float)scroll_offest;
-
-
if (m_zoom <
1.0f)
/* 放大限制 */
-
{
-
m_zoom =
1.0f;
-
}
-
-
if (m_zoom >
80.0f)
-
{
-
m_zoom =
80.0f;
-
}
-
-
update();
-
}
-
-
unsigned int PointCloudOpenGLWidget::drawMeshline(float size, int count)
-
{
-
std::vector<
float> mesh_vertexs;
-
unsigned
int vertex_count =
0;
-
-
float start = count * (size /
2);
-
float posX = start, posZ = start;
-
-
for (
int i =
0; i <= count; ++i)
-
{
-
mesh_vertexs.
push_back(posX);
-
mesh_vertexs.
push_back(start);
-
mesh_vertexs.
push_back(
0);
-
-
mesh_vertexs.
push_back(posX);
-
mesh_vertexs.
push_back(-start);
-
mesh_vertexs.
push_back(
0);
-
-
mesh_vertexs.
push_back(start);
-
mesh_vertexs.
push_back(posZ);
-
mesh_vertexs.
push_back(
0);
-
-
mesh_vertexs.
push_back(-start);
-
mesh_vertexs.
push_back(posZ);
-
mesh_vertexs.
push_back(
0);
-
-
posX = posX - size;
-
posZ = posZ - size;
-
}
-
-
glGenVertexArrays(
1, &m_VAO_MeshLine);
-
glGenBuffers(
1, &m_VBO_MeshLine);
-
-
glBindVertexArray(m_VAO_MeshLine);
-
-
glBindBuffer(GL_ARRAY_BUFFER, m_VBO_MeshLine);
-
-
glBufferData(GL_ARRAY_BUFFER, mesh_vertexs.
size() *
sizeof(
float), &mesh_vertexs[
0], GL_STATIC_DRAW);
-
-
glVertexAttribPointer(
0,
3, GL_FLOAT, GL_FALSE,
3 *
sizeof(
float), (
void *)
0);
-
glEnableVertexAttribArray(
0);
-
-
glBindBuffer(GL_ARRAY_BUFFER,
0);
-
-
glBindVertexArray(
0);
-
-
vertex_count = (
int)mesh_vertexs.
size() /
3;
-
-
return vertex_count;
-
}
-
-
void PointCloudOpenGLWidget::drawCooraxis(float length)
-
{
-
std::vector<
float> axis_vertexs =
-
{
-
//x,y ,z ,r, g, b
-
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
-
length,
0.0,
0.0,
1.0,
0.0,
0.0,
-
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
-
0.0, length,
0.0,
0.0,
1.0,
0.0,
-
0.0,
0.0,
0.0,
0.0,
0.0,
1.0,
-
0.0,
0.0, length,
0.0,
0.0,
1.0,
-
};
-
-
glGenVertexArrays(
1, &m_VAO_Axis);
-
glGenBuffers(
1, &m_VBO_Axis);
-
-
glBindVertexArray(m_VAO_Axis);
-
-
glBindBuffer(GL_ARRAY_BUFFER, m_VBO_Axis);
-
glBufferData(GL_ARRAY_BUFFER, axis_vertexs.
size() *
sizeof(
float), &axis_vertexs[
0], GL_STATIC_DRAW);
-
-
// 位置属性
-
glVertexAttribPointer(
0,
3, GL_FLOAT, GL_FALSE,
6 *
sizeof(
float), (
void *)
0);
-
glEnableVertexAttribArray(
0);
-
-
// 颜色属性
-
glVertexAttribPointer(
1,
3, GL_FLOAT, GL_FALSE,
6 *
sizeof(
float), (
void *)(
3 *
sizeof(
float)));
-
glEnableVertexAttribArray(
1);
-
-
glBindBuffer(GL_ARRAY_BUFFER,
0);
-
-
glBindVertexArray(
0);
-
}
-
-
unsigned int PointCloudOpenGLWidget::drawPointdata(std::vector<float> &pointVertexs)
-
{
-
unsigned
int point_count =
0;
-
-
glGenVertexArrays(
1, &m_VAO_Point);
-
glGenBuffers(
1, &m_VBO_Point);
-
-
glBindVertexArray(m_VAO_Point);
-
-
glBindBuffer(GL_ARRAY_BUFFER, m_VBO_Point);
-
glBufferData(GL_ARRAY_BUFFER, pointVertexs.
size() *
sizeof(
float), &pointVertexs[
0], GL_STATIC_DRAW);
-
-
// 位置属性
-
glVertexAttribPointer(
0,
3, GL_FLOAT, GL_FALSE,
4 *
sizeof(
float), (
void *)
0);
-
glEnableVertexAttribArray(
0);
-
-
// 颜色属性
-
glVertexAttribPointer(
1,
1, GL_FLOAT, GL_FALSE,
4 *
sizeof(
float), (
void *)(
3 *
sizeof(
float)));
-
glEnableVertexAttribArray(
1);
-
-
glBindBuffer(GL_ARRAY_BUFFER,
0);
-
-
glBindVertexArray(
0);
-
-
point_count = (
unsigned
int)pointVertexs.
size() /
4;
-
-
return point_count;
-
}
转载:https://blog.csdn.net/qq_40602000/article/details/128307566
查看评论