Advertisement
Guest User

Monogame control

a guest
Jul 13th, 2016
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.87 KB | None | 0 0
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // GraphicsDeviceControl.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9.  
  10. #region Using Statements
  11. using System;
  12. using System.Drawing;
  13. using System.Windows.Forms;
  14. using Microsoft.Xna.Framework.Graphics;
  15. #endregion
  16.  
  17. namespace MGControl
  18. {
  19.     // System.Drawing and the XNA Framework both define Color and Rectangle
  20.     // types. To avoid conflicts, we specify exactly which ones to use.
  21.     using Color = System.Drawing.Color;
  22.     using Rectangle = Microsoft.Xna.Framework.Rectangle;
  23.     using Microsoft.Xna.Framework;
  24.     using System.Diagnostics;
  25.     /// <summary>
  26.     /// Custom control uses the XNA Framework GraphicsDevice to render onto
  27.     /// a Windows Form. Derived classes can override the Initialize and Draw
  28.     /// methods to add their own drawing code.
  29.     /// </summary>
  30.     abstract public class GraphicsDeviceControl : Control
  31.     {
  32.         #region Fields
  33.  
  34.         // However many GraphicsDeviceControl instances you have, they all share
  35.         // the same underlying GraphicsDevice, managed by this helper service.
  36.         GraphicsDeviceService graphicsDeviceService;
  37.  
  38.         SwapChainRenderTarget _renderTarget;
  39.  
  40.         #endregion
  41.  
  42.         #region Properties
  43.  
  44.  
  45.         /// <summary>
  46.         /// Gets a GraphicsDevice that can be used to draw onto this control.
  47.         /// </summary>
  48.         public GraphicsDevice GraphicsDevice
  49.         {
  50.             get { return graphicsDeviceService.GraphicsDevice; }
  51.         }
  52.  
  53.         public RenderTarget2D DefaultRenderTarget { get { return _renderTarget; } }
  54.  
  55.  
  56.         /// <summary>
  57.         /// Gets an IServiceProvider containing our IGraphicsDeviceService.
  58.         /// This can be used with components such as the ContentManager,
  59.         /// which use this service to look up the GraphicsDevice.
  60.         /// </summary>
  61.         public ServiceContainer Services
  62.         {
  63.             get { return services; }
  64.         }
  65.  
  66.         ServiceContainer services = new ServiceContainer();
  67.  
  68.  
  69.         #endregion
  70.  
  71.         #region Initialization
  72.  
  73.         public GraphicsDeviceControl() : base()
  74.         {
  75.         }
  76.  
  77.         /// <summary>
  78.         /// Initializes the control.
  79.         /// </summary>
  80.         protected override void OnCreateControl()
  81.         {
  82.             // Don't initialize the graphics device if we are running in the designer.
  83.             if (!DesignMode)
  84.             {
  85.                 graphicsDeviceService = GraphicsDeviceService.AddRef(Handle,
  86.                                                                      ClientSize.Width,
  87.                                                                      ClientSize.Height);
  88.  
  89.                 _renderTarget = new SwapChainRenderTarget(GraphicsDevice, Handle, ClientSize.Width, ClientSize.Height);
  90.  
  91.                 // Register the service, so components like ContentManager can find it.
  92.                 //services.AddService<IGraphicsDeviceService>(graphicsDeviceService);
  93.  
  94.                 // Give derived classes a chance to initialize themselves.
  95.                 Initialize();
  96.  
  97.                 //Set the XNA mouse handing to use this window
  98.                 //Mouse.WindowHandle = Handle;
  99.  
  100.                 return;
  101.             }
  102.  
  103.             base.OnCreateControl();
  104.         }
  105.  
  106.  
  107.         /// <summary>
  108.         /// Disposes the control.
  109.         /// </summary>
  110.         protected override void Dispose(bool disposing)
  111.         {
  112.             if (graphicsDeviceService != null)
  113.             {
  114.                 graphicsDeviceService.Release(disposing);
  115.                 graphicsDeviceService = null;
  116.             }
  117.  
  118.             if (_renderTarget != null)
  119.             {
  120.                 _renderTarget.Dispose();
  121.                 _renderTarget = null;
  122.             }
  123.  
  124.  
  125.             base.Dispose(disposing);
  126.         }
  127.  
  128.  
  129.         #endregion
  130.  
  131.         #region Paint
  132.  
  133.         /// <summary>
  134.         /// Redraws the control in response to a WinForms paint message.
  135.         /// </summary>        
  136.         protected override void OnPaint(PaintEventArgs e)
  137.         {
  138.             try
  139.             {
  140.                 //call drawing                    
  141.                 string beginDrawError = BeginDraw();
  142.                 if (string.IsNullOrEmpty(beginDrawError))
  143.                 {
  144.                     // Draw the control using the GraphicsDevice.                    
  145.                     Draw();
  146.                     OnAfterDraw(EventArgs.Empty);
  147.                     EndDraw();
  148.                 }
  149.                 else
  150.                 {
  151.                     // If BeginDraw failed, show an error message using System.Drawing.
  152.                     PaintUsingSystemDrawing(e.Graphics, beginDrawError);
  153.                 }
  154.             }
  155.             catch (Exception ex)
  156.             {
  157.                 //MessageBox.Show(ex.StackTrace, ex.Message,MessageBoxButtons.OK,MessageBoxIcon.Error);
  158.                 Debug.WriteLine("EXCEPTION: " + ex.Message);
  159.             }
  160.             return;
  161.         }
  162.  
  163.  
  164.         /// <summary>
  165.         /// Attempts to begin drawing the control. Returns an error message string
  166.         /// if this was not possible, which can happen if the graphics device is
  167.         /// lost, or if we are running inside the Form designer.
  168.         /// </summary>
  169.         internal string BeginDraw()
  170.         {
  171.             // If we have no graphics device, we must be running in the designer.
  172.             if (graphicsDeviceService == null)
  173.             {
  174.                 return Text + "\n\n" + GetType();
  175.             }
  176.  
  177.             // Make sure the graphics device is big enough, and is not lost.
  178.             string deviceResetError = HandleDeviceReset();
  179.  
  180.             if (!string.IsNullOrEmpty(deviceResetError))
  181.             {
  182.                 return deviceResetError;
  183.             }
  184.  
  185.             GraphicsDevice.SetRenderTarget(_renderTarget);
  186.  
  187.             // Many GraphicsDeviceControl instances can be sharing the same
  188.             // GraphicsDevice. The device backbuffer will be resized to fit the
  189.             // largest of these controls. But what if we are currently drawing
  190.             // a smaller control? To avoid unwanted stretching, we set the
  191.             // viewport to only use the top left portion of the full backbuffer.
  192.             GraphicsDevice.Viewport = this.Viewport;
  193.  
  194.             return null;
  195.         }
  196.  
  197.         public Viewport Viewport { get { return new Viewport(0, 0, ClientSize.Width, ClientSize.Height); } }
  198.  
  199.  
  200.         /// <summary>
  201.         /// Ends drawing the control. This is called after derived classes
  202.         /// have finished their Draw method, and is responsible for presenting
  203.         /// the finished image onto the screen, using the appropriate WinForms
  204.         /// control handle to make sure it shows up in the right place.
  205.         /// </summary>
  206.         internal void EndDraw()
  207.         {
  208.             try
  209.             {
  210.                 Rectangle sourceRectangle = new Rectangle(0, 0, ClientSize.Width,
  211.                                                                 ClientSize.Height);
  212.                 _renderTarget.Present();
  213.             }
  214.             catch
  215.             {
  216.                 // Present might throw if the device became lost while we were
  217.                 // drawing. The lost device will be handled by the next BeginDraw,
  218.                 // so we just swallow the exception.
  219.             }
  220.         }
  221.  
  222.  
  223.         /// <summary>
  224.         /// Helper used by BeginDraw. This checks the graphics device status,
  225.         /// making sure it is big enough for drawing the current control, and
  226.         /// that the device is not lost. Returns an error string if the device
  227.         /// could not be reset.
  228.         /// </summary>
  229.         string HandleDeviceReset()
  230.         {
  231.             bool deviceNeedsReset = false;
  232.  
  233.             switch (GraphicsDevice.GraphicsDeviceStatus)
  234.             {
  235.                 case GraphicsDeviceStatus.Lost:
  236.                     // If the graphics device is lost, we cannot use it at all.
  237.                     return "Graphics device lost";
  238.  
  239.                 case GraphicsDeviceStatus.NotReset:
  240.                     // If device is in the not-reset state, we should try to reset it.
  241.                     deviceNeedsReset = true;
  242.                     break;
  243.  
  244.                 default:
  245.                     // If the device state is ok, check whether it is big enough.
  246.                     PresentationParameters pp = GraphicsDevice.PresentationParameters;
  247.  
  248.                     deviceNeedsReset = (ClientSize.Width != pp.BackBufferWidth) ||
  249.                                        (ClientSize.Height != pp.BackBufferHeight);
  250.                     break;
  251.             }
  252.  
  253.             // Do we need to reset the device?
  254.             if (deviceNeedsReset)
  255.             {
  256.                 try
  257.                 {
  258.                     graphicsDeviceService.ResetDevice(_renderTarget.Width,
  259.                                                       _renderTarget.Height);
  260.  
  261.                     //recreate window swapchain
  262.                     _renderTarget.Dispose();
  263.                     _renderTarget = new SwapChainRenderTarget(GraphicsDevice, Handle, ClientSize.Width, ClientSize.Height);
  264.                 }
  265.                 catch (Exception e)
  266.                 {
  267.                     return "Graphics device reset failed\n\n" + e;
  268.                 }
  269.             }
  270.  
  271.             return null;
  272.         }
  273.  
  274.  
  275.         /// <summary>
  276.         /// If we do not have a valid graphics device (for instance if the device
  277.         /// is lost, or if we are running inside the Form designer), we must use
  278.         /// regular System.Drawing method to display a status message.
  279.         /// </summary>
  280.         protected virtual void PaintUsingSystemDrawing(Graphics graphics, string text)
  281.         {
  282.             graphics.Clear(Color.CornflowerBlue);
  283.  
  284.             using (Brush brush = new SolidBrush(Color.Black))
  285.             {
  286.                 using (StringFormat format = new StringFormat())
  287.                 {
  288.                     format.Alignment = StringAlignment.Center;
  289.                     format.LineAlignment = StringAlignment.Center;
  290.  
  291.                     graphics.DrawString(text, Font, brush, ClientRectangle, format);
  292.                 }
  293.             }
  294.         }
  295.  
  296.         /// <summary>
  297.         /// Ignores WinForms paint-background messages. The default implementation
  298.         /// would clear the control to the current background color, causing
  299.         /// flickering when our OnPaint implementation then immediately draws some
  300.         /// other color over the top using the XNA Framework GraphicsDevice.
  301.         /// </summary>
  302.         protected override void OnPaintBackground(PaintEventArgs pevent)
  303.         {
  304.         }
  305.  
  306.  
  307.         #endregion
  308.  
  309.         #region Abstract Methods
  310.  
  311.         /// <summary>
  312.         /// Derived classes override this to initialize their drawing code.
  313.         /// </summary>
  314.         abstract protected void Initialize();
  315.  
  316.         /// <summary>
  317.         /// Derived classes override this to draw themselves using the GraphicsDevice.
  318.         /// </summary>
  319.         abstract internal void Draw();
  320.  
  321.         #endregion
  322.  
  323.  
  324.         private readonly object AfterDrawEventLock = new object();
  325.         private EventHandler AfterDrawEvent;
  326.         public event EventHandler AfterDraw
  327.         {
  328.             add { lock (AfterDrawEventLock) { AfterDrawEvent += value; } }
  329.             remove { lock (AfterDrawEventLock) { AfterDrawEvent -= value; } }
  330.         }
  331.         protected virtual void OnAfterDraw(EventArgs e)
  332.         {
  333.             EventHandler handler = null;
  334.             lock (AfterDrawEventLock)
  335.             {
  336.                 handler = AfterDrawEvent;
  337.                 if (handler == null) return;
  338.             }
  339.             handler(this, e);
  340.         }
  341.     }
  342. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement