在XNA中创建2D多边形

时间:2011-08-30 16:22:45

标签: c# animation xna draw polygon

我有一些问题。我是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 个答案:

答案 0 :(得分:3)

这就是我现在所拥有的。

生成带有一些所需符号的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);
}

抱歉,这有点很多。现在我的下一个任务。动画我的多边形。

希望它帮助同样有同样问题的人。

答案 1 :(得分:2)

这段代码对于绘制2D线非常有用,一些计算可以在初始化调用中完成,但我更喜欢这个例子来保持一致。

 public void DrawLine(VertexPositionColor[] Vertices)
    {           
        Game.GraphicsDevice.DepthStencilState = DepthStencilState.Default;

        Vector2 center;
        center.X = Game.GraphicsDevice.Viewport.Width * 0.5f;
        center.Y = Game.GraphicsDevice.Viewport.Height * 0.5f;

        Matrix View = Matrix.CreateLookAt( new Vector3( center, 0 ), new Vector3( center, 1 ), new Vector3( 0, -1, 0 ) );
        Matrix Projection = Matrix.CreateOrthographic( center.X * 2, center.Y * 2, -0.5f, 1 );
        Effect EffectLines = Game.Content.Load<Effect>( "lines" );
        EffectLines.CurrentTechnique = EffectLines.Techniques["Lines"];

        EffectLines.Parameters["xViewProjection"].SetValue( View * Projection );
        EffectLines.Parameters["xWorld"].SetValue( Matrix.Identity );

        foreach ( EffectPass pass in EffectLines.CurrentTechnique.Passes )
        {
            pass.Apply( );
            Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>
                ( PrimitiveType.LineList, Vertices, 0, Vertices.Length/2 );
        }            
    }

LINES.FX

uniform float4x4 xWorld;
uniform float4x4 xViewProjection;

void VS_Basico(in float4 inPos : POSITION,  in float4 inColor: COLOR0,  out float4     outPos: POSITION,    out float4 outColor:COLOR0 )
{
    float4 tmp = mul (inPos, xWorld);
    outPos = mul (tmp, xViewProjection);
    outColor = inColor; 
}

float4 PS_Basico(in float4 inColor:COLOR) :COLOR
{
return inColor;
}


technique Lines
{
pass Pass0
    {   
        VertexShader = compile vs_2_0 VS_Basico();
        PixelShader = compile ps_2_0 PS_Basico();
        FILLMODE = SOLID;
        CULLMODE = NONE;        
    }  
}

答案 2 :(得分:1)

我过去曾使用XNA进行物理模拟,我必须使用GraphicsDevice.DrawIndexedPrimitives绘制边界框(对于更多工作示例,您应该使用google或MSDN获取此函数。)

以下代码是我在项目中用于绘制3D几何图形的代码。

/// <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)方法

调用