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,7 +91,7 @@ public partial class CombinedTexture : IDisposable
var tex = type switch 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.Bitmap => CreateUncompressed( s, mipMaps ),
TextureSaveType.BC5 => CreateCompressed( s, mipMaps, false ), TextureSaveType.BC5 => CreateCompressed( s, mipMaps, false ),
TextureSaveType.BC7 => CreateCompressed( s, mipMaps, true ), TextureSaveType.BC7 => CreateCompressed( s, mipMaps, true ),
@ -117,25 +117,29 @@ public partial class CombinedTexture : IDisposable
private static void SaveTex( string path, ScratchImage input ) private static void SaveTex( string path, ScratchImage input )
{ {
var header = input.Meta.ToTexHeader(); var header = input.ToTexHeader();
if( header.Format == TexFile.TextureFormat.Unknown ) 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." ); 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 ); using var w = new BinaryWriter( stream );
header.Write( w ); header.Write( w );
w.Write( input.Pixels ); w.Write( input.Pixels );
} }
private static ScratchImage AddMipMaps( ScratchImage input, bool mipMaps ) 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 ) private static ScratchImage CreateUncompressed( ScratchImage input, bool mipMaps )
{ {
if( input.Meta.Format == DXGIFormat.B8G8R8A8UNorm) if( input.Meta.Format == DXGIFormat.B8G8R8A8UNorm )
return AddMipMaps(input, mipMaps); {
return AddMipMaps( input, mipMaps );
}
if( input.Meta.Format.IsCompressed() ) if( input.Meta.Format.IsCompressed() )
{ {
@ -151,8 +155,8 @@ public partial class CombinedTexture : IDisposable
private static ScratchImage CreateCompressed( ScratchImage input, bool mipMaps, bool bc7 ) private static ScratchImage CreateCompressed( ScratchImage input, bool mipMaps, bool bc7 )
{ {
var format = bc7 ? DXGIFormat.BC7UNorm : DXGIFormat.BC5UNorm; var format = bc7 ? DXGIFormat.BC7UNorm : DXGIFormat.BC3UNorm;
if( input.Meta.Format == format) if( input.Meta.Format == format )
{ {
return input; return input;
} }

View file

@ -61,8 +61,8 @@ public static class TexFileParser
return i; return i;
} }
width = Math.Max( width / 2, 4 ); width = Math.Max( width / 2, 1 );
height = Math.Max( height / 2, 4 ); height = Math.Max( height / 2, 1 );
lastOffset = offset; lastOffset = offset;
lastSize = requiredSize; 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() var ret = new TexFile.TexHeader()
{ {
Height = ( ushort )meta.Height, Height = ( ushort )meta.Height,
@ -121,34 +122,33 @@ public static class TexFileParser
_ => 0, _ => 0,
}, },
}; };
unsafe
{
ret.LodOffset[ 0 ] = 0;
ret.LodOffset[ 1 ] = 1;
ret.LodOffset[ 2 ] = 2;
ret.OffsetToSurface[ 0 ] = 80; ret.FillSurfaceOffsets( scratch );
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;
}
}
return ret; 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 ) public static TexMeta ToTexMeta( this TexFile.TexHeader header )
=> new() => new()
{ {

Binary file not shown.