2017-07-28 77 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; 
} 

类似的东西...