私は均一なバッファオブジェクト(UBO)を作成しようとしていますが、私はユニフォームで配列を埋める必要があります。私が現在やっているのは、ハードコーディングされた構造です。よりダイナミックな均一シェーダを作成するにはどうすればよいですか?
[Serializable,StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MaterialBlock
{
private Vector4 uniform;
};
次に、構造体からバイト配列を取得するためにマーシャリングを使用し、その配列でUBOを埋めます。
public void SetUniformShader(MaterialBlock block, int count) {
int maxSizeMaterialUniformBuffer;
int sizeMaterialBlock = Marshal.SizeOf(typeof (MaterialBlock));
int sizeUniformInstance = sizeMaterialBlock*count;
int uniformInstancesPerBlock;
int numberOfBlocks;
int activeUniformBlocks;
byte[] mtlBuffer;
int uniformBlockIndex;
GL.GetActiveUniformBlock(ProgramId, 0, ActiveUniformBlockParameter.UniformBlockBinding,
out uniformBlockIndex);
GL.GetProgram(ProgramId, ProgramParameter.ActiveUniformBlocks, out activeUniformBlocks);
GL.GetInteger(GetPName.MaxUniformBlockSize, out maxSizeMaterialUniformBuffer);
uniformInstancesPerBlock = maxSizeMaterialUniformBuffer/sizeMaterialBlock;
numberOfBlocks =
(int) Math.Ceiling(((double) sizeUniformInstance/uniformInstancesPerBlock*sizeMaterialBlock));
mtlBuffer = new byte[maxSizeMaterialUniformBuffer];
IntPtr buffer = Marshal.AllocHGlobal(sizeMaterialBlock);
Marshal.StructureToPtr(block, buffer, false);
for (int i = 0; i < uniformInstancesPerBlock; i++) {
Marshal.Copy(buffer, mtlBuffer, i*sizeMaterialBlock, sizeMaterialBlock);
}
Marshal.FreeHGlobal(buffer);
GL.GenBuffers(1, out _iUniform);
GL.BindBuffer(BufferTarget.UniformBuffer, _iUniform);
GL.BufferData(BufferTarget.UniformBuffer, new IntPtr(sizeMaterialBlock), mtlBuffer,
BufferUsageHint.DynamicDraw);
}
オンデマンド構造を作成するするSystem.Reflectionを使用することなく、均一な情報を保持するために、より動的な方法があった場合、私は思っていました。フラグメントと頂点シェーダを実行したときに、文字列を使用してからGL.CreateShader()とGL.ShaderSourceを使用できました。 ShaderType.GeometryShaderは実際には統一シェーダであり、ラベルは異なっています。
完全に異なることを意味していても、どのような方法でも理解できます。私が何らかの情報を残しておけば、謝罪し、要請に応じて追加しようとします。
私はこの質問で多くのことを混乱しています。 glBindBufferでバッファオブジェクトをバインドする前にglBufferDataを呼び出す方法がわかりません。あなたのコードの後のテキストは、シェーダーの作成について語っていますが、それは統一ブロックとはほとんど関係がありません。結局のところ、OpenGLはCとC++用に設計されており、C#では管理されていませんでした。これは非常に低レベルのAPIなので、その多くの部分でC#の自然ではない相互作用が必要になります。 –
glBindBuffer/BufferDataのミックスアップは、私の間違いです。私はもっと良い質問があると思います。「均一なオブジェクトを作成するにはどうすればよいのですか?」私はそのハードコーディングされた構造を持つ必要はありません。 (バッファ/バインドミックスアップを反映するために提供されたコードを変更する)。 – Zaneo
"ShaderType.GeometryShaderは実際には統一シェーダです"、そうですか?どう言う意味ですか?いいえ、ジオメトリシェーダは、統一シェーダの別の用語ではありません。とにかく均一シェーダは何ですか? –