0


13. OPenGL与QT界面元素交互控制图形渲染

1. 说明:

前面文章中讲到的 OPenGL 渲染都是在页面加载完成即立刻渲染的,如果向控制图形渲染的时间,可以在QT界面中添加一些元素来进行控制。此时需要用到OPenGL当中的makeCurrent(),update(),doneCurrent()函数。
效果展示:

opengl与qt交互

2. 步骤一:

在myopenglwidget.h文件中添加一个枚举,放置要绘制的图形类型,同时声明三个函数,分别为drawShape(),clearGraphic(),setWireFrame(),方便主界面上的元素调用,相应代码如下:
myopenglwidget.h:

#ifndefMYOPENGLWIDGET_H#defineMYOPENGLWIDGET_H#include<QObject>#include<QWidget>#include<QOpenGLWidget>#include<QOpenGLFunctions_3_3_Core>classMyOpenGLWidget:publicQOpenGLWidget,QOpenGLFunctions_3_3_Core{
    Q_OBJECT
public://添加图形类型枚举enumShape{None,Rect,Circle,Triangle};explicitMyOpenGLWidget(QWidget *parent =nullptr);//添加三个辅助函数voiddrawShape(Shape shape);voidclearGraphic();voidsetWireFrame(bool wireFrame);protected:virtualvoidinitializeGL()override;virtualvoidresizeGL(int w,int h)override;virtualvoidpaintGL()override;

signals:private://定义一个中间变量
    Shape m_shape;};#endif// MYOPENGLWIDGET_H

3. 步骤二:

对上面的三个辅助函数进行设计,其中每触发一个函数,都应该让OPenGL重新绘制,此时应调用 update() 函数,而在更新视图之前,需要记录当前的视图是什么样的,所以还需要在此之前调用 makeCurrent() 函数,视图更新结束后,需要告知OPenGL已经绘制完毕,此时需要调用 doneCurrent() 函数,相应代码如下:
myopenglwidget.cpp:

#include"myopenglwidget.h"unsignedint VBO,VAO;//添加一个索引控制器unsignedint EBO;//定义一个全局的着色器控制器unsignedint shaderProgram;float vertices[]={-0.5f,-0.5f,0.0f,0.5f,-0.5f,0.0f,0.0f,0.5f,0.0f};//使用4个顶点数据绘制两个三角形float vertices2[]={0.5f,0.5f,0.0f,0.5f,-0.5f,0.0f,-0.5f,-0.5f,0.0f,-0.5f,0.5f,0.0f};//添加索引数据unsignedint indices[]={0,1,3,1,2,3};MyOpenGLWidget::MyOpenGLWidget(QWidget *parent):QOpenGLWidget(parent){}//绘制图形辅助函数voidMyOpenGLWidget::drawShape(MyOpenGLWidget::Shape shape){makeCurrent();//记录当前视图
    m_shape = shape;update();//视图更新doneCurrent();//结束视图更新}//清空函数voidMyOpenGLWidget::clearGraphic(){makeCurrent();drawShape(MyOpenGLWidget::None);makeCurrent();glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);update();doneCurrent();}//设置线框模式函数voidMyOpenGLWidget::setWireFrame(bool wireFrame){makeCurrent();if(wireFrame){glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);//以线框模式绘制图形}else{glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);//以填充模式绘制图形}update();doneCurrent();}voidMyOpenGLWidget::initializeGL(){initializeOpenGLFunctions();

    shaderProgram =glCreateProgram();//void glGenVertexArrays(GLsizei n, GLuint *arrays)生成顶点数组对象名称// n: 要产生的VAO对象的数量// arrays: 存放产生的VAO对象的名称glGenVertexArrays(1,&VAO);// void glGenBuffers(GLsizei n,GLuint *buffers)生成顶点缓冲对象// n: 要产生的VBO对象的数量// arrays: 存放产生的VBO对象的名称glGenBuffers(1,&VBO);//初始化索引器glGenBuffers(1,&EBO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);//绑定VAO和VBOglBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER,VBO);//在VBO中存入顶点数据glBufferData(GL_ARRAY_BUFFER,sizeof(vertices2),vertices2,GL_STATIC_DRAW);//告诉VAO怎么在VBO中拿数据glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)0);//开启第一个VAOglEnableVertexAttribArray(0);//用完之后解除绑定(信息已经被记录下来了)glBindBuffer(GL_ARRAY_BUFFER,0);glBindVertexArray(0);}voidMyOpenGLWidget::resizeGL(int w,int h){Q_UNUSED(w);Q_UNUSED(h);}voidMyOpenGLWidget::paintGL(){glClearColor(0.5f,0.9f,0.4f,1.0f);glClear(GL_COLOR_BUFFER_BIT);//在渲染前只需开启对应的VAO即可glBindVertexArray(VAO);//switch判断 m_shape 的类型,进行不同图形的绘制switch(m_shape){case Rect:glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,&indices);break;default:break;}}

4. 步骤三:

在主界面中添加三个按钮,分别用来绘制,清空,设置线框模式,并相应其clicked信号,调用对应的函数即可,相应代码如下:
myopenglwidget.h:

#ifndefLEARNOPENGL_H#defineLEARNOPENGL_H#include<QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui {classLearnOpenGL;}
QT_END_NAMESPACE

classLearnOpenGL:publicQMainWindow{
    Q_OBJECT

public:LearnOpenGL(QMainWindow *parent =nullptr);~LearnOpenGL();private slots://三个按钮的槽函数voidon_btn_drawRect_clicked();voidon_btn_Clear_clicked();voidon_btn_setFrame_clicked();private:
    Ui::LearnOpenGL *ui;};#endif// LEARNOPENGL_H

myopenglwidget.cpp:

#include"learnopengl.h"#include"ui_learnopengl.h"LearnOpenGL::LearnOpenGL(QMainWindow *parent):QMainWindow(parent),ui(new Ui::LearnOpenGL){
    ui->setupUi(this);setCentralWidget(ui->openGLWidget);}LearnOpenGL::~LearnOpenGL(){delete ui;}voidLearnOpenGL::on_btn_drawRect_clicked(){
    ui->openGLWidget->drawShape(MyOpenGLWidget::Rect);//调用绘制图形}voidLearnOpenGL::on_btn_Clear_clicked(){
    ui->openGLWidget->clearGraphic();//调用清空图形}bool frame =true;voidLearnOpenGL::on_btn_setFrame_clicked(){
    ui->openGLWidget->setWireFrame(frame);//调用线框模式
    frame =!frame;}
标签: qt 交互 图形渲染

本文转载自: https://blog.csdn.net/FY_13781298928/article/details/129061436
版权归原作者 山间点烟雨 所有, 如有侵权,请联系我们删除。

“13. OPenGL与QT界面元素交互控制图形渲染”的评论:

还没有评论