gpt4 book ai didi

C# (Unity) 不同托管数组类型之间的快速复制

转载 作者:行者123 更新时间:2023-11-30 16:49:36 28 4
gpt4 key购买 nike

我有一个 byte[] 颜色,我需要通过 SetPixels(Color32[]) 将其传输到 Texture2D 对象。我想知道从 byte[] 创建 Color32[] 的最快方法是什么。由于每个 Color32 是 4 个字节(每个 channel 1 个字节),因此元素数量将是四分之一。

Array.CopyTo 不允许不同的对象数组类型。

根据我的阅读,托管代码似乎无法将 byte[] 重新解释为 Color32[] 并完全跳过复制。

这个 (Color32[] -> byte[]) 的反转 has a SO solution通过编码,但似乎涉及大量复制。

private static byte[] Color32ArrayToByteArray(Color32[] colors)
{
int length = 4 * colors.Length;
byte[] bytes = new byte[length];
IntPtr ptr = Marshal.AllocHGlobal(length); // unmanaged memory alloc
Marshal.StructureToPtr(colors, ptr, true); // memcpy 1
Marshal.Copy(ptr, bytes, 0, length); // memcpy 2
Marshal.FreeHGlobal(ptr);
return bytes;
}

就我而言,我正在使用:

 int length = bytes.Length;
IntPtr ptr = Marshal.AllocHGlobal(length); // unmanaged mem alloc
Marshal.Copy(bytes, 0, ptr, length); // memcpy 1
Marshal.PtrToStructure(ptr, colors); // memcpy 2
Marshal.FreeHGlobal(ptr);

但是,在执行 myTexture.SetPixels(colors) 后我没有看到纹理更新。仍在尝试找出原因。

无论如何,我是否必须执行 2 个内存副本才能在 C# 中完成此操作?好像很浪费。。我正在寻找 C# 中的联合来绕过副本。

最佳答案

这是我学到的:

1) 无需编码黑白托管和非托管内存即可将 byte[] 转换为 Color32[],反之亦然。相反,在 C# 中使用联合:

[StructLayout(LayoutKind.Explicit)]
public struct Color32Bytes
{
[FieldOffset(0)]
public byte[] byteArray;

[FieldOffset(0)]
public Color32[] colors;
}

Color32Bytes data = new Color32Bytes();
data.byteArray = new byte[width * height * bytesPerPixel];
data.colors = new Color32[width * height];

现在,如果您使用来自相机的数据更新 byteArray,您可以使用 myTexture.SetPixels(data.colors) 将其应用于 Texture2D

不涉及复制。

2) 不需要上面的联合解决方案。哈哈。作为NineBerry指出,您可以通过以下方式将原始字节缓冲区上传到纹理myTexture.LoadRawTextureData(bytes);

这对我来说是完美的,因为我的相机字节缓冲区是 BGRA(从低到高),我需要在上传之前调整 channel (昂贵)或者如果我使用 (1)

3) Unity 中的 SetPixels 方法在低端系统上可能开销很大。我没有深入挖掘,但我怀疑这是因为在引擎盖下创建的 D3D 纹理使用 D3D_USAGE_DEFAULT ,这意味着更新它们必须使用 UpdateSubresource这会导致驱动程序复制和可能的停顿(无法更新 GPU 当前正在使用的资源)。

因此,理想的解决方案是编写一个原生插件,使用 D3D_USAGE_DYNAMIC 创建 2D 纹理,对其进行映射-更新-取消映射,然后将该引用传递回 Unity。现在有点矫枉过正,但我​​稍后可能会重新讨论这个问题。

关于C# (Unity) 不同托管数组类型之间的快速复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36438710/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com