diff options
author | chai <chaifix@163.com> | 2021-04-07 21:06:10 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-04-07 21:06:10 +0800 |
commit | c7e2d8f773baa3955f17402b842eb43329c5f3a0 (patch) | |
tree | 5ba3985d20a2908a67fefa89579f6cf3a94b6a5a /Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics | |
parent | e7dfbec8e8634e767d78959941daf71a96e021cf (diff) |
+UI_Effect
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.cs | 229 | ||||
-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.cs | 169 |
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(); - } - } -} |