1)问题
我想绘制点负载图。数据集不是静态的,并且点在流动。目前,我将图形存储在顶点缓冲区中,并在它们出现时立即添加新点。问题是缓冲区空间不足时。也许此刻我将太多数据传递到缓冲区,但是我可以将其设置为的最大大小为
int buffer_size = 1215 * (Utilities.SizeOf<Vector4>()
+ Utilities.SizeOf<Vector4>()
+ Utilities.SizeOf<Vector2>());
等于48 600。
对于48 640,我得到一个错误
A first chance exception of type
'System.AccessViolationException' occurred in SharpDX.Direct3D11.dll
Additional information: There was try to read or write to/from protected memory
我的想法是创建两个Vertex Buffer,如果其中一个完全写入第二个Vertex Buffer,则仍然要绘制它们。编写时将带有标志MapMode.WriteNoOverwrite。如果第二个已满,则使用标志MapMode.WriteDiscard写入第一个中的第一个单元,这将基本上清除缓冲区。
2)问题:
如何从多个顶点缓冲区写入?
3)现有代码
我设置了一个包含两个插槽信息的布局:
var layout = new InputLayout(device, passSignature, new InputElement[]
{
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0)
,new InputElement("COLOR", 0, Format.R32G32B32A32_Float
, InputElement.AppendAligned, 0)
,new InputElement("TEXCOORD", 0, Format.R32G32_Float
, InputElement.AppendAligned, 0)
// semantic index had also to be increased as has a slot number
,new InputElement("POSITION",1, Format.R32G32B32A32_Float, 0, 1)
,new InputElement("COLOR", 1, Format.R32G32B32A32_Float
, InputElement.AppendAligned, 1)
,new InputElement("TEXCOORD", 1, Format.R32G32_Float
, InputElement.AppendAligned, 1)
});
创建缓冲区的数据并设置顶点缓冲区。
float[] buffer_data = new float[] {
-1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
, 0.2f, -0.4f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f
......
var vertices = Buffer.Create(device
, BindFlags.VertexBuffer
, buffer_data
, buffer_size
, ResourceUsage.Dynamic
, CpuAccessFlags.Write
, ResourceOptionFlags.None
, 0);
context.InputAssembler.InputLayout = layout;
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineList;
context.InputAssembler.SetVertexBuffers(
0
, new Buffer[] { vertices, vertices2 }
, new int[] { 40, 40 }
, new int[] { 0, 0 }
);
画画
int sectionsToDraw = 32;
context.ClearRenderTargetView(renderView, Color.Black);
// Main loop
RenderLoop.Run(form, () =>
{
for (int i = 0; i < technique.Description.PassCount; ++i)
{
pass.Apply(context);
context.PixelShader.SetShaderResource(0, textureView);
context.GeometryShader.SetConstantBuffer(0, _constantBuffer);
context.Draw(sectionsToDraw,0);
}
swapChain.Present(0, PresentFlags.None);
});
和我的着色器的结构
struct VS_IN
{
float4 pos : POSITION;
float4 col : COLOR;
float2 tex : TEXCOORD;
};
struct GS_IN
{
float4 pos : SV_POSITION;
float4 col : COLOR;
float2 tex : TEXCOORD;
};
struct PS_IN
{
float4 pos : SV_POSITION;
float4 col : COLOR;
float2 tex : TEXCOORD;
};
我不知道如何从第一个插槽中抽奖。它仅从插槽1中的缓冲区中提取。
问题不在于:-在两个缓冲区中绘制点的正确设置-传递给contect.Draw的绘制顶点数-第一个参数中的绘制-我还尝试过更改着色器的结构以使用POSITION1或COLOR1,但是没有帮助,但也许我没有正确执行。
我仅通过在render函数中的InputAssambler中切换缓冲区就设法从两个Vertex缓冲区中绘制
VertexBufferBinding vb = new VertexBufferBinding(vertices
, Utilities.SizeOf<Vector4>()
+ Utilities.SizeOf<Vector4>()
+ Utilities.SizeOf<Vector2>()
, 0);
VertexBufferBinding vb2 = new VertexBufferBinding(vertices2
, Utilities.SizeOf<Vector4>()
+ Utilities.SizeOf<Vector4>()
+ Utilities.SizeOf<Vector2>()
, 0);
然后在渲染循环中
RenderLoop.Run(form, () =>
{
context.ClearRenderTargetView(renderView, Color.Black);
....
context.InputAssembler.SetVertexBuffers(0, vb);
context.Draw(sectionsToDraw,0);
context.InputAssembler.SetVertexBuffers(0, vb2);
context.Draw(sectionsToDraw, 0);
....
}
当然,使用此解决方案还可以简化布局
var layout = new InputLayout(device, passSignature, new InputElement[]
{
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0)
,new InputElement("COLOR", 0, Format.R32G32B32A32_Float
, InputElement.AppendAligned, 0)
,new InputElement("TEXCOORD", 0, Format.R32G32_Float
, InputElement.AppendAligned, 0)
}
但是现在,我不确定我的解决方案是否不涉及在每次绘制调用时都复制整个缓冲区。我必须多读一些。
我认为我的问题是我正在使用Directx 11,并且找不到局部缓冲区锁,就像我在Directx 9中发现的那样。http: //sharpdx.org/documentation/api/m-sharpdx -direct3d9-vertexbuffer-lock在DirectX 11中似乎没有。我发现可以使用资源的MapSubresource,但是根据MSDN, “缓冲区定义为单个子资源”。因此,不可能像我想要的那样仅锁定缓冲区的一部分。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句