332 lines
8.3 KiB
C#
332 lines
8.3 KiB
C#
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace AllIn13DShader
|
|
{
|
|
public class GradientEditorDrawer
|
|
{
|
|
private const float OFFSET = 5f;
|
|
|
|
private Gradient gradient;
|
|
private Rect lastRect;
|
|
private Texture2D previewTex;
|
|
private GradientCreatorTool gradientCreatorTool;
|
|
|
|
private bool createGradientToggle;
|
|
private bool textureSaved;
|
|
private bool usingPreviewTex;
|
|
private bool isModifyingExistingTexture;
|
|
|
|
private Texture lastSavedTexture;
|
|
private Gradient lastGradient;
|
|
|
|
private GradientTexture gradientTextureAsset;
|
|
|
|
private void RefreshReferences(Texture lastTexture)
|
|
{
|
|
if (gradient == null)
|
|
{
|
|
gradient = new Gradient();
|
|
}
|
|
|
|
if (previewTex == null)
|
|
{
|
|
previewTex = new Texture2D(128, 128);
|
|
}
|
|
|
|
if (gradientCreatorTool == null)
|
|
{
|
|
gradientCreatorTool = new GradientCreatorTool();
|
|
}
|
|
|
|
if (lastSavedTexture == null)
|
|
{
|
|
lastSavedTexture = lastTexture;
|
|
}
|
|
|
|
if (lastGradient == null)
|
|
{
|
|
lastGradient = new Gradient();
|
|
}
|
|
}
|
|
|
|
private Texture RefreshGradientState(Texture texValue)
|
|
{
|
|
Texture res = texValue;
|
|
|
|
if (createGradientToggle)
|
|
{
|
|
lastSavedTexture = texValue;
|
|
|
|
isModifyingExistingTexture = EditorUtils.IsProjectAsset(lastSavedTexture);
|
|
|
|
this.gradientTextureAsset = GradientCreatorTool.FindGradientTexureByTex(texValue);
|
|
if (this.gradientTextureAsset != null)
|
|
{
|
|
GradientCreatorTool.CopyGradient(gradientTextureAsset.gradient, gradient);
|
|
}
|
|
else
|
|
{
|
|
if (texValue != null)
|
|
{
|
|
gradient = CreateGradientFromTexture(texValue);
|
|
}
|
|
else
|
|
{
|
|
gradient = new Gradient();
|
|
}
|
|
}
|
|
|
|
previewTex = gradientCreatorTool.CreateGradientTexture(gradient);
|
|
res = previewTex;
|
|
}
|
|
else
|
|
{
|
|
GradientCreatorTool.CopyGradient(gradient, lastGradient);
|
|
previewTex = null;
|
|
res = lastSavedTexture;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
private Gradient CreateGradientFromTexture(Texture texSource)
|
|
{
|
|
int width = texSource.width;
|
|
int height = texSource.height;
|
|
|
|
RenderTexture renderTex = RenderTexture.GetTemporary(
|
|
width,
|
|
height,
|
|
0,
|
|
RenderTextureFormat.Default,
|
|
RenderTextureReadWrite.Linear);
|
|
|
|
Graphics.Blit(texSource, renderTex);
|
|
RenderTexture previous = RenderTexture.active;
|
|
RenderTexture.active = renderTex;
|
|
Texture2D readableText = new Texture2D(texSource.width, texSource.height);
|
|
readableText.filterMode = texSource.filterMode;
|
|
readableText.wrapMode = texSource.wrapMode;
|
|
readableText.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
|
|
readableText.Apply();
|
|
RenderTexture.active = previous;
|
|
RenderTexture.ReleaseTemporary(renderTex);
|
|
|
|
|
|
Gradient res = new Gradient();
|
|
List<GradientColorKey> gradientColorKeys = new List<GradientColorKey>();
|
|
|
|
int numSamples = 5;
|
|
float step = (((float)width) / numSamples) / width;
|
|
|
|
Vector2 sampleUV = Vector2.zero;
|
|
sampleUV.y = renderTex.height * 0.5f;
|
|
for (int i = 0; i < numSamples; i++)
|
|
{
|
|
Color col = readableText.GetPixelBilinear(sampleUV.x, sampleUV.y);
|
|
gradientColorKeys.Add(new GradientColorKey(col, sampleUV.x));
|
|
|
|
sampleUV.x += step;
|
|
}
|
|
|
|
Color lastCol = readableText.GetPixelBilinear(sampleUV.x, sampleUV.y);
|
|
gradientColorKeys.Add(new GradientColorKey(lastCol, sampleUV.x));
|
|
|
|
res.colorKeys = gradientColorKeys.ToArray();
|
|
res.mode = GradientMode.Blend;
|
|
|
|
return res;
|
|
}
|
|
|
|
public Texture Draw(Rect position, Texture gradientTexture)
|
|
{
|
|
RefreshReferences(gradientTexture);
|
|
|
|
lastRect = position;
|
|
|
|
Texture texValue = gradientTexture;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
if (createGradientToggle && texValue == null)
|
|
{
|
|
texValue = lastSavedTexture;
|
|
createGradientToggle = false;
|
|
}
|
|
|
|
texValue = DrawTextureField(texValue, 60f, "Color ramp texture");
|
|
bool changes = EditorGUI.EndChangeCheck();
|
|
if (changes)
|
|
{
|
|
createGradientToggle = false;
|
|
lastSavedTexture = texValue;
|
|
}
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
DrawCreateGradientToggle(15f, "Create Gradient");
|
|
bool createGradientToggleChanged = EditorGUI.EndChangeCheck();
|
|
if (createGradientToggleChanged)
|
|
{
|
|
texValue = RefreshGradientState(texValue);
|
|
}
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
if (createGradientToggle)
|
|
{
|
|
texValue = DrawGradientField(40f, "Gradient", texValue);
|
|
}
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
bool gradientFieldChanged = EditorGUI.EndChangeCheck();
|
|
if (gradientFieldChanged && !textureSaved)
|
|
{
|
|
previewTex = gradientCreatorTool.CreateGradientTexture(TextureSizes._256, FilterMode.Bilinear, gradient);
|
|
texValue = previewTex;
|
|
|
|
usingPreviewTex = true;
|
|
}
|
|
|
|
textureSaved = false;
|
|
|
|
return texValue;
|
|
}
|
|
|
|
private Texture DrawTextureField(Texture tex, float height, string label)
|
|
{
|
|
Rect rect = new Rect(lastRect);
|
|
rect.height = height;
|
|
|
|
GUIStyle labelStyle = EditorStyles.label;
|
|
labelStyle.alignment = TextAnchor.UpperLeft;
|
|
|
|
Rect labelRect = new Rect(rect);
|
|
labelRect.width = 200f;
|
|
EditorGUI.LabelField(labelRect, new GUIContent(label), labelStyle);
|
|
|
|
GUIStyle textureStyle = EditorStyles.objectField;
|
|
textureStyle.alignment = TextAnchor.MiddleLeft;
|
|
|
|
Rect textureRect = new Rect(rect);
|
|
textureRect.width = height;
|
|
textureRect.height = height;
|
|
textureRect.x = rect.width - textureRect.width - 10f;
|
|
|
|
Texture res = (Texture)EditorGUI.ObjectField(textureRect, tex, typeof(Texture), false);
|
|
lastRect.y += height;
|
|
|
|
return res;
|
|
}
|
|
|
|
private Texture DrawGradientField(float height, string label, Texture texValue)
|
|
{
|
|
Texture res = texValue;
|
|
|
|
Rect rect = new Rect(lastRect);
|
|
rect.height = height;
|
|
rect.y += height * 0.5f;
|
|
|
|
float createButtonWidth = 100f;
|
|
|
|
GUIStyle labelStyle = EditorStyles.label;
|
|
labelStyle.alignment = TextAnchor.UpperLeft;
|
|
Rect labelRect = new Rect(rect);
|
|
labelRect.width = 200f;
|
|
EditorGUI.LabelField(labelRect, new GUIContent(label), labelStyle);
|
|
|
|
GUIStyle textureStyle = EditorStyles.objectField;
|
|
textureStyle.alignment = TextAnchor.MiddleLeft;
|
|
|
|
Rect gradientAndButtonRect = new Rect(rect);
|
|
gradientAndButtonRect.width = rect.width - labelRect.width;
|
|
gradientAndButtonRect.height = rect.height;
|
|
gradientAndButtonRect.x = labelRect.x + labelRect.width;
|
|
|
|
Rect gradientRect = new Rect(gradientAndButtonRect);
|
|
gradientRect.width = gradientAndButtonRect.width * 0.5f;
|
|
gradientRect.height = rect.height * 0.5f;
|
|
gradientRect.x = rect.x + rect.width - gradientRect.width - (createButtonWidth * 2f) - 10f;
|
|
gradient = EditorGUI.GradientField(gradientRect, gradient);
|
|
|
|
Rect createButtonRect = new Rect(gradientAndButtonRect);
|
|
createButtonRect.width = createButtonWidth;
|
|
createButtonRect.height = gradientRect.height;
|
|
createButtonRect.x = gradientRect.x + gradientRect.width + 10f;
|
|
|
|
Rect modifyButtonRect = new Rect(createButtonRect);
|
|
modifyButtonRect.x = createButtonRect.x + createButtonRect.width + 10f;
|
|
|
|
if (GUI.Button(createButtonRect, "Save Texture"))
|
|
{
|
|
res = ChangeTextureOnDisk(true);
|
|
}
|
|
|
|
EditorGUI.BeginDisabledGroup(!isModifyingExistingTexture || gradientTextureAsset == null);
|
|
if (GUI.Button(modifyButtonRect, "Overwrite"))
|
|
{
|
|
res = ChangeTextureOnDisk(false);
|
|
}
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
lastRect.y += height + OFFSET;
|
|
|
|
if (usingPreviewTex && !textureSaved)
|
|
{
|
|
Rect helpBoxRect = new Rect(lastRect);
|
|
helpBoxRect.height = 40f;
|
|
EditorGUI.HelpBox(helpBoxRect, "Texture is not saved! Click on Save Texture to save it", MessageType.Warning);
|
|
|
|
lastRect.y += helpBoxRect.height + OFFSET;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
private Texture ChangeTextureOnDisk(bool createNew)
|
|
{
|
|
gradientCreatorTool.CreateGradientTexture(gradient);
|
|
Texture savedTex = gradientCreatorTool.SaveGradientTexture(gradientTextureAsset, createNew);
|
|
|
|
Texture res = savedTex;
|
|
lastSavedTexture = savedTex;
|
|
|
|
textureSaved = true;
|
|
usingPreviewTex = false;
|
|
createGradientToggle = false;
|
|
|
|
gradientTextureAsset = null;
|
|
|
|
return res;
|
|
}
|
|
|
|
private void DrawCreateGradientToggle(float height, string label)
|
|
{
|
|
Rect rect = new Rect(lastRect);
|
|
rect.height = height;
|
|
|
|
Rect toggleRect = new Rect(rect);
|
|
|
|
createGradientToggle = EditorGUI.ToggleLeft(toggleRect, label, createGradientToggle);
|
|
|
|
lastRect.y += height;
|
|
}
|
|
|
|
public float GetPropertyHeight()
|
|
{
|
|
float res = 80f;
|
|
|
|
if (createGradientToggle)
|
|
{
|
|
res += 45f;
|
|
if (usingPreviewTex)
|
|
{
|
|
res += 40f;
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
}
|
|
} |