10

SurfaceTextureカメラのプレビューとオーバーレイテクスチャをミックスしたいと思います。私はこれらのシェーダーを処理に使用しています:

private final String vss = "attribute vec2 vPosition;\n"
        + "attribute vec2 vTexCoord;\n"
        + "varying vec2 texCoord;\n"
        + "void main() {\n" 
        + "  texCoord = vTexCoord;\n"
        + "  gl_Position = vec4 ( vPosition.x, vPosition.y, 0.0, 1.0 );\n"
        + "}";

private final String fss = "#extension GL_OES_EGL_image_external : require\n"
        + "precision mediump float;\n"
        + "uniform samplerExternalOES sTexture;\n"
        + "uniform sampler2D filterTexture;\n"
        + "varying vec2 texCoord;\n"
        + "void main() {\n"
        +"  vec4 t_camera = texture2D(sTexture,texCoord);\n"
        //+"  vec4 t_overlayer = texture2D(filterTexture, texCoord);\n" 
        //+ "  gl_FragColor = t_overlayer;\n" + "}";
        + "  gl_FragColor = t_camera;\n" + "}";

私の目標は、混合することt_cameraですt_overlayer。私が表示t_cameraするか、t_overlayer個別に表示すると、機能します(カメラのプレビューまたはテクスチャを表示します)。しかし、コメントを外すt_overlayerと、t_camera黒になります(どういうわけかひどくサンプリングされています)。私のオーバーレイヤーテクスチャは512x512とCLAMPT_TO_EDGEです。この問題は、Android Emulator、HTCEvo3Dなどでのみ発生します。しかし、SGS3、HTC One Xでは、問題なく動作します。

なにが問題ですか?Evo 3Dに拡張機能がないのですか、それとも何ですか?

4

8 に答える 8

5

コードに正しいテクスチャ ID を設定していないため、この問題が発生していると思います。これは、論理的に見える仮定の典型的なエラーですが、実際にはドキュメントではそのように定義されていません。この拡張機能のドキュメントを確認すると、次の (編集された) TEXT が表示されます。

各 TEXTURE_EXTERNAL_OES テクスチャ オブジェクトは、 バインド先のテクスチャ ユニットごとに最大 3 つのテクスチャ イメージ ユニットを必要とする場合があります。が TEXTURE_EXTERNAL_OES に設定されている場合、この値は 1 から 3 の間 (両端を含む) になります。他の有効なテクスチャ ターゲットの場合、この値は常に 1 になります。TEXTURE_EXTERNAL_OES テクスチャ オブジェクトがバインドされている場合、1 つのテクスチャ ユニットに必要なテクスチャ イメージ ユニットの数は 1、2、または 3であることに注意してください。テクスチャ ユニットには、ちょうど 1 つのテクスチャ イメージ ユニットが必要です。

これは、id 0 を使用する場合、少なくとも 1 つの追加が機能することを意味します。あなたの場合:

GLES20.glUniform1i(sTextureHandle, 1);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
        sTextureId);

2D テクスチャの場合:

GLES20.glUniform1i(filterTextureHandle, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, filterTextureID);

私はこれがあなたのために運動すると確信しています.

于 2013-03-27T13:36:45.860 に答える
3

これは答えではなく、質問の詳細です.OpenGl ESの専門家が問題を理解するのに役立つかもしれません.


オーバーレイに使用される 3 つのテクスチャと、メディア プレーヤーからの出力をキャプチャするために使用される 1 つの外部テクスチャがあります。外部テクスチャのみを使用すると、MPlayer からのフレームが期待どおりに出力されます。同じ完全なコードは、Nexus4、Samsung Galaxy S3、S4 などで正常に動作します (すべてのデバイスは adreno gpu または Arm の Mali400 を使用します) ハードウェアの違いは、Nexus 7 が Nvidia Tegra 3 ボードを使用することです。


編集 (私の側でどのように解決されたか)

