【问题标题】:SharpDX draw multiple primitives at the same timeSharpDX 同时绘制多个图元
【发布时间】:2018-01-04 07:36:12
【问题描述】:

我正在尝试使用 sharpdx 创建高级 API。它必须能够绘图,但我被困在如何让它同时与多个 Draw 调用一起工作。

我是这样称呼班级的

DirectXFinalD d33d = new DirectXFinalD();

在这里我创建了一个 viereck(rectangle) 类型的新对象

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

这里我将对象传递给类

d33d.DrawDirectX(viereck);

它已经工作了,但问题是,我希望它能够在任何给定时间传递更多对象,并让它们被绘制。 我已经尝试过总是更新顶点缓冲区并且总是 += 顶点,但问题是不同的形状需要不同的拓扑。这是课程:

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。任何帮助将不胜感激

【问题讨论】:

    标签: c# wpf directx sharpdx


    【解决方案1】:

    我可以看到您正在调用 Attach 的。在此附加方法中,您只创建 1 个顶点缓冲区,其网格取决于 objectToDraw

    您应该将着色器编译代码和顶点缓冲区设置解耦。

    您可以创建一个类来管理顶点缓冲区并“知道”如何绘制网格。

    例如:(伪)

    [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;
    }
    

    类似的...

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多