using System.Collections.Generic; using UnityEngine; using UnityEngine.Experimental.Rendering; namespace UnityEditor.TerrainTools { /// /// Provides a collection class for mapping string and integer values to s. /// public class RTHandleCollection : System.IDisposable { private bool m_Disposed; private Dictionary< int, RTHandle > m_Handles; private Dictionary< int, GraphicsFormat > m_Formats; private Dictionary< string, int > m_NameToHash; private Dictionary< int, string > m_HashToName; private List< int > m_Hashes; /// /// Access an RTHandle using an int hash. /// public RTHandle this[int hash] { get { if (m_Handles.ContainsKey(hash)) { return m_Handles[hash]; } return null; } set { m_Handles[hash] = value; } } /// /// Access an RTHandle using a string. /// public RTHandle this[string name] { get { if (m_NameToHash.ContainsKey(name)) { return m_Handles[m_NameToHash[name]]; } return null; } set { m_Handles[m_NameToHash[name]] = value; } } /// /// Initializes and returns an instance of RTHandleCollection. /// public RTHandleCollection() { m_Handles = new Dictionary(); m_Formats = new Dictionary(); m_NameToHash = new Dictionary(); m_HashToName = new Dictionary(); m_Hashes = new List(); } /// /// Adds an description to the RTHandleCollection for later use when you call . /// /// The hash or integer value used to identify the RTHandle. /// The name used to identify the RTHandle. /// The to use for the RTHandle description. public void AddRTHandle(int hash, string name, GraphicsFormat format) { if (!m_Handles.ContainsKey(hash)) { m_NameToHash.Add(name, hash); m_HashToName.Add(hash, name); m_Handles.Add(hash, null); m_Formats.Add(hash, format); m_Hashes.Add(hash); } else { // if the RTHandle already exists, assume they are changing the descriptor m_Formats[hash] = format; m_NameToHash[name] = hash; m_HashToName[hash] = name; } } /// /// Checks to see if an with the provided name already exists. /// /// The name used to identify an RTHandle in this RTHandleCollection. /// Returns true if the RTHandle exists. public bool ContainsRTHandle(string name) { return m_NameToHash.ContainsKey(name); } /// /// Checks to see if an with the provided hash value already exists. /// /// The hash or integer value used to identify an RTHandle in this RTHandleCollection. /// Returns the RTHandle reference associated with the provided hash or integer value. Returns NULL if the key isn't found. public RTHandle GetRTHandle(int hash) { if (m_Handles.ContainsKey(hash)) { return m_Handles[hash]; } return null; } /// /// Gathers all added s using the width, height, and depth values, if provided. /// /// The width of the RTHandle to gather. /// The height of the RTHandle to gather. /// The optional depth of the RTHandle to gather. public void GatherRTHandles(int width, int height, int depth = 0) { foreach (int key in m_Hashes) { var desc = new RenderTextureDescriptor(width, height, m_Formats[key], depth); m_Handles[key] = RTUtils.GetNewHandle(desc).WithName(m_HashToName[key]); m_Handles[key].RT.Create(); } } /// /// Releases the gathered resources. /// public void ReleaseRTHandles() { foreach (int key in m_Hashes) { if (m_Handles[key] != null) { var handle = m_Handles[key]; RTUtils.Release(handle); m_Handles[key] = null; } } } /// /// Renders a debug GUI in the SceneView that displays all the s in this RTHandleCollection. /// /// The size used to draw the Textures. public void OnSceneGUI(float size) { const float padding = 10; Handles.BeginGUI(); { Color prev = GUI.color; Rect rect = new Rect(padding, padding, size, size); foreach (KeyValuePair p in m_Handles) { GUI.color = new Color(1, 0, 1, 1); GUI.DrawTexture(rect, Texture2D.whiteTexture, ScaleMode.ScaleToFit); GUI.color = Color.white; if (p.Value != null) { GUI.DrawTexture(rect, p.Value, ScaleMode.ScaleToFit, false); } else { GUI.Label(rect, "NULL"); } Rect labelRect = rect; labelRect.y = rect.yMax; labelRect.height = EditorGUIUtility.singleLineHeight; GUI.Box(labelRect, m_HashToName[p.Key], Styles.box); rect.y += padding + size + EditorGUIUtility.singleLineHeight; if (rect.yMax + EditorGUIUtility.singleLineHeight > Screen.height - EditorGUIUtility.singleLineHeight * 2) { rect.y = padding; rect.x = rect.xMax + padding; } } GUI.color = prev; } Handles.EndGUI(); } /// /// Calls the overridden method. /// public void Dispose() { Dispose(true); } /// /// Releases the gathered resources, and clears the RTHandleCollection Dictionary. /// /// Override this method if you create a class that derives from RTHandleCollection. /// Whether to dispose resources when clearing releasing the RTHandleCollection. /// When the value is true, Unity disposes of resources. Otherwise, Unity does not dispose of resources. /// public virtual void Dispose(bool dispose) { if (m_Disposed) return; if (!dispose) return; ReleaseRTHandles(); m_Handles.Clear(); m_Disposed = true; } private static class Styles { public static GUIStyle box; static Styles() { box = new GUIStyle(EditorStyles.helpBox); box.normal.textColor = Color.white; } } } }