2017-07-28 74 views
0

我正在嘗試使用sharpdx創建高級API。它必須能夠繪製,但我堅持如何使它與多個Draw調用同時工作。SharpDX同時繪製多個圖元

這是我如何調用類

DirectXFinalD d33d = new DirectXFinalD(); 

在這裏,我創建類型viereck的新對象(矩形)

Viereck viereck = new Viereck(0, 0, 0.2, 0.1, myBrush, myBrush, 1, false); 

在這裏,我傳遞對象的類

d33d.DrawDirectX(viereck); 

它已經工作,但問題是,我希望它能夠在任何給定的t時間內傳遞更多的對象ime,並讓它們畫出來。 我已經嘗試過始終更新頂點緩衝區,始終+ =頂點,但問題是不同的形狀需要不同的拓撲。這裏是這個類:

namespace DrawHost 
{ 

public class DirectXFinalD : DrawHost.DirectXBaseD<D3D11>, IDrawable 
{ 

; 
    public DirectXFinalD(IDrawable objectToDraw = null, DataStream stream = null) 
    { 
     this.objectToDraw = objectToDraw; 
     if (stream == null) 
     stream = new DataStream(32 * 612500, true, true); 
     else 
     this.stream = stream; 
    } 

    protected override void Attach() 
    { 
     #region Shader 
     if (Renderer == null) 
      return; 
     device = Renderer.Device; 
     context = device.ImmediateContext; 

     // Compile Vertex and Pixel shaders 
     vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "VS", "vs_4_0", ShaderFlags.None, EffectFlags.None); 
     vertexShader = new VertexShader(device, vertexShaderByteCode); 
     pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "PS", "ps_4_0", ShaderFlags.None, EffectFlags.None); 
     pixelShader = new PixelShader(device, pixelShaderByteCode); 

     // Layout from VertexShader input signature 
     layout = new InputLayout(device, ShaderSignature.GetInputSignature(vertexShaderByteCode), new[] { 
      new InputElement("POSITION",0,Format.R32G32B32A32_Float,0,0), 
      new InputElement("COLOR",0,Format.R32G32B32A32_Float,16,0) 
     }); 
     #endregion 
     if (objectToDraw == null) { } 
     else 
     { 
      float r = 0; 
      float g = 0; 
      float b = 0; 
      switch (objectToDraw.ToString()) 
      { 
       #region Dreieck 
       case "Dreieck": 
        Dreieck dreieck = (Dreieck)objectToDraw; 
        topology = PrimitiveTopology.TriangleStrip; 
        ConvertColor(ref r, ref g, ref b, ((System.Windows.Media.SolidColorBrush)dreieck.Color).Color); 

        streamList.Add(new Vector4((Convert.ToSingle(dreieck.X)), (Convert.ToSingle(dreieck.Y)/10), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f)); 
        streamList.Add(new Vector4(((Convert.ToSingle(dreieck.X) + Convert.ToSingle(dreieck.Width))), -(Convert.ToSingle(dreieck.Y)), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f)); 
        streamList.Add(new Vector4(-(Convert.ToSingle(dreieck.X)), -((Convert.ToSingle(dreieck.Y) + Convert.ToSingle(dreieck.Height))), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f)); 

        break; 
       #endregion 

       #region Viereck 
       case "Viereck": 
        Viereck viereck = (Viereck)objectToDraw; 
        topology = PrimitiveTopology.TriangleStrip; 
        ConvertColor(ref r, ref g, ref b, ((System.Windows.Media.SolidColorBrush)viereck.Color).Color); 

        streamList.Add(new Vector4((Convert.ToSingle(viereck.X)), (Convert.ToSingle(viereck.Y)), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f));// ok 
        streamList.Add(new Vector4(((Convert.ToSingle(viereck.X))), (Convert.ToSingle(viereck.Y) + Convert.ToSingle(viereck.Height)), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f));// ok 
        streamList.Add(new Vector4((Convert.ToSingle(viereck.X) + Convert.ToSingle(viereck.Width)), (Convert.ToSingle(viereck.Y)), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f));// ok 
        streamList.Add(new Vector4((Convert.ToSingle(viereck.X) + Convert.ToSingle(viereck.Width)), ((Convert.ToSingle(viereck.Y) + Convert.ToSingle(viereck.Height))), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f));// ok 

        break; 
       #endregion 

       #region Kreis 
       case "Kreis": 
        topology = PrimitiveTopology.Undefined; 
        Kreis kreis = (Kreis)objectToDraw; 
        ConvertColor(ref r, ref g, ref b, ((System.Windows.Media.SolidColorBrush)kreis.Color).Color); 
        for (float j = 0; j <= 360; j++) 
        { 
         for (double i = 0; i <= 360; i++) //254 
        { 
          double rad = i * (Math.PI/180); 
          float x = (float)Math.Cos(rad) * ((float)kreis.Width/2); 
          float y = (float)Math.Sin(rad) * ((float)kreis.Height/2); 
         streamList.Add(new Vector4(x , y, 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f)); 


         } 
        } 

        break; 
        #endregion 

      }; 

      foreach (Vector4 a in streamList) 
      { 
       stream.WriteRange(new[] { a }); 
      } 
      stream.Position = 0; 
      streamGV streamGV = new streamGV(stream); 
      //streamGV.GetList(streamList); 
      //streamList = null; 
      GC.Collect(); 
     } 
     vertices = new Buffer(device, stream, new BufferDescription() 
     { 
      BindFlags = BindFlags.VertexBuffer, 
      CpuAccessFlags = CpuAccessFlags.None, 
      OptionFlags = ResourceOptionFlags.None, 
      SizeInBytes = (int)stream.Length, 
      Usage = ResourceUsage.Default, 
      StructureByteStride = 0, 
     }); 

