我是Monogame(OpenGL)的新手。
我想绘制10.000多个图元,只是矩形。
public class RectangleObject
{
public BasicEffect Effect { get; set; }
public Matrix PointTranslation { get; set; }
public Matrix PointRotation { get; set; }
public Matrix PointScale { get; set; }
public VertexPositionColor[] VerticesList { get; set; }
private VertexBuffer vertexBuffer;
private Game game;
public RectangleObject(Game game)
{
this.game = game;
Effect = new BasicEffect(game.GraphicsDevice) { VertexColorEnabled = true };
VerticesList = new VertexPositionColor[4];
vertexBuffer = new VertexBuffer(game.GraphicsDevice,
typeof(VertexPositionColor),
VerticesList.Length,
BufferUsage.WriteOnly);
vertexBuffer.SetData<VertexPositionColor>(VerticesList.ToArray());
game.GraphicsDevice.SetVertexBuffer(vertexBuffer);
}
public void DrawRectangle()
{
Effect.World = PointScale * PointRotation * PointTranslation;
Effect.CurrentTechnique.Passes[0].Apply();
game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
PrimitiveType.TriangleStrip,
VerticesList,
0,
vertexBuffer.VertexCount / 2);
}
}
我想旋转/平移/缩放每个矩形对象,因为每个对象有3个矩阵。 应用程序正在加载内容,创建100 * 100的RectangleObjects网格,并在Draw()方法中调用RectangleObject的DrawRectangle()方法。 当我尝试绘制50 * 50时,它保持60FPS。但如果我尝试绘制10.000个矩形,应用程序运行15-25FPS。
问题是:
答案 0 :(得分:2)
我怀疑你的游戏正在向GPU重新发送相同的几何体,无论几何体是否已经改变(从你所说的那些应该是静态的)。此外,我认为出于性能原因,您将受益于索引原语(见下文)。
根据Riemer,您应在致电SetVertexBuffer()
之前致电DrawIndexedPrimitives()
:
完成后,您只需要使用 DrawIndexedPrimitives方法而不是DrawUserIndexedPrimitives 方法指示您的图形卡从其自己的内存中获取顶点和索引数据。在我们调用此方法之前,我们需要让您的显卡知道它应该从存储在自己内存中的缓冲区读取:Tell me more...
e.g。 (来自Riemer)
device.Indices = myIndexBuffer; // <------------- NEW
device.SetVertexBuffer(myVertexBuffer);
device.DrawIndexedPrimitives(PrimitiveType.TriangleList, //
0,
0,
vertices.Length,
0,
indices.Length / 3);
请注意DrawIndexedPrimitives
的使用。我建议你调查DrawUserPrimitives
以上。另请注意,您需要更改代码才能使用索引。
请勿在{{1}}构造函数中调用game.GraphicsDevice.SetVertexBuffer(vertexBuffer)
。我无法想到你应该在这些对象中进行任何GPU更改的原因。在RectangleObject()
方法中执行此操作。
通过这些更改,您将获得基本上VBO与当前的性能,GPU目前正在考虑的“动态”#34; VAO。
通过使用相同几何体的实例化而不是将相同的几何体乘以10,000次,可以获得出色的性能。