Sign in to follow this  
cpt spleen

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

Recommended Posts

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,

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this