rj-action-library/Runtime/Shading/Generators/Generic/ShaderCode.cs

184 lines
4.5 KiB
C#
Raw Normal View History

2025-09-17 08:25:03 +00:00
using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
public class ShaderCode
{
public string variantName = "";
public ShaderPhase phase;
public bool sortableCode = false;
public List<ShaderCodeVariableOccurance> variableOccurances = new List<ShaderCodeVariableOccurance>();
protected virtual string _GetCode( ShaderGenerationContext context )
{
return "";
}
public string GetCode( ShaderGenerationContext context )
{
return _GetCode( context );
}
public void ResolveVariableOccurances( ShaderGenerationContext context )
{
var code = GetCode( context );
var lexed = GDShaderLexer.Lex( code );
var index = lexed.CreateIndex();
var relevantVariables = ShaderCodeVariable.DefaultVariables.Map( v => v.variableName ).CreateSet();
var foundVariables = lexed.Filter( le => le.Is( LexerMatcherLibrary.CwordMatcher ) && relevantVariables.Contains( le.match ) );
var mapped = new Dictionary<ShaderCodeVariableOccurance,LexerEvent>();
foundVariables.ForEach(
( w )=>
{
var nextTokenResult = LexerEvent.Find( lexed, index[ w ],
( le ) =>
{
if ( le.Is( LexerMatcherLibrary.OperatorMatcher ) )
{
return LexerEvent.FindResultType.Found;
}
if ( le.IsAnyOf( LexerMatcherLibrary.Ignore ) )
{
return LexerEvent.FindResultType.KeepSearching;
}
return LexerEvent.FindResultType.NotFound;
}
);
if ( LexerEvent.FindResultType.NotFound == nextTokenResult.type )
{
variableOccurances.Add( ShaderCodeVariableOccurance.Read( w.match ) );
}
else
{
var token = lexed[ nextTokenResult.index ];
if ( token.match == "=" )
{
variableOccurances.Add( ShaderCodeVariableOccurance.Assignment( w.match ) );
}
else if ( token.MatchIsAny( "++", "--", "+=", "-=", "*=", "/=" ) )
{
variableOccurances.Add( ShaderCodeVariableOccurance.Modification( w.match ) );
}
else
{
variableOccurances.Add( ShaderCodeVariableOccurance.Read( w.match ) );
}
}
mapped[ variableOccurances.Last() ] = w;
}
);
variableOccurances.ForEach(
( vo )=>
{
var lineInfo = mapped[ vo ].GetLineInfo( code );
RJLog.Log( vo.type, ":", vo.variable.variableName, " >> ", lineInfo );
}
);
}
}
public class StringShaderCode:ShaderCode
{
public string code = "";
public StringShaderCode( string code )
{
this.code = code;
}
protected override string _GetCode( ShaderGenerationContext context )
{
return code;
}
public static StringShaderCode FromLines( List<string> code, bool addBreaks = true )
{
return new StringShaderCode( code.Join( addBreaks ? "\n" : "" ) );
}
}
public class BuiltInTextureShaderCode:ShaderCode
{
public enum TextureType
{
Screen,
Depth,
NormalRoughness
}
public TextureType textureType => _textureType;
TextureType _textureType;
public static BuiltInTextureShaderCode Screen
{
get
{
var sc = new BuiltInTextureShaderCode();
sc._textureType = TextureType.Screen;
return sc;
}
}
public static BuiltInTextureShaderCode Depth
{
get
{
var sc = new BuiltInTextureShaderCode();
sc._textureType = TextureType.Depth;
return sc;
}
}
public static BuiltInTextureShaderCode NormalRoughness
{
get
{
var sc = new BuiltInTextureShaderCode();
sc._textureType = TextureType.NormalRoughness;
return sc;
}
}
public ShaderCode GetBuiltInCode()
{
if ( _textureType == TextureType.Screen )
{
return new StringShaderCode( ShaderGenerationModule.ScreenTextureUniform().LineBreak() );
}
if ( _textureType == TextureType.Depth )
{
return new StringShaderCode( ShaderGenerationModule.DepthTextureUniform().LineBreak() );
}
if ( _textureType == TextureType.NormalRoughness )
{
return new StringShaderCode( ShaderGenerationModule.NormalRoughnessTextureUniform().LineBreak() );
}
return null;
}
}
}