一、OpenGL 3D 点云数据显示
在Qt中使用OpenGL显示3D点云数据是一个常见的需求,特别是在计算机视觉、机器人学和三维重建等领域。下面我将介绍一个基本的实现方案。
基本实现步骤
1. 创建Qt OpenGL窗口
首先,你需要创建一个继承自QOpenGLWidget
的类:
cpp
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
class PointCloudViewer : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit PointCloudViewer(QWidget *parent = nullptr);
~PointCloudViewer();
protected:
void initializeGL() override;
void resizeGL(int w, int h) override;
void paintGL() override;
private:
// 点云数据
std::vector<float> m_points; // x,y,z,r,g,b 格式
GLuint m_vbo;
GLuint m_vao;
};
2. 实现OpenGL初始化
cpp
PointCloudViewer::PointCloudViewer(QWidget *parent)
: QOpenGLWidget(parent), m_vbo(0), m_vao(0)
{
// 设置OpenGL版本和格式
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
}
void PointCloudViewer::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// 创建VAO和VBO
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
// 初始化着色器
m_shaderProgram = new QOpenGLShaderProgram(this);
m_shaderProgram->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/pointcloud.vert");
m_shaderProgram->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/pointcloud.frag");
m_shaderProgram->link();
// 启用深度测试
glEnable(GL_DEPTH_TEST);
}
3. 顶点和片段着色器
创建两个着色器文件:
pointcloud.vert:
glsl
#version 330 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 color;
out vec3 fragColor;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0);
fragColor = color;
}
pointcloud.frag:
glsl
#version 330 core
in vec3 fragColor;
out vec4 outColor;
void main()
{
outColor = vec4(fragColor, 1.0);
}
4. 加载和显示点云数据
cpp
void PointCloudViewer::loadPointCloud(const std::vector<float>& points)
{
m_points = points;
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, m_points.size() * sizeof(float), m_points.data(), 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);
glBindVertexArray(0);
update();
}
void PointCloudViewer::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 model;
QMatrix4x4 view;
QMatrix4x4 projection;
// 设置相机和投影矩阵
view.lookAt(QVector3D(0, 0, 5), QVector3D(0,