ユニフォーム名の最大長が必要です。uniform test
つまり、ユニフォームとを使用した使用済みプログラムを指定するとuniform myuniform
、glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, outParam)
10の出力が得られるはずです(「myuniform」の場合)。
1つの定義されたユニフォームでセットアップされた非常に単純なテストシェーダーがあります。uniform float time
glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, outParam)
の長さである5を返しますtime
。「time」を別のものに変更すると、変更された長さが返されます(例:「timer」に変更すると6が返されます)。
glGetProgramiv
とGL_ACTIVE_UNIFORMS
は、2つのユニフォームがあることを教えてくれます。レポートしている2番目のユニフォームはgl_ModelViewProjectionMatrixです。
リストにgl_ModelViewProjectionMatrixを含めても問題ありません。シェーダーで使用していますが、他の戻り値と組み合わせると問題が発生します。「gl_ModelViewProjectionMatrix」がリストに含まれている場合、glGetProgramivが「gl_ModelViewProjectionMatrix」の長さを返さないのはなぜですか?アプリケーションの属性と変数のフルネームが必要ですが、最大長が5になっているため、glGetActiveUniform
「gl_M」という統一された名前が返されます。これは受け入れられません。
名前の最大長にMVPマトリックスを含めるか、名前のリストに含めないでください。リストに名前を含めることは意味がありませんが、名前の最大長の計算には含めません。
これは私だけに起こっているのですか?グーグルを使ってそれについて他に何も見つけることができませんでした。最大長のクエリを放棄し、常に非常に大きなバッファを使用することもできますが、以前に非常に長い変数名をいくつか見たことがあるため、エラーが発生しないようにするには、バッファを大きくする必要があります。とにかく、それは本当の修正ではありません。
このテストは、属性に対して正しく機能しています。私はgl_Vertexを使用しており、他の属性はありません。システムは、長さが10で名前がgl_Vertexの1つの現在の属性を正しく報告します。時間ユニフォームを完全に削除すると、MVPマトリックスが唯一の使用済みユニフォームとして残り、システムは1つの現在のユニフォーム、最大名の長さ0を報告するため、返された最大長で名前を取得しても何も得られません。
完全を期すために、以下のコードを含めます。コードはJavaであり、JOGLを使用してOpenGLバインディングにアクセスします。関連する領域を強調するために、この問題に関係のない行を削除しました。これは、ここで取得した値を実際に表示するGUI部分を含め、ほとんどがGUIの更新でした。上記のように、属性を取得する部分も正常に機能するため、削除しました。
Java主義に警戒しているCの人々のための参考までに:バッファ(、、IntBuffer
)をポインタのように、のように、そしてのように考えてByteBuffer
ください。私はCとC++でもOpenGLを使用しているので、ここのGLSLの達人がそれを好む場合は、これをCで書き直すことができます。FloatBuffer
buffer.get()
buffer[n++]
buffer = IntBuffer.allocate(n)
malloc()
助言がありますか?
// add options to panelShaderParameters
public void updateShaderParameters(GLAutoDrawable surface)
{
GL2 gl = surface.getGL().getGL2();
IntBuffer outParam = IntBuffer.allocate(1);
int numParameters = 0,
maxNameLength = 0;
IntBuffer size = null,
type = null;
ByteBuffer name = null;
gl.glGetProgramiv(shader.getName(), GL2.GL_ACTIVE_UNIFORMS, outParam);
numParameters = outParam.get();
outParam = IntBuffer.allocate(1);
gl.glGetProgramiv(shader.getName(), GL2.GL_ACTIVE_UNIFORM_MAX_LENGTH, outParam);
maxNameLength = outParam.get();
for(int i = 0; i < numParameters; i += 1)
{
size = IntBuffer.allocate(1);
type = IntBuffer.allocate(1);
name = ByteBuffer.allocate(maxNameLength);
gl.glGetActiveUniform(shader.getName(), i, maxNameLength, (IntBuffer)null, size, type, name);
byte[] nameBuffer = new byte[maxNameLength];
name.position(0);
name.get(nameBuffer);
}
}