QT之openGL使用(二)
gitee地址:only_view/opengl
QT交互
使用QT界面调用OpenGL效果。
myopenglwidget.cpp
#include "myopenglwidget.h"//创建VBO和VAO对象,并赋予ID
unsigned int VBO,VAO,EBO;float vertices[] = {//6个点为一个矩形0.5f,0.5f,0.0f,0.5f,-0.5f,0.0f,-0.5f,0.5f,0.0f,-0.5f,-0.5f,0.0f,
};unsigned int indices[] = {0,1,2,1,2,3
};
//顶点片段着色器
const char* vertexSharedSource = "#version 330 core\n""layout (location = 0) in vec3 aPos;\n void main()\n""{\n"" gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0);\n""}\0";const char* fragmentShaderSource = "#version 330 core\n""out vec4 FragColor;\n""void main()\n""{\n""FragColor = vec4(1.0f,0.5f,0.2f,1.0f);\n }\n";unsigned int shaderProgram ;
unsigned int vertexShader;
unsigned int fragmentShader;MyOpenGLWidget::MyOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{}MyOpenGLWidget::~MyOpenGLWidget()
{//数据回收makeCurrent();glDeleteBuffers(1,&VBO);glDeleteBuffers(1,&VAO);glDeleteBuffers(1,&EBO);glDeleteProgram(shaderProgram);doneCurrent();
}void MyOpenGLWidget::drawShape(MyOpenGLWidget::Shape shape)
{m_shape = shape;update(); //会调用
}void MyOpenGLWidget::setWriteframe(bool flag)
{makeCurrent();if(flag){glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); //线框}else{glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); //填充}doneCurrent();update(); //更新}void MyOpenGLWidget::initializeGL()
{initializeOpenGLFunctions(); //初始化OpenGL函数,将QT里的函数指针指向显卡的函数。//创建VBO和VAO对象,并赋予IDglGenVertexArrays(1,&VAO);glGenBuffers(1,&VBO);//绑定VBO和VAO对象glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER,VBO);//为当前绑定到target的缓冲区对象创建一个新的数据存储//如果data不是NULL,则使用来自此指针的数据初始化数据存储glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);//告知显卡如何去解析缓冲区里的值//第0个属性里面3个值glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)0);//开启VAO管理的第一个属性值。glEnableVertexAttribArray(0);//VAO VBO 进行休息。
// glBindVertexArray(0); //解绑glBindBuffer(GL_ARRAY_BUFFER,0);//顶点着色器vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader,1,&vertexSharedSource,NULL);glCompileShader(vertexShader);//片段着色器shaderfragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);glCompileShader(fragmentShader); //编译程序//进行链接程序shaderProgram = glCreateProgram();glAttachShader(shaderProgram,vertexShader);glAttachShader(shaderProgram,fragmentShader);glLinkProgram(shaderProgram);//EBOglGenBuffers(1,&EBO);//绑定VBO和VAO对象glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);//EBO解绑,解绑之后数据会丢失
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);glDeleteShader(vertexShader);glDeleteShader(fragmentShader);}void MyOpenGLWidget::resizeGL(int w, int h)
{}void MyOpenGLWidget::paintGL()
{//需要先初始化在使用qDebug() <<"m_shape ="<< m_shape;glClearColor(0.2f,0.2f,0.2f,1.0f); //设置状态glClear(GL_COLOR_BUFFER_BIT); //使用状态glUseProgram(shaderProgram);glBindVertexArray(VAO);switch (m_shape){case Rect:glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);break;default:break;}}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);connect(ui->draw_btn,&QPushButton::clicked,this,&MainWindow::drawOpenGL);connect(ui->clean_btn,&QPushButton::clicked,this,&MainWindow::clearOpenGL);connect(ui->wireframe_btn,&QPushButton::clicked,this,&MainWindow::wireframeOpenGL);}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::drawOpenGL()
{qDebug()<<"drawOpenGL";ui->openGLWidget->drawShape(MyOpenGLWidget::Shape::Rect);}void MainWindow::clearOpenGL()
{qDebug()<<"clearOpenGL";ui->openGLWidget->drawShape(MyOpenGLWidget::Shape::None);
}void MainWindow::wireframeOpenGL()
{qDebug()<<"wireframeOpenGL "<< ui->wireframe_btn->isChecked();ui->openGLWidget->setWriteframe(ui->wireframe_btn->isChecked());}
将shaser放到文件中使用。
可以使用QT中的QOpenGLShaserProgram
myopenglwidget.h
#ifndef MYOPENGLWIDGET_H
#define MYOPENGLWIDGET_H#include <QWidget>
#include <QOpenGLWidget>
#include <qopenglfunctions_3_3_core.h>
//#include <QOpenGLFunctions_4_5_Core> //这是最新版本
#include <QDebug>
#include <QOpenGLShaderProgram> //opengl着色程序。class MyOpenGLWidget : public QOpenGLWidget,QOpenGLFunctions_3_3_Core
{Q_OBJECT
public:explicit MyOpenGLWidget(QWidget *parent = nullptr);~MyOpenGLWidget();enum Shape{None=0,Rect,Circle,Triangle};void drawShape(Shape shape);void setWriteframe(bool flag);
private:Shape m_shape;QOpenGLShaderProgram m_program;protected:virtual void initializeGL();virtual void resizeGL(int w, int h);virtual void paintGL();signals:};#endif // MYOPENGLWIDGET_H
myopenglwidget.cpp
#include "myopenglwidget.h"//创建VBO和VAO对象,并赋予ID
unsigned int VBO,VAO,EBO;float vertices[] = {//6个点为一个矩形0.5f,0.5f,0.0f,0.5f,-0.5f,0.0f,-0.5f,0.5f,0.0f,-0.5f,-0.5f,0.0f,
};unsigned int indices[] = {0,1,2,1,2,3
};
//顶点片段着色器
const char* vertexSharedSource = "#version 330 core\n""layout (location = 0) in vec3 aPos;\n void main()\n""{\n"" gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0);\n""}\0";const char* fragmentShaderSource = "#version 330 core\n""out vec4 FragColor;\n""void main()\n""{\n""FragColor = vec4(1.0f,0.5f,0.2f,1.0f);\n }\n";unsigned int shaderProgram ;
unsigned int vertexShader;
unsigned int fragmentShader;MyOpenGLWidget::MyOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{}MyOpenGLWidget::~MyOpenGLWidget()
{//数据回收makeCurrent();glDeleteBuffers(1,&VBO);glDeleteBuffers(1,&VAO);glDeleteBuffers(1,&EBO);
// glDeleteProgram(shaderProgram);m_program.deleteLater();doneCurrent();
}void MyOpenGLWidget::drawShape(MyOpenGLWidget::Shape shape)
{m_shape = shape;update(); //会调用
}void MyOpenGLWidget::setWriteframe(bool flag)
{makeCurrent();if(flag){glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); //线框}else{glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); //填充}doneCurrent();update(); //更新}void MyOpenGLWidget::initializeGL()
{initializeOpenGLFunctions(); //初始化OpenGL函数,将QT里的函数指针指向显卡的函数。//创建VBO和VAO对象,并赋予IDglGenVertexArrays(1,&VAO);glGenBuffers(1,&VBO);//绑定VBO和VAO对象glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER,VBO);//为当前绑定到target的缓冲区对象创建一个新的数据存储//如果data不是NULL,则使用来自此指针的数据初始化数据存储glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);//告知显卡如何去解析缓冲区里的值//第0个属性里面3个值glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)0);//开启VAO管理的第一个属性值。glEnableVertexAttribArray(0);//VAO VBO 进行休息。
// glBindVertexArray(0); //解绑glBindBuffer(GL_ARRAY_BUFFER,0);// //顶点着色器
// vertexShader = glCreateShader(GL_VERTEX_SHADER);
// glShaderSource(vertexShader,1,&vertexSharedSource,NULL);
// glCompileShader(vertexShader);// //片段着色器shader
// fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
// glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
// glCompileShader(fragmentShader); //编译程序//使用qt的对象来进行编译链接。bool success;
// m_program.addShaderFromSourceCode(QOpenGLShader::Vertex,vertexSharedSource); //方式一
// m_program.addShaderFromSourceCode(QOpenGLShader::Fragment,fragmentShaderSource);//方式二m_program.addCacheableShaderFromSourceFile(QOpenGLShader::Vertex,":/shaders/shapes.vert");m_program.addCacheableShaderFromSourceFile(QOpenGLShader::Fragment,":/shaders/shapes.frag");success = m_program.link();if(success){qDebug()<<"link Success";}else{qDebug()<<"line Failed";}// //进行链接程序
// shaderProgram = glCreateProgram();
// glAttachShader(shaderProgram,vertexShader);
// glAttachShader(shaderProgram,fragmentShader);
// glLinkProgram(shaderProgram);//EBOglGenBuffers(1,&EBO);//绑定VBO和VAO对象glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);//EBO解绑,解绑之后数据会丢失
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);glDeleteShader(vertexShader);glDeleteShader(fragmentShader);}void MyOpenGLWidget::resizeGL(int w, int h)
{}void MyOpenGLWidget::paintGL()
{//需要先初始化在使用qDebug() <<"m_shape ="<< m_shape;glClearColor(0.2f,0.2f,0.2f,1.0f); //设置状态glClear(GL_COLOR_BUFFER_BIT); //使用状态// glUseProgram(shaderProgram);m_program.bind();glBindVertexArray(VAO);switch (m_shape){case Rect:glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);break;default:break;}}
用这个资源文件来进行分开加载
GLSL in out
OpenGL Shading Language
#include "myopenglwidget.h"//创建VBO和VAO对象,并赋予ID
unsigned int VBO,VAO,EBO;float vertices[] = {//6个点为一个矩形0.5f,0.5f,0.0f,0.5f,-0.5f,0.0f,-0.5f,0.5f,0.0f,-0.5f,-0.5f,0.0f,
};unsigned int indices[] = {0,1,2,1,2,3
};
//顶点片段着色器
const char* vertexSharedSource = "#version 330 core\n""layout (location = 0) in vec3 aPos;\n void main()\n""{\n"" gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0);\n""}\0";const char* fragmentShaderSource = "#version 330 core\n""out vec4 FragColor;\n""void main()\n""{\n""FragColor = vec4(1.0f,0.5f,0.2f,1.0f);\n }\n";unsigned int shaderProgram ;
unsigned int vertexShader;
unsigned int fragmentShader;MyOpenGLWidget::MyOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{}MyOpenGLWidget::~MyOpenGLWidget()
{//数据回收makeCurrent();glDeleteBuffers(1,&VBO);glDeleteBuffers(1,&VAO);glDeleteBuffers(1,&EBO);
// glDeleteProgram(shaderProgram);m_program.deleteLater();doneCurrent();
}void MyOpenGLWidget::drawShape(MyOpenGLWidget::Shape shape)
{m_shape = shape;update(); //会调用
}void MyOpenGLWidget::setWriteframe(bool flag)
{makeCurrent();if(flag){glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); //线框}else{glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); //填充}doneCurrent();update(); //更新}void MyOpenGLWidget::initializeGL()
{initializeOpenGLFunctions(); //初始化OpenGL函数,将QT里的函数指针指向显卡的函数。//创建VBO和VAO对象,并赋予IDglGenVertexArrays(1,&VAO);glGenBuffers(1,&VBO);//绑定VBO和VAO对象glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER,VBO);//为当前绑定到target的缓冲区对象创建一个新的数据存储//如果data不是NULL,则使用来自此指针的数据初始化数据存储glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);//告知显卡如何去解析缓冲区里的值//第0个属性里面3个值glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)0);//开启VAO管理的第一个属性值。glEnableVertexAttribArray(0);//VAO VBO 进行休息。
// glBindVertexArray(0); //解绑glBindBuffer(GL_ARRAY_BUFFER,0);// //顶点着色器
// vertexShader = glCreateShader(GL_VERTEX_SHADER);
// glShaderSource(vertexShader,1,&vertexSharedSource,NULL);
// glCompileShader(vertexShader);// //片段着色器shader
// fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
// glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
// glCompileShader(fragmentShader); //编译程序//使用qt的对象来进行编译链接。bool success;
// m_program.addShaderFromSourceCode(QOpenGLShader::Vertex,vertexSharedSource); //方式一
// m_program.addShaderFromSourceCode(QOpenGLShader::Fragment,fragmentShaderSource);//方式二m_program.addCacheableShaderFromSourceFile(QOpenGLShader::Vertex,":/shaders/shapes.vert");m_program.addCacheableShaderFromSourceFile(QOpenGLShader::Fragment,":/shaders/shapes.frag");success = m_program.link();if(success){qDebug()<<"link Success";}else{qDebug()<<"line Failed";}// //进行链接程序
// shaderProgram = glCreateProgram();
// glAttachShader(shaderProgram,vertexShader);
// glAttachShader(shaderProgram,fragmentShader);
// glLinkProgram(shaderProgram);//EBOglGenBuffers(1,&EBO);//绑定VBO和VAO对象glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);//EBO解绑,解绑之后数据会丢失
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);glDeleteShader(vertexShader);glDeleteShader(fragmentShader);}void MyOpenGLWidget::resizeGL(int w, int h)
{}void MyOpenGLWidget::paintGL()
{//需要先初始化在使用qDebug() <<"m_shape ="<< m_shape;glClearColor(0.2f,0.2f,0.2f,1.0f); //设置状态glClear(GL_COLOR_BUFFER_BIT); //使用状态// glUseProgram(shaderProgram);m_program.bind();glBindVertexArray(VAO);switch (m_shape){case Rect:glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);break;default:break;}}
GLSL Layout