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閱讀 230,247評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,520評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,362評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,805評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,541評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,896評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,887評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,062評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,608評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,356評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,555評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,077評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,769評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,175評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,489評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,289評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,516評論 2 379

推薦閱讀更多精彩內容