开发者

How would I create a more dynamic uniform shader?

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);
       开发者_Go百科     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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