diff --git a/DDSTextureLoader/DDSTextureLoader.cpp b/DDSTextureLoader/DDSTextureLoader.cpp index 20d8660..5bd454e 100644 --- a/DDSTextureLoader/DDSTextureLoader.cpp +++ b/DDSTextureLoader/DDSTextureLoader.cpp @@ -33,6 +33,8 @@ #pragma comment(lib,"dxguid.lib") #endif +using namespace DirectX; + //-------------------------------------------------------------------------------------- // Macros //-------------------------------------------------------------------------------------- @@ -99,6 +101,11 @@ struct DDS_PIXELFORMAT #define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME +enum DDS_MISC_FLAGS2 +{ + DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x3L, +}; + typedef struct { uint32_t size; @@ -123,7 +130,7 @@ typedef struct uint32_t resourceDimension; uint32_t miscFlag; // see D3D11_RESOURCE_MISC_FLAG uint32_t arraySize; - uint32_t reserved; + uint32_t miscFlags2; } DDS_HEADER_DXT10; #pragma pack(pop) @@ -237,7 +244,7 @@ static HRESULT LoadTextureDataFromFile( _In_z_ const wchar_t* fileName, return E_FAIL; } - DDS_HEADER* hdr = reinterpret_cast( ddsData.get() + sizeof( uint32_t ) ); + auto hdr = reinterpret_cast( ddsData.get() + sizeof( uint32_t ) ); // Verify header to validate DDS file if (hdr->size != sizeof(DDS_HEADER) || @@ -1109,7 +1116,7 @@ static HRESULT CreateTextureFromDDS( _In_ ID3D11Device* d3dDevice, if ((header->ddspf.flags & DDS_FOURCC) && (MAKEFOURCC( 'D', 'X', '1', '0' ) == header->ddspf.fourCC )) { - const DDS_HEADER_DXT10* d3d10ext = reinterpret_cast( (const char*)header + sizeof(DDS_HEADER) ); + auto d3d10ext = reinterpret_cast( (const char*)header + sizeof(DDS_HEADER) ); arraySize = d3d10ext->arraySize; if (arraySize == 0) @@ -1310,6 +1317,28 @@ static HRESULT CreateTextureFromDDS( _In_ ID3D11Device* d3dDevice, return hr; } + +//-------------------------------------------------------------------------------------- +static DDS_ALPHA_MODE GetAlphaMode( _In_ const DDS_HEADER* header ) +{ + if ( header->ddspf.flags & DDS_FOURCC ) + { + if ( MAKEFOURCC( 'D', 'X', '1', '0' ) == header->ddspf.fourCC ) + { + auto d3d10ext = reinterpret_cast( (const char*)header + sizeof(DDS_HEADER) ); + return static_cast(d3d10ext->miscFlags2 & DDS_MISC_FLAGS2_ALPHA_MODE_MASK); + } + else if ( ( MAKEFOURCC( 'D', 'X', 'T', '2' ) == header->ddspf.fourCC ) + || ( MAKEFOURCC( 'D', 'X', 'T', '4' ) == header->ddspf.fourCC ) ) + { + return DDS_ALPHA_MODE_PREMULTIPLIED; + } + } + + return DDS_ALPHA_MODE_STRAIGHT; +} + + //-------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT DirectX::CreateDDSTextureFromMemory( ID3D11Device* d3dDevice, @@ -1317,11 +1346,12 @@ HRESULT DirectX::CreateDDSTextureFromMemory( ID3D11Device* d3dDevice, size_t ddsDataSize, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, - size_t maxsize ) + size_t maxsize, + DDS_ALPHA_MODE* alphaMode ) { return CreateDDSTextureFromMemoryEx( d3dDevice, ddsData, ddsDataSize, maxsize, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, - texture, textureView ); + texture, textureView, alphaMode ); } _Use_decl_annotations_ @@ -1335,7 +1365,8 @@ HRESULT DirectX::CreateDDSTextureFromMemoryEx( ID3D11Device* d3dDevice, unsigned int miscFlags, bool forceSRGB, ID3D11Resource** texture, - ID3D11ShaderResourceView** textureView ) + ID3D11ShaderResourceView** textureView, + DDS_ALPHA_MODE* alphaMode ) { if ( texture ) { @@ -1363,7 +1394,7 @@ HRESULT DirectX::CreateDDSTextureFromMemoryEx( ID3D11Device* d3dDevice, return E_FAIL; } - const DDS_HEADER* header = reinterpret_cast( ddsData + sizeof( uint32_t ) ); + auto header = reinterpret_cast( ddsData + sizeof( uint32_t ) ); // Verify header to validate DDS file if (header->size != sizeof(DDS_HEADER) || @@ -1405,6 +1436,9 @@ HRESULT DirectX::CreateDDSTextureFromMemoryEx( ID3D11Device* d3dDevice, { SetDebugObjectName(*textureView, "DDSTextureLoader"); } + + if ( alphaMode ) + *alphaMode = GetAlphaMode( header ); } return hr; @@ -1416,11 +1450,12 @@ HRESULT DirectX::CreateDDSTextureFromFile( ID3D11Device* d3dDevice, const wchar_t* fileName, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, - size_t maxsize ) + size_t maxsize, + DDS_ALPHA_MODE* alphaMode ) { return CreateDDSTextureFromFileEx( d3dDevice, fileName, maxsize, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, - texture, textureView ); + texture, textureView, alphaMode ); } _Use_decl_annotations_ @@ -1433,7 +1468,8 @@ HRESULT DirectX::CreateDDSTextureFromFileEx( ID3D11Device* d3dDevice, unsigned int miscFlags, bool forceSRGB, ID3D11Resource** texture, - ID3D11ShaderResourceView** textureView ) + ID3D11ShaderResourceView** textureView, + DDS_ALPHA_MODE* alphaMode ) { if ( texture ) { @@ -1470,9 +1506,9 @@ HRESULT DirectX::CreateDDSTextureFromFileEx( ID3D11Device* d3dDevice, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, texture, textureView ); -#if defined(_DEBUG) || defined(PROFILE) if ( SUCCEEDED(hr) ) { +#if defined(_DEBUG) || defined(PROFILE) if (texture != 0 || textureView != 0) { CHAR strFileA[MAX_PATH]; @@ -1514,8 +1550,11 @@ HRESULT DirectX::CreateDDSTextureFromFileEx( ID3D11Device* d3dDevice, } } } - } #endif + if ( alphaMode ) + *alphaMode = GetAlphaMode( header ); + } + return hr; } diff --git a/DDSTextureLoader/DDSTextureLoader.h b/DDSTextureLoader/DDSTextureLoader.h index 0b099f8..729e22e 100644 --- a/DDSTextureLoader/DDSTextureLoader.h +++ b/DDSTextureLoader/DDSTextureLoader.h @@ -41,19 +41,29 @@ namespace DirectX { + enum DDS_ALPHA_MODE + { + DDS_ALPHA_MODE_STRAIGHT = 0, + DDS_ALPHA_MODE_PREMULTIPLIED = 1, + DDS_ALPHA_MODE_4TH_CHANNEL = 2, + DDS_ALPHA_MODE_OPAQUE = 3, + }; + HRESULT CreateDDSTextureFromMemory( _In_ ID3D11Device* d3dDevice, _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, _In_ size_t ddsDataSize, _Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11ShaderResourceView** textureView, - _In_ size_t maxsize = 0 + _In_ size_t maxsize = 0, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr ); HRESULT CreateDDSTextureFromFile( _In_ ID3D11Device* d3dDevice, _In_z_ const wchar_t* szFileName, _Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11ShaderResourceView** textureView, - _In_ size_t maxsize = 0 + _In_ size_t maxsize = 0, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr ); HRESULT CreateDDSTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, @@ -66,7 +76,8 @@ namespace DirectX _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Out_opt_ ID3D11Resource** texture, - _Out_opt_ ID3D11ShaderResourceView** textureView + _Out_opt_ ID3D11ShaderResourceView** textureView, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr ); HRESULT CreateDDSTextureFromFileEx( _In_ ID3D11Device* d3dDevice, @@ -78,6 +89,7 @@ namespace DirectX _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Out_opt_ ID3D11Resource** texture, - _Out_opt_ ID3D11ShaderResourceView** textureView + _Out_opt_ ID3D11ShaderResourceView** textureView, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr ); } \ No newline at end of file