QT中OpenGL显示solidworks导出3D模型(.obj格式)

只是显示并鼠标简单交互下,不太熟悉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);
}

 

posted @ 2021-11-30 09:49  清热降火  阅读(866)  评论(0编辑  收藏  举报