Pynote

Python、機械学習、画像処理について

Qt - Qt で OpenGL の API を利用する方法について

試した環境

  • Qt 5.10

手順

空のウィンドウが表示されるこちらのコードを元に説明する。

CMake を編集する。

find_package(OpenGL) で OpenGL パッケージを検索し、target_link_libraries() でライブラリをリンクする。

cmake_minimum_required(VERSION 3.1.0)

project(sample)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)

find_package(Qt5 COMPONENTS Core Widgets REQUIRED)
find_package(OpenGL)

file(GLOB_RECURSE CPP_FILES src/*.cpp)
file(GLOB_RECURSE UI_FILES src/*.ui)
file(GLOB_RECURSE QRC_FILES res/*.qrc)

include_directories(src)

add_executable(${PROJECT_NAME}
    ${CPP_FILES}
    ${UI_FILES}
    ${QRC_FILES}
)

target_link_libraries(${PROJECT_NAME}
    Qt5::Widgets
    ${OPENGL_LIBRARY}
)

OpenGL を描写するための自作ウィジェットを作る

OpenGLAPI で描画するには、QOpenGLWidget というウィジェットクラスを用いる。
QOpenGLWidget を継承したカスタムクラス MyOpenGLWidget を作成する。

myopenglwidget.h

#ifndef MYOPENGLWIDGET_H
#define MYOPENGLWIDGET_H

#include <QOpenGLFunctions>
#include <QOpenGLWidget>

class MyOpenGLWidget
    : public QOpenGLWidget
    , protected QOpenGLFunctions
{
    Q_OBJECT

  public:
    MyOpenGLWidget(QWidget *parent);
    ~MyOpenGLWidget();

  protected:
    void initializeGL() override;
    void resizeGL(int w, int h) override;
    void paintGL() override;
};

#endif  // MYOPENGLWIDGET_H

myopenglwidget.cpp

#include "myopenglwidget.h"

MyOpenGLWidget::MyOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
}

MyOpenGLWidget::~MyOpenGLWidget()
{
}

/**
 * @brief 初期化処理を記述する。
 */
void MyOpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();
}

/**
 * @brief リサイズされた際の処理を記述する。
 */
void MyOpenGLWidget::resizeGL(int width, int height)
{
}

/**
 * @brief 描画する際の処理を記述する。
 */
void MyOpenGLWidget::paintGL()
{
}

ウィジェットリストから QOpenGLWidget をフォーム上にドラッグアンドドロップする。

フォーム上の追加した QOpenGLWidget を右クリックし、「格上げ先の指定」を選択する。
格上げされたクラス名を「MyOpenGLWidget」、ヘッダファイルを「myopenglwidget.h」と入力し、「追加」をクリックする。

「格上げされたクラスの一覧」から追加した「MyOpenGLWidget」を選択し、「格上げ」ボタンをクリックする。

ここで一旦ビルドすると、次のウィンドウが表示される。
OpenGL の描写命令を記述していないため、フォーム上のウィジェットは真っ黒な状態である。


OpenGLAPI で描画命令を記述する。

描写できることを確認するため、ポリゴンを描画する。
描画の確認が目的なので、GLSL は使わず、固定機能パイプラインを利用する。

初期化処理を記述する。

OpenGLAPI を呼ぶ前に initializeOpenGLFunctions() を呼ぶ必要があることに注意する。

myopenglwidget.cpp

void MyOpenGLWidget::initializeGL()
{
    // OpenGL の API を呼ぶ前に呼ぶ。
    initializeOpenGLFunctions();
}
描画する際の処理を記述する。

3点 (0, 0., 0), (-0., 0, 0), (0.8, 0, 0) から成るポリゴンを描画する。

myopenglwidget.cpp

void MyOpenGLWidget::paintGL()
{
    glBegin(GL_TRIANGLES);
    glColor3d(1.f, 0.f, 0.f);  // 赤色
    glVertex3d(0.f, 0.8f, 0.f);
    glVertex3d(-0.8f, 0.f, 0.f);
    glVertex3d(0.8f, 0.f, 0.f);
    glEnd();
}

ビルドする。

ここまでの手順がうまくいっている場合、ビルドして実行すると、三角形が描画される。