Files
taptap2024_GJ_chidouren/Assets/3rd/UIEffect/Scripts/Common/ParameterTexture.cs

191 lines
6.0 KiB
C#
Raw Normal View History

2024-10-16 00:03:41 +08:00
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>
[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)
{
this._propertyName = propertyName;
this._channels = ((channels - 1) / 4 + 1) * 4;
this._instanceLimit = ((instanceLimit - 1) / 2 + 1) * 2;
this._data = new byte[this._channels * this._instanceLimit];
this._stack = new Stack<int>(this._instanceLimit);
for (int i = 1; i < this._instanceLimit + 1; i++)
{
this._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 < this._stack.Count)
{
target.parameterIndex = this._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);
this._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) * this._channels + channelId;
if (0 < target.parameterIndex && this._data[index] != value)
{
this._data[index] = value;
this._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 (this._propertyId == 0)
{
this._propertyId = Shader.PropertyToID(this._propertyName);
}
if (mat)
{
mat.SetTexture(this._propertyId, this._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) / this._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 (!this._texture)
{
bool isLinear = QualitySettings.activeColorSpace == ColorSpace.Linear;
this._texture = new Texture2D(this._channels / 4, this._instanceLimit, TextureFormat.RGBA32, false, isLinear);
this._texture.filterMode = FilterMode.Point;
this._texture.wrapMode = TextureWrapMode.Clamp;
updates.Add(UpdateParameterTexture);
this._needUpload = true;
}
}
void UpdateParameterTexture()
{
if (this._needUpload && this._texture)
{
this._needUpload = false;
this._texture.LoadRawTextureData(this._data);
this._texture.Apply(false, false);
}
}
}
}