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

242 lines
7.2 KiB
C#

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