Graphics XNA 4图形设备

Graphics XNA 4图形设备,graphics,xna-4.0,dispose,Graphics,Xna 4.0,Dispose,从我在图形编程方面的几年经验中,我学到了一件事,那就是你永远不应该把对图形上下文的引用传递给一个对象,并且在程序运行期间对它进行操作(JOGL明确地说明了这一点)。当图形设备(GPU)被重置、关闭或发生其他奇怪的事情时,上下文可能会失效。 我最近深入研究了XNA 4.0中的编程,我的一个项目涉及的对象需要了解窗口/视口的大小、何时调整窗口大小以及何时动态缓冲区丢失其内容(需要在可能失效的GraphicsDevice上重建缓冲区)。在更新阶段,我没有将GraphicsDevice和GameWind

从我在图形编程方面的几年经验中,我学到了一件事,那就是你永远不应该把对图形上下文的引用传递给一个对象,并且在程序运行期间对它进行操作(JOGL明确地说明了这一点)。当图形设备(GPU)被重置、关闭或发生其他奇怪的事情时,上下文可能会失效。 我最近深入研究了XNA 4.0中的编程,我的一个项目涉及的对象需要了解窗口/视口的大小、何时调整窗口大小以及何时动态缓冲区丢失其内容(需要在可能失效的GraphicsDevice上重建缓冲区)。在更新阶段,我没有将GraphicsDevice和GameWindow传递给许多方法,也没有将它们传递给其他方法,而是选择将它们传递给构造函数。例如:

public Camera(GameWindow w, GraphicsDeviceManager m) {
    // ... Yada-yada matrices
    gdm = m;
    window = w;
    window.ClientSizeChanged += OnWindowResize;
}
public void Dispose() {
    window.ClientSizeChanged -= OnWindowResize;
    window = null;
    gdm = null;
}
// Control Logic ...
public void OnWindowResize(object Sender, EventArgs args) {
    Vector2 s = new Vector2(gdm.GraphicsDevice.Viewport.TitleSafeArea.Width, gdm.GraphicsDevice.Viewport.TitleSafeArea.Height);
    // Recalculate Projection ...
}

这样做安全吗,还是在后台发生了我需要注意的事情?

我在当前的游戏项目中解决了这个问题,以单例运行游戏,这使得它可以在命名空间内的静态上下文中使用
Game.Instance.graphicsDevice
将始终指向当前图形设备对象,即使上下文已更改。当上下文无效/更改/重置/等等时,XNA会引发各种事件,您可以通过挂接到这些事件来重新加载/重新渲染内容并根据需要调整缓冲区大小

或者,您可以使用
ref
关键字传递
GraphicsDevice
,这可能是一个快速的、插入式的修复,只需与原始调用者使用相同的引用即可,假设实例化对象的调用方要么拥有原始引用对象,要么将
GraphicsDevice
ref
一起传递给它