WuhuIslandTesting/Library/PackageCache/com.unity.render-pipelines.universal@8148.0.7-4/Editor/ShaderGUI/UIClasses/TextureField.cs
2025-01-07 02:06:59 +01:00

365 lines
15 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using static UnityEngine.UI.InputField;
using Object = UnityEngine.Object;
using System;
using SLZ.SLZEditorTools;
using UnityEngine.Rendering;
namespace UnityEditor.SLZMaterialUI
{
public class TextureField : VisualElement, BaseMaterialField
{
public MaterialProperty textureProperty;
public VisualElement leftAlignBox { get; private set; }
public VisualElement rightAlignBox { get; private set; }
public string tooltip2 { get { return texObjField.tooltip; } set { texObjField.tooltip = value; } }
public Texture defaultTexture;
public UnityEditor.UIElements.ObjectField texObjField;
Texture currentValue;
Image thumbnail;
bool isNormalMap;
RenderTexture thumbnailRT;
UnityEngine.Rendering.TextureDimension textureType;
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
static Action<ObjectField> s_updateObjDelegate;
static Action<ObjectField> UpdateObjDelegate
{
get {
if (s_updateObjDelegate == null)
{
MethodInfo m = typeof(UnityEditor.UIElements.ObjectField).GetMethod("UpdateDisplay", BindingFlags.Instance | BindingFlags.NonPublic);
if (m == null)
{
Debug.LogError("Missing UpdateDisplay method");
}
s_updateObjDelegate = (Action<ObjectField>)m.CreateDelegate(typeof(Action<ObjectField>));
}
return s_updateObjDelegate;
}
}
public TextureField(MaterialProperty textureProperty, int texturePropertyIdx, bool isNormalMap, Texture defaultTexture = null)
{
this.textureProperty = textureProperty;
this.currentValue = textureProperty.textureValue;
this.shaderPropertyIdx = texturePropertyIdx;
this.isNormalMap = isNormalMap;
this.defaultTexture = defaultTexture;
RegisterCallback<DetachFromPanelEvent>(evt => Dispose());
leftAlignBox = new VisualElement();
leftAlignBox.AddToClassList("materialGUILeftBox");
rightAlignBox = new VisualElement();
rightAlignBox.AddToClassList("materialGUIRightBox");
style.flexDirection = FlexDirection.Row;
texObjField = new UnityEditor.UIElements.ObjectField();
//List<SearchProvider> providers = new List<SearchProvider>() { new SearchProvider("sfklahlkjhsa", "hello") };
//textureField.searchContext = new SearchContext(providers, "t:Texture2D", SearchFlags.Default);
//textureField.bindingPath = "m_SavedProperties.m_TexEnvs.Array.data[0].second.m_Texture";
textureType = textureProperty.textureDimension;
switch (textureProperty.textureDimension)
{
case (UnityEngine.Rendering.TextureDimension.Tex2D):
texObjField.objectType = typeof(Texture2D);
break;
case (UnityEngine.Rendering.TextureDimension.Tex3D):
texObjField.objectType = typeof(Texture3D);
break;
case (UnityEngine.Rendering.TextureDimension.Tex2DArray):
texObjField.objectType = typeof(Texture2DArray);
break;
case (UnityEngine.Rendering.TextureDimension.Cube):
texObjField.objectType = typeof(Cubemap);
break;
case (UnityEngine.Rendering.TextureDimension.CubeArray):
texObjField.objectType = typeof(CubemapArray);
break;
}
VisualElement background = texObjField.ElementAt(0);
background.style.backgroundColor = StyleKeyword.None;
background.style.borderBottomColor = StyleKeyword.None;
background.style.borderLeftColor = StyleKeyword.None;
background.style.borderRightColor = StyleKeyword.None;
background.style.borderTopColor = StyleKeyword.None;
background.style.borderBottomWidth = StyleKeyword.None;
background.style.borderLeftWidth = StyleKeyword.None;
background.style.borderRightWidth = StyleKeyword.None;
background.style.borderTopWidth = StyleKeyword.None;
background.style.borderTopLeftRadius = StyleKeyword.None;
background.style.borderTopRightRadius = StyleKeyword.None;
background.style.borderBottomLeftRadius = StyleKeyword.None;
background.style.borderBottomRightRadius = StyleKeyword.None;
background.style.justifyContent = Justify.FlexStart;
background.style.flexWrap = Wrap.NoWrap;
background.style.overflow = Overflow.Hidden;
VisualElement contents = background.ElementAt(0);
contents.style.flexShrink = 0;
contents.style.flexGrow = 1;
contents.style.overflow = Overflow.Hidden;
contents.style.flexBasis = StyleKeyword.Auto;
VisualElement oldlabel = contents.ElementAt(1);
oldlabel.style.display = DisplayStyle.None;
VisualElement searchButton = background.ElementAt(1);
searchButton.style.width = StyleKeyword.Auto;
searchButton.style.backgroundImage = StyleKeyword.None;
searchButton.style.flexDirection = FlexDirection.Row;
searchButton.style.overflow = Overflow.Hidden;
searchButton.style.flexBasis = StyleKeyword.Auto;
VisualElement fakeRadial = new VisualElement();
fakeRadial.AddToClassList("unity-object-field__selector");
fakeRadial.pickingMode = PickingMode.Ignore;
fakeRadial.style.backgroundColor = Color.clear;
Label label = new Label(textureProperty.displayName);
label.pickingMode = PickingMode.Ignore;
label.style.textOverflow = TextOverflow.Ellipsis;
searchButton.Add(fakeRadial);
searchButton.Add(label);
Image oldThumbnail = contents.ElementAt(0) as Image;
oldThumbnail.style.display = DisplayStyle.None;
thumbnail = new Image();
thumbnail.AddToClassList("textureFieldThumb");
thumbnail.AddToClassList("unity-object-field-display__icon");
thumbnail.pickingMode = PickingMode.Ignore;
thumbnail.scaleMode = ScaleMode.StretchToFill;
thumbnail.tintColor = Color.white;
thumbnailRT = new RenderTexture((int)(32.0f * EditorGUIUtility.pixelsPerPoint), (int)(32.0f * EditorGUIUtility.pixelsPerPoint), 1, RenderTextureFormat.ARGB32, 1);
thumbnailRT.depth = 0;
thumbnailRT.name = textureProperty.name + "_icon";
thumbnailRT.Create();
thumbnail.image = thumbnailRT;
contents.Insert(0, thumbnail);
texObjField.RegisterValueChangedCallback(OnObjectFieldChanged);
if (textureProperty.hasMixedValue)
{
currentValue = null;
texObjField.showMixedValue = true;
}
else
{
//if (textureProperty.textureValue == null && defaultTexture != null)
//{
// textureProperty.textureValue = defaultTexture;
// currentValue = defaultTexture;
//}
texObjField.showMixedValue = false;
}
texObjField.SetValueWithoutNotify(currentValue);
UpdateThumbnail();
leftAlignBox.Add(texObjField);
Add(leftAlignBox);
Add(rightAlignBox);
}
void OnObjectFieldChanged(ChangeEvent<Object> evt)
{
value = evt.newValue;
}
public void SetValueWithoutNotify(Object newValue)
{
if (newValue == null || newValue is Texture)
{
currentValue = (Texture) newValue;
if (currentValue == null && defaultTexture != null)
{
currentValue = defaultTexture;
}
UpdateThumbnail();
textureProperty.textureValue = currentValue;
texObjField.SetValueWithoutNotify(currentValue);
UpdateObjDelegate.Invoke(texObjField);
texObjField.showMixedValue = newValue == null;
}
else throw new System.ArgumentException($"Expected object of type {typeof(Texture2D)}");
}
public Object value
{
get => currentValue;
set
{
if (value == currentValue)
return;
Object previous = currentValue;
SetValueWithoutNotify(value);
}
}
void UpdateThumbnail()
{
BlitTextureIcon(thumbnailRT, currentValue, textureType);
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
bool valueChanged = currentValue != boundProp.textureValue;
textureProperty = boundProp;
if (valueChanged)
{
currentValue = boundProp.textureValue;
texObjField.SetValueWithoutNotify(currentValue);
UpdateThumbnail();
}
texObjField.showMixedValue = boundProp.hasMixedValue;
}
void Dispose()
{
if (thumbnailRT != null)
{
thumbnailRT.Clear();
}
}
static Material s_blitMaterial;
static LocalKeyword[] dimKeywords;
static LocalKeyword normalMapKeyword;
static int prop_Blit2D = Shader.PropertyToID("_Blit2D");
static int prop_Blit2DArray = Shader.PropertyToID("_Blit2DArray");
static int prop_BlitCube = Shader.PropertyToID("_BlitCube");
static int prop_BlitCubeArray = Shader.PropertyToID("_BlitCubeArray");
static int prop_Blit3D = Shader.PropertyToID("_Blit3D");
static int prop_BlitDim = Shader.PropertyToID("_BlitDim");
static void UpdateKeywords()
{
Shader blitShader = s_blitMaterial.shader;
dimKeywords[(int)TextureDimension.Tex2D - 2] = new LocalKeyword(blitShader, "DIM_2D");
dimKeywords[(int)TextureDimension.Tex2DArray - 2] = new LocalKeyword(blitShader, "DIM_2DARRAY");
dimKeywords[(int)TextureDimension.Cube - 2] = new LocalKeyword(blitShader, "DIM_CUBE");
dimKeywords[(int)TextureDimension.CubeArray - 2] = new LocalKeyword(blitShader, "DIM_CUBEARRAY");
dimKeywords[(int)TextureDimension.Tex3D - 2] = new LocalKeyword(blitShader, "DIM_3D");
normalMapKeyword = new LocalKeyword(blitShader, "NORMAL_MAP");
}
void BlitTextureIcon(RenderTexture icon, Texture tex, TextureDimension texType)
{
if (icon == null) return;
RenderTexture active = RenderTexture.active;
if (tex == null)
{
RenderTexture.active = icon;
GL.Clear(false, true, Color.clear, 0);
RenderTexture.active = active;
return;
}
if (s_blitMaterial == null || s_blitMaterial.shader == null || dimKeywords == null)
{
Shader blitShader = Shader.Find("Hidden/ShaderGUITextureIconBlit");
if (blitShader == null)
{
Debug.LogError("Could not find Blit_ShaderGUI.shader (Hidden/ShaderGUITextureIconBlit), cannot generate material thumbnails");
return;
}
s_blitMaterial = new Material(blitShader);
dimKeywords = new LocalKeyword[5];
}
UpdateKeywords();
int offsetDimEnum = (int)texType - 2;
for (int i = 0; i < 5; i++)
{
if (i == offsetDimEnum)
s_blitMaterial.EnableKeyword(dimKeywords[i]);
else
s_blitMaterial.DisableKeyword(dimKeywords[i]);
}
switch (texType)
{
case TextureDimension.Tex2D:
s_blitMaterial.SetTexture(prop_Blit2D, tex);
break;
case TextureDimension.Tex2DArray:
s_blitMaterial.SetTexture(prop_Blit2DArray, tex);
break;
case TextureDimension.Cube:
s_blitMaterial.SetTexture(prop_BlitCube, tex);
s_blitMaterial.SetVector(prop_BlitDim, new Vector4(tex.width, tex.height, 0, 0));
break;
case TextureDimension.CubeArray:
s_blitMaterial.SetTexture(prop_BlitCubeArray, tex);
s_blitMaterial.SetVector(prop_BlitDim, new Vector4(tex.width, tex.height, 0, 0));
break;
case TextureDimension.Tex3D:
s_blitMaterial.SetTexture(prop_Blit3D, tex);
s_blitMaterial.SetVector(prop_BlitDim, new Vector4(tex.width, tex.height, 0, 0));
break;
default:
Debug.LogError("Shader GUI Icon Blitter: Unknown texture dimension " + texType);
return;
}
if (isNormalMap)
{
s_blitMaterial.EnableKeyword(normalMapKeyword);
}
Graphics.Blit(tex, icon, s_blitMaterial);
RenderTexture.active = active;
if (isNormalMap)
{
s_blitMaterial.DisableKeyword(normalMapKeyword);
}
switch (texType)
{
case TextureDimension.Tex2D:
s_blitMaterial.SetTexture(prop_Blit2D, null);
break;
case TextureDimension.Tex2DArray:
s_blitMaterial.SetTexture(prop_Blit2DArray, null);
break;
case TextureDimension.Cube:
s_blitMaterial.SetTexture(prop_BlitCube, null);
break;
case TextureDimension.CubeArray:
s_blitMaterial.SetTexture(prop_BlitCubeArray, null);
break;
case TextureDimension.Tex3D:
s_blitMaterial.SetTexture(prop_Blit3D, null);
break;
}
}
}
}