2011-08-30 40 views
6

Tôi có một số vấn đề. Tôi mới đến XNA và muốn vẽ một hình đa giác mà trông giống như thế này (Cuối cùng, tôi muốn những điểm đến được ngẫu nhiên):Tạo đa giác 2D trong XNA

Polygon within a rectangle

Vì vậy, tôi đọc một số bài báo và đây là những gì Tôi đã kết thúc với:

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; 
} 

Khi tôi gọi Render nó bắt đầu vẽ một số hình vuông như thể nó ở đâu trong vòng lặp. Tôi đoán tôi đang làm tất cả sai. Tôi rất thích nó nếu ai đó chỉ cho tôi đi đúng hướng. Chỉ cần tạo một đa giác và vẽ nó. Nó có vẻ đơn giản ...

+0

Bạn có thay đổi các đỉnh sau khi đặt chúng lần đầu tiên không? – Cameron

+0

Không, tôi chỉ gọi Render một lần –

+0

Bạn đang gọi Render ở đâu? –

Trả lời

3

Ở đây nó những gì tôi có ngay bây giờ.

Một lớp tạo ra BasicEffect với một số asignments mong muốn.

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); 
    } 
} 

Đây là lớp PolygonShape tôi

/// <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); 
} 

Xin lỗi, đó là loại rất nhiều. Bây giờ cho nhiệm vụ tiếp theo của tôi. Hoạt hình đa giác của tôi.

Hy vọng nó sẽ giúp những người đồng nghiệp có cùng một vấn đề.

1

Tôi đã làm việc với XNA trong quá khứ về mô phỏng vật lý, nơi tôi phải vẽ các hộp giới hạn với GraphicsDevice.DrawIndexedPrimitives (Bạn nên google hoặc MSDN cho chức năng này để biết thêm ví dụ.)

Mã bên dưới là những gì tôi đã sử dụng trong dự án của mình để vẽ hình 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(); 
} 

Chức năng này là một phương pháp thành viên của một đối tượng hình học (lớp) và được gọi từ lớp game Draw(GameTime) phương pháp

+0

Bạn có thể chỉ cho tôi cách các đối tượng _mVertexDeclaration, _mIndexBuffer và _mVertexBuffer trông như thế nào? –

+0

Chúng trông giống hệt như chúng là gì. Kiểm tra API cho GraphicsDevice.VertexDeclaration, GraphicsDevice.Indices và Microsoft.Xna.Framework.Graphics.VertexBuffer tương ứng. – Jake

2

mã này rất hữu ích để vẽ đường 2D, một số calcs thể được thực hiện vào một bắt đầu cuộc gọi, nhưng tôi thích cho ví dụ này để giữ tất cả lại với nhau.

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;   
    } 
} 
+0

Tôi đã thử giải pháp của bạn nhưng tôi nhận được thông báo lỗi này: Cả trình đổ bóng và pixel shader phải được đặt trên thiết bị trước khi thực hiện bất kỳ thao tác vẽ nào. –

+0

tôi đã thêm pixel shader vào dòng.fx – Blau

Các vấn đề liên quan