Click here to Skip to main content
15,888,340 members
Please Sign up or sign in to vote.
4.50/5 (2 votes)
See more:
I have one project using XNA 4.0 and win form. I want to render with XNA 4.0 inside a windows form. But I don't know how.
If any of you have any idea then please tell me know. Thanks!
Posted
Updated 7-Oct-12 5:59am
v3

1 solution

using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
using System.Threading;
namespace XNAWinForms
{
    using Color = System.Drawing.Color;
    using Rectangle = Microsoft.Xna.Framework.Rectangle;  
    public class ServiceContainer : IServiceProvider
    {
        Dictionary<Type, object> services = new Dictionary<Type, object>();

        public void AddService<T>(T service)
        {
            services.Add(typeof(T), service);
        }
        public object GetService(Type serviceType)
        {
            object service;
            services.TryGetValue(serviceType, out service);
            return service;
        }
    }
    class GraphicsDeviceService : IGraphicsDeviceService
    {
        #region Fields
        static GraphicsDeviceService singletonInstance;
        static int referenceCount;

        #endregion
        GraphicsDeviceService(IntPtr windowHandle, int width, int height)
        {
            parameters = new PresentationParameters();
            parameters.BackBufferWidth = Math.Max(width, 1);
            parameters.BackBufferHeight = Math.Max(height, 1);
            parameters.BackBufferFormat = SurfaceFormat.Color;
            parameters.DepthStencilFormat = DepthFormat.Depth24;
            parameters.DeviceWindowHandle = windowHandle;
            parameters.PresentationInterval = PresentInterval.Immediate;
            parameters.IsFullScreen = false;
            graphicsDevice = new GraphicsDevice(GraphicsAdapter.DefaultAdapter,
                                                GraphicsProfile.Reach,
                                                parameters);
        }

        public static GraphicsDeviceService AddRef(IntPtr windowHandle,
                                                   int width, int height)
        {
            if (Interlocked.Increment(ref referenceCount) == 1)
            {
                singletonInstance = new GraphicsDeviceService(windowHandle,
                                                              width, height);
            }
            return singletonInstance;
        }
        public void Release(bool disposing)
        {
            if (Interlocked.Decrement(ref referenceCount) == 0)
            {
                if (disposing)
                {
                    if (DeviceDisposing != null)
                        DeviceDisposing(this, EventArgs.Empty);
                    graphicsDevice.Dispose();
                }
                graphicsDevice = null;
            }
        }
        public void ResetDevice(int width, int height)
        {
            if (DeviceResetting != null)
                DeviceResetting(this, EventArgs.Empty);
            parameters.BackBufferWidth = Math.Max(parameters.BackBufferWidth, width);
            parameters.BackBufferHeight = Math.Max(parameters.BackBufferHeight, height);
            graphicsDevice.Reset(parameters);
            if (DeviceReset != null)
                DeviceReset(this, EventArgs.Empty);
        }

        public GraphicsDevice GraphicsDevice
        {
            get { return graphicsDevice; }
        }
        GraphicsDevice graphicsDevice;

        PresentationParameters parameters;

        // IGraphicsDeviceService events.
        public event EventHandler<EventArgs> DeviceCreated;
        public event EventHandler<EventArgs> DeviceDisposing;
        public event EventHandler<EventArgs> DeviceReset;
        public event EventHandler<EventArgs> DeviceResetting;
    }
    abstract public class GraphicsDeviceControl : Control
    {
        #region Fields

        GraphicsDeviceService graphicsDeviceService;

        #endregion
        #region Properties

        public GraphicsDevice GraphicsDevice
        {
            get { return graphicsDeviceService.GraphicsDevice; }
        }
        public ServiceContainer Services
        {
            get { return services; }
        }
        ServiceContainer services = new ServiceContainer();

        #endregion
        #region Initialization

        protected override void OnCreateControl()
        {
            if (!DesignMode)
            {
                graphicsDeviceService = GraphicsDeviceService.AddRef(Handle,ClientSize.Width,ClientSize.Height);
                services.AddService<IGraphicsDeviceService>(graphicsDeviceService);
                Initialize();
            }
            base.OnCreateControl();
        }
        protected override void Dispose(bool disposing)
        {
            if (graphicsDeviceService != null)
            {
                graphicsDeviceService.Release(disposing);
                graphicsDeviceService = null;
            }
            base.Dispose(disposing);
        }

