飞道的博客

QT点云显示--基于QOpenGLWidget和QOpenGLFunctions实现

1410人阅读  评论(0)

一、实现功能

1、网格显示

2、坐标轴显示

3、鼠标操作旋转、平移、缩放

4、点云显示

之前写了一篇基于QGLWidget实现,此版本的功能接口基本保持一致,方便对比

QT点云显示--基于QGLWidget实现_Jason~shen的博客-CSDN博客1、网格显示2、坐标轴显示3、鼠标操作旋转、平移、缩放4、点云显示。https://blog.csdn.net/qq_40602000/article/details/128293336?spm=1001.2014.3001.5501

QGLWidget与QOpenGLWidget的区别:

1、QGLWidget中是直接调用opengl指令,个人觉得比较方便,逻辑清晰,可以了解opengl底层的接口;

2、QOpenGLWidget是调用QOpenGLFunctions中封装接口,从Qt5.4开始,Qt推荐使用QOpenGLWidget和QOpenGL类。

二、实现效果

 

 

 

三、实现方法

细节待补充

完整代码

PointCloudOpenGLWidget.h

  
  1. #ifndef BASEOPENGLWIDGET_H
  2. #define BASEOPENGLWIDGET_H
  3. #include <QOpenGLWidget>
  4. #include <QOpenGLFunctions_3_3_Core>
  5. #include <QOpenGLShaderProgram>
  6. #include <QOpenGLTexture>
  7. #include <QMouseEvent>
  8. #include "opengllib_global.h"
  9. class OPENGLLIBSHARED_EXPORT PointCloudOpenGLWidget: public QOpenGLWidget, public QOpenGLFunctions_3_3_Core
  10. {
  11. Q_OBJECT
  12. public:
  13. PointCloudOpenGLWidget(QWidget *parent = 0);
  14. ~ PointCloudOpenGLWidget();
  15. void updatePoints(const QVector<QVector3D> &points);
  16. void loadCsvFile(const QString &path);
  17. protected:
  18. void initializeGL() override;
  19. void paintGL() override;
  20. void resizeGL(int width, int height) override;
  21. void mousePressEvent(QMouseEvent *event) override;
  22. void mouseMoveEvent(QMouseEvent *event) override;
  23. void wheelEvent(QWheelEvent *event);
  24. virtual unsigned int drawMeshline(float size, int count);
  25. virtual void drawCooraxis(float length);
  26. virtual unsigned int drawPointdata(std::vector<float> &pointVertexs);
  27. protected:
  28. QOpenGLShaderProgram m_shaderProgramMesh;
  29. QOpenGLShaderProgram m_shaderProgramAxis;
  30. QOpenGLShaderProgram m_shaderProgramPoint;
  31. unsigned int m_VBO_MeshLine;
  32. unsigned int m_VAO_MeshLine;
  33. unsigned int m_VBO_Axis;
  34. unsigned int m_VAO_Axis;
  35. unsigned int m_VBO_Point;
  36. unsigned int m_VAO_Point;
  37. std::vector< float> m_pointData;
  38. unsigned int m_pointCount;
  39. unsigned int m_vertexCount;
  40. float m_xRotate;
  41. float m_zRotate;
  42. float m_xTrans;
  43. float m_yTrans;
  44. float m_zoom;
  45. QPoint lastPos;
  46. };
