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

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM