3

このトピックに関するスタック オーバーフローに関する多くの質問と回答をここで見てきました。これらの回答から、GLSL 属性をユーザー定義のセマンティクスにバインドする解決策を思いつきました。私はそれについていくつかの意見と議論を得て、それが有効なアイデアであるかどうかを確認したかったのです.

まず、ユーザー定義のセマンティクスのリストがあると仮定しましょう。

enum VertexElementSemantic
{
  POSITION, NORMAL, AMBIENT, DIFFUSE, SPECULAR,
  TEX_COORD0, TEX_COORD1, TEX_COORD2, TEX_COORD3,
  INDICES
};

また、頂点属性ポインターの設定に必要なデータをカプセル化する構造体。

struct VertexElement
{
  unsigned int m_source;
  unsigned int m_offset;
  unsigned int m_stride;
}

現在、一部の RenderOperation クラスには、VertexElementSemantics から VertexElements へのマップが含まれています。形式、サイズ、および VertexElement が正規化されているかどうかは、そのセマンティックによって決定できます。

このポインターを設定するために必要な最後の情報は、属性の場所そのものです。ここで、VertexElementSemantic を特定の場所にバインドします。

この質問に対する最初の回答から、次のように各属性の目的の場所を明示的に指定できることがわかります。

layout(location = 0) in vec3 position;

そのため、セマンティクスをこれらのハードコードされた場所にマッピングできますが、この場所を各シェーダーでハードコードする必要があります。これらの場所を変更するには、すべてのシェーダーを調べて編集する必要があります。

ただし、この値は Shader ソースによって提供される必要はまったくありません。この質問への回答から、次のように #defines をシェーダーに外部から追加できることがわかります。

char *sources[2] = { "#define FOO\n", sourceFromFile };
glShaderSourceARB(shader, 2, sources, NULL);

これを使用して、各セマンティックの目的の場所の変数を #defines する文字列を作成できます。たとえば、各シェーダーの先頭に次を挿入する文字列を作成できます。

#define POSITION_LOCATION 0
#define NORMAL_LOCATION 1
#define AMBIENT_LOCATION 2
...

属性の場所の明示的な記述に戻ると、次のように記述できるはずです。

layout(location = POSITION_LOCATION) in vec3 position;
layout(location = NORMAL_LOCATION) in vec3 normal;
layout(location = AMBIENT_LOCATION) in vec4 ambient;

このメソッドを使用すると、コード内の各セマンティックの目的の属性の場所を設定できます。また、シェーダー自体に一種のセマンティック バインディングの感覚を提供します。このようなシステムは、属性の場所に意味を与えるという問題を解決するための正しい方向への一歩ですか?

4

1 に答える 1