# [ACCEPTED]-How do I draw lines using XNA?-shapes

Score: 19

When working with XNA, everything (even 9 2d primitives) have to be expressed in a 8 way that a 3d card can understand, which 7 means that a line is just a set of vertices.

MSDN 6 has a pretty good walkthrough here:

http://msdn.microsoft.com/en-us/library/bb196414.aspx#ID2EEF

You'll 5 find that it takes more code to render a 4 primitive line than it would take to just 3 setup a textured quad and rotate that, since 2 in essence, your doing the same thing when 1 rendering a line.

Score: 16

Following NoHayProblema's answer (I cannot 11 comment yet).

That answer, although the correct 10 one for this old question, is incomplete. Texture2D 9 constructor returns an uninitialized texture, which 8 is never painted on screen. In order to 7 use that approach, you need to set the texture's 6 data like this:

``````Texture2D SimpleTexture = new Texture2D(GraphicsDevice, 1, 1, false,
SurfaceFormat.Color);

Int32[] pixel = {0xFFFFFF}; // White. 0xFF is Red, 0xFF0000 is Blue
SimpleTexture.SetData<Int32> (pixel, 0, SimpleTexture.Width * SimpleTexture.Height);

// Paint a 100x1 line starting at 20, 50
this.spriteBatch.Draw(SimpleTexture, new Rectangle(20, 50, 100, 1), Color.Blue);
``````

Take into account that the 5 way you write the data into pixel must be 4 consistent with the texture's SurfaceFormat. The 3 example works because the texture is being 2 formatted as RGB. Rotations can be applied 1 in spriteBatch.Draw like this:

``````this.spriteBatch.Draw (SimpleTexture, new Rectangle(0, 0, 100, 1), null,
Color.Blue, -(float)Math.PI/4, new Vector2 (0f, 0f), SpriteEffects.None, 1f);
``````
Score: 10

found a tutorial for that http://www.bit-101.com/blog/?p=2832

its using a BasicEffect 5 (shader) and the built in draw user primitive 4 in XNA 4.0

some code samples i find helpful:

``````basicEffect = new BasicEffect(GraphicsDevice);
basicEffect.VertexColorEnabled = true;
basicEffect.Projection = Matrix.CreateOrthographicOffCenter
(0, GraphicsDevice.Viewport.Width,     // left, right
GraphicsDevice.Viewport.Height, 0,    // bottom, top
0, 1);
``````

draw method

``````basicEffect.CurrentTechnique.Passes.Apply();
var vertices = new VertexPositionColor;
vertices.Position = new Vector3(100, 100, 0);
vertices.Color = Color.Black;
vertices.Position = new Vector3(200, 100, 0);
vertices.Color = Color.Red;
vertices.Position = new Vector3(200, 200, 0);
vertices.Color = Color.Black;
vertices.Position = new Vector3(100, 200, 0);
vertices.Color = Color.Red;

GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, vertices, 0, 2);
``````

have fun and vote 2 up if this helped you. also pay a visit 1 to the tutorial i got this from.

Score: 8

Well, you can do it in a very simple way 4 without getting into the 3D horrible vector 3 stuff.

Just create a quick texture, for example:

`Texture2D SimpleTexture = new Texture2D(GraphicsDevice, 1, 1, false, SurfaceFormat.Color);`

And 2 then just draw a line using that texture:

`this.spriteBatch.Draw(SimpleTexture, new Rectangle(100, 100, 100, 1), Color.Blue);`

I 1 hope this helps

Score: 4

The simplest best way, I think, is to get 3 the image of just a white pixel then stretch 2 that pixel in a rectangle to look like a 1 line

