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
|
|
|
}
|
|
|
|
}
|