2

まず、「キー」パターンが一般的なパターンとして受け入れられているかどうかはわかりませんが、最近SOに何らかの形で出現しているので...

私がしたいこと?

C++ でシェーダー操作クラスを作成します。ここでの私の問題は、特に均一な値 (C++ から GLSL に「直接」送信される値) の設定に焦点を当てています。

どうしたの?

(OpenGL に慣れていない人も貢献できるように簡単な説明) - ユニフォーム変数は、グローバルglUniform*関数を使用して設定され、最初のパラメーターとして、現在バインドされているシェーダー ( int) 内のユニフォームの場所を取得します。

したがって、一般的な使用法は次のとおりです。

glBindProgram(myProgramNum);
int Location = glGetUniformLocation(myProgramNum, "myUniformParameterName");
float myValue = 42.f; // arbitrary data
glUniform1f (Location, myValue);

上記をカプセル化するために必要ないくつかのメソッドを作成しました。

void SetUniform1f (std::string const& name, float a);
void SetUniformVector3 (std::string const& name, CVector3 const& vec);
void SetUniformMatrix4 (std::string const& name, CMatrix4 const& mat);

ただし、これらすべてがglGetUniformLocation(int, const char*). それらの一部はリアルタイムで使用されるため、不要なパフォーマンス オーバーヘッドが発生します。

最初のアイデア

私は、各関数の 2 つのバージョンを作成できると考えましstd::stringint

ただし、ユーザーが悪意のあるパラメーターを送信できるため、純粋な OpenGL アクセスよりも優れたものにはなりません。

2つ目のアイデア

したがって、適切な方法は、特定のユニフォームの場所を含む、シェーダー クラスからある種の「キー」オブジェクトを生成することです。ただし、特定の CShader クラス インスタンスにリンクする必要があります。これは、あるオブジェクトでキーを生成して別のオブジェクトに渡し、望ましくない動作を引き起こす可能性があるためです。

私の質問は、C++ でこのようなことは可能ですか? キーオブジェクトの「親」オブジェクトへのポインターを保持し、それが有効なパラメーターであるかどうかを毎回テストする必要がありますか?

私が推測できたのは、キークラスを CShader にネストし、CShader をフレンドにする必要があるということです。また、コピーされたオブジェクトが引き続き有効なキーになるように、自明なコンストラクターをプライベートに宣言し、コピーコンストラクターをオーバーロードする必要があります。

4

1 に答える 1

2

一様変数を設定するには、整数のみが必要です。実際、一連の を呼び出す代わりに、glGetUniformLocationこれらの値を にキャッシュしないのはなぜstd::map<std::string, int>ですか? をクエリしたmapほうが速いですね。

あなたの質問ではすべてが明確ではありませんが (親ポインタ?、悪意のある値?)、最後に、CShaderクラスの架空のユーザーは、均一な値を設定するためのショートカットを望んでいます。実際、シェーダー リンケージの後にユニフォームをクエリすることも ( glGetActiveUniformを使用)、必要に応じてユニフォームをクエリしてユニフォームの場所をキャッシュすることもできます。

于 2012-06-10T22:42:53.890 に答える