184 lines
4.5 KiB
C#
184 lines
4.5 KiB
C#
![]() |
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|