A Simple DrawLine function is probably the base function for most of the typical Shape Drawing functions like DrawRectangle, DrawTriangle and DrawCircle. During my Editor project I wanted a tile to be marked by a red rect that should be drawn around a tile. Unfortunately XNA doesn not support simple shape drawing functions yet, so I decided to to some research and code them on my own. Of course many people recommended the "DrawPrimitive" way, using all the native 3D-Hardware methods but I wanted to use something more simple, because I didn´t need performance but easy-to-use stuff.
Since XNA makes Texture scaling so easy, another possibility is to just create a 1*1 white Texture2D and scale it to the length of the line and then rotate it, so it exactly looks like the line a normal DrawLine function would produce. In the end you have a very easy but still effective function that you can build on for other shape drawing functions like DrawRect which would simply contain of 4 calls for each edge.
Here is the code for this simple function - feel free to comment on improvments or ask questions:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Editor
{
class XNAShape
{
Texture2D pixel;
GraphicsDevice myDevice;
public XNAShape(GraphicsDevice myDevice)
{
this.myDevice = myDevice;
CreatePixelTexture();
myDevice.DeviceReset += new EventHandler(myDevice_DeviceReset);
}
//Each time the device is reset, we need to recreate the Texture - otherwise it crashes in windowed mode
void myDevice_DeviceReset(object sender, EventArgs e)
{
CreatePixelTexture();
}
//Creates a white 1*1 Texture that is used for the lines by scaling and rotating it
public void CreatePixelTexture()
{
int TargetWidth = 1;
int TargetHeight = 1;
RenderTarget2D LevelRenderTarget = new RenderTarget2D(myDevice, TargetWidth, TargetHeight, 1,
myDevice.PresentationParameters.BackBufferFormat, myDevice.PresentationParameters.MultiSampleType,
myDevice.PresentationParameters.MultiSampleQuality, RenderTargetUsage.PreserveContents);
DepthStencilBuffer stencilBuffer = new DepthStencilBuffer(myDevice, TargetWidth, TargetHeight,
myDevice.DepthStencilBuffer.Format, myDevice.PresentationParameters.MultiSampleType,
myDevice.PresentationParameters.MultiSampleQuality);
myDevice.SetRenderTarget(0, LevelRenderTarget);
// Cache the current depth buffer
DepthStencilBuffer old = myDevice.DepthStencilBuffer;
// Set our custom depth buffer
myDevice.DepthStencilBuffer = stencilBuffer;
myDevice.Clear(Color.White);
myDevice.SetRenderTarget(0, null);
// Reset the depth buffer
myDevice.DepthStencilBuffer = old;
pixel = LevelRenderTarget.GetTexture();
}
//Calculates the distances and the angle and than draws a line
public void DrawLine(SpriteBatch sprite,Vector2 start, Vector2 end, Color color)
{
int distance = (int)Vector2.Distance(start, end);
Vector2 connection = end - start;
Vector2 baseVector = new Vector2(1, 0);
float alpha = (float)Math.Acos(Vector2.Dot(connection, baseVector) / (connection.Length() * baseVector.Length()));
if (pixel != null)
sprite.Draw(pixel, new Rectangle((int)start.X, (int)start.Y, distance, 1),
null, color, alpha, new Vector2(0, 0),SpriteEffects.None, 0);
}
//Draws a rect with the help of DrawLine
public void DrawRect(SpriteBatch sprite, Rectangle rect, Color color)
{
// | left
DrawLine(sprite, new Vector2(rect.X, rect.Y), new Vector2(rect.X, rect.Y + rect.Height), color);
// - top
DrawLine(sprite, new Vector2(rect.X, rect.Y), new Vector2(rect.X + rect.Width, rect.Y ), color);
// - bottom
DrawLine(sprite, new Vector2(rect.X, rect.Y + rect.Height),
new Vector2(rect.X + rect.Width, rect.Y + rect.Height), color);
// | right
DrawLine(sprite, new Vector2(rect.X + rect.Width, rect.Y),
new Vector2(rect.X + rect.Width, rect.Y + rect.Height), color);
}
}
}
本文介绍了一种使用XNA创建简单绘图函数的方法,通过缩放和旋转1*1的白色纹理来绘制线条,并进一步实现矩形等形状的绘制。这种方法不需要高性能表现,但易于使用。
663

被折叠的 条评论
为什么被折叠?



