mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-27 01:12:54 +08:00
DDS file import code, Texture unknowns research
This commit is contained in:
parent
529eb779a4
commit
c59047bdee
@ -122,6 +122,7 @@
|
|||||||
<Compile Include="GameFiles\RpfFile.cs" />
|
<Compile Include="GameFiles\RpfFile.cs" />
|
||||||
<Compile Include="GameFiles\RpfManager.cs" />
|
<Compile Include="GameFiles\RpfManager.cs" />
|
||||||
<Compile Include="GameFiles\Utils\Data.cs" />
|
<Compile Include="GameFiles\Utils\Data.cs" />
|
||||||
|
<Compile Include="GameFiles\Utils\DDSIO.cs" />
|
||||||
<Compile Include="GameFiles\Utils\GTACrypto.cs" />
|
<Compile Include="GameFiles\Utils\GTACrypto.cs" />
|
||||||
<Compile Include="GameFiles\Utils\GTAKeys.cs" />
|
<Compile Include="GameFiles\Utils\GTAKeys.cs" />
|
||||||
<Compile Include="GameFiles\Utils\Jenk.cs" />
|
<Compile Include="GameFiles\Utils\Jenk.cs" />
|
||||||
|
@ -186,7 +186,7 @@ namespace CodeWalker.GameFiles
|
|||||||
//TestCuts();
|
//TestCuts();
|
||||||
//TestYlds();
|
//TestYlds();
|
||||||
//TestYcds();
|
//TestYcds();
|
||||||
//TestYtds();
|
TestYtds();
|
||||||
//TestYbns();
|
//TestYbns();
|
||||||
//TestYdrs();
|
//TestYdrs();
|
||||||
//TestYdds();
|
//TestYdds();
|
||||||
@ -3440,6 +3440,7 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
public void TestYtds()
|
public void TestYtds()
|
||||||
{
|
{
|
||||||
|
bool ddstest = true;
|
||||||
bool savetest = false;
|
bool savetest = false;
|
||||||
var errorfiles = new List<RpfEntry>();
|
var errorfiles = new List<RpfEntry>();
|
||||||
foreach (RpfFile file in AllRpfs)
|
foreach (RpfFile file in AllRpfs)
|
||||||
@ -3461,6 +3462,23 @@ namespace CodeWalker.GameFiles
|
|||||||
UpdateStatus("Error! " + ex.ToString());
|
UpdateStatus("Error! " + ex.ToString());
|
||||||
errorfiles.Add(entry);
|
errorfiles.Add(entry);
|
||||||
}
|
}
|
||||||
|
if (ddstest && (ytdfile != null) && (ytdfile.TextureDict != null))
|
||||||
|
{
|
||||||
|
foreach (var tex in ytdfile.TextureDict.Textures.data_items)
|
||||||
|
{
|
||||||
|
var dds = Utils.DDSIO.GetDDSFile(tex);
|
||||||
|
var tex2 = Utils.DDSIO.GetTexture(dds);
|
||||||
|
if (!tex.Name.StartsWith("script_rt"))
|
||||||
|
{
|
||||||
|
if (tex.Data?.FullData?.Length != tex2.Data?.FullData?.Length)
|
||||||
|
{ }
|
||||||
|
if (tex.Stride != tex2.Stride)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
if ((tex.Format != tex2.Format) || (tex.Width != tex2.Width) || (tex.Height != tex2.Height) || (tex.Depth != tex2.Depth) || (tex.Levels != tex2.Levels))
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
}
|
||||||
if (savetest && (ytdfile != null) && (ytdfile.TextureDict != null))
|
if (savetest && (ytdfile != null) && (ytdfile.TextureDict != null))
|
||||||
{
|
{
|
||||||
var fentry = entry as RpfFileEntry;
|
var fentry = entry as RpfFileEntry;
|
||||||
@ -3687,7 +3705,7 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
public void TestYdrs()
|
public void TestYdrs()
|
||||||
{
|
{
|
||||||
bool savetest = true;
|
bool savetest = false;
|
||||||
bool boundsonly = true;
|
bool boundsonly = true;
|
||||||
var errorfiles = new List<RpfEntry>();
|
var errorfiles = new List<RpfEntry>();
|
||||||
foreach (RpfFile file in AllRpfs)
|
foreach (RpfFile file in AllRpfs)
|
||||||
@ -3800,7 +3818,7 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
public void TestYfts()
|
public void TestYfts()
|
||||||
{
|
{
|
||||||
bool savetest = true;
|
bool savetest = false;
|
||||||
var errorfiles = new List<RpfEntry>();
|
var errorfiles = new List<RpfEntry>();
|
||||||
foreach (RpfFile file in AllRpfs)
|
foreach (RpfFile file in AllRpfs)
|
||||||
{
|
{
|
||||||
@ -3855,6 +3873,7 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
public void TestYpts()
|
public void TestYpts()
|
||||||
{
|
{
|
||||||
|
var savetest = false;
|
||||||
var errorfiles = new List<RpfEntry>();
|
var errorfiles = new List<RpfEntry>();
|
||||||
foreach (RpfFile file in AllRpfs)
|
foreach (RpfFile file in AllRpfs)
|
||||||
{
|
{
|
||||||
@ -3875,7 +3894,7 @@ namespace CodeWalker.GameFiles
|
|||||||
UpdateStatus("Error! " + ex.ToString());
|
UpdateStatus("Error! " + ex.ToString());
|
||||||
errorfiles.Add(entry);
|
errorfiles.Add(entry);
|
||||||
}
|
}
|
||||||
if ((ypt != null) && (ypt.PtfxList != null))
|
if (savetest && (ypt != null) && (ypt.PtfxList != null))
|
||||||
{
|
{
|
||||||
var fentry = entry as RpfFileEntry;
|
var fentry = entry as RpfFileEntry;
|
||||||
if (fentry == null)
|
if (fentry == null)
|
||||||
|
@ -22,7 +22,7 @@ namespace CodeWalker.GameFiles
|
|||||||
// structure data
|
// structure data
|
||||||
public uint Unknown_10h { get; set; } // 0x00000000
|
public uint Unknown_10h { get; set; } // 0x00000000
|
||||||
public uint Unknown_14h { get; set; } // 0x00000000
|
public uint Unknown_14h { get; set; } // 0x00000000
|
||||||
public uint Unknown_18h { get; set; } // 0x00000001
|
public uint Unknown_18h { get; set; } = 1; // 0x00000001
|
||||||
public uint Unknown_1Ch { get; set; } // 0x00000000
|
public uint Unknown_1Ch { get; set; } // 0x00000000
|
||||||
public ResourceSimpleList64_uint TextureNameHashes { get; set; }
|
public ResourceSimpleList64_uint TextureNameHashes { get; set; }
|
||||||
public ResourcePointerList64<Texture> Textures { get; set; }
|
public ResourcePointerList64<Texture> Textures { get; set; }
|
||||||
@ -143,7 +143,7 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
// structure data
|
// structure data
|
||||||
public uint VFT { get; set; }
|
public uint VFT { get; set; }
|
||||||
public uint Unknown_4h { get; set; } // 0x00000001
|
public uint Unknown_4h { get; set; } = 1; // 0x00000001
|
||||||
public uint Unknown_8h { get; set; } // 0x00000000
|
public uint Unknown_8h { get; set; } // 0x00000000
|
||||||
public uint Unknown_Ch { get; set; } // 0x00000000
|
public uint Unknown_Ch { get; set; } // 0x00000000
|
||||||
public uint Unknown_10h { get; set; } // 0x00000000
|
public uint Unknown_10h { get; set; } // 0x00000000
|
||||||
@ -153,7 +153,8 @@ namespace CodeWalker.GameFiles
|
|||||||
public uint Unknown_20h { get; set; } // 0x00000000
|
public uint Unknown_20h { get; set; } // 0x00000000
|
||||||
public uint Unknown_24h { get; set; } // 0x00000000
|
public uint Unknown_24h { get; set; } // 0x00000000
|
||||||
public ulong NamePointer { get; set; }
|
public ulong NamePointer { get; set; }
|
||||||
public uint Unknown_30h { get; set; }
|
public ushort Unknown_30h { get; set; } = 1;
|
||||||
|
public ushort Unknown_32h { get; set; }
|
||||||
public uint Unknown_34h { get; set; } // 0x00000000
|
public uint Unknown_34h { get; set; } // 0x00000000
|
||||||
public uint Unknown_38h { get; set; } // 0x00000000
|
public uint Unknown_38h { get; set; } // 0x00000000
|
||||||
public uint Unknown_3Ch { get; set; } // 0x00000000
|
public uint Unknown_3Ch { get; set; } // 0x00000000
|
||||||
@ -181,7 +182,8 @@ namespace CodeWalker.GameFiles
|
|||||||
this.Unknown_20h = reader.ReadUInt32();
|
this.Unknown_20h = reader.ReadUInt32();
|
||||||
this.Unknown_24h = reader.ReadUInt32();
|
this.Unknown_24h = reader.ReadUInt32();
|
||||||
this.NamePointer = reader.ReadUInt64();
|
this.NamePointer = reader.ReadUInt64();
|
||||||
this.Unknown_30h = reader.ReadUInt32();
|
this.Unknown_30h = reader.ReadUInt16();
|
||||||
|
this.Unknown_32h = reader.ReadUInt16();
|
||||||
this.Unknown_34h = reader.ReadUInt32();
|
this.Unknown_34h = reader.ReadUInt32();
|
||||||
this.Unknown_38h = reader.ReadUInt32();
|
this.Unknown_38h = reader.ReadUInt32();
|
||||||
this.Unknown_3Ch = reader.ReadUInt32();
|
this.Unknown_3Ch = reader.ReadUInt32();
|
||||||
@ -195,6 +197,22 @@ namespace CodeWalker.GameFiles
|
|||||||
{
|
{
|
||||||
NameHash = JenkHash.GenHash(Name.ToLowerInvariant());
|
NameHash = JenkHash.GenHash(Name.ToLowerInvariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (Unknown_32h)
|
||||||
|
{
|
||||||
|
case 0x20:
|
||||||
|
case 0x28:
|
||||||
|
case 0x30:
|
||||||
|
case 0x38:
|
||||||
|
case 0x40:
|
||||||
|
case 0x48:
|
||||||
|
case 0x80:
|
||||||
|
case 0x90:
|
||||||
|
case 0x2://embedded
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -218,6 +236,7 @@ namespace CodeWalker.GameFiles
|
|||||||
writer.Write(this.Unknown_24h);
|
writer.Write(this.Unknown_24h);
|
||||||
writer.Write(this.NamePointer);
|
writer.Write(this.NamePointer);
|
||||||
writer.Write(this.Unknown_30h);
|
writer.Write(this.Unknown_30h);
|
||||||
|
writer.Write(this.Unknown_32h);
|
||||||
writer.Write(this.Unknown_34h);
|
writer.Write(this.Unknown_34h);
|
||||||
writer.Write(this.Unknown_38h);
|
writer.Write(this.Unknown_38h);
|
||||||
writer.Write(this.Unknown_3Ch);
|
writer.Write(this.Unknown_3Ch);
|
||||||
@ -251,13 +270,16 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
|
|
||||||
// structure data
|
// structure data
|
||||||
public uint Unknown_40h { get; set; }
|
public byte Unknown_40h { get; set; }
|
||||||
|
public byte Unknown_41h { get; set; }
|
||||||
|
public byte Unknown_42h { get; set; }
|
||||||
|
public byte Unknown_43h { get; set; }
|
||||||
public uint Unknown_44h { get; set; } // 0x00000000
|
public uint Unknown_44h { get; set; } // 0x00000000
|
||||||
public uint Unknown_48h { get; set; }
|
public uint Unknown_48h { get; set; } // 0, 1
|
||||||
public uint Unknown_4Ch { get; set; } // 0x00000000
|
public uint Unknown_4Ch { get; set; } // 0x00000000
|
||||||
public ushort Width { get; set; }
|
public ushort Width { get; set; }
|
||||||
public ushort Height { get; set; }
|
public ushort Height { get; set; }
|
||||||
public ushort Unknown_54h { get; set; } // 0x0001
|
public ushort Depth { get; set; } = 1; //is depth > 1 supported?
|
||||||
public ushort Stride { get; set; }
|
public ushort Stride { get; set; }
|
||||||
public TextureFormat Format { get; set; }
|
public TextureFormat Format { get; set; }
|
||||||
public byte Unknown_5Ch { get; set; } // 0x00
|
public byte Unknown_5Ch { get; set; } // 0x00
|
||||||
@ -299,13 +321,16 @@ namespace CodeWalker.GameFiles
|
|||||||
base.Read(reader, parameters);
|
base.Read(reader, parameters);
|
||||||
|
|
||||||
// read structure data
|
// read structure data
|
||||||
this.Unknown_40h = reader.ReadUInt32();
|
this.Unknown_40h = reader.ReadByte();
|
||||||
|
this.Unknown_41h = reader.ReadByte();
|
||||||
|
this.Unknown_42h = reader.ReadByte();
|
||||||
|
this.Unknown_43h = reader.ReadByte();
|
||||||
this.Unknown_44h = reader.ReadUInt32();
|
this.Unknown_44h = reader.ReadUInt32();
|
||||||
this.Unknown_48h = reader.ReadUInt32();
|
this.Unknown_48h = reader.ReadUInt32();
|
||||||
this.Unknown_4Ch = reader.ReadUInt32();
|
this.Unknown_4Ch = reader.ReadUInt32();
|
||||||
this.Width = reader.ReadUInt16();
|
this.Width = reader.ReadUInt16();
|
||||||
this.Height = reader.ReadUInt16();
|
this.Height = reader.ReadUInt16();
|
||||||
this.Unknown_54h = reader.ReadUInt16();
|
this.Depth = reader.ReadUInt16();
|
||||||
this.Stride = reader.ReadUInt16();
|
this.Stride = reader.ReadUInt16();
|
||||||
this.Format = (TextureFormat)reader.ReadUInt32();
|
this.Format = (TextureFormat)reader.ReadUInt32();
|
||||||
this.Unknown_5Ch = reader.ReadByte();
|
this.Unknown_5Ch = reader.ReadByte();
|
||||||
@ -332,6 +357,171 @@ namespace CodeWalker.GameFiles
|
|||||||
this.Levels,
|
this.Levels,
|
||||||
this.Stride
|
this.Stride
|
||||||
);
|
);
|
||||||
|
|
||||||
|
switch (Unknown_40h)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 0xA:
|
||||||
|
case 0xB:
|
||||||
|
case 0xC:
|
||||||
|
case 0xE:
|
||||||
|
case 0x10:
|
||||||
|
case 0x12:
|
||||||
|
case 0x13:
|
||||||
|
case 0x14:
|
||||||
|
case 0x15:
|
||||||
|
case 0x16:
|
||||||
|
case 0x17:
|
||||||
|
case 0x18:
|
||||||
|
case 0x19:
|
||||||
|
case 0x1A:
|
||||||
|
case 0x26:
|
||||||
|
case 0x34:
|
||||||
|
case 0x36:
|
||||||
|
case 0x37:
|
||||||
|
case 0x42:
|
||||||
|
case 0x54:
|
||||||
|
case 0x56:
|
||||||
|
case 0x57:
|
||||||
|
case 0x74:
|
||||||
|
case 0x76:
|
||||||
|
case 0x77:
|
||||||
|
case 0x20://embedded only
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (Unknown_41h)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
case 6:
|
||||||
|
case 8:
|
||||||
|
case 0xA:
|
||||||
|
case 0xC:
|
||||||
|
case 0xE:
|
||||||
|
case 0x10:
|
||||||
|
case 0x11:
|
||||||
|
case 0x12:
|
||||||
|
case 0x13:
|
||||||
|
case 0x14:
|
||||||
|
case 0x16:
|
||||||
|
case 0x17:
|
||||||
|
case 0x18:
|
||||||
|
case 0x1C:
|
||||||
|
case 0x1E:
|
||||||
|
case 0x20:
|
||||||
|
case 0x22:
|
||||||
|
case 0x28:
|
||||||
|
case 0x2B:
|
||||||
|
case 0x2C:
|
||||||
|
case 0x30:
|
||||||
|
case 0x38:
|
||||||
|
case 0x39:
|
||||||
|
case 0x3C:
|
||||||
|
case 0x40:
|
||||||
|
case 0x4C:
|
||||||
|
case 0x4E:
|
||||||
|
case 0x50:
|
||||||
|
case 0x54:
|
||||||
|
case 0x56:
|
||||||
|
case 0x57:
|
||||||
|
case 0x58:
|
||||||
|
case 0x5A:
|
||||||
|
case 0x5C:
|
||||||
|
case 0x5E:
|
||||||
|
case 0x60:
|
||||||
|
case 0x64:
|
||||||
|
case 0x68:
|
||||||
|
case 0x70:
|
||||||
|
case 0x78:
|
||||||
|
case 0x80:
|
||||||
|
case 0x90:
|
||||||
|
case 0x9C:
|
||||||
|
case 0x9E:
|
||||||
|
case 0xA0:
|
||||||
|
case 0xA8:
|
||||||
|
case 0xAA:
|
||||||
|
case 0xAC:
|
||||||
|
case 0xAE:
|
||||||
|
case 0xB0:
|
||||||
|
case 0xB2:
|
||||||
|
case 0xB4:
|
||||||
|
case 0xB8:
|
||||||
|
case 0xBC:
|
||||||
|
case 0xC0:
|
||||||
|
case 0xD0:
|
||||||
|
case 7://embedded only
|
||||||
|
case 0xA4://embedded only
|
||||||
|
case 0xAB://embedded only
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (Unknown_42h)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 0xA:
|
||||||
|
case 0xB:
|
||||||
|
case 0xC:
|
||||||
|
case 0xE:
|
||||||
|
case 0x10:
|
||||||
|
case 0x12:
|
||||||
|
case 0x14:
|
||||||
|
case 0x15:
|
||||||
|
case 0x18:
|
||||||
|
case 0x19:
|
||||||
|
case 0x20:
|
||||||
|
case 0x21:
|
||||||
|
case 0x24:
|
||||||
|
case 0x2A:
|
||||||
|
case 0x40:
|
||||||
|
case 0x55:
|
||||||
|
case 0x80://embedded only
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (Unknown_43h)
|
||||||
|
{
|
||||||
|
case 0x20://32
|
||||||
|
case 0x28://40
|
||||||
|
case 0x30://48
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (Unknown_48h)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -345,12 +535,15 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
// write structure data
|
// write structure data
|
||||||
writer.Write(this.Unknown_40h);
|
writer.Write(this.Unknown_40h);
|
||||||
|
writer.Write(this.Unknown_41h);
|
||||||
|
writer.Write(this.Unknown_42h);
|
||||||
|
writer.Write(this.Unknown_43h);
|
||||||
writer.Write(this.Unknown_44h);
|
writer.Write(this.Unknown_44h);
|
||||||
writer.Write(this.Unknown_48h);
|
writer.Write(this.Unknown_48h);
|
||||||
writer.Write(this.Unknown_4Ch);
|
writer.Write(this.Unknown_4Ch);
|
||||||
writer.Write(this.Width);
|
writer.Write(this.Width);
|
||||||
writer.Write(this.Height);
|
writer.Write(this.Height);
|
||||||
writer.Write(this.Unknown_54h);
|
writer.Write(this.Depth);
|
||||||
writer.Write(this.Stride);
|
writer.Write(this.Stride);
|
||||||
writer.Write((uint)this.Format);
|
writer.Write((uint)this.Format);
|
||||||
writer.Write(this.Unknown_5Ch);
|
writer.Write(this.Unknown_5Ch);
|
||||||
|
@ -69,6 +69,32 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//additional dds importing code modified from: https://gist.github.com/spazzarama/2710d020d1d615cde20c607711655167
|
||||||
|
// DDSTextureLoader Ported to C# by Justin Stenning, March 2017
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// File: DDSTextureLoader.cpp
|
||||||
|
//
|
||||||
|
// Functions for loading a DDS texture and creating a Direct3D runtime resource for it
|
||||||
|
//
|
||||||
|
// Note these functions are useful as a light-weight runtime loader for DDS files. For
|
||||||
|
// a full-featured DDS file reader, writer, and texture processing pipeline see
|
||||||
|
// the 'Texconv' sample and the 'DirectXTex' library.
|
||||||
|
//
|
||||||
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||||
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||||
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||||
|
// http://go.microsoft.com/fwlink/?LinkId=248929
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
using CodeWalker.GameFiles;
|
using CodeWalker.GameFiles;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -332,7 +358,142 @@ namespace CodeWalker.Utils
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Texture GetTexture(byte[] ddsfile)
|
||||||
|
{
|
||||||
|
var ms = new MemoryStream(ddsfile);
|
||||||
|
var br = new BinaryReader(ms);
|
||||||
|
|
||||||
|
var header = new DDS_HEADER();
|
||||||
|
var header10 = new DDS_HEADER_DXT10();
|
||||||
|
var useheader10 = false;
|
||||||
|
|
||||||
|
if (!DXTex._ReadDDSHeader(br, out header, out header10, out useheader10))
|
||||||
|
{ return null; }
|
||||||
|
|
||||||
|
var width = header.dwWidth;
|
||||||
|
var height = header.dwHeight;
|
||||||
|
var depth = header.dwDepth;
|
||||||
|
var mipCount = header.dwMipMapCount;
|
||||||
|
if (mipCount == 0)
|
||||||
|
{
|
||||||
|
mipCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEX_DIMENSION resDim = 0;
|
||||||
|
uint arraySize = 1;
|
||||||
|
DXGI_FORMAT format = DXGI_FORMAT.DXGI_FORMAT_UNKNOWN;
|
||||||
|
bool isCubeMap = false;
|
||||||
|
|
||||||
|
if (useheader10)
|
||||||
|
{
|
||||||
|
arraySize = header10.arraySize;
|
||||||
|
format = header10.dxgiFormat;
|
||||||
|
resDim = (TEX_DIMENSION)header10.resourceDimension;
|
||||||
|
|
||||||
|
if (arraySize == 0) throw new Exception("ArraySize was 0! This isn't supported...");
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_AI44:
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_IA44:
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_P8:
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_A8P8:
|
||||||
|
throw new NotSupportedException(string.Format("{0} DXGI format is not supported", format.ToString()));
|
||||||
|
default:
|
||||||
|
if (DXTex.BitsPerPixel(format) == 0)
|
||||||
|
throw new NotSupportedException(string.Format("{0} DXGI format is not supported", format.ToString()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (resDim)
|
||||||
|
{
|
||||||
|
case TEX_DIMENSION.TEX_DIMENSION_TEXTURE1D:
|
||||||
|
if ((header.dwFlags & DXTex.DDS_HEIGHT) > 0 && height != 1) throw new NotSupportedException("1D texture's height wasn't 1!");
|
||||||
|
height = depth = 1; // D3DX writes 1D textures with a fixed Height of 1
|
||||||
|
break;
|
||||||
|
case TEX_DIMENSION.TEX_DIMENSION_TEXTURE2D:
|
||||||
|
if ((header10.miscFlag & (uint)TEX_MISC_FLAG.TEX_MISC_TEXTURECUBE) > 0) { arraySize *= 6; isCubeMap = true; }
|
||||||
|
depth = 1;
|
||||||
|
break;
|
||||||
|
case TEX_DIMENSION.TEX_DIMENSION_TEXTURE3D:
|
||||||
|
if ((header.dwFlags & DXTex.DDS_HEADER_FLAGS_VOLUME) == 0) throw new ArgumentException("3D texture without volume flag!");
|
||||||
|
if (arraySize > 1) throw new ArgumentException("3D texture with ArraySize > 1!");
|
||||||
|
break;
|
||||||
|
default: throw new ArgumentException("Unknown resource dimension!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
format = header.ddspf.GetDXGIFormat();
|
||||||
|
|
||||||
|
if (format == DXGI_FORMAT.DXGI_FORMAT_UNKNOWN) throw new ArgumentException("Unknown DDS format.");
|
||||||
|
if ((header.dwFlags & DXTex.DDS_HEADER_FLAGS_VOLUME) > 0)
|
||||||
|
{
|
||||||
|
resDim = TEX_DIMENSION.TEX_DIMENSION_TEXTURE3D;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((header.dwCaps2 & DXTex.DDS_CUBEMAP) > 0)
|
||||||
|
{
|
||||||
|
if ((header.dwCaps2 & DXTex.DDS_CUBEMAP_ALLFACES) != DXTex.DDS_CUBEMAP_ALLFACES) throw new ArgumentException("Not all faces in cubemap exist!");//requires all 6 faces
|
||||||
|
arraySize = 6;
|
||||||
|
isCubeMap = true;
|
||||||
|
}
|
||||||
|
depth = 1;
|
||||||
|
resDim = TEX_DIMENSION.TEX_DIMENSION_TEXTURE2D;
|
||||||
|
// Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture
|
||||||
|
}
|
||||||
|
if (DXTex.BitsPerPixel(format) == 0) throw new Exception(string.Format("{0} DXGI format is not supported", format.ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCubeMap)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
DXTex.ComputePitch(format, (int)width, (int)height, out int rowPitch, out int slicePitch, 0);
|
||||||
|
var stride = slicePitch / height;
|
||||||
|
var scanlines = DXTex.ComputeScanlines(format, (int)height);
|
||||||
|
|
||||||
|
var brem = ms.Length - ms.Position;
|
||||||
|
var ddsdata = br.ReadBytes((int)brem);
|
||||||
|
|
||||||
|
var tex = new Texture();
|
||||||
|
tex.Width = (ushort)width;
|
||||||
|
tex.Height = (ushort)height;
|
||||||
|
tex.Depth = (ushort)depth;
|
||||||
|
tex.Levels = (byte)mipCount;
|
||||||
|
tex.Format = GetTextureFormat(format);
|
||||||
|
tex.Stride = (ushort)stride;
|
||||||
|
tex.Data = new TextureData();
|
||||||
|
tex.Data.FullData = ddsdata;
|
||||||
|
|
||||||
|
//tex.Unknown_43h = (byte)header.ddspf.dwSize;
|
||||||
|
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static TextureFormat GetTextureFormat(DXGI_FORMAT f)
|
||||||
|
{
|
||||||
|
var format = (TextureFormat)0;
|
||||||
|
switch (f)
|
||||||
|
{
|
||||||
|
// compressed
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM: format = TextureFormat.D3DFMT_DXT1; break;
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM: format = TextureFormat.D3DFMT_DXT3; break;
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM: format = TextureFormat.D3DFMT_DXT5; break;
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM: format = TextureFormat.D3DFMT_ATI1; break;
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM: format = TextureFormat.D3DFMT_ATI2; break;
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM: format = TextureFormat.D3DFMT_BC7; break;
|
||||||
|
|
||||||
|
// uncompressed
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM: format = TextureFormat.D3DFMT_A1R5G5B5; break;
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_A8_UNORM: format = TextureFormat.D3DFMT_A8; break;
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM: format = TextureFormat.D3DFMT_A8B8G8R8; break;
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_R8_UNORM: format = TextureFormat.D3DFMT_L8; break;
|
||||||
|
case DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM: format = TextureFormat.D3DFMT_A8R8G8B8; break;
|
||||||
|
}
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
private static DXGI_FORMAT GetDXGIFormat(TextureFormat f)
|
private static DXGI_FORMAT GetDXGIFormat(TextureFormat f)
|
||||||
{
|
{
|
||||||
@ -1015,6 +1176,7 @@ namespace CodeWalker.Utils
|
|||||||
|
|
||||||
public static uint DDS_FLAGS_VOLUME = 0x00200000; // DDSCAPS2_VOLUME
|
public static uint DDS_FLAGS_VOLUME = 0x00200000; // DDSCAPS2_VOLUME
|
||||||
|
|
||||||
|
public static uint DDS_MAGIC = 0x20534444; // "DDS "
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1104,7 +1266,6 @@ namespace CodeWalker.Utils
|
|||||||
|
|
||||||
int sizeofddsheader = 31 * 4;
|
int sizeofddsheader = 31 * 4;
|
||||||
int sizeofddsheader10 = 5 * 4;
|
int sizeofddsheader10 = 5 * 4;
|
||||||
const uint DDS_MAGIC = 0x20534444; // "DDS "
|
|
||||||
|
|
||||||
required = 4/*sizeof(uint32_t)*/ + sizeofddsheader/*sizeof(DDS_HEADER)*/;
|
required = 4/*sizeof(uint32_t)*/ + sizeofddsheader/*sizeof(DDS_HEADER)*/;
|
||||||
|
|
||||||
@ -1313,6 +1474,68 @@ namespace CodeWalker.Utils
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static bool _ReadDDSHeader(BinaryReader br, out DDS_HEADER header, out DDS_HEADER_DXT10 header10, out bool useheader10)
|
||||||
|
{
|
||||||
|
var magic = br.ReadUInt32();
|
||||||
|
if (magic != DDS_MAGIC) throw new Exception("Invalid DDS magic!");
|
||||||
|
|
||||||
|
//var header = new DDS_HEADER();
|
||||||
|
//var header10 = new DDS_HEADER_DXT10();
|
||||||
|
int sizeofddsheader = 31 * 4;
|
||||||
|
int sizeofddspixelformat = 8 * 4;
|
||||||
|
|
||||||
|
header.dwSize = br.ReadUInt32();
|
||||||
|
header.dwFlags = br.ReadUInt32();
|
||||||
|
header.dwHeight = br.ReadUInt32();
|
||||||
|
header.dwWidth = br.ReadUInt32();
|
||||||
|
header.dwPitchOrLinearSize = br.ReadUInt32();
|
||||||
|
header.dwDepth = br.ReadUInt32(); // only if DDS_HEADER_FLAGS_VOLUME is set in dwFlags
|
||||||
|
header.dwMipMapCount = br.ReadUInt32();
|
||||||
|
|
||||||
|
//public uint dwReserved1[11]; //x11
|
||||||
|
for (int i = 0; i < 11; i++) br.ReadUInt32();
|
||||||
|
|
||||||
|
header.ddspf.dwSize = br.ReadUInt32();
|
||||||
|
header.ddspf.dwFlags = br.ReadUInt32();
|
||||||
|
header.ddspf.dwFourCC = br.ReadUInt32();
|
||||||
|
header.ddspf.dwRGBBitCount = br.ReadUInt32();
|
||||||
|
header.ddspf.dwRBitMask = br.ReadUInt32();
|
||||||
|
header.ddspf.dwGBitMask = br.ReadUInt32();
|
||||||
|
header.ddspf.dwBBitMask = br.ReadUInt32();
|
||||||
|
header.ddspf.dwABitMask = br.ReadUInt32();
|
||||||
|
|
||||||
|
header.dwCaps = br.ReadUInt32();
|
||||||
|
header.dwCaps2 = br.ReadUInt32();
|
||||||
|
header.dwCaps3 = br.ReadUInt32();
|
||||||
|
header.dwCaps4 = br.ReadUInt32();
|
||||||
|
header.dwReserved2 = br.ReadUInt32();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(((DDS_PIXELFORMAT.DDS_FOURCC & header.ddspf.dwFlags) > 0) &&
|
||||||
|
(DDS_PIXELFORMAT.MAKEFOURCC('D', 'X', '1', '0') == header.ddspf.dwFourCC))
|
||||||
|
{
|
||||||
|
header10.dxgiFormat = (DXGI_FORMAT)br.ReadUInt32();
|
||||||
|
header10.resourceDimension = br.ReadUInt32();
|
||||||
|
header10.miscFlag = br.ReadUInt32(); // see DDS_RESOURCE_MISC_FLAG
|
||||||
|
header10.arraySize = br.ReadUInt32();
|
||||||
|
header10.miscFlags2 = br.ReadUInt32(); // see DDS_MISC_FLAGS2
|
||||||
|
useheader10 = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
header10 = new DDS_HEADER_DXT10();
|
||||||
|
useheader10 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.dwSize != sizeofddsheader || header.ddspf.dwSize != sizeofddspixelformat)
|
||||||
|
{
|
||||||
|
throw new Exception("Invalid DDS header size");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1596,86 +1819,250 @@ namespace CodeWalker.Utils
|
|||||||
public static uint DDS_PAL8 = 0x00000020; // DDPF_PALETTEINDEXED8
|
public static uint DDS_PAL8 = 0x00000020; // DDPF_PALETTEINDEXED8
|
||||||
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_DXT1 = new DDS_PIXELFORMAT(
|
public static DDS_PIXELFORMAT DDSPF_DXT1 = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 );
|
||||||
32, DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 );
|
public static DDS_PIXELFORMAT DDSPF_DXT2 = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '2'), 0, 0, 0, 0, 0);
|
||||||
|
public static DDS_PIXELFORMAT DDSPF_DXT3 = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0);
|
||||||
public static DDS_PIXELFORMAT DDSPF_DXT2 = new DDS_PIXELFORMAT(
|
public static DDS_PIXELFORMAT DDSPF_DXT4 = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0);
|
||||||
32, DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '2'), 0, 0, 0, 0, 0);
|
public static DDS_PIXELFORMAT DDSPF_DXT5 = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0);
|
||||||
|
public static DDS_PIXELFORMAT DDSPF_BC4_UNORM = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('B','C','4','U'), 0, 0, 0, 0, 0);
|
||||||
public static DDS_PIXELFORMAT DDSPF_DXT3 = new DDS_PIXELFORMAT(
|
public static DDS_PIXELFORMAT DDSPF_BC4_SNORM = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('B','C','4','S'), 0, 0, 0, 0, 0);
|
||||||
32, DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0);
|
public static DDS_PIXELFORMAT DDSPF_BC5_UNORM = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('B','C','5','U'), 0, 0, 0, 0, 0);
|
||||||
|
public static DDS_PIXELFORMAT DDSPF_BC5_SNORM = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('B','C','5','S'), 0, 0, 0, 0, 0);
|
||||||
public static DDS_PIXELFORMAT DDSPF_DXT4 = new DDS_PIXELFORMAT(
|
public static DDS_PIXELFORMAT DDSPF_R8G8_B8G8 = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('R','G','B','G'), 0, 0, 0, 0, 0);
|
||||||
32, DDS_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0);
|
public static DDS_PIXELFORMAT DDSPF_G8R8_G8B8 = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0);
|
||||||
|
public static DDS_PIXELFORMAT DDSPF_YUY2 = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0);
|
||||||
public static DDS_PIXELFORMAT DDSPF_DXT5 = new DDS_PIXELFORMAT(
|
public static DDS_PIXELFORMAT DDSPF_A8R8G8B8 = new DDS_PIXELFORMAT(32, DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
|
||||||
32, DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0);
|
public static DDS_PIXELFORMAT DDSPF_X8R8G8B8 = new DDS_PIXELFORMAT(32, DDS_RGB, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000);
|
||||||
|
public static DDS_PIXELFORMAT DDSPF_A8B8G8R8 = new DDS_PIXELFORMAT(32, DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||||
public static DDS_PIXELFORMAT DDSPF_BC4_UNORM = new DDS_PIXELFORMAT(
|
public static DDS_PIXELFORMAT DDSPF_X8B8G8R8 = new DDS_PIXELFORMAT(32, DDS_RGB, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000);
|
||||||
32, DDS_FOURCC, MAKEFOURCC('B','C','4','U'), 0, 0, 0, 0, 0);
|
public static DDS_PIXELFORMAT DDSPF_G16R16 = new DDS_PIXELFORMAT(32, DDS_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000);
|
||||||
|
public static DDS_PIXELFORMAT DDSPF_R5G6B5 = new DDS_PIXELFORMAT(32, DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000);
|
||||||
public static DDS_PIXELFORMAT DDSPF_BC4_SNORM = new DDS_PIXELFORMAT(
|
public static DDS_PIXELFORMAT DDSPF_A1R5G5B5 = new DDS_PIXELFORMAT(32, DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000);
|
||||||
32, DDS_FOURCC, MAKEFOURCC('B','C','4','S'), 0, 0, 0, 0, 0);
|
public static DDS_PIXELFORMAT DDSPF_A4R4G4B4 = new DDS_PIXELFORMAT(32, DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000);
|
||||||
|
public static DDS_PIXELFORMAT DDSPF_R8G8B8 = new DDS_PIXELFORMAT(32, DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000);
|
||||||
public static DDS_PIXELFORMAT DDSPF_BC5_UNORM = new DDS_PIXELFORMAT(
|
public static DDS_PIXELFORMAT DDSPF_L8 = new DDS_PIXELFORMAT(32, DDS_LUMINANCE, 0, 8, 0xff, 0x00, 0x00, 0x00);
|
||||||
32, DDS_FOURCC, MAKEFOURCC('B','C','5','U'), 0, 0, 0, 0, 0);
|
public static DDS_PIXELFORMAT DDSPF_L16 = new DDS_PIXELFORMAT(32, DDS_LUMINANCE, 0, 16, 0xffff, 0x0000, 0x0000, 0x0000);
|
||||||
|
public static DDS_PIXELFORMAT DDSPF_A8L8 = new DDS_PIXELFORMAT(32, DDS_LUMINANCEA, 0, 16, 0x00ff, 0x0000, 0x0000, 0xff00);
|
||||||
public static DDS_PIXELFORMAT DDSPF_BC5_SNORM = new DDS_PIXELFORMAT(
|
public static DDS_PIXELFORMAT DDSPF_A8 = new DDS_PIXELFORMAT(32, DDS_ALPHA, 0, 8, 0x00, 0x00, 0x00, 0xff);
|
||||||
32, DDS_FOURCC, MAKEFOURCC('B','C','5','S'), 0, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_R8G8_B8G8 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_FOURCC, MAKEFOURCC('R','G','B','G'), 0, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_G8R8_G8B8 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_YUY2 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_A8R8G8B8 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_X8R8G8B8 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_RGB, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_A8B8G8R8 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_X8B8G8R8 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_RGB, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_G16R16 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_R5G6B5 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_A1R5G5B5 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_A4R4G4B4 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_R8G8B8 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_L8 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_LUMINANCE, 0, 8, 0xff, 0x00, 0x00, 0x00);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_L16 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_LUMINANCE, 0, 16, 0xffff, 0x0000, 0x0000, 0x0000);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_A8L8 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_LUMINANCEA, 0, 16, 0x00ff, 0x0000, 0x0000, 0xff00);
|
|
||||||
|
|
||||||
public static DDS_PIXELFORMAT DDSPF_A8 = new DDS_PIXELFORMAT(
|
|
||||||
32, DDS_ALPHA, 0, 8, 0x00, 0x00, 0x00, 0xff);
|
|
||||||
|
|
||||||
// D3DFMT_A2R10G10B10/D3DFMT_A2B10G10R10 should be written using DX10 extension to avoid D3DX 10:10:10:2 reversal issue
|
// D3DFMT_A2R10G10B10/D3DFMT_A2B10G10R10 should be written using DX10 extension to avoid D3DX 10:10:10:2 reversal issue
|
||||||
|
|
||||||
// This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat)
|
// This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat)
|
||||||
public static DDS_PIXELFORMAT DDSPF_DX10 = new DDS_PIXELFORMAT(
|
public static DDS_PIXELFORMAT DDSPF_DX10 = new DDS_PIXELFORMAT(32, DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0);
|
||||||
32, DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private bool ISBITMASK(uint r, uint g, uint b, uint a)
|
||||||
|
{
|
||||||
|
return ((dwRBitMask == r) && (dwGBitMask == g) && (dwBBitMask == b) && (dwABitMask == a));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DXGI_FORMAT GetDXGIFormat()
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((dwFlags & DDS_RGB) > 0)
|
||||||
|
{
|
||||||
|
// Note that sRGB formats are written using the "DX10" extended header
|
||||||
|
|
||||||
|
switch (dwRGBBitCount)
|
||||||
|
{
|
||||||
|
case 32:
|
||||||
|
if (ISBITMASK(0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000))
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ISBITMASK(0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000))
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ISBITMASK(0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000))
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_B8G8R8X8_UNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No DXGI format maps to ISBITMASK(0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000) aka D3DFMT_X8B8G8R8
|
||||||
|
|
||||||
|
// Note that many common DDS reader/writers (including D3DX) swap the
|
||||||
|
// the RED/BLUE masks for 10:10:10:2 formats. We assumme
|
||||||
|
// below that the 'backwards' header mask is being used since it is most
|
||||||
|
// likely written by D3DX. The more robust solution is to use the 'DX10'
|
||||||
|
// header extension and specify the DXGI_FORMAT_R10G10B10A2_UNORM format directly
|
||||||
|
|
||||||
|
// For 'correct' writers, this should be 0x000003ff, 0x000ffc00, 0x3ff00000 for RGB data
|
||||||
|
if (ISBITMASK(0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000))
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R10G10B10A2_UNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No DXGI format maps to ISBITMASK(0x000003ff, 0x000ffc00, 0x3ff00000, 0xc0000000) aka D3DFMT_A2R10G10B10
|
||||||
|
|
||||||
|
if (ISBITMASK(0x0000ffff, 0xffff0000, 0x00000000, 0x00000000))
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R16G16_UNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ISBITMASK(0xffffffff, 0x00000000, 0x00000000, 0x00000000))
|
||||||
|
{
|
||||||
|
// Only 32-bit color channel format in D3D9 was R32F
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R32_FLOAT; // D3DX writes this out as a FourCC of 114
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 24:
|
||||||
|
// No 24bpp DXGI formats aka D3DFMT_R8G8B8
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 16:
|
||||||
|
if (ISBITMASK(0x7c00, 0x03e0, 0x001f, 0x8000))
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM;
|
||||||
|
}
|
||||||
|
if (ISBITMASK(0xf800, 0x07e0, 0x001f, 0x0000))
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_B5G6R5_UNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No DXGI format maps to ISBITMASK(0x7c00, 0x03e0, 0x001f, 0x0000) aka D3DFMT_X1R5G5B5
|
||||||
|
if (ISBITMASK(0x0f00, 0x00f0, 0x000f, 0xf000))
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No DXGI format maps to ISBITMASK(0x0f00, 0x00f0, 0x000f, 0x0000) aka D3DFMT_X4R4G4B4
|
||||||
|
|
||||||
|
// No 3:3:2, 3:3:2:8, or paletted DXGI formats aka D3DFMT_A8R3G3B2, D3DFMT_R3G3B2, D3DFMT_P8, D3DFMT_A8P8, etc.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((dwFlags & DDS_LUMINANCE) > 0)
|
||||||
|
{
|
||||||
|
if (8 == dwRGBBitCount)
|
||||||
|
{
|
||||||
|
if (ISBITMASK(0x000000ff, 0x00000000, 0x00000000, 0x00000000))
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R8_UNORM; // D3DX10/11 writes this out as DX10 extension
|
||||||
|
}
|
||||||
|
|
||||||
|
// No DXGI format maps to ISBITMASK(0x0f, 0x00, 0x00, 0xf0) aka D3DFMT_A4L4
|
||||||
|
}
|
||||||
|
|
||||||
|
if (16 == dwRGBBitCount)
|
||||||
|
{
|
||||||
|
if (ISBITMASK(0x0000ffff, 0x00000000, 0x00000000, 0x00000000))
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R16_UNORM; // D3DX10/11 writes this out as DX10 extension
|
||||||
|
}
|
||||||
|
if (ISBITMASK(0x000000ff, 0x00000000, 0x00000000, 0x0000ff00))
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM; // D3DX10/11 writes this out as DX10 extension
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((dwFlags & DDS_ALPHA) > 0)
|
||||||
|
{
|
||||||
|
if (8 == dwRGBBitCount)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_A8_UNORM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((dwFlags & DDS_FOURCC) > 0)
|
||||||
|
{
|
||||||
|
if (MAKEFOURCC('D', 'X', 'T', '1') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM;
|
||||||
|
}
|
||||||
|
if (MAKEFOURCC('D', 'X', 'T', '3') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM;
|
||||||
|
}
|
||||||
|
if (MAKEFOURCC('D', 'X', 'T', '5') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// While pre-mulitplied alpha isn't directly supported by the DXGI formats,
|
||||||
|
// they are basically the same as these BC formats so they can be mapped
|
||||||
|
if (MAKEFOURCC('D', 'X', 'T', '2') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM;
|
||||||
|
}
|
||||||
|
if (MAKEFOURCC('D', 'X', 'T', '4') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MAKEFOURCC('A', 'T', 'I', '1') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM;
|
||||||
|
}
|
||||||
|
if (MAKEFOURCC('B', 'C', '4', 'U') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM;
|
||||||
|
}
|
||||||
|
if (MAKEFOURCC('B', 'C', '4', 'S') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MAKEFOURCC('A', 'T', 'I', '2') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM;
|
||||||
|
}
|
||||||
|
if (MAKEFOURCC('B', 'C', '5', 'U') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM;
|
||||||
|
}
|
||||||
|
if (MAKEFOURCC('B', 'C', '5', 'S') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BC6H and BC7 are written using the "DX10" extended header
|
||||||
|
|
||||||
|
if (MAKEFOURCC('R', 'G', 'B', 'G') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R8G8_B8G8_UNORM;
|
||||||
|
}
|
||||||
|
if (MAKEFOURCC('G', 'R', 'G', 'B') == dwFourCC)
|
||||||
|
{
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_G8R8_G8B8_UNORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for D3DFORMAT enums being set here
|
||||||
|
switch (dwFourCC)
|
||||||
|
{
|
||||||
|
case 36: // D3DFMT_A16B16G16R16
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_UNORM;
|
||||||
|
|
||||||
|
case 110: // D3DFMT_Q16W16V16U16
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_SNORM;
|
||||||
|
|
||||||
|
case 111: // D3DFMT_R16F
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R16_FLOAT;
|
||||||
|
|
||||||
|
case 112: // D3DFMT_G16R16F
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R16G16_FLOAT;
|
||||||
|
|
||||||
|
case 113: // D3DFMT_A16B16G16R16F
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||||
|
|
||||||
|
case 114: // D3DFMT_R32F
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R32_FLOAT;
|
||||||
|
|
||||||
|
case 115: // D3DFMT_G32R32F
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R32G32_FLOAT;
|
||||||
|
|
||||||
|
case 116: // D3DFMT_A32B32G32R32F
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DXGI_FORMAT.DXGI_FORMAT_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
@ -788,7 +788,8 @@ namespace CodeWalker
|
|||||||
}
|
}
|
||||||
var texParam = new TextureBase();
|
var texParam = new TextureBase();
|
||||||
texParam.Unknown_4h = 1;
|
texParam.Unknown_4h = 1;
|
||||||
texParam.Unknown_30h = 131073;//wtf is this? 2x shorts, 0x00020001
|
texParam.Unknown_30h = 1;// 131073;//wtf is this? 2x shorts, 0x00020001
|
||||||
|
texParam.Unknown_32h = 2;
|
||||||
texParam.Name = name;
|
texParam.Name = name;
|
||||||
texParam.NameHash = JenkHash.GenHash(name.ToLowerInvariant());
|
texParam.NameHash = JenkHash.GenHash(name.ToLowerInvariant());
|
||||||
return texParam;
|
return texParam;
|
||||||
|
@ -612,7 +612,6 @@
|
|||||||
<Compile Include="Utils\TextInputForm.Designer.cs">
|
<Compile Include="Utils\TextInputForm.Designer.cs">
|
||||||
<DependentUpon>TextInputForm.cs</DependentUpon>
|
<DependentUpon>TextInputForm.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Utils\DDSIO.cs" />
|
|
||||||
<Compile Include="Utils\GTAFolder.cs" />
|
<Compile Include="Utils\GTAFolder.cs" />
|
||||||
<Compile Include="Utils\InputUtils.cs" />
|
<Compile Include="Utils\InputUtils.cs" />
|
||||||
<Compile Include="Utils\MapUtils.cs" />
|
<Compile Include="Utils\MapUtils.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user