QWidget/Qt5 + OpenGL


Qt5でOpenGLを利用するためのサンプルコードをGitHub repositoryとして用意しました.作成したのは「これがOpenGL?」と思えるほど,思いつく限り一番単純と思われるアプリケーションです.

OpenGLの環境設定はmain.cxxで整えています.GLWidgetクラスで描画を行っていますが,main.cxxでOpenGL 4.3 Core Profile用の関数表(gl)を利用してOpenGLコマンドを発行しています.

#include "mainwindow.hxx"
#include <QApplication>
#include <QSurfaceFormat>
#include <QOpenGLContext>
#include <iostream>
#include <map>
extern Ui::MainWindow mainWindow;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSurfaceFormat fmt;
fmt.setMajorVersion(4); fmt.setMinorVersion(5);
fmt.setProfile(QSurfaceFormat::CoreProfile);
fmt.setSamples(4);
fmt.setDepthBufferSize(24);
QSurfaceFormat::setDefaultFormat(fmt);
MainWindow *w = new MainWindow;
QOpenGLContext *m_context = new QOpenGLContext;
m_context->create();
std::map<QSurfaceFormat::OpenGLContextProfile, std::string> profile_str = {
{ QSurfaceFormat::OpenGLContextProfile::NoProfile, "NO Profile"},
{ QSurfaceFormat::OpenGLContextProfile::CoreProfile, "Core Profile"},
{ QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile, "Compatibility Profile"}
};
fmt = m_context->format();
qWarning("OpenGL %d.%d %s", fmt.version().first, fmt.version().second, profile_str[fmt.profile()].c_str());
w->show();
return a.exec();
}

手元のノートパソコンはintelのオンボードのGPUとは別にNvidiaのGPUの双発機で,アプリケーションに応じてどちらを描画エンジンとして利用するかを指定できるのですが,後者の環境は正しく認識されません.もうすこし確認してからQt Forumで質問してみようと思います.

この小さなサンプルコードを作るにあたって多くのサイトのお世話になりました.ごく一部について,以下に紹介します.

  • Dr. Roland Krause, “State of the art OpenGL and Qt,” Jul. 2015, — KDABと並んでQtを支えているICSの技術者がQtのウィンドウやウィジェットとOpenGLとの関係を概説しています.
  • Sean Harmer, “OpenGL in Qt 5.1,” Part I-V, Mar. 2013. — KDABの技術者がQt5におけるOpenGLのサポートをかなり細かく説明しています.少し内容が古いのですが,概略を理解する上でとても参考になります.
  • Qtの公式チュートリアル, “Hello GL2 example,” コーディングに関しては,このコードが一番参考になりました.QtとOpenGLについての記事は多いのですが,Qt4についての内容が多く,またOpenGLの古いバージョンに依存したものがほとんどでここに至るまでに苦労しました.Qt5のチュートリアルは大量のサンプルコードがあるのですが,調べた限りで,Core Profileを扱っているのはこの例だけのようです.
  • QOpenGLFunctionsクラスのversionFunctionsメソッドの公式マニュアル

QWidget/Qt5 + OpenGL」への1件のフィードバック

  1. QOpenGLFunctions_x_y の扱いについてもっと単純化できるような気がして,いじっているうちにものすごく簡単になりました.難しく考えすぎていたのかもしれません.今回の版では,GLWidget に QOpenGLFunctions_4_3 を継承させていますが,これを抽象化させてもよさそうな気がします.バージョン違いについては,main.cxx で確認すればいいので.

    void GLWidget::initializeGL() {
    QSurfaceFormat fmt = QOpenGLContext::currentContext()->format();
    qWarning("OpenGL %d.%d %s", fmt.version().first, fmt.version().second, profile_str[fmt.profile()].c_str());
    initializeOpenGLFunctions();
    }

    view raw
    glwidget.cxx
    hosted with ❤ by GitHub

    #include "mainwindow.hxx"
    #include <QApplication>
    #include <QSurfaceFormat>
    #include <QOpenGLContext>
    #include <iostream>
    #include <map>
    extern Ui::MainWindow mainWindow;
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    QSurfaceFormat fmt;
    fmt.setMajorVersion(4); fmt.setMinorVersion(5);
    fmt.setProfile(QSurfaceFormat::CoreProfile);
    fmt.setSamples(4);
    fmt.setDepthBufferSize(24);
    QSurfaceFormat::setDefaultFormat(fmt);
    MainWindow *w = new MainWindow;
    w->show();
    return a.exec();
    }

    view raw
    main.cxx
    hosted with ❤ by GitHub

コメントは受け付けていません。