예제 #1
0
        public unsafe static LightDevice Create(Control ctrl, int initWidth = -1, int initHeight = -1)
        {
            var ret = new LightDevice();

            //initialize size
            {
                var width  = initWidth == -1 ? ctrl.ClientSize.Width : initWidth;
                var height = initHeight == -1 ? ctrl.ClientSize.Height : initHeight;

                ret._ctrl   = ctrl;
                ret._form   = ctrl.FindForm();
                ret._width  = width;
                ret._height = height;
                ret._dpi    = GetDpiForWindow(ret._form.Handle);
            }

            try
            {
                using (var adapter = new ComScopeGuard())
                {
                    //Find the adapter
                    adapter.Ptr = GetAdapter();

                    //create core objects
                    IntPtr swapChain, device, immediateContext;
                    {
                        var d = new SwapChainDescription(ctrl.Handle, ret._width, ret._height);

                        Native.D3D11CreateDeviceAndSwapChain(
                            adapter.Ptr, adapter.Ptr == IntPtr.Zero ? 1u : 0u,
                            IntPtr.Zero, 0, IntPtr.Zero, 0, 7, ref d,
                            out swapChain, out device, out var featureLevel, out immediateContext).Check();

                        ret._device    = device;
                        ret._swapchain = swapChain;
                        ret._context   = immediateContext;
                    }

                    //get default render target
                    IntPtr renderView;
                    {
                        using (var backBuffer = new ComScopeGuard())
                        {
                            SwapChain.GetBuffer(swapChain, 0, Guids.Texture2D, out backBuffer.Ptr).Check();
                            Device.CreateRenderTargetView(device, backBuffer.Ptr, null, out renderView).Check();
                        }
                        ret._defaultRenderView = renderView;
                    }

                    //get DXGI.Output
                    {
                        var i = Adapter.EnumOutputs(adapter.Ptr, 0, out var output);
                        //Sometimes this can fail, but it should not affect our other functions.
                        //TODO Actually we should think of supporting multiple outputs.
                        if (i != 0x887A0002)
                        {
                            i.Check();
                        }
                        ret._output = output;
                    }

                    ret._defaultRenderTarget = RenderTargetObject.CreateSwapchainTarget(ret);
                    ret.AddEventHandlers();
                }
            }
            catch (NativeException e)
            {
                ret.Dispose(true);
                throw e;
            }
            return(ret);
        }