RenderStuff Updates
This commit is contained in:
		
							parent
							
								
									966cb7e28c
								
							
						
					
					
						commit
						66d24be2c1
					
				|  | @ -10,22 +10,52 @@ namespace Rokojori | ||||||
|       return ( 1 << bit ); |       return ( 1 << bit ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static long GetInt64BitMask( int bit ) | ||||||
|  |     { | ||||||
|  |       return ( 1 << bit ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public static int SetBit( int value, int bitPosition ) |     public static int SetBit( int value, int bitPosition ) | ||||||
|     { |     { | ||||||
|       return value | GetInt32BitMask( bitPosition ); |       return value | GetInt32BitMask( bitPosition ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static long SetBit( long value, int bitPosition ) | ||||||
|  |     { | ||||||
|  |       return value | GetInt64BitMask( bitPosition ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public static int UnsetBit( int value, int bitPosition ) |     public static int UnsetBit( int value, int bitPosition ) | ||||||
|     { |     { | ||||||
|       return value & ~GetInt32BitMask( bitPosition ); |       return value & ~GetInt32BitMask( bitPosition ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static long UnsetBit( long value, int bitPosition ) | ||||||
|  |     { | ||||||
|  |       return value & ~GetInt64BitMask( bitPosition ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public static bool IsBitSet( int value, int bitPosition ) |     public static bool IsBitSet( int value, int bitPosition ) | ||||||
|     { |     { | ||||||
|       var mask = GetInt32BitMask( bitPosition ); |       var mask = GetInt32BitMask( bitPosition ); | ||||||
|       return ( value & mask ) == mask; |       return ( value & mask ) == mask; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static bool IsBitSet( long value, int bitPosition ) | ||||||
|  |     { | ||||||
|  |       var mask = GetInt64BitMask( bitPosition ); | ||||||
|  |       return ( value & mask ) == mask; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static bool IsMaskSet( int value, int mask ) | ||||||
|  |     { | ||||||
|  |       return ( value & mask ) == mask; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static bool IsMaskSet( long value, long mask ) | ||||||
|  |     { | ||||||
|  |       return ( value & mask ) == mask; | ||||||
|  |     } | ||||||
|      |      | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -145,6 +145,13 @@ namespace Rokojori | ||||||
|       GD.PrintRich( trace ); |       GD.PrintRich( trace ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     static void LogErrorWithFullTrace( string message ) | ||||||
|  |     { | ||||||
|  |       var trace = GetFullTrace(); | ||||||
|  |       GD.PrintErr("\n" +  message ); | ||||||
|  |       GD.PrintRich( trace ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     static void LogErrorMessage( string message, int frameIndex = 3 ) |     static void LogErrorMessage( string message, int frameIndex = 3 ) | ||||||
|     { |     { | ||||||
|       var trace = GetTrace( frameIndex ); |       var trace = GetTrace( frameIndex ); | ||||||
|  | @ -218,6 +225,11 @@ namespace Rokojori | ||||||
|       LogErrorMessage( GetLogString( objects ) ); |       LogErrorMessage( GetLogString( objects ) ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static void ErrorFull( params object[] objects) | ||||||
|  |     { | ||||||
|  |       LogErrorWithFullTrace( GetLogString( objects ) ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public static void Error( Node node, params object[] objects) |     public static void Error( Node node, params object[] objects) | ||||||
|     { |     { | ||||||
|       LogErrorMessage( "" +  HierarchyName.Of( node ) + "\n" + GetLogString( objects ), 4 ); |       LogErrorMessage( "" +  HierarchyName.Of( node ) + "\n" + GetLogString( objects ), 4 ); | ||||||
|  |  | ||||||
|  | @ -54,7 +54,15 @@ namespace Rokojori | ||||||
|     public Callable GrabTextureButton => Callable.From(  |     public Callable GrabTextureButton => Callable.From(  | ||||||
|       async () =>  |       async () =>  | ||||||
|       { |       { | ||||||
|         texture2D = await alphaGrabTestEffect.GetImageTexture( async ()=> await this.RequestNextFrame() ); |         var result = await alphaGrabTestEffect.GetImageTexture( async ()=> await this.RequestNextFrame() ); | ||||||
|  | 
 | ||||||
|  |         if ( result == null ) | ||||||
|  |         { | ||||||
|  |           this.LogError( "No texture" ); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         texture2D = result; | ||||||
|       }  |       }  | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,135 @@ | ||||||
|  | using System.Collections; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using Godot; | ||||||
|  | using System; | ||||||
|  | using System.Linq; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | namespace Rokojori | ||||||
|  | { | ||||||
|  |   [Tool] | ||||||
|  |   [GlobalClass] | ||||||
|  |   public partial class GrabTexture2:Action | ||||||
|  |   {  | ||||||
|  |     [Export] | ||||||
|  |     public SubViewport viewport; | ||||||
|  | 
 | ||||||
|  |     [Export] | ||||||
|  |     public Texture2D target; | ||||||
|  | 
 | ||||||
|  |     [Export] | ||||||
|  |     public MeshInstance3D meshInstance3D; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     [ExportToolButton( "Grab Texture")] | ||||||
|  |     public Callable GrabButton => Callable.From(  | ||||||
|  |       () =>  | ||||||
|  |       { | ||||||
|  |         Grab(); | ||||||
|  |       }  | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     async void Grab() | ||||||
|  |     {    | ||||||
|  |       var updateMode = viewport.RenderTargetUpdateMode; | ||||||
|  | 
 | ||||||
|  |       if ( updateMode != SubViewport.UpdateMode.Always ) | ||||||
|  |       { | ||||||
|  |         viewport.RenderTargetUpdateMode = SubViewport.UpdateMode.Always; | ||||||
|  |         await this.RequestNextFrame(); | ||||||
|  |         viewport.RenderTargetUpdateMode = updateMode; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |       var viewPortFormat = RDTextureFormats.GetDataFormat( viewport ); | ||||||
|  |       var viewPortData = viewport.GetTexture().GetImage().GetData(); | ||||||
|  |       var viewPortSize = viewport.Size; | ||||||
|  | 
 | ||||||
|  |       this.LogInfo( "Creating context" ); | ||||||
|  |       var ctx = RDContext.Local(); | ||||||
|  |       ctx.computeSize = viewPortSize; | ||||||
|  |       ctx.messageLogLevel = Messages.GetLevel( MessageType.Verbose ); | ||||||
|  |        | ||||||
|  |        | ||||||
|  |       this.LogInfo( "Creating textures" ); | ||||||
|  |        | ||||||
|  |       var outputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat ); | ||||||
|  |       this.LogInfo( "Usage", RDTextureFormats.UsageInfo( outputTexture.format.UsageBits ) ); | ||||||
|  |       | ||||||
|  | 
 | ||||||
|  |       var inputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat ); | ||||||
|  |       inputTexture.SetData( viewPortData ); | ||||||
|  | 
 | ||||||
|  |       var graph = CreateGraph( ctx, inputTexture, outputTexture ); | ||||||
|  | 
 | ||||||
|  |       graph.ProcessForView(); | ||||||
|  |       | ||||||
|  |       ctx.SubmitAndSync(); | ||||||
|  | 
 | ||||||
|  |       var width = outputTexture.width; | ||||||
|  |       var height = outputTexture.height; | ||||||
|  |       var format = outputTexture.imageFormat;  | ||||||
|  | 
 | ||||||
|  |       var data = outputTexture.GetData(); | ||||||
|  | 
 | ||||||
|  |       this.LogInfo( "Copying texture" ); | ||||||
|  |        | ||||||
|  |       ctx.SubmitAndSync(); | ||||||
|  |       await this.RequestNextFrame(); | ||||||
|  | 
 | ||||||
|  |       var image = Image.CreateFromData( width, height, false, format, data ); | ||||||
|  |       var buffer = TextureCombinerBuffer.From( ImageTexture.CreateFromImage( image ) ); | ||||||
|  | 
 | ||||||
|  |       target = buffer.CreateImageTexture(); | ||||||
|  | 
 | ||||||
|  |       var material3D = (StandardMaterial3D) meshInstance3D.MaterialOverride; | ||||||
|  |       material3D.AlbedoTexture = target; | ||||||
|  | 
 | ||||||
|  |       ctx.CleanUp(); | ||||||
|  | 
 | ||||||
|  |       await this.RequestNextFrame(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |        | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     RDGraph CreateGraph( RDContext ctx, RDTexture it, RDTexture ot ) | ||||||
|  |     { | ||||||
|  |       var graph = new RDGraph( ctx ); | ||||||
|  | 
 | ||||||
|  |       var viewTexture = CEG_BufferTexture.From( graph, it ); | ||||||
|  |       var bufferTexture = CEG_BufferTexture.From( graph, ot );     | ||||||
|  | 
 | ||||||
|  |       var copy = new CEG_Copy( graph ); | ||||||
|  |       var radialBlur = new CEG_RadialBlur( graph ); | ||||||
|  | 
 | ||||||
|  |       graph.InitializeNodes(); | ||||||
|  | 
 | ||||||
|  |       copy.SetTextureSlotInputs( viewTexture, bufferTexture ); | ||||||
|  |       radialBlur.SetTextureSlotInputs( copy.output, copy.input );  | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |       graph.SetProcessOrder(  | ||||||
|  |         viewTexture, bufferTexture,  | ||||||
|  |         copy, radialBlur  | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |       radialBlur.constants.Set( | ||||||
|  |         new Vector2( 0.5f, 0.5f ),  | ||||||
|  |         0.5f,  | ||||||
|  |         0.5f,  | ||||||
|  |         16,         | ||||||
|  |         Vector2.Zero | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |       return graph; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  |   }  | ||||||
|  | } | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | uid://ctj2rxanlda0d | ||||||
|  | @ -0,0 +1,120 @@ | ||||||
|  | using System.Collections; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using Godot; | ||||||
|  | using System; | ||||||
|  | using System.Linq; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | namespace Rokojori | ||||||
|  | { | ||||||
|  |   [Tool] | ||||||
|  |   [GlobalClass] | ||||||
|  |   public partial class GrabTextureRD:Action | ||||||
|  |   {  | ||||||
|  |     [Export] | ||||||
|  |     public SubViewport viewport; | ||||||
|  | 
 | ||||||
|  |     [Export] | ||||||
|  |     public Texture2D target; | ||||||
|  | 
 | ||||||
|  |     [Export] | ||||||
|  |     public MeshInstance3D meshInstance3D; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     [ExportToolButton( "Grab Texture")] | ||||||
|  |     public Callable GrabButton => Callable.From(  | ||||||
|  |       () =>  | ||||||
|  |       { | ||||||
|  |         Grab(); | ||||||
|  |       }  | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     async void Grab() | ||||||
|  |     {    | ||||||
|  |       var updateMode = viewport.RenderTargetUpdateMode; | ||||||
|  | 
 | ||||||
|  |       if ( updateMode != SubViewport.UpdateMode.Always ) | ||||||
|  |       { | ||||||
|  |         viewport.RenderTargetUpdateMode = SubViewport.UpdateMode.Always; | ||||||
|  |         await this.RequestNextFrame(); | ||||||
|  |         viewport.RenderTargetUpdateMode = updateMode; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |       var viewPortFormat = RDTextureFormats.GetDataFormat( viewport ); | ||||||
|  |       var viewPortData = viewport.GetTexture().GetImage().GetData(); | ||||||
|  | 
 | ||||||
|  |       this.LogInfo( "Creating context" ); | ||||||
|  |       var ctx = RDContext.Local(); | ||||||
|  |       ctx.messageLogLevel = Messages.GetLevel( MessageType.Verbose ); | ||||||
|  | 
 | ||||||
|  |       this.LogInfo( "Creating program" ); | ||||||
|  |       ctx.SetProgramFromPath( CEG_AlphaColorDilation.shaderPath ); | ||||||
|  | 
 | ||||||
|  |       this.LogInfo( "Creating textures" ); | ||||||
|  |        | ||||||
|  |       var outputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat ); | ||||||
|  |       this.LogInfo( "Usage", RDTextureFormats.UsageInfo( outputTexture.format.UsageBits ) ); | ||||||
|  |       outputTexture.SetData( new Color( 1, 1, 1, 1 ) ); | ||||||
|  | 
 | ||||||
|  |        | ||||||
|  | 
 | ||||||
|  |       // var inputTexture  = RDTexture.CreateCopyFrom( ctx, viewport ); | ||||||
|  |       var inputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat ); | ||||||
|  |       inputTexture.SetData( viewPortData ); | ||||||
|  |       // inputTexture.SetData( new Color( 0, 1, 0, 1 ) ); | ||||||
|  | 
 | ||||||
|  |       this.LogInfo( "Assigning input texture:", ctx.shader, ctx.shader.rid ); | ||||||
|  |       ctx.AssignTexture( inputTexture ); | ||||||
|  | 
 | ||||||
|  |       this.LogInfo( "Assigning output texture" );  | ||||||
|  |       ctx.AssignTexture( outputTexture ); | ||||||
|  | 
 | ||||||
|  |       this.LogInfo( "Compute group sizes" ); | ||||||
|  |       ctx.CalculateComputeGroups( 8, viewport.Size ); | ||||||
|  | 
 | ||||||
|  |       this.LogInfo( "Process compute program" ); | ||||||
|  |       ctx.ProcessComputeProgram(); | ||||||
|  | 
 | ||||||
|  |       this.LogInfo( "Waiting to render" ); | ||||||
|  |       | ||||||
|  |       ctx.SubmitAndSync(); | ||||||
|  | 
 | ||||||
|  |       var width = outputTexture.width; | ||||||
|  |       var height = outputTexture.height; | ||||||
|  |       var format = outputTexture.imageFormat;  | ||||||
|  | 
 | ||||||
|  |       var data = outputTexture.GetData(); | ||||||
|  |       data = data.ToList().ToArray(); | ||||||
|  | 
 | ||||||
|  |       this.LogInfo( "Copying texture" ); | ||||||
|  |        | ||||||
|  |       ctx.SubmitAndSync(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |       await this.RequestNextFrame(); | ||||||
|  | 
 | ||||||
|  |       var image = Image.CreateFromData( width, height, false, format, data ); | ||||||
|  |       var buffer = TextureCombinerBuffer.From( ImageTexture.CreateFromImage( image ) ); | ||||||
|  | 
 | ||||||
|  |       target = buffer.CreateImageTexture(); | ||||||
|  | 
 | ||||||
|  |       var material3D = (StandardMaterial3D) meshInstance3D.MaterialOverride; | ||||||
|  |       material3D.AlbedoTexture = target; | ||||||
|  | 
 | ||||||
|  |       ctx.CleanUp(); | ||||||
|  | 
 | ||||||
|  |       await this.RequestNextFrame(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |        | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  |   }  | ||||||
|  | } | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | uid://cl0fx4gpluvhh | ||||||
|  | @ -14,16 +14,6 @@ namespace Rokojori | ||||||
|       Initialize(); |       Initialize(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|      |  | ||||||
|     [Export] |  | ||||||
|     public float intensity = 0.5f; |  | ||||||
| 
 |  | ||||||
|     [Export] |  | ||||||
|     public float shiftAll = 0.5f; |  | ||||||
| 
 |  | ||||||
|     [Export] |  | ||||||
|     public float unshiftCenter = 16f; |  | ||||||
| 
 |  | ||||||
|     [Export] |     [Export] | ||||||
|     public Vector2 rShift = new Vector2( -0.001f, 0.0f ); |     public Vector2 rShift = new Vector2( -0.001f, 0.0f ); | ||||||
| 
 | 
 | ||||||
|  | @ -33,6 +23,16 @@ namespace Rokojori | ||||||
|     [Export] |     [Export] | ||||||
|     public Vector2 bShift = new Vector2( 0.001f, 0.0f ); |     public Vector2 bShift = new Vector2( 0.001f, 0.0f ); | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|  |     [Export] | ||||||
|  |     public float intensity = 0.5f; | ||||||
|  | 
 | ||||||
|  |     [Export] | ||||||
|  |     public float shiftAll = 0.5f; | ||||||
|  | 
 | ||||||
|  |     [Export] | ||||||
|  |     public float unshiftCenter = 16f; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     CEG_ScreenColorTexure screenColorTexture; |     CEG_ScreenColorTexure screenColorTexture; | ||||||
|  | @ -52,8 +52,6 @@ namespace Rokojori | ||||||
| 
 | 
 | ||||||
|       graph.InitializeNodes();       |       graph.InitializeNodes();       | ||||||
| 
 | 
 | ||||||
|        |  | ||||||
| 
 |  | ||||||
|       copy.SetTextureSlotInputs( screenColorTexture, bufferTexture ); |       copy.SetTextureSlotInputs( screenColorTexture, bufferTexture ); | ||||||
|       chromaticAberation.SetTextureSlotInputs( copy.output, copy.input );  |       chromaticAberation.SetTextureSlotInputs( copy.output, copy.input );  | ||||||
| 
 | 
 | ||||||
|  | @ -68,12 +66,13 @@ namespace Rokojori | ||||||
|     protected override void ForAllViews() |     protected override void ForAllViews() | ||||||
|     { |     { | ||||||
|       chromaticAberation.constants.Set( |       chromaticAberation.constants.Set( | ||||||
|         intensity,  | 
 | ||||||
|         shiftAll,  |  | ||||||
|         unshiftCenter, |  | ||||||
|         rShift, |         rShift, | ||||||
|         gShift, |         gShift, | ||||||
|         bShift |         bShift, | ||||||
|  |         intensity,  | ||||||
|  |         shiftAll,  | ||||||
|  |         unshiftCenter        | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -31,7 +31,7 @@ void main() | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	vec4 original_pixel = imageLoad(originalImage, current_seed_position); | 	vec4 original_pixel = imageLoad( originalImage, current_seed_position ); | ||||||
| 
 | 
 | ||||||
| 	// The current pixel is on the edge of the outline, outer side | 	// The current pixel is on the edge of the outline, outer side | ||||||
| 	if (distance_to_seed > outlinesSize - 1.0f)  | 	if (distance_to_seed > outlinesSize - 1.0f)  | ||||||
|  |  | ||||||
|  | @ -58,7 +58,7 @@ namespace Rokojori | ||||||
| 
 | 
 | ||||||
|     protected override void ForAllViews() |     protected override void ForAllViews() | ||||||
|     {      |     {      | ||||||
|       context.CalculateComputeGroups( _groupSize ); |       context.CalculateSceneComputeGroups( _groupSize ); | ||||||
| 
 | 
 | ||||||
|       SetConstants(); |       SetConstants(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -16,6 +16,24 @@ namespace Rokojori | ||||||
|         Warning( "ro == null, couldn't clean up: ", info ); |         Warning( "ro == null, couldn't clean up: ", info ); | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
|  | 
 | ||||||
|  |       if ( ! ro.rid.IsValid ) | ||||||
|  |       {  | ||||||
|  |         Verbose( "Not valid rid:", ro.rid ); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ( ro is RDPipeline ) | ||||||
|  |       { | ||||||
|  |         Verbose( "Not cleaning pipelines" ); | ||||||
|  |         return;  | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ( ro is RDUniformSet ) | ||||||
|  |       { | ||||||
|  |         Verbose( "Not cleaning uniform sets" ); | ||||||
|  |         return;  | ||||||
|  |       } | ||||||
|        |        | ||||||
|       Verbose( "Cleaning up: ", info, ro.rid  ); |       Verbose( "Cleaning up: ", info, ro.rid  ); | ||||||
|       renderingDevice.FreeRid( ro.rid ); |       renderingDevice.FreeRid( ro.rid ); | ||||||
|  | @ -29,7 +47,7 @@ namespace Rokojori | ||||||
|       _cleanUps.ForEach(  |       _cleanUps.ForEach(  | ||||||
|         c =>  |         c =>  | ||||||
|         { |         { | ||||||
|           Free( c, "_cleanUps[" + index + "]"); |           Free( c, _cleanUpInfo[ index ] ); | ||||||
|           index ++; |           index ++; | ||||||
|         } |         } | ||||||
|       ); |       ); | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ namespace Rokojori | ||||||
| 
 | 
 | ||||||
|       if ( logMessages ) |       if ( logMessages ) | ||||||
|       { |       { | ||||||
|         RJLog.Log( message ); |         RJLog.ErrorFull( message ); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -37,7 +37,7 @@ namespace Rokojori | ||||||
| 
 | 
 | ||||||
|       if ( logMessages && Messages.GetLevel( MessageType.Warning ) >= messageLogLevel ) |       if ( logMessages && Messages.GetLevel( MessageType.Warning ) >= messageLogLevel ) | ||||||
|       { |       { | ||||||
|         RJLog.Log( message ); |         RJLog.ErrorFull( message ); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,19 +6,36 @@ namespace Rokojori | ||||||
| {   | {   | ||||||
|   public partial class RDContext |   public partial class RDContext | ||||||
|   { |   { | ||||||
|  |      | ||||||
|     protected RenderingDevice _renderingDevice; |     protected RenderingDevice _renderingDevice; | ||||||
|     public RenderingDevice renderingDevice => _renderingDevice; |     public RenderingDevice renderingDevice => _renderingDevice; | ||||||
|   | 
 | ||||||
|  |     protected bool _localRenderingDevice; | ||||||
|  |     public bool isLocalRenderingDevice => _localRenderingDevice; | ||||||
|  | 
 | ||||||
|     protected RDShader _shader; |     protected RDShader _shader; | ||||||
|     public RDShader shader => _shader; |     public RDShader shader => _shader; | ||||||
| 
 | 
 | ||||||
|     protected RDPipeline _pipeline; |     protected RDPipeline _pipeline; | ||||||
|     public RDPipeline pipeline => _pipeline; |     public RDPipeline pipeline => _pipeline; | ||||||
| 
 | 
 | ||||||
|  |     public static RDContext Local() | ||||||
|  |     { | ||||||
|  |       var ctx = new RDContext(); | ||||||
|  |       ctx.Initialize( true ); | ||||||
|  |       return ctx; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public void Initialize( bool local = false) |     public void Initialize( bool local = false) | ||||||
|     { |     { | ||||||
|  |       _localRenderingDevice = local; | ||||||
|       _renderingDevice = local ? RenderingServer.Singleton.CreateLocalRenderingDevice(): |       _renderingDevice = local ? RenderingServer.Singleton.CreateLocalRenderingDevice(): | ||||||
|                                  RenderingServer.Singleton.GetRenderingDevice(); |                                  RenderingServer.Singleton.GetRenderingDevice(); | ||||||
|  | 
 | ||||||
|  |       if ( _renderingDevice == null ) | ||||||
|  |       { | ||||||
|  |         Error( "Could not initialize rendering device" ); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -52,7 +69,18 @@ namespace Rokojori | ||||||
|       return RDTexture.Depth( this ); |       return RDTexture.Depth( this ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|      |     public void SetProgram( RDProgram p ) | ||||||
|  |     { | ||||||
|  |       SetShaderAndPipeline( p.shader, p.pipeline ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void SetProgramFromPath( string path ) | ||||||
|  |     { | ||||||
|  |       Verbose( "Creating program:", path ); | ||||||
|  |       var program = RDProgram.FromPath( this, path ); | ||||||
|  |       SetProgram( program ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public void SetShaderAndPipeline( RDShader shader, RDPipeline pipeline ) |     public void SetShaderAndPipeline( RDShader shader, RDPipeline pipeline ) | ||||||
|     { |     { | ||||||
|       if ( shader == null || pipeline == null ) |       if ( shader == null || pipeline == null ) | ||||||
|  | @ -77,7 +105,8 @@ namespace Rokojori | ||||||
|     public void AssignScreenDepthTexture( RDSampler sampler = null, int setIndex = -1 ) |     public void AssignScreenDepthTexture( RDSampler sampler = null, int setIndex = -1 ) | ||||||
|     { |     { | ||||||
|       AssignTexture( GetScreenDepthTexture(), sampler, setIndex ); |       AssignTexture( GetScreenDepthTexture(), sampler, setIndex ); | ||||||
|     } |     }  | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     public void AssignTexture( RDTexture texture, RDSampler sampler = null, int setIndex = -1 ) |     public void AssignTexture( RDTexture texture, RDSampler sampler = null, int setIndex = -1 ) | ||||||
|     { |     { | ||||||
|  | @ -110,33 +139,111 @@ namespace Rokojori | ||||||
|       _uniformSets.Add( uniformSet ); |       _uniformSets.Add( uniformSet ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public void CreateUniformaSet( params RDUniform[] uniforms ) | ||||||
|  |     { | ||||||
|  |       var setIndex = _uniformSets.Count; | ||||||
|  |      _CreateUniformSetRid( setIndex, uniforms ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Rid _CreateUniformSetRid( int index, params RDUniform[] uniforms ) | ||||||
|  |     { | ||||||
|  |       var array = new Godot.Collections.Array<RDUniform>(); | ||||||
|  |       array.AddRange( uniforms ); | ||||||
|  | 
 | ||||||
|  |       if ( ! isLocalRenderingDevice ) | ||||||
|  |       { | ||||||
|  |         return UniformSetCacheRD.GetCache( shader.rid, (uint) index, array ); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |         return renderingDevice.UniformSetCreate( array, shader.rid, (uint) index ); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public void Clear() |     public void Clear() | ||||||
|     { |     { | ||||||
|        _uniformSets.Clear(); |        _uniformSets.Clear(); | ||||||
|       pushConstants = null; |       pushConstants = null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public Vector2I computeSize = new Vector2I( 512, 512 ); | ||||||
|  | 
 | ||||||
|  |     public Vector2I GetComputeSize() | ||||||
|  |     { | ||||||
|  |       if ( _sceneBuffers != null ) | ||||||
|  |       { | ||||||
|  |         return _sceneBuffers.GetInternalSize(); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return computeSize; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public void SetComputeGroups( Vector3I groups ) |     public void SetComputeGroups( Vector3I groups ) | ||||||
|     { |     { | ||||||
|       this._groups = groups; |       this._groups = groups; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     public void CalculateComputeGroups( int groupSize ) |     public void CalculateSceneComputeGroups( int groupSize ) | ||||||
|     { |     { | ||||||
|       CalculateComputeGroups( new Vector3I( groupSize, groupSize, 0 ) ); |       var size = GetComputeSize(); | ||||||
|  |       CalculateComputeGroups( new Vector3I( groupSize, groupSize, 0 ), size ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void CalculateComputeGroups( Vector3I groupSize ) |     public void CalculateSceneComputeGroups( Vector3I groupSize ) | ||||||
|     { |     { | ||||||
|       var size = sceneBuffers.GetInternalSize(); |       var size = GetComputeSize(); | ||||||
|  |       CalculateComputeGroups( groupSize, size ); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|  |     public void CalculateComputeGroups( int groupSize, Vector2I size ) | ||||||
|  |     { | ||||||
|  |       CalculateComputeGroups( new Vector3I( groupSize, groupSize, 0 ), size ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void CalculateComputeGroups( Vector3I groupSize, Vector2I size ) | ||||||
|  |     { | ||||||
|       var xGroups = Mathf.CeilToInt( size.X / (float) groupSize.X ); |       var xGroups = Mathf.CeilToInt( size.X / (float) groupSize.X ); | ||||||
|       var yGroups = groupSize.Y == 0 ? 1 : Mathf.CeilToInt( size.Y / (float) groupSize.Y ); |       var yGroups = groupSize.Y == 0 ? 1 : Mathf.CeilToInt( size.Y / (float) groupSize.Y ); | ||||||
|       var zGroups = groupSize.Z == 0 ? 1 : Mathf.CeilToInt( size.Y / (float) groupSize.Y ); |       var zGroups = 1; | ||||||
| 
 | 
 | ||||||
|       SetComputeGroups( new Vector3I( xGroups, yGroups, zGroups ) ); |       SetComputeGroups( new Vector3I( xGroups, yGroups, zGroups ) ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public void Submit() | ||||||
|  |     { | ||||||
|  |       if ( ! isLocalRenderingDevice ) | ||||||
|  |       { | ||||||
|  |         Error( "You can only submit or sync in non-local rendering devices" ); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       renderingDevice.Submit(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void Sync() | ||||||
|  |     { | ||||||
|  |       if ( ! isLocalRenderingDevice ) | ||||||
|  |       { | ||||||
|  |         Error( "You can only submit or sync in non-local rendering devices" ); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       renderingDevice.Sync(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void SubmitAndSync() | ||||||
|  |     { | ||||||
|  |       if ( ! isLocalRenderingDevice ) | ||||||
|  |       { | ||||||
|  |         Error( "You can only submit or sync in non-local rendering devices" ); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       Submit(); | ||||||
|  |       Sync(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public void ProcessComputeProgram() |     public void ProcessComputeProgram() | ||||||
|     { |     { | ||||||
|       try |       try | ||||||
|  |  | ||||||
|  | @ -7,6 +7,14 @@ namespace Rokojori | ||||||
|    |    | ||||||
|   public class RDProgram |   public class RDProgram | ||||||
|   {  |   {  | ||||||
|  |     protected RDContext _context; | ||||||
|  |     public RDContext context => _context; | ||||||
|  | 
 | ||||||
|  |     public RDProgram( RDContext context ) | ||||||
|  |     { | ||||||
|  |       _context = context; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public enum Type  |     public enum Type  | ||||||
|     { |     { | ||||||
|       VertexFragment, |       VertexFragment, | ||||||
|  | @ -17,9 +25,32 @@ namespace Rokojori | ||||||
|     public Type type => _type; |     public Type type => _type; | ||||||
| 
 | 
 | ||||||
|     protected RDShader _shader; |     protected RDShader _shader; | ||||||
|     public RDShader shader; |     public RDShader shader => _shader; | ||||||
| 
 | 
 | ||||||
|     protected RDPipeline _pipeline; |     protected RDPipeline _pipeline; | ||||||
|     public RDPipeline pipeline; |     public RDPipeline pipeline => _pipeline; | ||||||
|  | 
 | ||||||
|  |     public static RDProgram FromPath( RDContext context, string path ) | ||||||
|  |     { | ||||||
|  |       var p = new RDProgram( context ); | ||||||
|  | 
 | ||||||
|  |       p._shader = RDShader.FromPath( context, path ); | ||||||
|  | 
 | ||||||
|  |       if ( p._shader == null || ! p._shader.rid.IsValid ) | ||||||
|  |       { | ||||||
|  |         context.Error( "Invalid shader", path ); | ||||||
|  |         return null; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       p._pipeline = RDPipeline.Create( context, p._shader ); | ||||||
|  | 
 | ||||||
|  |        if ( p._pipeline == null || ! p._pipeline.rid.IsValid ) | ||||||
|  |       { | ||||||
|  |         context.Error( "Invalid pipeline", path ); | ||||||
|  |         return null; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return p;  | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -8,10 +8,38 @@ namespace Rokojori | ||||||
|     public RDShader( RDContext context, Rid rid ):base( context, rid ) |     public RDShader( RDContext context, Rid rid ):base( context, rid ) | ||||||
|     {} |     {} | ||||||
| 
 | 
 | ||||||
|     public static RDShader CreateFromSpirV( RDContext context, RDShaderSpirV rDShaderSpirV ) |     public static RDShader CreateFromSpirV( RDContext context, RDShaderSpirV rDShaderSpirV, string pathInfo = null ) | ||||||
|     { |     { | ||||||
|       var shaderID = context.renderingDevice.ShaderCreateFromSpirV( rDShaderSpirV ); |       var shaderID = context.renderingDevice.ShaderCreateFromSpirV( rDShaderSpirV ); | ||||||
|  | 
 | ||||||
|  |       if ( ! shaderID.IsValid ) | ||||||
|  |       { | ||||||
|  |         context.Error( "Couldn't create shader from spirV. PathInfo:", pathInfo ); | ||||||
|  |         return null; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|       return new RDShader( context, shaderID ); |       return new RDShader( context, shaderID ); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public static RDShader FromPath( RDContext context, string path ) | ||||||
|  |     { | ||||||
|  |       var glslFile = GD.Load<RDShaderFile>( path ); | ||||||
|  | 
 | ||||||
|  |       if ( glslFile == null ) | ||||||
|  |       { | ||||||
|  |         context.Error( "File not found:", path ); | ||||||
|  |         return null; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       var spirV = glslFile.GetSpirV(); | ||||||
|  | 
 | ||||||
|  |       if ( spirV == null ) | ||||||
|  |       { | ||||||
|  |         context.Error( "SpirV is null", path ); | ||||||
|  |         return null; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return CreateFromSpirV( context, spirV, path ); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -26,6 +26,121 @@ namespace Rokojori | ||||||
|       return new RDTexture( context, rid );   |       return new RDTexture( context, rid );   | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public void SetData( byte[] data, int layer = 0 ) | ||||||
|  |     { | ||||||
|  |       var error = context.renderingDevice.TextureUpdate( rid, (uint) layer, data ); | ||||||
|  | 
 | ||||||
|  |       if ( error == Error.Ok ) | ||||||
|  |       { | ||||||
|  |         context.Verbose( "Data was set" ); | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       context.Error( error ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void SetData( Viewport viewport ) | ||||||
|  |     { | ||||||
|  |       SetData( viewport.GetTexture().GetImage() ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void SetData( Image image ) | ||||||
|  |     { | ||||||
|  |       var textureDataFormat = RDTextureFormats.ImageFormatToDataFormat( image.GetFormat() ); | ||||||
|  | 
 | ||||||
|  |       if ( textureDataFormat != format.Format ) | ||||||
|  |       { | ||||||
|  |         context.Error( "Incompatible image format:", textureDataFormat, " Expected:", format.Format ); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |       SetData( image.GetData() ); | ||||||
|  |     }  | ||||||
|  | 
 | ||||||
|  |     public int numPixels => (int) ( format.Width * format.Height ); | ||||||
|  |     public int channelsPerPixel => RDTextureFormats.GetNumChannels( format.Format ); | ||||||
|  | 
 | ||||||
|  |     public RDTextureFormats.PixelChannelEncoding pixelChannelEncoding => RDTextureFormats.GetPixelChannelEncoding( format.Format ); | ||||||
|  | 
 | ||||||
|  |     public int bytesPerPixel => RDTextureFormats.NumBytesFor( pixelChannelEncoding ) * channelsPerPixel; | ||||||
|  | 
 | ||||||
|  |     public int GetNumBytes( int layer = 0 ) | ||||||
|  |     { | ||||||
|  |       var bytes = numPixels * bytesPerPixel; | ||||||
|  |        | ||||||
|  |       while ( layer > 0 ) | ||||||
|  |       { | ||||||
|  |         bytes /= 4; | ||||||
|  |         layer --; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return bytes; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void SetData( Color color ) | ||||||
|  |     { | ||||||
|  |       var fmt = format.Format; | ||||||
|  | 
 | ||||||
|  |       var colorBytes = RDTextureFormats.ColorToBytes( color, fmt ); | ||||||
|  | 
 | ||||||
|  |       if ( colorBytes == null ) | ||||||
|  |       { | ||||||
|  |         context.Error( "Unsupported texture format" ); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       context.Verbose( "ColorBytes:", colorBytes ); | ||||||
|  | 
 | ||||||
|  |       var bytes = new byte[ GetNumBytes() ]; | ||||||
|  | 
 | ||||||
|  |       context.Verbose( "NumPixels", numPixels, "BytesPerPixel", bytesPerPixel, "Num Bytes", GetNumBytes( 0 ) ); | ||||||
|  | 
 | ||||||
|  |       for ( int i = 0; i < bytes.Length; i+= colorBytes.Length ) | ||||||
|  |       { | ||||||
|  |         System.Array.Copy( colorBytes, 0, bytes, i, colorBytes.Length ); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       context.Verbose( "First Byte", bytes[ 0 ], bytes[ 1 ], bytes[ 2 ], bytes[ 3 ] ); | ||||||
|  | 
 | ||||||
|  |       SetData( bytes ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public byte[] GetData( int layer = 0) | ||||||
|  |     { | ||||||
|  |       return context.renderingDevice.TextureGetData( rid, (uint) layer ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public int width => (int) format.Width; | ||||||
|  |     public int height => (int) format.Height; | ||||||
|  | 
 | ||||||
|  |     public RenderingDevice.DataFormat dataFormat => format.Format; | ||||||
|  |     public Image.Format imageFormat => RDTextureFormats.DataFormatToImageFormat( dataFormat ); | ||||||
|  | 
 | ||||||
|  |     public Image GetImage() | ||||||
|  |     {       | ||||||
|  |       var fmt = format; | ||||||
|  |       var imgF = RDTextureFormats.DataFormatToImageFormat( format.Format ); | ||||||
|  | 
 | ||||||
|  |        | ||||||
|  |       var data = GetData(); | ||||||
|  | 
 | ||||||
|  |       var output = ""; | ||||||
|  |       for ( int i = 0; i < 20; i++ ) | ||||||
|  |       { | ||||||
|  |         if ( i != 0 ){ output += ", "; } | ||||||
|  |         output += data[ i ] + ""; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       context.Verbose( "Converting:", fmt.Format, ">>", imgF, "output:", output ); | ||||||
|  |       return Image.CreateFromData( (int) fmt.Width, (int)fmt.Height, false, imgF, data ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Texture2D GetTexture2D() | ||||||
|  |     { | ||||||
|  |       return ImageTexture.CreateFromImage( GetImage() ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public RDTextureFormat format  |     public RDTextureFormat format  | ||||||
|     { |     { | ||||||
|       get |       get | ||||||
|  | @ -67,7 +182,7 @@ namespace Rokojori | ||||||
|       return new RDTexture( context, rid );   |       return new RDTexture( context, rid );   | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static RDTextureFormat DefaultFormat( int w, int h,  RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Unorm ) |     public static RDTextureFormat DefaultFormat( int w, int h,  RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Sfloat) | ||||||
|     { |     { | ||||||
|       var format = new RDTextureFormat(); |       var format = new RDTextureFormat(); | ||||||
| 
 | 
 | ||||||
|  | @ -77,60 +192,51 @@ namespace Rokojori | ||||||
|       format.UsageBits = RenderingDevice.TextureUsageBits.StorageBit |  |       format.UsageBits = RenderingDevice.TextureUsageBits.StorageBit |  | ||||||
|                          RenderingDevice.TextureUsageBits.SamplingBit | |                          RenderingDevice.TextureUsageBits.SamplingBit | | ||||||
|                          RenderingDevice.TextureUsageBits.CanCopyFromBit |  |                          RenderingDevice.TextureUsageBits.CanCopyFromBit |  | ||||||
|  |                          RenderingDevice.TextureUsageBits.CanUpdateBit | | ||||||
|  |                          RenderingDevice.TextureUsageBits.CanCopyToBit | | ||||||
|                          RenderingDevice.TextureUsageBits.CpuReadBit |                          RenderingDevice.TextureUsageBits.CpuReadBit | ||||||
|                         ; |                         ; | ||||||
| 
 | 
 | ||||||
|       return format; |       return format; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static RDTextureFormat FormatChangeSize( RDTextureFormat tf, Vector2I size ) |     public static RDTexture Create( RDContext context, Vector2I size, RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Sfloat ) | ||||||
|     { |  | ||||||
|       return FormatChangeSize( tf, size.X, size.Y ); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     public static RDTextureFormat FormatChangeSize( RDTextureFormat tf, int w, int h ) |  | ||||||
|     { |  | ||||||
|       var clone = FormatCopy( tf ); |  | ||||||
|       clone.Width = (uint) w; |  | ||||||
|       clone.Height = (uint) h; |  | ||||||
|       return clone; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public static RDTextureFormat FormatCopy( RDTextureFormat tf ) |  | ||||||
|     { |  | ||||||
|       var format = new RDTextureFormat(); |  | ||||||
| 
 |  | ||||||
|       format.Format = tf.Format; |  | ||||||
| 
 |  | ||||||
|       format.Width  = tf.Width; |  | ||||||
|       format.Height = tf.Height; |  | ||||||
|       format.Depth = tf.Depth; |  | ||||||
| 
 |  | ||||||
|       format.ArrayLayers = tf.ArrayLayers; |  | ||||||
|       format.Mipmaps = tf.Mipmaps; |  | ||||||
|       format.TextureType = tf.TextureType; |  | ||||||
|       format.Samples = tf.Samples;       |  | ||||||
|       format.UsageBits = tf.UsageBits; |  | ||||||
|       format.IsResolveBuffer = tf.IsResolveBuffer; |  | ||||||
|       format.IsDiscardable = tf.IsDiscardable; |  | ||||||
| 
 |  | ||||||
|       return tf; |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public static RDTexture Create( RDContext context, Vector2I size, RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Unorm ) |  | ||||||
|     { |     { | ||||||
|       return Create( context, size.X, size.Y, dataFormat ); |       return Create( context, size.X, size.Y, dataFormat ); | ||||||
|     } |     }     | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     public static RDTexture Create( RDContext context, int width, int height,  |     public static RDTexture Create( RDContext context, int width, int height,  | ||||||
|                                     RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Unorm ) |                                     RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Sfloat, | ||||||
|  |                                     RenderingDevice.TextureUsageBits textureUsageBits = RDTextureFormats.Usage_Default ) | ||||||
|     { |     { | ||||||
|       var view   = new RDTextureView(); |       var view   = new RDTextureView(); | ||||||
|       var format = DefaultFormat( width, height, dataFormat ); |       var format = RDTextureFormats.DefaultFormat( width, height, dataFormat ); | ||||||
|  |       format.UsageBits = textureUsageBits; | ||||||
|  | 
 | ||||||
|  |       context.Verbose( "Format:", format, "DataFormat",  dataFormat); | ||||||
| 
 | 
 | ||||||
|       var rid = context.renderingDevice.TextureCreate( format, view );  |       var rid = context.renderingDevice.TextureCreate( format, view );  | ||||||
|       return new RDTexture( context, rid );   |       return new RDTexture( context, rid );   | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     public static RDTexture CreateCopyFrom( RDContext context, SubViewport viewport ) | ||||||
|  |     { | ||||||
|  |       var dataFormat = RDTextureFormats.GetDataFormat( viewport ); | ||||||
|  |       var bytes = RDTextureFormats.GetNumBytes( viewport ); | ||||||
|  |       var image = viewport.GetTexture().GetImage(); | ||||||
|  |       var viewPortImageFormat = image.GetFormat(); | ||||||
|  |       var rdFormat = RDTextureFormats.ImageFormatToDataFormat( viewPortImageFormat ); | ||||||
|  |       var data = image.GetData(); | ||||||
|  | 
 | ||||||
|  |       RJLog.Log( "Data", data.Length, Lists.SubList( data, 0, 100 ) ); | ||||||
|  | 
 | ||||||
|  |       RJLog.Log( "Copying Texture From", viewport.Size, viewPortImageFormat, rdFormat, "Bytes", bytes ); | ||||||
|  |       var texture = Create( context, viewport.Size, dataFormat ); | ||||||
|  |    | ||||||
|  |       texture.SetData( data ); | ||||||
|  |       return texture; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -0,0 +1,440 @@ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
|  | using Godot; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Text; | ||||||
|  | 
 | ||||||
|  | namespace Rokojori | ||||||
|  | {   | ||||||
|  |   public class RDTextureFormats | ||||||
|  |   { | ||||||
|  |     public enum PixelChannelEncoding | ||||||
|  |     { | ||||||
|  |       Unknown, | ||||||
|  | 
 | ||||||
|  |       uInt8, | ||||||
|  |       sInt8, | ||||||
|  |        | ||||||
|  |       uInt16, | ||||||
|  |       sInt16, | ||||||
|  |       sFloat16, | ||||||
|  |       uNorm16, | ||||||
|  |       sNorm16, | ||||||
|  |        | ||||||
|  |       uInt32, | ||||||
|  |       sInt32, | ||||||
|  |       sFloat32 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static readonly List<PixelChannelEncoding> bits8 = new List<PixelChannelEncoding>()  | ||||||
|  |     {  | ||||||
|  |       PixelChannelEncoding.uInt8, | ||||||
|  |       PixelChannelEncoding.sInt8 | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     public static readonly List<PixelChannelEncoding> bits32 = new List<PixelChannelEncoding>()  | ||||||
|  |     {  | ||||||
|  |       PixelChannelEncoding.uInt32, | ||||||
|  |       PixelChannelEncoding.sInt32, | ||||||
|  |       PixelChannelEncoding.sFloat32 | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     public static int NumBytesFor( PixelChannelEncoding encoding ) | ||||||
|  |     { | ||||||
|  |       if ( PixelChannelEncoding.Unknown == encoding ) | ||||||
|  |       { | ||||||
|  |         return -1; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ( bits8.Contains( encoding ) ) | ||||||
|  |       { | ||||||
|  |         return 1; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ( bits32.Contains( encoding ) ) | ||||||
|  |       { | ||||||
|  |         return 4; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return 2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static string UsageInfo( RenderingDevice.TextureUsageBits bits ) | ||||||
|  |     { | ||||||
|  |       var enums = Enum.GetValues<RenderingDevice.TextureUsageBits>(); | ||||||
|  | 
 | ||||||
|  |       var sb = new StringBuilder(); | ||||||
|  |       var first = true; | ||||||
|  | 
 | ||||||
|  |       Array.ForEach( enums,  | ||||||
|  |         e =>  | ||||||
|  |         { | ||||||
|  |           if ( ! BitMath.IsMaskSet( (long)bits, (long)e ) ) | ||||||
|  |           { | ||||||
|  |             return; | ||||||
|  |           }  | ||||||
|  | 
 | ||||||
|  |           if ( first ){ first = false; } | ||||||
|  |           else { sb.Append( ", " ); } | ||||||
|  | 
 | ||||||
|  |           sb.Append( e + "" ); | ||||||
|  |            | ||||||
|  |         } | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |       return sb.ToString(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public const RenderingDevice.TextureUsageBits Usage_Default =  | ||||||
|  |                     RenderingDevice.TextureUsageBits.SamplingBit | | ||||||
|  |                     RenderingDevice.TextureUsageBits.StorageBit | | ||||||
|  |                     RenderingDevice.TextureUsageBits.CpuReadBit | | ||||||
|  |                     RenderingDevice.TextureUsageBits.CanUpdateBit | | ||||||
|  |                     RenderingDevice.TextureUsageBits.CanCopyFromBit | | ||||||
|  |                     RenderingDevice.TextureUsageBits.CanCopyToBit;                     | ||||||
|  |     | ||||||
|  | 
 | ||||||
|  |     public static RDTextureFormat DefaultFormat( int w, int h,  RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Unorm ) | ||||||
|  |     { | ||||||
|  |       var format = new RDTextureFormat(); | ||||||
|  | 
 | ||||||
|  |       format.Width  = (uint) w; | ||||||
|  |       format.Height = (uint) h; | ||||||
|  |       format.Format = dataFormat; | ||||||
|  |       format.UsageBits = Usage_Default; | ||||||
|  | 
 | ||||||
|  |       return format; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static RDTextureFormat FormatChangeSize( RDTextureFormat tf, Vector2I size ) | ||||||
|  |     { | ||||||
|  |       return FormatChangeSize( tf, size.X, size.Y ); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public static RDTextureFormat FormatChangeSize( RDTextureFormat tf, int w, int h ) | ||||||
|  |     { | ||||||
|  |       var clone = FormatCopy( tf ); | ||||||
|  |       clone.Width = (uint) w; | ||||||
|  |       clone.Height = (uint) h; | ||||||
|  |       return clone; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static int GetNumPixels( SubViewport viewport ) | ||||||
|  |     { | ||||||
|  |       return viewport.Size.X * viewport.Size.Y; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static int GetNumBytes( SubViewport viewport ) | ||||||
|  |     { | ||||||
|  |       var numChannels = viewport.TransparentBg ? 4 : 3; | ||||||
|  |       var encoding = viewport.UseHdr2D ? 2 : 1; | ||||||
|  | 
 | ||||||
|  |       return GetNumPixels( viewport ) * numChannels * encoding; | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |     public static RenderingDevice.DataFormat GetDataFormat( Viewport viewport ) | ||||||
|  |     { | ||||||
|  |       var imageFormat = viewport.GetTexture().GetImage().GetFormat(); | ||||||
|  |       return ImageFormatToDataFormat( imageFormat ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static RDTextureFormat FormatCopy( RDTextureFormat tf ) | ||||||
|  |     { | ||||||
|  |       var format = new RDTextureFormat(); | ||||||
|  | 
 | ||||||
|  |       format.Format = tf.Format; | ||||||
|  | 
 | ||||||
|  |       format.Width  = tf.Width; | ||||||
|  |       format.Height = tf.Height; | ||||||
|  |       format.Depth = tf.Depth; | ||||||
|  | 
 | ||||||
|  |       format.ArrayLayers = tf.ArrayLayers; | ||||||
|  |       format.Mipmaps = tf.Mipmaps; | ||||||
|  |       format.TextureType = tf.TextureType; | ||||||
|  |       format.Samples = tf.Samples;       | ||||||
|  |       format.UsageBits = tf.UsageBits; | ||||||
|  |       format.IsResolveBuffer = tf.IsResolveBuffer; | ||||||
|  |       format.IsDiscardable = tf.IsDiscardable; | ||||||
|  | 
 | ||||||
|  |       return tf; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static RenderingDevice.DataFormat DataFormat( int channels, PixelChannelEncoding encoding ) | ||||||
|  |     { | ||||||
|  |       if ( 1 == channels ) | ||||||
|  |       { | ||||||
|  |         return DataFormat_1Channel( encoding ); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ( 2 == channels ) | ||||||
|  |       { | ||||||
|  |         return DataFormat_2Channels( encoding ); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ( 3 == channels ) | ||||||
|  |       { | ||||||
|  |         return DataFormat_3Channels( encoding ); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if ( 4 == channels ) | ||||||
|  |       { | ||||||
|  |         return DataFormat_4Channels( encoding ); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return RenderingDevice.DataFormat.Max; | ||||||
|  |     }  | ||||||
|  | 
 | ||||||
|  |     public static RenderingDevice.DataFormat ImageFormatToDataFormat( Image.Format imageFormat ) | ||||||
|  |     { | ||||||
|  |       RJLog.Log( "ImageFormatToDataFormat", imageFormat ); | ||||||
|  | 
 | ||||||
|  |       switch ( imageFormat ) | ||||||
|  |       { | ||||||
|  |         case Image.Format.Rgb8: return RenderingDevice.DataFormat.R8G8B8Uint; | ||||||
|  |         case Image.Format.Rgba8: return RenderingDevice.DataFormat.R8G8B8A8Uint; | ||||||
|  |         case Image.Format.Rgbah: return RenderingDevice.DataFormat.R16G16B16A16Sfloat; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return RenderingDevice.DataFormat.Max; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static Image.Format DataFormatToImageFormat( RenderingDevice.DataFormat dataFormat ) | ||||||
|  |     { | ||||||
|  |       switch ( dataFormat  ) | ||||||
|  |       { | ||||||
|  |         case RenderingDevice.DataFormat.R8G8B8A8Uint: return Image.Format.Rgba8; | ||||||
|  |         case RenderingDevice.DataFormat.R8G8B8Uint: return Image.Format.Rgb8;   | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Sfloat: return Image.Format.Rgbah;   | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return Image.Format.Max; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static RenderingDevice.DataFormat DataFormat_1Channel( PixelChannelEncoding encoding ) | ||||||
|  |     {       | ||||||
|  |       switch ( encoding ) | ||||||
|  |       { | ||||||
|  |         case PixelChannelEncoding.uInt8: return RenderingDevice.DataFormat.R8Uint; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return RenderingDevice.DataFormat.Max; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static RenderingDevice.DataFormat DataFormat_2Channels( PixelChannelEncoding encoding ) | ||||||
|  |     {       | ||||||
|  |       switch ( encoding ) | ||||||
|  |       { | ||||||
|  |         case PixelChannelEncoding.uInt8: return RenderingDevice.DataFormat.R8Uint; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return RenderingDevice.DataFormat.Max; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static RenderingDevice.DataFormat DataFormat_3Channels( PixelChannelEncoding encoding ) | ||||||
|  |     {       | ||||||
|  |       switch ( encoding ) | ||||||
|  |       { | ||||||
|  |         case PixelChannelEncoding.uInt8: return RenderingDevice.DataFormat.R8G8B8Uint; | ||||||
|  |         case PixelChannelEncoding.sInt8: return RenderingDevice.DataFormat.R8G8B8Sint; | ||||||
|  | 
 | ||||||
|  |         case PixelChannelEncoding.uInt16: return RenderingDevice.DataFormat.R16G16B16Uint; | ||||||
|  |         case PixelChannelEncoding.sInt16: return RenderingDevice.DataFormat.R16G16B16Sint; | ||||||
|  |         case PixelChannelEncoding.sFloat16: return RenderingDevice.DataFormat.R16G16B16Sfloat; | ||||||
|  |         case PixelChannelEncoding.uNorm16: return RenderingDevice.DataFormat.R16G16B16Unorm; | ||||||
|  |         case PixelChannelEncoding.sNorm16: return RenderingDevice.DataFormat.R16G16B16Snorm; | ||||||
|  | 
 | ||||||
|  |         case PixelChannelEncoding.uInt32: return RenderingDevice.DataFormat.R32G32B32Uint; | ||||||
|  |         case PixelChannelEncoding.sInt32: return RenderingDevice.DataFormat.R32G32B32Sint; | ||||||
|  |         case PixelChannelEncoding.sFloat32: return RenderingDevice.DataFormat.R32G32B32Sfloat; | ||||||
|  |          | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return RenderingDevice.DataFormat.Max; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | 
 | ||||||
|  |     | ||||||
|  | 
 | ||||||
|  |     public static RenderingDevice.DataFormat DataFormat_4Channels( PixelChannelEncoding encoding ) | ||||||
|  |     {       | ||||||
|  |       switch ( encoding ) | ||||||
|  |       { | ||||||
|  |          | ||||||
|  |         case PixelChannelEncoding.uInt8: return RenderingDevice.DataFormat.R8G8B8A8Uint; | ||||||
|  |         case PixelChannelEncoding.sInt8: return RenderingDevice.DataFormat.R8G8B8A8Sint; | ||||||
|  | 
 | ||||||
|  |         case PixelChannelEncoding.uInt16: return RenderingDevice.DataFormat.R16G16B16A16Uint; | ||||||
|  |         case PixelChannelEncoding.sInt16: return RenderingDevice.DataFormat.R16G16B16A16Sint; | ||||||
|  |         case PixelChannelEncoding.sFloat16: return RenderingDevice.DataFormat.R16G16B16A16Sfloat; | ||||||
|  |         case PixelChannelEncoding.uNorm16: return RenderingDevice.DataFormat.R16G16B16A16Unorm; | ||||||
|  |         case PixelChannelEncoding.sNorm16: return RenderingDevice.DataFormat.R16G16B16A16Snorm; | ||||||
|  | 
 | ||||||
|  |         case PixelChannelEncoding.uInt32: return RenderingDevice.DataFormat.R32G32B32A32Uint; | ||||||
|  |         case PixelChannelEncoding.sInt32: return RenderingDevice.DataFormat.R32G32B32A32Sint; | ||||||
|  |         case PixelChannelEncoding.sFloat32: return RenderingDevice.DataFormat.R32G32B32A32Sfloat; | ||||||
|  |          | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return RenderingDevice.DataFormat.Max; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // m: case ((?:\w|\.)*): return ((?:\w|\.)*); | ||||||
|  |     // r: case $2: return $1; | ||||||
|  | 
 | ||||||
|  |     public static PixelChannelEncoding GetPixelChannelEncoding( RenderingDevice.DataFormat format ) | ||||||
|  |     { | ||||||
|  |       switch ( format ) | ||||||
|  |       { | ||||||
|  |         case RenderingDevice.DataFormat.R8G8B8Sint: return PixelChannelEncoding.sInt8; | ||||||
|  | 
 | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16Uint: return PixelChannelEncoding.uInt16; | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16Sint: return PixelChannelEncoding.sInt16; | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16Sfloat: return PixelChannelEncoding.sFloat16; | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16Unorm: return PixelChannelEncoding.uNorm16; | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16Snorm: return PixelChannelEncoding.sNorm16; | ||||||
|  | 
 | ||||||
|  |         case RenderingDevice.DataFormat.R32G32B32Uint: return PixelChannelEncoding.uInt32; | ||||||
|  |         case RenderingDevice.DataFormat.R32G32B32Sint: return PixelChannelEncoding.sInt32; | ||||||
|  |         case RenderingDevice.DataFormat.R32G32B32Sfloat: return PixelChannelEncoding.sFloat32; | ||||||
|  | 
 | ||||||
|  |         case RenderingDevice.DataFormat.R8G8B8A8Uint: return PixelChannelEncoding.uInt8; | ||||||
|  |         case RenderingDevice.DataFormat.R8G8B8A8Sint: return PixelChannelEncoding.sInt8; | ||||||
|  | 
 | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Uint: return PixelChannelEncoding.uInt16; | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Sint: return PixelChannelEncoding.sInt16; | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Sfloat: return PixelChannelEncoding.sFloat16; | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Unorm: return PixelChannelEncoding.uNorm16; | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Snorm: return PixelChannelEncoding.sNorm16; | ||||||
|  | 
 | ||||||
|  |         case RenderingDevice.DataFormat.R32G32B32A32Uint: return PixelChannelEncoding.uInt32; | ||||||
|  |         case RenderingDevice.DataFormat.R32G32B32A32Sint: return PixelChannelEncoding.sInt32; | ||||||
|  |         case RenderingDevice.DataFormat.R32G32B32A32Sfloat: return PixelChannelEncoding.sFloat32; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return PixelChannelEncoding.Unknown; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static int GetNumChannels( RenderingDevice.DataFormat format ) | ||||||
|  |     { | ||||||
|  |       switch ( format ) | ||||||
|  |       { | ||||||
|  |         case RenderingDevice.DataFormat.R8G8B8Sint:  | ||||||
|  | 
 | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16Uint:  | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16Sint:  | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16Sfloat:  | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16Unorm: | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16Snorm: | ||||||
|  | 
 | ||||||
|  |         case RenderingDevice.DataFormat.R32G32B32Uint:  | ||||||
|  |         case RenderingDevice.DataFormat.R32G32B32Sint:  | ||||||
|  |         case RenderingDevice.DataFormat.R32G32B32Sfloat: | ||||||
|  |          | ||||||
|  |          return 3; | ||||||
|  | 
 | ||||||
|  |         case RenderingDevice.DataFormat.R8G8B8A8Uint: | ||||||
|  |         case RenderingDevice.DataFormat.R8G8B8A8Sint: | ||||||
|  | 
 | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Uint: | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Sint:  | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Sfloat:  | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Unorm: | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Snorm:  | ||||||
|  | 
 | ||||||
|  |         case RenderingDevice.DataFormat.R32G32B32A32Uint: | ||||||
|  |         case RenderingDevice.DataFormat.R32G32B32A32Sint:  | ||||||
|  |         case RenderingDevice.DataFormat.R32G32B32A32Sfloat: | ||||||
|  |           return 4; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static void WriteUShort( ushort shortValue, byte[] output, int offset ) | ||||||
|  |     { | ||||||
|  |       output[ offset + 0 ] = (byte)(shortValue & 0xFF);  | ||||||
|  |       output[ offset + 1 ] = (byte)((shortValue >> 8) & 0xFF);  | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static void WriteUNorm( float value, byte[] output, int offset ) | ||||||
|  |     { | ||||||
|  |       var shortValue = (ushort)( Mathf.Clamp( value, 0.0f, 1.0f ) * 65535 ); | ||||||
|  |       WriteUShort( shortValue, output, offset ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static ushort FloatToHalf( float value ) | ||||||
|  |     { | ||||||
|  |       uint fbits = BitConverter.SingleToUInt32Bits(value); | ||||||
|  | 
 | ||||||
|  |       uint sign = (fbits >> 16) & 0x8000; | ||||||
|  |       uint val  = (fbits & 0x7FFFFFFF); | ||||||
|  | 
 | ||||||
|  |       // NaN / Inf -> maximal darstellen | ||||||
|  |       if ( val > 0x47FFEFFF ) | ||||||
|  |       { | ||||||
|  |         return (ushort)(sign | 0x7FFF);  | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |       if ( val < 0x38800000)  // Subnormal | ||||||
|  |       { | ||||||
|  |         uint mant = (val & 0x007FFFFF) | 0x00800000; | ||||||
|  |         int exp = 113 - (int)(val >> 23); | ||||||
|  |         mant = (mant >> exp); | ||||||
|  | 
 | ||||||
|  |         return (ushort)(sign | (mant >> 13)); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |         uint exp = (val >> 23) - 112; | ||||||
|  |         uint mant = (val & 0x007FFFFF);           | ||||||
|  |         return (ushort)(sign | (exp << 10) | (mant >> 13)); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static void WriteFloat16( float value, byte[] output, int offset ) | ||||||
|  |     { | ||||||
|  |       ushort r = FloatToHalf( value ); | ||||||
|  |       WriteUShort( r, output, offset ); | ||||||
|  |     }  | ||||||
|  |      | ||||||
|  |     public static byte[] ColorToBytes( Color color, RenderingDevice.DataFormat format ) | ||||||
|  |     { | ||||||
|  |       switch ( format ) | ||||||
|  |       { | ||||||
|  |         case RenderingDevice.DataFormat.R8G8B8A8Uint: | ||||||
|  |         { | ||||||
|  |           var bytes = new byte[ 4 ]; | ||||||
|  |           bytes[ 0 ] = (byte) ( color.R * 255 );  | ||||||
|  |           bytes[ 1 ] = (byte) ( color.G * 255 );  | ||||||
|  |           bytes[ 2 ] = (byte) ( color.B * 255 );  | ||||||
|  |           bytes[ 3 ] = (byte) ( color.A * 255 );  | ||||||
|  |           return bytes; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Unorm: | ||||||
|  |         { | ||||||
|  |           var bytes = new byte[ 8 ]; | ||||||
|  |           WriteUNorm( color.R, bytes, 0 ); | ||||||
|  |           WriteUNorm( color.G, bytes, 2 ); | ||||||
|  |           WriteUNorm( color.B, bytes, 4 ); | ||||||
|  |           WriteUNorm( color.A, bytes, 6 ); | ||||||
|  |           return bytes; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         case RenderingDevice.DataFormat.R16G16B16A16Sfloat: | ||||||
|  |         { | ||||||
|  |           var bytes = new byte[ 8 ]; | ||||||
|  |           WriteFloat16( color.R, bytes, 0 ); | ||||||
|  |           WriteFloat16( color.G, bytes, 2 ); | ||||||
|  |           WriteFloat16( color.B, bytes, 4 ); | ||||||
|  |           WriteFloat16( color.A, bytes, 6 ); | ||||||
|  |           return bytes; | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return null; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | uid://bwinqvkypbchr | ||||||
|  | @ -21,8 +21,9 @@ namespace Rokojori | ||||||
|       uniform.Binding = 0; |       uniform.Binding = 0; | ||||||
|       uniform.AddId( texture.rid ); |       uniform.AddId( texture.rid ); | ||||||
| 
 | 
 | ||||||
|       var rd = context.renderingDevice; | 
 | ||||||
|       var rid = UniformSetCacheRD.GetCache( context.shader.rid, (uint) setIndex, new Array<RDUniform> { uniform } ); |       var rid = context._CreateUniformSetRid( setIndex, uniform ); | ||||||
|  |       // UniformSetCacheRD.GetCache( context.shader.rid, (uint) setIndex, new Array<RDUniform> { uniform } ); | ||||||
|       // var rid = rd.UniformSetCreate( new Array<RDUniform>{ uniform }, effect.context.shader.rid, (uint) setIndex ); |       // var rid = rd.UniformSetCreate( new Array<RDUniform>{ uniform }, effect.context.shader.rid, (uint) setIndex ); | ||||||
| 
 | 
 | ||||||
|       return new RDUniformSet( context, setIndex, rid ); |       return new RDUniformSet( context, setIndex, rid ); | ||||||
|  | @ -35,10 +36,9 @@ namespace Rokojori | ||||||
|       uniform.Binding = 0; |       uniform.Binding = 0; | ||||||
|       uniform.AddId( sampler.rid ); |       uniform.AddId( sampler.rid ); | ||||||
|       uniform.AddId( texture.rid ) ; |       uniform.AddId( texture.rid ) ; | ||||||
| 
 |  | ||||||
|       var rd = context.renderingDevice; |  | ||||||
|        |        | ||||||
|       var rid = UniformSetCacheRD.GetCache( context.shader.rid, (uint) setIndex, new Array<RDUniform>{ uniform } ); |       // var rid = UniformSetCacheRD.GetCache( context.shader.rid, (uint) setIndex, new Array<RDUniform>{ uniform } ); | ||||||
|  |       var rid = context._CreateUniformSetRid( setIndex, uniform ); | ||||||
|       // var rid = rd.UniformSetCreate( new Array<RDUniform>{ uniform }, effect.context.shader.rid, (uint) setIndex ); |       // var rid = rd.UniformSetCreate( new Array<RDUniform>{ uniform }, effect.context.shader.rid, (uint) setIndex ); | ||||||
| 
 | 
 | ||||||
|       return new RDUniformSet( context, setIndex, rid ); |       return new RDUniformSet( context, setIndex, rid ); | ||||||
|  |  | ||||||
|  | @ -17,6 +17,10 @@ namespace Rokojori | ||||||
|     { |     { | ||||||
|       this._context = context; |       this._context = context; | ||||||
|       this._rid = rid; |       this._rid = rid; | ||||||
|  | 
 | ||||||
|  |       this._context.AddToCleanUp( this, GetType().Name + "@" + _rid ); | ||||||
|  | 
 | ||||||
|  |       context.Verbose( "Creating", GetType().Name, rid ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,93 @@ | ||||||
|  | #[compute] | ||||||
|  | #version 450 | ||||||
|  | 
 | ||||||
|  | layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in; | ||||||
|  | 
 | ||||||
|  | layout( rgba16f, set = 0, binding = 0 )  | ||||||
|  | uniform image2D inputImage; | ||||||
|  | 
 | ||||||
|  | layout( rgba16f, set = 1, binding = 0 )  | ||||||
|  | uniform image2D outputImage; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void main( )   | ||||||
|  | { | ||||||
|  |   float treshold = 0.5; | ||||||
|  |   | ||||||
|  |   ivec2 size = imageSize( inputImage ); | ||||||
|  |   ivec2 texelCoord = ivec2( gl_GlobalInvocationID.xy ); | ||||||
|  |    | ||||||
|  |   if ( any( greaterThanEqual( texelCoord, size ) )  )  | ||||||
|  |   { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   | ||||||
|  |   vec4 color = imageLoad( inputImage, texelCoord ); | ||||||
|  | 
 | ||||||
|  |   // color = vec4( 1.0, 0.0, 0.0, 0.0 ); | ||||||
|  |    | ||||||
|  |   if ( color.a >= treshold ) | ||||||
|  |   { | ||||||
|  |     imageStore( outputImage, texelCoord, color ); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   // else | ||||||
|  |   // { | ||||||
|  |   //   imageStore( outputImage, texelCoord, vec4(1,1,1,1) ); | ||||||
|  |   //   return; | ||||||
|  |   // } | ||||||
|  | 
 | ||||||
|  |   // if ( color.a <= treshold ) | ||||||
|  |   // { | ||||||
|  |   //   color = vec4( 1.0, 0.5, color.a, 1.0 ); | ||||||
|  |   // } | ||||||
|  |   // else | ||||||
|  |   // { | ||||||
|  |   //   color = vec4( 0.0, 1.0, 0.0, 1.0 ); | ||||||
|  |   // } | ||||||
|  |    | ||||||
|  |   // imageStore( outputImage, texelCoord, color ); | ||||||
|  | 
 | ||||||
|  |   // imageStore( outputImage, texel_coord, vec4( color.a, color.a, color.a, 1.0 ) ); | ||||||
|  | 
 | ||||||
|  |   int kernelRadius = 16; | ||||||
|  | 
 | ||||||
|  |   float closestDistance = kernelRadius * kernelRadius * 2; | ||||||
|  |   vec4 closestColor = color; | ||||||
|  |    | ||||||
|  |   for ( int x = -kernelRadius; x <= kernelRadius; x++ ) | ||||||
|  |   { | ||||||
|  |     for ( int y = -kernelRadius; y <= kernelRadius; y++ ) | ||||||
|  |     { | ||||||
|  |       ivec2 offset = ivec2( x, y ); | ||||||
|  |       float d = length( vec2( offset ) ); | ||||||
|  | 
 | ||||||
|  |       if ( d >= closestDistance ) | ||||||
|  |       { | ||||||
|  |         continue; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       ivec2 t = texelCoord + ivec2( x, y ); | ||||||
|  | 
 | ||||||
|  |       if ( t.x < 0 || t.y < 0 || ( any( greaterThanEqual( texelCoord, size ) )  ) )  | ||||||
|  |       { | ||||||
|  |         continue; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       vec4 nColor = imageLoad( inputImage, t ); | ||||||
|  | 
 | ||||||
|  |       if ( nColor.a < treshold ) | ||||||
|  |       { | ||||||
|  |         continue;  | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       closestDistance = d; | ||||||
|  |       closestColor = nColor; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   imageStore( outputImage, texelCoord, vec4( closestColor.rgb, color.a ) ); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | [remap] | ||||||
|  | 
 | ||||||
|  | importer="glsl" | ||||||
|  | type="RDShaderFile" | ||||||
|  | uid="uid://byc7b6xlw0fnj" | ||||||
|  | path="res://.godot/imported/AlphaColorDilation.glsl-7665d7fc960d5dbc00617ba2dd53045f.res" | ||||||
|  | 
 | ||||||
|  | [deps] | ||||||
|  | 
 | ||||||
|  | source_file="res://addons/rokojori_action_library/Runtime/Rendering/RenderGraph/Nodes/Processors/Color/AlphaColorDilation/AlphaColorDilation.glsl" | ||||||
|  | dest_files=["res://.godot/imported/AlphaColorDilation.glsl-7665d7fc960d5dbc00617ba2dd53045f.res"] | ||||||
|  | 
 | ||||||
|  | [params] | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,17 @@ | ||||||
|  | 
 | ||||||
|  | using Godot; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | 
 | ||||||
|  | namespace Rokojori | ||||||
|  | {   | ||||||
|  |   public class CEG_AlphaColorDilation:CEG_ImageProcessor | ||||||
|  |   { | ||||||
|  |     public static readonly string shaderPath =  | ||||||
|  |       RDGraph.Path( "Nodes/Processors/Color/AlphaColorDilation/AlphaColorDilation.glsl" ); | ||||||
|  | 
 | ||||||
|  |     public CEG_AlphaColorDilation( RDGraph graph ):base( graph, shaderPath ) | ||||||
|  |     {}  | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | uid://daimt0g1aluu4 | ||||||
|  | @ -12,12 +12,12 @@ uniform image2D outputImage; | ||||||
| layout( push_constant, std430 )  | layout( push_constant, std430 )  | ||||||
| uniform Params  | uniform Params  | ||||||
| { | { | ||||||
|   float amount; |  | ||||||
|   float shiftAll; |  | ||||||
|   float unshiftCenter; |  | ||||||
|   vec2 rShift; |   vec2 rShift; | ||||||
|   vec2 gShift; |   vec2 gShift; | ||||||
|   vec2 bShift; |   vec2 bShift; | ||||||
|  |   float amount; | ||||||
|  |   float shiftAll; | ||||||
|  |   float unshiftCenter; | ||||||
| 
 | 
 | ||||||
| } params; | } params; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,8 +11,15 @@ uniform restrict writeonly image2D outputImage; | ||||||
| 
 | 
 | ||||||
| void main()  | void main()  | ||||||
| { | { | ||||||
|  |   ivec2 imgSize = imageSize( inputImage ); | ||||||
| 	ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy ); | 	ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy ); | ||||||
| 	vec4 currentPixel = imageLoad( inputImage, currentPosition ); | 
 | ||||||
|    |   if ( any( greaterThanEqual( currentPosition, imgSize ) )  )  | ||||||
|  |   { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 	vec4 currentPixel = imageLoad( inputImage, currentPosition );  | ||||||
|  | 
 | ||||||
| 	imageStore( outputImage, currentPosition, currentPixel ); | 	imageStore( outputImage, currentPosition, currentPixel ); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ namespace Rokojori | ||||||
|       if ( texture == null || scaledSize != texture.size ) |       if ( texture == null || scaledSize != texture.size ) | ||||||
|       { |       { | ||||||
|         AutoClean( texture, graph.context.renderingDevice ); |         AutoClean( texture, graph.context.renderingDevice ); | ||||||
|         format = RDTexture.FormatChangeSize( format, scaledSize ); |         format = RDTextureFormats.FormatChangeSize( format, scaledSize ); | ||||||
|         texture = RDTexture.Create( graph.context, format ); |         texture = RDTexture.Create( graph.context, format ); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|  | @ -63,6 +63,20 @@ namespace Rokojori | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   public class CEG_TextureCreator_Reference:CEG_TextureCreator | ||||||
|  |   { | ||||||
|  |     public RDTexture _texture; | ||||||
|  |      | ||||||
|  |     public CEG_TextureCreator_Reference( RDTexture texture ) | ||||||
|  |     { | ||||||
|  |       this._texture = texture; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public override RDTexture Create( RDTexture texture, RDGraph graph ) | ||||||
|  |     { | ||||||
|  |       return _texture; | ||||||
|  |     } | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|   public class CEG_BufferTexture:RGGraphProcessor, RDGraphTextureSlotInput |   public class CEG_BufferTexture:RGGraphProcessor, RDGraphTextureSlotInput | ||||||
|  | @ -106,6 +120,20 @@ namespace Rokojori | ||||||
|       return new CEG_BufferTexture( graph, new CEG_TextureCreator_FixedSize() ); |       return new CEG_BufferTexture( graph, new CEG_TextureCreator_FixedSize() ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static CEG_BufferTexture FixedSize( RDGraph graph, Vector2I size ) | ||||||
|  |     { | ||||||
|  |       var creator = new CEG_TextureCreator_FixedSize(); | ||||||
|  |       creator.format.Width = (uint) size.X; | ||||||
|  |       creator.format.Height = (uint) size.Y; | ||||||
|  |       return new CEG_BufferTexture( graph, creator ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static CEG_BufferTexture From( RDGraph graph, RDTexture texture ) | ||||||
|  |     { | ||||||
|  |       var creator = new CEG_TextureCreator_Reference( texture ); | ||||||
|  |       return new CEG_BufferTexture( graph, creator ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public override void Process() |     public override void Process() | ||||||
|     { |     { | ||||||
|       _texture = _creator.Create( _texture, graph ); |       _texture = _creator.Create( _texture, graph ); | ||||||
|  |  | ||||||
|  | @ -0,0 +1,17 @@ | ||||||
|  | 
 | ||||||
|  | using Godot; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | 
 | ||||||
|  | namespace Rokojori | ||||||
|  | {   | ||||||
|  |   public class CEG_JFAAssign:CEG_ImageProcessor | ||||||
|  |   { | ||||||
|  |     public static readonly string shaderPath =  | ||||||
|  |       RDGraph.Path( "Nodes/Processors/JFA/JFA_Assign.glsl" ); | ||||||
|  | 
 | ||||||
|  |     public CEG_JFAAssign( RDGraph graph ):base( graph, shaderPath ) | ||||||
|  |     {}  | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,24 @@ | ||||||
|  | #[compute] | ||||||
|  | #version 450 | ||||||
|  | 
 | ||||||
|  | layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in; | ||||||
|  | 
 | ||||||
|  | layout( rgba16, set = 0, binding = 0 )  | ||||||
|  | uniform restrict readonly image2D inputImage; | ||||||
|  | 
 | ||||||
|  | layout( rgba16, set = 1, binding = 0 )  | ||||||
|  | uniform restrict readonly image2D originalImage; | ||||||
|  | 
 | ||||||
|  | layout( rgba16, set = 2, binding = 0 )  | ||||||
|  | uniform restrict writeonly image2D outputImage; | ||||||
|  | 
 | ||||||
|  | void main()  | ||||||
|  | { | ||||||
|  | 	ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy ); | ||||||
|  | 	vec4 currentPixel = imageLoad( inputImage, currentPosition ); | ||||||
|  | 	ivec2 seedPosition = ivec2( packUnorm2x16( currentPixel.xy ), packUnorm2x16( currentPixel.zw ) ); | ||||||
|  | 
 | ||||||
|  | 	vec4 originalPixel = imageLoad( originalImage, seedPosition ); | ||||||
|  | 
 | ||||||
|  | 	imageStore(outputImage, currentPosition, vec4(originalPixel.xyz, originalPixel.a)); | ||||||
|  | } | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | [remap] | ||||||
|  | 
 | ||||||
|  | importer="glsl" | ||||||
|  | type="RDShaderFile" | ||||||
|  | uid="uid://1ovj3jsq1vp6" | ||||||
|  | path="res://.godot/imported/JFA_Assign.glsl-fb7dfb3a0e8b719d928d34ea126deab2.res" | ||||||
|  | 
 | ||||||
|  | [deps] | ||||||
|  | 
 | ||||||
|  | source_file="res://addons/rokojori_action_library/Runtime/Rendering/RenderGraph/Nodes/Processors/JFA/JFA_Assign.glsl" | ||||||
|  | dest_files=["res://.godot/imported/JFA_Assign.glsl-fb7dfb3a0e8b719d928d34ea126deab2.res"] | ||||||
|  | 
 | ||||||
|  | [params] | ||||||
|  | 
 | ||||||
|  | @ -10,18 +10,18 @@ layout( rgba16, set = 1, binding = 0 ) | ||||||
| uniform restrict writeonly image2D outputImage; | uniform restrict writeonly image2D outputImage; | ||||||
| 
 | 
 | ||||||
| layout( push_constant, std430 )  | layout( push_constant, std430 )  | ||||||
| uniform Params  | uniform Parameters  | ||||||
| { | { | ||||||
|   float alphaTreshold; |   float alphaTreshold; | ||||||
| 
 | 
 | ||||||
| } params; | } parameters; | ||||||
| 
 | 
 | ||||||
| void main()  | void main()  | ||||||
| { | { | ||||||
| 	ivec2 currentPosition  = ivec2( gl_GlobalInvocationID.xy ); | 	ivec2 currentPosition  = ivec2( gl_GlobalInvocationID.xy ); | ||||||
| 	vec4 currentPixel = imageLoad( inputImage, currentPosition ); | 	vec4 currentPixel = imageLoad( inputImage, currentPosition ); | ||||||
| 
 | 
 | ||||||
| 	if ( currentPixel.a < params.alphaTreshold )  | 	if ( currentPixel.a < parameters.alphaTreshold )  | ||||||
|   { |   { | ||||||
| 		vec4 packedZero = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) ); | 		vec4 packedZero = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) ); | ||||||
| 		imageStore( outputImage, currentPosition, packedZero ); | 		imageStore( outputImage, currentPosition, packedZero ); | ||||||
|  |  | ||||||
|  | @ -10,7 +10,11 @@ layout(rgba16, set = 1, binding = 0) | ||||||
| uniform restrict writeonly image2D outputImage; | uniform restrict writeonly image2D outputImage; | ||||||
| 
 | 
 | ||||||
| layout(std430, set = 2, binding = 0)  | layout(std430, set = 2, binding = 0)  | ||||||
| buffer restrict readonly JumpDistanceBuffer { int jump; } jdb; | buffer restrict readonly DistanceParameters  | ||||||
|  | {  | ||||||
|  |   int jump;  | ||||||
|  |    | ||||||
|  | } distanceParameters; | ||||||
| 
 | 
 | ||||||
| void main()  | void main()  | ||||||
| { | { | ||||||
|  | @ -20,7 +24,7 @@ void main() | ||||||
| 	float distanceToClosestSeed = 1.0f / 0.0f; | 	float distanceToClosestSeed = 1.0f / 0.0f; | ||||||
| 	vec4 closestSeed = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) ); | 	vec4 closestSeed = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) ); | ||||||
| 
 | 
 | ||||||
|   ivec2 jdbJump = ivec2( jdb.jump, jdb.jump ); |   ivec2 jump = ivec2( distanceParameters.jump, distanceParameters.jump ); | ||||||
| 
 | 
 | ||||||
| 	for ( int x = -1; x <= 1; x++ )  | 	for ( int x = -1; x <= 1; x++ )  | ||||||
|   { |   { | ||||||
|  | @ -28,7 +32,7 @@ void main() | ||||||
|     { |     { | ||||||
|       ivec2 xy = ivec2( x, y );  |       ivec2 xy = ivec2( x, y );  | ||||||
| 
 | 
 | ||||||
| 			ivec2 checkPosition = currentPosition + jdbJump * xy;  | 			ivec2 checkPosition = currentPosition + jump * xy;  | ||||||
| 
 | 
 | ||||||
| 			if ( checkPosition.x < 0 || checkPosition.y < 0 ||  | 			if ( checkPosition.x < 0 || checkPosition.y < 0 ||  | ||||||
|            checkPosition.x >= imageSize.x || checkPosition.y >= imageSize.y )  |            checkPosition.x >= imageSize.x || checkPosition.y >= imageSize.y )  | ||||||
|  |  | ||||||
|  | @ -62,7 +62,7 @@ namespace Rokojori | ||||||
|       var context = graph.context; |       var context = graph.context; | ||||||
| 
 | 
 | ||||||
|       context.Clear(); |       context.Clear(); | ||||||
|       context.CalculateComputeGroups( _groupSize ); |       context.CalculateSceneComputeGroups( _groupSize ); | ||||||
|       context.SetShaderAndPipeline( _shader, _pipeline ); |       context.SetShaderAndPipeline( _shader, _pipeline ); | ||||||
| 
 | 
 | ||||||
|       _textureSlots.ForEach( t =>  |       _textureSlots.ForEach( t =>  | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ namespace Rokojori | ||||||
| 
 | 
 | ||||||
|   public static class Lists |   public static class Lists | ||||||
|   { |   { | ||||||
|  | 
 | ||||||
|     public static bool IsOneOf<T>( T value, params T[] values ) |     public static bool IsOneOf<T>( T value, params T[] values ) | ||||||
|     { |     { | ||||||
|       for ( int i = 0; i < values.Length; i++ ) |       for ( int i = 0; i < values.Length; i++ ) | ||||||
|  | @ -237,6 +238,18 @@ namespace Rokojori | ||||||
|     public static List<T> From<T>( params T[] elements ) |     public static List<T> From<T>( params T[] elements ) | ||||||
|     { |     { | ||||||
|       return ToList( elements ); |       return ToList( elements ); | ||||||
|  |     }  | ||||||
|  | 
 | ||||||
|  |     public static List<T> SubList<T>( T[] elements, int offset, int length ) | ||||||
|  |     { | ||||||
|  |       var list = new List<T>(); | ||||||
|  | 
 | ||||||
|  |       for ( int i = 0; i < length; i++ ) | ||||||
|  |       { | ||||||
|  |         list.Add( elements[ i + offset ] ); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return list; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static List<T> ToList<T>( T[] array ) |     public static List<T> ToList<T>( T[] array ) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Josef
						Josef