Implimented RGBA buttons

This commit is contained in:
Chromium 2025-04-29 06:53:17 +01:00
parent b1b129c8c1
commit 05600f7bc1
2 changed files with 145 additions and 39 deletions

View File

@ -1,27 +1,35 @@
using ImageProcessingGraph.Editor.Nodes.NodeAttributes; using ImageProcessingGraph.Editor.Nodes.NodeAttributes;
using UnityEngine; using UnityEngine;
using Unity.Collections;
using Unity.Jobs;
using Unity.Burst;
namespace ImageProcessingGraph.Editor.Nodes.Types.Image.Utilities.ViewNode namespace ImageProcessingGraph.Editor.Nodes.Types.Image.Utilities.ViewNode
{ {
[NodeInfo("View Texture", "Utility/View Texture", false, null ,typeof(ViewTextureNodeEditor))] [NodeInfo("View Texture", "Utility/View Texture", false, null ,typeof(ViewTextureNodeEditor))]
public class ViewTextureNode : BaseImageNode public partial class ViewTextureNode : BaseImageNode
{ {
[NodeAttributes.Input("Texture")] public Texture2D texture; [NodeAttributes.Input("Texture")] public Texture2D texture;
[NodeAttributes.Input("Image Data")] public ImageData imageData; [NodeAttributes.Input("Image Data")] public ImageData imageData;
public delegate void OnImageUpdated(); public delegate void OnImageUpdated();
public OnImageUpdated onImageUpdated; public OnImageUpdated onImageUpdated;
public Texture2D cachedRGB;
public Texture2D cachedR;
public Texture2D cachedG;
public Texture2D cachedB;
public Texture2D cachedA;
public override void Process() public override void Process()
{ {
if (texture == null) if (texture == null)
{ {
texture = imageData.ToTexture2D(); texture = imageData.ToTexture2D();
} }
//CHANGE NPOT SETTING GenerateChannelTextures(texture);
onImageUpdated?.Invoke(); onImageUpdated?.Invoke();
} }
@ -30,5 +38,98 @@ namespace ImageProcessingGraph.Editor.Nodes.Types.Image.Utilities.ViewNode
texture = null; texture = null;
imageData = default; imageData = default;
} }
private void GenerateChannelTextures(Texture2D source)
{
var pixels = source.GetPixels();
int length = pixels.Length;
NativeArray<Color> inputPixels = new NativeArray<Color>(pixels, Allocator.TempJob);
NativeArray<Color> outputR = new NativeArray<Color>(length, Allocator.TempJob);
NativeArray<Color> outputG = new NativeArray<Color>(length, Allocator.TempJob);
NativeArray<Color> outputB = new NativeArray<Color>(length, Allocator.TempJob);
NativeArray<Color> outputA = new NativeArray<Color>(length, Allocator.TempJob);
var jobR = new ChannelJob(ChannelType.R, inputPixels, outputR);
var jobG = new ChannelJob(ChannelType.G, inputPixels, outputG);
var jobB = new ChannelJob(ChannelType.B, inputPixels, outputB);
var jobA = new ChannelJob(ChannelType.A, inputPixels, outputA);
JobHandle handleR = jobR.Schedule(length, 64);
JobHandle handleG = jobG.Schedule(length, 64);
JobHandle handleB = jobB.Schedule(length, 64);
JobHandle handleA = jobA.Schedule(length, 64);
var handles = new NativeArray<JobHandle>(4, Allocator.Temp);
handles[0] = handleR;
handles[1] = handleG;
handles[2] = handleB;
handles[3] = handleA;
JobHandle.CompleteAll(handles);
handles.Dispose();
cachedRGB = source;
cachedR = CreateTexture(source.width, source.height, outputR);
cachedG = CreateTexture(source.width, source.height, outputG);
cachedB = CreateTexture(source.width, source.height, outputB);
cachedA = CreateTexture(source.width, source.height, outputA);
inputPixels.Dispose();
outputR.Dispose();
outputG.Dispose();
outputB.Dispose();
outputA.Dispose();
}
private Texture2D CreateTexture(int width, int height, NativeArray<Color> colors)
{
Texture2D tex = new Texture2D(width, height, TextureFormat.RGBA32, false);
tex.SetPixels(colors.ToArray());
tex.Apply();
return tex;
}
[BurstCompile]
private struct ChannelJob : IJobParallelFor
{
public ChannelType channelType;
[ReadOnly] public NativeArray<Color> input;
public NativeArray<Color> output;
public ChannelJob(ChannelType type, NativeArray<Color> input, NativeArray<Color> output)
{
this.channelType = type;
this.input = input;
this.output = output;
}
public void Execute(int index)
{
Color c = input[index];
switch (channelType)
{
case ChannelType.R:
output[index] = new Color(c.r, c.r, c.r, 1f);
break;
case ChannelType.G:
output[index] = new Color(c.g, c.g, c.g, 1f);
break;
case ChannelType.B:
output[index] = new Color(c.b, c.b, c.b, 1f);
break;
case ChannelType.A:
output[index] = new Color(c.a, c.a, c.a, 1f);
break;
}
}
}
private enum ChannelType
{
R, G, B, A
}
} }
} }

View File

