using Godot; using System.Collections.Generic; namespace Rokojori { [Tool] [GlobalClass] public partial class RokojoriCompositorEffect:CompositorEffect { public static readonly string effectsPath = "res://addons/rokojori_action_library/Runtime/Rendering/Compositor/CompositorEffects"; public static string Path( string path ) { return effectsPath + "/" + path; } RDContext _context; public RDContext context => _context; protected virtual void OnConfigure(){} protected virtual void OnInitialize(){} protected virtual void ForAllViews(){} protected virtual void RenderView(){} public RokojoriCompositorEffect():base() { RenderingServer.CallOnRenderThread( Callable.From( _InitializeCompositorEffect ) ); } protected void _InitializeCompositorEffect() { OnConfigure(); _context = new RDContext(); _context.Initialize(); OnInitialize(); } bool _hasError = false; public override void _RenderCallback( int effectCallbackType, RenderData renderData ) { if ( _hasError || context.HasError() ) { this.LogInfo( context.messages ); return; } context.messages.Clear(); try { if ( context.renderingDevice == null ) { context.Error( "No render device" ); return; } var sceneBuffers = ( RenderSceneBuffersRD ) renderData.GetRenderSceneBuffers(); var sceneData = ( RenderSceneDataRD ) renderData.GetRenderSceneData(); if ( sceneBuffers == null && sceneData == null ) { context.Error( "sceneBuffers == null && sceneData == null" ); return; } var size = sceneBuffers.GetInternalSize(); if ( size.X == 0 || size.Y == 0 ) { context.Warning( "InternalSize.X == 0 || InternalSize.Y == 0" ); return; } _context.SetRenderData( renderData, sceneBuffers, sceneData ); _context.SetView( -1 ); ForAllViews(); int viewCount = ( int ) sceneBuffers.GetViewCount(); for ( int i = 0; i < viewCount; i++ ) { _context.SetView( i ); RenderView(); } } catch( System.Exception e ) { this.LogError( e ); _hasError = true; } if ( context.HasError() ) { _hasError = true; } } public override void _Notification( int what ) { var _shader = context.shader; context.Verbose( "Got notification: ", what ); if ( what != NotificationPredelete || ( _shader == null || !_shader.valid ) || context.renderingDevice == null ) { context.Verbose( "what != NotificationPredelete", what != NotificationPredelete, "( _shader == null || !_shader.valid )", ( _shader == null || !_shader.valid ), "rd == null", context.renderingDevice == null ); return; } context.Free( _shader, "Shader" ); context.CleanUp(); } } }