1. 程式人生 > >解讀Qt OpenGL示例程式 openglwindow

解讀Qt OpenGL示例程式 openglwindow

QtOpenGL示例openglwindow

基於qt5.7.1示例程式openglwindow的解讀1

openglewindow

  • 程式流程
    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 <QtGui/QGuiApplication>
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 <QtGui/QWindow>
#include <QtGui/QOpenGLFunctions> 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 <QtCore/QCoreApplication>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>

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));
}
  • 參考網頁:

相關推薦

解讀Qt OpenGL示例程式 openglwindow

QtOpenGL示例openglwindow 基於qt5.7.1示例程式openglwindow的解讀1 程式流程 show()-->exposeEvent()-->run()-->postEvent()

qt opengl示例

#include <QObject> #include <QOpenGLWidget> #include <GL/gl.h> #include <GL/glu.h> #include <QOpenGLFunctions> #include

Qt+OpenGL做的蕾達顯示程式[含原始碼]

uniform sampler2D qt_Texture0; varying vec4 qt_TexCoord0; uniform float specialSector; uniform float cycle; uniform float decayFactor; uniform float anten

VS2012下基於Glut OpenGL glScissor示例程式

剪裁測試用於限制繪製區域。我們可以指定一個矩形的剪裁視窗,當啟用剪裁測試後,只有在這個視窗之內的畫素才能被繪製,其它畫素則會被丟棄。換句話說,無論怎麼繪製,剪裁視窗以外的畫素將不會被修改。有的朋友可能玩過《魔獸爭霸3》這款遊戲。遊戲時如果選中一個士兵,則畫面下方的一個方

OpenGL程式設計精髓》光碟示例程式執行環境配置

=============================================================== 【問題】 #include <gl\glaux.h> 這一行缺少檔案,導致編譯不過 =======================

今天終於將qt-opengl 的一個簡單的程式寫出來了,

在建立的時候大家一定注意 在它的管理檔案中一定要新增一句 QT+=openglwidgets 在構建之前一定要記得執行以下 qmake 個是配置工程檔案的 未配置的 時候可能會出現link 2019 的錯誤

VS2012下基於Glut OpenGL GL_POLYGON_STIPPLE示例程式

直線可以被畫成虛線,而多邊形則可以進行鏤空。 首先,使用glEnable(GL_POLYGON_STIPPLE);來啟動鏤空模式(使用glDisable(GL_POLYGON_STIPPLE)可以關閉之)。 然後,使用glPolygonStipple來設定鏤空的樣式

45.Qt openGL實現三維繪圖

窗口 err lin span protected 調用 event header 實現 main.cpp #include <QApplication> #include <iostream> #include "tetrahea

用超 7500 萬的 GitHub 程式碼倉庫實力解讀:哪門程式語言熱度最高

來源:開源中國 連結:oschina.net/news/92822/ranking-programming-languages-by-github-users(點選尾部閱讀原文前往) 有開發者在 reddit 釋出了一個帖子,內容是通過對 GitHub

第2篇 Qt5基礎(二)編寫Qt多視窗程式

  1、通過程式碼來設定按鈕的中文文字會覆蓋以前在設計模式設定的文字,(另外,如果大家以前學過Qt 4,那麼現在可能會激動地發現不用在使用setCodecForTr()等函式就可以直接顯示中文了)不過,在程式碼中直接使用中文字不是一個好的習慣,建議在編寫程式時使用英文,當程式完成後使用

[MapReduce_1] 執行 Word Count 示例程式

  0. 說明   MapReduce 實現 Word Count 示意圖 && Word Count 程式碼編寫        1. MapReduce 實現 Word Count 示意圖    &

3.1示例程式p33

#include “stdio.h” int main(void ) { float weight ; float value; printf(“are you worth in rhodium ?/ n”); printf(“let`s check it out .\n”); printf

MyBatis概述和Hello示例程式以及傳統的CRUD

  目錄   1.MyBatis概述 1、mybatis簡介 2、mybatis歷史 3、為什麼要使用mybatis 4.理解 SqlSession及其子父類的含義! 2.MyBatis的Hello示例程式 1、建立一個數據庫和一個單表 2

《OpenCV3程式設計入門》——3.1.9 綜合示例程式:影象的載入、顯示與輸出

書中關於影象的載入、顯示與輸出的綜合應用。有些細節知識將在本部落格後續更新。 #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> using namespace cv; int

Cesium入門2 - Cesium環境搭建及第一個示例程式

Cesium入門2 - Cesium環境搭建及第一個示例程式 Cesium中文網:http://cesiumcn.org/ | 國內快速訪問:http://cesium.coinidea.com/ 驗證瀏覽器 Cesium需要瀏覽器支援WebGL,可以通過CesiumJS官網

Qt在GUI程式裡顯示控制檯介面

在GUI程式裡有時我們想簡單的列印些資訊來進行測試,然而因為不是控制檯程式,所以不能直接通過控制檯輸出,要實現這點就要做一下兩點: 1:在.pro檔案中加入一句: CONFIG+= console 2:在執行設定裡勾選在終端執行的選項 注:如果只做了第一點,那麼資訊會顯示在”&nbs

Qt】QTest:編譯Qt單元測試程式

一、使用方法 1、測試程式原始碼 TestQString.pro QT += testlib QT -= gui TARGET = tst_TestQStringTest CONFIG += console CONFIG -= app_bund

並行作業1:MPI安裝,及示例程式執行

執行MPI程式 系統採用vm下ubuntu16.04 一、MPI系統安裝 1.1 安裝環境 (1)作業系統:Ubuntu 16.04.4 (64位)。 (2)g++ 版本:gcc version 5.4.0 1.2 安裝包下載地址及安裝包 (1)下載地址:http

公鑰加密,私鑰解密示例程式(JAVA)

公鑰加密,私鑰解密示例程式(JAVA)       最近再研究Java安全方面的東西,總結一下,大家有用到的可以參考下。         1.證書生成        

QT從console程式到到視窗程式之實踐

我們都知道,在QT中基於Qobject的視窗有兩類,QWidget和QWindow,當然,這兩類下又有QDialog,QWidget,QMainWindow,QSplashScreen,QMidSubWindow,QDesktopWidget五個類。 這裡,我們來看看QMainWindo