public DDS(D3DFormat Format, Bitmap bitmap) { SquishFlags flags = SquishFlags.kDxt1; bool bCompressed = true; switch (Format) { case D3DFormat.DXT1: flags = SquishFlags.kDxt1; break; case D3DFormat.DXT3: flags = SquishFlags.kDxt3; break; case D3DFormat.DXT5: flags = SquishFlags.kDxt5; break; default: bCompressed = false; break; } format = Format; width = bitmap.Width; height = bitmap.Height; var mip = new MipMap(); mip.Width = width; mip.Height = height; byte[] data = new byte[mip.Width * mip.Height * 4]; BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, mip.Width, mip.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); Marshal.Copy(bmpdata.Scan0, data, 0, bmpdata.Stride * bmpdata.Height); bitmap.UnlockBits(bmpdata); if (bCompressed) { for (uint i = 0; i < data.Length - 4; i += 4) { byte r = data[i + 0]; data[i + 0] = data[i + 2]; data[i + 2] = r; } byte[] dest = new byte[Squish.Squish.GetStorageRequirements(mip.Width, mip.Height, flags | SquishFlags.kColourIterativeClusterFit | SquishFlags.kWeightColourByAlpha)]; Squish.Squish.CompressImage(data, mip.Width, mip.Height, ref dest, flags | SquishFlags.kColourIterativeClusterFit | SquishFlags.kWeightColourByAlpha); mip.Data = dest; } else { mip.Data = data; } mipMaps.Add(mip); }
public BreckfestSettings() { this.clutter = false; this.raw = false; this.force = false; this.format = D3DFormat.DXT5; }
public DDS(D3DFormat Format, Bitmap bitmap) { SquishFlags flags = SquishFlags.kDxt1; bool bCompressed = true; switch (Format) { case D3DFormat.DXT1: flags = SquishFlags.kDxt1; break; case D3DFormat.DXT3: flags = SquishFlags.kDxt3; break; case D3DFormat.DXT5: flags = SquishFlags.kDxt5; break; default: bCompressed = false; break; } format = Format; width = bitmap.Width; height = bitmap.Height; var mip = new MipMap(); mip.Width = width; mip.Height = height; byte[] data = new byte[mip.Width * mip.Height * 4]; BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, mip.Width, mip.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); Marshal.Copy(bmpdata.Scan0, data, 0, bmpdata.Stride * bmpdata.Height); bitmap.UnlockBits(bmpdata); if (bCompressed) { for (uint i = 0; i < data.Length - 4; i += 4) { byte r = data[i + 0]; data[i + 0] = data[i + 2]; data[i + 2] = r; } byte[] dest = new byte[Squish.Squish.GetStorageRequirements(mip.Width, mip.Height, flags | SquishFlags.kColourIterativeClusterFit)]; Squish.Squish.CompressImage(data, mip.Width, mip.Height, ref dest, flags | SquishFlags.kColourIterativeClusterFit); mip.Data = dest; } else { mip.Data = data; } mipMaps.Add(mip); }
public void Read(BinaryReader br) { // Full structure of rage::grcTexturePC // rage::datBase VTable = br.ReadUInt32(); // rage::pgBase BlockMapOffset = ResourceUtil.ReadOffset(br); // Texture Info struct: Unknown1 = br.ReadUInt32(); // BYTE, BYTE, WORD Unknown2 = br.ReadUInt32(); Unknown3 = br.ReadUInt32(); uint nameOffset = ResourceUtil.ReadOffset(br); Unknown4 = br.ReadUInt32(); // Texture Data struct: Width = br.ReadUInt16(); Height = br.ReadUInt16(); Format = (D3DFormat)br.ReadInt32(); StrideSize = br.ReadUInt16(); Type = br.ReadByte(); Levels = br.ReadByte(); UnknownFloat1 = br.ReadSingle(); UnknownFloat2 = br.ReadSingle(); UnknownFloat3 = br.ReadSingle(); UnknownFloat4 = br.ReadSingle(); UnknownFloat5 = br.ReadSingle(); UnknownFloat6 = br.ReadSingle(); PrevTextureInfoOffset = ResourceUtil.ReadOffset(br); NextTextureInfoOffset = ResourceUtil.ReadOffset(br); RawDataOffset = ResourceUtil.ReadDataOffset(br); Unknown6 = br.ReadUInt32(); // Read texture name br.BaseStream.Seek(nameOffset, SeekOrigin.Begin); Name = ResourceUtil.ReadNullTerminatedString(br); }
/// <summary> /// Decode DDS Header. /// </summary> /// <param name="reader">Image stream.</param> /// <param name="description">Image description.</param> public void DecodeHeader(BinaryReader reader, out ImageDescription description) { Header header = ImageHelpers.ReadStruct <Header>(reader); DxgiFormat dxgiFormat; D3DFormat d3dFormat = D3DFormat.Unknown; HeaderDx10 headerDX10 = default; if (header.PixelFormat.FourCC != Helper.DX10) { Helper.DetermineFormat(ref header.PixelFormat, out dxgiFormat, out d3dFormat); } else { byte[] headerDx10Bytes = reader.ReadBytes(Marshal.SizeOf(typeof(HeaderDx10))); GCHandle headerDx10Handle = GCHandle.Alloc(headerDx10Bytes, GCHandleType.Pinned); headerDX10 = (HeaderDx10)Marshal.PtrToStructure(headerDx10Handle.AddrOfPinnedObject(), typeof(HeaderDx10)); headerDx10Handle.Free(); dxgiFormat = headerDX10.Format; } uint faces = 1; if (headerDX10.MiscFlags.HasFlag(ResourceMiscFlags.TextureCube) || header.Caps2.HasFlag(Caps2.CubeMap)) { faces = 6; } description = new ImageDescription() { imageFormat = ImageFormat.DDS, Width = header.Width, Height = header.Height, Depth = header.Flags.HasFlag(HeaderFlags.Depth) ? header.Depth : 1, MipLevels = header.MipMapCount == 0 ? 1 : header.MipMapCount, ArraySize = headerDX10.ArraySize == 0 ? 1 : headerDX10.ArraySize, Faces = faces, pixelFormat = (WaveEngine.Common.Graphics.PixelFormat)dxgiFormat, }; }
public static bool IsFormatCompressed(DxgiFormat dxgiFormat, D3DFormat d3dFormat) { switch (dxgiFormat) { case DxgiFormat.BC1_TYPELESS: case DxgiFormat.BC1_UNORM: case DxgiFormat.BC1_UNORM_SRGB: case DxgiFormat.BC2_TYPELESS: case DxgiFormat.BC2_UNORM: case DxgiFormat.BC2_UNORM_SRGB: case DxgiFormat.BC3_TYPELESS: case DxgiFormat.BC3_UNORM: case DxgiFormat.BC3_UNORM_SRGB: case DxgiFormat.BC4_TYPELESS: case DxgiFormat.BC4_UNORM: case DxgiFormat.BC4_SNORM: case DxgiFormat.BC5_TYPELESS: case DxgiFormat.BC5_UNORM: case DxgiFormat.BC5_SNORM: case DxgiFormat.BC6H_TYPELESS: case DxgiFormat.BC6H_UF16: case DxgiFormat.BC6H_SF16: case DxgiFormat.BC7_TYPELESS: case DxgiFormat.BC7_UNORM: case DxgiFormat.BC7_UNORM_SRGB: return(true); } switch (d3dFormat) { case D3DFormat.Dxt1: case D3DFormat.Dxt2: case D3DFormat.Dxt3: case D3DFormat.Dxt4: case D3DFormat.Dxt5: return(true); } return(false); }
public static int GetMipSize(D3DFormat format, ushort width, ushort height) { width = Math.Max((ushort)4, width); height = Math.Max((ushort)4, height); if (format == D3DFormat.DXT1) { return ((((width + 3) / 4) * ((height + 3) / 4)) * 8); } if (format == D3DFormat.DXT5 || format == D3DFormat.ATI2) { return ((((width + 3) / 4) * ((height + 3) / 4)) * 16); } return(width * height * 4); }
public DDS(D3DFormat format, Bitmap bitmap) { SquishFlags flags = SquishFlags.kDxt1; bool compressed = true; switch (format) { case D3DFormat.DXT1: flags = SquishFlags.kDxt1; break; case D3DFormat.DXT3: flags = SquishFlags.kDxt3; break; case D3DFormat.DXT5: flags = SquishFlags.kDxt5; break; default: compressed = false; break; } Format = format; Width = bitmap.Width; Height = bitmap.Height; MipMap mip = new MipMap { Width = Width, Height = Height }; byte[] data = new byte[mip.Width * mip.Height * 4]; BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, mip.Width, mip.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Marshal.Copy(bmpdata.Scan0, data, 0, bmpdata.Stride * bmpdata.Height); bitmap.UnlockBits(bmpdata); if (compressed) { for (uint i = 0; i < data.Length - 4; i += 4) { byte r = data[i + 0]; data[i + 0] = data[i + 2]; data[i + 2] = r; } byte[] dest = new byte[Squish.Squish.GetStorageRequirements(mip.Width, mip.Height, flags | SquishFlags.kColourIterativeClusterFit)]; Squish.Squish.CompressImage(data, mip.Width, mip.Height, dest, flags | SquishFlags.kColourIterativeClusterFit, true); mip.Data = dest; } else { mip.Data = data; } MipMaps.Add(mip); }
public D3DBaseTexture(BinaryReader br) { BitVector32 bv = new BitVector32(); commonType = br.ReadUInt16(); referenceCount = (int)br.ReadUInt32(); fence = (int)br.ReadUInt32(); readFence = (int)br.ReadUInt32(); identifier = (int)br.ReadUInt32(); baseFlush = (int)br.ReadUInt32(); mipFlush = (int)br.ReadUInt32(); bv = new BitVector32((int)br.ReadUInt32()); var type = BitVector32.CreateSection(3); var signx = BitVector32.CreateSection(3, type); var signy = BitVector32.CreateSection(3, signx); var signz = BitVector32.CreateSection(3, signy); var signw = BitVector32.CreateSection(3, signz); var clampx = BitVector32.CreateSection(7, signw); var clampy = BitVector32.CreateSection(7, clampx); var clampz = BitVector32.CreateSection(7, clampy); var spacer = BitVector32.CreateSection(7, clampz); var pitch = BitVector32.CreateSection(511, spacer); var tiled = BitVector32.CreateSection(1, pitch); this.tiled = (bv[tiled] == 1); this.pitch = bv[pitch]; clampX = bv[clampx]; clampY = bv[clampy]; clampZ = bv[clampz]; signX = bv[signx]; signY = bv[signy]; signZ = bv[signz]; signW = bv[signw]; this.type = bv[type]; bv = new BitVector32((int)br.ReadUInt32()); var dataformat = BitVector32.CreateSection(63); var endian = BitVector32.CreateSection(3, dataformat); var requestsize = BitVector32.CreateSection(3, endian); var stacked = BitVector32.CreateSection(1, requestsize); var clamppolicy = BitVector32.CreateSection(1, stacked); var baseaddressa = BitVector32.CreateSection(1023, clamppolicy); var baseaddressb = BitVector32.CreateSection(1023, baseaddressa); baseAddress = ((int)bv[baseaddressb] << 10) | bv[baseaddressa]; clampPolicy = bv[clamppolicy]; this.stacked = (bv[stacked] == 1); requestSize = bv[requestsize]; this.endian = bv[endian]; dataFormat = (D3DFormat)bv[dataformat]; br.ReadUInt32(); // GPUTEXTURESIZE bv = new BitVector32((int)br.ReadUInt32()); var bordersize = BitVector32.CreateSection(1); spacer = BitVector32.CreateSection(7, bordersize); var anisofilter = BitVector32.CreateSection(7, spacer); var mipfilter = BitVector32.CreateSection(3, anisofilter); var minfilter = BitVector32.CreateSection(3, mipfilter); var magfilter = BitVector32.CreateSection(3, minfilter); var expadjust = BitVector32.CreateSection(63, magfilter); var swizzlew = BitVector32.CreateSection(7, expadjust); var swizzlez = BitVector32.CreateSection(7, swizzlew); var swizzley = BitVector32.CreateSection(7, swizzlez); var swizzlex = BitVector32.CreateSection(7, swizzley); var numformat = BitVector32.CreateSection(1, swizzlex); borderSize = bv[bordersize]; anisoFilter = bv[anisofilter]; mipFilter = bv[mipfilter]; minFilter = bv[minfilter]; magFilter = bv[magfilter]; expAdjust = bv[expadjust]; swizzleX = bv[swizzlex]; swizzleY = bv[swizzley]; swizzleZ = bv[swizzlez]; swizzleW = bv[swizzlew]; numFormat = bv[numformat]; br.ReadBytes(8); }
public static TDX LoadFromBitmap(Bitmap asset, string name, D3DFormat format) { TDX tdx = null; if (tdx == null) { tdx = new TDX(); Bitmap b = asset; SquishFlags flags = SquishFlags.kDxt1; tdx.Name = name; tdx.Format = format; switch (tdx.Format) { case D3DFormat.DXT1: flags = SquishFlags.kDxt1; break; case D3DFormat.DXT5: flags = SquishFlags.kDxt5; break; } List <Bitmap> mipBitmaps = GenerateMips(b, b.Width, b.Height); foreach (Bitmap mb in mipBitmaps) { MipMap mip = new MipMap() { Width = mb.Width, Height = mb.Height }; byte[] data = new byte[mb.Width * mb.Height * 4]; byte[] dest = new byte[Squish.Squish.GetStorageRequirements(mb.Width, mb.Height, flags | SquishFlags.kColourIterativeClusterFit | SquishFlags.kWeightColourByAlpha)]; int ii = 0; for (int y = 0; y < mb.Height; y++) { for (int x = 0; x < mb.Width; x++) { Color p = mb.GetPixel(x, y); data[ii + 0] = p.R; data[ii + 1] = p.G; data[ii + 2] = p.B; data[ii + 3] = p.A; ii += 4; } } if (format == D3DFormat.ATI2) { dest = BC5Unorm.Compress(data, (ushort)mb.Width, (ushort)mb.Height, GetMipSize(format, (ushort)mb.Width, (ushort)mb.Height)); } else { Squish.Squish.CompressImage(data, mb.Width, mb.Height, ref dest, flags | SquishFlags.kColourClusterFit); } mip.Data = dest; tdx.MipMaps.Add(mip); } } return(tdx); }
public D3DBaseTexture(BinaryReader br) { BitVector32 bv = new BitVector32(); commonType = br.ReadUInt16(); referenceCount = (int)br.ReadUInt32(); fence = (int)br.ReadUInt32(); readFence = (int)br.ReadUInt32(); identifier = (int)br.ReadUInt32(); baseFlush = (int)br.ReadUInt32(); mipFlush = (int)br.ReadUInt32(); bv = new BitVector32((int)br.ReadUInt32()); BitVector32.Section type = BitVector32.CreateSection(3); BitVector32.Section signx = BitVector32.CreateSection(3, type); BitVector32.Section signy = BitVector32.CreateSection(3, signx); BitVector32.Section signz = BitVector32.CreateSection(3, signy); BitVector32.Section signw = BitVector32.CreateSection(3, signz); BitVector32.Section clampx = BitVector32.CreateSection(7, signw); BitVector32.Section clampy = BitVector32.CreateSection(7, clampx); BitVector32.Section clampz = BitVector32.CreateSection(7, clampy); BitVector32.Section spacer = BitVector32.CreateSection(7, clampz); BitVector32.Section pitch = BitVector32.CreateSection(511, spacer); BitVector32.Section tiled = BitVector32.CreateSection(1, pitch); this.tiled = (bv[tiled] == 1); this.pitch = bv[pitch]; clampX = bv[clampx]; clampY = bv[clampy]; clampZ = bv[clampz]; signX = bv[signx]; signY = bv[signy]; signZ = bv[signz]; signW = bv[signw]; this.type = bv[type]; bv = new BitVector32((int)br.ReadUInt32()); BitVector32.Section dataformat = BitVector32.CreateSection(63); BitVector32.Section endian = BitVector32.CreateSection(3, dataformat); BitVector32.Section requestsize = BitVector32.CreateSection(3, endian); BitVector32.Section stacked = BitVector32.CreateSection(1, requestsize); BitVector32.Section clamppolicy = BitVector32.CreateSection(1, stacked); BitVector32.Section baseaddressa = BitVector32.CreateSection(1023, clamppolicy); BitVector32.Section baseaddressb = BitVector32.CreateSection(1023, baseaddressa); baseAddress = ((int)bv[baseaddressb] << 10) | bv[baseaddressa]; clampPolicy = bv[clamppolicy]; this.stacked = (bv[stacked] == 1); requestSize = bv[requestsize]; this.endian = bv[endian]; dataFormat = (D3DFormat)bv[dataformat]; br.ReadUInt32(); // GPUTEXTURESIZE bv = new BitVector32((int)br.ReadUInt32()); BitVector32.Section bordersize = BitVector32.CreateSection(1); spacer = BitVector32.CreateSection(7, bordersize); BitVector32.Section anisofilter = BitVector32.CreateSection(7, spacer); BitVector32.Section mipfilter = BitVector32.CreateSection(3, anisofilter); BitVector32.Section minfilter = BitVector32.CreateSection(3, mipfilter); BitVector32.Section magfilter = BitVector32.CreateSection(3, minfilter); BitVector32.Section expadjust = BitVector32.CreateSection(63, magfilter); BitVector32.Section swizzlew = BitVector32.CreateSection(7, expadjust); BitVector32.Section swizzlez = BitVector32.CreateSection(7, swizzlew); BitVector32.Section swizzley = BitVector32.CreateSection(7, swizzlez); BitVector32.Section swizzlex = BitVector32.CreateSection(7, swizzley); BitVector32.Section numformat = BitVector32.CreateSection(1, swizzlex); borderSize = bv[bordersize]; anisoFilter = bv[anisofilter]; mipFilter = bv[mipfilter]; minFilter = bv[minfilter]; magFilter = bv[magfilter]; expAdjust = bv[expadjust]; swizzleX = bv[swizzlex]; swizzleY = bv[swizzley]; swizzleZ = bv[swizzlez]; swizzleW = bv[swizzlew]; numFormat = bv[numformat]; br.ReadBytes(8); }
public static int FormatBits(DxgiFormat dxgiFormat, D3DFormat d3dFormat) { if (dxgiFormat >= DxgiFormat.R32G32B32A32_TYPELESS && dxgiFormat <= DxgiFormat.R32G32B32A32_SINT) { return(128); } if (dxgiFormat >= DxgiFormat.R32G32B32_TYPELESS && dxgiFormat <= DxgiFormat.R32G32B32_SINT) { return(96); } if (dxgiFormat >= DxgiFormat.R16G16B16A16_TYPELESS && dxgiFormat <= DxgiFormat.X32_TYPELESS_G8X24_UINT) { return(64); } if (dxgiFormat >= DxgiFormat.R10G10B10A2_TYPELESS && dxgiFormat <= DxgiFormat.X24_TYPELESS_G8_UINT) { return(32); } if (dxgiFormat >= DxgiFormat.R8G8_UNORM && dxgiFormat <= DxgiFormat.R16_SINT) { return(16); } if (dxgiFormat >= DxgiFormat.R8_TYPELESS && dxgiFormat <= DxgiFormat.A8_UNORM) { return(8); } if (dxgiFormat == DxgiFormat.R9G9B9E5_SHAREDEXP) { return(32); } if (dxgiFormat >= DxgiFormat.R8G8_B8G8_UNORM && dxgiFormat <= DxgiFormat.G8R8_G8B8_UNORM) { return(16); } if (dxgiFormat >= DxgiFormat.BC1_TYPELESS && dxgiFormat <= DxgiFormat.BC1_UNORM_SRGB) { return(4); } if (dxgiFormat >= DxgiFormat.BC2_TYPELESS && dxgiFormat <= DxgiFormat.BC3_UNORM_SRGB) { return(8); } if (dxgiFormat >= DxgiFormat.BC4_TYPELESS && dxgiFormat <= DxgiFormat.BC4_SNORM) { return(4); } if (dxgiFormat >= DxgiFormat.BC5_TYPELESS && dxgiFormat <= DxgiFormat.BC5_SNORM) { return(8); } if (dxgiFormat >= DxgiFormat.B8G8R8A8_TYPELESS && dxgiFormat <= DxgiFormat.B8G8R8X8_UNORM_SRGB) { return(32); } if (dxgiFormat >= DxgiFormat.BC6H_TYPELESS && dxgiFormat <= DxgiFormat.BC7_UNORM_SRGB) { return(8); } switch (d3dFormat) { case D3DFormat.R8G8B8: return(24); case D3DFormat.X8R8G8B8: case D3DFormat.A8R8G8B8: case D3DFormat.A2B10G10R10: case D3DFormat.A8B8G8R8: case D3DFormat.X8B8G8R8: case D3DFormat.G16R16: case D3DFormat.A2R10G10B10: case D3DFormat.X8L8V8U8: case D3DFormat.Q8W8V8U8: case D3DFormat.V16U16: case D3DFormat.A2W10V10U10: case D3DFormat.D32: case D3DFormat.D24S8: case D3DFormat.D24X8: case D3DFormat.D24X4S4: case D3DFormat.D32SingleLockable: case D3DFormat.D24SingleS8: case D3DFormat.D32Lockable: case D3DFormat.Index32: case D3DFormat.G16R16F: case D3DFormat.R32F: return(32); case D3DFormat.R5G6B5: case D3DFormat.X1R5G5B5: case D3DFormat.A1R5G5B5: case D3DFormat.A4R4G4B4: case D3DFormat.A8R3G3B2: case D3DFormat.X4R4G4B4: case D3DFormat.A8P8: case D3DFormat.A8L8: case D3DFormat.V8U8: case D3DFormat.L6V5U5: case D3DFormat.D16Lockable: case D3DFormat.D15S1: case D3DFormat.D16: case D3DFormat.L16: case D3DFormat.Index16: case D3DFormat.R16F: case D3DFormat.CxV8U8: case D3DFormat.Yuy2: case D3DFormat.G8R8_G8B8: case D3DFormat.R8G8_B8G8: case D3DFormat.Uyvy: return(16); case D3DFormat.R3G3B2: case D3DFormat.A8: case D3DFormat.P8: case D3DFormat.L8: case D3DFormat.A4L4: case D3DFormat.S8Lockable: return(8); case D3DFormat.A16B16G16R16: case D3DFormat.Q16W16V16U16: case D3DFormat.A16B16G16R16F: case D3DFormat.G32R32F: return(64); case D3DFormat.A32B32G32R32F: return(128); case D3DFormat.A1: return(1); } throw new ArgumentException("The format does not have a fixed size"); }
public static void DetermineFormat(ref PixelFormat pixelFormat, out DxgiFormat dxgiFormat, out D3DFormat d3dFormat) { switch (pixelFormat.Flags) { case PixelFormatFlags.Rgb | PixelFormatFlags.AlphaPixels: switch (pixelFormat.RgbBitCount) { case 32: switch (pixelFormat.RBitMask) { case 0x000000ff: dxgiFormat = DxgiFormat.R8G8B8A8_UNORM; d3dFormat = D3DFormat.A8B8G8R8; return; case 0x0000ffff: dxgiFormat = DxgiFormat.R16G16_UNORM; d3dFormat = D3DFormat.G16R16; return; case 0x000003ff: dxgiFormat = DxgiFormat.R10G10B10A2_UNORM; d3dFormat = D3DFormat.A2B10G10R10; return; case 0x00ff0000: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.A8R8G8B8; return; case 0x3ff00000: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.A2R10G10B10; return; } break; case 16: switch (pixelFormat.RBitMask) { case 0x7c00: dxgiFormat = DxgiFormat.B5G5R5A1_UNORM; d3dFormat = D3DFormat.A1R5G5B5; return; case 0x0f00: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.A4R4G4B4; return; case 0x00e0: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.A8R3G3B2; return; } break; } break; case PixelFormatFlags.Rgb: switch (pixelFormat.RgbBitCount) { case 32: switch (pixelFormat.RBitMask) { case 0x0000ffff: dxgiFormat = DxgiFormat.R16G16_UNORM; d3dFormat = D3DFormat.G16R16; return; case 0x00ff0000: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.X8R8G8B8; return; case 0x000000ff: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.X8B8G8R8; return; } break; case 24: if (pixelFormat.RBitMask == 0xff0000) { dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.R8G8B8; return; } break; case 16: switch (pixelFormat.RBitMask) { case 0xf800: dxgiFormat = DxgiFormat.B5G6R5_UNORM; d3dFormat = D3DFormat.R5G6B5; return; case 0x7c00: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.X1R5G5B5; return; case 0x0f00: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.X4R4G4B4; return; } break; } break; case PixelFormatFlags.Alpha: if (pixelFormat.ABitMask == 0xff) { dxgiFormat = DxgiFormat.A8_UNORM; d3dFormat = D3DFormat.A8; return; } break; case PixelFormatFlags.Luminance: switch (pixelFormat.RgbBitCount) { case 16: switch (pixelFormat.RBitMask) { case 0x00ff: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.A8L8; return; case 0xffff: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.L16; return; } break; case 8: switch (pixelFormat.RBitMask) { case 0xff: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.L8; return; case 0x0f: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.A4L4; return; } break; } break; case PixelFormatFlags.FourCC: switch (pixelFormat.FourCC) { case DXT1: dxgiFormat = DxgiFormat.BC1_UNORM; d3dFormat = D3DFormat.Dxt1; return; case DXT3: dxgiFormat = DxgiFormat.BC2_UNORM; d3dFormat = D3DFormat.Dxt3; return; case DXT5: dxgiFormat = DxgiFormat.BC3_UNORM; d3dFormat = D3DFormat.Dxt5; return; case BC4U: dxgiFormat = DxgiFormat.BC4_UNORM; d3dFormat = D3DFormat.Unknown; return; case BC4S: dxgiFormat = DxgiFormat.BC4_SNORM; d3dFormat = D3DFormat.Unknown; return; case ATI2: dxgiFormat = DxgiFormat.BC5_UNORM; d3dFormat = D3DFormat.Unknown; return; case BC5S: dxgiFormat = DxgiFormat.BC5_SNORM; d3dFormat = D3DFormat.Unknown; return; case RGBG: dxgiFormat = DxgiFormat.G8R8_G8B8_UNORM; d3dFormat = D3DFormat.R8G8_B8G8; return; case GRGB: dxgiFormat = DxgiFormat.R8G8_B8G8_UNORM; d3dFormat = D3DFormat.G8R8_G8B8; return; case 36: dxgiFormat = DxgiFormat.R16G16B16A16_UNORM; d3dFormat = D3DFormat.A16B16G16R16; return; case 110: dxgiFormat = DxgiFormat.R16G16B16A16_SNORM; d3dFormat = D3DFormat.Q16W16V16U16; return; case 111: dxgiFormat = DxgiFormat.R16_FLOAT; d3dFormat = D3DFormat.R16F; return; case 112: dxgiFormat = DxgiFormat.R16G16_FLOAT; d3dFormat = D3DFormat.G16R16F; return; case 113: dxgiFormat = DxgiFormat.R16G16B16A16_FLOAT; d3dFormat = D3DFormat.A16B16G16R16F; return; case 114: dxgiFormat = DxgiFormat.R32_FLOAT; d3dFormat = D3DFormat.R32F; return; case 115: dxgiFormat = DxgiFormat.R32G32_FLOAT; d3dFormat = D3DFormat.G32R32F; return; case 116: dxgiFormat = DxgiFormat.R32G32B32A32_FLOAT; d3dFormat = D3DFormat.A32B32G32R32F; return; case DXT2: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.Dxt2; return; case DXT4: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.Dxt4; return; case UYVY: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.Uyvy; return; case YUY2: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.Yuy2; return; case 117: dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.CxV8U8; return; case DX10: throw new InvalidOperationException("This methjod is unappropriate for DX10-flagged formats"); } break; case PixelFormatFlags.Yuv: break; ////default: //// throw new ArgumentOutOfRangeException(); } dxgiFormat = DxgiFormat.UNKNOWN; d3dFormat = D3DFormat.Unknown; }
public BreckfestSettings() { this.clutter = false; this.raw = false; this.force = false; this.norename = false; this.format = D3DFormat.DXT5; }
public void Read(BinaryReader br) { // Full structure of rage::grcTexturePC // rage::datBase VTable = br.ReadUInt32(); // rage::pgBase BlockMapOffset = ResourceUtil.ReadOffset(br); // Texture Info struct: Unknown1 = br.ReadUInt32(); // BYTE, BYTE, WORD Unknown2 = br.ReadUInt32(); Unknown3 = br.ReadUInt32(); uint nameOffset = ResourceUtil.ReadOffset(br); Unknown4 = br.ReadUInt32(); // Texture Data struct: Width = br.ReadUInt16(); Height = br.ReadUInt16(); Format = (D3DFormat) br.ReadInt32(); StrideSize = br.ReadUInt16(); Type = br.ReadByte(); Levels = br.ReadByte(); UnknownFloat1 = br.ReadSingle(); UnknownFloat2 = br.ReadSingle(); UnknownFloat3 = br.ReadSingle(); UnknownFloat4 = br.ReadSingle(); UnknownFloat5 = br.ReadSingle(); UnknownFloat6 = br.ReadSingle(); PrevTextureInfoOffset = ResourceUtil.ReadOffset(br); NextTextureInfoOffset = ResourceUtil.ReadOffset(br); RawDataOffset = ResourceUtil.ReadDataOffset(br); Unknown6 = br.ReadUInt32(); // Read texture name br.BaseStream.Seek(nameOffset, SeekOrigin.Begin); Name = ResourceUtil.ReadNullTerminatedString(br); }
public static int GetMipSize(D3DFormat format, ushort width, ushort height) { width = Math.Max((ushort)4, width); height = Math.Max((ushort)4, height); if (format == D3DFormat.DXT1) { return (((width + 3) / 4) * ((height + 3) / 4)) * 8; } if (format == D3DFormat.DXT5 || format == D3DFormat.ATI2) { return (((width + 3) / 4) * ((height + 3) / 4)) * 16; } return width * height * 4; }
public static TDX LoadFromBitmap(Bitmap asset, string name, D3DFormat format) { TDX tdx = null; if (tdx == null) { tdx = new TDX(); var b = asset; var flags = Squish.SquishFlags.kDxt1; tdx.Name = name; tdx.Format = format; switch (tdx.Format) { case D3DFormat.DXT1: flags = Squish.SquishFlags.kDxt1; break; case D3DFormat.DXT5: flags = Squish.SquishFlags.kDxt5; break; } var mipBitmaps = GenerateMips(b, b.Width, b.Height); foreach (var mb in mipBitmaps) { var mip = new MipMap(); mip.Width = mb.Width; mip.Height = mb.Height; byte[] data = new byte[mb.Width * mb.Height * 4]; byte[] dest = new byte[Squish.Squish.GetStorageRequirements(mb.Width, mb.Height, flags | Squish.SquishFlags.kColourIterativeClusterFit | Squish.SquishFlags.kWeightColourByAlpha)]; int ii = 0; for (int y = 0; y < mb.Height; y++) { for (int x = 0; x < mb.Width; x++) { var p = mb.GetPixel(x, y); data[ii + 0] = p.R; data[ii + 1] = p.G; data[ii + 2] = p.B; data[ii + 3] = p.A; ii += 4; } } if (format == D3DFormat.ATI2) dest = BC5Unorm.Compress(data, (ushort)mb.Width, (ushort)mb.Height, GetMipSize(format, (ushort)mb.Width, (ushort)mb.Height)); else Squish.Squish.CompressImage(data, mb.Width, mb.Height, ref dest, flags | Squish.SquishFlags.kColourClusterFit); mip.Data = dest; tdx.MipMaps.Add(mip); } } return tdx; }
public void SaveTexture(VTMapEntry textureEntry, string outputPath, bool SaveTDX, bool SaveTGA, bool SaveOther, ImageFormat format) { int divisor = GetDivisor(); int xPos = PageNum == 0 ? textureEntry.Column : textureEntry.Column / divisor; int yPos = PageNum == 0 ? textureEntry.Row : textureEntry.Row / divisor; int tileRow = (int)Math.Floor(yPos / (float)TileSize); int tileCol = (int)Math.Floor(xPos / (float)TileSize); tileRow = tileRow < 0 ? 0 : tileRow; tileCol = tileCol < 0 ? 0 : tileCol; int numTilesX = (int)Math.Ceiling(textureEntry.GetWidth(PageNum) / (float)TileSize); int numTilesY = (int)Math.Ceiling(textureEntry.GetHeight(PageNum) / (float)TileSize); int bitmapheight = textureEntry.GetHeight(PageNum); int bitmapwidth = textureEntry.GetWidth(PageNum); Bitmap stitched = new Bitmap(bitmapwidth, bitmapheight); D3DFormat guessedFormat = D3DFormat.DXT5; bool formatGuessed = false; for (int row = tileRow; row < Tiles.Count && row <= tileRow + numTilesY; row++) { int rowStart = row * TileSize; int rowEnd = (row + 1) * TileSize; for (int col = tileCol; col < Tiles[row].Count && col <= tileCol + numTilesX; col++) { if (Tiles[row][col] == null) { continue; } int colStart = col * TileSize; int colEnd = (col + 1) * TileSize; if (Tiles[row][col].Texture == null) { Tiles[row][col].GetTextureFromZAD(); } if (Tiles[row][col].Texture == null) { continue; } if (!formatGuessed) { guessedFormat = Tiles[row][col].Texture.Format; } Bitmap decompressed = Tiles[row][col].Texture.GetBitmap(); int firstPixelRow = rowStart < yPos ? yPos - rowStart : TilePadding; int lastPixelRow = TileSize + TilePadding; int firstPixelCol = colStart < xPos ? xPos - colStart : TilePadding; int lastPixelCol = TileSize + TilePadding; for (int y = firstPixelRow; y < lastPixelRow; y++) { if ((row * TileSize + (y - TilePadding)) - (yPos) >= bitmapheight) { break; } for (int x = firstPixelCol; x < lastPixelCol; x++) { if ((col * TileSize + (x - TilePadding)) - xPos >= bitmapwidth) { break; } Color pixelColour = decompressed.GetPixel(x, y); stitched.SetPixel((col * TileSize + (x - TilePadding)) - xPos, (row * TileSize + (y - TilePadding)) - (yPos), pixelColour); } } } } if (!Directory.Exists(Path.GetDirectoryName(outputPath))) { Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); } if (SaveTDX) { TDX newtdx = TDX.LoadFromBitmap(stitched, Path.GetFileNameWithoutExtension(outputPath), guessedFormat); newtdx.Save(outputPath); } if (SaveTGA) { if (File.Exists(outputPath)) { File.Delete(outputPath); } using (FileStream stream = new FileStream(outputPath, FileMode.OpenOrCreate)) using (BinaryWriter writer = new BinaryWriter(stream)) { int tgaWidth = bitmapwidth; int tgaHeight = bitmapheight; int tgaTileRowCount = Tiles.Count - 1; writer.Write((byte)0); writer.Write((byte)0); writer.Write((byte)2); writer.Write((short)0); writer.Write((short)0); writer.Write((byte)0); writer.Write((short)0); writer.Write((short)0); writer.Write((short)bitmapwidth); writer.Write((short)bitmapheight); writer.Write((byte)32); writer.Write((byte)0); BitmapData data = stitched.LockBits(new Rectangle(0, 0, stitched.Width, stitched.Height), ImageLockMode.ReadOnly, stitched.PixelFormat); unsafe { // important to use the BitmapData object's Width and Height // properties instead of the Bitmap's. for (int x = data.Height - 1; x >= 0; x--) { byte *row = (byte *)data.Scan0 + (x * data.Stride); for (int y = 0; y < data.Width; y++) { int columnOffset = y * 4; byte B = row[columnOffset]; byte G = row[columnOffset + 1]; byte R = row[columnOffset + 2]; byte alpha = row[columnOffset + 3]; writer.Write(B); writer.Write(G); writer.Write(R); writer.Write(alpha); } } } stitched.UnlockBits(data); } } if (SaveOther) { using (FileStream str = File.OpenWrite(outputPath)) { stitched.Save(str, format); } } stitched.Dispose(); }