Unity Hololens 崩溃

Unity Hololens Crashes

我正在编写一个应用程序,该应用程序使用 Unity 和 Hololens 的相机。它工作正常。然后我改变了一些东西(稍后解释)并且在崩溃后得到以下错误:

d3d11: failed to create staging 2D texture w=896 h=504 d3dfmt=87 [887a0005]

d3d11: failed to lock buffer 1104C69C of size 4194304 [0x8007000E].

DrawBuffers() got a range of indices but no index buffer (Filename: C:\buildslave\unity\build\Runtime/GfxDevice/d3d11/DrawBuffersD3D11.cpp Line: 137)

我已经搜索了这些错误,但没有适用的解决方案。我希望我能对此有所了解。


我在做什么,我改变了什么

基本上程序以字节数组的形式从相机获取帧 byte[] _latestImage;
最初此图像应用于纹理,如

_videoTexture.LoadRawTextureData(_latestImage);
_videoTexture.wrapMode = TextureWrapMode.Clamp;
_videoTexture.Apply();
_videoPanelUIRenderer.sharedMaterial.SetTexture("_MainTex", _videoTexture);

其中 _videoTexture 是 Texture2D,_videoPanelUIRenderer 是渲染器。

这行得通。然后我在函数 ProcessSync 中处理数组 _latestImage 以将其转换为 Gray。这也适用于唯一的问题:由于数组正在处理(变成灰色)但是 also 正在由相机自动更新,当应用于纹理时,它会闪烁,有时会变成灰色,有时是彩色的。但除此之外,没有崩溃。

所以我的下一步是 Clone 处理函数开始时的那个数组,这样我就可以处理这个新数组并将它应用到纹理上,而不会受到 new 的干扰来自相机的数据。

所以我做到了:

 void ProcessSync(byte[] rawimage, Matrix4x4 cTwMatrix, Matrix4x4 pMatrix)
    {
        int rr, gg, bb;
        int p = 0;
        int yval;
        byte[] image=(byte[])rawimage.Clone();//<--THIS is the only change

        for (int y = 0; y < height; y++)
            for (int x = 0; x < width; x++)
              { //...some processing here
               }

       //Then apply it to the texture like indicated above
}

当我应用它时,应用程序工作正常,我可以看到我得到的是灰色图像...但一段时间后它崩溃并显示上面的消息。

我的图片是 896x504 所以我猜

d3d11: failed to create staging 2D texture w=896 h=504 d3dfmt=87 [887a0005]

意味着 Texture2D 以某种方式创建失败,但为什么呢?我的纹理只在视频模式初始化时创建一次,所以我不明白为什么会这样。

我猜错误可能与我克隆图像有关。有人能帮我一下吗?

正如@Equalsk 在评论中提到的,原始数组可能会被重用(考虑到 Array 是引用类型)。您可以做的一件事是在传入 ProcessSync() 之前创建数组的副本,不让原始指针在方法中被使用。

还有一件事我会建议:方法应该有单一的职责(return 处理过的数组)。然后应将生成的 byte[] 应用于纹理。

byte[] ProcessSync(byte[] image, Matrix4x4 cTwMatrix, Matrix4x4 pMatrix)
{
    int rr, gg, bb;
    int p = 0;
    int yval;

    for (int y = 0; y < height; y++)
        for (int x = 0; x < width; x++)
          { //...some processing here
           }
    return image;
}

然后按如下方式使用:

var image = ProcessSync(_latestImage.ToArray(),_cTwCatrix, _pMatrix);

_videoTexture.LoadRawTextureData(image);
_videoTexture.wrapMode = TextureWrapMode.Clamp;
_videoTexture.Apply();
_videoPanelUIRenderer.sharedMaterial.SetTexture("_MainTex", _videoTexture);

注意:ToArray()System.Linq 的扩展,它创建了一个副本。如果您愿意,可以使用 复制数组。

希望这对您有所帮助:)