用openGL+QT简单实现二进制stl文件读取显示并通过鼠标旋转缩放

** 本文仅通过用openGL+QT简单实现二进制stl文件读取显示并通过鼠标旋转缩放, 是比较入门的级别,由于个人能力有限,新手级别,所以未能施加光影灯光等操作, 未能让显示的stl文件更加真实。**

**

效果图:

在这里插入图片描述

**

1. main.cpp


```cpp
#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Triangle t;
    t.resize(1000,800);
    t.show();
    return a.exec();
}

**

2. shader.cpp

#include "shader.h"

Shader::Shader(const QString& vertexPath, const QString& fragmentPath){
    QOpenGLShader vertexShader(QOpenGLShader::Vertex);
    bool success = vertexShader.compileSourceFile(vertexPath);
    if(!success){
        qDebug() << "ERROR::SHADER::VERTEX::COMPILATION_FAILED" << endl;
        qDebug() << vertexShader.log() << endl;
    }

    QOpenGLShader fragmentShader(QOpenGLShader::Fragment);
    success  =fragmentShader.compileSourceFile(fragmentPath);
    if(!success){
        qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED" << endl;
        qDebug() << fragmentShader.log() << endl;
    }

   shaderProgram.addShader(&vertexShader);
   shaderProgram.addShader(&fragmentShader);
   success = shaderProgram.link();
   if(!success){
        qDebug() << "ERROR::SHADER::PROGRAM::LINKING_FAILED" << endl;
        qDebug() << shaderProgram.log() << endl;
   }
}

Shader::~Shader(){
}

3.widget.cpp

#include "widget.h"
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QMouseEvent>
#include <QWheelEvent>

GLfloat vertices[100000000];
GLuint VBO, VAO;

Triangle::Triangle(){
    this->setWindowTitle("STL_Show");
}

Triangle::~Triangle(){
    delete ourShader;
    core->glDeleteVertexArrays(1, &VAO);
    core->glDeleteBuffers(1, &VBO);
   // delete vertices;
}

void Triangle::initializeGL(){

    //着色器部分
    core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
    ourShader = new Shader(":/shader/vertexshadersource.txt", ":/shader/fragmentshadersource.txt");

    //vertices = (float *) malloc(sizeof (float)*10000000);
    //VAO,VBO数据部分

    this->stl_Read(); //获取stl文件,并存入vertices数组。

    core->glGenVertexArrays(1, &VAO);//两个参数,第一个为需要创建的缓存数量。第二个为用于存储单一ID或多个ID的GLuint变量或数组的地址
    core->glGenBuffers(1, &VBO);

    core->glBindVertexArray(VAO);

    core->glBindBuffer(GL_ARRAY_BUFFER, VBO);
    core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    core->glEnableVertexAttribArray(0);
    core->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
    core->glEnableVertexAttribArray(1);

    core->glBindBuffer(GL_ARRAY_BUFFER, 0);
    core->glBindVertexArray(0);


    // view matrix
    view.setToIdentity();
    view.lookAt(QVector3D(0.0f, 0.0f, 1.0f), QVector3D(0.0f,0.0f,0.0f), QVector3D(0.0f,1.0f,0.0f));

    //开启状态
    core->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    core->glEnable(GL_DEPTH_TEST);
}

void Triangle::resizeGL(int w, int h){

    core->glViewport(0, 0, w, h);
    projection.setToIdentity();
    projection.perspective(60.0f, (GLfloat)w/(GLfloat)h, 0.1f, 100.0f);
}

void Triangle::paintGL(){

    core->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // transform the model
    model.setToIdentity();
    model.translate(xtrans, ytrans, ztrans);
    model.rotate(rotation);
    QMatrix4x4 mv = view * model;
    ourShader->setMat4("ModelViewMatrix", mv);
    ourShader->setMat4("MVP", projection * mv);
    ourShader->use();

    core->glBindVertexArray(VAO);
    //绘制三角形
    core->glDrawArrays(GL_TRIANGLES, 0, VerticesCnt/6);
    //绘制点云
   //core->glDrawArrays(GL_POINTS, 0, VerticesCnt/2);

}

void Triangle::mousePressEvent(QMouseEvent *event)
{
    mousePos = QVector2D(event->pos());
    event->accept();
}

void Triangle::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons() == Qt::LeftButton)
    {
        QVector2D newPos = (QVector2D)event->pos();
        QVector2D diff = newPos - mousePos;
        qreal angle = (diff.length())/3.6;
        QVector3D rotationAxis = QVector3D(diff.y(), diff.x(), 0.0).normalized();
        rotation = QQuaternion::fromAxisAndAngle(rotationAxis, angle) * rotation;
        mousePos = newPos;
        this->update();
    }
    event->accept();
}

void Triangle::wheelEvent(QWheelEvent *event)
{
    QPoint numDegrees = event->angleDelta() / 8;
    if (numDegrees.y() > 0) {
        ztrans += 0.25f;
    } else if (numDegrees.y() < 0) {
        ztrans -= 0.25f;
    }
    this->update();
    event->accept();
}

void Triangle::stl_Read()    //读取二进制stl文件
{

    GLint fileSize;  //记录文件大小
    QFile STL_file(":/shader/l2.STL");
    bool isOk = STL_file.open(QIODevice::ReadOnly);
    fileSize = STL_file.size();
    GLchar * buf = (char *)malloc(sizeof(char)*fileSize);
    if(isOk == true)
    {
       QDataStream stream(&STL_file);
       stream.readRawData(buf,fileSize);
       STL_file.close();
    }

    const GLchar* p = buf;
    GLchar name[80];
    GLfloat temp;
    GLint binary_i;
    GLint triangle_num;
    memcpy(name,p,80);//记录文件名
    p += 80; //跳过文件名
    memcpy(&triangle_num,p,4);//记录三角形个数
    p += 4; //跳过个数标识
    qDebug()<<triangle_num<<"\n"; //控制台打印三角形个数
    for (binary_i=0;binary_i<triangle_num;binary_i++)
    {
         p += 12;//跳过头部的法向量
        //vertex
         memcpy(&temp,p,4);vertices[VerticesCnt] = temp ;p+=4;VerticesCnt++;//vertices[0]赋值
         memcpy(&temp,p,4);vertices[VerticesCnt] = temp;p+=4;VerticesCnt++;//vertices[1]赋值
         memcpy(&temp,p,4);vertices[VerticesCnt] = temp ;p+=4;VerticesCnt++;//vertices[2]赋值
         vertices[VerticesCnt] = 1.0;VerticesCnt++;
         vertices[VerticesCnt] = 0.9;VerticesCnt++;
         vertices[VerticesCnt] = 0.6;VerticesCnt++;
        //vertex
         memcpy(&temp,p,4);vertices[VerticesCnt] = temp ;p+=4;VerticesCnt++;//vertices[0]赋值
         memcpy(&temp,p,4);vertices[VerticesCnt] = temp ;p+=4;VerticesCnt++;//vertices[1]赋值
         memcpy(&temp,p,4);vertices[VerticesCnt] = temp ;p+=4;VerticesCnt++;//vertices[2]赋值
         vertices[VerticesCnt] = 1.0;VerticesCnt++;
         vertices[VerticesCnt] = 0.9;VerticesCnt++;
         vertices[VerticesCnt] = 0.6;VerticesCnt++;
         //vertex
         memcpy(&temp,p,4);vertices[VerticesCnt] = temp;p+=4;VerticesCnt++;//vertices[0]赋值
         memcpy(&temp,p,4);vertices[VerticesCnt] = temp ;p+=4;VerticesCnt++;//vertices[1]赋值
         memcpy(&temp,p,4);vertices[VerticesCnt] = temp ;p+=4;VerticesCnt++;//vertices[2]赋值
         vertices[VerticesCnt] = 1.0;VerticesCnt++;
         vertices[VerticesCnt] = 0.9;VerticesCnt++;
         vertices[VerticesCnt] = 0.6;VerticesCnt++;
         p += 2;//跳过尾部标志
     }
     free(buf);
}


参考博客:
https://blog.csdn.net/qq_27133869/article/details/105645644
https://blog.csdn.net/chaojiwudixiaofeixia/article/details/78043051

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山野万里_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值