XNA — рисование 2D-линий

Я уже просмотрел http://msdn.microsoft.com/en-us/library/bb196414.aspx#ID2EEF здесь объясняют, как рисовать 2D-линии в xna, но я получаю исключение (см. скрипт)

            {
                int points = 3;//I tried different values(1,2,3,4)
                VertexPositionColor[] primitiveList = new VertexPositionColor[points];

                for (int x = 0; x < points / 2; x++)
                {
                    for (int y = 0; y < 2; y++)
                    {
                        primitiveList[(x * 2) + y] = new VertexPositionColor(
                            new Vector3(x * 100, y * 100, 0), Color.White);
                    }
                }
                // Initialize an array of indices of type short.
                short[] lineListIndices = new short[(points * 2) - 2];

                // Populate the array with references to indices in the vertex buffer
                for (int i = 0; i < points - 1; i++)
                {
                    lineListIndices[i * 2] = (short)(i);
                    lineListIndices[(i * 2) + 1] = (short)(i + 1);
                }
                GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
                    PrimitiveType.LineList,
                    primitiveList,
                    0,  // vertex buffer offset to add to each element of the index buffer
                    8,  // number of vertices in pointList
                    lineListIndices,  // the index buffer
                    0,  // first index element to read
                    7   // number of primitives to draw
                    ); <---This parameter must be a valid index within the array. Parameter name: primitiveCount
            }

но я понятия не имею, как это исправить, так как я впервые делаю 2D-графику с использованием 3D-рендеринга.

Задний план:

Я делаю движок 2D-игры для xna, и я хочу создать класс для рисования простых фигур, я уже знаю, что вы можете использовать пиксельный трюк 1x1 Texture2D для рисования, но я также хочу знать этот способ, потому что иначе ЦП выполнять все вычисления, в то время как GPU может легко справиться с этим.


person MooshBeef    schedule 24.06.2013    source источник
comment
Я использую эту библиотеку bitbucket.org/C3/2d-xna-primitives/wiki/ Главная   -  person Dmi7ry    schedule 24.06.2013


Ответы (2)


Поскольку вы действительно не указали ошибку или что-то еще, я просто покажу вам, как я их рисую.

Я использую этот метод расширения для рисования одной линии, вам понадобится белая текстура 1x1.

public static void DrawLine(this SpriteBatch spriteBatch, Vector2 begin, Vector2 end, Color color, int width = 1)
{
    Rectangle r = new Rectangle((int)begin.X, (int)begin.Y, (int)(end - begin).Length()+width, width);
    Vector2 v = Vector2.Normalize(begin - end);
    float angle = (float)Math.Acos(Vector2.Dot(v, -Vector2.UnitX));
    if (begin.Y > end.Y) angle = MathHelper.TwoPi - angle;
    spriteBatch.Draw(Pixel, r, null, color, angle, Vector2.Zero, SpriteEffects.None, 0);
}

Это также нарисует форму, состоящую из точек, closed определяет, должна ли форма быть замкнутой или нет.

    public static void DrawPolyLine(this SpriteBatch spriteBatch, Vector2[] points, Color color, int width = 1, bool closed = false)
    {


        for (int i = 0; i < points.Length - 1; i++)
            spriteBatch.DrawLine(points[i], points[i + 1], color, width);
        if (closed)
            spriteBatch.DrawLine(points[points.Length - 1], points[0], color, width);

    }
person Cyral    schedule 24.06.2013

Прежде всего, это определение ваших вершин. Это выглядит немного странно. Если points равно 3, то внешний цикл идет от 0..0, а внутренний цикл от 0..1. Итак, у вас есть две вершины. Есть только одна линия, которую вы можете нарисовать с помощью этих точек. Если вы укажете points = 4, то у вас фактически будет четыре точки.

Кажется, что вы хотите нарисовать непрерывную линию без повторяющихся вершин. Таким образом, вам действительно не нужно индексированное представление (с индексным буфером). Достаточно указать вершины одну за другой.

Чтобы нарисовать непрерывную линию, вы должны использовать PrimitiveType.LineStrip. Это автоматически соединит вершины линиями. Итак, вам нужны индексы points - 1 (если вы действительно хотите их использовать).

В вызове DrawUserIndexedPrimitives() есть несколько неправильных аргументов, которые вызывают исключение:

  1. Вы говорите, что количество вершин равно 8, что определенно неверно. Это (points / 2) * 2.
  2. Вы говорите, что количество примитивов равно 7, что тоже неверно. Это должно быть points - 1.

Но опять же, ваше определение вершин и индексов несовместимо. Вы должны исправить это, прежде чем продолжить.

person Nico Schertler    schedule 24.06.2013