164 lines
3.8 KiB
C#
164 lines
3.8 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Godot;
|
|
using System;
|
|
|
|
|
|
|
|
namespace Rokojori
|
|
{
|
|
public class TextureCombinerBuffer
|
|
{
|
|
int _width;
|
|
public int width => _width;
|
|
|
|
int _height;
|
|
public int height => _height;
|
|
|
|
Color[] _pixels;
|
|
|
|
public static TextureCombinerBuffer Create( int w, int h )
|
|
{
|
|
var tb = new TextureCombinerBuffer();
|
|
tb._height = h;
|
|
tb._width = w;
|
|
tb._pixels = new Color[ w * h ];
|
|
|
|
return tb;
|
|
}
|
|
|
|
public static TextureCombinerBuffer From( Texture2D texture )
|
|
{
|
|
var buffer = Create( texture.GetWidth(), texture.GetHeight() );
|
|
buffer.CopyFrom( texture.GetImage(), 0, 0, 0, 0, texture.GetWidth(), texture.GetHeight() );
|
|
|
|
return buffer;
|
|
}
|
|
|
|
public TextureCombinerBuffer Resize( int w, int h )
|
|
{
|
|
var buffer = Create( w, h );
|
|
|
|
for ( int i = 0; i < w; i++ )
|
|
{
|
|
for ( int j = 0; j < h; j++ )
|
|
{
|
|
var uv = new Vector2( i / (float) w, j / (float) h );
|
|
var pixel = SampleBilinearUV( uv );
|
|
|
|
buffer.SetAt( i, j, pixel );
|
|
}
|
|
}
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
public void CopyFrom( Image image, int sourceX, int sourceY, int ownX, int ownY, int w, int h )
|
|
{
|
|
for ( int i = 0; i < w; i++ )
|
|
{
|
|
for ( int j = 0; j < h; j++ )
|
|
{
|
|
var sourcePixel = image.GetPixel( sourceX + i, sourceY + j );
|
|
|
|
SetAt( ownX + i, ownY + j, sourcePixel );
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public void CopyTo( int ownX, int ownY, int targetX, int targetY, int w, int h, TextureCombinerBuffer output )
|
|
{
|
|
for ( int i = 0; i < w; i++ )
|
|
{
|
|
for ( int j = 0; j < h; j++ )
|
|
{
|
|
var ownPixel = GetAt( ownX + i, ownY + j );
|
|
|
|
output.SetAt( targetX + i, targetY + j, ownPixel );
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public void CopyTo( int ownX, int ownY, int targetX, int targetY, int w, int h, Image image )
|
|
{
|
|
for ( int i = 0; i < w; i++ )
|
|
{
|
|
for ( int j = 0; j < h; j++ )
|
|
{
|
|
var ownPixel = GetAt( ownX + i, ownY + j );
|
|
image.SetPixel( targetX + i, targetY + j, ownPixel );
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public int ComputeIndexFromPosition( int x, int y )
|
|
{
|
|
return x + y * _width;
|
|
}
|
|
|
|
public void SetAt( int x, int y, Color value )
|
|
{
|
|
SetIndexed( ComputeIndexFromPosition( x, y ), value );
|
|
}
|
|
|
|
public void SetIndexed( int index, Color value )
|
|
{
|
|
_pixels[ index ] = value;
|
|
}
|
|
|
|
public Color GetAt( int x, int y )
|
|
{
|
|
return GetIndexed( ComputeIndexFromPosition( x, y ) );
|
|
}
|
|
|
|
public Color GetIndexed( int index )
|
|
{
|
|
return _pixels[ index ];
|
|
}
|
|
|
|
public Color SampleNearestUV( Vector2 uv )
|
|
{
|
|
return SampleNearestImage( uv.X * width, uv.Y * height );
|
|
}
|
|
|
|
public Color SampleNearestImage( float imageDimensionsX, float imageDimensionsY )
|
|
{
|
|
return GetAt( Mathf.RoundToInt( imageDimensionsX ), Mathf.RoundToInt( imageDimensionsY ) );
|
|
}
|
|
|
|
public Color SampleBilinearUV( Vector2 uv )
|
|
{
|
|
return SampleBilinearImage( uv.X * width, uv.Y * height );
|
|
}
|
|
|
|
public Color SampleBilinearImage( float imageDimensionsX, float imageDimensionsY )
|
|
{
|
|
var lowX = Mathf.FloorToInt( imageDimensionsX );
|
|
var highX = Mathf.Min( lowX + 1, width - 1 );
|
|
var lerpX = imageDimensionsX - lowX;
|
|
|
|
|
|
|
|
var lowY = Mathf.FloorToInt( imageDimensionsY );
|
|
var highY = Mathf.Min( lowY + 1, height - 1 );
|
|
var lerpY = imageDimensionsY - lowY;
|
|
|
|
|
|
var ll = GetAt( lowX, lowY );
|
|
var hl = GetAt( highX, lowY );
|
|
|
|
var lh = GetAt( lowX, highY );
|
|
var hh = GetAt( highX, highY );
|
|
|
|
var upper = ll.Lerp( hl, lerpX );
|
|
var lower = lh.Lerp( hh, lerpX );
|
|
|
|
return upper.Lerp( lower, lerpY );
|
|
}
|
|
}
|
|
} |