123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using Object = UnityEngine.Object;
- namespace FairyGUI
- {
- [Flags]
- public enum MaterialFlags
- {
- Clipped = 1,
- SoftClipped = 2,
- StencilTest = 4,
- AlphaMask = 8,
- Grayed = 16,
- ColorFilter = 32
- }
-
-
-
- public class MaterialManager
- {
- public event Action<Material> onCreateNewMaterial;
- public bool firstMaterialInFrame;
- NTexture _texture;
- Shader _shader;
- List<string> _addKeywords;
- Dictionary<int, List<MaterialRef>> _materials;
- bool _combineTexture;
- class MaterialRef
- {
- public Material material;
- public int frame;
- public BlendMode blendMode;
- public uint group;
- }
- const int internalKeywordsCount = 6;
- static string[] internalKeywords = new[] { "CLIPPED", "SOFT_CLIPPED", null, "ALPHA_MASK", "GRAYED", "COLOR_FILTER" };
-
-
-
-
-
- internal MaterialManager(NTexture texture, Shader shader)
- {
- _texture = texture;
- _shader = shader;
- _materials = new Dictionary<int, List<MaterialRef>>();
- _combineTexture = texture.alphaTexture != null;
- }
-
-
-
-
-
- public int GetFlagsByKeywords(IList<string> keywords)
- {
- if (_addKeywords == null)
- _addKeywords = new List<string>();
- int flags = 0;
- for (int i = 0; i < keywords.Count; i++)
- {
- string s = keywords[i];
- if (string.IsNullOrEmpty(s))
- continue;
- int j = _addKeywords.IndexOf(s);
- if (j == -1)
- {
- j = _addKeywords.Count;
- _addKeywords.Add(s);
- }
- flags += (1 << (j + internalKeywordsCount));
- }
- return flags;
- }
-
-
-
-
-
-
-
- public Material GetMaterial(int flags, BlendMode blendMode, uint group)
- {
- if (blendMode != BlendMode.Normal && BlendModeUtils.Factors[(int)blendMode].pma)
- flags |= (int)MaterialFlags.ColorFilter;
- List<MaterialRef> items;
- if (!_materials.TryGetValue(flags, out items))
- {
- items = new List<MaterialRef>();
- _materials[flags] = items;
- }
- int frameId = Time.frameCount;
- int cnt = items.Count;
- MaterialRef result = null;
- for (int i = 0; i < cnt; i++)
- {
- MaterialRef item = items[i];
- if (item.group == group && item.blendMode == blendMode)
- {
- if (item.frame != frameId)
- {
- firstMaterialInFrame = true;
- item.frame = frameId;
- }
- else
- firstMaterialInFrame = false;
- if (_combineTexture)
- item.material.SetTexture(ShaderConfig.ID_AlphaTex, _texture.alphaTexture);
- return item.material;
- }
- else if (result == null && (item.frame > frameId || item.frame < frameId - 1))
- result = item;
- }
- if (result == null)
- {
- result = new MaterialRef() { material = CreateMaterial(flags) };
- items.Add(result);
- }
- else if (_combineTexture)
- result.material.SetTexture(ShaderConfig.ID_AlphaTex, _texture.alphaTexture);
- if (result.blendMode != blendMode)
- {
- BlendModeUtils.Apply(result.material, blendMode);
- result.blendMode = blendMode;
- }
- result.group = group;
- result.frame = frameId;
- firstMaterialInFrame = true;
- return result.material;
- }
-
-
-
-
- Material CreateMaterial(int flags)
- {
- Material mat = new Material(_shader);
- mat.mainTexture = _texture.nativeTexture;
- if (_texture.alphaTexture != null)
- {
- mat.EnableKeyword("COMBINED");
- mat.SetTexture(ShaderConfig.ID_AlphaTex, _texture.alphaTexture);
- }
- for (int i = 0; i < internalKeywordsCount; i++)
- {
- if ((flags & (1 << i)) != 0)
- {
- string s = internalKeywords[i];
- if (s != null)
- mat.EnableKeyword(s);
- }
- }
- if (_addKeywords != null)
- {
- int keywordCnt = _addKeywords.Count;
- for (int i = 0; i < keywordCnt; i++)
- {
- if ((flags & (1 << (i + internalKeywordsCount))) != 0)
- mat.EnableKeyword(_addKeywords[i]);
- }
- }
- mat.hideFlags = DisplayObject.hideFlags;
- if (onCreateNewMaterial != null)
- onCreateNewMaterial(mat);
- return mat;
- }
-
-
-
- public void DestroyMaterials()
- {
- var iter = _materials.GetEnumerator();
- while (iter.MoveNext())
- {
- List<MaterialRef> items = iter.Current.Value;
- if (Application.isPlaying)
- {
- int cnt = items.Count;
- for (int j = 0; j < cnt; j++)
- Object.Destroy(items[j].material);
- }
- else
- {
- int cnt = items.Count;
- for (int j = 0; j < cnt; j++)
- Object.DestroyImmediate(items[j].material);
- }
- items.Clear();
- }
- iter.Dispose();
- }
-
-
-
- public void RefreshMaterials()
- {
- _combineTexture = _texture.alphaTexture != null;
- var iter = _materials.GetEnumerator();
- while (iter.MoveNext())
- {
- List<MaterialRef> items = iter.Current.Value;
- int cnt = items.Count;
- for (int j = 0; j < cnt; j++)
- {
- Material mat = items[j].material;
- mat.mainTexture = _texture.nativeTexture;
- if (_combineTexture)
- {
- mat.EnableKeyword("COMBINED");
- mat.SetTexture(ShaderConfig.ID_AlphaTex, _texture.alphaTexture);
- }
- }
- }
- iter.Dispose();
- }
- }
- }
|