繁体   English   中英

我将如何创建更动态的统一着色器?

[英]How would I create a more dynamic uniform shader?

我正在尝试创建一个统一缓冲区 object (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 着色器,它与 label 不同。

任何方法都会受到赞赏,即使这意味着完全不同。 如果我遗漏了任何信息,我深表歉意,并会根据要求尝试添加。

有什么方法可以创建一个统一的 object?

没有“统一对象”这样的东西。 只有缓冲区对象,可用于存储统一数据。 它们还可用于存储顶点数据、像素数据和各种其他内容。 但它们都是相同的 object 类型:缓冲区 object。 你以同样的方式创建它们。

向缓冲区 object 提供数据的方法相当简单。 glBuffer(Sub)Data 和 glMapBuffer(Range)。 您的问题不在于接口,而是 C#,它不是本机 API。 所以你必须跳过箍来上传你的数据。

老实说,我建议使用一点 C++/CLI 作为处理缓冲区 object 数据上传的接口。 与托管对象相比,处理本机对象中的数据更容易且不那么冗长。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM