using System.Diagnostics; using System.Collections; using System.Collections.Generic; using System; using Godot; using System.Linq; namespace Rokojori { [Tool] [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/RenderingManager.svg") ] public partial class RenderingManager:Node { [ExportToolButton( "Ensure Global Shader Properties")] public Callable ensureGlobalShaderPropertiesButton => Callable.From( ()=> { EnsureGlobalShaderProperties(); } ); [ExportToolButton( "Update Shaders")] public Callable updateShadersButton => Callable.From( ()=> { shaders.ForEach( ( s )=> { var code = RenderingServer.Singleton.ShaderGetCode( s.GetRid() ); code += "\n "; RenderingServer.Singleton.ShaderSetCode( s.GetRid(), code ); } ); } ); [Export] public Shader[] shaders; [ExportToolButton( "Get Material Code")] public Callable getMaterialCodeButton => Callable.From( ()=> { var shaderRID = material._GetShaderRid(); var code = RenderingServer.Singleton.ShaderGetCode( shaderRID ); this.LogInfo( "Shader:", code ); } ); [Export] public Material material; void EnsureGlobalShaderProperties() { var globalProperties = RenderingServer.GlobalShaderParameterGetList(); var map = new HashSet(); foreach ( var g in globalProperties ) { map.Add( g ); } for ( int i = 0; i < data.numGlobalShaderProperties; i++ ) { var p = data.GetGlobalShaderPropertyAt( i ); this.LogInfo( "Prop:", i ); if ( p == null || map.Contains( p.GetPropertyName().propertyName ) ) { continue; } this.LogInfo( i, ">>", p.GetPropertyName().propertyName ); p.AddAsGlobalUniform(); } } public T GetShaderPropertyByName( ShaderPropertyName name ) where T:ShaderProperty { if ( data == null ) { return null; } if ( data.globalShaderPropertyBlocks != null ) { foreach ( var b in data.globalShaderPropertyBlocks ) { var p = GetShaderPropertyByName( b.shaderProperties, name ); if ( p != null ) { return p as T; } } } return GetShaderPropertyByName( data.globalShaderProperties, name ) as T; } public ShaderProperty GetShaderPropertyByName( ShaderProperty[] properties, ShaderPropertyName name ) { if ( properties == null ) { return null; } return properties.Find( p => p.GetPropertyName().propertyName == name.propertyName ); } [Export] public bool ensureGlobalShaderPropertiesOnReady = true; [Export] public RenderingManagerData data = new RenderingManagerData(); List _assignedProperties = new List(); public override void _Ready() { if ( ! ensureGlobalShaderPropertiesOnReady ) { return; } EnsureGlobalShaderProperties(); } public override void _Process( double delta ) { UpdateProperties(); } void UpdateProperties() { if ( data == null ) { return; } if ( _assignedProperties.Count != data.numGlobalShaderProperties ) { CreatePropertyList(); } for ( int i = 0; i < data.numGlobalShaderProperties; i++ ) { var p = data.GetGlobalShaderPropertyAt( i ); if ( p != _assignedProperties[ i ].property ) { _assignedProperties.Clear(); CreatePropertyList(); UpdateProperties(); return; } _assignedProperties[ i ].Update(); } } void CreatePropertyList() { _assignedProperties.Clear(); for ( int i = 0; i < data.numGlobalShaderProperties; i++ ) { _assignedProperties.Add( AssignedShaderProperty.From( data.GetGlobalShaderPropertyAt( i ) ) ); } } public static int GetStencilReferenceIndex( StencilLayer stencilLayer ) { if ( stencilLayer == null ) { return -1; } var rm = Unique.Get(); if ( rm == null ) { return stencilLayer.fallBackIndex; } var rmIndex = rm.data.stencilLayers.IndexOf( stencilLayer ); return rmIndex == -1 ? stencilLayer.fallBackIndex : ( rmIndex + 1 ); } } }