ユニフォーム バッファ オブジェクト (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 が実際には Uniform シェーダーであり、ラベルが異なることです。
たとえそれが完全に異なることを意味するとしても、どんな方法でも大歓迎です。情報を省略した場合はお詫びし、リクエストに応じて追加しようとします。