diff options
author | chai <chaifix@163.com> | 2021-04-07 21:33:14 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-04-07 21:33:14 +0800 |
commit | c47b92e92cf33ae8bf2f38929e137294397e4735 (patch) | |
tree | c67ae3419eaf15e84f1679186e107f598de33978 /Assets/Scripts/Common/ParameterTexture.cs |
Diffstat (limited to 'Assets/Scripts/Common/ParameterTexture.cs')
-rw-r--r-- | Assets/Scripts/Common/ParameterTexture.cs | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/Assets/Scripts/Common/ParameterTexture.cs b/Assets/Scripts/Common/ParameterTexture.cs new file mode 100644 index 0000000..3249828 --- /dev/null +++ b/Assets/Scripts/Common/ParameterTexture.cs @@ -0,0 +1,190 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Rendering; +using System; + +namespace Coffee.UIEffects +{ + public interface IParameterTexture + { + int parameterIndex { get; set; } + + ParameterTexture paramTex { get; } + } + + /// <summary> + /// Parameter texture. + /// </summary> + [System.Serializable] + public class ParameterTexture + { + //################################ + // Public Members. + //################################ + + /// <summary> + /// Initializes a new instance of the <see cref="Coffee.UIEffects.ParameterTexture"/> class. + /// </summary> + /// <param name="channels">Channels.</param> + /// <param name="instanceLimit">Instance limit.</param> + /// <param name="propertyName">Property name.</param> + public ParameterTexture(int channels, int instanceLimit, string propertyName) + { + _propertyName = propertyName; + _channels = ((channels - 1) / 4 + 1) * 4; + _instanceLimit = ((instanceLimit - 1) / 2 + 1) * 2; + _data = new byte[_channels * _instanceLimit]; + + _stack = new Stack<int>(_instanceLimit); + for (int i = 1; i < _instanceLimit + 1; i++) + { + _stack.Push(i); + } + } + + + /// <summary> + /// Register the specified target. + /// </summary> + /// <param name="target">Target.</param> + public void Register(IParameterTexture target) + { + Initialize(); + if (target.parameterIndex <= 0 && 0 < _stack.Count) + { + target.parameterIndex = _stack.Pop(); +// Debug.LogFormat("<color=green>@@@ Register {0} : {1}</color>", target, target.parameterIndex); + } + } + + /// <summary> + /// Unregister the specified target. + /// </summary> + /// <param name="target">Target.</param> + public void Unregister(IParameterTexture target) + { + if (0 < target.parameterIndex) + { +// Debug.LogFormat("<color=red>@@@ Unregister {0} : {1}</color>", target, target.parameterIndex); + _stack.Push(target.parameterIndex); + target.parameterIndex = 0; + } + } + + /// <summary> + /// Sets the data. + /// </summary> + /// <param name="target">Target.</param> + /// <param name="channelId">Channel identifier.</param> + /// <param name="value">Value.</param> + public void SetData(IParameterTexture target, int channelId, byte value) + { + int index = (target.parameterIndex - 1) * _channels + channelId; + if (0 < target.parameterIndex && _data[index] != value) + { + _data[index] = value; + _needUpload = true; + } + } + + /// <summary> + /// Sets the data. + /// </summary> + /// <param name="target">Target.</param> + /// <param name="channelId">Channel identifier.</param> + /// <param name="value">Value.</param> + public void SetData(IParameterTexture target, int channelId, float value) + { + SetData(target, channelId, (byte) (Mathf.Clamp01(value) * 255)); + } + + /// <summary> + /// Registers the material. + /// </summary> + /// <param name="mat">Mat.</param> + public void RegisterMaterial(Material mat) + { + if (_propertyId == 0) + { + _propertyId = Shader.PropertyToID(_propertyName); + } + + if (mat) + { + mat.SetTexture(_propertyId, _texture); + } + } + + /// <summary> + /// Gets the index of the normalized. + /// </summary> + /// <returns>The normalized index.</returns> + /// <param name="target">Target.</param> + public float GetNormalizedIndex(IParameterTexture target) + { + return ((float) target.parameterIndex - 0.5f) / _instanceLimit; + } + + + //################################ + // Private Members. + //################################ + + Texture2D _texture; + bool _needUpload; + int _propertyId; + readonly string _propertyName; + readonly int _channels; + readonly int _instanceLimit; + readonly byte[] _data; + readonly Stack<int> _stack; + static List<Action> updates; + + /// <summary> + /// Initialize this instance. + /// </summary> + void Initialize() + { +#if UNITY_EDITOR + if (!UnityEditor.EditorApplication.isPlaying && UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode) + { + return; + } +#endif + if (updates == null) + { + updates = new List<Action>(); + Canvas.willRenderCanvases += () => + { + var count = updates.Count; + for (int i = 0; i < count; i++) + { + updates[i].Invoke(); + } + }; + } + + if (!_texture) + { + bool isLinear = QualitySettings.activeColorSpace == ColorSpace.Linear; + _texture = new Texture2D(_channels / 4, _instanceLimit, TextureFormat.RGBA32, false, isLinear); + _texture.filterMode = FilterMode.Point; + _texture.wrapMode = TextureWrapMode.Clamp; + + updates.Add(UpdateParameterTexture); + _needUpload = true; + } + } + + void UpdateParameterTexture() + { + if (_needUpload && _texture) + { + _needUpload = false; + _texture.LoadRawTextureData(_data); + _texture.Apply(false, false); + } + } + } +} |