Руководство по программированию для DDS

Direct3D реализует формат файла DDS для хранения несжатых или сжатых текстур (DXTn). Формат файла реализует несколько немного различных типов, предназначенных для хранения разных типов данных, и поддерживает однослойные текстуры, текстуры с MIP-картами, карты кубов, объемные карты и массивы текстур (в Direct3D 10/11). В этом разделе описывается макет файла DDS.

Сведения о создании текстуры в Direct3D 11 см. в разделе Практическое руководство. Создание текстуры. Справку по Direct3D 9 см. в статье Поддержка текстур в D3DX (Direct3D 9).

Макет файла DDS

DDS-файл — это двоичный файл, который содержит следующую информацию:

  • Параметр DWORD (контрольное число), содержащий четырехсимвольное кодовое значение «DDS « (0x20534444).

  • Описание данных, содержащихся в файле.

    Данные описываются с описанием заголовка с помощью DDS_HEADER; формат пикселей определяется с помощью DDS_PIXELFORMAT. Обратите внимание, что структуры DDS_HEADER и DDS_PIXELFORMAT заменяют устаревшие структуры DirectDraw 7 DDSURFACEDESC2, DDSCAPS2 и DDPIXELFORMAT DirectDraw 7. DDS_HEADER является двоичным эквивалентом DDSURFACEDESC2 и DDSCAPS2. DDS_PIXELFORMAT является двоичным эквивалентом DDPIXELFORMAT.

    DWORD               dwMagic;
    DDS_HEADER          header;
    
    

    Если параметру DDS_PIXELFORMAT dwFlags присвоено значение DDPF_FOURCC а параметру dwFourCC присвоено значение DX10, будет представлена дополнительная структура DDS_HEADER_DXT10 для размещения массивов текстур или форматов DXGI, которые не могут быть выражены как формат пикселей RGB, например форматы с плавающей запятой, форматы sRGB и т. д. При наличии структуры DDS_HEADER_DXT10 все описание данных будет выглядеть следующим образом.

    DWORD               dwMagic;
    DDS_HEADER          header;
    DDS_HEADER_DXT10    header10;
    
  • Указатель на массив байтов, содержащий сведения о главной плоскости.

    BYTE bdata[]
    
  • Указатель на массив байтов, содержащий сведения об остальных плоскостях, например об уровнях MIP, гранях в кубической текстуре, глубин в объемной текстуре. В статьях, ссылки на которые приведены ниже, представлены дополнительные сведения о структуре DDS-файлов для текстуры, кубической текстуры или объемной текстуры.

    BYTE bdata2[]
    

Для широкой поддержки оборудования рекомендуется использовать DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB. DXGI_FORMAT_BC3_UNORM или DXGI_FORMAT_BC3_UNORM_SRGB формате.

Дополнительные сведения о сжатых форматах текстур см. в разделах Сжатие блочных текстур в Direct3D 11 и Сжатие блоков (Direct3D 10).

Библиотека D3DX (например, D3DX11.lib) и другие аналогичные библиотеки ненадежно или несогласованно предоставляют значение тона в элементе dwPitchOrLinearSizeструктуры DDS_HEADER . Поэтому при чтении и записи в DDS-файлы рекомендуется вычислять тон одним из следующих способов для указанных форматов:

  • Для форматов со сжатием блоков вычисляйте тон как:

    max( 1, ((ширина+3)/4) ) * размер блока

    Размер блока составляет 8 байт для форматов DXT1, BC1 и BC4 и 16 байт для других форматов со сжатием блоков.

  • Для R8G8_B8G8, G8R8_G8B8, устаревших форматов, упакованных в UYVY, и устаревших форматов, упакованных в формате YUY2, вычисляете тон следующим образом:

    ((ширина+1) >> 1) * 4

  • Для других форматов вычисляете тон как:

    ( ширина * бит на пиксель + 7 ) / 8

    Вы делите на 8 для выравнивания байтов.

Примечание

Вычисленное значение тона не всегда равно тоналу, который предоставляет среда выполнения. В некоторых ситуациях он выравнивается по DWORD, а в других — по байтам. Поэтому рекомендуется копировать строку сканирования за один раз, а не пытаться скопировать все изображение в одной копии.

