gpt4 book ai didi

c# - 如何在应用新设置时防止 GraphicsDevice 被处置?

转载 作者:可可西里 更新时间:2023-11-01 08:48:53 24 4
gpt4 key购买 nike

我的游戏窗口允许手动调整大小,这意味着它可以像任何其他普通窗口一样通过拖动其边缘来调整大小。该游戏还使用了 RenderTarget2D rt2d ,主要渲染目标在主要绘制方法中设置为:GraphicsDevice.SetRenderTarget(rt2d) , 但它被重置回 null (默认渲染目标)在主要 Draw 方法的末尾,这让人​​有点困惑:这真的是问题的根源吗,在 Render Target 设置为 rt2d 之间调整游戏窗口大小,而不是重置回默认值?现在看起来是这样。

主要 Draw 方法中的代码应该总是将主要渲染目标重置回 null ,所以没有预期的情况,这通常不会发生。

不过,调整游戏窗口大小的结果有时会导致 GraphicsDevice.isDisposed返回 true , 然后游戏抛出 System.ObjectDisposedException在第一个SpriteBatch.End() .我发现有关此错误的帖子可以追溯到 XNA 的最初几天,但没有很好的解释(也没有提到更改渲染目标,因此它也可能是这些帖子的问题根源)。

现在我可以通过多次调用此方法来触发此错误:

graphics.PreferredBackBufferWidth = graphics.PreferredBackBufferWidth;
graphics.PreferredBackBufferHeight = graphics.PreferredBackBufferHeight;
graphics.ApplyChanges();

...在主要的 Draw 方法中有以下几行:

RenderTarget2D rt2d = new RenderTarget2D(GraphicsDevice,
graphics.PreferredBackBufferWidth,
graphics.PreferredBackBufferHeight);
GraphicsDevice.SetRenderTarget(rt2d);
sb.Begin();
// main draw method here, it's pretty big, so it might be taking long
// enough to process to actually resize before resetting render target
sb.End();

GraphicsDevice.SetRenderTarget(null);
sb.Begin();
// draw the whole rt2d to the screen
sb.End();

我的猜测是,如果调整大小发生在渲染目标重置之前,我应该中止帧绘制并重置渲染目标,但我仍然不确定这正是导致此问题的原因。

更新:有Window.ClientSizeChangedgraphics.PreparingDeviceSettings事件,但即使它们触发,默认渲染目标似乎也无济于事。

我想这不是“调整客户区大小和应用新图形设置之间的超时”之类的。这很可能是由非默认渲染目标引起的。

而且可能并不是渲染目标尺寸与新屏幕尺寸不同,因为当将图形设备尺寸更改为完全相同的值时,这也会引发异常。

UPD2:我只是尝试让全屏切换一个挂起的操作,使 F11 设置为 isFullscreenTogglePendingtrue 并在主程序的开头检查它 Update方法,它根本没有帮助。然后我发现以前的全屏模式也是从主更新方法切换的,只是不是在一开始,而是在输入更新方法的中途,所以在主 Update 中的哪个位置并不重要。它运行的方法,它仍然会导致此错误。有趣的是,GraphicsDevice.isDisposed抛出异常时为false


这是异常信息:

System.ObjectDisposedException occurred
Message=Cannot access a disposed object.
Object name: 'GraphicsDevice'.
Source=Microsoft.Xna.Framework
ObjectName=GraphicsDevice
StackTrace:
at Microsoft.Xna.Framework.Helpers.CheckDisposed(Object obj, IntPtr pComPtr)
at Microsoft.Xna.Framework.Graphics.BlendState.Apply(GraphicsDevice device)
at Microsoft.Xna.Framework.Graphics.GraphicsDevice.set_BlendState(BlendState value)
at Microsoft.Xna.Framework.Graphics.SpriteBatch.SetRenderState()
at Microsoft.Xna.Framework.Graphics.SpriteBatch.End()
at secret_project.Game1.Draw(GameTime gameTime) in P:\msvs projects\secret_project\Game1.cs:line 3310
InnerException:

它位于 spriteBatch.End()在主 Draw 调用中。

如何防止此错误?


可能相关的问题:

最佳答案

两件事:1.我不熟悉渲染目标......但这也许会有所帮助?来自 MSDN:

“渲染目标代表显示内存的线性区域,通常驻留在显示卡的显示内存中。因此,在设备重置时必须重新创建 RenderTarget 对象。”

2。除此之外,我曾经遇到过类似的问题。我在绘制调用结束时处理纹理。这会很好用,除非我试图移动窗口。每隔一段时间,当我尝试移动游戏窗口时,(对于纹理)就会发生 ObjectDisposed 异常。我对推理的最佳猜测是更新线程和绘制线程会错位,即使只是一小会儿,并且纹理会在有机会重置之前再次调用。我从来没有找到停止效果的方法,除了在尝试绘制之前确保对象没有被丢弃。

当然,我们的情况可能完全不相关,但作为一种可能的解决方法,只需添加一个标志,该标志将在最近重新调整窗口大小时停止任何绘制调用。

如果这不能解决问题,希望它能帮助缩小问题范围。

关于c# - 如何在应用新设置时防止 GraphicsDevice 被处置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16225701/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com