解读Qt OpenGL示例程序 openglwindow

QtOpenGL示例openglwindow

基于qt5.7.1示例程序openglwindow的解读1

  • 程序流程
    show()-->exposeEvent()-->run()-->postEvent()
    -->event()-->run()-->postEvent()
    -->event()-->run()-->postEvent()
    -->event()-->run()-->postEvent()
    -->event()-->run()-->postEvent()

    注释: 每次窗口大小改变是都会产生exposeEvent信号,
          绘画结束后通过postEvent产生一个event信号。
  • pro文件
QT -= core
QT += gui

CONFIG += c++11
CONFIG += console

SOURCES += main.cpp \
    openglwindow.cpp

HEADERS += \
    openglwindowain.cpp
  • main.cpp文件
#include "openglwindow.h"
#include 

int main(int argc, char *argv[])
{
    QGuiApplication a(argc, argv);

    OpenGLWindow window;
    window.resize(640, 480);
    window.show();
    // window.run();      // 不需要run,show()自动进入
    return a.exec()
}
  • openglwindow.h文件
#ifndef OPENGLWINDOW_H
#define OPENGLWINDOW_H

#include 
#include 

QT_BEGIN_NAMESPACE
class QPainter;
class QOpenGLContext;
class QOpenGLPaintDevice;
class QOpenGLShaderProgram;
QT_END_NAMESPACE

class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
    Q_OBJECT
public:
    explicit OpenGLWindow(QWindow *parent = 0);
     ~OpenGLWindow();
      void TestFunction();                  // Test绘图
      void InitShader();                    // 初始化着色器(画刷)
      void DrawImage();                     // 执行绘图动作
private:
    QOpenGLContext *m_context;              // 画板对象
    QOpenGLShaderProgram *m_program;        // 着色器(画刷)对象

    GLuint m_posAttr;                       // 着色器参数:属性
    GLuint m_colAttr;                       // 着色器参数:纹理
    GLuint m_matrixUniform;                 // 着色器参数:uniform

    int  m_frame;                           // 循环变量,只要到一次
    bool m_update_pending;                  // 绘图完成标志(窗口更新标志)

public slots:
    void run();                             // 动画效果实现

protected:                                  // 消息发生器(重载而来)
    bool event(QEvent *event) Q_DECL_OVERRIDE;
    void exposeEvent(QExposeEvent *event) Q_DECL_OVERRIDE;
};

#endif // OPENGLWINDOW_H
  • openglwindow.cpp文件
#include "openglwindow.h"
#include 
#include 
#include 
#include 

static const char *vertexShaderSource =     // 着色器语言
    "attribute highp vec4 posAttr;\n"
    "attribute lowp vec4 colAttr;\n"
    "varying lowp vec4 col;\n"
    "uniform highp mat4 matrix;\n"
    "void main() {\n"
    "   col = colAttr;\n"
    "   gl_Position = matrix * posAttr;\n"
    "}\n";

static const char *fragmentShaderSource =   // 着色器语言
    "varying lowp vec4 col;\n"
    "void main() {\n"
    "   gl_FragColor = col;\n"
    "}\n";

OpenGLWindow::OpenGLWindow(QWindow *parent)
    : QWindow(parent)
    , m_context(0)
    , m_frame(0)
    , m_update_pending(false)
{
    setSurfaceType(QWindow::OpenGLSurface);
}

OpenGLWindow::~OpenGLWindow()
{
    if(m_context)
     delete m_context;
}

void OpenGLWindow::TestFunction()
{
    if(m_context)
    {
        m_context->makeCurrent(this);
        DrawImage();
        m_context->swapBuffers(this);
        return;
    }

    m_context = new QOpenGLContext(this);
    m_context->create();

    m_context->makeCurrent(this);
    initializeOpenGLFunctions();
    InitShader();
    DrawImage();
    m_context->swapBuffers(this);
}

void OpenGLWindow::InitShader()
{
    m_program = new QOpenGLShaderProgram(this);
    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
    m_program->link();
    m_posAttr = m_program->attributeLocation("posAttr");
    m_colAttr = m_program->attributeLocation("colAttr");
    m_matrixUniform = m_program->uniformLocation("matrix");
}

void OpenGLWindow::DrawImage()
{
    const qreal retinaScale = devicePixelRatio();
    glViewport(0, 0, width() * retinaScale, height() * retinaScale);
    glClear(GL_COLOR_BUFFER_BIT);
    m_program->bind();

    QMatrix4x4 matrix;
    matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f);
    matrix.translate(0, 0, -2);
    matrix.rotate(100.0f * m_frame++ / screen()->refreshRate(), 0, 1, 0); 

    m_program->setUniformValue(m_matrixUniform, matrix);

    GLfloat vertices[] = {
        0.0f, 0.707f,
        -0.5f, -0.5f,
        0.5f, -0.5f
    };

    GLfloat colors[] = {
        1.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 1.0f
    };

    glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, vertices);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(0);

    m_program->release();
}

bool OpenGLWindow::event(QEvent *event)
{
    if(event->type() != QEvent::UpdateRequest)
        return QWindow::event(event);

    m_update_pending = false;
    if(isExposed()) run();

    return true;
}

void OpenGLWindow::exposeEvent(QExposeEvent *event)
{
    Q_UNUSED(event);

    if(isExposed()) run();
}

void OpenGLWindow::run()
{
    TestFunction();

    if (m_update_pending) return;
    m_update_pending = true;

    QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
}
  • 参考网页:

  1. Qt OpenGL教程:http://qiliang.net/old/nehe_qt/index.html ↩

你可能感兴趣的:(qt,c++)