     stream.Dispose(); 


     // Prepare All the stages 
     context.InputAssembler.InputLayout = (layout); 
     context.InputAssembler.PrimitiveTopology = topology; 
     context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, 32, 0)); 
     context.VertexShader.Set(vertexShader); 
     context.PixelShader.Set(pixelShader); 

    } 



    public override void RenderScene(DrawEventArgs args) 
    { 
     Renderer.Device.ImmediateContext.ClearRenderTargetView(Renderer.RenderTargetView, new Color4(0.6f, 0, 0, 0)); 
     Renderer.Device.ImmediateContext.Draw((int)stream.Length, 0); 

     return; 
    } 

    public override void Case(DXElement dxviewer) 
    { 
     dxviewer11 = dxviewer; 

} 

    public override void DrawDirectX(IDrawable objectToDraw) 
    { 
     this.objectToDraw = objectToDraw; 
     //dxviewer11.Renderer = new Scene_11(); 
     //Renderer = new D3D11(); 
     stream = new DataStream(32 * 612500, true, true); 
     streamGV strean = new streamGV(); 
     dxviewer11.Renderer = new DirectXFinalD(objectToDraw, stream) { Renderer = new D3D11() }; 



    } 

    private void ConvertColor(ref float r, ref float g, ref float b, System.Windows.Media.Color color) 
    { 
     r = (float)(color.R * 255); 
     g = (float)(color.G * 255); 
     b = (float)(color.B * 255); 
    } 



} 

我怎樣才能讓它們同時被繪製?我正在使用sharpdx作爲我的渲染表單。一個問題是,我總是不得不改變拓撲結構,例如三角形需要trianglelist,但對於我使用Linestrip的圓形。任何幫助,將不勝感激

回答

0

正如我所看到你打電話的附件。在這種附加方法中,您只創建1個頂點緩衝區,網格取決於objectToDraw

你應該分解你的着色器編譯代碼和你的vertexbuffer設置。

您可以創建一個類來管理頂點緩衝區,'知道'如何繪製網格。

例如:(僞)

[StructLayout(LayoutKind.Sequential)] 
public struct Vertex 
{ 
    public const int Stride = 16 + 16; 

    public Vector4 Pos; 
    public Color4 Color; 
} 

public class Mesh 
{ 
    private Vertex[] _vertices; 
    private int[] _indices; 

    private SharpDX.Direct3D11.Buffer _indexBuffer; 
    private SharpDX.Direct3D11.Buffer _vertexBuffer; 
    private VertexBufferBinding _vertexBufferBinding; 

    public Mesh(Vertex[] vertices, int[] indices) 
    { 
     // save the vertices in a field 
     _vertices = value; 

     var vbd = new BufferDescription(
      SharpDX.Utilities.SizeOf<Vertex>() * _vertices.Length, 
      ResourceUsage.Immutable, 
      BindFlags.VertexBuffer, 
      CpuAccessFlags.None, 
      ResourceOptionFlags.None, 
      0); 

     // setup the vertex buffer 
     _vertexBuffer = SharpDX.Direct3D11.Buffer.Create<Vertex>(DX11.Device, _vertices, vbd); 

     // create the binding 
     _vertexBufferBinding = new VertexBufferBinding(_vertexBuffer, Vertex.Stride, 0); 


     _indices = value; 

     var ibd = new BufferDescription(
       sizeof(int) * _indices.Length, 
       ResourceUsage.Immutable, 
       BindFlags.IndexBuffer, 
       CpuAccessFlags.None, 
       ResourceOptionFlags.None, 
       0); 

     // setup the index buffer 
     _indexBuffer = SharpDX.Direct3D11.Buffer.Create<int>(DX11.Device, _indices, ibd); 
    } 

    // the SelectBuffers will select the right vertex buffer. 
    // this could be combined with the Draw method, but I rather not 
    // You should call this ones even when you draw multiple the same mesh. 
    public void SelectBuffers() 
    { 
     DX11.Device.ImmediateContext.InputAssembler.SetVertexBuffers(0, _vertexBufferBinding); 
     DX11.Device.ImmediateContext.InputAssembler.SetIndexBuffer(_indexBuffer, SharpDX.DXGI.Format.R32_UInt, 0); 

    } 

    public void Draw() 
    { 
     DX11.Device.ImmediateContext.DrawIndexed(_indices.Length, 0, 0); 
    } 
} 

List<Mesh> _meshes = new List<Mesh>(); 

public void SetupShaders() 
{ 
    vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "VS", "vs_4_0", ShaderFlags.None, EffectFlags.None); 
    vertexShader = new VertexShader(device, vertexShaderByteCode); 
    pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "PS", "ps_4_0", ShaderFlags.None, EffectFlags.None); 

    ...... etc 
} 

public Mesh SetupMesh(object objectToDraw) 
{ 
    switch(.....) 
    { 
     // .. implement your beautiful switch ;-) 
    } 
    return new Mesh(vertices, indices); 
} 

public void Init() 
{ 
    SetupShaders(); 

    _meshes.Add(SetupMesh(new Dreieck(.....))); 
    _meshes.Add(SetupMesh(new Viereck(.....))); 
    _meshes.Add(SetupMesh(new Kreis(.....))); 
} 


public override void RenderScene(DrawEventArgs args) 
{ 
    Renderer.Device.ImmediateContext.ClearRenderTargetView(Renderer.RenderTargetView, new Color4(0.6f, 0, 0, 0)); 

    foreach(var mesh in _meshes) 
    { 
     mesh.SelectBuffers(); 
     mesh.Draw(); 
    } 
    return; 
} 

類似的東西...