Qt GUI で OpenGL 機能の状態を検査:QOpenGLExtraFunctions::glIsEnabledi() 関数徹底解説


QOpenGLExtraFunctions::glIsEnabledi() 関数は、OpenGL ES 3.x、OpenGL 3.x、または OpenGL 4.x コンテキストにおいて、特定の OpenGL 機能が有効かどうかを検査するために使用されます。この関数は、OpenGL ES 3.x 標準で定義されており、Qt GUI ライブラリによって Qt 6 以降で使用可能になっています。

構文

GLboolean QOpenGLExtraFunctions::glIsEnabledi(GLenum target, GLuint index);

パラメータ

  • index: 検査対象の OpenGL 機能のインデックス。このパラメータは、target によって異なります。
  • target: 検査対象の OpenGL 機能を指定する列挙値。使用可能な値は次のとおりです。
    • GL_VERTEX_ARRAY: 頂点配列が有効かどうかを検査します。
    • GL_TEXTURE_2D: 2D テクスチャが有効かどうかを検査します。
    • GL_TEXTURE_3D: 3D テクスチャが有効かどうかを検査します。
    • GL_TEXTURE_CUBE_MAP: キューブマップ テクスチャが有効かどうかを検査します。
    • GL_TEXTURE_1D: 1D テクスチャが有効かどうかを検査します。
    • GL_TEXTURE_2D_ARRAY: 2D テクスチャ配列が有効かどうかを検査します。
    • GL_TEXTURE_CUBE_MAP_ARRAY: キューブマップ テクスチャ配列が有効かどうかを検査します。
    • GL_TEXTURE_RENDERBUFFER: レンダーバッファ テクスチャが有効かどうかを検査します。
    • GL_TEXTURE_BUFFER: バッファ テクスチャが有効かどうかを検査します。
    • GL_LINE_SMOOTH: ラインのスムージングが有効かどうかを検査します。
    • GL_POINT_SMOOTH: ポイントのスムージングが有効かどうかを検査します。
    • GL_POLYGON_SMOOTH: ポリゴンのスムージングが有効かどうかを検査します.
    • GL_MULTISAMPLE: マルチサンプリングが有効かどうかを検査します。
    • GL_SAMPLE_ALPHA_COVERAGE: サンプル アルファ カバレッジが有効かどうかを検査します。
    • GL_DEBUG_OUTPUT_SYNCHRONOUS: デバッグ出力同期が有効かどうかを検査します。
    • GL_BLEND: ブレンドが有効かどうかを検査します。
    • GL_DEPTH_TEST: 深度テストが有効かどうかを検査します。
    • GL_STENCIL_TEST: ステンシル テストが有効かどうかを検査します。
    • GL_CULL_FACE: カリングが有効かどうかを検査します。
    • GL_SCISSOR_TEST: はさみテストが有効かどうかを検査します。

戻り値

関数は、検査対象の OpenGL 機能が有効な場合は GL_TRUE、無効な場合は GL_FALSE を返します。

QOpenGLExtraFunctions glFuncs(context);

// 頂点配列が有効かどうかを検査
if (glFuncs.glIsEnabledi(GL_VERTEX_ARRAY)) {
    // 頂点配列が有効なので、頂点データを設定して描画処理を行う
} else {
    // 頂点配列が無効なので、有効にしてから描画処理を行う
    glFuncs.glEnable(GL_VERTEX_ARRAY);
}
  • Qt GUI ライブラリを使用して OpenGL プログラミングを行う場合は、QOpenGLExtraFunctions クラスを使用して OpenGL 機能のラッパー関数にアクセスする必要があります。
  • この関数は、OpenGL ES 3.x、OpenGL 3.x、または OpenGL 4.x コンテキストでのみ使用できます。
  • QOpenGLExtraFunctions::glIsEnabledi() 関数は、OpenGL ES 3.x 標準で定義された glIsEnabledi() 関数の Qt GUI ライブラリにおけるラッパー関数です。


#include <QCoreApplication>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QWindow>

class MyWindow : public QWindow
{
public:
    MyWindow();

protected:
    virtual bool event(QEvent *event) override;

private:
    void initialize();
    void paint();

    QOpenGLContext *context;
    QOpenGLFunctions *glFuncs;
};

MyWindow::MyWindow()
{
    setSurfaceType(QSurface::OpenGLSurface);
    setFormat(QSurfaceFormat::defaultFormat());

    context = new QOpenGLContext(this);
    context->setFormat(format());
    context->create();

    setContext(context);

    glFuncs = new QOpenGLFunctions(context);
}

bool MyWindow::event(QEvent *event)
{
    if (event->type() == QEvent::Paint) {
        paint();
        return true;
    }

    return QWindow::event(event);
}