Варианты DDS

Существует множество средств, которые создают и используют DDS-файлы, но они могут отличаться в деталях того, что им нужно в заголовке. Записи должны заполнять заголовки как можно более полно, а читатели должны проверка минимальные значения для максимальной совместимости. Чтобы проверить DDS-файл, средство чтения должно убедиться, что длина файла не менее 128 байт для размещения магического значения и базового заголовка, магическое значение — 0x20534444 ("DDS"), размер DDS_HEADER — 124, а DDS_PIXELFORMAT в заголовке — 32. Если параметру DDS_PIXELFORMAT dwFlags присвоено значение DDPF_FOURCC, а параметру dwFourCC присвоено значение DX10, общий размер файла должен быть не менее 148 байт.

Существуют некоторые распространенные варианты, в которых формат пикселей устанавливается в DDPF_FOURCC коде, где dwFourCC имеет значение D3DFORMAT или значение перечисления DXGI_FORMAT. Невозможно определить, является ли значение перечисления D3DFORMAT или DXGI_FORMAT, поэтому настоятельно рекомендуется использовать расширение DX10 и заголовок DDS_HEADER_DXT10 вместо этого для хранения dxgiFormat, если базовый DDS_PIXELFORMAT не может выразить формат.

Стандартный DDS_PIXELFORMAT следует использовать для обеспечения максимальной совместимости для хранения несжатых данных RGB и данных DXT1-5, так как не все средства DDS поддерживают расширение DX10.

Использование массивов текстур в Direct3D 10/11

Новые структуры DDS (DDS_HEADER и DDS_HEADER_DXT10) в Direct3D 10/11 расширяют формат файлов DDS для поддержки массива текстур, который является новым типом ресурсов в Direct3D 10/11. Ниже приведен пример кода, который показывает, как получить доступ к различным уровням MIP-карты в массиве текстур с помощью новых заголовков.

DWORD               dwMagic;
DDS_HEADER          header;
DDS_HEADER_DXT10    header10;
   
for (int iArrayElement = 0; iArrayElement < header10.arraySize; iArrayElement++)
{
   for (int iMipLevel = 0; iMipLevel < header.dwMipMapCount; iMipLevel++)
   {
     ...
   }
}       

Распространенные форматы ресурсов файлов DDS и связанное содержимое заголовка

