2017-04-11 15 views
0

すでにコンパイル済みのglslシェーダプログラムでuniformパラメータのサイズを取得しようとしています。私は既定の型のユニフォームのためだけにそれを行ういくつかの関数を見つけました。しかし、カスタムタイプの統一されたパラメータのためにそれを行う方法はありますか?例えばC++コードからコンパイルされたglsl shader uniformパラメータのサイズを取得する

:私はあなたの最終目標は、基本的にspheres.lengthであることを仮定しているとの結果が10である

struct Sphere 
{ 
    vec3 position; 
    float raduis; 
}; 

#define SPHERES 10 
uniform Sphere spheres[SPHERES]; 

答えて

1

シェーダのコンパイル後にサイズを変更することができないため、最適な方法は、その長さを別の場所に保存することです。


配列の長さを取得する簡単な方法はありません。配列自体は存在しないためです。コンパイルすると、配列の各要素(および構造体の各要素)は、それぞれ独自の統一になります。行うことの必要性によって明らかである:

glGetUniformLocation(program, "spheres[4].position") 

事はあなたのシェーダがだけにしてspheres[4].positionspheres[8].positionを使用している場合、他の全てのspheres[x].positionが存在しません離れため、最適化される可能性が高いということです。


どのようにして均一な配列の長さが得られますか?

glGetActiveUniform()と正規表現またはsscanf()を使用してこれを達成できます。そして、あなたが行うことができ、あなたが提供されていますどのように多くのspheres[x].positionチェックしたいと言う:

GLint count; 
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count); 

const GLsizei NAME_MAX_LENGTH = 64 

GLint location, size; 
GLenum type; 
GLchar name[NAME_MAX_LENGTH]; 
GLsizei nameLength; 

int index, charsRead; 

for (GLint i = 0; i < count; ++i) 
{ 
    glGetActiveUniform(program, (GLuint)i, NAME_MAX_LENGTH, &nameLength, &size, &type, name); 

    if (sscanf(name, "spheres[%d].position%n", &index, &charsRead) && (charsRead == nameLength)) 
    { 
     // Now we know spheres[index].position is available 
    } 
} 

あなたはさらにそれがどのデータタイプを把握するGL_FLOATまたはGL_FLOAT_VEC3typeを比較することができます。

int countを追加し、一致するたびに増分すると覚えておいてください。たとえ最後にcount3であっても。それは要素0, 1, 2が利用可能であるということを意味しません。それは容易に要素0, 5, 8であることができます。

その他の注意事項:

  • nameがNULL終端文字列
  • %nでは、文字の数はこれまでのところ、この大きな説明のための
+0

感謝を読んだが、私の質問は、サイズを取得する方法ですそれがユーザー定義の型を持っているならば、それはその名前で統一された変数を返します。申し訳ありませんが、私は最も難しい場合を示すためにそこに配列を追加しましたが、それは私の疑問を不明瞭にしました。したがって、ここではより簡単な統一宣言があります:「均一な球体」と、私のC++コードから「球体」のサイズを取得したいのです。 –

+1

私の答えはすでにそれをカバー? 'type'を使用してください。というのは、それ自体には球体[i]がないので、sizeof(球体[i])は存在しないということです。個々の要素のみがそれぞれユニフォームにマップされます。だからあなたはすべての球[i]を調べなければなりません。その後、そのタイプをチェックして、最終的なサイズを確定することができます。したがって、配列の最終サイズをチェックしたい場合、すべての 'sphere。*'をチェックする必要があります。 – Vallentin

関連する問題