rj-action-library/Runtime/Procedural/Baking/GrabTextureRD.cs

120 lines
2.9 KiB
C#

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();
}
}
}