XNA basic 2D line and point batch source...

Started by
0 comments, last by Noggs_ 15 years, 5 months ago
Hi, not sure if this is the right place to post this but... I recently had a reason to draw some 2D lines and points with XNA. After doing some inept googling etc, I didn't find anything that really fitted what I was after. So after doing some reading: How To: Draw Points, Lines, and Other 3D Primitives I made a line batch and point batch set of classes. Here are the rotten fruits of my labours. They are pretty basic with plenty of room for improvement. I used a generic list rather than a fixed length vertex array for flexibility. It won't be the fastest but you can easily swap this out. As mentioned earlier they are 2D - they use Vertex2 and an orthographic off center projection matrix. The PointBatch...

using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
using Vector2 = Microsoft.Xna.Framework.Vector2;
using Vector3 = Microsoft.Xna.Framework.Vector3;
using Matrix = Microsoft.Xna.Framework.Matrix;

namespace A.Namespace.Of.Your.Choice.Graphics
{
    public sealed class PointBatch
    {
        private GraphicsDevice graphicsDevice;
        private List<VertexPositionColor> points =
            new List<VertexPositionColor>();
        private VertexDeclaration vertexDeclaration;
        private BasicEffect basicEffect;
        private int pointSize;

        public PointBatch( GraphicsDevice graphicsDevice, float alpha, int pointSize )
        {
            this.graphicsDevice = graphicsDevice;

            basicEffect = new BasicEffect( graphicsDevice, null );
            basicEffect.VertexColorEnabled = true;
            basicEffect.Alpha = alpha;
            basicEffect.Projection = Matrix.CreateOrthographicOffCenter( 0.0F,
                graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height, 0.0F,
                0.0F, -1.0F );
            basicEffect.View = Matrix.Identity;
            basicEffect.World = Matrix.Identity;

            vertexDeclaration = new VertexDeclaration( graphicsDevice,
                VertexPositionColor.VertexElements );

            this.pointSize = pointSize;
        }

        public void Begin()
        {
            points.Clear();
        }

        public void Batch( Vector2 point, Color color )
        {
            VertexPositionColor batchPoint = new VertexPositionColor(
                new Vector3( point, 0.0F ), color );

            points.Add( batchPoint );
        }

        public void End()
        {
            if( points.Count > 0 )
            {
                graphicsDevice.VertexDeclaration = vertexDeclaration;
                graphicsDevice.RenderState.PointSize = pointSize;
                graphicsDevice.RenderState.FillMode = FillMode.Solid;

                basicEffect.Begin();

                foreach( EffectPass effectPass in basicEffect.CurrentTechnique.Passes )
                {
                    effectPass.Begin();

                    graphicsDevice.DrawUserPrimitives<VertexPositionColor>(
                        PrimitiveType.PointList, points.ToArray(), 0, points.Count );

                    effectPass.End();
                }

                basicEffect.End();
            }
        }
    }
}

The LineBatch...

using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
using Vector2 = Microsoft.Xna.Framework.Vector2;
using Vector3 = Microsoft.Xna.Framework.Vector3;
using Matrix = Microsoft.Xna.Framework.Matrix;

namespace A.Namespace.Of.Your.Choice.Graphics
{
    public sealed class LineBatch
    {
        private GraphicsDevice graphicsDevice;
        private List<VertexPositionColor> points =
            new List<VertexPositionColor>();
        private List<short> indices = new List<short>();
        private VertexDeclaration vertexDeclaration;
        private BasicEffect basicEffect;

        public LineBatch( GraphicsDevice graphicsDevice, float alpha )
        {
            this.graphicsDevice = graphicsDevice;

            basicEffect = new BasicEffect( graphicsDevice, null );
            basicEffect.VertexColorEnabled = true;
            basicEffect.Alpha = alpha;
            basicEffect.Projection = Matrix.CreateOrthographicOffCenter( 0.0F,
                graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height, 0.0F,
                0.0F, -1.0F );
            basicEffect.View = Matrix.Identity;
            basicEffect.World = Matrix.Identity;

            vertexDeclaration = new VertexDeclaration( graphicsDevice,
                VertexPositionColor.VertexElements );
        }

        public void Begin()
        {
            points.Clear();
            indices.Clear();
        }

        public void Batch( Vector2 startPoint, Vector2 endPoint,
            Color color, float layerDepth )
        {
            Batch( startPoint, color, layerDepth );
            Batch( endPoint, color, layerDepth );
        }

        public void Batch( Vector2 startPoint, Color startColor, 
            Vector2 endPoint, Color endColor, float layerDepth )
        {
            Batch( startPoint, startColor, layerDepth );
            Batch( endPoint, endColor, layerDepth );
        }

        public void Batch( Vector2 point, Color color, float layerDepth )
        {
            VertexPositionColor batchPoint =
                new VertexPositionColor(
                new Vector3( point, layerDepth ), color );
            points.Add( batchPoint );

            indices.Add( ( short ) indices.Count );
        }

        public void End()
        {
            if( points.Count > 0 )
            {
                graphicsDevice.VertexDeclaration = vertexDeclaration;
                graphicsDevice.RenderState.FillMode = FillMode.Solid;

                basicEffect.Begin();

                foreach( EffectPass effectPass in basicEffect.CurrentTechnique.Passes )
                {
                    effectPass.Begin();

                    graphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
                        PrimitiveType.LineList, points.ToArray(), 0, points.Count,
                        indices.ToArray(), 0, points.Count / 2 );

                    effectPass.End();
                }

                basicEffect.End();
            }
        }
    }
}

Hopefully at least one person might find them useful. As is where is. Any suggestions on improvements, bugs, etc welcome. Cheers,
Advertisement
Can I just say thanks - this is literally a simple drop-in and run bit of code. Exactly what I needed for drawing debug lines :)

Nice work!

This topic is closed to new replies.

Advertisement