using UnityEngine; namespace UnityEditor.Performance.ProfileAnalyzer { internal class Draw2D { public enum Origin { TopLeft, BottomLeft }; Origin m_Origin = Origin.TopLeft; GUIStyle m_GLStyle; string m_ShaderName; Material m_Material; Rect m_Rect; Vector4 m_ClipRect; bool m_ClipRectEnabled = false; public Draw2D(string shaderName) { m_ShaderName = shaderName; CheckAndSetupMaterial(); } public bool CheckAndSetupMaterial() { if (m_Material == null) { var shader = Shader.Find(m_ShaderName); if (shader == null) { Debug.LogFormat("Unable to locate shader {0}", m_ShaderName); return false; } m_Material = new Material(shader); if (m_Material == null) { Debug.LogFormat("Unable to create material for {0}", m_ShaderName); return false; } } return true; } public bool IsMaterialValid() { if (m_Material == null) return false; return true; } public void OnGUI() { if (m_GLStyle == null) { m_GLStyle = new GUIStyle(GUI.skin.box); m_GLStyle.padding = new RectOffset(0, 0, 0, 0); m_GLStyle.margin = new RectOffset(0, 0, 0, 0); } } public void SetClipRect(Rect clipRect) { m_ClipRect = new Vector4(clipRect.x, clipRect.y, clipRect.x + clipRect.width, clipRect.y + clipRect.height); m_ClipRectEnabled = true; if (CheckAndSetupMaterial()) { m_Material.SetFloat("_UseClipRect", m_ClipRectEnabled ? 1f : 0f); m_Material.SetVector("_ClipRect", m_ClipRect); } } public void ClearClipRect() { m_ClipRectEnabled = false; if (CheckAndSetupMaterial()) { m_Material.SetFloat("_UseClipRect", m_ClipRectEnabled ? 1f : 0f); m_Material.SetVector("_ClipRect", m_ClipRect); } } public Rect GetClipRect() { return new Rect(m_ClipRect.x, m_ClipRect.y, m_ClipRect.z - m_ClipRect.x, m_ClipRect.w - m_ClipRect.y); } public bool DrawStart(Rect r, Origin origin = Origin.TopLeft) { if (Event.current.type != EventType.Repaint) return false; if (!CheckAndSetupMaterial()) return false; m_Material.SetPass(0); m_Rect = r; m_Origin = origin; return true; } public bool DrawStart(float w, float h, Origin origin = Origin.TopLeft, GUIStyle style = null) { Rect r = GUILayoutUtility.GetRect(w, h, style == null ? m_GLStyle : style, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false)); return DrawStart(r, origin); } public void DrawEnd() { } public void Translate(ref float x, ref float y) { // Translation done CPU side so we have world space coords in the shader for clipping. if (m_Origin == Origin.BottomLeft) { x = m_Rect.xMin + x; y = m_Rect.yMax - y; } else { x = m_Rect.xMin + x; y = m_Rect.yMin + y; } } public void DrawFilledBox(float x, float y, float w, float h, Color col) { float x2 = x + w; float y2 = y + h; Translate(ref x, ref y); Translate(ref x2, ref y2); if (m_Origin == Origin.BottomLeft) { GL.Begin(GL.TRIANGLE_STRIP); GL.Color(col); GL.Vertex3(x, y, 0); GL.Vertex3(x, y2, 0); GL.Vertex3(x2, y, 0); GL.Vertex3(x2, y2, 0); GL.End(); } else { GL.Begin(GL.TRIANGLE_STRIP); GL.Color(col); GL.Vertex3(x, y, 0); GL.Vertex3(x2, y, 0); GL.Vertex3(x, y2, 0); GL.Vertex3(x2, y2, 0); GL.End(); } } public void DrawFilledBox(float x, float y, float w, float h, float r, float g, float b) { DrawFilledBox(x, y, w, h, new Color(r, g, b)); } public void DrawLine(float x, float y, float x2, float y2, Color col) { Translate(ref x, ref y); Translate(ref x2, ref y2); GL.Begin(GL.LINES); GL.Color(col); GL.Vertex3(x, y, 0); GL.Vertex3(x2, y2, 0); GL.End(); } public void DrawLine(float x, float y, float x2, float y2, float r, float g, float b) { DrawLine(x, y, x2, y2, new Color(r, g, b)); } public void DrawBox(float x, float y, float w, float h, Color col) { float x2 = x + w; float y2 = y + h; Translate(ref x, ref y); Translate(ref x2, ref y2); GL.Begin(GL.LINE_STRIP); GL.Color(col); GL.Vertex3(x, y, 0); GL.Vertex3(x2, y, 0); GL.Vertex3(x2, y2, 0); GL.Vertex3(x, y2, 0); GL.Vertex3(x, y, 0); GL.End(); } public void DrawBox(float x, float y, float w, float h, float r, float g, float b) { DrawBox(x, y, w, h, new Color(r, g, b)); } } }