我正在使用SlimDX(使用DX10 / 11),到目前为止我得到了一些不错的结果,但我坚持将一个Vector4s数组传递给着色器。
如果我尝试以下结构:
[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个字段并将其填充(我可以使用反射但仍然可以)。如何使用数组将Vector4传递给我的constantbuffer?
如果无论如何这是一个愚蠢的想法,应该以另一种方式完成,请告诉我。这是我第一次编写directx和着色器相关的东西。
完成:
C#中的缓冲区声明
cPerFrameBuffer = new SlimDX.Direct3D11.Buffer(device, new BufferDescription
{
Usage = ResourceUsage.Default,
SizeInBytes = Marshal.SizeOf(typeof(PerFrameBuffer)),
BindFlags = BindFlags.ConstantBuffer
});
context.VertexShader.SetConstantBuffer(cPerFrameBuffer, 0);
我如何更新缓冲区:
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);
}
提前致谢
答案 0 :(得分:1)
我遇到了同样的问题。我改变了缓冲区写作。现在它可以工作
这是我的结构
[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);
不幸的是,这会导致数据的额外副本。就我而言,我没有注意到任何性能问题。