Создание 2D многоугольника в XNA - PullRequest
6 голосов
/ 30 августа 2011

У меня какая-то проблема. Я новичок в XNA и хочу нарисовать многоугольник, который будет выглядеть примерно так (В конце я хочу, чтобы эти точки были случайными):

Polygon within a rectangle

Итак, я прочитал несколько статей, и вот что я закончил:

private VertexPositionColor[] vertices;

public TextureClass()
{
    setupVertices();
}

public override void Render(SpriteBatch spriteBatch)
{
    Texture2D texture = createTexture(spriteBatch);
    spriteBatch.Draw(texture, new Rectangle((int)vertices[0].Position.X, (int)vertices[0].Position.Y, 30, 30), Color.Brown);
}

private Texture2D createTexture(SpriteBatch spriteBatch)
{
    Texture2D texture = new Texture2D(spriteBatch.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
    texture.SetData<Color>(new Color[] { Color.Brown });
    return texture;
}

Когда я звоню Render, он начинает рисовать некоторые квадраты, как если бы это было в цикле. Я просто догадываюсь, что делаю все неправильно. Я был бы рад, если бы кто-то указал мне правильное направление. Просто создаем многоугольник и рисуем его. Это казалось таким простым ...

Ответы [ 3 ]

3 голосов
/ 31 августа 2011

Вот то, что у меня есть сейчас.

Класс, который генерирует BasicEffect с некоторыми желаемыми назначениями.

public class StandardBasicEffect : BasicEffect
{
    public StandardBasicEffect(GraphicsDevice graphicsDevice)
        : base(graphicsDevice)
    {
        this.VertexColorEnabled = true;
        this.Projection = Matrix.CreateOrthographicOffCenter(
            0, graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height, 0, 0, 1);
    }

    public StandardBasicEffect(BasicEffect effect)
        : base(effect) { }

    public BasicEffect Clone()
    {
        return new StandardBasicEffect(this);
    }
}

Вот мой класс PolygonShape

/// <summary>
/// A Polygon object that you will be able to draw.
/// Animations are being implemented as we speak.
/// </summary>
/// <param name="graphicsDevice">The graphicsdevice from a Game object</param>
/// <param name="vertices">The vertices in a clockwise order</param>
public PolygonShape(GraphicsDevice graphicsDevice, VertexPositionColor[] vertices)
{
    this.graphicsDevice = graphicsDevice;
    this.vertices = vertices;
    this.triangulated = false;

    triangulatedVertices = new VertexPositionColor[vertices.Length * 3];
    indexes = new int[vertices.Length];
}

/// <summary>
/// Triangulate the set of VertexPositionColors so it will be drawn correcrly        
/// </summary>
/// <returns>The triangulated vertices array</returns>}
public VertexPositionColor[] Triangulate()
{
    calculateCenterPoint();{
    setupIndexes();
    for (int i = 0; i < indexes.Length; i++)
    {
        setupDrawableTriangle(indexes[i]);
    }

    triangulated = true;
    return triangulatedVertices;
}

/// <summary>
/// Calculate the center point needed for triangulation.
/// The polygon will be irregular, so this isn't the actual center of the polygon
/// but it will do for now, as we only need an extra point to make the triangles with</summary>
private void calculateCenterPoint()
{
    float xCount = 0, yCount = 0;

    foreach (VertexPositionColor vertice in vertices)
    {
        xCount += vertice.Position.X;
        yCount += vertice.Position.Y;
    }

    centerPoint = new Vector3(xCount / vertices.Length, yCount / vertices.Length, 0);
}

private void setupIndexes()
{
    for (int i = 1; i < triangulatedVertices.Length; i = i + 3)
    {
        indexes[i / 3] = i - 1;
    }
}

private void setupDrawableTriangle(int index)
{
    triangulatedVertices[index] = vertices[index / 3]; //No DividedByZeroException?...
    if (index / 3 != vertices.Length - 1)
        triangulatedVertices[index + 1] = vertices[(index / 3) + 1];
    else
        triangulatedVertices[index + 1] = vertices[0];
    triangulatedVertices[index + 2].Position = centerPoint;
}

/// <summary>
/// Draw the polygon. If you haven't called Triangulate yet, I wil do it for you.
/// </summary>
/// <param name="effect">The BasicEffect needed for drawing</param>
public void Draw(BasicEffect effect)
{
    try
    {
        if (!triangulated)
            Triangulate();

        draw(effect);
    }
    catch (Exception exception)
    {
        throw exception;
    }
}

private void draw(BasicEffect effect)
{
    effect.CurrentTechnique.Passes[0].Apply();
    graphicsDevice.DrawUserPrimitives<VertexPositionColor>(
        PrimitiveType.TriangleList, triangulatedVertices, 0, vertices.Length);
}

Извините, это довольно много. Теперь для моего следующего квеста. Анимация моего многоугольника.

Надеюсь, это помогло другим людям с такой же проблемой.

2 голосов
/ 31 августа 2011

этот код полезен для рисования 2D-линий, некоторые вызовы могут быть выполнены в вызове инициализации, но я предпочитаю, чтобы в этом примере все было вместе.*

1 голос
/ 30 августа 2011

В прошлом я работал с XNA над симуляцией физики, где мне приходилось рисовать ограничивающие рамки с помощью GraphicsDevice.DrawIndexedPrimitives (для более проработанных примеров вы должны использовать Google или MSDN для этой функции.)

Код ниже - это то, что я использовал в своем проекте для рисования трехмерной геометрии.

/// <summary>
/// Draw the primitive.
/// </summary>
/// <param name="world">World Matrix</param>
/// <param name="view">View Matrix</param>
/// <param name="projection">Projection Matrix</param>
/// <param name="color">Color of the primitive</param>
public void Draw(Matrix world, Matrix view, Matrix projection, Color color)
{
    _mGraphicsDevice.VertexDeclaration = _mVertexDeclaration;
    _mGraphicsDevice.Vertices[0].SetSource(_mVertexBuffer, 0, VertexPositionNormal.SizeInBytes);
    _mGraphicsDevice.Indices = _mIndexBuffer;

    _mBasicEffect.DiffuseColor = color.ToVector3();
    _mBasicEffect.World = _mTransform * world;
    _mBasicEffect.View = view;
    _mBasicEffect.Projection = projection;

    int primitiveCount = _mIndex.Count / 3;

    _mBasicEffect.Begin();
    foreach (EffectPass pass in _mBasicEffect.CurrentTechnique.Passes)
    {
        pass.Begin();
        _mGraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _mVertex.Count, 0, primitiveCount);
        pass.End();
    }
    _mBasicEffect.End();
}

Эта функция является методом-членом геометрического объекта (класса) и вызывается из класса Game 'Draw(GameTime) method

...