Qt与OpenGL绘制大全(加载obj模型文件、点、线、面、立方体、圆等)
1、功能介绍
最近项目要求用Qt+OpenGL绘制图形,要求可以加载Obj模型文件,并且可以画点、线、多边形(三角形、四边形、五边形、...、n边形、空心圆、实心圆、圆柱、圆锥、圆台等,在绘制前后还可以分别指定图形的透明度、颜色、大小等参数。
2、成果展示
画布版:
添加天空盒:
3、关键技术
Qt、 OpenGl、 着色器
4、关键代码
4.1、画布使用
成果展示左侧部分是我为验证接口写的调试界面,主要代码都是在右侧画布上,只是将画布潜在了调试的类里。
mainwindow.ui
mainwindow.h
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "OpenGLMainWidget.h"
#include <QtMath>
#include <vector>
#include <random>
#include <cmath>
#include <QProgressDialog>
#include <QListWidgetItem>
QT_BEGIN_NAMESPACE
namespace Ui {class MainWindow;}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;float height, float depth);
public:
OpenGLMainWidget* m_openGLWidget;
private slots:
void on_pushButton_clearCanvas_clicked();
...
};
#endif // MAINWINDOW_H
mainwindow.cpp
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QCoreApplication>
#include <QFileDialog>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setWindowState(Qt::WindowMaximized);
m_openGLWidget = new OpenGLMainWidget(parent);
ui->gridLayout_5->addWidget(m_openGLWidget);
}
MainWindow::~MainWindow()
{
delete ui;
}
4.2、可用接口
通过这些接口,可以完成对点、线、多边形(三角形、四边形、五边形、...、n边形、空心圆、实心圆、圆柱、圆锥、圆台等图形的绘制与修改。注意看每个接口后的注释!
OpenGLMainWidget.h
cpp
public:
explicit OpenGLMainWidget(QWidget* parent = nullptr);
~OpenGLMainWidget();
//画布可画:
//1、obj模型
//2、图形
//2.1、点
//2.2、线
//2.3、多边形(三角形、四边形、五边形、...、n边形)
//2.4、其他(实心圆、空心圆、圆锥、圆柱、圆台)
//------------------------------------------------------------------------------------对画布的操作-------------------------------------------------------------
void UpdateTheCanvas(); //刷新画布
void ClearCanvas(); //清空画布
void RemoveAllModels(); //清除所有模型
void RemoveAllGraphics(); //清除所有图形(除模型以外的所有物体)
void RemoveAllPoints(); //清除所有点
void RemoveAllLineSegments(); //清除所有线
void RemoveAllPolygons(); //清除所有多边形
void SetAllModelTransparencyByCode(const float &transparency); //修改所有模型透明度
void SetAllPolygonsFaceTransparencyByCode(const float &transparency); //修改所有多边形面透明度
void SetAllPolygonsEdgeTransparencyByCode(const float &transparency); //修改所有多边形面透明度
void SetAllPolygonsFaceColorByCode(const QVector3D &color); //修改所有多边形面颜色
void SetAllPolygonsEdgeColorByCode(const QVector3D &color); //修改所有多边形边颜色
void SetCamaraPosition(const QVector3D &cameraPosition); //修改相机位置
void RestoreOriginalPosition(); //将相机、模型、多边形恢复到最初位置
void CheckSkyBox(const bool &isload); //设置是否使用天空盒
void SetSkyBoxImagePath(const SkyBoxStruct &skyBoxImagePath); //设置天空盒素材
void SetCanvasColor(const QVector4D &canvasColor); //设置画布背景颜色
//------------------------------------------------------------------------------------对模型的操作-------------------------------------------------------------
void loadModel(const LoadModelInfo &loadModelInfo); //加载模型
void RemoveModelsByCode(const QStringList &codeList); //根据模型code删除画布上的指定模型
void SetModelWorldPosByCode(const QString &code,const QVector3D &worldPos); //修改模型位置
void SetModelRotationAngleByCode(const QStringList &codeList,const QVector3D &rotationAngle); //旋转模型角度
void SetModelIsDisplayOutlineByCode(const QStringList &codeList,const bool &display); //设置模型是否显示外轮廓
void SetModelOutlineColorByCode(const QStringList &codeList,const QVector3D &outlineColor); //修改外轮廓颜色
void SetModelScaleByCode(const QStringList &codeList, const QVector3D &scale); //修改缩放比例
void SetModelTransparencyByCode(const QStringList &codeList,const float &transparency); //修改透明度
//------------------------------------------------------------------------------------对点的操作-------------------------------------------------------------
void DrawPoint(const LoadPointInfo &loadPointInfo); //绘制点
void RemovePointByCode(const QStringList &codeList); //根据code删除画布上的指定点
void SetPointColorByCode(const QStringList &codeList,const QVector3D &color); //修改颜色
void SetPointTransparencyByCode(const QStringList &codeList, float transparency); //修改透明度
void SetPointSizeByCode(const QStringList &codeList, float size); //修改点的尺寸
//------------------------------------------------------------------------------------对线段的操作-------------------------------------------------------------
void DrawLineSegment(const LoadLineSegmentInfo &loadLineSegmentInfo); //画线段
void RemoveLineSegmentByCode(const QStringList &codeList); //根据code删除画布上的指定线段
void SetLineSegmentTransparencyByCode(const QStringList &codeList,const float &transparency); //修改透明度
void SetLineSegmentColorByCode(const QStringList &codeList,const QVector3D &color); //修改颜色
void SetLineSegmentWidthByCode(const QStringList &codeList, float width); //修改线宽
//------------------------------------------------------------------------------------对多边形的操作-------------------------------------------------------------
void DrawPolygons(const QVector<LoadPolygonInfo> &loadPolygonInfoVec); // 画多边形
void RemovePolygonsByCode(const QStringList &codeList); //根据code删除画布上的指定多边形
void SetPolygonFaceTransparencyByCode(const QStringList &codeList,const float &transparency); //修改多边形面版透明度
void SetPolygonEdgeTransparencyByCode(const QStringList &codeList,const float &transparency); //修改多边形边框透明度
void SetPolygonFaceColorByCode(const QStringList &codeList,const QVector3D &faceColor); //修改多边形面颜色
void SetPolygonEdgeColorByCode(const QStringList &codeList,const QVector3D &edgeColor); //修改多边形边框颜色
void SetPolygonIsTextureByCode(const bool &isTexture); //设置多边形是否贴图
void SetPolygonTexturePathByCode(const QString &code,const QString &texturePath); //修改多边形贴图文件
void SetPolygonEdgeWidthByCode(const QStringList &codeList, float width); //修改边框线宽
//------------------------------------------------------------------------------------对圆台的操作-------------------------------------------------------------
void DrawFrustumCone(const LoadFrustumConeInfo &loadFrustumConeInfo); //画圆台
void RemoveFrustumConesByCode(const QStringList &codeList); //根据code删除画布上的指定圆台
void SetFrustumConeTransparencyByCode(const QStringList &codeList, float transparency); //修改透明度
void SetFrustumConeColorByCode(const QStringList &codeList, const QVector3D &color); //修改颜色
//------------------------------------------------------------------------------------对圆柱的操作-------------------------------------------------------------
void DrawCylinder(const LoadCylinderInfo &loadCylinderInfo); //画圆柱
void RemoveCylindersByCode(const QStringList &codeList); //根据code删除画布上的指定圆柱
void SetCylinderTransparencyByCode(const QStringList &codeList, float transparency); //修改透明度
void SetCylinderColorByCode(const QStringList &codeList, const QVector3D &color); //修改颜色
//------------------------------------------------------------------------------------对圆锥的操作-------------------------------------------------------------
void DrawCone(const LoadConeInfo &loadConeInfo); //画圆锥
void RemoveConesByCode(const QStringList &codeList); //根据code删除画布上的指定圆锥
void SetConeTransparencyByCode(const QStringList &codeList, float transparency); //修改透明度
void SetConeColorByCode(const QStringList &codeList, const QVector3D &color); //修改颜色
//------------------------------------------------------------------------------------对圆的操作-------------------------------------------------------------
void DrawCircular(const LoadCircleInfo &loadCircleInfo); //画圆
void RemoveCircularsByCode(const QStringList &codeList); //根据code删除画布上的指定圆
void SetCircularTransparencyByCode(const QStringList &codeList, float transparency); //修改透明度
void SetCircularColorByCode(const QStringList &codeList, const QVector3D &color); //修改颜色
//------------------------------------------------------------------------------------其他算法-------------------------------------------------------------
std::vector<std::vector<float> > CalculateCubeFaces(const QVector3D ¢er, float width, float height, float depth);//根据长方体的中心坐标、宽度、高度、深度,计算长方体六个面的顶点坐标,返回包含6个面的顶点坐标集合,每个面由4个顶点共12个浮点数组成
signals:
void MousePickingPosSignal(QVector3D worldPos);//鼠标拾取位置信号
void MouseClickedModelSignal(QString modelCode);//鼠标点击模型返回的信号
protected:
void keyPressEvent(QKeyEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
5、扩展
目前还在不停增加功能,后续希望能够添加文字、坐标指示器等。