Qt5.5中OpenGL着色器程序編寫

Qt5中包含了OpenGL模塊,並且對其進行了一些封裝,下面就Qt5中OpenGL的程序寫法舉例:
Qt5中雖然包含了OpenGL,但是沒有添加“glu.h>”庫,所以有些以前在Qt4中的寫法會不太成功,比如設置投影矩陣等,具體方法可以參考:http://blog.csdn.net/ccf19881030/article/details/17842981中的做法。
但是在下面的例子中沒有加入glu庫,是完全基於Qt中OpenGL寫的。

實驗平臺

VS2010+Qt5.5;

實驗步驟

  1. 新建Qt工程,包含QOpenGL模塊

在控件中可以加入QOpenGLWidget控件,但是也可以對其做提升。代碼如下:

class OpenGLWidget : public QOpenGLWidget , protected QOpenGLFunctions
{
    Q_OBJECT
public:
    OpenGLWidget(QWidget *parent=0);
    ~OpenGLWidget();
    void initializeGL();
    void resizeGL(int w, int h);
    void paintGL();

2.初始化工作

OpenGLWidget::OpenGLWidget(QWidget *parent)
    : QOpenGLWidget(parent)
{
    QSurfaceFormat format;
    format.setDepthBufferSize(24);
    setFormat(format);
    setMouseTracking(false);
}

3.設置視圖模型投影矩陣
Qt5中OpenGL的視圖-投影矩陣是要自己設置的,不再免費提供。故:

QMatrix4x4 mModelMatrix;//模型矩陣  
QMatrix4x4 mViewMatrix; //視圖矩陣  
QMatrix4x4 mProjectionMatrix; //投影矩陣  
QMatrix4x4 mMVPMatrix; //MVP矩陣

最後mMVPMatrix = mProjectionMatrix * mViewMatrix * mModelMatrix;
4.着色器
GLSL是OpenGL着色語言的統稱,是一種編程語言,在應用程序中使用頂點或片段着色器,按照如下步驟:
對於每個着色器對象:

  1. 創建着色器對象;
  2. 把着色器源代碼編譯爲目標代碼;
  3. 驗證;
    然後將多個着色器對象鏈接到一個着色器程序中,需要:

  4. 創建一個着色器程序;

  5. 將着色器對象鏈接到程序;
  6. 鏈接着色器程序;
  7. 驗證;
    着色器代碼解讀:
const GLchar *vshader_source =
        "attribute vec4 posAttr;\n"
        "uniform mat4 matrix;\n"
        "void main() {\n"
        "   gl_Position = matrix * posAttr;\n"
        "}\n";
    const GLchar *cshader_source =
        "uniform vec4 color;\n"
        "void main(){\n"
        "   gl_FragColor= color;\n"
        "}\n";

“attribute”表示輸入變量,輸出爲”varying”。”uniform”限定一個變量的值由應用程序在着色器執行之前指定,並且在圖圓的處理過程中不會變化。
“vec4”是類似於QVector4D,”mat4”類似QMatrix4x4;

5.代碼工作

void OpenGLWidget::resizeGL(int w, int h)
{
    mProjectionMatrix.setToIdentity();
    mProjectionMatrix.perspective(60.0f, w / float(h), 0.01f, 1000.0f);//投影矩陣
}
void OpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();
    shadercode();
}
void OpenGLWidget::paintGL()
{
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     mModelMatrix.setToIdentity();
     mModelMatrix.rotate(angles, 0.0f, 1.0f, 0.0f);
    drawelem();
    OpenGLWidget::update();//刷新
}
void OpenGLWidget::shadercode()
{
    const GLchar *vshader_source =
        "attribute vec4 posAttr;\n"
        "uniform mat4 matrix;\n"
        "void main() {\n"
        "   gl_Position = matrix * posAttr;\n"
        "}\n";
    const GLchar *cshader_source =
        "uniform vec4 color;\n"
        "void main(){\n"
        "   gl_FragColor= color;\n"
        "}\n";
    angles=0.0;
    m_shaderprogram=new QOpenGLShaderProgram(this);
    QOpenGLShader vecShader(QOpenGLShader::Vertex);
    vecShader.compileSourceCode(vshader_source);
    QOpenGLShader colShader(QOpenGLShader::Fragment);
    //vec_handl=m_shaderprogram->addShaderFromSourceCode(QOpenGLShader::Vertex,vshader_source);
    //col_handl=m_shaderprogram->addShaderFromSourceCode(QOpenGLShader::Fragment,cshader_source);
    colShader.compileSourceCode(cshader_source);
    m_shaderprogram->addShader(&vecShader);
    m_shaderprogram->addShader(&colShader);
    m_shaderprogram->link();
    vec_handl=m_shaderprogram->attributeLocation("posAttr");
    col_handl=m_shaderprogram->uniformLocation("color");
    mvp_handl=m_shaderprogram->uniformLocation("matrix");
    mViewMatrix.lookAt(QVector3D(0.0f, 0.0f, -3.0f), QVector3D(0.0f, 0.0f, 1.0f), QVector3D(0.0f, 1.0f, 0.0f));
}
void OpenGLWidget::drawelem()
{
    static GLfloat const triangleVertices[] = {
        1.0f,  0.0f,  0.0f,
        0.0f, 1.0f, 0.0f,
        -1.0f,  0.0f, 0.0f
    };
    QVector4D colors(1.0f, 1.0f, 0.0f, 1.0f) ;
    mMVPMatrix = mProjectionMatrix  * mViewMatrix * mModelMatrix; 
    m_shaderprogram->enableAttributeArray(vec_handl);
    m_shaderprogram->setAttributeArray(vec_handl,triangleVertices,3);
    m_shaderprogram->setUniformValue(mvp_handl,mMVPMatrix);
    m_shaderprogram->setUniformValue("color",colors);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    m_shaderprogram->bind();
    m_shaderprogram->disableAttributeArray(vec_handl);
    m_shaderprogram->disableAttributeArray(col_handl);
}

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章