``````class Line
{
Texture pixel = ((set this to a texture of a white pixel with no border));
Vector2 p1, p2; //this will be the position in the center of the line
int length, thickness; //length and thickness of the line, or width and height of rectangle
Rectangle rect; //where the line will be drawn
float rotation; // rotation of the line, with axis at the center of the line
Color color;

//p1 and p2 are the two end points of the line
public Line(Vector2 p1, Vector2 p2, int thickness, Color color)
{
this.p1 = p1;
this.p2 = p2;
this.thickness = thickness;
this.color = color;
}

public void Update(GameTime gameTime)
{
length = (int)Vector2.Distance(p1, p2); //gets distance between the points
rotation = getRotation(p1.X, p1.Y, p2.X, p2.Y); //gets angle between points(method on bottom)
rect = new Rectangle((int)p1.X, (int)p1.Y, length, thickness)

//To change the line just change the positions of p1 and p2
}

public void Draw(SpriteBatch spriteBatch, GameTime gameTime)
{
spriteBatch.Draw(pixel, rect, null, color, rotation, new Vector2.Zero, SpriteEffects.None, 0.0f);
}

//this returns the angle between two points in radians
private float getRotation(float x, float y, float x2, float y2)
{
float adj = x - x2;
float opp = y - y2;
float tan = opp / adj;
res = (res - 180) % 360;
if (res < 0) { res += 360; }
return res;
}
``````

Hope this helps

Score: 2

There is also the "round line" code 2 that "manders" has released on 1 CodePlex:

Here is the blog post about it:

Score: 2

Just stretch a white pixel.

``````        point = game.Content.Load<Texture2D>("ui/point");

public void DrawLine(Vector2 start, Vector2 end, Color color)
{
Vector2 edge = end - start;
float angle = (float)Math.Atan2(edge.Y, edge.X);

spriteBatch.Begin();
spriteBatch.Draw(point,
new Rectangle((int)start.X, (int)start.Y, (int)edge.Length(), 1),
null,
color,
angle,
new Vector2(0, 0),
SpriteEffects.None,
0);
spriteBatch.End();
}
``````

0

Score: 2

I wanted to draw rays so that I could debug 18 rays created by explosions and where they 17 intersect objects. This will draw a single 16 pixel thin line between two points. This 15 is what I did:

Class to store some simple 14 ray data. The XNA default ray class could 13 work, but it doesn't store the length of 12 the ray to intersection.

``````public class myRay
{
public Vector3 position, direction;
public float length;
}
``````

A list to store 11 the rays that are to be drawn:

``````List<myRay> DebugRays= new List<myRay>();
``````

Create a BasicEffect 10 and pass it a "Matrix.CreateOrthographicOffCenter" projection 9 with your desired resolution in the LoadContent 8 method.

Then run this in the draw method:

``````private void DrawRays()
{
spriteBatch.Begin();

foreach (myRay ray in DebugRays)
{
//An array of 2 vertices - a start and end position
VertexPositionColor[] Vertices = new VertexPositionColor;
int[] Indices = new int;

//Starting position of the ray
Vertices = new VertexPositionColor()
{
Color = Color.Orange,
Position = ray.position
};

//End point of the ray
Vertices = new VertexPositionColor()
{
Color = Color.Orange,
Position = ray.position + (ray.direction * ray.length)
};

Indices = 0;
Indices = 1;

foreach (EffectPass pass in BasicEffect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.LineStrip, Vertices, 0, 2, Indices, 0, 1, VertexPositionColorTexture.VertexDeclaration);
}
}

spriteBatch.End();
}
``````

So 7 when an explosion happens in my game it 6 does this (Psuedocode):

``````OnExplosionHappened()
{
DebugRays.Clear()

myRay ray = new myRay()
{
position = explosion.Position,
direction = GetDirection(explosion, solid),
//Used GetValueOrDefault here to prevent null value errors
length = explosionRay.Intersects(solid.BoundingBox).GetValueOrDefault()
};

}
``````

It's pretty simple 5 (It possibly looks way more complicated 4 than it is) and it'd be easy to put it into 3 a separate class that you never have to 2 think about again. It also lets you draw 1 a whole lot of lines at once.

Score: 1

I encountered this problem my self and decided 3 to make a class called LineBatch. LineBatch 2 will draw lines without needing a spriteBatch 1 or dots. The class is below.

