2016-04-29 8 views
0

wie im Titel gesagt, ich füge ein UserControl zu einem TabControl. Das funktioniert einfach gut. Aber wenn ich mit SharpDX.Direct3D11 auf dieses UserControl rendere, verschwindet die Registerkarte.C# Hinzufügen von UserControl zu TabControl dann Rendern mit SharpDX

Ich habe versucht, es so einfach wie möglich zu halten, damit die Steuerung funktioniert. Der Code, den ich für das Steuerelement verwende, stammt aus den bereitgestellten Beispielen. Das Beispiel "MiniCube" funktioniert, wenn ich es in der bereitgestellten Lösung erstelle.

Hier ist der Code i machen verwenden:

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(); 
    } 
    } 
} 

ich sonst keine Ausnahmen oder etwas nicht bekommen. Der Tab verschwindet einfach und das ist alles. Soweit ich feststellen konnte, dass der Code läuft, habe ich eine Debug-Session eingecheckt.

Die SharpDXRenderManager ist nur aus dem Usercontrol selbst, hier der Code genannt:

public partial class Planner : UserControl 
{ 
     private SharpDXRenderManager renderManager; 

     public Planner() 
     { 
      InitializeComponent(); 

      renderManager = new SharpDXRenderManager(this); 
      renderManager.Render(); 
     } 
} 
+0

Können Sie Code von einer anderen Stelle einfügen, an der 'SharpDXRenderManager' aufgerufen wird? Wenn das an irgendwelchen seltsamen Orten aufgerufen wird, überschreibt es den Inhalt Ihres privaten 'renderTarget'-Feldes. – gmiley

Antwort

0

Das Problem ist, dass ich das machen Prozess direkt nach der Initialisierung begonnen haben. Ich löste es, indem ich die Methode Render() im OnLoad (EventArgs e) Event anrief.