Search code examples
sharpdx

SharpDX:How to place SharpDX Window in Winforms Window?


I'm actually tryin to place SharpDX Window in Winforms Window like in the following video: http://www.youtube.com/watch?v=g-JupOxwB-k

In SharpDX this method doesn't work.Can anyone tell me how to EASILY do this ?


Solution

  • don't think of it as putting a sharpDX window into a winforms window.

    instead think of it as how to output SharpDX to the windows handle (sorta)

    the key is in the SharpDX.DXGI.SwapChain. when creating this you will need a SwapChainDescription

    I like to create mine like

    SwapChainDescription scd = new SwapChainDescription()
    {
      //set other fields
      OutputHandle = yourform.Handle,
      //set other fields
    };
    

    Handle SwapChainDescription

    so when you call SwapChain.Present() it will render to the form.

    this is the basic way to do it with straight SharpDX and not the toolkit stuff

    EDIT 04222019 LINKS DO NOT WORK --- 01052022 Link fixed

    if you want to use the toolkit's GraphicsDevice you will have to set the Presenter property. in almost the same way you set the window handle in the presentation parameters.

    https://github.com/sharpdx/Toolkit/tree/master/Documentation

    also the toolkit has the RenderForm which plays nice with the Game class

    04222019

    EDIT (DirectX Example)

    here is an example using straight SharpDX (No Toolkit). for complete examples you should refer to the github examples HERE

    As stated above all you need to do to render to a WindowsForm window is pass the Handle to the SwapChain

    visual studio 2012

    1. add the references: (all other references are default winforms project references)

    references to add

    1. some using statements to make things easier:

         namespace YourNameSpaceHere
         {
             using Device = SharpDX.Direct3D11.Device;
      
             using Buffer = SharpDX.Direct3D11.Buffer;
      
             ...the rest of the application
         } 
      
    2. the Form class: here we make the device, swap chain, render target , and render target view a variable of the Form class we are declaring

       public partial class Form1 : Form //default vs2012 declaration
       {
           Device d;                   //Direct311
           SwapChain sc;               //DXGI
      
           Texture2D target;           //Direct3D11
           RenderTargetView targetveiw;//DIrect3D11
      
           ...the rest of the form
      
       }       
      
    3. Initializing the Device and SwapChain: this is what works for me on my system. if you have problems than you need to research your specific implementation and hardware. DirectX (and by extension SharpDX) has methods by which you can detect what the hardware will support.

    the main code Example:

    using System;
    
    using System.ComponentModel;//needed to overide OnClosing
    //I removed useless usings
    using System.Windows.Forms;
    
    using SharpDX.Direct3D11;
    using SharpDX.DXGI;
    using SharpDX;
    
    
    namespace WindowsFormsApplication2
    {
    using Device = SharpDX.Direct3D11.Device;
    using Buffer = SharpDX.Direct3D11.Buffer;
    
    
    public partial class Form1 : Form
    {
        Device d;
        SwapChain sc;
    
        Texture2D target;
        RenderTargetView targetveiw;       
    
        public Form1()
        {
            InitializeComponent();
    
            SwapChainDescription scd = new SwapChainDescription()
            {
                BufferCount = 1,                                 //how many buffers are used for writing. it's recommended to have at least 2 buffers but this is an example
                Flags = SwapChainFlags.None,
                IsWindowed = true,                               //it's windowed
                ModeDescription = new ModeDescription(
                    this.ClientSize.Width,                       //windows veiwable width
                    this.ClientSize.Height,                      //windows veiwable height
                    new Rational(60,1),                          //refresh rate
                    Format.R8G8B8A8_UNorm),                      //pixel format, you should resreach this for your specific implementation
    
                OutputHandle = this.Handle,                      //the magic 
    
                SampleDescription = new SampleDescription(1, 0), //the first number is how many samples to take, anything above one is multisampling.
                SwapEffect = SwapEffect.Discard,
                Usage = Usage.RenderTargetOutput
            };
    
            Device.CreateWithSwapChain(
                SharpDX.Direct3D.DriverType.Hardware,//hardware if you have a graphics card otherwise you can use software
                DeviceCreationFlags.Debug,           //helps debuging don't use this for release verion
                scd,                                 //the swapchain description made above
                out d, out sc                        //our directx objects
                );
    
            target = Texture2D.FromSwapChain<Texture2D>(sc, 0);
            targetveiw = new RenderTargetView(d, target);
    
            d.ImmediateContext.OutputMerger.SetRenderTargets(targetveiw);
    
        }
    
        protected override void OnClosing(CancelEventArgs e)
        {
            //dipose of all objects
            d.Dispose();
            sc.Dispose();
            target.Dispose();
            targetveiw.Dispose();
                       
            base.OnClosing(e);
        }
    
        protected override void OnPaint(PaintEventArgs e)
        {
            //I am rendering here for this example
            //normally I use a seperate thread to call Draw() and Present() in a loop
            d.ImmediateContext.ClearRenderTargetView(targetveiw, Color.CornflowerBlue);//Color to make it look like default XNA project output.
            sc.Present(0, PresentFlags.None);
    
            base.OnPaint(e);
        }
    
    }
    }
    

    this is meant to get you started with using DirectX using ShaprDX in a managed environment, specifically C# on Windows. there is much much more you will need to get something real off the ground. and this is meant as the gateway to rendering on a Winforms window using SharpDX. I don't explain things like vertex/index buffers or rendering Textures/Sprites. because it is out of scope for the question.