mirror of
https://github.com/microsoft/DirectXTex.git
synced 2026-02-08 05:46:14 +01:00
[texconv] Implemented alpha coverage preservation option (#82)
This commit is contained in:
committed by
Chuck Walbourn
parent
a79989a4f0
commit
f2c4d94a35
@@ -101,6 +101,7 @@ enum OPTIONS
|
||||
OPT_COLORKEY,
|
||||
OPT_TONEMAP,
|
||||
OPT_X2_BIAS,
|
||||
OPT_PRESERVE_ALPHA_COVERAGE,
|
||||
OPT_INVERT_Y,
|
||||
OPT_FILELIST,
|
||||
OPT_ROTATE_COLOR,
|
||||
@@ -187,6 +188,7 @@ const SValue g_pOptions[] =
|
||||
{ L"c", OPT_COLORKEY },
|
||||
{ L"tonemap", OPT_TONEMAP },
|
||||
{ L"x2bias", OPT_X2_BIAS },
|
||||
{ L"keepcoverage", OPT_PRESERVE_ALPHA_COVERAGE },
|
||||
{ L"inverty", OPT_INVERT_Y },
|
||||
{ L"flist", OPT_FILELIST },
|
||||
{ L"rotatecolor", OPT_ROTATE_COLOR },
|
||||
@@ -751,6 +753,7 @@ namespace
|
||||
wprintf(L" -nits <value> paper-white value in nits to use for HDR10 (def: 200.0)\n");
|
||||
wprintf(L" -tonemap Apply a tonemap operator based on maximum luminance\n");
|
||||
wprintf(L" -x2bias Enable *2 - 1 conversion cases for unorm/pos-only-float\n");
|
||||
wprintf(L" -keepcoverage <ref> Preserve alpha coverage in generated mips for alpha test ref\n");
|
||||
wprintf(L" -inverty Invert Y (i.e. green) channel values\n");
|
||||
wprintf(L" -flist <filename> use text file with a list of input files (one per line)\n");
|
||||
|
||||
@@ -1116,6 +1119,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
DWORD colorKey = 0;
|
||||
DWORD dwRotateColor = 0;
|
||||
float paperWhiteNits = 200.f;
|
||||
float preserveAlphaCoverageRef = 0.0f;
|
||||
|
||||
wchar_t szPrefix[MAX_PATH];
|
||||
wchar_t szSuffix[MAX_PATH];
|
||||
@@ -1183,6 +1187,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
case OPT_FILELIST:
|
||||
case OPT_ROTATE_COLOR:
|
||||
case OPT_PAPER_WHITE_NITS:
|
||||
case OPT_PRESERVE_ALPHA_COVERAGE:
|
||||
if (!*pValue)
|
||||
{
|
||||
if ((iArg + 1 >= argc))
|
||||
@@ -1569,15 +1574,27 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
case OPT_PAPER_WHITE_NITS:
|
||||
if (swscanf_s(pValue, L"%f", &paperWhiteNits) != 1)
|
||||
{
|
||||
wprintf(L"Invalid value specified with -nits (%ls)\n", pValue);
|
||||
wprintf(L"\n");
|
||||
wprintf(L"Invalid value specified with -nits (%ls)\n\n", pValue);
|
||||
PrintUsage();
|
||||
return 1;
|
||||
}
|
||||
else if (paperWhiteNits > 10000.f || paperWhiteNits <= 0.f)
|
||||
{
|
||||
wprintf(L"-nits (%ls) parameter must be between 0 and 10000\n", pValue);
|
||||
wprintf(L"\n");
|
||||
wprintf(L"-nits (%ls) parameter must be between 0 and 10000\n\n", pValue);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case OPT_PRESERVE_ALPHA_COVERAGE:
|
||||
if (swscanf_s(pValue, L"%f", &preserveAlphaCoverageRef) != 1)
|
||||
{
|
||||
wprintf(L"Invalid value specified with -keepcoverage (%ls)\n\n", pValue);
|
||||
PrintUsage();
|
||||
return 1;
|
||||
}
|
||||
else if (preserveAlphaCoverageRef < 0.0f || preserveAlphaCoverageRef > 1.0f)
|
||||
{
|
||||
wprintf(L"-keepcoverage (%ls) parameter must be between 0.0 and 1.0\n\n", pValue);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -1655,6 +1672,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
// Convert images
|
||||
bool nonpow2warn = false;
|
||||
bool non4bc = false;
|
||||
bool preserveAlphaCoverage = false;
|
||||
ComPtr<ID3D11Device> pDevice;
|
||||
|
||||
for (auto pConv = conversion.begin(); pConv != conversion.end(); ++pConv)
|
||||
@@ -2526,6 +2544,12 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
cimage.reset();
|
||||
}
|
||||
|
||||
// --- Determine whether preserve alpha coverage is required (if requested) ----
|
||||
if (preserveAlphaCoverageRef > 0.0f && HasAlpha(info.format) && !image->IsAlphaAllOpaque())
|
||||
{
|
||||
preserveAlphaCoverage = true;
|
||||
}
|
||||
|
||||
// --- Generate mips -----------------------------------------------------------
|
||||
DWORD dwFilter3D = dwFilter;
|
||||
if (!ispow2(info.width) || !ispow2(info.height) || !ispow2(info.depth))
|
||||
@@ -2542,9 +2566,11 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if ((!tMips || info.mipLevels != tMips) && (info.mipLevels != 1))
|
||||
if ((!tMips || info.mipLevels != tMips || preserveAlphaCoverage) && (info.mipLevels != 1))
|
||||
{
|
||||
// Mips generation only works on a single base image, so strip off existing mip levels
|
||||
// Also required for preserve alpha coverage so that existing mips are regenerated
|
||||
|
||||
std::unique_ptr<ScratchImage> timage(new (std::nothrow) ScratchImage);
|
||||
if (!timage)
|
||||
{
|
||||
@@ -2670,6 +2696,59 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
cimage.reset();
|
||||
}
|
||||
|
||||
// --- Preserve mipmap alpha coverage (if requested) ---------------------------
|
||||
if (preserveAlphaCoverage && info.mipLevels != 1)
|
||||
{
|
||||
std::unique_ptr<ScratchImage> timage(new (std::nothrow) ScratchImage);
|
||||
if (!timage)
|
||||
{
|
||||
wprintf(L"\nERROR: Memory allocation failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
hr = timage->Initialize(image->GetMetadata());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L" FAILED [keepcoverage] (%x)\n", hr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const size_t items = image->GetMetadata().arraySize;
|
||||
for (size_t item = 0; item < items; ++item)
|
||||
{
|
||||
auto img = image->GetImage(0, item, 0);
|
||||
assert(img);
|
||||
|
||||
hr = CopyRectangle(*img, Rect(0, 0, info.width, info.height), *timage->GetImage(0, item, 0), TEX_FILTER_DEFAULT, 0, 0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L" FAILED [keepcoverage] (%x)\n", hr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
hr = ScaleMipMapsAlphaForCoverage(img, info, item, preserveAlphaCoverageRef, *timage);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L" FAILED [keepcoverage] (%x)\n", hr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
auto& tinfo = timage->GetMetadata();
|
||||
tinfo;
|
||||
|
||||
assert(info.width == tinfo.width);
|
||||
assert(info.height == tinfo.height);
|
||||
assert(info.depth == tinfo.depth);
|
||||
assert(info.arraySize == tinfo.arraySize);
|
||||
assert(info.mipLevels == tinfo.mipLevels);
|
||||
assert(info.miscFlags == tinfo.miscFlags);
|
||||
assert(info.dimension == tinfo.dimension);
|
||||
|
||||
image.swap(timage);
|
||||
cimage.reset();
|
||||
}
|
||||
|
||||
// --- Premultiplied alpha (if requested) --------------------------------------
|
||||
if ((dwOptions & (DWORD64(1) << OPT_PREMUL_ALPHA))
|
||||
&& HasAlpha(info.format)
|
||||
|
||||
Reference in New Issue
Block a user