``````public class LineBatch
{
bool began;
GraphicsDevice GraphicsDevice;
List<VertexPositionColor> verticies = new List<VertexPositionColor>();
BasicEffect effect;
public LineBatch(GraphicsDevice graphics)
{
GraphicsDevice = graphics;
effect = new BasicEffect(GraphicsDevice);
Matrix world = Matrix.Identity;
Matrix view = Matrix.CreateTranslation(-GraphicsDevice.Viewport.Width / 2, -GraphicsDevice.Viewport.Height / 2, 0);
Matrix projection = Matrix.CreateOrthographic(GraphicsDevice.Viewport.Width, -GraphicsDevice.Viewport.Height, -10, 10);
effect.World = world;
effect.View = view;
effect.VertexColorEnabled = true;
effect.Projection = projection;
effect.DiffuseColor = Color.White.ToVector3();
}
{
GraphicsDevice = graphics;
effect = new BasicEffect(GraphicsDevice);
Matrix world = Matrix.Identity;
Matrix view = Matrix.CreateTranslation(-GraphicsDevice.Viewport.Width / 2, -GraphicsDevice.Viewport.Height / 2, 0);
Matrix projection = Matrix.CreateOrthographic(GraphicsDevice.Viewport.Width, -GraphicsDevice.Viewport.Height, -10, 10);
effect.World = world;
effect.View = view;
effect.VertexColorEnabled = true;
effect.Projection = projection;
effect.DiffuseColor = Color.White.ToVector3();
}
{
Vector2 offset = new Vector2(
);
Draw(start, start + offset, color);
}
public void DrawOutLineOfRectangle(Rectangle rectangle, Color color)
{
Draw(new Vector2(rectangle.X, rectangle.Y), new Vector2(rectangle.X + rectangle.Width, rectangle.Y), color);
Draw(new Vector2(rectangle.X, rectangle.Y), new Vector2(rectangle.X, rectangle.Y + rectangle.Height), color);
Draw(new Vector2(rectangle.X + rectangle.Width, rectangle.Y), new Vector2(rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height), color);
Draw(new Vector2(rectangle.X, rectangle.Y + rectangle.Height), new Vector2(rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height), color);
}
public void DrawOutLineOfTriangle(Vector2 point_1, Vector2 point_2, Vector2 point_3, Color color)
{
Draw(point_1, point_2, color);
Draw(point_1, point_3, color);
Draw(point_2, point_3, color);
}
{
return angleDegrees * ((float)Math.PI) / 180.0f;
}
public void DrawAngledLine(Vector2 start, float length, float angleDegrees, Color color)
{
}
public void Draw(Vector2 start, Vector2 end, Color color)
{
}
public void Draw(Vector3 start, Vector3 end, Color color)
{
}
public void End()
{
if (!began)
else
Begin();
if (verticies.Count > 0)
{
VertexBuffer vb = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor), verticies.Count, BufferUsage.WriteOnly);
vb.SetData<VertexPositionColor>(verticies.ToArray());
GraphicsDevice.SetVertexBuffer(vb);

foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawPrimitives(PrimitiveType.LineList, 0, verticies.Count / 2);
}
}
began = false;
}
public void Begin()
{
if (began)
throw new ArgumentException("You forgot end.");
else
End();
verticies.Clear();
began = true;
}
}
``````
Score: 0

Here is a simple way that I use to make 5 lines by specifying a start coordinate, an 4 end coordinate, width, and color of them:

NOTE: you 3 must add a file named "dot" to the content 2 directory (the line will be made out of 1 these).

``````using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Xna.LineHelper
{
public class LineManager
{
int loopCounter;
int lineLegnth;
Vector2 lineDirection;
Vector2 _position;
Color dotColor;
Rectangle _rectangle;
List<Texture2D> _dots = new List<Texture2D>();
FunctionsLibrary functions = new FunctionsLibrary();

public void CreateLineFiles(Vector2 startPosition, Vector2 endPosition, int width, Color color, ContentManager content)
{
dotColor = color;
_position.X = startPosition.X;
_position.Y = startPosition.Y;
lineLegnth = functions.Distance((int)startPosition.X, (int)endPosition.X, (int)startPosition.Y, (int)endPosition.Y);
lineDirection = new Vector2((endPosition.X - startPosition.X) / lineLegnth, (endPosition.Y - startPosition.Y) / lineLegnth);
_dots.Clear();
loopCounter = 0;
_rectangle = new Rectangle((int)startPosition.X, (int)startPosition.Y, width, width);
while (loopCounter < lineLegnth)
{

loopCounter += 1;
}

}

{
foreach (Texture2D dot in _dots)
{
_position.X += lineDirection.X;
_position.Y += lineDirection.Y;
_rectangle.X = (int)_position.X;
_rectangle.Y = (int)_position.Y;
sb.Draw(dot, _rectangle, dotColor);
}
}
}

public class FunctionsLibrary
{
//Random for all methods
Random Rand = new Random();

#region math
public int TriangleArea1(int bottom, int height)
{
int answer = (bottom * height / 2);
}

public double TriangleArea2(int A, int B, int C)
{
int s = ((A + B + C) / 2);
double answer = (Math.Sqrt(s * (s - A) * (s - B) * (s - C)));
}
public int RectangleArea(int side1, int side2)
{
int answer = (side1 * side2);
}
public int SquareArea(int side)
{
int answer = (side * side);
}
public double CircleArea(int diameter)
{
double answer = (((diameter / 2) * (diameter / 2)) * Math.PI);
}
public int Diference(int A, int B)
{
int distance = Math.Abs(A - B);
return distance;
}
#endregion

#region standardFunctions

public int Distance(int x1, int x2, int y1, int y2)
{
return (int)(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
}

#endregion

}
}
``````

More Related questions