QT+OpenGL(01)--實現三角形渲染

1.openglwidget.ui數組


<ui version="4.0">
 <author/>
 <comment/>
 <exportmacro/>
 <class>OpenGLWidget</class>
 <widget class="QWidget" name="OpenGLWidget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
 </widget>
 <pixmapfunction/>
 <connections/>
</ui>


2. openglwidget.h函數

#ifndef OPENGLWIDGET_H
#define OPENGLWIDGET_H

#include <QWidget>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <GL/gl.h>
#include <qopengl.h>
#include <qopenglfunctions.h>
#include <qopenglshaderprogram.h>

namespace Ui {
class OpenGLWidget;
}

class OpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT


public:
    QOpenGLShaderProgram* program;
    GLuint programId;
    GLuint verVbo;
    GLuint indexVbo;
    GLuint colorVbo;
    GLuint  matrixLocation;
    GLuint vertexLocation;
    GLuint clorLocation;
    QMatrix4x4  projection;
    GLsizei vVerticesLen;
    GLsizei triIndexLen;
    GLsizei colorsLen ;

    GLuint triIndexs[3] = {0, 1, 2};
    GLfloat vertex[6] = {
        -0.5f, 0.0f,
        0.5f, 0.0f,
        0.0f, 0.5f,
    };
    GLfloat colors[12] = {1.0f, 0.0f, 0.0f, 1.0f,
                        0.0f, 1.0f, 0.0f, 1.0f,
                        0.0f, 0.0f, 1.0f, 1.0f,
                       };

    explicit OpenGLWidget(QWidget *parent = nullptr);
    ~OpenGLWidget();


//    //三角形頂點座標
//    GLfloat* vertex;

//    //三角形頂點索引
//    GLuint* triIndexs;

//    //三角形頂點顏色
//    GLfloat* colors;


private:
    Ui::OpenGLWidget *ui;
protected:
    void initializeGL();
    void paintGL();
    void resizeGL(int w, int h);
    void initVbo();
};

#endif // OPENGLWIDGET_H


3. openglwidget.cppui

#include "openglwidget.h"
#include "ui_openglwidget.h"
#include <GL/gl.h>
#include <qopengl.h>
#include <qopenglfunctions.h>
#include <qopenglshaderprogram.h>



OpenGLWidget::OpenGLWidget(QWidget *parent) :
    QOpenGLWidget(parent),
    ui(new Ui::OpenGLWidget)
{
    ui->setupUi(this);
}



OpenGLWidget::~OpenGLWidget()
{
    delete ui;
}

void OpenGLWidget::initializeGL()
{
    //調用內容初始化函數
    initializeOpenGLFunctions();

    program = new QOpenGLShaderProgram(this);

    if(!program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/vertexshader.vect")){
        printf("no found vertexshader.vert");
        return;
    }
    if(!program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/fragmentshader.frag")){
        printf("no found fragmentshader.frag");
        return;
    }
    if(!program->link()){
        printf("no link");
        return;
    }
    if(!program->bind()){
        printf("no bind");
        return;
    }

    // 獲取shaderprogram的id號,而後能夠經過id號獲取一些屬性...
    programId = program->programId();
    printf("programId: %d", programId);
    // 從shaderprogram裏面獲取變量標識
    matrixLocation = glGetUniformLocation(programId, "matrix");
    vertexLocation = glGetAttribLocation(programId, "vPosition");
    clorLocation = glGetAttribLocation(programId, "vColor");

    initVbo();
}
void OpenGLWidget::initVbo(){

    // 計算得到數組長度
    vVerticesLen = sizeof(vertex)/sizeof(GLfloat);
    triIndexLen = sizeof(triIndexs)/sizeof(GLuint);
    colorsLen = sizeof(colors)/sizeof(GLfloat);

    // 初始化頂點buffer並裝載數據到顯存


    glGenBuffers(1, &verVbo);
    glBindBuffer(GL_ARRAY_BUFFER, verVbo);
    glBufferData(GL_ARRAY_BUFFER, vVerticesLen * sizeof(GLfloat), vertex, GL_STATIC_DRAW);

    // 初始化索引buffer並裝載數據到顯存
    glGenBuffers(1, &indexVbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVbo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, triIndexLen * sizeof(GLuint), triIndexs, GL_STATIC_DRAW);

    // 初始化顏色buffer並裝載數據到顯存
    glGenBuffers(1, &colorVbo);
    glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
    glBufferData(GL_ARRAY_BUFFER, colorsLen * sizeof(GLfloat), colors, GL_STATIC_DRAW);
}


void OpenGLWidget::resizeGL(int w, int h)
{
    //當窗口大小改變時,調整界面座標顯示高度和寬度
    glViewport(0, 0, w, h);

    // 模型矩陣重置
    projection.setToIdentity();
    // 透視投影
    qreal aspect = qreal(w) / qreal(h ? h : 1);
    projection.perspective(60.0f, aspect, 1.0f, 100.0f);
    // 增長了模型矩陣,須要作必定偏移量,保證物體剛開始渲染出來時能夠被看到!
    projection.translate(0.0f, 0.0f, -2.0f);

}

void OpenGLWidget::paintGL()
{
    //清除以前圖形並將背景設置爲黑色(設置爲黑色純粹我的愛好!)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    // shader傳入模型視圖矩陣 projection能夠理解爲創建了一個座標系空間,能夠再這個空間內設置圖形
    glUniformMatrix4fv(matrixLocation, 1, GL_FALSE, projection.data());

    // shader綁定並啓用顏色數組buffer
    glBindBuffer(GL_ARRAY_BUFFER,colorVbo);
    glVertexAttribPointer(clorLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(clorLocation);
    // 顏色值rgba,因此每四個float值做爲一個顏色值,若是隻是但願rgb,取三個值做爲顏色值便可!


    // shader綁定並啓用頂點數組buffer
    glBindBuffer(GL_ARRAY_BUFFER, verVbo);
    glVertexAttribPointer( vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(vertexLocation);

    // shader綁定並頂點索引數組buffer - 索引無需啓用
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexVbo);
    glDrawElements(GL_TRIANGLES, triIndexLen, GL_UNSIGNED_INT, 0);

    // 解綁buffer、關閉啓用頂點、顏色數組
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(vertexLocation);
    glDisableVertexAttribArray(clorLocation);

}


4. vertexshader.vectthis

//vertexshader.vert
uniform mat4 matrix;
in vec4 vPosition;
in vec4 vColor;
out vec4 fColor;

void main(void)
{
    fColor = vColor;
    gl_Position = matrix * vPosition;
}


5. fragmentshader.fragspa

//fragmentshader.frag
in vec4 fColor;

void main(void)
{
    gl_FragColor = fColor;
}


------------------------------------------------------------------------------------------------------code

相關文章
相關標籤/搜索