1

ユニフォーム バッファ オブジェクト (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 シェーダーであり、ラベルが異なることです。

たとえそれが完全に異なることを意味するとしても、どんな方法でも大歓迎です。情報を省略した場合はお詫びし、リクエストに応じて追加しようとします。

4

1 に答える 1

0

均一なオブジェクトを作成するためのすべての方法は何ですか?

「均一な物体」というものはありません。均一なデータを格納するために使用できるバッファオブジェクトのみがあります。また、頂点データ、ピクセルデータ、およびその他のさまざまなものを格納するために使用することもできます。しかし、それらはすべて同じオブジェクトタイプです:バッファオブジェクト。そして、あなたはそれらをすべて同じ方法で作成します。

バッファオブジェクトにデータを提供する方法はかなり簡単です。glBuffer(Sub)Data、およびglMapBuffer(Range)。問題は、ネイティブAPIではないC#ほどのインターフェイスではありません。したがって、データをアップロードするには、フープを飛び越える必要があります。

正直なところ、バッファオブジェクトデータのアップロードを処理するためのインターフェイスとして、小さなC ++/CLIを使用することをお勧めします。管理対象オブジェクトよりもネイティブオブジェクトのデータを処理する方が簡単で冗長性が低くなります。

于 2011-08-15T06:50:05.937 に答える