Fix some texture handling.

This commit is contained in:
Ottermandias 2022-09-29 13:00:31 +02:00
parent fe4955f8fc
commit fabe2a9a16
3 changed files with 41 additions and 37 deletions

View file

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

View file

@ -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.