只是显示并鼠标简单交互下,不太熟悉OpenGL,代码抄的
QT中新建一个ModelGLWidget类
modelglwidget.h
#ifndef MODELGLWIDGET_H #define MODELGLWIDGET_H #include <QWidget> #include <QOpenGLWidget> #include <QOpenGLFunctions_3_3_Core> #include <QOpenGLBuffer> #include <QOpenGLShaderProgram> class ModelGLWidget : public QOpenGLWidget, QOpenGLFunctions_3_3_Core { Q_OBJECT public: explicit ModelGLWidget(QWidget *parent = nullptr); ~ModelGLWidget(); void rotateBy(int xAngle, int yAngle, int zAngle); QString objPath; protected: void initializeGL() override; void resizeGL(int w, int h) override; void paintGL() override; void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; private: unsigned int VBO, VAO, EBO; QVector<float> vertextPoints; QVector<int> facesIndexs; void makeModel(QString path); QOpenGLShaderProgram program; QPoint lastPos; int xRot; int yRot; int zRot; signals: void clicked(); }; #endif // MODELGLWIDGET_H
modelglwidget.cpp
#include "modelglwidget.h" #include <QFile> #include "mainwindow.h" #include <QMouseEvent> #include <QMessageBox> #include <QDebug> ModelGLWidget::ModelGLWidget(QWidget *parent) : QOpenGLWidget(parent) { } ModelGLWidget::~ModelGLWidget() { makeCurrent(); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); glDeleteVertexArrays(1, &VAO); doneCurrent(); } void ModelGLWidget::rotateBy(int xAngle, int yAngle, int zAngle) { xRot += xAngle; yRot += yAngle; zRot += zAngle; update(); } void ModelGLWidget::initializeGL() { initializeOpenGLFunctions(); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); if(objPath != NULL) makeModel(objPath); bool sucess; program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shapes.vert"); program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shapes.frag"); sucess = program.link(); } void ModelGLWidget::resizeGL(int w, int h) { Q_UNUSED(w);Q_UNUSED(h); } void ModelGLWidget::paintGL() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); QMatrix4x4 m; m.ortho(-0.5f, +0.5f, +0.5f, -0.5f, 4.0f, 15.0f); m.translate(0.0f, 0.0f, -10.0f); m.rotate(xRot / 16.0f, 1.0f, 0.0f, 0.0f); m.rotate(yRot / 16.0f, 0.0f, 1.0f, 0.0f); m.rotate(zRot / 16.0f, 0.0f, 0.0f, 1.0f); program.setUniformValue("matrix", m); program.bind(); glBindVertexArray(VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glDrawElements(GL_TRIANGLES, int(facesIndexs.length()), GL_UNSIGNED_INT, 0/*&fIndexs*/); } void ModelGLWidget::mousePressEvent(QMouseEvent *event) { lastPos = event->pos(); } void ModelGLWidget::mouseMoveEvent(QMouseEvent *event) { int dx = event->x() - lastPos.x(); int dy = event->y() - lastPos.y(); if (event->buttons() & Qt::LeftButton) { rotateBy(8 * dy, 8 * dx, 0); } else if (event->buttons() & Qt::RightButton) { rotateBy(8 * dy, 0, 8 * dx); } lastPos = event->pos(); } void ModelGLWidget::mouseReleaseEvent(QMouseEvent *event) { emit clicked(); } void ModelGLWidget::makeModel(QString path) { QFile file(path); file.open(QFile::ReadOnly); if(file.isOpen()) { while(!file.atEnd()) { QByteArray lineData = file.readLine(); lineData = lineData.remove(lineData.count() - 2, 2); if(lineData == "") continue; QList<QByteArray> strValues = lineData.split(' '); QString dataType = strValues.takeFirst(); if(dataType == 'v') { vertextPoints.push_back(strValues[0].toFloat()); vertextPoints.push_back(strValues[1].toFloat()); vertextPoints.push_back(strValues[2].toFloat()); } if(dataType == 'f') { facesIndexs.push_back(strValues[0].toInt()-1); facesIndexs.push_back(strValues[1].toInt()-1); facesIndexs.push_back(strValues[2].toInt()-1); } } } float *max = std::max_element(std::begin(vertextPoints), std::end(vertextPoints)); float maxCal = 3*(*max); float* vPoints = new float[vertextPoints.length()]; int* fIndexs = new int[facesIndexs.length()]; for(int i=0;i<vertextPoints.length();++i) vPoints[i] = vertextPoints.at(i)/maxCal; for(int j=0;j<facesIndexs.length();j++) fIndexs[j] = facesIndexs.at(j); glGenBuffers(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*vertextPoints.length(), vPoints, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*facesIndexs.length(), fIndexs, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof (float), (void*)0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); delete [] vPoints; delete [] fIndexs; }
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); setWindowTitle("点云生成器v1.0"); code = QTextCodec::codecForName("GB2312"); //字符处理 dialog->setModal(false); dialog->setGeometry(100, 100, 500, 500); dialog->setFixedSize(500, 500); } void MainWindow::on_importModelBtn_clicked() { ModelGLWidget *myGL = new ModelGLWidget(dialog); readPath = QFileDialog::getOpenFileName(this, "选择一个obj文件", "", "(*.obj)"); myGL->setGeometry(0, 0, 500, 500); myGL->objPath = readPath; dialog->show(); }
资源文件
shapes.frag
#version 330 core out vec4 FragColor; void main() { FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); }
shapes.vert
#version 330 core layout(location = 0) in vec3 aPos; uniform mediump mat4 matrix; void main() { gl_Position = matrix*vec4(aPos.x, aPos.y, aPos.z, 1.0f); }