Opengl 和 Qml 混合編程

Opengl 和 Qml 混合編程

  • Opengl 描繪3D效果
  • Qml描繪2D效果

效果

0_1527065966207_20180523_165855.gif

源代碼

Fork me on Gitee

加強版效果

  • 1.底層的opengl描繪背景
  • 2.在qml描繪前描繪opengl,所以opengl處於底層
  • 3.中間層描繪qml
  • 4.在qml描繪後描繪opengl,所以opengl處於頂層
  • 5.使用QQuickItem構建組件,供qml調用,組件內部描繪opengl
  • 6.爲了讓上層opengl背景透明

觀察可以發現每層的遮擋效果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-QmctiXdd-1593416516901)(https://res.cloudinary.com/qtdream/image/upload/v1527139252/cloundinary/hm9mn8ltlhrrkn1q3isw.gif)]

1.底層的opengl描繪背景

原理是在最遠的地方放一張圖片,放大圖片,直到完全鋪滿視口

//混合顯示背景
    glBlendFunc(GL_ONE, GL_ZERO);

    //描繪背景
    glBindVertexArray(m_VAO[1]);
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO[1]);

    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)0);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*1));
    glVertexAttribPointer(m_texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*2));

    //背景的矩陣
    QMatrix4x4 modelBg;
    modelBg.translate(0.0f, 0.0f, -10.0f);
    modelBg.scale(4.0f * 8, 3.0f * 8, 1.0f);
    modelBg.rotate(0, 0, 1, 0);
    m_program->setUniformValue(m_model, modelBg);

    m_textureBg->bind();

    glDrawArrays(GL_QUADS,0, 4);
    m_textureBg->release();

2.在qml描繪前描繪opengl,所以opengl處於底層

以前我們是用timer來更新繪製,現在我們根據qml繪製時機,在渲染前,先渲染opengl,且不清除畫面,然後再繪製qml,這樣就變成上下兩層,

connect(window(), &QQuickWindow::beforeRendering, m_triangleWindow, &TriangleWindow::renderNow, Qt::DirectConnection);

//渲染qml前不清畫面,保留opengl
win->setClearBeforeRendering(false);

4.在qml描繪後描繪opengl,所以opengl處於頂層

渲染qml後,再次渲染opengl

connect(window(), &QQuickWindow::afterRendering, m_triangleWindow, &UpTriangleWindow::renderNow, Qt::DirectConnection);
  • mainwindow類繼承QQuickItem,裏面使用渲染qml前繪製opengl
  • upmainwindow類繼承QQuickItem,裏面使用渲染qml後繪製opengl
  • mainwindow類使用TriangleWindow這個opengl類,TriangleWindow裏面繪製了背景圖片
  • upmainwindow類使用UpTriangleWindow這個opengl類,裏面爲了透明背景,沒有清除GL_COLOR_BUFFER_BIT顏色緩衝區
  • 關於清除opengl背景問題,我使用混合,成功去除了清除色,但是背景仍然顯示一個黑色,實在沒有辦法,於是使用了這個餿主意——沒有清除GL_COLOR_BUFFER_BIT

註冊

將c++類註冊到qml使用

//註冊opengl到qml
    qmlRegisterType<MainWindow>("MainWindow", 1, 0, "MainWindow");
    qmlRegisterType<UpMainWindow>("UpMainWindow", 1, 0, "UpMainWindow");

調用

0_1527140533208_08cee63c-6392-4ad8-8ffe-d4e71ee6fdb1-image.png

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