Okay, lets start.
I was very surprised that XNA doesn't come with 2d primitives library, you can't draw lines, rectangles and other simple objects, you can only draw sprites, which is a bit odd...
Anyway, I searched the net but couldn't find any library that could replace it. Also there wasn't any general solution to it also.
So... I decided to write my own library
Here it is. Just look at it for now, then I explain everthing.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace QWE { class Primitives2d { Texture2D pixel; //our pixel texture we will be using to draw primitives GraphicsDevice gd; //graphics device to use SpriteBatch sb; //sprite batch to use public Primitives2d(GraphicsDevice graphicsDevice, SpriteBatch spriteBatch) { //saving GD for use in drawing funtions this.gd = graphicsDevice; this.sb = spriteBatch; //creating our simple pixel pixel = new Texture2D(gd, 1, 1); pixel.SetData(new Color[] { Color.White }); } //draws a pixel public void DrawPixel(int x, int y , Color col) { sb.Draw(pixel, new Vector2(x,y), col); } //draws a line obviously :)/> public void DrawLine(int x1, int y1, int x2, int y2, Color col) { int deltax, deltay, x, y, xinc1, xinc2, yinc1, yinc2, den, num, numadd, numpixels, curpixel; deltax = Math.Abs(x2 - x1); // The difference between the x's deltay = Math.Abs(y2 - y1); // The difference between the y's x = x1; // Start x off at the first pixel y = y1; // Start y off at the first pixel if (x2 >= x1) // The x-values are increasing { xinc1 = 1; xinc2 = 1; } else // The x-values are decreasing { xinc1 = -1; xinc2 = -1; } if (y2 >= y1) // The y-values are increasing { yinc1 = 1; yinc2 = 1; } else // The y-values are decreasing { yinc1 = -1; yinc2 = -1; } if (deltax >= deltay) // There is at least one x-value for every y-value { xinc1 = 0; // Don't change the x when numerator >= denominator yinc2 = 0; // Don't change the y for every iteration den = deltax; num = deltax / 2; numadd = deltay; numpixels = deltax; // There are more x-values than y-values } else // There is at least one y-value for every x-value { xinc2 = 0; // Don't change the x for every iteration yinc1 = 0; // Don't change the y when numerator >= denominator den = deltay; num = deltay / 2; numadd = deltax; numpixels = deltay; // There are more y-values than x-values } for (curpixel = 0; curpixel <= numpixels; curpixel++) { DrawPixel(x,y,col); num += numadd; // Increase the numerator by the top of the fraction if (num >= den) // Check if numerator >= denominator { num -= den; // Calculate the new numerator value x += xinc1; // Change the x as appropriate y += yinc1; // Change the y as appropriate } x += xinc2; // Change the x as appropriate y += yinc2; // Change the y as appropriate } } public void DrawRectangle(Rectangle rect, Color col, Boolean filled) { if (filled) { sb.Draw(pixel, rect, col); } else { DrawLine(rect.X, rect.Y, rect.X + rect.Width, rect.Y,col); DrawLine(rect.X, rect.Y, rect.X, rect.Y + rect.Height,col); DrawLine(rect.X + rect.Width, rect.Y, rect.X + rect.Width, rect.Y + rect.Height, col); DrawLine(rect.X, rect.Y + rect.Height, rect.X + rect.Width, rect.Y + rect.Height, col); } } } }
Okay. What I do.
First I create texture/sprite in memory with only one pixel and white color. We will be using this sprite to draw all of our primitives manually, pixel by pixel.
First function is drawing a pixel itself. It's pretty straightforward.
DrawLine is drawing the line using previous DrawPisel function and this algorithm http://en.wikipedia...._line_algorithm
Draw Rectangle is also similar to previous function.
This realisation is quite slow, drawind just 500 lines with length about 400 will drop fps to 12/sec.
Still I think it's enought for vector games or other purposes.
You can implement drawing circle and other premitives using the same principle.
Ah, and how you call these functions:
spriteBatch.Begin();
primitives2d.DrawPixel(25, 25, new Color(255,255,255));
Random rnd = new Random();
for(int i = 0; i<5; i++) {
Primitives2d.DrawLine(rnd.Next(0,800), rnd.Next(0,800), rnd.Next(0,800), rnd.Next(0,800), new Color(255, 255, 255));
}
primitives2d.DrawRectangle(new Rectangle(100, 100, 500, 500), new Color(0, 32, 0, 128), true);
primitives2d.DrawRectangle(new Rectangle(100, 100, 500, 200), new Color(255, 0, 0), false);
spriteBatch.End();



MultiQuote

|