Question

From my few years of experience programming in graphics, one thing that I have learned is that you should never pass in a reference to a graphics context to an object and operate on it for the duration of the program (JOGL explicitly states this). A context can be invalidated when something such as the graphics device (GPU) is reset, turned off, or some other weird thing happens. I have recently delved back into programming in XNA 4.0, and one of my projects involves objects needing to know about the size of the window/viewport, when the window is resized, and when dynamic buffers have lost their content (requiring the buffers to be rebuilt on a possibly invalidated GraphicsDevice). Instead of passing in the GraphicsDevice and GameWindow to numerous methods in the update phase or for Disposal, I have opted to pass them into constructors. For example:

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 ...
}

Is it safe to do something like this, or is something happening in the background that I need to be aware of?

Was it helpful?

Solution

I solved this problem in my current game project by running the game as a singleton, which makes it available in a static context within the namespace. Game.Instance.graphicsDevice will always point to the current graphics device object, even if the context has changed. XNA raises various events when the context is invalidated/changed/reset/etc., and you can reload/re-render things and resize buffers as needed by hooking in to these events.

Alternatively, you could pass GraphicsDevice with the ref keyword, which might be a quick, drop-in fix by simply being the same reference as the original caller, assuming that caller that instantiated your objects either has the original reference object or had the GraphicsDevice passed to it with ref as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top