rokojori_action_library/Runtime/Rendering/RenderingManager.cs

269 lines
5.9 KiB
C#

using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System;
using Godot;
using System.Linq;
using Rokojori.Extensions;
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(
()=>
{
UpdateShaders();
}
);
void UpdateShaders()
{
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<string>();
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<T>( 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 bool updateShadersOnReady = true;
[Export]
public RenderingManagerData data = new RenderingManagerData();
List<AssignedShaderProperty> _assignedProperties = new List<AssignedShaderProperty>();
public enum EditorUpdateMode
{
No_Update,
Update,
Update_Skipped,
Debug_Update
}
[Export]
public EditorUpdateMode editorUpdateMode = EditorUpdateMode.Update_Skipped;
[Export( PropertyHint.Range, "1,100")]
public int editorUpdateModeSkipping = 2;
int _editorUpdateSkipCounter = 0;
public override void _Ready()
{
if ( ensureGlobalShaderPropertiesOnReady )
{
EnsureGlobalShaderProperties();
}
if ( updateShadersOnReady )
{
UpdateShaders();
}
}
public override void _Process( double delta )
{
UpdateProperties();
}
void UpdateProperties()
{
if ( Engine.IsEditorHint() )
{
if ( EditorUpdateMode.No_Update == editorUpdateMode )
{
return;
}
if ( EditorUpdateMode.Update_Skipped == editorUpdateMode )
{
if ( _editorUpdateSkipCounter == 0 )
{
_editorUpdateSkipCounter = editorUpdateModeSkipping;
}
else
{
_editorUpdateSkipCounter --;
return;
}
}
}
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 )
{
this.LogInfo( "Recreating properties:", i, p, _assignedProperties[ i ] );
_assignedProperties.Clear();
CreatePropertyList();
UpdateProperties();
return;
}
var updated = _assignedProperties[ i ].Update( EditorUpdateMode.Debug_Update == editorUpdateMode );
if ( updated && EditorUpdateMode.Debug_Update == editorUpdateMode )
{
this.LogInfo( _assignedProperties[ i ].property.GetPropertyName().propertyName, " >> ", _assignedProperties[ i ].value );
}
}
}
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<RenderingManager>.Get();
if ( rm == null )
{
return stencilLayer.fallBackIndex;
}
var rmIndex = rm.data.stencilLayers.IndexOf( stencilLayer );
return rmIndex == -1 ? stencilLayer.fallBackIndex : ( rmIndex + 1 );
}
}
}