summaryrefslogtreecommitdiff
path: root/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs')
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs203
1 files changed, 203 insertions, 0 deletions
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs
new file mode 100644
index 0000000..c67ec42
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs
@@ -0,0 +1,203 @@
+using System;
+using UnityEngine;
+using UnityEngine.EventSystems;
+using UnityEngine.Rendering;
+using UnityEngine.Serialization;
+
+namespace UnityEngine.UI
+{
+ [AddComponentMenu("UI/Mask", 13)]
+ [ExecuteInEditMode]
+ [RequireComponent(typeof(RectTransform))]
+ [DisallowMultipleComponent]
+ public class Mask : UIBehaviour, ICanvasRaycastFilter, IMaterialModifier
+ {
+ [NonSerialized]
+ private RectTransform m_RectTransform;
+ public RectTransform rectTransform
+ {
+ get { return m_RectTransform ?? (m_RectTransform = GetComponent<RectTransform>()); }
+ }
+
+ [SerializeField]
+ [FormerlySerializedAs("m_ShowGraphic")]
+ private bool m_ShowMaskGraphic = true;
+ public bool showMaskGraphic
+ {
+ get { return m_ShowMaskGraphic; }
+ set
+ {
+ if (m_ShowMaskGraphic == value)
+ return;
+
+ m_ShowMaskGraphic = value;
+ if (graphic != null)
+ graphic.SetMaterialDirty();
+ }
+ }
+
+ [NonSerialized] private Graphic m_Graphic;
+ public Graphic graphic
+ {
+ get { return m_Graphic ?? (m_Graphic = GetComponent<Graphic>()); }
+ }
+
+ [NonSerialized] private Material m_MaskMaterial;
+
+ [NonSerialized] private Material m_UnmaskMaterial;
+
+ protected Mask()
+ {}
+
+ public virtual bool MaskEnabled() { return IsActive() && graphic != null; }
+
+ [Obsolete("Not used anymore.")]
+ public virtual void OnSiblingGraphicEnabledDisabled() {}
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ if (graphic != null)
+ {
+ graphic.canvasRenderer.hasPopInstruction = true;
+ graphic.SetMaterialDirty();
+ }
+
+ MaskUtilities.NotifyStencilStateChanged(this);
+ }
+
+ protected override void OnDisable()
+ {
+ // we call base OnDisable first here
+ // as we need to have the IsActive return the
+ // correct value when we notify the children
+ // that the mask state has changed.
+ base.OnDisable();
+ if (graphic != null)
+ {
+ graphic.SetMaterialDirty();
+ graphic.canvasRenderer.hasPopInstruction = false;
+ graphic.canvasRenderer.popMaterialCount = 0;
+ }
+
+ StencilMaterial.Remove(m_MaskMaterial);
+ m_MaskMaterial = null;
+ StencilMaterial.Remove(m_UnmaskMaterial);
+ m_UnmaskMaterial = null;
+
+ MaskUtilities.NotifyStencilStateChanged(this);
+ }
+
+#if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ base.OnValidate();
+
+ if (!IsActive())
+ return;
+
+ if (graphic != null)
+ graphic.SetMaterialDirty();
+
+ MaskUtilities.NotifyStencilStateChanged(this);
+ }
+
+#endif
+
+ public virtual bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
+ {
+ if (!isActiveAndEnabled)
+ return true;
+
+ return RectTransformUtility.RectangleContainsScreenPoint(rectTransform, sp, eventCamera);
+ }
+
+ /// Stencil calculation time!
+ public virtual Material GetModifiedMaterial(Material baseMaterial)
+ {
+ if (!MaskEnabled())
+ return baseMaterial;
+
+ var rootSortCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform);
+ var stencilDepth = MaskUtilities.GetStencilDepth(transform, rootSortCanvas);
+ if (stencilDepth >= 8) // 不支持8层及以上的mask, 0-7支持,这是因为stencilRef和stencilMask只有一个字节
+ {
+ Debug.LogError("Attempting to use a stencil mask with depth > 8", gameObject);
+ return baseMaterial;
+ }
+
+ int desiredStencilBit = 1 << stencilDepth;
+
+ // if we are at the first level...
+ // we want to destroy what is there
+ if (desiredStencilBit == 1) // 最上层的mask
+ {
+ // Ref = 1
+ // Op = Replace
+ // Func = Always
+ // ReadMask = 255
+ // WriteMask = 255
+ var maskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, m_ShowMaskGraphic ? ColorWriteMask.All : 0);
+ StencilMaterial.Remove(m_MaskMaterial);
+ m_MaskMaterial = maskMaterial;
+
+ // Ref = 1
+ // Op = Zero
+ // Func = Always
+ // ReadMask = 255
+ // WriteMask = 255
+ var unmaskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Zero, CompareFunction.Always, 0);
+ StencilMaterial.Remove(m_UnmaskMaterial);
+ m_UnmaskMaterial = unmaskMaterial;
+ graphic.canvasRenderer.popMaterialCount = 1;
+ graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0);
+
+ return m_MaskMaterial;
+ }
+
+ // Ref = desiredStencilBit | (desiredStencilBit - 1)
+ // Op = Replace
+ // Func = Equal
+ // ReadMask = desiredStencilBit - 1
+ // WriteMask = desiredStencilBit | (desiredStencilBit - 1)
+
+ //otherwise we need to be a bit smarter and set some read / write masks
+ var maskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit | (desiredStencilBit - 1), StencilOp.Replace, CompareFunction.Equal, m_ShowMaskGraphic ? ColorWriteMask.All : 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1));
+ StencilMaterial.Remove(m_MaskMaterial);
+ m_MaskMaterial = maskMaterial2;
+
+ // Ref = desiredStencilBit - 1
+ // Op = Replace
+ // Func = Equal
+ // ReadMask = desiredStencilBit - 1
+ // WriteMask = desiredStencilBit | (desiredStencilBit - 1)
+ graphic.canvasRenderer.hasPopInstruction = true;
+ var unmaskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit - 1, StencilOp.Replace, CompareFunction.Equal, 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1));
+ StencilMaterial.Remove(m_UnmaskMaterial);
+ m_UnmaskMaterial = unmaskMaterial2;
+ graphic.canvasRenderer.popMaterialCount = 1;
+ graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0);
+
+ return m_MaskMaterial;
+ }
+
+
+ #region UGUI_DEBUG
+
+ Vector3[] cornors = new Vector3[4];
+
+ void OnDrawGizmos()
+ {
+ Rect rect = rectTransform.rect;
+ Gizmos.color = Color.yellow;
+ rectTransform.GetWorldCorners(cornors);
+ for (int i = 0; i < cornors.Length; ++i)
+ {
+ Gizmos.DrawLine(cornors[i], cornors[(i + 1) % cornors.Length]);
+ }
+ }
+
+ #endregion
+
+ }
+}