mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Fix some texture handling.
This commit is contained in:
parent
fe4955f8fc
commit
fabe2a9a16
3 changed files with 41 additions and 37 deletions
|
|
@ -91,11 +91,11 @@ public partial class CombinedTexture : IDisposable
|
|||
|
||||
var tex = type switch
|
||||
{
|
||||
TextureSaveType.AsIs => _current.Type is Texture.FileType.Bitmap or Texture.FileType.Png ? CreateUncompressed(s, mipMaps ) : s,
|
||||
TextureSaveType.AsIs => _current.Type is Texture.FileType.Bitmap or Texture.FileType.Png ? CreateUncompressed( s, mipMaps ) : s,
|
||||
TextureSaveType.Bitmap => CreateUncompressed( s, mipMaps ),
|
||||
TextureSaveType.BC5 => CreateCompressed( s, mipMaps, false ),
|
||||
TextureSaveType.BC7 => CreateCompressed( s, mipMaps, true ),
|
||||
_ => throw new ArgumentOutOfRangeException( nameof( type ), type, null ),
|
||||
TextureSaveType.BC5 => CreateCompressed( s, mipMaps, false ),
|
||||
TextureSaveType.BC7 => CreateCompressed( s, mipMaps, true ),
|
||||
_ => throw new ArgumentOutOfRangeException( nameof( type ), type, null ),
|
||||
};
|
||||
|
||||
if( !writeTex )
|
||||
|
|
@ -117,25 +117,29 @@ public partial class CombinedTexture : IDisposable
|
|||
|
||||
private static void SaveTex( string path, ScratchImage input )
|
||||
{
|
||||
var header = input.Meta.ToTexHeader();
|
||||
var header = input.ToTexHeader();
|
||||
if( header.Format == TexFile.TextureFormat.Unknown )
|
||||
{
|
||||
throw new Exception( $"Could not save tex file with format {input.Meta.Format}, not convertible to a valid .tex formats." );
|
||||
}
|
||||
|
||||
using var stream = File.OpenWrite( path );
|
||||
using var stream = File.Open( path, File.Exists(path) ? FileMode.Truncate : FileMode.CreateNew);
|
||||
using var w = new BinaryWriter( stream );
|
||||
header.Write( w );
|
||||
w.Write( input.Pixels );
|
||||
}
|
||||
|
||||
private static ScratchImage AddMipMaps( ScratchImage input, bool mipMaps )
|
||||
=> mipMaps ? input.GenerateMipMaps() : input;
|
||||
=> mipMaps
|
||||
? input.GenerateMipMaps( Math.Min( 13, 1 + BitOperations.Log2( ( uint )Math.Max( input.Meta.Width, input.Meta.Height ) ) ) )
|
||||
: input;
|
||||
|
||||
private static ScratchImage CreateUncompressed( ScratchImage input, bool mipMaps )
|
||||
{
|
||||
if( input.Meta.Format == DXGIFormat.B8G8R8A8UNorm)
|
||||
return AddMipMaps(input, mipMaps);
|
||||
if( input.Meta.Format == DXGIFormat.B8G8R8A8UNorm )
|
||||
{
|
||||
return AddMipMaps( input, mipMaps );
|
||||
}
|
||||
|
||||
if( input.Meta.Format.IsCompressed() )
|
||||
{
|
||||
|
|
@ -151,8 +155,8 @@ public partial class CombinedTexture : IDisposable
|
|||
|
||||
private static ScratchImage CreateCompressed( ScratchImage input, bool mipMaps, bool bc7 )
|
||||
{
|
||||
var format = bc7 ? DXGIFormat.BC7UNorm : DXGIFormat.BC5UNorm;
|
||||
if( input.Meta.Format == format)
|
||||
var format = bc7 ? DXGIFormat.BC7UNorm : DXGIFormat.BC3UNorm;
|
||||
if( input.Meta.Format == format )
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ public static class TexFileParser
|
|||
return i;
|
||||
}
|
||||
|
||||
width = Math.Max( width / 2, 4 );
|
||||
height = Math.Max( height / 2, 4 );
|
||||
width = Math.Max( width / 2, 1 );
|
||||
height = Math.Max( height / 2, 1 );
|
||||
lastOffset = offset;
|
||||
lastSize = requiredSize;
|
||||
}
|
||||
|
|
@ -103,8 +103,9 @@ public static class TexFileParser
|
|||
}
|
||||
}
|
||||
|
||||
public static TexFile.TexHeader ToTexHeader( this TexMeta meta )
|
||||
public static TexFile.TexHeader ToTexHeader( this ScratchImage scratch )
|
||||
{
|
||||
var meta = scratch.Meta;
|
||||
var ret = new TexFile.TexHeader()
|
||||
{
|
||||
Height = ( ushort )meta.Height,
|
||||
|
|
@ -121,34 +122,33 @@ public static class TexFileParser
|
|||
_ => 0,
|
||||
},
|
||||
};
|
||||
unsafe
|
||||
{
|
||||
ret.LodOffset[ 0 ] = 0;
|
||||
ret.LodOffset[ 1 ] = 1;
|
||||
ret.LodOffset[ 2 ] = 2;
|
||||
|
||||
ret.OffsetToSurface[ 0 ] = 80;
|
||||
var size = meta.Format.BitsPerPixel() * meta.Width * meta.Height / 8;
|
||||
for( var i = 1; i < meta.MipLevels; ++i )
|
||||
{
|
||||
ret.OffsetToSurface[ i ] = ( uint )( 80 + size );
|
||||
size >>= 2;
|
||||
if( size == 0 )
|
||||
{
|
||||
ret.MipLevels = ( ushort )i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( var i = ret.MipLevels; i < 13; ++i )
|
||||
{
|
||||
ret.OffsetToSurface[ i ] = 0;
|
||||
}
|
||||
}
|
||||
ret.FillSurfaceOffsets( scratch );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static unsafe void FillSurfaceOffsets( this ref TexFile.TexHeader header, ScratchImage scratch )
|
||||
{
|
||||
var idx = 0;
|
||||
fixed( byte* ptr = scratch.Pixels )
|
||||
{
|
||||
foreach( var image in scratch.Images )
|
||||
{
|
||||
var offset = ( byte* )image.Pixels - ptr;
|
||||
header.OffsetToSurface[ idx++ ] = ( uint )( 80 + offset );
|
||||
}
|
||||
}
|
||||
|
||||
for( ; idx < 13; ++idx )
|
||||
header.OffsetToSurface[ idx ] = 0;
|
||||
|
||||
header.LodOffset[ 0 ] = 0;
|
||||
header.LodOffset[ 1 ] = 1;
|
||||
header.LodOffset[ 2 ] = 2;
|
||||
}
|
||||
|
||||
|
||||
public static TexMeta ToTexMeta( this TexFile.TexHeader header )
|
||||
=> new()
|
||||
{
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue