mirror of
https://github.com/microsoft/DirectXTex.git
synced 2025-07-10 04:00:13 +02:00
texassemble: merge command
This commit is contained in:
parent
dd5f68c60d
commit
b29d024dfc
@ -53,6 +53,7 @@ enum COMMANDS
|
|||||||
CMD_V_CROSS,
|
CMD_V_CROSS,
|
||||||
CMD_H_STRIP,
|
CMD_H_STRIP,
|
||||||
CMD_V_STRIP,
|
CMD_V_STRIP,
|
||||||
|
CMD_MERGE,
|
||||||
CMD_MAX
|
CMD_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -106,6 +107,7 @@ const SValue g_pCommands[] =
|
|||||||
{ L"v-cross", CMD_V_CROSS },
|
{ L"v-cross", CMD_V_CROSS },
|
||||||
{ L"h-strip", CMD_H_STRIP },
|
{ L"h-strip", CMD_H_STRIP },
|
||||||
{ L"v-strip", CMD_V_STRIP },
|
{ L"v-strip", CMD_V_STRIP },
|
||||||
|
{ L"merge", CMD_MERGE },
|
||||||
{ nullptr, 0 }
|
{ nullptr, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -250,9 +252,9 @@ const SValue g_pExtFileTypes [] =
|
|||||||
{ L".WDP", WIC_CODEC_WMP },
|
{ L".WDP", WIC_CODEC_WMP },
|
||||||
{ L".HDP", WIC_CODEC_WMP },
|
{ L".HDP", WIC_CODEC_WMP },
|
||||||
{ L".JXR", WIC_CODEC_WMP },
|
{ L".JXR", WIC_CODEC_WMP },
|
||||||
#ifdef USE_OPENEXR
|
#ifdef USE_OPENEXR
|
||||||
{ L"EXR", CODEC_EXR },
|
{ L"EXR", CODEC_EXR },
|
||||||
#endif
|
#endif
|
||||||
{ nullptr, CODEC_DDS }
|
{ nullptr, CODEC_DDS }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -483,7 +485,8 @@ namespace
|
|||||||
wprintf(L" array create texture array\n");
|
wprintf(L" array create texture array\n");
|
||||||
wprintf(L" cubearray create cubemap array\n");
|
wprintf(L" cubearray create cubemap array\n");
|
||||||
wprintf(L" h-cross or v-cross create a cross image from a cubemap\n");
|
wprintf(L" h-cross or v-cross create a cross image from a cubemap\n");
|
||||||
wprintf(L" h-strip or v-strip create a strip image from a cubemap\n\n");
|
wprintf(L" h-strip or v-strip create a strip image from a cubemap\n");
|
||||||
|
wprintf(L" merge create texture from rgb image and alpha image\n\n");
|
||||||
wprintf(L" -r wildcard filename search is recursive\n");
|
wprintf(L" -r wildcard filename search is recursive\n");
|
||||||
wprintf(L" -w <n> width\n");
|
wprintf(L" -w <n> width\n");
|
||||||
wprintf(L" -h <n> height\n");
|
wprintf(L" -h <n> height\n");
|
||||||
@ -506,6 +509,29 @@ namespace
|
|||||||
wprintf(L"\n <filter>: ");
|
wprintf(L"\n <filter>: ");
|
||||||
PrintList(13, g_pFilters);
|
PrintList(13, g_pFilters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT SaveImageFile(const Image& img, DWORD fileType, const wchar_t* szOutputFile)
|
||||||
|
{
|
||||||
|
switch (fileType)
|
||||||
|
{
|
||||||
|
case CODEC_DDS:
|
||||||
|
return SaveToDDSFile(img, DDS_FLAGS_NONE, szOutputFile);
|
||||||
|
|
||||||
|
case CODEC_TGA:
|
||||||
|
return SaveToTGAFile(img, szOutputFile);
|
||||||
|
|
||||||
|
case CODEC_HDR:
|
||||||
|
return SaveToHDRFile(img, szOutputFile);
|
||||||
|
|
||||||
|
#ifdef USE_OPENEXR
|
||||||
|
case CODEC_EXR:
|
||||||
|
return SaveToEXRFile(img, szOutputFile);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
return SaveToWICFile(img, WIC_FLAGS_NONE, GetWICCodec(static_cast<WICCodecs>(fileType)), szOutputFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -524,7 +550,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
DWORD dwFilter = TEX_FILTER_DEFAULT;
|
DWORD dwFilter = TEX_FILTER_DEFAULT;
|
||||||
DWORD dwSRGB = 0;
|
DWORD dwSRGB = 0;
|
||||||
DWORD dwFilterOpts = 0;
|
DWORD dwFilterOpts = 0;
|
||||||
DWORD CrossFileType = WIC_CODEC_BMP;
|
DWORD fileType = WIC_CODEC_BMP;
|
||||||
|
|
||||||
wchar_t szOutputFile[MAX_PATH] = {};
|
wchar_t szOutputFile[MAX_PATH] = {};
|
||||||
|
|
||||||
@ -554,10 +580,11 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
case CMD_V_CROSS:
|
case CMD_V_CROSS:
|
||||||
case CMD_H_STRIP:
|
case CMD_H_STRIP:
|
||||||
case CMD_V_STRIP:
|
case CMD_V_STRIP:
|
||||||
|
case CMD_MERGE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wprintf(L"Must use one of: cube, volume, array, cubearray,\n h-cross, v-cross, h-strip, or v-strip\n\n");
|
wprintf(L"Must use one of: cube, volume, array, cubearray,\n h-cross, v-cross, h-strip, v-strip, or merge\n\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -669,7 +696,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
wchar_t ext[_MAX_EXT];
|
wchar_t ext[_MAX_EXT];
|
||||||
_wsplitpath_s(szOutputFile, nullptr, 0, nullptr, 0, nullptr, 0, ext, _MAX_EXT);
|
_wsplitpath_s(szOutputFile, nullptr, 0, nullptr, 0, nullptr, 0, ext, _MAX_EXT);
|
||||||
|
|
||||||
CrossFileType = LookupByName(ext, g_pExtFileTypes);
|
fileType = LookupByName(ext, g_pExtFileTypes);
|
||||||
|
|
||||||
switch (dwCommand)
|
switch (dwCommand)
|
||||||
{
|
{
|
||||||
@ -677,10 +704,11 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
case CMD_V_CROSS:
|
case CMD_V_CROSS:
|
||||||
case CMD_H_STRIP:
|
case CMD_H_STRIP:
|
||||||
case CMD_V_STRIP:
|
case CMD_V_STRIP:
|
||||||
|
case CMD_MERGE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (CrossFileType != CODEC_DDS)
|
if (fileType != CODEC_DDS)
|
||||||
{
|
{
|
||||||
wprintf(L"Assembled output file must be a dds\n");
|
wprintf(L"Assembled output file must be a dds\n");
|
||||||
return 1;
|
return 1;
|
||||||
@ -792,6 +820,14 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CMD_MERGE:
|
||||||
|
if (conversion.size() > 2)
|
||||||
|
{
|
||||||
|
wprintf(L"ERROR: merge output only accepts 2 input files\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert images
|
// Convert images
|
||||||
@ -910,7 +946,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef USE_OPENEXR
|
#ifdef USE_OPENEXR
|
||||||
else if (_wcsicmp(ext, L".exr") == 0)
|
else if (_wcsicmp(ext, L".exr") == 0)
|
||||||
{
|
{
|
||||||
hr = LoadFromEXRFile(pConv->szSrc, &info, *image);
|
hr = LoadFromEXRFile(pConv->szSrc, &info, *image);
|
||||||
@ -920,7 +956,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// WIC shares the same filter values for mode and dither
|
// WIC shares the same filter values for mode and dither
|
||||||
@ -1392,31 +1428,89 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (CrossFileType)
|
hr = SaveImageFile(*dest, fileType, szOutputFile);
|
||||||
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
case CODEC_DDS:
|
wprintf(L" FAILED (%x)\n", hr);
|
||||||
hr = SaveToDDSFile(*dest, DDS_FLAGS_NONE, szOutputFile);
|
return 1;
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CODEC_TGA:
|
case CMD_MERGE:
|
||||||
hr = SaveToTGAFile(*dest, szOutputFile);
|
{
|
||||||
break;
|
// Capture alpha from source image (the second input filename)
|
||||||
|
ScratchImage alphaImage;
|
||||||
case CODEC_HDR:
|
hr = alphaImage.Initialize2D(DXGI_FORMAT_R32_FLOAT, width, height, 1, 1);
|
||||||
hr = SaveToHDRFile(*dest, szOutputFile);
|
if (FAILED(hr))
|
||||||
break;
|
{
|
||||||
|
wprintf(L"FAILED setting up alpha image (%x)\n", hr);
|
||||||
#ifdef USE_OPENEXR
|
return 1;
|
||||||
case CODEC_EXR:
|
|
||||||
hr = SaveToEXRFile(*dest, szOutputFile);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
hr = SaveToWICFile(*dest, WIC_FLAGS_NONE, GetWICCodec(static_cast<WICCodecs>(CrossFileType)), szOutputFile);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Image& img = *alphaImage.GetImage(0, 0, 0);
|
||||||
|
|
||||||
|
hr = EvaluateImage(*loadedImages[1]->GetImage(0, 0, 0),
|
||||||
|
[&](const XMVECTOR* pixels, size_t width, size_t y)
|
||||||
|
{
|
||||||
|
auto alphaPtr = reinterpret_cast<float*>(img.pixels + img.rowPitch * y);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < width; ++j)
|
||||||
|
{
|
||||||
|
XMVECTOR value = pixels[j];
|
||||||
|
|
||||||
|
// DXTex's Open Alpha onto Surface always loaded alpha from the blue channel
|
||||||
|
|
||||||
|
*alphaPtr++ = XMVectorGetZ(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
wprintf(L" FAILED [reading alpha image] (%x)\n", hr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge with rgb from our source iamge (the first input filename)
|
||||||
|
const Image& rgb = *loadedImages[0]->GetImage(0, 0, 0);
|
||||||
|
|
||||||
|
ScratchImage result;
|
||||||
|
hr = TransformImage(rgb, [&](XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t width, size_t y)
|
||||||
|
{
|
||||||
|
auto alphaPtr = reinterpret_cast<float*>(img.pixels + img.rowPitch * y);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < width; ++j)
|
||||||
|
{
|
||||||
|
XMVECTOR value = inPixels[j];
|
||||||
|
|
||||||
|
XMVECTOR nvalue = XMVectorReplicate(*alphaPtr++);
|
||||||
|
|
||||||
|
value = XMVectorSelect(nvalue, value, g_XMSelect1110);
|
||||||
|
|
||||||
|
outPixels[j] = value;
|
||||||
|
}
|
||||||
|
}, result);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
wprintf(L" FAILED [merge image] (%x)\n", hr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write merged texture
|
||||||
|
wprintf(L"\nWriting %ls ", szOutputFile);
|
||||||
|
PrintInfo(result.GetMetadata());
|
||||||
|
wprintf(L"\n");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
if (~dwOptions & (1 << OPT_OVERWRITE))
|
||||||
|
{
|
||||||
|
if (GetFileAttributesW(szOutputFile) != INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
wprintf(L"\nERROR: Output file already exists, use -y to overwrite\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = SaveImageFile(*result.GetImage(0, 0, 0), fileType, szOutputFile);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
wprintf(L" FAILED (%x)\n", hr);
|
wprintf(L" FAILED (%x)\n", hr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user