代码之家  ›  专栏  ›  技术社区  ›  Kamil Szot

有没有办法检查Texture2D当前是否未使用,以便我可以对其执行SetData()?

  •  0
  • Kamil Szot  · 技术社区  · 14 年前

    尝试对最近由SpriteBatch绘制的Texture2D执行SetData()-n将导致以下异常:

    操作已中止。不能修改已在设备上设置的资源,也不能修改已在平铺支架中使用的资源。

    我能否提前确定执行SetData()是否会引发此异常?

    3 回复  |  直到 14 年前
        1
  •  1
  •   msteiger    14 年前

    基本上,您有三种选择:

    1) 查看SpriteBatch是否已完成其操作,然后调用SetData()。绘图方法通常是异步的。这意味着,它们被添加到please render me队列中,方法立即返回。您需要的是绘图完成时的回调通知或对Draw()的同步调用。

    2) 避免SetData()被中断。你可以把它放到我不推荐的关键部分。应该可以锁定纹理数据。在Direct3D中称为LockRect(),在XNA中应该类似。

    3) 应该有一些方法,比如Flush(),等待所有与图形相关的操作完成。

        2
  •  1
  •   Andrew Russell    14 年前

    基本上没有。

    最简单的办法就是只打电话 SetData 在你的 Update 方法。

    设置数据 在你的 Draw 方法,因为该设备可以用旧数据做各种巫术。对此进行了详细说明 in the "Caution" box on its MSDN page .

    SetDataOptions 具有 Texture2D.SetData removed in XNA 4.0

    Shawn Hargreaves explains here 怎样 如果您想覆盖您可能正在使用的数据,请不要抱怨”。以及为什么很难做到正确。

        3
  •  1
  •   JulianR    14 年前

    我通过创建两个纹理,并在活动纹理之间切换,基本上是双缓冲,解决了这样一个问题:

    void CreateTextures()
    {
    
      depth_1 = new Texture2D(this.GraphicsDevice, width, height, false, SurfaceFormat.Single);
      depth_2 = new Texture2D(this.GraphicsDevice, width, height, false, SurfaceFormat.Single);
    
      depth_current = depth_1;
    
      ...
    
    }
    
    void Draw(GameTime gt)
    {
      depth_current = depth_current == depth_1 ? depth_2 : depth_1;
      Depth.SetData(this.DepthBuffer);
    
      ...
    
    }
    

    SetData 除了画画,我想这是最好的方法。