#region License
#endregion
#region Using Statements
using
System;
using
Microsoft.Xna.Framework.Graphics;
#endregion
namespace
Microsoft.Xna.Framework
{
public
class
GraphicsDeviceManager : IGraphicsDeviceService, IDisposable, IGraphicsDeviceManager
{
#region Public Properties
public
GraphicsProfile GraphicsProfile
{
get
;
set
;
}
public
GraphicsDevice GraphicsDevice
{
get
{
if
(graphicsDevice ==
null
)
{
((IGraphicsDeviceManager)
this
).CreateDevice();
}
return
graphicsDevice;
}
}
public
bool
IsFullScreen
{
get
;
set
;
}
public
bool
PreferMultiSampling
{
get
;
set
;
}
public
SurfaceFormat PreferredBackBufferFormat
{
get
;
set
;
}
public
int
PreferredBackBufferHeight
{
get
;
set
;
}
public
int
PreferredBackBufferWidth
{
get
;
set
;
}
public
DepthFormat PreferredDepthStencilFormat
{
get
;
set
;
}
public
bool
SynchronizeWithVerticalRetrace
{
get
;
set
;
}
public
DisplayOrientation SupportedOrientations
{
get
{
return
supportedOrientations;
}
set
{
supportedOrientations = value;
if
(game.Window !=
null
)
{
game.Window.SetSupportedOrientations(supportedOrientations);
}
}
}
#endregion
#region Private Variables
private
Game game;
private
GraphicsDevice graphicsDevice;
private
DisplayOrientation supportedOrientations;
private
bool
drawBegun;
private
bool
disposed;
#endregion
#region Public Static Fields
public
static
readonly
int
DefaultBackBufferWidth = 800;
public
static
readonly
int
DefaultBackBufferHeight = 480;
#endregion
#region Public Events
public
event
EventHandler<EventArgs> Disposed;
#endregion
#region IGraphicsDeviceService Events
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 Constructor
public
GraphicsDeviceManager(Game game)
{
if
(game ==
null
)
{
throw
new
ArgumentNullException(
"The game cannot be null!"
);
}
this
.game = game;
supportedOrientations = DisplayOrientation.Default;
PreferredBackBufferHeight = DefaultBackBufferHeight;
PreferredBackBufferWidth = DefaultBackBufferWidth;
PreferredBackBufferFormat = SurfaceFormat.Color;
PreferredDepthStencilFormat = DepthFormat.Depth24;
SynchronizeWithVerticalRetrace =
true
;
PreferMultiSampling =
false
;
if
(game.Services.GetService(
typeof
(IGraphicsDeviceManager)) !=
null
)
{
throw
new
ArgumentException(
"Graphics Device Manager Already Present"
);
}
game.Services.AddService(
typeof
(IGraphicsDeviceManager),
this
);
game.Services.AddService(
typeof
(IGraphicsDeviceService),
this
);
}
#endregion
#region Deconstructor
~GraphicsDeviceManager()
{
Dispose(
false
);
}
#endregion
#region Dispose Methods
protected
virtual
void
Dispose(
bool
disposing)
{
if
(!disposed)
{
if
(disposing)
{
if
(graphicsDevice !=
null
)
{
OnDeviceDisposing(
this
, EventArgs.Empty);
graphicsDevice.Dispose();
graphicsDevice =
null
;
}
}
if
(Disposed !=
null
)
{
Disposed(
this
, EventArgs.Empty);
}
disposed =
true
;
}
}
void
IDisposable.Dispose()
{
Dispose(
true
);
GC.SuppressFinalize(
this
);
}
#endregion
#region Public Methods
public
void
ApplyChanges()
{
if
(graphicsDevice ==
null
)
{
return
;
}
GraphicsDeviceInformation gdi =
new
GraphicsDeviceInformation();
gdi.Adapter = GraphicsDevice.Adapter;
gdi.GraphicsProfile = GraphicsDevice.GraphicsProfile;
gdi.PresentationParameters = GraphicsDevice.PresentationParameters.Clone();
gdi.PresentationParameters.BackBufferFormat =
PreferredBackBufferFormat;
gdi.PresentationParameters.BackBufferWidth =
PreferredBackBufferWidth;
gdi.PresentationParameters.BackBufferHeight =
PreferredBackBufferHeight;
gdi.PresentationParameters.DepthStencilFormat =
PreferredDepthStencilFormat;
gdi.PresentationParameters.IsFullScreen =
IsFullScreen;
if
(!PreferMultiSampling)
{
gdi.PresentationParameters.MultiSampleCount = 0;
}
else
if
(gdi.PresentationParameters.MultiSampleCount == 0)
{
gdi.PresentationParameters.MultiSampleCount = Math.Min(
GraphicsDevice.GLDevice.MaxMultiSampleCount,
8
);
}
OnPreparingDeviceSettings(
this
,
new
PreparingDeviceSettingsEventArgs(gdi)
);
OnDeviceResetting(
this
, EventArgs.Empty);
game.Window.BeginScreenDeviceChange(
gdi.PresentationParameters.IsFullScreen
);
game.Window.EndScreenDeviceChange(
gdi.Adapter.Description,
gdi.PresentationParameters.BackBufferWidth,
gdi.PresentationParameters.BackBufferHeight
);
FNAPlatform.SetPresentationInterval(
SynchronizeWithVerticalRetrace ?
gdi.PresentationParameters.PresentationInterval :
PresentInterval.Immediate
);
GraphicsDevice.Reset(gdi.PresentationParameters, gdi.Adapter);
OnDeviceReset(
this
, EventArgs.Empty);
}
public
void
ToggleFullScreen()
{
IsFullScreen = !IsFullScreen;
ApplyChanges();
}
#endregion
#region Internal Methods
internal
void
INTERNAL_ResizeGraphicsDevice(
int
width,
int
height)
{
PresentationParameters pp = GraphicsDevice.PresentationParameters;
if
(pp.BackBufferWidth != width || pp.BackBufferHeight != height)
{
OnDeviceResetting(
this
, EventArgs.Empty);
pp.BackBufferWidth = width;
pp.BackBufferHeight = height;
GraphicsDevice.Reset();
OnDeviceReset(
this
, EventArgs.Empty);
}
}
#endregion
#region Protected Methods
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);
}
}
#endregion
#region IGraphicsDeviceManager Methods
void
IGraphicsDeviceManager.CreateDevice()
{
GraphicsDeviceInformation gdi =
new
GraphicsDeviceInformation();
gdi.Adapter = GraphicsAdapter.DefaultAdapter;
gdi.GraphicsProfile = GraphicsProfile;
gdi.PresentationParameters =
new
PresentationParameters();
gdi.PresentationParameters.DeviceWindowHandle = game.Window.Handle;
gdi.PresentationParameters.DepthStencilFormat = DepthFormat.Depth24;
gdi.PresentationParameters.IsFullScreen =
false
;
OnPreparingDeviceSettings(
this
,
new
PreparingDeviceSettingsEventArgs(gdi)
);
GraphicsProfile = gdi.GraphicsProfile;
PreferredBackBufferFormat = gdi.PresentationParameters.BackBufferFormat;
PreferredDepthStencilFormat = gdi.PresentationParameters.DepthStencilFormat;
graphicsDevice =
new
GraphicsDevice(
gdi.Adapter,
gdi.GraphicsProfile,
gdi.PresentationParameters
);
ApplyChanges();
OnDeviceCreated(
this
, EventArgs.Empty);
}
bool
IGraphicsDeviceManager.BeginDraw()
{
if
(graphicsDevice ==
null
)
{
return
false
;
}
drawBegun =
true
;
return
true
;
}
void
IGraphicsDeviceManager.EndDraw()
{
if
(graphicsDevice !=
null
&& drawBegun)
{
drawBegun =
false
;
graphicsDevice.Present();
}
}
#endregion
}
}