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-通過着色器來渲染漸變三角形