Формат ресурса dwFlags dwRGBBitCount dwRBitMask dwGBitMask dwBBitMask dwABitMask
DXGI_FORMAT_R8G8B8A8_UNORM
D3DFMT_A8B8G8R8
DDS_RGBA 32 0xff 0xff00 0xff0000 0xff000000
DXGI_FORMAT_R16G16_UNORM
D3DFMT_G16R16
DDS_RGBA 32 0xffff 0xffff0000
**
DXGI_FORMAT_R10G10B10A2_UNORM
D3DFMT_A2B10G10R10
DDS_RGBA 32 0x3ff 0xffc00 0x3ff00000
DXGI_FORMAT_R16G16_UNORM
D3DFMT_G16R16
DDS_RGB 32 0xffff 0xffff0000
DXGI_FORMAT_B5G5R5A1_UNORM
D3DFMT_A1R5G5B5
DDS_RGBA 16 0x7c00 0x3e0 0x1f 0x8000
DXGI_FORMAT_B5G6R5_UNORM
D3FMT_R5G6B5
DDS_RGB 16 0xf800 0x7e0 0x1f
DXGI_A8_UNORM
D3DFMT_A8
DDS_ALPHA 8 0xff
D3DFMT_A8R8G8B8
DDS_RGBA 32 0xff0000 0xff00 0xff 0xff000000
D3DFMT_X8R8G8B8
DDS_RGB 32 0xff0000 0xff00 0xff
D3DFMT_X8B8G8R8
DDS_RGB 32 0xff 0xff00 0xff0000
**
D3DFMT_A2R10G10B10
DDS_RGBA 32 0x3ff00000 0xffc00 0x3ff 0xc0000000
D3DFMT_R8G8B8
DDS_RGB 24 0xff0000 0xff00 0xff
D3DFMT_X1R5G5B5
DDS_RGB 16 0x7c00 0x3e0 0x1f
D3DFMT_A4R4G4B4
DDS_RGBA 16 0xf00 0xf0 0xf 0xf000
D3DFMT_X4R4G4B4
DDS_RGB 16 0xf00 0xf0 0xf
D3DFMT_A8R3G3B2
DDS_RGBA 16 0xe0 0x1c 0x3 0xff00
D3DFMT_A8L8
DDS_LUMINANCE 16 0xff 0xff00
D3DFMT_L16
DDS_LUMINANCE 16 0xffff
D3DFMT_L8
DDS_LUMINANCE 8 0xff
D3DFMT_A4L4
DDS_LUMINANCE 8 0xf 0xf0
Формат ресурса dwFlags dwFourCC
DXGI_FORMAT_BC1_UNORM
D3DFMT_DXT1
DDS_FOURCC "DXT1"
DXGI_FORMAT_BC2_UNORM
D3DFMT_DXT3
DDS_FOURCC "DXT3"
DXGI_FORMAT_BC3_UNORM
D3DFMT_DXT5
DDS_FOURCC "DXT5"
*
DXGI_FORMAT_BC4_UNORM
DDS_FOURCC "BC4U"
*
DXGI_FORMAT_BC4_SNORM
DDS_FOURCC "BC4S"
*
DXGI_FORMAT_BC5_UNORM
DDS_FOURCC "ATI2"
*
DXGI_FORMAT_BC5_SNORM
DDS_FOURCC "BC5S"
DXGI_FORMAT_R8G8_B8G8_UNORM
D3DFMT_R8G8_B8G8
DDS_FOURCC "RGBG"
DXGI_FORMAT_G8R8_G8B8_UNORM
D3DFMT_G8R8_G8B8
DDS_FOURCC "GRGB"
*
DXGI_FORMAT_R16G16B16A16_UNORM
D3DFMT_A16B16G16R16
DDS_FOURCC 36
*
DXGI_FORMAT_R16G16B16A16_SNORM
D3DFMT_Q16W16V16U16
DDS_FOURCC 110
*
DXGI_FORMAT_R16_FLOAT
D3DFMT_R16F
DDS_FOURCC 111
*
DXGI_FORMAT_R16G16_FLOAT
D3DFMT_G16R16F
DDS_FOURCC 112
*
DXGI_FORMAT_R16G16B16A16_FLOAT
D3DFMT_A16B16G16R16F
DDS_FOURCC 113
*
DXGI_FORMAT_R32_FLOAT
D3DFMT_R32F
DDS_FOURCC 114
*
DXGI_FORMAT_R32G32_FLOAT
D3DFMT_G32R32F
DDS_FOURCC 115
*
DXGI_FORMAT_R32G32B32A32_FLOAT
D3DFMT_A32B32G32R32F
DDS_FOURCC 116
D3DFMT_DXT2
DDS_FOURCC "DXT2"
D3DFMT_DXT4
DDS_FOURCC "DXT4"
D3DFMT_UYVY
DDS_FOURCC "UYVY"
D3DFMT_YUY2
DDS_FOURCC YUY2
D3DFMT_CxV8U8
DDS_FOURCC 117
Любой формат DXGI DDS_FOURCC "DX10"

* = надежное средство чтения DDS должно иметь возможность обрабатывать эти устаревшие коды формата. Однако такое средство чтения DDS должно предпочесть использовать расширение заголовка DX10 при записи этих кодов формата, чтобы избежать неоднозначности.

** = Из-за некоторых давних проблем в распространенных реализациях средств чтения и записи DDS наиболее надежным способом записи данных типа 10:10:10:2 является использование расширения заголовка DX10 с кодом DXGI_FORMAT "24" (т. е. значение DXGI_FORMAT_R10G10B10A2_UNORM). D3DFMT_A2R10G10B10 данные должны быть преобразованы в данные типа 10:10:10:2 перед записью в виде DDS-файла DXGI_FORMAT_R10G10B10A2_UNORM формата.

DDS