web-dev-qa-db-ja.com

OpenGL ES 2.0でテクスチャを2D背景として描画するにはどうすればよいですか?

OpenGL ES 2.0を使い始めたばかりですが、簡単な2D出力を作成したいと思います。 480x800の解像度で、背景テクスチャを描画するにはどうすればよいですか?

[私の開発環境はJava/Androidなので、それに直接関連する例が最適ですが、他の言語でもかまいません。]

17
Mark Ingram

Androidを使用している場合でも、着信するビデオのフレームに対してこれを行うiPhoneサンプルアプリケーションを作成しました。このサンプルのコードは、 ここ からダウンロードできます。ライブビデオを使用してカラーベースのオブジェクトトラッキングを行うこのアプリケーションについての記事があります。これは ここ と読むことができます。

このアプリケーションでは、2つの三角形を描画して長方形を生成し、次の座標を使用してテクスチャを作成します。

   static const GLfloat squareVertices[] = {
        -1.0f, -1.0f,
        1.0f, -1.0f,
        -1.0f,  1.0f,
        1.0f,  1.0f,
    };

    static const GLfloat textureVertices[] = {
        1.0f, 1.0f,
        1.0f, 0.0f,
        0.0f,  1.0f,
        0.0f,  0.0f,
    };

ビデオフレームをテクスチャとして通過させるために、次の頂点シェーダーを備えた単純なプログラムを使用します。

attribute vec4 position;
attribute vec4 inputTextureCoordinate;

varying vec2 textureCoordinate;

void main()
{
    gl_Position = position;
    textureCoordinate = inputTextureCoordinate.xy;
}

および次のフラグメントシェーダー:

varying highp vec2 textureCoordinate;

uniform sampler2D videoFrame;

void main()
{
    gl_FragColor = texture2D(videoFrame, textureCoordinate);
}

描画は、適切なプログラムを使用するだけの簡単な問題です。

glUseProgram(directDisplayProgram);

テクスチャを均一に設定する:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, videoFrameTexture);

glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0);   

属性の設定:

glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);

次に、三角形を描画します。

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
32
Brad Larson

実際には背景を描画しません。代わりに、長方形(または、より正確には、長方形を形成する2つの三角形)を描画し、それにテクスチャを設定します。これは、画面上に他のオブジェクトを描画することとまったく違いはありません。

これがどのように行われるかを示す場所はたくさんあります。おそらく、これを示すAndroidサンプルプロジェクトもあります。

トリッキーな部分は、何かの前または後ろに何かを表示することです。これを機能させるには、深度バッファーを設定し、深度テストを有効にする必要があります(glEnable(GL_DEPTH_TEST))。また、頂点にはZ座標が必要です(そして、頂点が2つではなく3つの値で構成されていることをglDrawElementsに伝えます)。

そうしないと、オブジェクトはglDrawElements()関数が呼び出された順序でレンダリングされます(つまり、最後に描画した方が残りを覆い隠してしまいます)。

私のアドバイスは、あなたがそれのコツをつかむまで、背景画像を持たないか、何か空想的なことをしないことです。 OpenGL ES 2.0には一種の急な学習曲線があり、ES 1.xのチュートリアルは、2.0にはないgluPerspectiveのようなヘルパー関数を使用できるため、3Dを機能させるのに実際には役立ちません。何もない背景に三角形を作成することから始めます。次に、それを正方形にします。次に、すでに凝ったものにしたい場合は、テクスチャを追加します。ポジションで遊ぶ。頂点のZ値を変更するとどうなるかを確認してください。 (ヒント:深度テストが有効になっていない場合はそれほど多くありません。それでも、透視投影がない場合は、オブジェクトが遠くにあるほど小さくならないため、何もないように見えます。起こりました)

数日後、それはそれほどイライラすることをやめ、そしてあなたはついにほとんど「それを手に入れる」。

15
fzwo