I have created a new control that derives from UserControl. In that control, I add the D3D device, swapchain, etc, and that control will present a 3D display. I am having some repainting issues in that the control does not seem to like when Invalidate() is called to repaint itself. Inside the repaint I have:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if(_d3dDevice != null)
{
_d3dDevice.ClearRenderTargetView(_renderTargetView, Color.Blue);
_d3dDevice.ClearDepthStencilView(_depthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
_swapChain.Present(0, PresentFlags.None);
}
}
However, on the first paint something is not working because the control is painted gray and not Blue. If I resize the window (not having overridden OnResize, it turns Blue). If I override OnResize, and call Invalidate from it, it turns gray.
What is strange is I have copy and paste the same D3D initialization code into a Form, and it works correctly. Anyone know why a UserControl might be throwing it off?
private void InitDirect3D()
{
SwapChainDescription sd = new SwapChainDescription();
sd.ModeDescription = new ModeDescription(Width, Height, new SlimDX.Rational(60, 1), Format.R8G8B8A8_UNorm);
sd.SampleDescription = new SampleDescription(1, 0);
sd.Usage = Usage.RenderTargetOutput;
sd.BufferCount = 1;
sd.OutputHandle = Handle;
sd.IsWindowed = true;
sd.SwapEffect = SwapEffect.Discard;
sd.Flags = SwapChainFlags.None;
// Create the device.
DeviceCreationFlags createDeviceFlags = DeviceCreationFlags.None;
#if DEBUG
createDeviceFlags |= DeviceCreationFlags.Debug;
#endif
SlimDX.Direct3D10.Device.CreateWithSwapChain(null, DriverType.Hardware,
createDeviceFlags, sd, out _d3dDevice, out _swapChain);
ResizeBackBuffer();
}
private void ResizeBackBuffer()
{
// Release the old views, as they hold references to the buffers we
// will be destroying. Also release the old depth/stencil buffer.
if(_renderTargetView != null)
_renderTargetView.Dispose();
if(_depthStencilView != null)
_depthStencilView.Dispose();
if(_depthStencilBuffer != null)
_depthStencilBuffer.Dispose();
_swapChain.ResizeBuffers(1, ClientSize.Width, ClientSize.Height, Format.R8G8B8A8_UNorm, SwapChainFlags.None);
Texture2D backBuffer = Texture2D.FromSwapChain<Texture2D>(_swapChain, 0);
_renderTargetView = new RenderTargetView(_d3dDevice, backBuffer);
backBuffer.Dispose();
// Create the depth/stencil buffer and view.
Texture2DDescription depthStencilDesc = new Texture2DDescription();
depthStencilDesc.Width = ClientSize.Width;
depthStencilDesc.Height = ClientSize.Height;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = Format.D24_UNorm_S8_UInt;
depthStencilDesc.SampleDescription = new SampleDescription(1, 0);
depthStencilDesc.Usage = ResourceUsage.Default;
depthStencilDesc.BindFlags = BindFlags.DepthStencil;
depthStencilDesc.CpuAccessFlags = 0;
depthStencilDesc.OptionFlags = ResourceOptionFlags.None;
_depthStencilBuffer = new Texture2D(_d3dDevice, depthStencilDesc);
_depthStencilView = new DepthStencilView(_d3dDevice, _depthStencilBuffer);
// Bind the render target view and depth/stencil view to the pipeline.
_d3dDevice.OutputMerger.SetTargets(_depthStencilView, _renderTargetView);
// Set the viewport transform.
Viewport vp = new Viewport(0, 0, ClientSize.Width, ClientSize.Height, 0.0f, 1.0f);
_d3dDevice.Rasterizer.SetViewports(vp);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!DesignMode)
{
InitDirect3D();
}
}
private SlimDX.Direct3D10.Device _d3dDevice;
private SwapChain _swapChain;
private Texture2D _depthStencilBuffer;
private RenderTargetView _renderTargetView;
private DepthStencilView _depthStencilView;