2012-10-10 19:26:53 +00:00
|
|
|
#region Using Statements
|
2011-10-31 05:36:24 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
2011-11-11 07:29:49 +00:00
|
|
|
using System.IO;
|
2012-08-25 17:27:45 +00:00
|
|
|
using ANX.Framework.Graphics;
|
2011-12-07 08:40:40 +00:00
|
|
|
using ANX.Framework.NonXNA;
|
2012-10-10 19:26:53 +00:00
|
|
|
using ANX.Framework.NonXNA.Development;
|
|
|
|
|
|
|
|
#endregion
|
2011-10-31 05:36:24 +00:00
|
|
|
|
2012-08-09 09:45:04 +00:00
|
|
|
// 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
|
2011-10-31 05:36:24 +00:00
|
|
|
|
|
|
|
namespace ANX.Framework
|
|
|
|
{
|
2012-10-14 16:40:10 +00:00
|
|
|
[PercentageComplete(60)]
|
2012-10-10 19:26:53 +00:00
|
|
|
[Developer("Glatzemann")]
|
2012-10-13 19:43:12 +00:00
|
|
|
[TestState(TestStateAttribute.TestState.Untested)]
|
two commits were missing, both by KorsarNek:
"Removed the SupportedPlatformsImpl classes and replaced them with a new SupportedPlatforms attribute on the assembly level.
Removed a few class constructors which could cause problems when loading a game.
Made ResetElapsedTime in the game class reset to 0 instead of TimeSpan.MinValue.
Removed the restriction in the InputDeviceFactory for which InputDevices are supported.
Added a Logger for Metro which works with the current Logger implementation.
Changed that when a platform is recognized that is higher than Windows 8, it gets treated like Windows 8, not like Windows 7.
Due to the SupportedPlatforms change, the assembly loader is now faster in finding out which assemblies contains addIns. For not Metro system, it's also added that a warning gets written if an AddIn references a different ANX version than that of the running assembly.
OpenGL and DirectX have been updated to the newest versions.
XAudio system uses now the same SharpDX version as all the other systems.
ParameterBuffer for WindowsMetro gets now correctly created by considering the size constraints for constant buffers.
Fixed an erroneous finalizer in the xaudio system.
Made the metro projects convert to Windows 8.1, as Windows 8.0 is not supported by the newer SharpDX versions. It's now also necessary to use at least Visual Studio 2013 to build the Metro versions.
Made the samples work again on Windows."
"Fixed the creation of the swap chain for windows metro and removed the dependency of the Metro Rendersystem onto the Metro Platformsytem.
All occurrences of WindowHandles have been replaced with a custom WindowHandle type which should work out of the box in most cases, but does still represent a breaking change to XNA.
The ProjectConverter for Metro was adjusted so that with just changing the way the application is initialized, most projects that worked with ANX before should now work under win rt. The sample SimpleNoContent does now work out of the box for win rt, after a project conversion.
The application name for win rt apps is now a guid, the display name stayed the same though. That's to be more compliant with the way win rt apps are normally created.
The default namespace and namespace of the classes for the Sample "SimpleNoContent" is renamed from "SimpleModernUI" to "SimpleNoContent".
With the new way win rt apps are initialized for ANX, it's necessary to first create the WindowsGameHost for WinRT with a handler how to create the game instance and give that to the CoreApplication object to run it.
Also took care of a few annoying bugs when working with win rt and ANX where no InputDevices could be created on the first frame (Issue #1164 ) and that it wasn't possible to use the localfolder of the application on the first update and all the other stuff for which an instance of the Application class was necessary."
2015-03-29 13:48:33 +02:00
|
|
|
public class GraphicsDeviceManager : IGraphicsDeviceManager, IDisposable, IGraphicsDeviceService
|
|
|
|
{
|
|
|
|
#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;
|
|
|
|
private int backBufferHeight = DefaultBackBufferHeight;
|
|
|
|
private SurfaceFormat backBufferFormat = SurfaceFormat.Color;
|
|
|
|
private DepthFormat depthStencilFormat = DepthFormat.Depth24;
|
|
|
|
private GraphicsProfile graphicsProfile;
|
|
|
|
private GraphicsDeviceInformation currentGraphicsDeviceInformation;
|
|
|
|
private bool synchronizeWithVerticalRetrace = true;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Events
|
|
|
|
public event EventHandler<EventArgs> Disposed;
|
|
|
|
public event EventHandler<EventArgs> DeviceCreated;
|
|
|
|
public event EventHandler<EventArgs> DeviceDisposing;
|
|
|
|
public event EventHandler<EventArgs> DeviceReset;
|
|
|
|
public event EventHandler<EventArgs> DeviceResetting;
|
|
|
|
public event EventHandler<PreparingDeviceSettingsEventArgs> PreparingDeviceSettings;
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Public
|
|
|
|
public GraphicsDevice GraphicsDevice
|
|
|
|
{
|
|
|
|
get { return this.graphicsDevice; }
|
|
|
|
}
|
|
|
|
|
|
|
|
public GraphicsProfile GraphicsProfile
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.currentGraphicsDeviceInformation.GraphicsProfile;
|
|
|
|
}
|
|
|
|
set
|
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public DepthFormat PreferredDepthStencilFormat
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.currentGraphicsDeviceInformation.PresentationParameters.DepthStencilFormat;
|
|
|
|
}
|
|
|
|
set
|
|
|
|
{
|
|
|
|
this.depthStencilFormat = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public SurfaceFormat PreferredBackBufferFormat
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.currentGraphicsDeviceInformation.PresentationParameters.BackBufferFormat;
|
|
|
|
}
|
|
|
|
set
|
|
|
|
{
|
|
|
|
this.backBufferFormat = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public int PreferredBackBufferWidth
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.currentGraphicsDeviceInformation.PresentationParameters.BackBufferWidth;
|
|
|
|
}
|
|
|
|
set
|
|
|
|
{
|
|
|
|
this.backBufferWidth = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public int PreferredBackBufferHeight
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.currentGraphicsDeviceInformation.PresentationParameters.BackBufferHeight;
|
|
|
|
}
|
|
|
|
set
|
|
|
|
{
|
|
|
|
this.backBufferHeight = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool IsFullScreen
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.currentGraphicsDeviceInformation.PresentationParameters.IsFullScreen;
|
|
|
|
}
|
|
|
|
set
|
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool SynchronizeWithVerticalRetrace
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return (graphicsDevice != null && graphicsDevice.NativeDevice != null) ?
|
|
|
|
graphicsDevice.NativeDevice.VSync :
|
|
|
|
synchronizeWithVerticalRetrace;
|
|
|
|
}
|
|
|
|
set
|
|
|
|
{
|
|
|
|
synchronizeWithVerticalRetrace = value;
|
|
|
|
if (graphicsDevice != null && graphicsDevice.NativeDevice != null)
|
|
|
|
graphicsDevice.NativeDevice.VSync = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool PreferMultiSampling
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.currentGraphicsDeviceInformation.PresentationParameters.MultiSampleCount > 0;
|
|
|
|
}
|
|
|
|
set { throw new NotImplementedException(); }
|
|
|
|
}
|
|
|
|
|
|
|
|
public DisplayOrientation SupportedOrientations
|
|
|
|
{
|
|
|
|
get { throw new NotImplementedException(); }
|
|
|
|
set { throw new NotImplementedException(); }
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Constructor
|
|
|
|
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();
|
|
|
|
|
|
|
|
Window_ClientSizeChanged(null, EventArgs.Empty);
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region BeginDraw
|
|
|
|
public bool BeginDraw()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region CreateDevice
|
|
|
|
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 += 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))
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
#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)
|
|
|
|
{
|
|
|
|
return GraphicsDevice.GraphicsProfile == newDeviceInfo.GraphicsProfile;
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
protected virtual void RankDevices(List<GraphicsDeviceInformation> 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)
|
|
|
|
{
|
|
|
|
backBufferWidth = game.Window.ClientBounds.Width;
|
|
|
|
backBufferHeight = game.Window.ClientBounds.Height;
|
|
|
|
|
|
|
|
if (graphicsDevice != null)
|
|
|
|
{
|
|
|
|
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<T>(EventHandler<T> 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
|
|
|
|
}
|
2011-10-31 05:36:24 +00:00
|
|
|
}
|