5

システム: Android 4.03、OpenGL ES 2.0

問題:最初のフレームが別のプログラム/シェーダーで既にレンダリングされた後に glAttachShader が呼び出されると、一部のデバイス (Galaxy S3) が「GL_INVALID_VALUE」エラーでクラッシュします (エラー スタックに詳細はありません)。他のデバイス (Asus eee TF101) はそれでまったく問題ありません。エラーは常に発生するわけではなく、代わりに「GL_INVALID_ENUM」になることもあります。onDrawFrame の最初の呼び出しですべてのシェーダーを強制的にコンパイルすると、すべての (私の) デバイスで動作します。

質問: openGL(ES) マシンがシェーダーをコンパイルできない状態はありますか? バインドされたバッファ、テクスチャ、または有効な属性配列が、プログラムへのシェーダのアタッチを妨げる可能性はありますか? もしそうなら、シェーダーを取り付けてプログラムをリンクする前に確保しなければならない理想的な状態は何ですか? 他のオブジェクトが他のシェーダーで既にレンダリングされた後にシェーダーをコンパイルすることは有効ですか?

バックグラウンド:私は、openGL グラフィックスをよりオブジェクト指向の方法 (「シーン」、「マテリアル」、「モデル」などのオブジェクトを使用) で使用して、ゲームを簡単に作成できるようにする Android ライブラリを開発しています。シーン、モデルなどは、GL コンテキストとは異なるスレッドで作成されます。onDrawFrame がこれらのオブジェクトの 1 つに遭遇した場合にのみ、適切なスレッド内でバッファ オブジェクト バインディング、テクスチャ バインディング、およびシェーダ コンパイルを実行します。コードの最初ですべてのシェーダーをコンパイルすることは避けたいと思います。シェーダー ソースは、マテリアル、モデル、およびシーンの要件に応じて組み立てられます (例: マテリアル: バンプ マッピングを含む、モデル: マトリックス パレット スキミングを含む、シーン: フォグを含む)。モデルがシーンから削除されたら、シェーダーをもう一度削除します。別のモデルを追加すると、

現時点では、コードを掲載せずにできるだけ簡潔にしようとしています。このライブラリから関連部分を抽出するのは難しいことは想像に難くないでしょう。

4

2 に答える 2

2

レンダリング中にコンパイルすることは完全に有効ですが、ドライバーはそのためにリソース(CPU)を使用する必要があるため推奨されません。一部の状態はシェーダーに注入されるため、一部のドライバーは、ドライバー側でシェーダーの再コンパイルをトリガーすると述べています。描画呼び出しを同じドライバー状態を共有するチャンクに再編成することをお勧めします(ドライバーによって実行される最もコストのかかる操作の1つであるため、シェーダープログラムによって推奨されます)。

ヒント:シェーダーに宣言されているすべての変数、ユニフォーム、および属性を必ず「使用」してください。そうしないと、Maliドライバーがコンパイル中にそれらを削除し、ユニフォームの場所、属性の場所、および息子を取得しようとすると、ドライバーはGL_INVALID_VALUEを返します。

お役に立てば幸いです。

于 2013-01-22T15:47:27.203 に答える
0

Android開発キットに付属のBasicGLSurfaceViewサンプルコードをコピーしてプロジェクトを開始する場合は、最初に

checkGlError

頂点シェーダーをアタッチした後です。ただし、無効な値を使用したか、コード内のかなり前または別の場所で列挙した可能性があります。ただし、これは、glAttachShaderの後、この呼び出しによってのみ取得されます。

私の場合、フレームバッファのレンダリングターゲットとしてリンクされているテクスチャを削除しました。動作が遅い古いAndroidデバイスは、削除する前にシェーダーをコンパイルしましたが、新しいデバイスはなんとか呼び出しました

glFramebufferTexture2D

シェーダーをコンパイルする前に。全体がどういうわけかqueueEventとスレッドセーフの私の不十分な理解にリンクしています。

TraxNetとPrateekNinaの皆さんの努力に感謝します。

于 2013-01-26T14:54:45.563 に答える