我正在玩一些 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 传递给我的常量缓冲区?
如果无论如何这是一个愚蠢的想法,应该以其他方式完成,请告诉我。这是我第一次编写与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);
}
提前致谢