我正在尝试使用sharpdx创建高级API。它必须能够绘制,但我仍然坚持如何使它同时使用多个Draw调用。
这就是我打电话给班级的方式
DirectXFinalD d33d = new DirectXFinalD();
这里我创建了一个viereck(矩形)
类型的新对象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作为我的renderform。一个问题是我总是需要更改拓扑,例如三角形需要trianglelist
但是对于圆圈我使用Linestrip
。任何帮助将不胜感激
答案 0 :(得分:0)
我可以看到你正在调用附加的那些。在这个附加方法中,您只创建了1个顶点缓冲区,其网格取决于objectToDraw
。
您应该将着色器编译代码与顶点缓冲区设置分离。
你可以创建一个类来管理vertexbuffer并“知道”如何绘制网格。
例如:(PSEUDO)
[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;
}
像这样......