284 lines
6.7 KiB
C#
284 lines
6.7 KiB
C#
|
|
using Godot;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Rokojori
|
|
{
|
|
[Tool]
|
|
[GlobalClass]
|
|
public partial class RokojoriCompositorEffect:CompositorEffect
|
|
{
|
|
protected RenderingDevice _rd;
|
|
public RenderingDevice rd => _rd;
|
|
|
|
|
|
protected List<RenderingObject> _cleanUps = new List<RenderingObject>();
|
|
protected List<string> _cleanUpInfo = new List<string>();
|
|
|
|
EditableRokojoriCompositorContext _context;
|
|
protected bool _hasContext = false;
|
|
public RokojoriCompositorContext context => _hasContext ? _context : null;
|
|
|
|
protected List<Message> _messages = new List<Message>();
|
|
public List<Message> messages => _messages;
|
|
public bool logMessages = true;
|
|
public int messageLogLevel = Messages.GetLevel( MessageType.Verbose );
|
|
|
|
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();
|
|
|
|
_rd = RenderingServer.Singleton.GetRenderingDevice();
|
|
|
|
if ( _rd == null )
|
|
{
|
|
Error( "Found no rendering device" );
|
|
return;
|
|
}
|
|
|
|
_context = new EditableRokojoriCompositorContext();
|
|
_context.SetEffect( this );
|
|
|
|
_hasContext = true;
|
|
OnInitialize();
|
|
_hasContext = false;
|
|
|
|
}
|
|
|
|
public override void _RenderCallback( int effectCallbackType, RenderData renderData )
|
|
{
|
|
|
|
_hasContext = false;
|
|
|
|
if ( rd == null )
|
|
{
|
|
Error( "No render device" );
|
|
return;
|
|
}
|
|
|
|
var sceneBuffers = ( RenderSceneBuffersRD ) renderData.GetRenderSceneBuffers();
|
|
var sceneData = ( RenderSceneDataRD ) renderData.GetRenderSceneData();
|
|
|
|
if ( sceneBuffers == null && sceneData == null )
|
|
{
|
|
Error( "sceneBuffers == null && sceneData == null" );
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
var size = sceneBuffers.GetInternalSize();
|
|
|
|
if ( size.X == 0 || size.Y == 0 )
|
|
{
|
|
Warning( "InternalSize.X == 0 || InternalSize.Y == 0" );
|
|
return;
|
|
}
|
|
|
|
_context.SetRenderData( renderData, sceneBuffers, sceneData );
|
|
_context.SetView( -1 );
|
|
|
|
_context.SetGroups( new Vector3I( 1, 1, 1 ) );
|
|
|
|
|
|
|
|
_hasContext = true;
|
|
// var groups = ComputeGroups();
|
|
// _context.SetGroups( groups );
|
|
|
|
ForAllViews();
|
|
|
|
|
|
|
|
int viewCount = ( int ) sceneBuffers.GetViewCount();
|
|
|
|
for ( int i = 0; i < viewCount; i++ )
|
|
{
|
|
_context.SetView( i );
|
|
RenderView();
|
|
}
|
|
|
|
_hasContext = false;
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void _Notification( int what )
|
|
{
|
|
var _shader = context.shader;
|
|
|
|
Verbose( "Got notification: ", what );
|
|
|
|
if ( what != NotificationPredelete || ( _shader == null || !_shader.valid ) || rd == null )
|
|
{
|
|
Verbose(
|
|
"what != NotificationPredelete", what != NotificationPredelete,
|
|
"( _shader == null || !_shader.valid )", ( _shader == null || !_shader.valid ),
|
|
"rd == null", rd == null
|
|
);
|
|
return;
|
|
}
|
|
|
|
CleanUp( _shader, "Shader" );
|
|
|
|
var index = 0;
|
|
|
|
_cleanUps.ForEach(
|
|
c =>
|
|
{
|
|
CleanUp( c, "_cleanUps[" + index + "]");
|
|
index ++;
|
|
}
|
|
);
|
|
|
|
_cleanUps.Clear();
|
|
|
|
}
|
|
|
|
public void AddToCleanUp( RenderingObject ro, string info = null )
|
|
{
|
|
var _shader = context.shader;
|
|
|
|
if ( _cleanUps.Contains( ro ) || _shader == ro )
|
|
{
|
|
return;
|
|
}
|
|
|
|
_cleanUps.Add( ro );
|
|
_cleanUpInfo.Add( info );
|
|
}
|
|
|
|
public void AddToCleanUp( List<RenderingObject> ro, string info = null )
|
|
{
|
|
var index = 0;
|
|
info = info == null ? "" : info;
|
|
|
|
ro.ForEach(
|
|
r =>
|
|
{
|
|
AddToCleanUp( r, info + "["+ index + "]" );
|
|
index ++;
|
|
}
|
|
);
|
|
}
|
|
|
|
void CleanUp( RenderingObject ro, string info )
|
|
{
|
|
if ( ro == null )
|
|
{
|
|
Warning( "ro == null, couldn't clean up: ", info );
|
|
return;
|
|
}
|
|
|
|
Verbose( "Cleaning up: ", info, ro.rid );
|
|
rd.FreeRid( ro.rid );
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------
|
|
// ---------------------------------------------
|
|
// CONVINIENCE
|
|
// ---------------------------------------------
|
|
// ---------------------------------------------
|
|
|
|
public RDSampler Sampler( RDSamplerState state = null)
|
|
{
|
|
if ( state == null )
|
|
{
|
|
state = new RDSamplerState();
|
|
state.MinFilter = RenderingDevice.SamplerFilter.Linear;
|
|
state.MagFilter = RenderingDevice.SamplerFilter.Linear;
|
|
state.RepeatU = RenderingDevice.SamplerRepeatMode.Repeat;
|
|
state.RepeatV = RenderingDevice.SamplerRepeatMode.Repeat;
|
|
}
|
|
|
|
var sampler = RDSampler.Create( this, state );
|
|
return sampler;
|
|
}
|
|
|
|
public RDSampler Sampler( RenderingDevice.SamplerFilter filter, RenderingDevice.SamplerRepeatMode repeatMode)
|
|
{
|
|
var state = new RDSamplerState();
|
|
|
|
state.MinFilter = filter;
|
|
state.MagFilter = filter;
|
|
|
|
state.RepeatU = repeatMode;
|
|
state.RepeatV = repeatMode;
|
|
|
|
return Sampler( state );
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------
|
|
// ---------------------------------------------
|
|
// MESSAGES
|
|
// ---------------------------------------------
|
|
// ---------------------------------------------
|
|
|
|
|
|
public void Error( params object[] messages )
|
|
{
|
|
var message = RJLog.GetLogString( messages );
|
|
|
|
Messages.Error( _messages, message );
|
|
|
|
if ( logMessages )
|
|
{
|
|
this.LogError( message );
|
|
}
|
|
}
|
|
|
|
public void Warning( params object[] messages )
|
|
{
|
|
var message = RJLog.GetLogString( messages );
|
|
|
|
Messages.Warning( _messages, message );
|
|
|
|
if ( logMessages && Messages.GetLevel( MessageType.Warning ) >= messageLogLevel )
|
|
{
|
|
this.LogInfo( message );
|
|
}
|
|
}
|
|
|
|
public void Info( params object[] messages )
|
|
{
|
|
var message = RJLog.GetLogString( messages );
|
|
|
|
Messages.Info( _messages, message );
|
|
|
|
if ( logMessages && Messages.GetLevel( MessageType.Info ) >= messageLogLevel )
|
|
{
|
|
this.LogInfo( message );
|
|
}
|
|
}
|
|
|
|
public void Verbose( params object[] messages )
|
|
{
|
|
var message = RJLog.GetLogString( messages );
|
|
|
|
Messages.Verbose( _messages, message );
|
|
|
|
if ( logMessages && Messages.GetLevel( MessageType.Verbose ) >= messageLogLevel )
|
|
{
|
|
this.LogInfo( message );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
} |