summaryrefslogtreecommitdiff
path: root/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics')
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs229
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs.meta (renamed from Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/StencilMaterial.cs.meta)2
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/StencilMaterial.cs169
3 files changed, 230 insertions, 170 deletions
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs
new file mode 100644
index 0000000..4995dc1
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs
@@ -0,0 +1,229 @@
+using System;
+using UnityEngine.Events;
+using UnityEngine.Rendering;
+
+namespace UnityEngine.UI
+{
+ public abstract class MaskableGraphic : Graphic, IClippable, IMaskable, IMaterialModifier
+ {
+ [NonSerialized]
+ protected bool m_ShouldRecalculateStencil = true;
+
+ [NonSerialized]
+ protected Material m_MaskMaterial;
+
+ [NonSerialized]
+ private RectMask2D m_ParentMask;
+
+ // m_Maskable is whether this graphic is allowed to be masked or not. It has the matching public property maskable.
+ // The default for m_Maskable is true, so graphics under a mask are masked out of the box.
+ // The maskable property can be turned off from script by the user if masking is not desired.
+ // m_IncludeForMasking is whether we actually consider this graphic for masking or not - this is an implementation detail.
+ // m_IncludeForMasking should only be true if m_Maskable is true AND a parent of the graphic has an IMask component.
+ // Things would still work correctly if m_IncludeForMasking was always true when m_Maskable is, but performance would suffer.
+ [NonSerialized]
+ private bool m_Maskable = true;
+
+ [NonSerialized]
+ [Obsolete("Not used anymore.", true)]
+ protected bool m_IncludeForMasking = false;
+
+ [Serializable]
+ public class CullStateChangedEvent : UnityEvent<bool> {}
+
+ // Event delegates triggered on click.
+ [SerializeField]
+ private CullStateChangedEvent m_OnCullStateChanged = new CullStateChangedEvent();
+
+ public CullStateChangedEvent onCullStateChanged
+ {
+ get { return m_OnCullStateChanged; }
+ set { m_OnCullStateChanged = value; }
+ }
+
+ public bool maskable
+ {
+ get { return m_Maskable; }
+ set
+ {
+ if (value == m_Maskable)
+ return;
+ m_Maskable = value;
+ m_ShouldRecalculateStencil = true;
+ SetMaterialDirty();
+ }
+ }
+
+ [NonSerialized]
+ [Obsolete("Not used anymore", true)]
+ protected bool m_ShouldRecalculate = true;
+
+ [NonSerialized]
+ protected int m_StencilValue;
+
+ public virtual Material GetModifiedMaterial(Material baseMaterial)
+ {
+ var toUse = baseMaterial;
+
+ if (m_ShouldRecalculateStencil)
+ {
+ var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform);
+ m_StencilValue = maskable ? MaskUtilities.GetStencilDepth(transform, rootCanvas) : 0;
+ m_ShouldRecalculateStencil = false;
+ }
+
+ // if we have a enabled Mask component then it will
+ // generate the mask material. This is an optimisation
+ // it adds some coupling between components though :(
+ Mask maskComponent = GetComponent<Mask>();
+ if (m_StencilValue > 0 && (maskComponent == null || !maskComponent.IsActive()))
+ {
+ var maskMat = StencilMaterial.Add(toUse, (1 << m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << m_StencilValue) - 1, 0);
+ StencilMaterial.Remove(m_MaskMaterial);
+ m_MaskMaterial = maskMat;
+ toUse = m_MaskMaterial;
+ }
+ return toUse;
+ }
+
+ public virtual void Cull(Rect clipRect, bool validRect)
+ {
+ var cull = !validRect || !clipRect.Overlaps(rootCanvasRect, true);
+ UpdateCull(cull);
+ }
+
+ private void UpdateCull(bool cull)
+ {
+ var cullingChanged = canvasRenderer.cull != cull;
+ canvasRenderer.cull = cull;
+
+ if (cullingChanged)
+ {
+ UISystemProfilerApi.AddMarker("MaskableGraphic.cullingChanged", this);
+ m_OnCullStateChanged.Invoke(cull);
+ SetVerticesDirty();
+ }
+ }
+
+ public virtual void SetClipRect(Rect clipRect, bool validRect)
+ {
+ if (validRect)
+ canvasRenderer.EnableRectClipping(clipRect);
+ else
+ canvasRenderer.DisableRectClipping();
+ }
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ m_ShouldRecalculateStencil = true;
+ UpdateClipParent();
+ SetMaterialDirty();
+
+ if (GetComponent<Mask>() != null)
+ {
+ MaskUtilities.NotifyStencilStateChanged(this);
+ }
+ }
+
+ protected override void OnDisable()
+ {
+ base.OnDisable();
+ m_ShouldRecalculateStencil = true;
+ SetMaterialDirty();
+ UpdateClipParent();
+ StencilMaterial.Remove(m_MaskMaterial);
+ m_MaskMaterial = null;
+
+ if (GetComponent<Mask>() != null)
+ {
+ MaskUtilities.NotifyStencilStateChanged(this);
+ }
+ }
+
+#if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ base.OnValidate();
+ m_ShouldRecalculateStencil = true;
+ UpdateClipParent();
+ SetMaterialDirty();
+ }
+
+#endif
+
+ protected override void OnTransformParentChanged()
+ {
+ base.OnTransformParentChanged();
+
+ if (!isActiveAndEnabled)
+ return;
+
+ m_ShouldRecalculateStencil = true;
+ UpdateClipParent();
+ SetMaterialDirty();
+ }
+
+ [Obsolete("Not used anymore.", true)]
+ public virtual void ParentMaskStateChanged() {}
+
+ protected override void OnCanvasHierarchyChanged()
+ {
+ base.OnCanvasHierarchyChanged();
+
+ if (!isActiveAndEnabled)
+ return;
+
+ m_ShouldRecalculateStencil = true;
+ UpdateClipParent();
+ SetMaterialDirty();
+ }
+
+ readonly Vector3[] m_Corners = new Vector3[4];
+ private Rect rootCanvasRect
+ {
+ get
+ {
+ rectTransform.GetWorldCorners(m_Corners);
+
+ if (canvas)
+ {
+ Canvas rootCanvas = canvas.rootCanvas;
+ for (int i = 0; i < 4; ++i)
+ m_Corners[i] = rootCanvas.transform.InverseTransformPoint(m_Corners[i]);
+ }
+
+ return new Rect(m_Corners[0].x, m_Corners[0].y, m_Corners[2].x - m_Corners[0].x, m_Corners[2].y - m_Corners[0].y);
+ }
+ }
+
+ private void UpdateClipParent()
+ {
+ var newParent = (maskable && IsActive()) ? MaskUtilities.GetRectMaskForClippable(this) : null;
+
+ // if the new parent is different OR is now inactive
+ if (m_ParentMask != null && (newParent != m_ParentMask || !newParent.IsActive()))
+ {
+ m_ParentMask.RemoveClippable(this);
+ UpdateCull(false);
+ }
+
+ // don't re-add it if the newparent is inactive
+ if (newParent != null && newParent.IsActive())
+ newParent.AddClippable(this);
+
+ m_ParentMask = newParent;
+ }
+
+ public virtual void RecalculateClipping()
+ {
+ UpdateClipParent();
+ }
+
+ public virtual void RecalculateMasking()
+ {
+ m_ShouldRecalculateStencil = true;
+ SetMaterialDirty();
+ }
+ }
+}
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/StencilMaterial.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs.meta
index 3fd6a69..07f0d51 100644
--- a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/StencilMaterial.cs.meta
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 2d445d28188ffd745990df17f1ce8914
+guid: 1316d79994e789c448714be540d28f4f
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/StencilMaterial.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/StencilMaterial.cs
deleted file mode 100644
index c12f209..0000000
--- a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/StencilMaterial.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-using System;
-using System.Collections.Generic;
-using UnityEngine.Rendering;
-
-namespace UnityEngine.UI
-{
- /// <summary>
- /// Dynamic material class makes it possible to create custom materials on the fly on a per-Graphic basis,
- /// and still have them get cleaned up correctly.
- /// </summary>
- public static class StencilMaterial
- {
- private class MatEntry
- {
- public Material baseMat;
- public Material customMat;
- public int count;
-
- public int stencilId;
- public StencilOp operation = StencilOp.Keep;
- public CompareFunction compareFunction = CompareFunction.Always;
- public int readMask;
- public int writeMask;
- public bool useAlphaClip;
- public ColorWriteMask colorMask;
- }
-
- private static List<MatEntry> m_List = new List<MatEntry>();
-
- [Obsolete("Use Material.Add instead.", true)]
- public static Material Add(Material baseMat, int stencilID) { return null; }
-
- /// <summary>
- /// Add a new material using the specified base and stencil ID.
- /// </summary>
- public static Material Add(Material baseMat, int stencilID, StencilOp operation, CompareFunction compareFunction, ColorWriteMask colorWriteMask)
- {
- return Add(baseMat, stencilID, operation, compareFunction, colorWriteMask, 255, 255);
- }
-
- /// <summary>
- /// Add a new material using the specified base and stencil ID.
- /// </summary>
- public static Material Add(Material baseMat, int stencilID, StencilOp operation, CompareFunction compareFunction, ColorWriteMask colorWriteMask, int readMask, int writeMask)
- {
- if ((stencilID <= 0 && colorWriteMask == ColorWriteMask.All) || baseMat == null)
- return baseMat;
-
- if (!baseMat.HasProperty("_Stencil"))
- {
- Debug.LogWarning("Material " + baseMat.name + " doesn't have _Stencil property", baseMat);
- return baseMat;
- }
- if (!baseMat.HasProperty("_StencilOp"))
- {
- Debug.LogWarning("Material " + baseMat.name + " doesn't have _StencilOp property", baseMat);
- return baseMat;
- }
- if (!baseMat.HasProperty("_StencilComp"))
- {
- Debug.LogWarning("Material " + baseMat.name + " doesn't have _StencilComp property", baseMat);
- return baseMat;
- }
- if (!baseMat.HasProperty("_StencilReadMask"))
- {
- Debug.LogWarning("Material " + baseMat.name + " doesn't have _StencilReadMask property", baseMat);
- return baseMat;
- }
- if (!baseMat.HasProperty("_StencilWriteMask"))
- {
- Debug.LogWarning("Material " + baseMat.name + " doesn't have _StencilWriteMask property", baseMat);
- return baseMat;
- }
- if (!baseMat.HasProperty("_ColorMask"))
- {
- Debug.LogWarning("Material " + baseMat.name + " doesn't have _ColorMask property", baseMat);
- return baseMat;
- }
-
- for (int i = 0; i < m_List.Count; ++i)
- {
- MatEntry ent = m_List[i];
-
- if (ent.baseMat == baseMat
- && ent.stencilId == stencilID
- && ent.operation == operation
- && ent.compareFunction == compareFunction
- && ent.readMask == readMask
- && ent.writeMask == writeMask
- && ent.colorMask == colorWriteMask)
- {
- ++ent.count;
- return ent.customMat;
- }
- }
-
- var newEnt = new MatEntry();
- newEnt.count = 1;
- newEnt.baseMat = baseMat;
- newEnt.customMat = new Material(baseMat);
- newEnt.customMat.hideFlags = HideFlags.HideAndDontSave;
- newEnt.stencilId = stencilID;
- newEnt.operation = operation;
- newEnt.compareFunction = compareFunction;
- newEnt.readMask = readMask;
- newEnt.writeMask = writeMask;
- newEnt.colorMask = colorWriteMask;
- newEnt.useAlphaClip = operation != StencilOp.Keep && writeMask > 0;
-
- newEnt.customMat.name = string.Format("Stencil Id:{0}, Op:{1}, Comp:{2}, WriteMask:{3}, ReadMask:{4}, ColorMask:{5} AlphaClip:{6} ({7})", stencilID, operation, compareFunction, writeMask, readMask, colorWriteMask, newEnt.useAlphaClip, baseMat.name);
-
- newEnt.customMat.SetInt("_Stencil", stencilID);
- newEnt.customMat.SetInt("_StencilOp", (int)operation);
- newEnt.customMat.SetInt("_StencilComp", (int)compareFunction);
- newEnt.customMat.SetInt("_StencilReadMask", readMask);
- newEnt.customMat.SetInt("_StencilWriteMask", writeMask);
- newEnt.customMat.SetInt("_ColorMask", (int)colorWriteMask);
-
- // left for backwards compatability
- if (newEnt.customMat.HasProperty("_UseAlphaClip"))
- newEnt.customMat.SetInt("_UseAlphaClip", newEnt.useAlphaClip ? 1 : 0);
-
- if (newEnt.useAlphaClip)
- newEnt.customMat.EnableKeyword("UNITY_UI_ALPHACLIP");
- else
- newEnt.customMat.DisableKeyword("UNITY_UI_ALPHACLIP");
-
- m_List.Add(newEnt);
- return newEnt.customMat;
- }
-
- /// <summary>
- /// Remove an existing material, automatically cleaning it up if it's no longer in use.
- /// </summary>
- public static void Remove(Material customMat)
- {
- if (customMat == null)
- return;
-
- for (int i = 0; i < m_List.Count; ++i)
- {
- MatEntry ent = m_List[i];
-
- if (ent.customMat != customMat)
- continue;
-
- if (--ent.count == 0)
- {
- Misc.DestroyImmediate(ent.customMat);
- ent.baseMat = null;
- m_List.RemoveAt(i);
- }
- return;
- }
- }
-
- public static void ClearAll()
- {
- for (int i = 0; i < m_List.Count; ++i)
- {
- MatEntry ent = m_List[i];
-
- Misc.DestroyImmediate(ent.customMat);
- ent.baseMat = null;
- }
- m_List.Clear();
- }
- }
-}