3

我有以下代码来实例化一个常量缓冲区并将其绑定到像素着色器。ConstantBuffers.EveryFrame 是 ConstantBuffers 类中的一个结构,它包含我需要在每帧基础上更新的所有数据(当前只有一个 Color3 对象)。

everyFrame 是一个 Direct3D11 缓冲区对象,我将其用作常量缓冲区。上下文是我的 D3DDevice.ImmediateContext

int sizeInBytes;
ConstantBuffers.EveryFrame cb1 = new ConstantBuffers.EveryFrame();
cb1.Color = new Color3(0, 0, 0);
sizeInBytes = Marshal.SizeOf(typeof(ConstantBuffers.EveryFrame));
using (DataStream data = new DataStream(sizeInBytes, true, true))
{
    data.Write(cb1);
    data.Position = 0;
    everyFrame = new D3D.Buffer(device, data, new BufferDescription
    {
        Usage = ResourceUsage.Default,
        SizeInBytes = sizeInBytes,
        BindFlags = BindFlags.ConstantBuffer
    });
    context.PixelShader.SetConstantBuffer(everyFrame, 0);
}

当我运行此代码时,我收到以下错误:

SlimDX.Direct3D11.Direct3D11Exception was unhandled
  Message=E_INVALIDARG: An invalid parameter was passed to the returning function (-2147024809)
  Source=SlimDX
  StackTrace:
   at SlimDX.Result.Throw[T](Object dataKey, Object dataValue)
   at SlimDX.Result.Record[T](Int32 hr, Boolean failed, Object dataKey, Object dataValue)
   at SlimDX.Direct3D11.Buffer.Build(Device device, DataStream data, Int32 sizeInBytes, ResourceUsage usage, BindFlags bindFlags, CpuAccessFlags accessFlags, ResourceOptionFlags optionFlags, Int32 structureByteStride)
   at SlimDX.Direct3D11.Buffer..ctor(Device device, DataStream data, BufferDescription description)
   at VoxelGame.Form1.SetupConstantBuffers() in d:\files\my documents\visual studio 2010\Projects\VoxelGame\VoxelGame\Form1.cs:line 119
   at VoxelGame.Form1..ctor() in d:\files\my documents\visual studio 2010\Projects\VoxelGame\VoxelGame\Form1.cs:line 91
   at VoxelGame.Program.Main() in d:\files\my documents\visual studio 2010\Projects\VoxelGame\VoxelGame\Program.cs:line 21
   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

但是,当下面的代码运行时(在上面的代码之前只有几个调用)它工作正常。这段代码没有触及上面代码使用的任何变量,并且大多在单独的类中运行(设备通过类的构造函数传入,constantBuffer 是存储在类变量中的 Direct3D11 Buffer)

ConstantBuffers.EveryMotion cb2 = new ConstantBuffers.EveryMotion();
int sizeInBytes = Marshal.SizeOf(typeof(ConstantBuffers.EveryMotion));
using (DataStream data = new DataStream(sizeInBytes, true, true))
{
    data.Write(cb2);
    data.Position = 0;
    constantBuffer = new D3D.Buffer(device, data, new BufferDescription
    {
        Usage = ResourceUsage.Default,
        SizeInBytes = sizeInBytes,
        BindFlags = BindFlags.ConstantBuffer
    });
    device.ImmediateContext.VertexShader.SetConstantBuffer(constantBuffer, 0);
}

供参考的是 ConstantBuffer 结构

[StructLayout(LayoutKind.Sequential)]
public struct EveryMotion
{
    public Matrix WorldViewProjection;
}

[StructLayout(LayoutKind.Sequential)]
public struct EveryFrame
{
    public Color3 Color;
}
4

1 回答 1

6

常量缓冲区需要它们的数据正确对齐;SizeInBytes 属性需要是 16 的倍数,这是 Matrix (4*4*4) 的情况,但不是 Color3 (4*3) 的情况。

于 2011-03-01T18:49:33.813 回答