C# 尝试将带有Vector4数组的结构传递给cbuffer

C# 尝试将带有Vector4数组的结构传递给cbuffer,c#,slimdx,C#,Slimdx,我正在使用SlimDX(使用DX10/11),到目前为止我得到了一些不错的结果,但我一直在将向量数组传递给着色器 如果我尝试以下结构: [StructLayout(LayoutKind.Sequential)] public struct PerFrameBuffer { public Vector4 Position; public Matrix World; public Matrix V

我正在使用SlimDX(使用DX10/11),到目前为止我得到了一些不错的结果,但我一直在将向量数组传递给着色器

如果我尝试以下结构:

[StructLayout(LayoutKind.Sequential)]
        public struct PerFrameBuffer
        {
            public Vector4 Position;
            public Matrix World;
            public Matrix View;
            public Matrix Projection;

            [MarshalAs( UnmanagedType.ByValArray, SizeConst=2)]
            public Vector4[] Lights;
        }
并尝试将其存储在以下cbuffer中:

cbuffer cPerFrame : register( b0 )
{

    float4 xPosition;
    matrix xWorld;
    matrix xView;
    matrix xProjection;

    float4 pointLights[2];
}
我没有得到任何错误,但是矩阵中的值被破坏了

但是,当我在c#中声明我的结构时,如下所示:

[StructLayout(LayoutKind.Sequential)]
        public struct PerFrameBuffer
        {
            public Vector4 Position;
            public Matrix World;
            public Matrix View;
            public Matrix Projection;
            public Vector4 Light1;
            public Vector4 Light2;
        }
然后一切正常

我真的不想在结构中创建64个字段并像那样填充它们(我可以使用反射,但仍然如此)。如何使用数组将矢量4传递给我的constantbuffer

如果这是一个愚蠢的想法,应该用另一种方式来做,请让我知道。这是我第一次编程directx和着色器相关的东西

待完成:

用C语言声明缓冲区#

如何更新缓冲区:

var cb = new AbstractDXManager.PerFrameBuffer()
   {
       Position = new Vector4(camera.Position, 1.0f),
       Projection = Matrix.Transpose(camera.ProjectionMatrix),
       View = Matrix.Transpose(camera.ViewMatrix),
       World = Matrix.Transpose(Matrix.Identity),

   };
   cb.Lights = new Vector4[2];
   cb.Lights[0] = cb.Position;
   cb.Lights[1] = new Vector4(20, 20, 20, 1);
   var context = device.ImmediateContext;

   using (DataStream data = new DataStream(Marshal.SizeOf(typeof(PerFrameBuffer)), true, true))
   {
       data.Write(cb);
       data.Position = 0;
       context.UpdateSubresource(new DataBox(0, 0, data), cPerFrameBuffer, 0);
   }

提前谢谢

我也有同样的问题。我改了写缓冲区。现在它起作用了

这是我的结构

[StructLayout(LayoutKind.Sequential,Pack=1)]
public struct WorldConstants
{
    public Matrix View;
    public Matrix Projection;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public Color4 [] DiffuseColor;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public Color4[] AmbientColor;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public Vector4[] LightDirection;
    public Vector4 ViewPosition;
}
我使用StructToPtr来获取所有的数据

        using (DataStream stream = new DataStream(streamSize, true, true))
        {
            int rawsize = Marshal.SizeOf(typeof(ElementT));
            IntPtr buffer = Marshal.AllocHGlobal(rawsize);
            foreach (var element in elements)
            {
                Marshal.StructureToPtr(element, buffer, false);
                stream.WriteRange(buffer,rawsize);
            }
            Marshal.FreeHGlobal(buffer);

不幸的是,这会导致额外的数据副本。在我的例子中,我没有注意到任何性能问题。

我后来通过将单个字段写入数据流而不是一次写入整个结构来解决它。当我这样做时,我可以很容易地为数组字段使用for循环。(完全忘记了这个问题)。
        using (DataStream stream = new DataStream(streamSize, true, true))
        {
            int rawsize = Marshal.SizeOf(typeof(ElementT));
            IntPtr buffer = Marshal.AllocHGlobal(rawsize);
            foreach (var element in elements)
            {
                Marshal.StructureToPtr(element, buffer, false);
                stream.WriteRange(buffer,rawsize);
            }
            Marshal.FreeHGlobal(buffer);