XNA для начинающих: как объединить массивы вершин в один буфер вершин

Я только недавно начал использовать XNA, и теперь я столкнулся с проблемой новичков, производительностью. Объекты, которые я рисую, имеют свой собственный буфер вершин, поэтому, когда у меня есть ~ 50 тысяч объектов, частота кадров резко падает (с 60 до 5-12).

Мне посоветовали объединить вершины в куски, но я не знаю, как это сделать.

Буду признателен за любую помощь, которую я могу получить с примерами кода.

Изменить: это код, который я придумал с помощью Блау.

var cubes = newChunk.Where(c => c != null && !badIndex.Contains(c.BlockType));
VertexPositionColorTextureNormal[] verts = new VertexPositionColorTextureNormal[cubes.Sum(c => c.Vertices.Count)];
int VertexOffset = 0;
var inTheRightOrder = cubes;
foreach (var cube in inTheRightOrder)
{
    var cb = cube.Vertices.ToArray();
    for (int v = 0; v < cb.Length; v++)
    {
        verts[VertexOffset + v] = cb[v];
    }

    VertexOffset += cb.Length;
}
VertexBuffer newVB = new VertexBuffer(device, VertexPositionColorTextureNormal.VertexDeclaration, verts.Length, BufferUsage.WriteOnly);
newVB.SetData(verts);
var ck = new Cube { Vertices = verts, BoundingBox = BoundingBox.CreateFromPoints(verts.Select(i => i.Position)), Buffer = newVB, Cubes = cubes.Count() };
Cubes.Add(ck);

person NoLifeKing    schedule 26.11.2011    source источник
comment
50 000 объектов? возможно, вам нужно обрезать объекты перед рисованием...   -  person Blau    schedule 26.11.2011
comment
Объекты создаются только с видимыми вершинами, поэтому, если куб виден только сверху, создаются только верхние вершины.   -  person NoLifeKing    schedule 27.11.2011


Ответы (1)


Чтобы объединить их, вам нужно что-то похожее на это.

int NumVerts = Objects.Sum(o => o.Vertex.Length);
int NumIndexes = Objects.Sum(o => o.Index.Length);

VertexPositionColor[] Vertex = new VertexPositionColor[NumVerts];
int[] Index = new int[NumIndexes];

int VertexOffset = 0;
int IndexOffset = 0;
foreach (Object object in Objects)
{
    for (int v=0; v<object.Vertex.Length; v++)
    {
        Vertex[VertexOffset+v] = object.Vertex[v] + VertexOffset;
    }

    for (int i=0; i<object.Index.Length; i++)
    {
        Index[IndexOffset+i] = object.Index[i] + VertexOffset;
    }

    VertexOffset += object.Vertex.Length;
    IdnexOffset += object.Index.Length;
}
person Blau    schedule 26.11.2011
comment
Спасибо, это много для меня значило, теперь мне просто нужно разделить все прозрачные блоки, поэтому я рисую их после того, как все остальные блоки отрендерились. - person NoLifeKing; 27.11.2011