编组C#结构体进入DX11 cbuffers [英] Marshalling C# Structs into DX11 cbuffers

查看:214
本文介绍了编组C#结构体进入DX11 cbuffers的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在与(我认为)的一些问题,我的结构的C#包装和传递他们通过cbuffers我已经注册的HLSL。当我在一个地收拾结构的信息似乎可以传递给着色器:

I'm having some issues with (i think) the packing of my structure in C# and passing them through to cbuffers i have registered in HLSL. When i pack my struct in one manner the information seems to be able to pass to the shader:

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

    [FieldOffset(12)]
    public int type;
}

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

When i create this struct and set it as my constant buffer in C# it seems to work just fine. I get what colours returned that i expect:

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;
}



但是,当我改变结构要使用另一个结构它似乎一个结构正确设置。需要注意的是内部结构将被包含在里面的额外信息,但我试图尽可能简化它现在:

But when i change the structure to be a struct using another struct it does seem to set properly. Note that internal struct is going to be containing extra information in it, but i was trying to simplify it as much as possible for now:

[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 '吨似乎工作。

Do you think there is a problem in the way i am packing my structs? Or could the issue be elsewhere, i only think it is my packing because i can get the first example to work when i set the constant buffer with a TestStruct, but as soon as i expand it to include the InternalTestStruct it doesn't seem to work.

任何帮助将是巨大的。

先谢谢了。

推荐答案

当你使用:

struct InternalType
{
    int type;
}

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



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

since InternalType is of size 4 it will pack into the layout of 16, so it's exactly the same as if you were just using an int.

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

To match the second c# structure using InternalTestStruct, you'd need to do:

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

如果你改变internaltype的大小大于一填充随后将成为自动(但它总是很高兴保持明确的)。

If you change internaltype to a size larger than one the padding will then become automatic (but it's always nice to keep it explicit).

这篇关于编组C#结构体进入DX11 cbuffers的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