【问题标题】:Unity Hololens CrashesUnity Hololens 崩溃
【发布时间】:2018-05-01 01:15:26
【问题描述】:

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

d3d11:无法创建分段 2D 纹理 w=896 h=504 d3dfmt=87 [887a0005]

d3d11:未能锁定大小为 4194304 [0x8007000E] 的缓冲区 1104C69C。

DrawBuffers() 获得了一系列索引,但没有索引缓冲区(文件名: C:\buildslave\unity\build\Runtime/GfxDevice/d3d11/DrawBuffersD3D11.cpp 线路:137)

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


我在做什么以及我改变了什么

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

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

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

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

所以我的下一步是在处理函数开始时克隆该数组,这样我就可以处理这个新数组并将其应用于纹理,而不会受到来自相机的新数据的干扰.

所以我做到了:

 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:无法创建分段 2D 纹理 w=896 h=504 d3dfmt=87 [887a0005]

意味着无法创建Texture2D,但为什么呢?我的纹理只在视频模式初始化时创建一次,所以我不明白为什么会发生这种情况。

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

【问题讨论】:

  • 我确信 .Clone() 会返回一个浅拷贝的数组,即使包含的对象是值类型。可能是 rawimage 被操纵或处置,然后导致其副本出现问题。你可以考虑做一个深拷贝。我不是 100% 因此发表评论 ;-)

标签: c# unity3d crash hololens


【解决方案1】:

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

我建议的另一件事是:方法应该有单一的责任(返回已处理的数组)。然后应将生成的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 的扩展,它会创建一个副本。如果您愿意,可以使用other ways 复制数组。

希望这会有所帮助:)

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多