1

iOS デバイスで yuv イメージをレンダリングしたいと考えています。openGL を使用して実現できると思います。(実際には、そのような複数の画像を連続してレンダリングする必要があります)

私が理解しているのは、GLKit は iOS が作成した抽象化でありGLKView、レンダー バッファーを持ち、処理する があるということです。私は現在 を使用しようとしていますがGLKViewController、フレームの更新は目的の fps で正常に行われています。glClearこれは、関数呼び出しを使用して準拠します。

ここでのタスクは、ビューに画像をレンダリングすることです。

GLKBaseEffect基本的なシェーダーを持つクラスがあります。設定するプロパティがわからないので、作成してprepareToDraw各レンダリングの前に呼び出すだけです。

テクスチャを処理するためのクラスがありますが、GLKTextureLoaderQuartz 画像でのみ機能するように見えます。つまり、このクラスを使用して yuv420 平面をテクスチャにロードすることはできません。

// create the texture
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, [imageNSData bytes]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);  

このコードを使用してテクスチャを生成し、バインドしますが、ここで何をしようとしているのかよくわかりません。それが何であれ、画面に画像が表示されず、次に何をすべきかわかりません。

baseEffect に何かがあると仮定して、シェーダーは作成していません。

そして、このhttps://developer.apple.com/library/ios/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/WorkingwithEAGLContexts/WorkingwithEAGLContexts.html#//apple_ref/doc/uid/TP40008793-CH103-SW8は、私が持っていることを教えてくれますEAGLayer を使用して画面に画像をレンダリングします。

GLKit を使用して画像をレンダリングできますか? はいの場合、クラスを使用しないサンプル コードまたはチュートリアルはGLKTextureLoaderありますか (何も見つかりませんでした)。いいえの場合、レンダリングを使用するための同様のチュートリアルはありますEAGLLayerか (私は今までそれについて調べていません)?

4

1 に答える 1

4

ここでいくつかの異なるトピックについて本当に質問しているようです:

  • GLKViewvsで描く方法CAEAGLLayer
  • GLKBaseEffect一般的な OpenGL ES 描画へのGLKTextureLoader適合方法
  • テクスチャを作成したら、テクスチャを描画する方法
  • YUV 画像データのレンダリング方法

一つ一つ丁寧に扱っていこうと思います…


GLKViewやりたいOpenGL ES描画には問題ありません-リンク先の古いドキュメントが行うすべてのこと(フレームバッファ、CAEAGLLayersなどの設定)を行うので、そのコードを書く必要はありません。GLKView描画メソッド (drawRect:またはglkView:drawInRect:、サブクラスで描画するかデリゲートで描画するかに応じて) 内で、(または他のシステムで) 描画するのと同じ OpenGL ES 描画コードを記述しますCAEAGLLayer


GLKViewGLKTextureLoader、およびGLKBaseEffectを互いに独立して使用できます。独自の描画コードをすべて記述し、独自のシェーダーを使用する場合は、GLKViewを使用せずに で描画できますGLKBaseEffectGLKBaseEffect( OpenGL ゲーム テンプレートを使用して新しい Xcode プロジェクトを作成するときに見られるように、独自のものを組み合わせることもできます。) 同様に、GLKTextureLoader画像データを読み込みname、描画用にバインドするために必要な .で描いているかどうかに関係なく、それを使用できますGLKBaseEffect


テクスチャを取得したら、GLKTextureLoader自分でデータを読み取り/デコードして に提供するかどうかに関係なくglTexImage2D、それを使用して描画するための 3 つの基本的な手順があります。

  1. でテクスチャ名をバインドしglBindTextureます。
  2. テクスチャリングするジオメトリを描画します ( glDrawArraysglDrawElements、または同様のものを使用)
  3. テクセルを検索して色を出力するフラグメント シェーダーを用意します。

ビュー全体に画像を描画するだけの場合は、クワッド (2 つの三角形) を描画します。フルスクリーンで描画したいときに、1 つのクワッドで頂点配列オブジェクトを設定するために使用するコードを次に示します。

typedef struct __attribute__((packed)) {
    GLKVector3 position;
    GLKVector2 texcoord;
} Vertex;

static Vertex vertexData[] = {
    {{-1.0f,  1.0f, -1.0f}, {0.0f,  0.0f}},
    {{-1.0f, -1.0f, -1.0f}, {0.0f,  1.0f}},
    {{ 1.0f,  1.0f, -1.0f}, {1.0f,  0.0f}},
    {{ 1.0f, -1.0f, -1.0f}, {1.0f,  1.0f}},
};

glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);

glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *)offsetof(Vertex, position));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *)offsetof(Vertex, texcoord));
glBindVertexArrayOES(0);

次に、それを描画します。

glBindVertexArrayOES(_vertexArray);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

それは単なるジオメトリ描画部分です。GLKBaseEffectこれを--transformプロパティがデフォルトの恒等変換であり、そのプロパティがロードしたテクスチャまたは他の方法texture2d0で設定されている --と組み合わせると、テクスチャが表示されたビューいっぱいのビルボードが得られます。 .nameGLKTextureLoader


最後に、YUV の部分です。主にパントします。YUV テクスチャ データはどこから取得していますか? デバイスのカメラからのものである場合は、この回答で説明されているように、 CVOpenGLESTexture/を調べる必要があります。とにかく、この回答で説明されているように、拡張機能を使用して YUV テクスチャを処理できるはずです。YUV を RGB にオンザフライで処理するためのフラグメント シェーダーの記述については、この回答を参照することもできます。CVOpenGLESTextureCacheAPPLE_rgb_422

于 2013-09-18T22:32:50.433 に答える