PointCloudOpenGLWidget.cpp

  
  1. #include "PointCloudOpenGLWidget.h"
  2. #include <QDebug>
  3. PointCloudOpenGLWidget:: PointCloudOpenGLWidget(QWidget *parent)
  4. : QOpenGLWidget(parent)
  5. {
  6. m_xRotate = -30.0;
  7. m_zRotate = 100.0;
  8. m_xTrans = 0.0;
  9. m_yTrans = 0.0;
  10. m_zoom = 45.0;
  11. }
  12. PointCloudOpenGLWidget::~ PointCloudOpenGLWidget()
  13. {
  14. makeCurrent();
  15. glDeleteBuffers( 1, &m_VBO_MeshLine);
  16. glDeleteVertexArrays( 1, &m_VAO_MeshLine);
  17. glDeleteBuffers( 1, &m_VBO_Axis);
  18. glDeleteVertexArrays( 1, &m_VAO_Axis);
  19. glDeleteBuffers( 1, &m_VBO_Point);
  20. glDeleteVertexArrays( 1, &m_VAO_Point);
  21. m_shaderProgramMesh. release();
  22. m_shaderProgramAxis. release();
  23. m_shaderProgramPoint. release();
  24. doneCurrent();
  25. qDebug() << __FUNCTION__;
  26. }
  27. void PointCloudOpenGLWidget::updatePoints(const QVector<QVector3D> &points)
  28. {
  29. m_pointData. clear();
  30. for( auto vector3D : points)
  31. {
  32. m_pointData. push_back(vector3D. x());
  33. m_pointData. push_back(vector3D. y());
  34. m_pointData. push_back(vector3D. z());
  35. m_pointData. push_back( 1);
  36. }
  37. }
  38. void PointCloudOpenGLWidget::loadCsvFile(const QString &path)
  39. {
  40. m_pointData. clear();
  41. QFile inFile(path);
  42. if (inFile. open(QIODevice::ReadOnly))
  43. {
  44. QTextStream stream_text(&inFile);
  45. while (!stream_text. atEnd())
  46. {
  47. QString line = stream_text. readLine();
  48. QStringList strSplit = line. split( ",");
  49. double x = strSplit. value( 0). toDouble();
  50. double y = strSplit. value( 1). toDouble();
  51. double z = strSplit. value( 2). toDouble();
  52. m_pointData. push_back(x);
  53. m_pointData. push_back(y);
  54. m_pointData. push_back(z);
  55. m_pointData. push_back( 1);
  56. }
  57. inFile. close();
  58. }
  59. }
  60. void PointCloudOpenGLWidget::initializeGL()
  61. {
  62. initializeOpenGLFunctions();
  63. // enable depth_test
  64. glEnable(GL_DEPTH_TEST);
  65. // link meshline shaders vs文件为顶点着色器 fs为片段着色器
  66. m_shaderProgramMesh. addShaderFromSourceFile(QOpenGLShader::Vertex,
  67. ":/opengl/shader/shader_mesh.vs");
  68. m_shaderProgramMesh. addShaderFromSourceFile(QOpenGLShader::Fragment,
  69. ":/opengl/shader/shader_mesh.fs");
  70. m_shaderProgramMesh. link();
  71. // link coordinate axis shaders
  72. m_shaderProgramAxis. addShaderFromSourceFile(QOpenGLShader::Vertex,
  73. ":/opengl/shader/shader_axis.vs");
  74. m_shaderProgramAxis. addShaderFromSourceFile(QOpenGLShader::Fragment,
  75. ":/opengl/shader/shader_axis.fs");
  76. m_shaderProgramAxis. link();
  77. // link pointcloud shaders
  78. m_shaderProgramPoint. addShaderFromSourceFile(QOpenGLShader::Vertex,
  79. ":/opengl/shader/shader_point.vs");
  80. m_shaderProgramPoint. addShaderFromSourceFile(QOpenGLShader::Fragment,
  81. ":/opengl/shader/shader_point.fs");
  82. m_shaderProgramPoint. link();
  83. m_vertexCount = drawMeshline( 2.0, 16);
  84. m_pointCount = drawPointdata(m_pointData);
  85. qDebug() << "point_count" << m_pointCount;
  86. drawCooraxis( 4.0);
  87. }
  88. void PointCloudOpenGLWidget::paintGL()
  89. {
  90. glClearColor( 0.1f, 0.1f, 0.1f, 1.0f);
  91. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  92. /*
  93. 为了将坐标从一个坐标系转换到另一个坐标系,需要用到几个转换矩阵,
  94. 分别是模型(Model)、视图(View)、投影(Projection)三个矩阵。
  95. */
  96. QMatrix4x4 projection, view, model;
  97. //透视矩阵变换
  98. projection. perspective(m_zoom, ( float) width() / ( float) height(), 1.0f, 100.0f);
  99. // eye:摄像机位置 center:摄像机看的点位 up:摄像机上方的朝向
  100. view. lookAt( QVector3D( 0.0, 0.0, 50.0), QVector3D( 0.0, 0.0, 1.0), QVector3D( 0.0, 1.0, 0.0));
  101. model. translate(m_xTrans, m_yTrans, 0.0);
  102. model. rotate(m_xRotate, 1.0, 0.0, 0.0);
  103. model. rotate(m_zRotate, 0.0, 0.0, 1.0);
  104. m_shaderProgramMesh. bind();
  105. m_shaderProgramMesh. setUniformValue( "projection", projection);
  106. m_shaderProgramMesh. setUniformValue( "view", view);
  107. m_shaderProgramMesh. setUniformValue( "model", model);
  108. m_shaderProgramAxis. bind();
  109. m_shaderProgramAxis. setUniformValue( "projection", projection);
  110. m_shaderProgramAxis. setUniformValue( "view", view);
  111. m_shaderProgramAxis. setUniformValue( "model", model);
  112. m_shaderProgramPoint. bind();
  113. m_shaderProgramPoint. setUniformValue( "projection", projection);
  114. m_shaderProgramPoint. setUniformValue( "view", view);
  115. m_shaderProgramPoint. setUniformValue( "model", model);
  116. //画网格
  117. m_shaderProgramMesh. bind();
  118. glBindVertexArray(m_VAO_MeshLine);
  119. glLineWidth( 1.0f);
  120. glDrawArrays(GL_LINES, 0, m_vertexCount);
  121. //画坐标轴
  122. m_shaderProgramAxis. bind();
  123. glBindVertexArray(m_VAO_Axis);
  124. glLineWidth( 5.0f);
  125. glDrawArrays(GL_LINES, 0, 6);
  126. //画点云
  127. m_shaderProgramPoint. bind();
  128. glBindVertexArray(m_VAO_Point);
  129. glPointSize( 1.0f);
  130. glDrawArrays(GL_POINTS, 0, m_pointCount);
  131. }
  132. void PointCloudOpenGLWidget::resizeGL(int width, int height)
  133. {
  134. glViewport( 0, 0, width, height);
  135. }
  136. void PointCloudOpenGLWidget::mousePressEvent(QMouseEvent *event)
  137. {
  138. lastPos = event-> pos();
  139. }
  140. void PointCloudOpenGLWidget::mouseMoveEvent(QMouseEvent *event)
  141. {
  142. int dx = event-> pos(). x() - lastPos. x();
  143. int dy = event-> pos(). y() - lastPos. y();
  144. if (event-> buttons() & Qt::LeftButton)
  145. {
  146. m_xRotate = m_xRotate + 0.3 * dy;
  147. m_zRotate = m_zRotate + 0.3 * dx;
  148. if (m_xRotate > 30.0f)
  149. {
  150. m_xRotate = 30.0f;
  151. }
  152. if (m_xRotate < -120.0f)
  153. {
  154. m_xRotate = -120.0f;
  155. }
  156. update();
  157. }
  158. else if (event-> buttons() & Qt::MidButton)
  159. {
  160. m_xTrans = m_xTrans + 0.1 * dx;
  161. m_yTrans = m_yTrans - 0.1 * dy;
  162. update();
  163. }
  164. lastPos = event-> pos();
  165. }
  166. void PointCloudOpenGLWidget::wheelEvent(QWheelEvent *event)
  167. {
  168. auto scroll_offest = event-> angleDelta(). y() / 120;
  169. m_zoom = m_zoom - ( float)scroll_offest;
  170. if (m_zoom < 1.0f) /* 放大限制 */
  171. {
  172. m_zoom = 1.0f;
  173. }
  174. if (m_zoom > 80.0f)
  175. {
  176. m_zoom = 80.0f;
  177. }
  178. update();
  179. }
  180. unsigned int PointCloudOpenGLWidget::drawMeshline(float size, int count)
  181. {
  182. std::vector< float> mesh_vertexs;
  183. unsigned int vertex_count = 0;
  184. float start = count * (size / 2);
  185. float posX = start, posZ = start;
  186. for ( int i = 0; i <= count; ++i)
  187. {
  188. mesh_vertexs. push_back(posX);
  189. mesh_vertexs. push_back(start);
  190. mesh_vertexs. push_back( 0);
  191. mesh_vertexs. push_back(posX);
  192. mesh_vertexs. push_back(-start);
  193. mesh_vertexs. push_back( 0);
  194. mesh_vertexs. push_back(start);
  195. mesh_vertexs. push_back(posZ);
  196. mesh_vertexs. push_back( 0);
  197. mesh_vertexs. push_back(-start);
  198. mesh_vertexs. push_back(posZ);
  199. mesh_vertexs. push_back( 0);
  200. posX = posX - size;
  201. posZ = posZ - size;
  202. }
  203. glGenVertexArrays( 1, &m_VAO_MeshLine);
  204. glGenBuffers( 1, &m_VBO_MeshLine);
  205. glBindVertexArray(m_VAO_MeshLine);
  206. glBindBuffer(GL_ARRAY_BUFFER, m_VBO_MeshLine);
  207. glBufferData(GL_ARRAY_BUFFER, mesh_vertexs. size() * sizeof( float), &mesh_vertexs[ 0], GL_STATIC_DRAW);
  208. glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof( float), ( void *) 0);
  209. glEnableVertexAttribArray( 0);
  210. glBindBuffer(GL_ARRAY_BUFFER, 0);
  211. glBindVertexArray( 0);
  212. vertex_count = ( int)mesh_vertexs. size() / 3;
  213. return vertex_count;
  214. }
  215. void PointCloudOpenGLWidget::drawCooraxis(float length)
  216. {
  217. std::vector< float> axis_vertexs =
  218. {
  219. //x,y ,z ,r, g, b
  220. 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
  221. length, 0.0, 0.0, 1.0, 0.0, 0.0,
  222. 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
  223. 0.0, length, 0.0, 0.0, 1.0, 0.0,
  224. 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
  225. 0.0, 0.0, length, 0.0, 0.0, 1.0,
  226. };
  227. glGenVertexArrays( 1, &m_VAO_Axis);
  228. glGenBuffers( 1, &m_VBO_Axis);
  229. glBindVertexArray(m_VAO_Axis);
  230. glBindBuffer(GL_ARRAY_BUFFER, m_VBO_Axis);
  231. glBufferData(GL_ARRAY_BUFFER, axis_vertexs. size() * sizeof( float), &axis_vertexs[ 0], GL_STATIC_DRAW);
  232. // 位置属性
  233. glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof( float), ( void *) 0);
  234. glEnableVertexAttribArray( 0);
  235. // 颜色属性
  236. glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof( float), ( void *)( 3 * sizeof( float)));
  237. glEnableVertexAttribArray( 1);
  238. glBindBuffer(GL_ARRAY_BUFFER, 0);
  239. glBindVertexArray( 0);
  240. }
  241. unsigned int PointCloudOpenGLWidget::drawPointdata(std::vector<float> &pointVertexs)
  242. {
  243. unsigned int point_count = 0;
  244. glGenVertexArrays( 1, &m_VAO_Point);
  245. glGenBuffers( 1, &m_VBO_Point);
  246. glBindVertexArray(m_VAO_Point);
  247. glBindBuffer(GL_ARRAY_BUFFER, m_VBO_Point);
  248. glBufferData(GL_ARRAY_BUFFER, pointVertexs. size() * sizeof( float), &pointVertexs[ 0], GL_STATIC_DRAW);
  249. // 位置属性
  250. glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 4 * sizeof( float), ( void *) 0);
  251. glEnableVertexAttribArray( 0);
  252. // 颜色属性
  253. glVertexAttribPointer( 1, 1, GL_FLOAT, GL_FALSE, 4 * sizeof( float), ( void *)( 3 * sizeof( float)));
  254. glEnableVertexAttribArray( 1);
  255. glBindBuffer(GL_ARRAY_BUFFER, 0);
  256. glBindVertexArray( 0);
  257. point_count = ( unsigned int)pointVertexs. size() / 4;
  258. return point_count;
  259. }


转载:https://blog.csdn.net/qq_40602000/article/details/128307566
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场