diff --git a/ANX.Framework/GraphicsDeviceManager.cs b/ANX.Framework/GraphicsDeviceManager.cs index 152185fd..2da58e17 100644 --- a/ANX.Framework/GraphicsDeviceManager.cs +++ b/ANX.Framework/GraphicsDeviceManager.cs @@ -1,12 +1,9 @@ -#region Using Statements using System; using System.Collections.Generic; using System.IO; using ANX.Framework.Graphics; using ANX.Framework.NonXNA; -#endregion // Using Statements - // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. // For details see: http://anxframework.codeplex.com/license @@ -15,7 +12,13 @@ namespace ANX.Framework { public class GraphicsDeviceManager : IGraphicsDeviceManager, IDisposable, IGraphicsDeviceService { - #region Private Members + #region Constants + public static readonly int DefaultBackBufferWidth = 800; + public static readonly int DefaultBackBufferHeight = 480; + private const string RuntimeProfileResourceName = "Microsoft.Xna.Framework.RuntimeProfile"; + #endregion + + #region Private private Game game; private GraphicsDevice graphicsDevice; private int backBufferWidth = DefaultBackBufferWidth; @@ -23,253 +26,21 @@ namespace ANX.Framework private SurfaceFormat backBufferFormat = SurfaceFormat.Color; private DepthFormat depthStencilFormat = DepthFormat.Depth24; private GraphicsProfile graphicsProfile; - private bool isFullScreen; - private bool multiSampling; private GraphicsDeviceInformation currentGraphicsDeviceInformation; + private bool synchronizeWithVerticalRetrace = true; - #endregion // Private Members - - public static readonly int DefaultBackBufferWidth = 800; - public static readonly int DefaultBackBufferHeight = 480; + #endregion + #region Events public event EventHandler Disposed; public event EventHandler DeviceCreated; public event EventHandler DeviceDisposing; public event EventHandler DeviceReset; public event EventHandler DeviceResetting; public event EventHandler PreparingDeviceSettings; + #endregion - public GraphicsDeviceManager(Game game) - { - if (game == null) - { - throw new ArgumentNullException("game"); - } - - this.game = game; - - if (game.Services.GetService(typeof(IGraphicsDeviceManager)) != null) - { - throw new ArgumentException("The GraphicsDeviceManager was already registered to the game class"); - } - game.Services.AddService(typeof(IGraphicsDeviceManager), this); - - if (game.Services.GetService(typeof(IGraphicsDeviceService)) != null) - { - throw new ArgumentException("The GraphicsDeviceService was already registered to the game class"); - } - game.Services.AddService(typeof(IGraphicsDeviceService), this); - - game.Window.ClientSizeChanged += Window_ClientSizeChanged; - game.Window.ScreenDeviceNameChanged += Window_ScreenDeviceNameChanged; - game.Window.OrientationChanged += Window_OrientationChanged; - - this.graphicsProfile = FetchGraphicsProfile(); - } - - void Window_OrientationChanged(object sender, EventArgs e) - { - throw new NotImplementedException(); - } - - void Window_ScreenDeviceNameChanged(object sender, EventArgs e) - { - throw new NotImplementedException(); - } - - void Window_ClientSizeChanged(object sender, EventArgs e) - { - // TODO: validate - var parameters = graphicsDevice.PresentationParameters; - parameters.BackBufferWidth = game.Window.ClientBounds.Width; - parameters.BackBufferHeight = game.Window.ClientBounds.Height; - graphicsDevice.Reset(parameters); - } - - public bool BeginDraw() - { - return true; - } - - public void CreateDevice() - { - ApplyChanges(); - } - - private void CreateDevice(GraphicsDeviceInformation deviceInformation) - { - if (this.graphicsDevice != null) - { - System.Diagnostics.Debugger.Break(); // Test this!!! - this.graphicsDevice.Dispose(); - this.graphicsDevice = null; - } - - //TODO: validate graphics device - - this.graphicsDevice = new GraphicsDevice(deviceInformation.Adapter, deviceInformation.GraphicsProfile, deviceInformation.PresentationParameters); - GraphicsResourceTracker.Instance.UpdateGraphicsDeviceReference(this.graphicsDevice); - - //TODO: hookup events - this.graphicsDevice.DeviceResetting += graphicsDevice_DeviceResetting; - this.graphicsDevice.DeviceReset += graphicsDevice_DeviceReset; - - OnDeviceCreated(this, EventArgs.Empty); - } - - void graphicsDevice_DeviceReset(object sender, EventArgs e) - { - OnDeviceReset(this, EventArgs.Empty); - } - - void graphicsDevice_DeviceResetting(object sender, EventArgs e) - { - OnDeviceResetting(this, EventArgs.Empty); - } - - public void EndDraw() - { - this.graphicsDevice.Present(); - } - - public void ApplyChanges() - { - GraphicsDeviceInformation graphicsDeviceInformation = FindBestDevice(true); - OnPreparingDeviceSettings(this, new PreparingDeviceSettingsEventArgs(graphicsDeviceInformation)); - - if (graphicsDevice != null) - { - if (this.CanResetDevice(graphicsDeviceInformation)) - { - OnDeviceResetting(this, EventArgs.Empty); - - this.graphicsDevice.Reset(graphicsDeviceInformation.PresentationParameters, graphicsDeviceInformation.Adapter); - - OnDeviceReset(this, EventArgs.Empty); - } - else - { - //graphicsDevice.Dispose(); - //graphicsDevice = null; - // Dispose could not be used here because all references to graphicsDevice get dirty! - - graphicsDevice.Recreate(graphicsDeviceInformation.PresentationParameters); - } - } - - if (graphicsDevice == null) - { - CreateDevice(graphicsDeviceInformation); - } - - this.currentGraphicsDeviceInformation = graphicsDeviceInformation; - } - - public void ToggleFullScreen() - { - throw new NotImplementedException(); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (game != null) - if (game.Services.GetService(typeof(IGraphicsDeviceService)) == this) - game.Services.RemoveService(typeof(IGraphicsDeviceService)); - - if (graphicsDevice != null) - { - graphicsDevice.Dispose(); - graphicsDevice = null; - } - - if (Disposed != null) - Disposed(this, EventArgs.Empty); - } - } - - protected GraphicsDeviceInformation FindBestDevice(bool anySuitableDevice) - { - //TODO: implement FindBestDevice - - GraphicsDeviceInformation deviceInformation = new GraphicsDeviceInformation(); - - deviceInformation.PresentationParameters.DeviceWindowHandle = game.Window.Handle; - deviceInformation.PresentationParameters.BackBufferFormat = backBufferFormat; - deviceInformation.PresentationParameters.BackBufferWidth = backBufferWidth; - deviceInformation.PresentationParameters.BackBufferHeight = backBufferHeight; - deviceInformation.PresentationParameters.DepthStencilFormat = depthStencilFormat; - - return deviceInformation; - } - - protected virtual bool CanResetDevice(GraphicsDeviceInformation newDeviceInfo) - { - if (newDeviceInfo.Adapter == currentGraphicsDeviceInformation.Adapter && - newDeviceInfo.GraphicsProfile == currentGraphicsDeviceInformation.GraphicsProfile && - // newDeviceInfo.PresentationParameters.DepthStencilFormat == currentGraphicsDeviceInformation.PresentationParameters.DepthStencilFormat && - newDeviceInfo.PresentationParameters.BackBufferFormat == currentGraphicsDeviceInformation.PresentationParameters.BackBufferFormat) - { - return true; - } - - //TODO: implement CanResetDevice completly - - return false; - } - - protected virtual void RankDevices(List foundDevices) - { - throw new NotImplementedException(); - } - - protected virtual void OnDeviceCreated(Object sender, EventArgs args) - { - if (DeviceCreated != null) - { - DeviceCreated(sender, args); - } - } - - protected virtual void OnDeviceDisposing(Object sender, EventArgs args) - { - if (DeviceDisposing != null) - { - DeviceDisposing(sender, args); - } - } - - protected virtual void OnDeviceReset(Object sender, EventArgs args) - { - if (DeviceReset != null) - { - DeviceReset(sender, args); - } - } - - protected virtual void OnDeviceResetting(Object sender, EventArgs args) - { - if (DeviceResetting != null) - { - DeviceResetting(sender, args); - } - } - - protected virtual void OnPreparingDeviceSettings(Object sender, PreparingDeviceSettingsEventArgs args) - { - if (PreparingDeviceSettings != null) - { - PreparingDeviceSettings(sender, args); - } - } - + #region Public public GraphicsDevice GraphicsDevice { get { return this.graphicsDevice; } @@ -351,16 +122,15 @@ namespace ANX.Framework { get { - if (graphicsDevice != null && graphicsDevice.NativeDevice != null) - { - return graphicsDevice.NativeDevice.VSync; - } - - return true; + return (graphicsDevice != null && graphicsDevice.NativeDevice != null) ? + graphicsDevice.NativeDevice.VSync : + synchronizeWithVerticalRetrace; } set { - graphicsDevice.NativeDevice.VSync = value; + synchronizeWithVerticalRetrace = value; + if (graphicsDevice != null && graphicsDevice.NativeDevice != null) + graphicsDevice.NativeDevice.VSync = value; } } @@ -378,24 +148,249 @@ namespace ANX.Framework get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } + #endregion - private GraphicsProfile FetchGraphicsProfile() + #region Constructor + public GraphicsDeviceManager(Game game) { - Stream manifestResourceStream = ManifestHelper.GetManifestResourceStream( - game, "Microsoft.Xna.Framework.RuntimeProfile"); + if (game == null) + throw new ArgumentNullException("game"); + this.game = game; - if (manifestResourceStream != null) + if (game.Services.GetService(typeof(IGraphicsDeviceManager)) != null) + throw new ArgumentException("The GraphicsDeviceManager was already registered to the game class"); + game.Services.AddService(typeof(IGraphicsDeviceManager), this); + + if (game.Services.GetService(typeof(IGraphicsDeviceService)) != null) + throw new ArgumentException("The GraphicsDeviceService was already registered to the game class"); + game.Services.AddService(typeof(IGraphicsDeviceService), this); + + game.Window.ClientSizeChanged += Window_ClientSizeChanged; + game.Window.ScreenDeviceNameChanged += Window_ScreenDeviceNameChanged; + game.Window.OrientationChanged += Window_OrientationChanged; + + this.graphicsProfile = FetchGraphicsProfile(); + } + #endregion + + #region BeginDraw + public bool BeginDraw() + { + return true; + } + #endregion + + #region CreateDevice + public void CreateDevice() + { + ApplyChanges(); + } + + private void CreateDevice(GraphicsDeviceInformation deviceInformation) + { + if (this.graphicsDevice != null) { - using (StreamReader reader = new StreamReader(manifestResourceStream)) + System.Diagnostics.Debugger.Break(); // Test this!!! + this.graphicsDevice.Dispose(); + this.graphicsDevice = null; + } + + //TODO: validate graphics device + + this.graphicsDevice = new GraphicsDevice(deviceInformation.Adapter, deviceInformation.GraphicsProfile, + deviceInformation.PresentationParameters); + GraphicsResourceTracker.Instance.UpdateGraphicsDeviceReference(this.graphicsDevice); + + //TODO: hookup events + this.graphicsDevice.DeviceResetting += OnDeviceResetting; + this.graphicsDevice.DeviceReset += OnDeviceReset; + + // Update the vsync value in case it was set before creation of the device + SynchronizeWithVerticalRetrace = synchronizeWithVerticalRetrace; + + OnDeviceCreated(this, EventArgs.Empty); + } + #endregion + + #region EndDraw + public void EndDraw() + { + this.graphicsDevice.Present(); + } + #endregion + + #region ApplyChanges + public void ApplyChanges() + { + GraphicsDeviceInformation graphicsDeviceInformation = FindBestDevice(true); + OnPreparingDeviceSettings(this, new PreparingDeviceSettingsEventArgs(graphicsDeviceInformation)); + + if (graphicsDevice != null) + { + if (this.CanResetDevice(graphicsDeviceInformation)) { - if (reader.ReadToEnd().Contains("HiDef")) - { - return GraphicsProfile.HiDef; - } + OnDeviceResetting(this, EventArgs.Empty); + + this.graphicsDevice.Reset(graphicsDeviceInformation.PresentationParameters, + graphicsDeviceInformation.Adapter); + + OnDeviceReset(this, EventArgs.Empty); + } + else + { + //graphicsDevice.Dispose(); + //graphicsDevice = null; + // Dispose could not be used here because all references to graphicsDevice get dirty! + + graphicsDevice.Recreate(graphicsDeviceInformation.PresentationParameters); } } - return GraphicsProfile.Reach; + if (graphicsDevice == null) + CreateDevice(graphicsDeviceInformation); + + this.currentGraphicsDeviceInformation = graphicsDeviceInformation; } + #endregion + + #region ApplyChanges + public void ToggleFullScreen() + { + throw new NotImplementedException(); + } + #endregion + + #region Dispose + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (game != null && game.Services.GetService(typeof(IGraphicsDeviceService)) == this) + game.Services.RemoveService(typeof(IGraphicsDeviceService)); + + if (graphicsDevice != null) + { + graphicsDevice.Dispose(); + graphicsDevice = null; + } + + if (Disposed != null) + Disposed(this, EventArgs.Empty); + } + } + #endregion + + #region FindBestDevice + protected GraphicsDeviceInformation FindBestDevice(bool anySuitableDevice) + { + //TODO: implement FindBestDevice + + GraphicsDeviceInformation deviceInformation = new GraphicsDeviceInformation(); + + deviceInformation.PresentationParameters.DeviceWindowHandle = game.Window.Handle; + deviceInformation.PresentationParameters.BackBufferFormat = backBufferFormat; + deviceInformation.PresentationParameters.BackBufferWidth = backBufferWidth; + deviceInformation.PresentationParameters.BackBufferHeight = backBufferHeight; + deviceInformation.PresentationParameters.DepthStencilFormat = depthStencilFormat; + + return deviceInformation; + } + #endregion + + #region CanResetDevice + protected virtual bool CanResetDevice(GraphicsDeviceInformation newDeviceInfo) + { + if (newDeviceInfo.Adapter == currentGraphicsDeviceInformation.Adapter && + newDeviceInfo.GraphicsProfile == currentGraphicsDeviceInformation.GraphicsProfile && + //newDeviceInfo.PresentationParameters.DepthStencilFormat == currentGraphicsDeviceInformation.PresentationParameters.DepthStencilFormat && + newDeviceInfo.PresentationParameters.BackBufferFormat == currentGraphicsDeviceInformation.PresentationParameters.BackBufferFormat) + { + return true; + } + + //TODO: implement CanResetDevice completly + + return false; + } + #endregion + + protected virtual void RankDevices(List foundDevices) + { + throw new NotImplementedException(); + } + + private void Window_OrientationChanged(object sender, EventArgs e) + { + throw new NotImplementedException(); + } + + private void Window_ScreenDeviceNameChanged(object sender, EventArgs e) + { + throw new NotImplementedException(); + } + + private void Window_ClientSizeChanged(object sender, EventArgs e) + { + // TODO: validate + var parameters = graphicsDevice.PresentationParameters; + parameters.BackBufferWidth = game.Window.ClientBounds.Width; + parameters.BackBufferHeight = game.Window.ClientBounds.Height; + graphicsDevice.Reset(parameters); + } + + protected virtual void OnDeviceCreated(object sender, EventArgs args) + { + RaiseEventIfNotNull(DeviceCreated, sender, args); + } + + protected virtual void OnDeviceDisposing(object sender, EventArgs args) + { + RaiseEventIfNotNull(DeviceDisposing, sender, args); + } + + protected virtual void OnDeviceReset(object sender, EventArgs args) + { + RaiseEventIfNotNull(DeviceReset, sender, args); + } + + protected virtual void OnDeviceResetting(object sender, EventArgs args) + { + RaiseEventIfNotNull(DeviceResetting, sender, args); + } + + protected virtual void OnPreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs args) + { + RaiseEventIfNotNull(PreparingDeviceSettings, sender, args); + } + + #region RaiseEventIfNotNull + private void RaiseEventIfNotNull(EventHandler handler, object sender, T args) where T : EventArgs + { + if (handler != null) + handler(sender, args); + } + #endregion + + #region FetchGraphicsProfile + private GraphicsProfile FetchGraphicsProfile() + { + var result = GraphicsProfile.Reach; + Stream manifestResourceStream = ManifestHelper.GetManifestResourceStream(game, RuntimeProfileResourceName); + if (manifestResourceStream == null) + return result; + + using (StreamReader reader = new StreamReader(manifestResourceStream)) + if (reader.ReadToEnd().Contains("HiDef")) + result = GraphicsProfile.HiDef; + + return result; + } + #endregion } } diff --git a/Samples/SimpleSprite/Game1.cs b/Samples/SimpleSprite/Game1.cs index ff400655..d7336003 100644 --- a/Samples/SimpleSprite/Game1.cs +++ b/Samples/SimpleSprite/Game1.cs @@ -37,6 +37,8 @@ namespace WindowsGame1 { graphics = new GraphicsDeviceManager(this); graphics.PreparingDeviceSettings += graphics_PreparingDeviceSettings; + //graphics.SynchronizeWithVerticalRetrace = false; + //IsFixedTimeStep = false; Content.RootDirectory = "SampleContent"; }