Nvidia Tegra 3 では、外部テクスチャ サンプラーはサンプラーの中でアルファベット順が最も低い名前で呼び出される必要がありますが、Adreno 220 ではその逆が必要なようです。また、T3 では、外部テクスチャを最後にサンプリングする必要があります。Android 4.3 以降を使用するデバイスでは、これらのバグが解決される場合があります。Nvidia 側では、これはずっと前に解決されたバグでしたが、Nexus ドライバーは後で更新されました。そのため、どの GPU が存在するかを確認し、それに応じてコードを調整する必要がありました。

于 2013-05-31T20:19:37.680 に答える
3

OpenGl 実装のバグのようです。同じコードが Samsung Note では正常に機能しましたが、nexus 4 では正常に機能しませんでした。一部のデバイスでは、samplerExternalOES を過ぎて配置されたすべての変数に対して getUniformLocation が壊れているようです。

また、コンパイラは均一変数をアルファベット順にソートしているように見えるため、両方のデバイスで機能するようにする解決策は、samplerExternalEoz の名前を zzzTexture などに変更することでした。

于 2013-11-03T05:07:29.563 に答える
3

Nexus 7 でも同じ問題が発生し、気が狂いそうになりました。samplerExternalOES または sampler2D へのアクセスはまったく問題なく機能しましたが、同じシェーダーで両方にアクセスすると、予期しない結果が生じました。場合によっては、出力が黒くなることがあります。ルックアップの 1 つの出力に、不適切な量子化アーティファクトが含まれることがあります。動作は、サンプラーがバインドされているテクスチャ ユニットによっても異なります。すべてのopenglエラーとvalidateProgramの結果を確認しました。

最終的には、別のシェーダーを使用してカメラ出力にアクセスし、それをテクスチャにレンダリングするだけでうまくいきました。その後、通常の sampler2D を介して結果のテクスチャにアクセスでき、すべてが期待どおりに機能します。samplerExternalOES に関連するどこかにバグがあると思われます。

于 2012-12-27T06:48:22.987 に答える
2

sampler2D テクスチャと samplerExternalOES テクスチャへのアクセスの分割に関するuser1924406 の投稿 ( https://stackoverflow.com/a/14050597/3250829 ) を参照すると、開発中のアプリケーションがファイルまたはデバイス上のカメラを使用する代わりに、サーバーからストリーミングします。同じシェーダーで両方のテクスチャを使用すると、非常に奇妙な色付けアーティファクト (Galaxy S3 の場合) または彩度とコントラストの問題 (Nexus 4 の場合) が発生しました。

したがって、samplerExternalOES テクスチャのバグを回避する唯一の方法は (私がこれまで見てきたことから)、2 つのシェーダー プログラムを実行することです。 FBO からコンテンツを取得し、それを直接サーフェスに書き込みます。

確認する必要があることの 1 つは、FBO に書き込むときにテクスチャ座標が反転することがあることです。私の場合、V (または T または Y) 座標が反転され、その結果、水平軸を横切る鏡像が作成されました。第 2 段階でフラグメント シェーダーを作成するときは、これを考慮に入れる必要がありました。

これは、カメラから直接取得するのではなく、ファイルから読み取ったり、サーバーからストリーミングしたりする必要がある場合に備えて、私が共有したかった戦争の話です。

于 2014-02-04T18:24:32.433 に答える
1

私も同じ問題を抱えているかもしれません。何日も試した後、ここで解決策を提案しています。これが他の人に役立つことを願っています。

まず、問題文。Lukáš Jezný と同じように、プレビュー テクスチャとオーバーレイ テクスチャが 1 つずつあります。nexus 4/5 および他のほとんどのタイプでは問題なく動作しますが、OPPO find 5、Lenovo A820、Lenovo A720 では何も表示されません。

解決:

(1)Lukáš Jezný と同様に、YUV データを使用し、シェーダーで RGB に変換します。

(2)マルチパス描画、プレビューテクスチャを一度フレームバッファに描画して読み込み、再度画面に描画します。

(3)独自のプログラムを使用する前に別のプログラムを使用する。

    GLES20.glUseProgram(another one);
    GLES20.glUseProgram(your "real" program);

OPPO find 5、Lenovo A820、Lenovo A720などでのみ機能します。その理由は誰にもわかりません……。

于 2013-12-30T10:28:21.357 に答える