@ -9,7 +9,7 @@ namespace ImageProcessingGraph.Editor.Nodes.Types.Image.Utilities.ViewNode
private UnityEngine.UIElements.Image viewableImage; private UnityEngine.UIElements.Image viewableImage;
private Foldout foldout; private Foldout foldout;
private VisualElement buttonRow; private VisualElement buttonRow;
public ViewTextureNodeEditor(BaseImageNode node, ImageProcessingGraphViewWindow window) : base(node, window) public ViewTextureNodeEditor(BaseImageNode node, ImageProcessingGraphViewWindow window) : base(node, window)
{ {
//Port 0 is Texture2D //Port 0 is Texture2D
@ -18,30 +18,18 @@ namespace ImageProcessingGraph.Editor.Nodes.Types.Image.Utilities.ViewNode
IPTPort tex2DPort = InputPorts[0] as IPTPort; IPTPort tex2DPort = InputPorts[0] as IPTPort;
IPTPort imageDataPort = InputPorts[1] as IPTPort; IPTPort imageDataPort = InputPorts[1] as IPTPort;
tex2DPort.OnPortConnected += () => tex2DPort.OnPortConnected += () => { imageDataPort.style.display = DisplayStyle.None; };
{
imageDataPort.style.display = DisplayStyle.None;
};
tex2DPort.OnPortDisconnected += () => tex2DPort.OnPortDisconnected += () => { imageDataPort.style.display = DisplayStyle.Flex; };
{
imageDataPort.style.display = DisplayStyle.Flex; imageDataPort.OnPortConnected += () => { tex2DPort.style.display = DisplayStyle.None; };
};
imageDataPort.OnPortDisconnected += () => { tex2DPort.style.display = DisplayStyle.Flex; };
imageDataPort.OnPortConnected += () =>
{
tex2DPort.style.display = DisplayStyle.None;
};
imageDataPort.OnPortDisconnected += () =>
{
tex2DPort.style.display = DisplayStyle.Flex;
};
this.Q("output").style.display = DisplayStyle.None; this.Q("output").style.display = DisplayStyle.None;
ViewTextureNode viewImageNode = node as ViewTextureNode; ViewTextureNode viewImageNode = node as ViewTextureNode;
foldout = new Foldout foldout = new Foldout
{ {
text = "Texture Viewer", text = "Texture Viewer",
@ -50,7 +38,7 @@ namespace ImageProcessingGraph.Editor.Nodes.Types.Image.Utilities.ViewNode
foldout.style.backgroundColor = new Color(63f / 255f, 63f / 255f, 63f / 255f, 205f / 255f); foldout.style.backgroundColor = new Color(63f / 255f, 63f / 255f, 63f / 255f, 205f / 255f);
foldout.contentContainer.style.justifyContent = Justify.Center; foldout.contentContainer.style.justifyContent = Justify.Center;
Add(foldout); Add(foldout);
viewableImage = new UnityEngine.UIElements.Image viewableImage = new UnityEngine.UIElements.Image
{ {
scaleMode = ScaleMode.ScaleToFit scaleMode = ScaleMode.ScaleToFit
@ -59,12 +47,9 @@ namespace ImageProcessingGraph.Editor.Nodes.Types.Image.Utilities.ViewNode
viewableImage.style.height = 256; viewableImage.style.height = 256;
viewableImage.style.backgroundColor = Color.black; viewableImage.style.backgroundColor = Color.black;
foldout.Add(viewableImage); foldout.Add(viewableImage);
viewImageNode.onImageUpdated += () => viewImageNode.onImageUpdated += () => { viewableImage.image = viewImageNode.texture; };
{
viewableImage.image = viewImageNode.texture;
};
buttonRow = new VisualElement buttonRow = new VisualElement
{ {
style = style =
@ -76,7 +61,7 @@ namespace ImageProcessingGraph.Editor.Nodes.Types.Image.Utilities.ViewNode
marginBottom = 8, marginBottom = 8,
} }
}; };
string[] channels = { "RGB", "R", "G", "B", "A" }; string[] channels = { "RGB", "R", "G", "B", "A" };
foreach (var channel in channels) foreach (var channel in channels)
{ {
@ -87,13 +72,33 @@ namespace ImageProcessingGraph.Editor.Nodes.Types.Image.Utilities.ViewNode
btn.style.flexGrow = 1; btn.style.flexGrow = 1;
buttonRow.Add(btn); buttonRow.Add(btn);
} }
foldout.Add(buttonRow); foldout.Add(buttonRow);
} }
private void OnChannelClicked(ViewTextureNode viewNode, string channel) private void OnChannelClicked(ViewTextureNode viewNode, string channel)
{ {
Debug.Log($"[ViewTextureNodeEditor] Channel Selected: {channel}"); switch (channel)
{
case "RGB":
viewableImage.image = viewNode.cachedRGB;
break;
case "R":
viewableImage.image = viewNode.cachedR;
break;
case "G":
viewableImage.image = viewNode.cachedG;
break;
case "B":
viewableImage.image = viewNode.cachedB;
break;
case "A":
viewableImage.image = viewNode.cachedA;
break;
default:
Debug.LogError("[ViewTextureNodeEditor] Unknown channel clicked! Did you hack reality again?");
break;
}
} }
} }
} }