rj-action-library/Runtime/Rendering/Objects/RDTexture.cs

242 lines
7.2 KiB
C#
Raw Normal View History

2025-04-23 12:00:43 +00:00
using Godot;
namespace Rokojori
{
public class RDTexture: RenderingObject
{
2025-04-26 20:04:11 +00:00
public RDTexture( RDContext context, Rid rid ):base( context, rid ){}
2025-04-23 12:00:43 +00:00
2025-04-26 20:04:11 +00:00
public static RDTexture Create( RDContext effect, RDTextureFormat format, RDTextureView view )
2025-04-23 12:00:43 +00:00
{
2025-04-26 20:04:11 +00:00
return new RDTexture( effect, effect.renderingDevice.TextureCreate( format, view ) );
2025-04-23 12:00:43 +00:00
}
2025-04-26 20:04:11 +00:00
public static RDTexture Color( RDContext context )
2025-04-23 12:00:43 +00:00
{
var rid = context.sceneBuffers.GetColorLayer( (uint) context.view );
2025-04-26 20:04:11 +00:00
return new RDTexture( context, rid );
2025-04-23 12:00:43 +00:00
}
2025-04-26 20:04:11 +00:00
public static RDTexture Depth( RDContext context )
2025-04-23 12:00:43 +00:00
{
var rid = context.sceneBuffers.GetDepthLayer( (uint) context.view );
2025-04-26 20:04:11 +00:00
return new RDTexture( context, rid );
2025-04-23 12:00:43 +00:00
}
2025-04-24 13:39:00 +00:00
2025-04-29 19:46:45 +00:00
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() );
}
2025-04-24 13:39:00 +00:00
public RDTextureFormat format
{
get
{
2025-04-26 20:04:11 +00:00
return context.renderingDevice.TextureGetFormat( rid );
2025-04-24 13:39:00 +00:00
}
}
public Vector2I size
{
get
{
var textureFormat = format;
return new Vector2I( (int) textureFormat.Width, (int) textureFormat.Height );
}
}
2025-04-26 20:04:11 +00:00
public static RDTexture EnsureScreenSizeTexture( RDTexture texture, RDContext context, bool cleanUp = true )
2025-04-25 08:13:22 +00:00
{
2025-04-26 20:04:11 +00:00
var size = context.internalSize;
2025-04-25 08:13:22 +00:00
if ( texture == null || texture.size != size )
{
if ( cleanUp && texture != null )
{
2025-04-26 20:04:11 +00:00
context.Free( texture, "Old Screen Size Texture" );
2025-04-25 08:13:22 +00:00
}
2025-04-26 20:04:11 +00:00
texture = Create( context, size );
2025-04-25 08:13:22 +00:00
}
return texture;
}
2025-04-26 20:04:11 +00:00
public static RDTexture Create( RDContext context, RDTextureFormat format )
2025-04-24 13:39:00 +00:00
{
var view = new RDTextureView();
2025-04-26 20:04:11 +00:00
var rid = context.renderingDevice.TextureCreate( format, view );
return new RDTexture( context, rid );
2025-04-24 13:39:00 +00:00
}
2025-04-29 19:46:45 +00:00
public static RDTextureFormat DefaultFormat( int w, int h, RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Sfloat)
2025-04-24 13:39:00 +00:00
{
var format = new RDTextureFormat();
format.Width = (uint) w;
format.Height = (uint) h;
format.Format = dataFormat;
2025-04-25 08:13:22 +00:00
format.UsageBits = RenderingDevice.TextureUsageBits.StorageBit |
RenderingDevice.TextureUsageBits.SamplingBit |
RenderingDevice.TextureUsageBits.CanCopyFromBit |
2025-04-29 19:46:45 +00:00
RenderingDevice.TextureUsageBits.CanUpdateBit |
RenderingDevice.TextureUsageBits.CanCopyToBit |
2025-04-25 08:13:22 +00:00
RenderingDevice.TextureUsageBits.CpuReadBit
;
2025-04-24 13:39:00 +00:00
return format;
}
2025-04-29 19:46:45 +00:00
public static RDTexture Create( RDContext context, Vector2I size, RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Sfloat )
2025-04-24 13:39:00 +00:00
{
2025-04-26 20:04:11 +00:00
return Create( context, size.X, size.Y, dataFormat );
2025-04-29 19:46:45 +00:00
}
2025-04-24 13:39:00 +00:00
2025-04-26 20:04:11 +00:00
public static RDTexture Create( RDContext context, int width, int height,
2025-04-29 19:46:45 +00:00
RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Sfloat,
RenderingDevice.TextureUsageBits textureUsageBits = RDTextureFormats.Usage_Default )
2025-04-24 13:39:00 +00:00
{
var view = new RDTextureView();
2025-04-29 19:46:45 +00:00
var format = RDTextureFormats.DefaultFormat( width, height, dataFormat );
format.UsageBits = textureUsageBits;
context.Verbose( "Format:", format, "DataFormat", dataFormat);
2025-04-24 13:39:00 +00:00
2025-04-26 20:04:11 +00:00
var rid = context.renderingDevice.TextureCreate( format, view );
return new RDTexture( context, rid );
2025-04-24 13:39:00 +00:00
}
2025-04-29 19:46:45 +00:00
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;
}
2025-04-23 12:00:43 +00:00
}
}