2011-11-16 42 views
3

我遇到了一些问题(我认为)在C#中打包我的结构并将它们传递给我在HLSL中注册的cbuffers。当我在一个地收拾我的结构信息,似乎能够传递到shader:编组C#构造成DX11缓冲区

[StructLayout(LayoutKind.Explicit, Size = 16)] 
internal struct TestStruct 
{ 
    [FieldOffset(0)] 
    public Vector3 mEyePosition; 

    [FieldOffset(12)] 
    public int type; 
} 

当我创建这个结构并将其设置为在C#中我不断缓冲它似乎工作得很好。我得到了什么颜色回到我想到:

cbuffer PerFrame : register(b0) 
{ 
    Vector3 eyePos; 
    int type; 
} 

float3 GetColour() 
{ 
    float3 returnColour = float(0.0f, 0.0f, 0.0f); 

    switch(type) 
    { 
     case 0: 
      returnColour = float3(1.0f, 0.0f, 0.0f); 
      break; 
     case 1: 
      returnColour = float3(0.0f, 1.0f, 0.0f); 
      break; 
     case 2: 
      returnColour = float3(0.0f, 0.0f, 1.0f); 
      break; 
    } 

    return returnColour; 
} 

但是,当我改变结构是使用其他结构的结构体,它确实正确。需要注意的是内部结构将被包含在它的额外信息,但我试图尽可能简化它现在:

[StructLayout(Layout.Explicit, Size = 16)] //Note this is 16 because HLSL packs in 4 float 'chunks' 
internal struct InternalTestStruct 
{ 
    [FieldOffset(0)] 
    public int type; 
} 

[StructLayout(LayoutKind.Explicit, Size = 32)] 
internal struct TestStruct 
{ 
    [FieldOffset(0)] 
    public Vector3 mEyePosition; 

    //Missing 4 bytes here for correct packing. 

    [FieldOffset(16)] 
    public InternalTestStruct internal; 
} 

而在HLSL

struct InternalType 
{ 
    int type; 
} 

cbuffer PerFrame : register(b0) 
{ 
    Vector3 eyePos; 
    InternalType internalStruct; 
} 

float3 GetColour() 
{ 
    float3 returnColour = float(0.0f, 0.0f, 0.0f); 

    switch(internaltype.type) 
    { 
     case 0: 
      returnColour = float3(1.0f, 0.0f, 0.0f); 
      break; 
     case 1: 
      returnColour = float3(0.0f, 1.0f, 0.0f); 
      break; 
     case 2: 
      returnColour = float3(0.0f, 0.0f, 1.0f); 
      break; 
    } 

    return returnColour; 
} 

你觉得有我打包结构的方式有问题吗? 或者问题可以在其他地方,我只认为它是我的包装,因为我可以得到的第一个例子工作时,我设置恒定的缓冲区与TestStruct,但只要我扩大它包括InternalTestStruct它不似乎上班。

任何帮助将是伟大的。

在此先感谢。

回答

0

当你使用:

struct InternalType 
{ 
    int type; 
} 

cbuffer PerFrame : register(b0) 
{ 
    float3 eyePos; 
    InternalType internalStruct; 
} 

因为InternalType是大小为4的将装入16的布局,所以,如果你只是用一个int是完全一样的。

要符合使用InternalTestStruct第二个C#结构,你需要做的:

cbuffer PerFrame : register(b0) 
{ 
    float3 eyePos; 
    int dummy; //Here you need to force the padding 
    InternalType internalStruct; 
} 

如果更改internaltype的大小大于一则填充将成为自动的(但它总是很高兴,以保持它明确)。