2.通过QOpenGLWidget绘制三角形
1.QOpenGLWidget的早先版本
QGLWidget是遗留Qt OpenGL模块的一部分,和其他QGL类一样,应该在新的应用程序中避免使用。相反,从Qt 5.4开始,最好使用QOpenGLWidget和QOpenGL类。
如果开发XP平台,由于兼容性问题,Qt5.4(不含)之后的QtOpenglWidget 则不兼容,建议还是用QGLWidget.
2.QOpenGLWidget类是用于呈现OpenGL图形的部件
QOpenGLWidget提供显示集成到Qt应用程序中的OpenGL图形的功能。使用起来非常简单:让类继承它,并像其他QWidget一样使用子类,额外可以选择使用QPainer和标准的OpenGL渲染命令。
QOpenGLWidget提供了三个方便的虚拟函数,子类中重新实现这些函数来执行OpenGL绘制任务:
- paintGL():渲染OpenGL场景。该函数里面主要绘制部件,比如在全屏视频上面显示滑动条
- resizeGL ():当窗口尺寸发生变化时被调用,然后会调用paintGL()函数重新绘制一次(并且第一次显示时也会调用resizeGL() )。
- initializeGL():用于初始化,设置OpenGL要呈现的画面,只在程序开始时运行一次,之后不会再运行。
其中在initializeGL()中初始化具体如下所示:
然后在paintGL()中,每次当我们要绘制不同的物体时,便调用bind()来绑定对象、绘制完后,解绑对象,如果还要绘制下个物体,那么就取出对应的VAO,绑定它,绘制完物体后,再解绑。
3.三角形示例
4.头文件代码
#ifndef MYGLWIDGET_H #define MYGLWIDGET_H #include <QMainWindow> #include <QObject> #include <QWidget> #include <QOpenGLWidget> #include <QOpenGLFunctions> #include <QOpenGLShaderProgram> #include <QOpenGLBuffer> #include <QOpenGLVertexArrayObject> class myGlWidget : public QOpenGLWidget , protected QOpenGLFunctions { Q_OBJECT public: myGlWidget(QWidget *parent = nullptr); protected: void paintGL() ; void initializeGL() ; void resizeEvent(QResizeEvent *e) ; private: QOpenGLShaderProgram *program; QOpenGLVertexArrayObject vao; QOpenGLBuffer vbo; }; #endif // MYGLWIDGET_H
5.源文件代码
#include "myglwidget.h" #include <QtDebug> //GLSL3.0版本后,废弃了attribute关键字(以及varying关键字),属性变量统一用in/out作为前置关键字 #define GL_VERSION "#version 330 core\n" #define GLCHA(x) #@x //加单引号,将x变为字符 #define GLSTR(x) #x //加双引号,将x变为字符串 #define GET_GLSTR(x) GL_VERSION#x const char *vsrc = GET_GLSTR( layout (location = 0) in vec3 aPos; void main(void) { gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); } ); const char *fsrc =GET_GLSTR( out vec4 FragColor; void main(void) { FragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f); } ); //fsrc 等价于 --> const char *fsrc ="#version 330 core\n" // "out vec4 FragColor;\n" // "void main()\n" // "{\n" // " FragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);\n" // "}\n\0"; myGlWidget::myGlWidget(QWidget *parent):QOpenGLWidget(parent) { } void myGlWidget::paintGL() { // 绘制 // glViewport(0, 0, width(), height()); glClear(GL_COLOR_BUFFER_BIT); // 渲染Shader program->bind(); //绑定激活Program对象 vao.bind(); //绑定激活vao glDrawArrays(GL_TRIANGLES, 0, 3); //绘制3个定点,样式为三角形 vao.release(); //解绑 program->release(); //解绑 } void myGlWidget::initializeGL() { // 为当前环境初始化OpenGL函数 initializeOpenGLFunctions(); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //设置背景色为白色 //1.创建顶点着色器 QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); vshader->compileSourceCode(vsrc); //2.创建片元着色器 rgba(1.0f, 1.0f, 0.0f, 1.0f)表示黄色,而alpha值为1.0,表示完全不透明 QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); fshader->compileSourceCode(fsrc); //3.创建着色器程序 program = new QOpenGLShaderProgram; program->addShader(vshader); program->addShader(fshader); program->link(); program->bind();//激活Program对象 //4.初始化VBO,将顶点数据存储到buffer中,等待VAO激活后才能释放 float vertices[] = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f }; vbo.create(); vbo.bind(); //绑定到当前的OpenGL上下文, vbo.allocate(vertices, 9*sizeof(GLfloat)); vbo.setUsagePattern(QOpenGLBuffer::StreamDraw); //设置为一次修改,多次使用 //5.初始化VAO,设置顶点数据状态(顶点,法线,纹理坐标等) vao.create(); vao.bind(); GLint aPos = program->attributeLocation("aPos"); //获取aPos位置 if(aPos==-1) //未找到 { return; } program->setAttributeBuffer(aPos, GL_FLOAT, 0, 3, 0); //设置顶点属性 program->enableAttributeArray(aPos); //使能顶点属性 //6.解绑所有对象 vao.release(); vbo.release(); program->release(); } void myGlWidget::resizeEvent(QResizeEvent *e) { }
下章学习:
3.QOpenGLWidget-通过着色器来渲染渐变三角形
人间有真情,人间有真爱。