Question

I am stuck at the very beginning of slim DX..

My MdiParent name is view

What I want to do is create a RenderForm() or simular, Inside of a Form Application as MdiChild, the RenderForm() is a form where we display DirectX. The reason for this is to be able to create Menubars and buttons etc Inside the Parent form. I have tryed to create a new form for the rendering but it doesn't work very well with MessagePump(). The whole application hangs. The reason for this might be a endless loop. One other method I have tryed is to create a RenderForm inside the view by Calling a function from Main Program This doesn't work very well either since the Main Program aint executing any code after

Application.EnableVisualStyles();
Application.Run(new view()); 

I have tryed a ton of diffrent methods I came up with but with no success. I have googled for hours without result.

The code I am trying to modify is copyed from the SlimDX tutorial 2:

    using System.Windows.Forms;
    using SlimDX;
    using SlimDX.Direct3D11;
    using SlimDX.DXGI;
    using SlimDX.Windows;
    using Device = SlimDX.Direct3D11.Device;
    using Resource = SlimDX.Direct3D11.Resource;

    namespace DeviceCreation
    {
        static class Program
        {
            static void Main()
            {
                var form = new RenderForm("Tutorial 2: Device Creation");
                var description = new SwapChainDescription()
                {
                    BufferCount = 1,
                    Usage = Usage.RenderTargetOutput,
                    OutputHandle = form.Handle,
                    IsWindowed = true,
                    ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format.R8G8B8A8_UNorm),
                    SampleDescription = new SampleDescription(1, 0),
                    Flags = SwapChainFlags.AllowModeSwitch,
                    SwapEffect = SwapEffect.Discard
                };

                Device device;
                SwapChain swapChain;
                Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, description, out device, out swapChain);

                // create a view of our render target, which is the backbuffer of the swap chain we just created
                RenderTargetView renderTarget;
                using (var resource = Resource.FromSwapChain(swapChain, 0))
                    renderTarget = new RenderTargetView(device, resource);

                // setting a viewport is required if you want to actually see anything
                var context = device.ImmediateContext;
                var viewport = new Viewport(0.0f, 0.0f, form.ClientSize.Width, form.ClientSize.Height);
                context.OutputMerger.SetTargets(renderTarget);
                context.Rasterizer.SetViewports(viewport);

                // prevent DXGI handling of alt+enter, which doesn't work properly with Winforms
                using (var factory = swapChain.GetParent())
                    factory.SetWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAltEnter);

                // handle alt+enter ourselves
                form.KeyDown += (o, e) =>
                {
                    if (e.Alt && e.KeyCode == Keys.Enter)
                        swapChain.IsFullScreen = !swapChain.IsFullScreen;
                };

                MessagePump.Run(form, () =>
                {
                    // clear the render target to a soothing blue
                    context.ClearRenderTargetView(renderTarget, new Color4(0.5f, 0.5f, 1.0f));
                    swapChain.Present(0, PresentFlags.None);
                });

                // clean up all resources
                // anything we missed will show up in the debug output
                renderTarget.Dispose();
                swapChain.Dispose();
                device.Dispose();
            }
        }
    }


I have never succeeded to place the MessagePump() outside the Main Program.

Was it helpful?

Solution

Iv'e been playing with SlimDX for a few days now. MessagePump() does create an endless loop. I believe you can either create the child form on a new thread or just extend the parent with RenderForm instead of Form, which is what I did.

public partial class view: RenderForm
{
    public View()
    {
        // The static void Main code goes here
    }
}

edit

This is how you would start it on a new thread from the parent:

public partial class Form1 : Form
{
    Form2 renderForm;

    public Form1()
    {
        InitializeComponent();

        openNewRenderForm();
    }

    private void openNewRenderForm()
    {
        Thread thread = new Thread(new ThreadStart(startRenderForm));
        thread.Start();
    }

    private void startRenderForm()
    {
        renderForm = new Form2();
    }
}

Just remove the "var form = new RenderForm("Tutorial 2: Device Creation");" line from the RenderForm if the Form2 extends the RenderForm.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top