C# 有没有办法检查Texture2D当前是否未使用,以便我可以对其执行SetData()?
尝试在最近由SpriteBatch绘制的Texture2D上执行SetData()-n将导致以下异常: 操作已中止。您不能修改已在设备上设置的资源,也不能修改已在平铺支架中使用的资源。C# 有没有办法检查Texture2D当前是否未使用,以便我可以对其执行SetData()?,c#,vb.net,xna,C#,Vb.net,Xna,尝试在最近由SpriteBatch绘制的Texture2D上执行SetData()-n将导致以下异常: 操作已中止。您不能修改已在设备上设置的资源,也不能修改已在平铺支架中使用的资源。 我能否提前确定执行SetData()是否会引发此异常?基本上,您有三个选项: 1) 查看SpriteBatch是否已完成其操作,然后调用SetData()。绘图方法通常是异步的。这意味着,它们只是被添加到please render me队列中,该方法立即返回。您需要的是图形完成时的回调通知或对Draw()的同步调
我能否提前确定执行SetData()是否会引发此异常?基本上,您有三个选项: 1) 查看SpriteBatch是否已完成其操作,然后调用SetData()。绘图方法通常是异步的。这意味着,它们只是被添加到please render me队列中,该方法立即返回。您需要的是图形完成时的回调通知或对Draw()的同步调用 2) 避免SetData()被中断。你可以把它放到一个我不推荐的关键部分。应该可以锁定纹理数据。它在Direct3D中称为LockRect(),在XNA中应该类似 3) 应该有像Flush()这样的方法等待所有与图形相关的操作完成
很抱歉提供了不明确的帮助,但是您应该能够从XNA文档中找到方法名称。基本上,您有三个选项: 1) 查看SpriteBatch是否已完成其操作,然后调用SetData()。绘图方法通常是异步的。这意味着,它们只是被添加到please render me队列中,该方法立即返回。您需要的是图形完成时的回调通知或对Draw()的同步调用 2) 避免SetData()被中断。你可以把它放到一个我不推荐的关键部分。应该可以锁定纹理数据。它在Direct3D中称为LockRect(),在XNA中应该类似 3) 应该有像Flush()这样的方法等待所有与图形相关的操作完成 很抱歉提供了不明确的帮助,但是您应该能够从XNA文档中找到方法名称。基本上没有 最简单的方法是只在
Update
方法中调用SetData
在Draw
方法中使用SetData
是一种不好的做法,因为该设备可能会使用旧数据执行各种巫术。对此进行了详细解释
现在,在XNA3.1之前,您可以使用。但它看起来像是纹理的功能
如何使用SetDataOptions
告诉GPU“实际上是的,我确实想覆盖您可能正在使用的数据,不要抱怨”。以及为什么很难做到正确。基本上没有
最简单的方法是只在Update
方法中调用SetData
在Draw
方法中使用SetData
是一种不好的做法,因为该设备可能会使用旧数据执行各种巫术。对此进行了详细解释
现在,在XNA3.1之前,您可以使用。但它看起来像是纹理的功能
如何使用
SetDataOptions
告诉GPU“实际上是的,我确实想覆盖您可能正在使用的数据,不要抱怨”。我已经解决了这样一个问题,创建了两个纹理,并在活动纹理之间切换,基本上是双缓冲:
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);
...
}
在我的例子中,无法将
设置数据移动到绘图之外,但我认为这是最好的方法。我通过创建两个纹理并在活动纹理之间切换,基本上是双缓冲,解决了这样一个问题:
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
移动到绘图之外,但我认为这是最好的方法。我通过在SpriteBatch上保留我绘制的纹理哈希集()来解决问题我通过保留我绘制的纹理哈希集()来解决问题在SpriteBatch上,我很确定我一直在使用SetData from Update()方法。我只有一个线程,调用SetData的方法是从Update()调用的。它包含了一些cpu和磁盘密集型操作,所以我想将它放在Draw()之外,感谢关于SetDataOptions的提示。。。看起来很有趣。我很确定我一直在使用SetData from Update()方法。我只有一个线程,调用SetData的方法是从Update()调用的。它包含了一些cpu和磁盘密集型操作,所以我想将它放在Draw()之外,感谢关于SetDataOptions的提示。。。看起来很有趣,谢谢。我解决了这个问题,分配了两个纹理,而不是一个,并显示了一个,但将数据设置为另一个,然后进行切换。谢谢。我通过分配两个纹理(而不是一个)并显示一个纹理来解决这个问题,但将数据设置为另一个,然后切换它们。