        #endregion
        #region Paint
        public bool Render(RenderTarget2D _target)
        {
            return Render(_target, 0, 0);
        }
        public bool Render(RenderTarget2D _target,int _left, int _top)
        {
            GraphicsDevice.SetRenderTarget(_target);
            try
            {
                return Render(_left,_top,_target.Width, _target.Height);
            }
            finally
            {
                GraphicsDevice.SetRenderTarget(null);
            }
        }
        public bool Render()
        {
            return Render(0,0);
        }
        public bool Render(int _left, int _top, int _width, int _height)
        {
            return Render(new System.Drawing.Rectangle(_left, _top, _width, _height));
        }
        public bool Render(int _width, int _height)
        {
            return Render(new System.Drawing.Rectangle(0, 0, _width, _height));
        }
        public bool Render(System.Drawing.Rectangle _rect)
        {
            string beginDrawError = "";
            return Render(ref beginDrawError, _rect); 
        }
        protected bool Render(ref string beginDrawError, System.Drawing.Rectangle _rect)
        {
            if (_rect.Width == 0) _rect.Width = ClientSize.Width;
            if (_rect.Height == 0) _rect.Height = ClientSize.Height;
            beginDrawError = BeginDraw(_rect);
            if (string.IsNullOrEmpty(beginDrawError))
            {
                // Draw the control using the GraphicsDevice.
                Draw();
                EndDraw();
                return true;
            }
            return false;
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            string beginDrawError = "";
            if (!Render(ref beginDrawError,ClientRectangle))
            {
                PaintUsingSystemDrawing(e.Graphics, beginDrawError);
            }
        }
        private string BeginDraw()
        {
            return BeginDraw(0,0,ClientSize.Width, ClientSize.Height);
        }
        private string BeginDraw(int _left, int _top, int _width, int _height)
        {
            return BeginDraw(new System.Drawing.Rectangle(_left, _top, _width, _height));
        }
        private string BeginDraw(int _width, int _height)
        {
            return BeginDraw(0,0,_width, _height);
        }
        private string BeginDraw(System.Drawing.Rectangle _rect)
        {
            if (graphicsDeviceService == null)
            {
                return Text + "\n\n" + GetType();
            }
            string deviceResetError = HandleDeviceReset();
            if (!string.IsNullOrEmpty(deviceResetError))
            {
                return deviceResetError;
            }

            Viewport viewport = new Viewport();
            viewport.X = _rect.Left;
            viewport.Y = _rect.Top;
            viewport.Width = _rect.Width;
            viewport.Height = _rect.Height;
            viewport.MinDepth = 0;
            viewport.MaxDepth = 1;
            GraphicsDevice.Viewport = viewport;
            return null;
        }

        private void EndDraw()
        {
            try
            {
                Rectangle sourceRectangle = new Rectangle(0, 0, ClientSize.Width,
                                                                ClientSize.Height);
                GraphicsDevice.Present(sourceRectangle, null, this.Handle);
            }
            catch
            {
            }
        }

        private string HandleDeviceReset()
        {
            bool deviceNeedsReset = false;
            switch (GraphicsDevice.GraphicsDeviceStatus)
            {
                case GraphicsDeviceStatus.Lost:
                    // If the graphics device is lost, we cannot use it at all.
                    return "Graphics device lost";
                case GraphicsDeviceStatus.NotReset:
                    // If device is in the not-reset state, we should try to reset it.
                    deviceNeedsReset = true;
                    break;
                default:
                    // If the device state is ok, check whether it is big enough.
                    PresentationParameters pp = GraphicsDevice.PresentationParameters;
                    deviceNeedsReset = (ClientSize.Width > pp.BackBufferWidth) ||
                                       (ClientSize.Height > pp.BackBufferHeight);
                    break;
            }
            // Do we need to reset the device?
            if (deviceNeedsReset)
            {
                try
                {
                    graphicsDeviceService.ResetDevice(ClientSize.Width,
                                                      ClientSize.Height);
                }
                catch (Exception e)
                {
                    return "Graphics device reset failed\n\n" + e;
                }
            }
            return null;
        }
        protected virtual void PaintUsingSystemDrawing(Graphics graphics, string text)
        {
            graphics.Clear(Color.CornflowerBlue);
            using (Brush brush = new SolidBrush(Color.Black))
            {
                using (StringFormat format = new StringFormat())
                {
                    format.Alignment = StringAlignment.Center;
                    format.LineAlignment = StringAlignment.Center;
                    graphics.DrawString(text, Font, brush, ClientRectangle, format);
                }
            }
        }

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
        }

        #endregion
        #region Abstract Methods

        /// <summary>
        /// Derived classes override this to initialize their drawing code.
        /// </summary>
        protected abstract void Initialize();

        /// <summary>
        /// Derived classes override this to draw themselves using the GraphicsDevice.
        /// </summary>
        protected abstract void Draw();

        #endregion
    }
}


Inherit Your control from this one.
Override Draw and Initialize Methods.
Enjoy.

Regards,
Maxim.
 
Share this answer
 
Comments
haitrieu749 7-Oct-12 12:06pm    
First thanks very much! But I used your code and built error...I don't know where I was wrong. Have you example code? Can you share it!! Thanks. (sorry about bad english).
haitrieu749 7-Oct-12 12:08pm    
I use XNA 4.0 and rendering 3D.
Maxim Kartavenkov 7-Oct-12 12:29pm    
Yes, I also uses the XNA 4.0.
Try this link:
http://xbox.create.msdn.com/en-US/education/catalog/sample/winforms_series_1

Maxim.
Maxim Kartavenkov 7-Oct-12 12:32pm    
This one is also seems contains similar stuff
http://www.codeproject.com/Articles/21330/Easy-Rendering-with-XNA-Inside-a-Windows-Form
haitrieu749 8-Oct-12 2:02am    
Thank you very much!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900