rj-action-library/Runtime/Shading/Generators/ShaderGenerator.cs

125 lines
2.6 KiB
C#

using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.IO;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class ShaderGenerator:Node
{
[ExportToolButton( "Create" )]
public Callable CreateButton => Callable.From(
()=>
{
UpdateShader();
}
);
[Export]
public string path;
[Export]
public string shaderName;
[Export]
public Shader shader;
[Export]
public bool sendGodotUpdateMessage = false;
public virtual List<ShaderPhase> GetPhases()
{
return new List<ShaderPhase>();
}
public virtual List<ShaderGenerationModule> GetShaderGenerationModules( ShaderPhase phase )
{
return new List<ShaderGenerationModule>();
}
public virtual ShaderGenerationContext GenerateShaderVariants()
{
var context = new ShaderGenerationContext();
var phases = GetPhases();
this.LogInfo( context.variants );
phases.ForEach(
( phase )=>
{
context.phase = phase;
var modules = GetShaderGenerationModules( phase );
this.LogInfo( "PHASE", phase, ">>", context.variants, "MODS:", modules == null ? "-" : ( modules.Map( m => m.GetType().Name ) ));
if ( modules == null )
{
return;
}
modules.ForEach(
( m )=>
{
var code = m.GetCode( context );
this.LogInfo( phase, m.GetType().Name, code );
if ( code == null )
{
return;
}
context.Add( code );
}
);
}
);
return context;
}
public void UpdateShader()
{
var context = GenerateShaderVariants();
this.LogInfo( "Created variants:", context.variants );
var first = true;
foreach ( var variant in context.variants )
{
var shaderCode = variant.GetCode( context );
var absolutePath = path;
if ( absolutePath.StartsWith( "res://" ) || absolutePath.StartsWith( "user://" ) )
{
absolutePath = ProjectSettings.GlobalizePath( path );
}
this.LogInfo( shaderCode );
var filePath = FilePath.Join( absolutePath, shaderName + variant.variantName + ".gdshader" );
FilesSync.SaveUTF8( filePath, shaderCode );
if ( sendGodotUpdateMessage )
{
GodotEditorHelper.UpdateFile( filePath );
}
if ( first )
{
shader = ResourceLoader.Load<Shader>( filePath );
}
first =false;
}
}
}
}