mirror of
https://github.com/microsoft/DirectXTex.git
synced 2025-07-12 21:20:13 +02:00
Return TEX_ALPHA_MODE_OPAQUE metadata if the reader knows it returned opaque alpha (#150)
This commit is contained in:
parent
aacd3919e8
commit
7bda0c3a57
@ -427,9 +427,6 @@ namespace
|
|||||||
if (metadata.format == DXGI_FORMAT_UNKNOWN)
|
if (metadata.format == DXGI_FORMAT_UNKNOWN)
|
||||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||||
|
|
||||||
if (convFlags & CONV_FLAGS_PMALPHA)
|
|
||||||
metadata.miscFlags2 |= TEX_ALPHA_MODE_PREMULTIPLIED;
|
|
||||||
|
|
||||||
// Special flag for handling LUMINANCE legacy formats
|
// Special flag for handling LUMINANCE legacy formats
|
||||||
if (flags & DDS_FLAGS_EXPAND_LUMINANCE)
|
if (flags & DDS_FLAGS_EXPAND_LUMINANCE)
|
||||||
{
|
{
|
||||||
@ -515,6 +512,16 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implicit alpha mode
|
||||||
|
if (convFlags & CONV_FLAGS_NOALPHA)
|
||||||
|
{
|
||||||
|
metadata.SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
|
||||||
|
}
|
||||||
|
else if (convFlags & CONV_FLAGS_PMALPHA)
|
||||||
|
{
|
||||||
|
metadata.SetAlphaMode(TEX_ALPHA_MODE_PREMULTIPLIED);
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,6 +282,7 @@ namespace
|
|||||||
metadata.depth = metadata.arraySize = metadata.mipLevels = 1;
|
metadata.depth = metadata.arraySize = metadata.mipLevels = 1;
|
||||||
metadata.format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
metadata.format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||||
metadata.dimension = TEX_DIMENSION_TEXTURE2D;
|
metadata.dimension = TEX_DIMENSION_TEXTURE2D;
|
||||||
|
metadata.SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -159,6 +159,7 @@ namespace
|
|||||||
|
|
||||||
case 24:
|
case 24:
|
||||||
metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
metadata.SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
|
||||||
if (convFlags)
|
if (convFlags)
|
||||||
*convFlags |= CONV_FLAGS_EXPAND;
|
*convFlags |= CONV_FLAGS_EXPAND;
|
||||||
// We could use DXGI_FORMAT_B8G8R8X8_UNORM, but we prefer DXGI 1.0 formats
|
// We could use DXGI_FORMAT_B8G8R8X8_UNORM, but we prefer DXGI 1.0 formats
|
||||||
@ -280,6 +281,8 @@ namespace
|
|||||||
auto sPtr = static_cast<const uint8_t*>(pSource);
|
auto sPtr = static_cast<const uint8_t*>(pSource);
|
||||||
const uint8_t* endPtr = sPtr + size;
|
const uint8_t* endPtr = sPtr + size;
|
||||||
|
|
||||||
|
bool opaquealpha = false;
|
||||||
|
|
||||||
switch (image->format)
|
switch (image->format)
|
||||||
{
|
{
|
||||||
//--------------------------------------------------------------------------- 8-bit
|
//--------------------------------------------------------------------------- 8-bit
|
||||||
@ -349,7 +352,9 @@ namespace
|
|||||||
//-------------------------------------------------------------------------- 16-bit
|
//-------------------------------------------------------------------------- 16-bit
|
||||||
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
||||||
{
|
{
|
||||||
bool nonzeroa = false;
|
uint32_t minalpha = 255;
|
||||||
|
uint32_t maxalpha = 0;
|
||||||
|
|
||||||
for (size_t y = 0; y < image->height; ++y)
|
for (size_t y = 0; y < image->height; ++y)
|
||||||
{
|
{
|
||||||
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
|
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
|
||||||
@ -374,8 +379,11 @@ namespace
|
|||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
auto t = static_cast<uint16_t>(uint32_t(*sPtr) | uint32_t(*(sPtr + 1u) << 8));
|
auto t = static_cast<uint16_t>(uint32_t(*sPtr) | uint32_t(*(sPtr + 1u) << 8));
|
||||||
if (t & 0x8000)
|
|
||||||
nonzeroa = true;
|
uint32_t alpha = (t & 0x8000) ? 255 : 0;
|
||||||
|
minalpha = std::min(minalpha, alpha);
|
||||||
|
maxalpha = std::max(maxalpha, alpha);
|
||||||
|
|
||||||
sPtr += 2;
|
sPtr += 2;
|
||||||
|
|
||||||
for (; j > 0; --j, ++x)
|
for (; j > 0; --j, ++x)
|
||||||
@ -406,8 +414,11 @@ namespace
|
|||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
auto t = static_cast<uint16_t>(uint32_t(*sPtr) | uint32_t(*(sPtr + 1u) << 8));
|
auto t = static_cast<uint16_t>(uint32_t(*sPtr) | uint32_t(*(sPtr + 1u) << 8));
|
||||||
if (t & 0x8000)
|
|
||||||
nonzeroa = true;
|
uint32_t alpha = (t & 0x8000) ? 255 : 0;
|
||||||
|
minalpha = std::min(minalpha, alpha);
|
||||||
|
maxalpha = std::max(maxalpha, alpha);
|
||||||
|
|
||||||
sPtr += 2;
|
sPtr += 2;
|
||||||
*dPtr = t;
|
*dPtr = t;
|
||||||
|
|
||||||
@ -421,19 +432,26 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||||
if (!nonzeroa)
|
if (maxalpha == 0)
|
||||||
{
|
{
|
||||||
|
opaquealpha = true;
|
||||||
HRESULT hr = SetAlphaChannelToOpaque(image);
|
HRESULT hr = SetAlphaChannelToOpaque(image);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
else if (minalpha == 255)
|
||||||
|
{
|
||||||
|
opaquealpha = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//----------------------------------------------------------------------- 24/32-bit
|
//----------------------------------------------------------------------- 24/32-bit
|
||||||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||||
{
|
{
|
||||||
bool nonzeroa = false;
|
uint32_t minalpha = 255;
|
||||||
|
uint32_t maxalpha = 0;
|
||||||
|
|
||||||
for (size_t y = 0; y < image->height; ++y)
|
for (size_t y = 0; y < image->height; ++y)
|
||||||
{
|
{
|
||||||
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
|
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
|
||||||
@ -465,7 +483,7 @@ namespace
|
|||||||
t = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | 0xFF000000;
|
t = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | 0xFF000000;
|
||||||
sPtr += 3;
|
sPtr += 3;
|
||||||
|
|
||||||
nonzeroa = true;
|
minalpha = maxalpha = 255;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -475,10 +493,11 @@ namespace
|
|||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
// BGRA -> RGBA
|
// BGRA -> RGBA
|
||||||
t = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | uint32_t(*(sPtr + 3) << 24);
|
uint32_t alpha = *(sPtr + 3);
|
||||||
|
t = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | uint32_t(alpha << 24);
|
||||||
|
|
||||||
if (*(sPtr + 3) > 0)
|
minalpha = std::min(minalpha, alpha);
|
||||||
nonzeroa = true;
|
maxalpha = std::max(maxalpha, alpha);
|
||||||
|
|
||||||
sPtr += 4;
|
sPtr += 4;
|
||||||
}
|
}
|
||||||
@ -529,7 +548,7 @@ namespace
|
|||||||
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | 0xFF000000;
|
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | 0xFF000000;
|
||||||
sPtr += 3;
|
sPtr += 3;
|
||||||
|
|
||||||
nonzeroa = true;
|
minalpha = maxalpha = 255;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -539,10 +558,11 @@ namespace
|
|||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
// BGRA -> RGBA
|
// BGRA -> RGBA
|
||||||
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | uint32_t(*(sPtr + 3) << 24);
|
uint32_t alpha = *(sPtr + 3);
|
||||||
|
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | uint32_t(alpha << 24);
|
||||||
|
|
||||||
if (*(sPtr + 3) > 0)
|
minalpha = std::min(minalpha, alpha);
|
||||||
nonzeroa = true;
|
maxalpha = std::max(maxalpha, alpha);
|
||||||
|
|
||||||
sPtr += 4;
|
sPtr += 4;
|
||||||
}
|
}
|
||||||
@ -557,12 +577,17 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||||
if (!nonzeroa)
|
if (maxalpha == 0)
|
||||||
{
|
{
|
||||||
|
opaquealpha = true;
|
||||||
HRESULT hr = SetAlphaChannelToOpaque(image);
|
HRESULT hr = SetAlphaChannelToOpaque(image);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
else if (minalpha == 255)
|
||||||
|
{
|
||||||
|
opaquealpha = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -571,7 +596,7 @@ namespace
|
|||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return opaquealpha ? S_FALSE : S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -606,6 +631,8 @@ namespace
|
|||||||
auto sPtr = static_cast<const uint8_t*>(pSource);
|
auto sPtr = static_cast<const uint8_t*>(pSource);
|
||||||
const uint8_t* endPtr = sPtr + size;
|
const uint8_t* endPtr = sPtr + size;
|
||||||
|
|
||||||
|
bool opaquealpha = false;
|
||||||
|
|
||||||
switch (image->format)
|
switch (image->format)
|
||||||
{
|
{
|
||||||
//--------------------------------------------------------------------------- 8-bit
|
//--------------------------------------------------------------------------- 8-bit
|
||||||
@ -637,7 +664,9 @@ namespace
|
|||||||
//-------------------------------------------------------------------------- 16-bit
|
//-------------------------------------------------------------------------- 16-bit
|
||||||
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
||||||
{
|
{
|
||||||
bool nonzeroa = false;
|
uint32_t minalpha = 255;
|
||||||
|
uint32_t maxalpha = 0;
|
||||||
|
|
||||||
for (size_t y = 0; y < image->height; ++y)
|
for (size_t y = 0; y < image->height; ++y)
|
||||||
{
|
{
|
||||||
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
|
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
|
||||||
@ -656,8 +685,9 @@ namespace
|
|||||||
sPtr += 2;
|
sPtr += 2;
|
||||||
*dPtr = t;
|
*dPtr = t;
|
||||||
|
|
||||||
if (t & 0x8000)
|
uint32_t alpha = (t & 0x8000) ? 255 : 0;
|
||||||
nonzeroa = true;
|
minalpha = std::min(minalpha, alpha);
|
||||||
|
maxalpha = std::max(maxalpha, alpha);
|
||||||
|
|
||||||
if (convFlags & CONV_FLAGS_INVERTX)
|
if (convFlags & CONV_FLAGS_INVERTX)
|
||||||
--dPtr;
|
--dPtr;
|
||||||
@ -667,19 +697,26 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||||
if (!nonzeroa)
|
if (maxalpha == 0)
|
||||||
{
|
{
|
||||||
|
opaquealpha = true;
|
||||||
HRESULT hr = SetAlphaChannelToOpaque(image);
|
HRESULT hr = SetAlphaChannelToOpaque(image);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
else if (minalpha == 255)
|
||||||
|
{
|
||||||
|
opaquealpha = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//----------------------------------------------------------------------- 24/32-bit
|
//----------------------------------------------------------------------- 24/32-bit
|
||||||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||||
{
|
{
|
||||||
bool nonzeroa = false;
|
uint32_t minalpha = 255;
|
||||||
|
uint32_t maxalpha = 0;
|
||||||
|
|
||||||
for (size_t y = 0; y < image->height; ++y)
|
for (size_t y = 0; y < image->height; ++y)
|
||||||
{
|
{
|
||||||
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
|
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
|
||||||
@ -701,7 +738,7 @@ namespace
|
|||||||
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | 0xFF000000;
|
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | 0xFF000000;
|
||||||
sPtr += 3;
|
sPtr += 3;
|
||||||
|
|
||||||
nonzeroa = true;
|
minalpha = maxalpha = 255;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -711,10 +748,11 @@ namespace
|
|||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
// BGRA -> RGBA
|
// BGRA -> RGBA
|
||||||
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | uint32_t(*(sPtr + 3) << 24);
|
uint32_t alpha = *(sPtr + 3);
|
||||||
|
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | uint32_t(alpha << 24);
|
||||||
|
|
||||||
if (*(sPtr + 3) > 0)
|
minalpha = std::min(minalpha, alpha);
|
||||||
nonzeroa = true;
|
maxalpha = std::max(maxalpha, alpha);
|
||||||
|
|
||||||
sPtr += 4;
|
sPtr += 4;
|
||||||
}
|
}
|
||||||
@ -727,12 +765,17 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||||
if (!nonzeroa)
|
if (maxalpha == 0)
|
||||||
{
|
{
|
||||||
|
opaquealpha = true;
|
||||||
HRESULT hr = SetAlphaChannelToOpaque(image);
|
HRESULT hr = SetAlphaChannelToOpaque(image);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
else if (minalpha == 255)
|
||||||
|
{
|
||||||
|
opaquealpha = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -741,7 +784,7 @@ namespace
|
|||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return opaquealpha ? S_FALSE : S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -965,7 +1008,13 @@ HRESULT DirectX::LoadFromTGAMemory(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (metadata)
|
if (metadata)
|
||||||
|
{
|
||||||
memcpy(metadata, &mdata, sizeof(TexMetadata));
|
memcpy(metadata, &mdata, sizeof(TexMetadata));
|
||||||
|
if (hr == S_FALSE)
|
||||||
|
{
|
||||||
|
metadata->SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@ -1051,6 +1100,8 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||||||
|
|
||||||
assert(image.GetPixels());
|
assert(image.GetPixels());
|
||||||
|
|
||||||
|
bool opaquealpha = false;
|
||||||
|
|
||||||
if (!(convFlags & (CONV_FLAGS_RLE | CONV_FLAGS_EXPAND | CONV_FLAGS_INVERTX)) && (convFlags & CONV_FLAGS_INVERTY))
|
if (!(convFlags & (CONV_FLAGS_RLE | CONV_FLAGS_EXPAND | CONV_FLAGS_INVERTX)) && (convFlags & CONV_FLAGS_INVERTY))
|
||||||
{
|
{
|
||||||
// This case we can read directly into the image buffer in place
|
// This case we can read directly into the image buffer in place
|
||||||
@ -1101,7 +1152,8 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||||||
size_t rowPitch = img->rowPitch;
|
size_t rowPitch = img->rowPitch;
|
||||||
|
|
||||||
// Scan for non-zero alpha channel
|
// Scan for non-zero alpha channel
|
||||||
bool nonzeroa = false;
|
uint32_t minalpha = 255;
|
||||||
|
uint32_t maxalpha = 0;
|
||||||
|
|
||||||
for (size_t h = 0; h < img->height; ++h)
|
for (size_t h = 0; h < img->height; ++h)
|
||||||
{
|
{
|
||||||
@ -1109,22 +1161,27 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||||||
|
|
||||||
for (size_t x = 0; x < img->width; ++x)
|
for (size_t x = 0; x < img->width; ++x)
|
||||||
{
|
{
|
||||||
if ((*sPtr) & 0xff000000)
|
uint32_t alpha = ((*sPtr & 0xFF000000) >> 24);
|
||||||
{
|
|
||||||
nonzeroa = true;
|
minalpha = std::min(minalpha, alpha);
|
||||||
break;
|
maxalpha = std::max(maxalpha, alpha);
|
||||||
}
|
|
||||||
|
|
||||||
++sPtr;
|
++sPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nonzeroa)
|
|
||||||
break;
|
|
||||||
|
|
||||||
pPixels += rowPitch;
|
pPixels += rowPitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD tflags = (!nonzeroa) ? TEXP_SCANLINE_SETALPHA : TEXP_SCANLINE_NONE;
|
DWORD tflags = TEXP_SCANLINE_NONE;
|
||||||
|
if (maxalpha == 0)
|
||||||
|
{
|
||||||
|
opaquealpha = true;
|
||||||
|
tflags = TEXP_SCANLINE_SETALPHA;
|
||||||
|
}
|
||||||
|
else if (minalpha == 255)
|
||||||
|
{
|
||||||
|
opaquealpha = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Swizzle scanlines
|
// Swizzle scanlines
|
||||||
pPixels = img->pixels;
|
pPixels = img->pixels;
|
||||||
@ -1150,7 +1207,8 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Scan for non-zero alpha channel
|
// Scan for non-zero alpha channel
|
||||||
bool nonzeroa = false;
|
uint32_t minalpha = 255;
|
||||||
|
uint32_t maxalpha = 0;
|
||||||
|
|
||||||
const uint8_t *pPixels = img->pixels;
|
const uint8_t *pPixels = img->pixels;
|
||||||
if (!pPixels)
|
if (!pPixels)
|
||||||
@ -1167,24 +1225,21 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||||||
|
|
||||||
for (size_t x = 0; x < img->width; ++x)
|
for (size_t x = 0; x < img->width; ++x)
|
||||||
{
|
{
|
||||||
if (*sPtr & 0x8000)
|
uint32_t alpha = (*sPtr & 0x8000) ? 255 : 0;
|
||||||
{
|
|
||||||
nonzeroa = true;
|
minalpha = std::min(minalpha, alpha);
|
||||||
break;
|
maxalpha = std::max(maxalpha, alpha);
|
||||||
}
|
|
||||||
|
|
||||||
++sPtr;
|
++sPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nonzeroa)
|
|
||||||
break;
|
|
||||||
|
|
||||||
pPixels += rowPitch;
|
pPixels += rowPitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||||
if (!nonzeroa)
|
if (maxalpha == 0)
|
||||||
{
|
{
|
||||||
|
opaquealpha = true;
|
||||||
hr = SetAlphaChannelToOpaque(img);
|
hr = SetAlphaChannelToOpaque(img);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
@ -1192,6 +1247,10 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (minalpha == 255)
|
||||||
|
{
|
||||||
|
opaquealpha = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1234,10 +1293,19 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||||||
image.Release();
|
image.Release();
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hr == S_FALSE)
|
||||||
|
opaquealpha = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metadata)
|
if (metadata)
|
||||||
|
{
|
||||||
memcpy(metadata, &mdata, sizeof(TexMetadata));
|
memcpy(metadata, &mdata, sizeof(TexMetadata));
|
||||||
|
if (opaquealpha)
|
||||||
|
{
|
||||||
|
metadata->SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,7 @@ namespace
|
|||||||
{
|
{
|
||||||
GUID source;
|
GUID source;
|
||||||
GUID target;
|
GUID target;
|
||||||
|
TEX_ALPHA_MODE alphaMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
const WICConvert g_WICConvert[] =
|
const WICConvert g_WICConvert[] =
|
||||||
@ -88,54 +89,54 @@ namespace
|
|||||||
// Directly support the formats listed in XnaTexUtil::g_WICFormats, so no conversion required
|
// Directly support the formats listed in XnaTexUtil::g_WICFormats, so no conversion required
|
||||||
// Note target GUID in this conversion table must be one of those directly supported formats.
|
// Note target GUID in this conversion table must be one of those directly supported formats.
|
||||||
|
|
||||||
{ GUID_WICPixelFormat1bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
{ GUID_WICPixelFormat1bppIndexed, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
{ GUID_WICPixelFormat2bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
{ GUID_WICPixelFormat2bppIndexed, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
{ GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
{ GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
{ GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
{ GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
|
|
||||||
{ GUID_WICPixelFormat2bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM
|
{ GUID_WICPixelFormat2bppGray, GUID_WICPixelFormat8bppGray, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8_UNORM
|
||||||
{ GUID_WICPixelFormat4bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM
|
{ GUID_WICPixelFormat4bppGray, GUID_WICPixelFormat8bppGray, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8_UNORM
|
||||||
|
|
||||||
{ GUID_WICPixelFormat16bppGrayFixedPoint, GUID_WICPixelFormat16bppGrayHalf }, // DXGI_FORMAT_R16_FLOAT
|
{ GUID_WICPixelFormat16bppGrayFixedPoint, GUID_WICPixelFormat16bppGrayHalf, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16_FLOAT
|
||||||
{ GUID_WICPixelFormat32bppGrayFixedPoint, GUID_WICPixelFormat32bppGrayFloat }, // DXGI_FORMAT_R32_FLOAT
|
{ GUID_WICPixelFormat32bppGrayFixedPoint, GUID_WICPixelFormat32bppGrayFloat, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R32_FLOAT
|
||||||
|
|
||||||
{ GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat16bppBGRA5551 }, // DXGI_FORMAT_B5G5R5A1_UNORM
|
{ GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat16bppBGRA5551, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_B5G5R5A1_UNORM
|
||||||
{ GUID_WICPixelFormat32bppBGR101010, GUID_WICPixelFormat32bppRGBA1010102 }, // DXGI_FORMAT_R10G10B10A2_UNORM
|
{ GUID_WICPixelFormat32bppBGR101010, GUID_WICPixelFormat32bppRGBA1010102, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R10G10B10A2_UNORM
|
||||||
|
|
||||||
{ GUID_WICPixelFormat24bppBGR, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
{ GUID_WICPixelFormat24bppBGR, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
{ GUID_WICPixelFormat24bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
{ GUID_WICPixelFormat24bppRGB, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
{ GUID_WICPixelFormat32bppPBGRA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
{ GUID_WICPixelFormat32bppPBGRA, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
{ GUID_WICPixelFormat32bppPRGBA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
{ GUID_WICPixelFormat32bppPRGBA, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
|
|
||||||
{ GUID_WICPixelFormat48bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
{ GUID_WICPixelFormat48bppRGB, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
||||||
{ GUID_WICPixelFormat48bppBGR, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
{ GUID_WICPixelFormat48bppBGR, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
||||||
{ GUID_WICPixelFormat64bppBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
{ GUID_WICPixelFormat64bppBGRA, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
||||||
{ GUID_WICPixelFormat64bppPRGBA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
{ GUID_WICPixelFormat64bppPRGBA, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
||||||
{ GUID_WICPixelFormat64bppPBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
{ GUID_WICPixelFormat64bppPBGRA, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
||||||
|
|
||||||
{ GUID_WICPixelFormat48bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
{ GUID_WICPixelFormat48bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
||||||
{ GUID_WICPixelFormat48bppBGRFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
{ GUID_WICPixelFormat48bppBGRFixedPoint, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
||||||
{ GUID_WICPixelFormat64bppRGBAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
{ GUID_WICPixelFormat64bppRGBAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
||||||
{ GUID_WICPixelFormat64bppBGRAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
{ GUID_WICPixelFormat64bppBGRAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
||||||
{ GUID_WICPixelFormat64bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
{ GUID_WICPixelFormat64bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
||||||
{ GUID_WICPixelFormat64bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
{ GUID_WICPixelFormat64bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
||||||
{ GUID_WICPixelFormat48bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
{ GUID_WICPixelFormat48bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
||||||
|
|
||||||
{ GUID_WICPixelFormat128bppPRGBAFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
|
{ GUID_WICPixelFormat128bppPRGBAFloat, GUID_WICPixelFormat128bppRGBAFloat, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R32G32B32A32_FLOAT
|
||||||
{ GUID_WICPixelFormat128bppRGBFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
|
{ GUID_WICPixelFormat128bppRGBFloat, GUID_WICPixelFormat128bppRGBAFloat, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R32G32B32A32_FLOAT
|
||||||
{ GUID_WICPixelFormat128bppRGBAFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
|
{ GUID_WICPixelFormat128bppRGBAFixedPoint, GUID_WICPixelFormat128bppRGBAFloat, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R32G32B32A32_FLOAT
|
||||||
{ GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
|
{ GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R32G32B32A32_FLOAT
|
||||||
{ GUID_WICPixelFormat32bppRGBE, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
|
{ GUID_WICPixelFormat32bppRGBE, GUID_WICPixelFormat128bppRGBAFloat, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R32G32B32A32_FLOAT
|
||||||
|
|
||||||
{ GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
{ GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
{ GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
{ GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
||||||
{ GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
{ GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
{ GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
{ GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
||||||
|
|
||||||
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
|
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
|
||||||
{ GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
{ GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
{ GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
{ GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_UNORM
|
||||||
{ GUID_WICPixelFormat64bppPRGBAHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
{ GUID_WICPixelFormat64bppPRGBAHalf, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_FLOAT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We don't support n-channel formats
|
// We don't support n-channel formats
|
||||||
@ -148,11 +149,14 @@ namespace
|
|||||||
_In_ const WICPixelFormatGUID& pixelFormat,
|
_In_ const WICPixelFormatGUID& pixelFormat,
|
||||||
DWORD flags,
|
DWORD flags,
|
||||||
bool iswic2,
|
bool iswic2,
|
||||||
_Out_opt_ WICPixelFormatGUID* pConvert)
|
_Out_opt_ WICPixelFormatGUID* pConvert,
|
||||||
|
_Out_ TEX_ALPHA_MODE* alphaMode)
|
||||||
{
|
{
|
||||||
if (pConvert)
|
if (pConvert)
|
||||||
memset(pConvert, 0, sizeof(WICPixelFormatGUID));
|
memset(pConvert, 0, sizeof(WICPixelFormatGUID));
|
||||||
|
|
||||||
|
*alphaMode = TEX_ALPHA_MODE_UNKNOWN;
|
||||||
|
|
||||||
DXGI_FORMAT format = _WICToDXGI(pixelFormat);
|
DXGI_FORMAT format = _WICToDXGI(pixelFormat);
|
||||||
|
|
||||||
if (format == DXGI_FORMAT_UNKNOWN)
|
if (format == DXGI_FORMAT_UNKNOWN)
|
||||||
@ -174,6 +178,7 @@ namespace
|
|||||||
if (pConvert)
|
if (pConvert)
|
||||||
memcpy_s(pConvert, sizeof(WICPixelFormatGUID), &GUID_WICPixelFormat128bppRGBAFloat, sizeof(GUID));
|
memcpy_s(pConvert, sizeof(WICPixelFormatGUID), &GUID_WICPixelFormat128bppRGBAFloat, sizeof(GUID));
|
||||||
format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||||
|
*alphaMode = TEX_ALPHA_MODE_OPAQUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -187,6 +192,7 @@ namespace
|
|||||||
|
|
||||||
format = _WICToDXGI(g_WICConvert[i].target);
|
format = _WICToDXGI(g_WICConvert[i].target);
|
||||||
assert(format != DXGI_FORMAT_UNKNOWN);
|
assert(format != DXGI_FORMAT_UNKNOWN);
|
||||||
|
*alphaMode = g_WICConvert[i].alphaMode;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,10 +294,13 @@ namespace
|
|||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
metadata.format = DetermineFormat(pixelFormat, flags, iswic2, pConvert);
|
TEX_ALPHA_MODE alphaMode;
|
||||||
|
metadata.format = DetermineFormat(pixelFormat, flags, iswic2, pConvert, &alphaMode);
|
||||||
if (metadata.format == DXGI_FORMAT_UNKNOWN)
|
if (metadata.format == DXGI_FORMAT_UNKNOWN)
|
||||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||||
|
|
||||||
|
metadata.SetAlphaMode(alphaMode);
|
||||||
|
|
||||||
if (!(flags & WIC_FLAGS_IGNORE_SRGB))
|
if (!(flags & WIC_FLAGS_IGNORE_SRGB))
|
||||||
{
|
{
|
||||||
GUID containerFormat;
|
GUID containerFormat;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user