like in the title said, i add an UserControl to a TabControl. This is just working fine. But when i'm starting to Render to this UserControl using SharpDX.Direct3D11 the tab disappears.
I tried to keep it as simple as possible to get the control working. The code i use to render to the control is from the provided samples. The "MiniCube" sample is working when i build it in the provided solution.
Here is the code i use to render:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SDX = SharpDX;
using SharpDX.D3DCompiler;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Windows;
using Buffer = SharpDX.Direct3D11.Buffer;
using Device = SharpDX.Direct3D11.Device;
using OpenTK;
namespace mynamespace.SharpDX
{
public class SharpDXRenderManager
{
private UserControl renderTarget;
public SharpDXRenderManager(UserControl renderTarget)
{
this.renderTarget = renderTarget;
}
public void Render()
{
var desc = new SDX.DXGI.SwapChainDescription()
{
BufferCount = 1,
ModeDescription = new SDX.DXGI.ModeDescription(this.renderTarget.ClientSize.Width, this.renderTarget.ClientSize.Height, new SDX.DXGI.Rational(60, 1), Format.R8G8B8A8_UNorm),
IsWindowed = true,
OutputHandle = this.renderTarget.Handle,
SampleDescription = new SampleDescription(1, 0),
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput
};
Device device;
SwapChain swapChain;
Device.CreateWithSwapChain(SDX.Direct3D.DriverType.Hardware, SDX.Direct3D11.DeviceCreationFlags.Debug, desc, out device, out swapChain);
var context = device.ImmediateContext;
var factory = swapChain.GetParent<Factory>();
factory.MakeWindowAssociation(this.renderTarget.Handle, WindowAssociationFlags.IgnoreAll);
var vertexShaderByteCode = SDX.D3DCompiler.ShaderBytecode.CompileFromFile(mypath, "VS", "vs_4_0");
var vertexShader = new SDX.Direct3D11.VertexShader(device, vertexShaderByteCode);
var pixelShaderByteCode = SDX.D3DCompiler.ShaderBytecode.CompileFromFile(mypath, "PS", "ps_4_0");
var pixelShader = new SDX.Direct3D11.PixelShader(device, pixelShaderByteCode);
var signature = SDX.D3DCompiler.ShaderSignature.GetInputSignature(vertexShaderByteCode);
var layout = new SDX.Direct3D11.InputLayout(device, signature, new[]
{
new SDX.Direct3D11.InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
new SDX.Direct3D11.InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0)
});
var vertices = Buffer.Create(device, SDX.Direct3D11.BindFlags.VertexBuffer, new[]
{
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), // Front
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // BACK
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Top
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f,-1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), // Bottom
new Vector4( 1.0f,-1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f,-1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f,-1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4( 1.0f,-1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4( 1.0f,-1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), // Left
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), // Right
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
});
var contantBuffer = new Buffer(device, SDX.Utilities.SizeOf<Matrix4>(), SDX.Direct3D11.ResourceUsage.Default, SDX.Direct3D11.BindFlags.ConstantBuffer, SDX.Direct3D11.CpuAccessFlags.None, SDX.Direct3D11.ResourceOptionFlags.None, 0);
context.InputAssembler.InputLayout = layout;
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, SDX.Utilities.SizeOf<Vector4>() * 2, 0));
context.VertexShader.SetConstantBuffer(0, contantBuffer);
context.VertexShader.Set(vertexShader);
context.PixelShader.Set(pixelShader);
var view = Matrix4.LookAt(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
var proj = Matrix4.Identity;
var clock = new Stopwatch();
clock.Start();
bool userResized = true;
Texture2D backBuffer = null;
RenderTargetView renderView = null;
Texture2D depthBuffer = null;
DepthStencilView depthView = null;
this.renderTarget.Resize += (sender, args) => userResized = true;
RenderLoop.Run(this.renderTarget, () =>
{
if (userResized)
{
SDX.Utilities.Dispose(ref backBuffer);
SDX.Utilities.Dispose(ref renderView);
SDX.Utilities.Dispose(ref depthBuffer);
SDX.Utilities.Dispose(ref depthView);
swapChain.ResizeBuffers(desc.BufferCount, this.renderTarget.ClientSize.Width, renderTarget.ClientSize.Height, Format.Unknown, SwapChainFlags.None);
backBuffer = Texture2D.FromSwapChain<Texture2D>(swapChain, 0);
renderView = new RenderTargetView(device, backBuffer);
depthBuffer = new Texture2D(device, new Texture2DDescription()
{
Format = Format.D32_Float_S8X24_UInt,
ArraySize = 1,
MipLevels = 1,
Width = this.renderTarget.ClientSize.Width,
Height = this.renderTarget.ClientSize.Height,
SampleDescription = new SampleDescription(1, 0),
Usage = ResourceUsage.Default,
BindFlags = BindFlags.DepthStencil,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None
});
depthView = new DepthStencilView(device, depthBuffer);
context.Rasterizer.SetViewport(0f, 0f, this.renderTarget.ClientSize.Width, this.renderTarget.ClientSize.Height, 0f, 1f);
context.OutputMerger.SetTargets(depthView, renderView);
proj = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, this.renderTarget.ClientSize.Width / (float)this.renderTarget.ClientSize.Height, 0.1f, 100f);
userResized = false;
}
var time = clock.ElapsedMilliseconds / 1000f;
var viewProj = Matrix4.Mult(view, proj);
context.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1f, 0);
context.ClearRenderTargetView(renderView, new SDX.Mathematics.Interop.RawColor4(255f, 255f, 255f, 255f));
var worldViewProj = Matrix4.CreateRotationX(time) * Matrix4.CreateRotationY(time * 2f) * Matrix4.CreateRotationZ(time * 0.7f) * viewProj;
worldViewProj.Transpose();
context.UpdateSubresource(ref worldViewProj, contantBuffer);
swapChain.Present(0, PresentFlags.None);
});
signature.Dispose();
vertexShaderByteCode.Dispose();
vertexShader.Dispose();
pixelShaderByteCode.Dispose();
pixelShader.Dispose();
vertices.Dispose();
layout.Dispose();
contantBuffer.Dispose();
depthBuffer.Dispose();
depthView.Dispose();
renderView.Dispose();
backBuffer.Dispose();
context.ClearState();
context.Flush();
device.Dispose();
context.Dispose();
swapChain.Dispose();
factory.Dispose();
}
}
}
I don't get any Exceptions or anything else. The Tab just disappears and that#s all. As far as i could tell the code is running, this i have checked in a debug session.
The SharpDXRenderManager is only called from the UserControl itself, here the code:
public partial class Planner : UserControl
{
private SharpDXRenderManager renderManager;
public Planner()
{
InitializeComponent();
renderManager = new SharpDXRenderManager(this);
renderManager.Render();
}
}
The Problem is that i have started the render process straight after the initialization. I solved it by calling the Render() method in the the OnLoad(EventArgs e) Event.