3.OpenCLの利用

美顔、ステッカー、フィルターおよびメークアップ効果の実現にOpenGLの利用が必要です。

3.1 OpenGLの初期化

  1. opengl_check.exeを実行し,システムおよびGPUドライバーのopengl32.dllバージョンを確認する

  2. opengl_checkが失敗の場合は、Mesa版のopengl32.dllを用いてOpenGLの初期化を行う

  3. opengl_checkが成功の場合は、glfwライブラリを初期化し、glfwウィンドウを作成する。glfwウィンドウ作成が失敗の場合は、Mesa版のopengl32.dllを用いてOpenGLの初期化を行う

  4. glfwウィンドウの作成が成功したら,gl3wの初期化を行う。gl3wの初期化が失敗シた場合は,

    1. Mesa版のopengl32.dllを用いてOpenGLの初期化を行う

  5. OpenGLのバージョンを確認し,2.1以下またはOpenGLSLバージョンは1.2以下の場合は,エラーで返す

OpenGL初期化の詳細はhelper_opengl.hに参照してください。

inline bool InitGL() {
    glfwSetErrorCallback(PrintglfwError);
    bool bGLInited = false;
    if (!window) {
        try {
            int err = 0;
#ifdef WIN32 
if (opengl_check()) {
#endif 
    err = glfwInit();
    if (!err) {
        throw "OpenGL: fail to create window context!";
    }
    // Create a offscream mode window and its OpenGL context
    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
    window = glfwCreateWindow(10, 10, "hello", NULL, NULL);
#ifdef WIN32 
} 
#endif 
            if (!window) {
#ifdef WIN32 
                MesaOpenGL();
#else 
                throw "OpenGL: fail to init glfw";
#endif 
}
else { 
                // Make the window's context current
                glfwMakeContextCurrent(window);
#ifdef WIN32 
                err = gl3wInit();
                if (err != GL3W_OK) {
                    MesaOpenGL();
                }
#else 
                glewExperimental = GL_TRUE;
                err = glewInit();
                if (err != GLEW_OK) {
                    throw "OpenGL: fail to init glew\n";
                }
#endif 
} 
            const unsigned char* glVer = glGetString(GL_VERSION);
            const unsigned char* glslVer = glGetString(GL_SHADING_LANGUAGE_VERSION);
            float OpenglVersion = 0.f, GLSLVersion = 0.f;
            StringTo((char*)glVer, OpenglVersion);
            StringTo((char*)glslVer, GLSLVersion);
            fprintf(stdout, "Renderer: %s\n", glGetString(GL_RENDERER));
            fprintf(stdout, "OpenGL version supported %s\n", glGetString(GL_VERSION));
            fprintf(stdout, "OpenGLSL version supported %s\n",
            glGetString(GL_SHADING_LANGUAGE_VERSION));
            if (OpenglVersion <2.1f || GLSLVersion < 1.2f) {
                throw "OpenGL version is too old, we only support above opengl2.1 and glsl1.2.0";
            }
            bGLInited = true;
        }
        catch (std::exception &e){
            fprintf(stderr, "%s\n", e.what());
        }
        catch (const char* e){
            fprintf(stderr, "%s\n", e);
        }
        catch (...) {
            return false;
} } 
 else {
        GLFWwindow* curCtx = glfwGetCurrentContext();
        if (!curCtx)
            glfwMakeContextCurrent(window);
        bGLInited = true;
} 
    return bGLInited;
}

Mesa版opengl32.dllによるOpenGLの初期化は以下の通り。

  1. Mesa版opengl32.dllをロードする

  2. glfwライブラリの初期化を行い,glfwウィンドウを作成し,gl3wの初期化を行う

3.2 OpenGLレンダリング効果の利用

3.2.1 テクスチャバンディング

画像を処理する前に、テクスチャにバインドする必要があります。 テクスチャのバインド処理は、次のように行います。

  1. テクスチャのインデックスを生成する。

  2. テクスチャインデックスがテクスチャオブジェクトにバインドされていない場合、テクスチャインデックスをテクスチャユニットにバインドし、glTexImage2Dを使用して2Dテクスチャを生成してバインドを完了させます。

  3. 後続のビデオフレームでは、glTexSubImage2Dを使用して既存のテクスチャを変更します。

  4. ビデオ解像度が変更された場合は、手順2へ戻ります。

process textureインターフェースを使用して、効果をレンダリングする前に入力と出力のテクスチャーをバインドします。

process bufferを使用したエフェクトのレンダリングでは、テクスチャのバインディングは不要で、関数内部で行われます。

3.2.2 エフェクトレンダリング

この効果はOpenGLでprocess textureインターフェイスまたはprocess bufferインターフェイスを使って、次のように描画されます。他の効果については4.4を参照してください:

3.3 OpenGLのクローズ

プログラムの終了時には、glfw が作成したウィンドウを閉じて、glfwを終了させる必要があります。

Last updated