2011-08-30 105 views
6

我遇到某种问题。我是新来的XNA,并希望绘制多边形形状,看起来像这样(在最后,我想这点是随机的):在XNA中创建2D多边形

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它开始画一些正方形,如果它在一个循环的位置。我只是猜测我做错了所有事情。如果有人指出我正确的方向,我会很喜欢它。只需创建一个多边形并绘制它。它似乎很简单...

+0

第一次设置顶点后,您是否更改顶点? – Cameron

+0

不,我只是叫Render一次 –

+0

从哪里调用Render? –

回答

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

我用XNA曾在过去的物理模拟,我不得不动用包围盒与GraphicsDevice.DrawIndexedPrimitives(你应该谷歌或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(); 
} 

此函数是一个几何对象(类)的成员方法,并从游戏类Draw(GameTime)方法

+0

你能告诉我_mVertexDeclaration,_mIndexBuffer和_mVertexBuffer对象是怎么样的? –

+0

他们看起来完全一样。分别检查GraphicsDevice.VertexDeclaration,GraphicsDevice.Indices和Microsoft.Xna.Framework.Graphics.VertexBuffer的API。 – Jake

2

这个代码是绘制二维线是有用的,某些Calcs(计算)可以做成称为启动电话,但我更喜欢这个例子,以保持在一起。

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

我试过你的解决方案,但我得到这个errormessage:在执行任何绘制操作之前,必须在设备上设置顶点着色器和像素着色器。 –

+0

我已将像素着色器添加到lines.fx – Blau