This article's documentation is for anything that uses the Source engine. Click here for more information.

XTF

From Valve Developer Community
Jump to navigation Jump to search
English (en)Translate (Translate)

The Xbox Texture Format (XTF) is the proprietary texture format used for the Original Xbox Original Xbox port of Half-Life 2 Half-Life 2. It is modified from VTF v7.2, with additional features and quirks that reflect the needs of the Xbox hardware.

Tools

XTF files can be converted from VTF files, and can be viewed, edited and converted back using the following tools.

Format differences

  • An environment map is a six-faced cubemap. Since spheremap support had been dropped by this time, to optimize file size and RAM there is no seventh face, despite this format being forked from VTF v7.2.
  • Non-compressed formats such as RGB888 or BGRA8888 are swizzled, and must be deswizzled to be viewed correctly. The swizzling code must be written in a certain way to allow for non-square non-compressed textures, which are used by the game.
  • Low resolution image data is always stored in RGB888 format.
  • The P8 format is supported and widely used by the game to save VRAM, since support exists at the hardware level on this console. When the P8 format is used, a lookup table of 256 BGRA8888 pixels will be present after the header, and each byte in the image data will index into this table. There is a unique palette for each texture frame, and each palette is stored in a tightly packed sequence after the header.
  • Fallback texture data is a copy of the texture at 8x8 resolution and lower, stored near the header in the preload region. The preload region is copied to a different location when building the game, and the game will be able to use the fallback texture to read low quality texture data without loading the actual texture file yet. The fallback data uses the same format as the high resolution image data. To the best of my knowledge volumetric textures cannot have fallback data, as they do not support slices.
  • Mips are stored in the same order as DDS—largest to smallest—rather than the VTF order of smallest to largest.
  • The file signature is "XTF\0" instead of "VTF\0". The major and minor version are always v5.0.
  • There are frequent instances of padding to align parts of the file to a 512 byte boundary. XTF files are always unpacked to and loaded from the console's internal hard drive, so this is likely to align file components with the hard drive sector size.

Texture flags

In addition to VTF flags used in v7.2, there are three new flags for XTF:

Flag Value Comment
Preswizzled 0x4000000 Used to tell VTEX the input image is already swizzled.
Cacheable 0x8000000 Candidate for caching.
Unfilterable OK 0x10000000 Unknown.

File format

The XTF file format is described as follows.

XTF layout

  1. XTF Header
  2. XTF Low Resolution Image Data
  3. If format is P8
    • For Each Frame (First to Last)
      • XTF Frame Palette
  4. If fallback image data exists:
    • For Each Mipmap (Largest to Smallest)
      • For Each Frame (First to Last)
        • For Each Face (First to Last)
          • XTF Fallback Image Data
    • Padding to nearest 512 byte boundary
  5. For Each Mipmap (Largest to Smallest)
    • For Each Frame (First to Last)
      • For Each Face (First to Last)
        • For Each Z Slice (Min to Max; Varies with Mipmap)
          • XTF High Resolution Image Data
      • Padding to nearest 512 byte boundary (only if file size thus far exceeds 512 bytes)

XTF header

typedef struct tagXTFHEADER
{
    char            signature[4];        // File signature ("XTF\0", or as little-endian integer, 0x00465458).
    unsigned int    version[2];          // version[0].version[1] (always 5.0).
    unsigned int    headerSize;          // Size of the header struct (always 58 bytes).
    unsigned int    flags;               // XTF flags (from VTF v7.2, as well as the 3 XTF specific flags).
    unsigned short  width;               // Width of the largest mipmap in pixels.
    unsigned short  height;              // Height of the largest mipmap in pixels.
    unsigned short  depth;               // Depth of the largest mipmap.
    unsigned short  frames;              // Number of frames, if animated (1 for no animation).
    unsigned short  preloadSize;         // The number of bytes at the start of the file to preload. This includes the header, palette data, thumbnail, and fallback data, excluding padding if present.
    unsigned short  imageOffset;         // The location in the file to seek to to start reading image data.
    float           reflectivity[3];     // Reflectivity vector.
    float           bumpmapScale;        // Bumpmap scale.
    int             imageFormat;         // High resolution image format.
    unsigned char   lowResImageWidth;    // Low resolution image width.
    unsigned char   lowResImageHeight;   // Low resolution image height.
    unsigned char   fallbackImageWidth;  // Fallback image width.
    unsigned char   fallbackImageHeight; // Fallback image height.
    unsigned char   mipSkip;             // Scales downscaled textures back up to their original size on map geometry. E.g. if mip skip is 1, a 1024x1024 texture is mapped to 2048x2048 dimensions, since texture size determines calculated UVs in the BSP format.
    unsigned char   padding[1];          // This struct isn't tightly packed, so there's a leftover byte at the end.
} XTFHEADER;

Other implementations

  • The MIT C++ library SourcePP SourcePP (with C and Python wrappers)

See also