459 lines
9.6 KiB
C#
459 lines
9.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
[ExecuteInEditMode]
|
|
[AddComponentMenu("NGUI/Internal/Draw Call")]
|
|
public class UIDrawCall : MonoBehaviour
|
|
{
|
|
public enum Clipping
|
|
{
|
|
None = 0,
|
|
TextureMask = 1,
|
|
SoftClip = 3,
|
|
ConstrainButDontClip = 4
|
|
}
|
|
|
|
public delegate void OnRenderCallback(Material mat);
|
|
|
|
private static BetterList<UIDrawCall> mActiveList = new BetterList<UIDrawCall>();
|
|
|
|
private static BetterList<UIDrawCall> mInactiveList = new BetterList<UIDrawCall>();
|
|
|
|
[NonSerialized]
|
|
[HideInInspector]
|
|
public int widgetCount;
|
|
|
|
[NonSerialized]
|
|
[HideInInspector]
|
|
public UIPanel manager;
|
|
|
|
[NonSerialized]
|
|
[HideInInspector]
|
|
public UIPanel panel;
|
|
|
|
[NonSerialized]
|
|
[HideInInspector]
|
|
public bool alwaysOnScreen;
|
|
|
|
[NonSerialized]
|
|
[HideInInspector]
|
|
public BetterList<Vector3> verts = new BetterList<Vector3>();
|
|
|
|
[NonSerialized]
|
|
[HideInInspector]
|
|
public BetterList<Vector3> norms = new BetterList<Vector3>();
|
|
|
|
[NonSerialized]
|
|
[HideInInspector]
|
|
public BetterList<Vector4> tans = new BetterList<Vector4>();
|
|
|
|
[NonSerialized]
|
|
[HideInInspector]
|
|
public BetterList<Vector2> uvs = new BetterList<Vector2>();
|
|
|
|
[NonSerialized]
|
|
[HideInInspector]
|
|
public BetterList<Color32> cols = new BetterList<Color32>();
|
|
|
|
private Material mMaterial;
|
|
|
|
private Texture mTexture;
|
|
|
|
private Shader mShader;
|
|
|
|
private int mClipCount;
|
|
|
|
private Transform mTrans;
|
|
|
|
private Mesh mMesh;
|
|
|
|
private MeshFilter mFilter;
|
|
|
|
private MeshRenderer mRenderer;
|
|
|
|
private Material mDynamicMat;
|
|
|
|
private int[] mIndices;
|
|
|
|
private bool mRebuildMat = true;
|
|
|
|
private bool mLegacyShader;
|
|
|
|
private int mRenderQueue = 3000;
|
|
|
|
private int mTriangles;
|
|
|
|
[NonSerialized]
|
|
public bool isDirty;
|
|
|
|
[NonSerialized]
|
|
private bool mTextureClip;
|
|
|
|
public OnRenderCallback onRender;
|
|
|
|
private static List<int[]> mCache = new List<int[]>(10);
|
|
|
|
private static int[] ClipRange = null;
|
|
|
|
private static int[] ClipArgs = null;
|
|
|
|
public int renderQueue
|
|
{
|
|
get
|
|
{
|
|
return mRenderQueue;
|
|
}
|
|
set
|
|
{
|
|
if (mRenderQueue != value)
|
|
{
|
|
mRenderQueue = value;
|
|
if (mDynamicMat != null)
|
|
{
|
|
mDynamicMat.renderQueue = value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public int sortingOrder
|
|
{
|
|
get
|
|
{
|
|
if (!(mRenderer != null))
|
|
{
|
|
return 0;
|
|
}
|
|
return mRenderer.sortingOrder;
|
|
}
|
|
set
|
|
{
|
|
if (mRenderer != null && mRenderer.sortingOrder != value)
|
|
{
|
|
mRenderer.sortingOrder = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public Material baseMaterial
|
|
{
|
|
get
|
|
{
|
|
return mMaterial;
|
|
}
|
|
set
|
|
{
|
|
if (mMaterial != value)
|
|
{
|
|
mMaterial = value;
|
|
mRebuildMat = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public Texture mainTexture
|
|
{
|
|
get
|
|
{
|
|
return mTexture;
|
|
}
|
|
set
|
|
{
|
|
mTexture = value;
|
|
if (mDynamicMat != null)
|
|
{
|
|
mDynamicMat.mainTexture = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public Shader shader
|
|
{
|
|
get
|
|
{
|
|
return mShader;
|
|
}
|
|
set
|
|
{
|
|
if (mShader != value)
|
|
{
|
|
mShader = value;
|
|
mRebuildMat = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool isClipped => mClipCount != 0;
|
|
|
|
private void CreateMaterial()
|
|
{
|
|
mTextureClip = false;
|
|
mLegacyShader = false;
|
|
mClipCount = ((panel != null) ? panel.clipCount : 0);
|
|
string text = ((mShader != null) ? mShader.name : ((mMaterial != null) ? mMaterial.shader.name : "Unlit/Transparent Colored"));
|
|
text = text.Replace("GUI/Text Shader", "Unlit/Text");
|
|
if (text.Length > 2 && text[text.Length - 2] == ' ')
|
|
{
|
|
int num = text[text.Length - 1];
|
|
if (num > 48 && num <= 57)
|
|
{
|
|
text = text.Substring(0, text.Length - 2);
|
|
}
|
|
}
|
|
if (text.StartsWith("Hidden/"))
|
|
{
|
|
text = text.Substring(7);
|
|
}
|
|
text = text.Replace(" (SoftClip)", "");
|
|
text = text.Replace(" (TextureClip)", "");
|
|
if (panel != null && panel.clipping == Clipping.TextureMask)
|
|
{
|
|
mTextureClip = true;
|
|
shader = Shader.Find("Hidden/" + text + " (TextureClip)");
|
|
}
|
|
else if (mClipCount != 0)
|
|
{
|
|
shader = Shader.Find("Hidden/" + text + " " + mClipCount);
|
|
if (shader == null)
|
|
{
|
|
shader = Shader.Find(text + " " + mClipCount);
|
|
}
|
|
if (shader == null && mClipCount == 1)
|
|
{
|
|
mLegacyShader = true;
|
|
shader = Shader.Find(text + " (SoftClip)");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
shader = Shader.Find(text);
|
|
}
|
|
if (shader == null)
|
|
{
|
|
shader = Shader.Find("Unlit/Transparent Colored");
|
|
}
|
|
if (mMaterial != null)
|
|
{
|
|
if (IsWizardMaterial())
|
|
{
|
|
mDynamicMat = new Material(mMaterial);
|
|
mDynamicMat.EnableKeyword("USE_VERTEX_COLOR");
|
|
mDynamicMat.SetFloat("_SleeveSrcFactor", 5f);
|
|
mDynamicMat.SetFloat("_SleeveDstFactor", 10f);
|
|
mDynamicMat.SetFloat("_CullMode", 0f);
|
|
mDynamicMat.SetFloat("_ZWriteMode", 0f);
|
|
mLegacyShader = false;
|
|
if (isClipped)
|
|
{
|
|
mDynamicMat.EnableKeyword("USE_CLIP");
|
|
}
|
|
if (IsSleeveMaterial())
|
|
{
|
|
mDynamicMat.EnableKeyword("USE_SLEEVE");
|
|
}
|
|
mDynamicMat.shader = Shader.Find(mMaterial.shader.name);
|
|
}
|
|
else
|
|
{
|
|
mDynamicMat = new Material(mMaterial);
|
|
mDynamicMat.name = "[NGUI] " + mMaterial.name;
|
|
mDynamicMat.hideFlags = HideFlags.DontSave | HideFlags.NotEditable;
|
|
mDynamicMat.CopyPropertiesFromMaterial(mMaterial);
|
|
string[] shaderKeywords = mMaterial.shaderKeywords;
|
|
for (int i = 0; i < shaderKeywords.Length; i++)
|
|
{
|
|
mDynamicMat.EnableKeyword(shaderKeywords[i]);
|
|
}
|
|
if (shader != null)
|
|
{
|
|
mDynamicMat.shader = shader;
|
|
}
|
|
else if (mClipCount != 0)
|
|
{
|
|
Debug.LogError(text + " shader doesn't have a clipped shader version for " + mClipCount + " clip regions");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mDynamicMat = new Material(shader);
|
|
mDynamicMat.name = "[NGUI] " + shader.name;
|
|
mDynamicMat.hideFlags = HideFlags.DontSave | HideFlags.NotEditable;
|
|
}
|
|
}
|
|
|
|
private bool IsWizardMaterial()
|
|
{
|
|
if (mMaterial.shader.name == "Wizard/VariantSleeveShader")
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool IsSleeveMaterial()
|
|
{
|
|
if (mMaterial.name.Contains("sleeve"))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private Material RebuildMaterial()
|
|
{
|
|
NGUITools.DestroyImmediate(mDynamicMat);
|
|
CreateMaterial();
|
|
mDynamicMat.renderQueue = mRenderQueue;
|
|
if (mTexture != null)
|
|
{
|
|
mDynamicMat.mainTexture = mTexture;
|
|
}
|
|
if (mRenderer != null)
|
|
{
|
|
mRenderer.sharedMaterials = new Material[1] { mDynamicMat };
|
|
}
|
|
return mDynamicMat;
|
|
}
|
|
|
|
private void UpdateMaterials()
|
|
{
|
|
if (!(panel == null))
|
|
{
|
|
if (mRebuildMat || mDynamicMat == null || mClipCount != panel.clipCount || mTextureClip != (panel.clipping == Clipping.TextureMask))
|
|
{
|
|
RebuildMaterial();
|
|
mRebuildMat = false;
|
|
}
|
|
else if (mRenderer.sharedMaterial != mDynamicMat)
|
|
{
|
|
mRenderer.sharedMaterials = new Material[1] { mDynamicMat };
|
|
}
|
|
}
|
|
}
|
|
|
|
private int[] GenerateCachedIndexBuffer(int vertexCount, int indexCount)
|
|
{
|
|
int i = 0;
|
|
for (int count = mCache.Count; i < count; i++)
|
|
{
|
|
int[] array = mCache[i];
|
|
if (array != null && array.Length == indexCount)
|
|
{
|
|
return array;
|
|
}
|
|
}
|
|
int[] array2 = new int[indexCount];
|
|
int num = 0;
|
|
for (int j = 0; j < vertexCount; j += 4)
|
|
{
|
|
array2[num++] = j;
|
|
array2[num++] = j + 1;
|
|
array2[num++] = j + 2;
|
|
array2[num++] = j + 2;
|
|
array2[num++] = j + 3;
|
|
array2[num++] = j;
|
|
}
|
|
if (mCache.Count > 10)
|
|
{
|
|
mCache.RemoveAt(0);
|
|
}
|
|
mCache.Add(array2);
|
|
return array2;
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
if (ClipRange == null)
|
|
{
|
|
ClipRange = new int[4]
|
|
{
|
|
Shader.PropertyToID("_ClipRange0"),
|
|
Shader.PropertyToID("_ClipRange1"),
|
|
Shader.PropertyToID("_ClipRange2"),
|
|
Shader.PropertyToID("_ClipRange4")
|
|
};
|
|
}
|
|
if (ClipArgs == null)
|
|
{
|
|
ClipArgs = new int[4]
|
|
{
|
|
Shader.PropertyToID("_ClipArgs0"),
|
|
Shader.PropertyToID("_ClipArgs1"),
|
|
Shader.PropertyToID("_ClipArgs2"),
|
|
Shader.PropertyToID("_ClipArgs3")
|
|
};
|
|
}
|
|
}
|
|
|
|
private static UIDrawCall Create(string name, UIPanel pan, Material mat, Texture tex, Shader shader)
|
|
{
|
|
UIDrawCall uIDrawCall = Create(name);
|
|
uIDrawCall.gameObject.layer = pan.cachedGameObject.layer;
|
|
uIDrawCall.baseMaterial = mat;
|
|
uIDrawCall.mainTexture = tex;
|
|
uIDrawCall.shader = shader;
|
|
uIDrawCall.renderQueue = pan.startingRenderQueue;
|
|
uIDrawCall.sortingOrder = pan.sortingOrder;
|
|
uIDrawCall.manager = pan;
|
|
return uIDrawCall;
|
|
}
|
|
|
|
private static UIDrawCall Create(string name)
|
|
{
|
|
if (mInactiveList.size > 0)
|
|
{
|
|
UIDrawCall uIDrawCall = mInactiveList.Pop();
|
|
mActiveList.Add(uIDrawCall);
|
|
if (name != null)
|
|
{
|
|
uIDrawCall.name = name;
|
|
}
|
|
NGUITools.SetActive(uIDrawCall.gameObject, state: true);
|
|
return uIDrawCall;
|
|
}
|
|
GameObject obj = new GameObject(name);
|
|
UnityEngine.Object.DontDestroyOnLoad(obj);
|
|
UIDrawCall uIDrawCall2 = obj.AddComponent<UIDrawCall>();
|
|
mActiveList.Add(uIDrawCall2);
|
|
return uIDrawCall2;
|
|
}
|
|
|
|
public static void ClearAll()
|
|
{
|
|
bool isPlaying = Application.isPlaying;
|
|
int num = mActiveList.size;
|
|
while (num > 0)
|
|
{
|
|
UIDrawCall uIDrawCall = mActiveList[--num];
|
|
if ((bool)uIDrawCall)
|
|
{
|
|
if (isPlaying)
|
|
{
|
|
NGUITools.SetActive(uIDrawCall.gameObject, state: false);
|
|
}
|
|
else
|
|
{
|
|
NGUITools.DestroyImmediate(uIDrawCall.gameObject);
|
|
}
|
|
}
|
|
}
|
|
mActiveList.Clear();
|
|
}
|
|
|
|
public static void ReleaseInactive()
|
|
{
|
|
int num = mInactiveList.size;
|
|
while (num > 0)
|
|
{
|
|
UIDrawCall uIDrawCall = mInactiveList[--num];
|
|
if ((bool)uIDrawCall)
|
|
{
|
|
NGUITools.DestroyImmediate(uIDrawCall.gameObject);
|
|
}
|
|
}
|
|
mInactiveList.Clear();
|
|
}
|
|
}
|