unity drawing

using System.Reflection;

using UnityEngine;

// Line drawing routine originally courtesy of Linusmartensson:

// http://forum.unity3d.com/threads/71979-Drawing-lines-in-the-editor

//

// Rewritten to improve performance by Yossarian King / August 2013.

//

// This version produces virtually identical results to the original (tested by drawing

// one over the other and observing errors of one pixel or less), but for large numbers

// of lines this version is more than four times faster than the original, and comes

// within about 70% of the raw performance of Graphics.DrawTexture.

//

// Peak performance on my laptop is around 200,000 lines per second. The laptop is

// Windows 7 64-bit, Intel Core2 Duo CPU 2.53GHz, 4G RAM, NVIDIA GeForce GT 220M.

// Line width and anti-aliasing had negligible impact on performance.

//

// For a graph of benchmark results in a standalone Windows build, see this image:

// https://app.box.com/s/hyuhi565dtolqdm97e00

//

// For a Google spreadsheet with full benchmark results, see:

// https://docs.google.com/spreadsheet/ccc?key=0AvJlJlbRO26VdHhzeHNRMVF2UHZHMXFCTVFZN011V1E&usp=sharing

public static class Drawing

{

private static Texture2D aaLineTex = null;

private static Texture2D lineTex = null;

private static Material blitMaterial = null;

private static Material blendMaterial = null;

private static Rect lineRect = new Rect(0, 0, 1, 1);

// Draw a line in screen space, suitable for use from OnGUI calls from either

// MonoBehaviour or EditorWindow. Note that this should only be called during repaint

// events, when (Event.current.type == EventType.Repaint).

//

// Works by computing a matrix that transforms a unit square -- Rect(0,0,1,1) -- into

// a scaled, rotated, and offset rectangle that corresponds to the line and its width.

// A DrawTexture call used to draw a line texture into the transformed rectangle.

//

// More specifically:

//      scale x by line length, y by line width

//      rotate around z by the angle of the line

//      offset by the position of the upper left corner of the target rectangle

//

// By working out the matrices and applying some trigonometry, the matrix calculation comes

// out pretty simple. See https://app.box.com/s/xi08ow8o8ujymazg100j for a picture of my

// notebook with the calculations.

public static void DrawLine(Vector2 pointA, Vector2 pointB, Color color, float width, bool antiAlias)

{

// Normally the static initializer does this, but to handle texture reinitialization

// after editor play mode stops we need this check in the Editor.

#if UNITY_EDITOR

if (!lineTex)

{

Initialize();

}

#endif

// Note that theta = atan2(dy, dx) is the angle we want to rotate by, but instead

// of calculating the angle we just use the sine (dy/len) and cosine (dx/len).

float dx = pointB.x - pointA.x;

float dy = pointB.y - pointA.y;

float len = Mathf.Sqrt(dx * dx + dy * dy);

// Early out on tiny lines to avoid divide by zero.

// Plus what's the point of drawing a line 1/1000th of a pixel long??

if (len < 0.001f)

{

return;

}

// Pick texture and material (and tweak width) based on anti-alias setting.

Texture2D tex;

Material mat;

if (antiAlias)

{

// Multiplying by three is fine for anti-aliasing width-1 lines, but make a wide "fringe"

// for thicker lines, which may or may not be desirable.

width = width * 3.0f;

tex = aaLineTex;

mat = blendMaterial;

}

else

{

tex = lineTex;

mat = blitMaterial;

}

float wdx = width * dy / len;

float wdy = width * dx / len;

Matrix4x4 matrix = Matrix4x4.identity;

matrix.m00 = dx;

matrix.m01 = -wdx;

matrix.m03 = pointA.x + 0.5f * wdx;

matrix.m10 = dy;

matrix.m11 = wdy;

matrix.m13 = pointA.y - 0.5f * wdy;

// Use GL matrix and Graphics.DrawTexture rather than GUI.matrix and GUI.DrawTexture,

// for better performance. (Setting GUI.matrix is slow, and GUI.DrawTexture is just a

// wrapper on Graphics.DrawTexture.)

GL.PushMatrix();

GL.MultMatrix(matrix);

//Graphics.DrawTexture(lineRect, tex, lineRect, 0, 0, 0, 0, color, mat);

//Replaced by:

GUI.color = color;//this and...

GUI.DrawTexture( lineRect, tex );//this

GL.PopMatrix();

}

//

public static void DrawCircle(float x, float y, float z, float r, float accuracy)

{

GL.PushMatrix();

//绘制2D图像

GL.LoadOrtho();

float stride = r * accuracy;

float size = 1 / accuracy;

float x1 = x, x2 = x, y1 = 0, y2 = 0;

float x3 = x, x4 = x, y3 = 0, y4 = 0;

double squareDe;

squareDe = r * r - Mathf.Pow(x - x1, 2);

squareDe = squareDe > 0 ? squareDe : 0;

y1 = (float)(y + Mathf.Sqrt((float)squareDe));

squareDe = r * r - Mathf.Pow(x - x1, 2);

squareDe = squareDe > 0 ? squareDe : 0;

y2 = (float)(y - Mathf.Sqrt((float)squareDe));

for (int i = 0; i < size; i++)

{

x3 = x1 + stride;

x4 = x2 - stride;

squareDe = r * r - Mathf.Pow(x - x3, 2);

squareDe = squareDe > 0 ? squareDe : 0;

y3 = (float)(y + Mathf.Sqrt((float)squareDe));

squareDe = r * r - Mathf.Pow(x - x4, 2);

squareDe = squareDe > 0 ? squareDe : 0;

y4 = (float)(y - Mathf.Sqrt((float)squareDe));

//绘制线段

GL.Begin(GL.LINES);

GL.Color(Color.blue);

GL.Vertex(new Vector3(x1 / Screen.width, y1 / Screen.height, z));

GL.Vertex(new Vector3(x3 / Screen.width, y3 / Screen.height, z));

GL.End();

GL.Begin(GL.LINES);

GL.Color(Color.blue);

GL.Vertex(new Vector3(x2 / Screen.width, y1 / Screen.height, z));

GL.Vertex(new Vector3(x4 / Screen.width, y3 / Screen.height, z));

GL.End();

GL.Begin(GL.LINES);

GL.Color(Color.blue);

GL.Vertex(new Vector3(x1 / Screen.width, y2 / Screen.height, z));

GL.Vertex(new Vector3(x3 / Screen.width, y4 / Screen.height, z));

GL.End();

GL.Begin(GL.LINES);

GL.Color(Color.blue);

GL.Vertex(new Vector3(x2 / Screen.width, y2 / Screen.height, z));

GL.Vertex(new Vector3(x4 / Screen.width, y4 / Screen.height, z));

GL.End();

x1 = x3;

x2 = x4;

y1 = y3;

y2 = y4;

}

GL.PopMatrix();

}

public static void DrawCircle(Vector2 center, int radius, Color color, float width, int segmentsPerQuarter) {

DrawCircle(center, radius, color, width, false, segmentsPerQuarter);

}

public static void DrawCircle(Vector2 center, int radius, Color color, float width, bool antiAlias, int segmentsPerQuarter) {

float rh = (float)radius / 2;

Vector2 p1 = new Vector2(center.x, center.y - radius);

Vector2 p1_tan_a = new Vector2(center.x - rh, center.y - radius);

Vector2 p1_tan_b = new Vector2(center.x + rh, center.y - radius);

Vector2 p2 = new Vector2(center.x + radius, center.y);

Vector2 p2_tan_a = new Vector2(center.x + radius, center.y - rh);

Vector2 p2_tan_b = new Vector2(center.x + radius, center.y + rh);

Vector2 p3 = new Vector2(center.x, center.y + radius);

Vector2 p3_tan_a = new Vector2(center.x - rh, center.y + radius);

Vector2 p3_tan_b = new Vector2(center.x + rh, center.y + radius);

Vector2 p4 = new Vector2(center.x - radius, center.y);

Vector2 p4_tan_a = new Vector2(center.x - radius, center.y - rh);

Vector2 p4_tan_b = new Vector2(center.x - radius, center.y + rh);

DrawBezierLine(p1, p1_tan_b, p2, p2_tan_a, color, width, antiAlias, segmentsPerQuarter);

DrawBezierLine(p2, p2_tan_b, p3, p3_tan_b, color, width, antiAlias, segmentsPerQuarter);

DrawBezierLine(p3, p3_tan_a, p4, p4_tan_b, color, width, antiAlias, segmentsPerQuarter);

DrawBezierLine(p4, p4_tan_a, p1, p1_tan_a, color, width, antiAlias, segmentsPerQuarter);

}

// Other than method name, DrawBezierLine is unchanged from Linusmartensson's original implementation.

public static void DrawBezierLine(Vector2 start, Vector2 startTangent, Vector2 end, Vector2 endTangent, Color color, float width, bool antiAlias, int segments)

{

Vector2 lastV = CubeBezier(start, startTangent, end, endTangent, 0);

for (int i = 1; i < segments + 1; ++i)

{

Vector2 v = CubeBezier(start, startTangent, end, endTangent, i/(float)segments);

Drawing.DrawLine(lastV, v, color, width, antiAlias);

lastV = v;

}

}

private static Vector2 CubeBezier(Vector2 s, Vector2 st, Vector2 e, Vector2 et, float t)

{

float rt = 1 - t;

return rt * rt * rt * s + 3 * rt * rt * t * st + 3 * rt * t * t * et + t * t * t * e;

}

// This static initializer works for runtime, but apparently isn't called when

// Editor play mode stops, so DrawLine will re-initialize if needed.

static Drawing()

{

Initialize();

}

private static void Initialize()

{

if (lineTex == null)

{

lineTex = new Texture2D(1, 1, TextureFormat.ARGB32, false);

lineTex.SetPixel(0, 1, Color.white);

lineTex.Apply();

}

if (aaLineTex == null)

{

// TODO: better anti-aliasing of wide lines with a larger texture? or use Graphics.DrawTexture with border settings

aaLineTex = new Texture2D(1, 3, TextureFormat.ARGB32, false);

aaLineTex.SetPixel(0, 0, new Color(1, 1, 1, 0));

aaLineTex.SetPixel(0, 1, Color.white);

aaLineTex.SetPixel(0, 2, new Color(1, 1, 1, 0));

aaLineTex.Apply();

}

// GUI.blitMaterial and GUI.blendMaterial are used internally by GUI.DrawTexture,

// depending on the alphaBlend parameter. Use reflection to "borrow" these references.

blitMaterial = (Material)typeof(GUI).GetMethod("get_blitMaterial", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null);

blendMaterial = (Material)typeof(GUI).GetMethod("get_blendMaterial", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null);

}

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容