Unity-使用GetRawTextureData更改底层RGB字节而无需复制

时间:2019-04-05 12:08:50

标签: unity3d texture2d

我试图将OpenCV与Unity一起用于图像处理,并且试图使OpenCV和Unity代码之间的数据传输尽可能高效。

当前,我能够在C#中创建一个新的byte[],然后在OpenCV中将图像加载到这些字节中,然后使用texture.LoadRawTextureData(array)texture.Apply()在Unity中显示此纹理

但是,Unity文档建议使用texture.GetRawTextureData()获取对NativeArray的引用(返回byte[]的函数版本将复制原始数据),然后将数据直接写入此缓冲区(+调用Apply())。

不幸的是,NativeArrays上的文档非常稀缺-NativeArrays在内存中的外观如何?它们确实具有ToArray()函数,但这又会复制数据。我需要的是一个byte []数组,它可以是RGB24或RGBA32(似乎首选RGBA,因为即使纹理不透明,即使内存效率低下,现代GPU显然也不支持RGB24)。

是否可以在不进行复制和调用LoadRawTextureData()的情况下将指针传递到纹理中缓冲区的开头?还是Texture中的数据格式完全不同?

2 个答案:

答案 0 :(得分:0)

我对NativeArray感到困惑。看起来CopyTo()方法似乎没有分配内存。有一个ToArray()方法,我确定可以分配。

我能够设计出这种实用程序方法,对于网络摄像头供稿来说效果很好。

private byte[] m_byteCache = null;
public byte[] GetRawTextureData(Texture2D texture)
{
    NativeArray<byte> nativeByteArray = texture.GetRawTextureData<byte>();

    if (m_byteCache?.Length != nativeByteArray.Length)
    {
        m_byteCache = new byte[nativeByteArray.Length];
    }
    nativeByteArray.CopyTo(m_byteCache);

    return m_byteCache;
}

答案 1 :(得分:0)

ToArray()分配一个新数组。 CopyTo()不会分配内存,但它当然会复制数据。

但是我从文档中收集的是,您应该能够像访问普通数组一样访问NativeArray来修改内存,然后在相应的Texture对象上调用.Apply()。如果您可以使C#OpenCV代码写入其中,那应该可以解决问题。 NativeArray的问题是,我想您会直接获取代码所运行的任何实现的内存,因此确切的字节表示形式可能会因平台而异。同样,一旦纹理消失,内存将无效。