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

发布于 2024-11-29 08:05:54 字数 2234 浏览 0 评论 0原文

我正在尝试创建一个统一的缓冲区对象(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 实际上是统一着色器,并且标签不同。

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

I'm trying to create a uniform buffer object (UBO), and I need to fill the array with uniforms. The way I am currently doing it is with a hard coded structure.

[Serializable,StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct MaterialBlock
        {
            private Vector4 uniform;
        };

Then I use Marshaling to get the byte array from that structure, and I fill my UBO with that array.

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);


        }

I was wondering if there was a more dynamic way to hold the uniform information, without having to use System.Reflection to create the structure on demand. When I did the fragment and vertex shaders I was able to use a string, and then GL.CreateShader() and GL.ShaderSource. The only thin I can think of is that ShaderType.GeometryShader is actually the Uniform shader and it is label differently.

Any methods would be appreciated, even if it means doing it completely different. If I have left out any information, I apologise, and will try to add it on request.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

焚却相思 2024-12-06 08:05:54

创建统一对象的方法有哪些?

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

向缓冲区对象提供数据的方法相当简单。 glBuffer(Sub)数据和glMapBuffer(Range)。您的问题不在于接口,而在于 C#,它不是本机 API。因此,您必须克服重重困难才能上传数据。

老实说,我建议使用一点 C++/CLI 作为处理缓冲区对象数据上传的接口。处理本机对象中的数据比处理托管对象中的数据更容易、更简洁。

What are all the ways to create a uniform object?

There is no such thing as a "uniform object". There are only buffer objects, which can be used to store uniform data. They can also be used to store vertex data, pixel data, and various other stuff. But they're all the same object type: buffer object. And you create them all the same way.

The ways to supply data to a buffer object are fairly simple. glBuffer(Sub)Data, and glMapBuffer(Range). Your problem isn't with the interface so much as C#, which is not a native API. So you have to jump through hoops to upload your data.

Honestly, I would suggest using a little C++/CLI as an interface for handling your buffer object data uploading. It easier and less verbose to deal with data in native objects than in managed ones.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文