void MyWindow::initialize()
{
    glFuncs->initializeOpenGLFunctions();

    // 頂点配列を有効にする
    if (!glFuncs->glIsEnabledi(GL_VERTEX_ARRAY)) {
        glFuncs->glEnable(GL_VERTEX_ARRAY);
    }

    // 頂点シェーダーとフラグメントシェーダーを作成してコンパイルする
    GLuint vertexShader = glFuncs->glCreateShader(GL_VERTEX_SHADER);
    const char *vertexShaderSource =
        "attribute vec3 position;                                             "
        "void main() {                                                    "
        "    gl_Position = vec4(position, 1.0);                            "
        "}                                                                ";
    glFuncs->glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
    glFuncs->glCompileShader(vertexShader);

    GLuint fragmentShader = glFuncs->glCreateShader(GL_FRAGMENT_SHADER);
    const char *fragmentShaderSource =
        "precision highp float;                                           "
        "void main() {                                                    "
        "    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);                    "
        "}                                                                ";
    glFuncs->glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
    glFuncs->glCompileShader(fragmentShader);

    // シェーダープログラムを作成してリンクする
    GLuint shaderProgram = glFuncs->glCreateProgram();
    glFuncs->glAttachShader(shaderProgram, vertexShader);
    glFuncs->glAttachShader(shaderProgram, fragmentShader);
    glFuncs->glLinkProgram(shaderProgram);

    // 三角形の頂点データをバッファに格納する
    GLfloat vertices[] = {
        0.0f, 0.5f, 0.0f,
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f
    };

    GLuint vertexBuffer;
    glFuncs->glGenBuffers(1, &vertexBuffer);
    glFuncs->glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glFuncs->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // 頂点属性を構成する
    glFuncs->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
    glFuncs->glEnableVertexAttribArray(0);

    // シェーダープログラムを使用する
    glFuncs->glUseProgram(shaderProgram);
}

void MyWindow::paint()
{
    context->makeCurrent();

    // ビューポートを設定する
    glFuncs->glViewport(0, 0, width(), height());

    // フレームバッファをクリアする
    glFuncs->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glFuncs->glClear(GL_COLOR_BUFFER_BIT);

    // 三角形を描


OpenGL 標準の関数を使用する

OpenGL 標準には、glGetBooleanv() 関数という、特定の OpenGL 機能の状態を取得するために使用できる関数があります。この関数は、検査対象の OpenGL 機能を指定する列挙値と、結果を格納する変数を引数として受け取ります。

GLint enabled;
glGetBooleanv(GL_VERTEX_ARRAY, &enabled);

if (enabled) {
    // 頂点配列が有効なので、処理を行う
} else {
    // 頂点配列が無効なので、有効にして処理を行う
    glEnable(GL_VERTEX_ARRAY);
}

QOpenGLContext::functions() メソッドを使用する

QOpenGLContext::functions() メソッドは、QOpenGLExtraFunctions オブジェクトを取得するために使用できます。このオブジェクトは、OpenGL 機能のラッパー関数にアクセスするために使用できます。

QOpenGLExtraFunctions *glFuncs = context->functions();

if (glFuncs->isEnabled(GL_VERTEX_ARRAY)) {
    // 頂点配列が有効なので、処理を行う
} else {
    // 頂点配列が無効なので、有効にして処理を行う
    glFuncs->glEnable(GL_VERTEX_ARRAY);
}

マクロを使用する

OpenGL ヘッダーファイルには、特定の OpenGL 機能の状態を取得するために使用できるマクロが定義されています。

#if GL_ARB_vertex_array_bcast
    if (glIsEnabled(GL_VERTEX_ARRAY_BCAST)) {
        // 頂点配列ブロードキャストが有効なので、処理を行う
    } else {
        // 頂点配列ブロードキャストが無効なので、有効にして処理を行う
        glEnable(GL_VERTEX_ARRAY_BCAST);
    }
#endif

条件付きコンパイルを使用する

OpenGL ヘッダーファイルには、特定の OpenGL 機能がサポートされているかどうかを判断するために使用できるマクロが定義されています。これらのマクロを使用して、条件付きコンパイルを使用して、機能がサポートされている場合にのみコードを実行することができます。

#ifdef GL_ARB_vertex_array_bcast
    // 頂点配列ブロードキャストがサポートされているので、処理を行う
#else
    // 頂点配列ブロードキャストがサポートされていないので、処理を行わない
#endif

独自の関数を作成する

独自の関数を作成して、特定の OpenGL 機能の状態を取得することができます。この関数は、glGetBooleanv() 関数または glIsEnabled() マクロを使用して、必要な情報を取得することができます。