Merge branch 'master' into cs50
This commit is contained in:
commit
e6f78c53af
@ -7,10 +7,10 @@
|
||||
<authors>Microsoft</authors>
|
||||
<owners>microsoft,directxtk</owners>
|
||||
<summary>DirectXTex texture processing library</summary>
|
||||
<description>This version is for Windows desktop applications using Visual Studio 2015 Update 3 or Visual Studio 2017.
|
||||
<description>This version is for Windows desktop applications using Visual Studio 2015 Update 3 or Visual Studio 2017 and supports Windows 7 / DirectX 11.
|
||||
|
||||
DirectXTex, a shared source library for reading and writing .DDS files, and performing various texture content processing operations including resizing, format conversion, mip-map generation, block compression for Direct3D runtime texture resources, and height-map to normal-map conversion. This library makes use of the Windows Image Component (WIC) APIs. It also includes simple .TGA and .HDR readers and writers since these image file format are commonly used for texture content processing pipelines, but are not currently supported by a built-in WIC codec.</description>
|
||||
<releaseNotes>Matches the October 25, 2018 release on GitHub.</releaseNotes>
|
||||
<releaseNotes>Matches the November 16, 2018 release on GitHub.</releaseNotes>
|
||||
<projectUrl>http://go.microsoft.com/fwlink/?LinkId=248926</projectUrl>
|
||||
<iconUrl>https://github.com/Microsoft/DirectXTex/wiki/X_jpg.jpg</iconUrl>
|
||||
<licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
|
||||
|
44
.nuget/directxtex_desktop_win10.nuspec
Normal file
44
.nuget/directxtex_desktop_win10.nuspec
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="2.8.6">
|
||||
<id>directxtex_desktop_win10</id>
|
||||
<version>0.0.0-SpecifyVersionOnCommandline</version>
|
||||
<title>DirectXTex Library (VS 2015/VS 2017 Win32 for Windows 10)</title>
|
||||
<authors>Microsoft</authors>
|
||||
<owners>microsoft,directxtk</owners>
|
||||
<summary>DirectXTex texture processing library</summary>
|
||||
<description>This version is for Windows desktop applications using Visual Studio 2015 Update 3 or Visual Studio 2017 and supports Windows 10 including both DirectX 11 and DirectX 12.
|
||||
|
||||
DirectXTex, a shared source library for reading and writing .DDS files, and performing various texture content processing operations including resizing, format conversion, mip-map generation, block compression for Direct3D runtime texture resources, and height-map to normal-map conversion. This library makes use of the Windows Image Component (WIC) APIs. It also includes simple .TGA and .HDR readers and writers since these image file format are commonly used for texture content processing pipelines, but are not currently supported by a built-in WIC codec.</description>
|
||||
<releaseNotes>Matches the November 16, 2018 release on GitHub.</releaseNotes>
|
||||
<projectUrl>http://go.microsoft.com/fwlink/?LinkId=248926</projectUrl>
|
||||
<iconUrl>https://github.com/Microsoft/DirectXTex/wiki/X_jpg.jpg</iconUrl>
|
||||
<licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
|
||||
<tags>DirectX DirectXTex native nativepackage</tags>
|
||||
</metadata>
|
||||
|
||||
<files>
|
||||
|
||||
<file target="docs" src="Readme.*" />
|
||||
|
||||
<file target="include" src="DirectXTex\DirectXTex.h" />
|
||||
<file target="include" src="DirectXTex\DirectXTex.inl" />
|
||||
|
||||
<file target="lib\Win32\Debug" src="DirectXTex\Bin\Desktop_2015_Win10\Win32\Debug\*.lib" />
|
||||
<file target="lib\Win32\Debug" src="DirectXTex\Bin\Desktop_2015_Win10\Win32\Debug\*.pdb" />
|
||||
|
||||
<file target="lib\Win32\Release" src="DirectXTex\Bin\Desktop_2015_Win10\Win32\Release\*.lib" />
|
||||
<file target="lib\Win32\Release" src="DirectXTex\Bin\Desktop_2015_Win10\Win32\Release\*.pdb" />
|
||||
|
||||
<file target="lib\x64\Debug" src="DirectXTex\Bin\Desktop_2015_Win10\x64\Debug\*.lib" />
|
||||
<file target="lib\x64\Debug" src="DirectXTex\Bin\Desktop_2015_Win10\x64\Debug\*.pdb" />
|
||||
|
||||
<file target="lib\x64\Release" src="DirectXTex\Bin\Desktop_2015_Win10\x64\Release\*.lib" />
|
||||
<file target="lib\x64\Release" src="DirectXTex\Bin\Desktop_2015_Win10\x64\Release\*.pdb" />
|
||||
|
||||
<file src=".nuget/directxtex_desktop_win10.targets" target="build\native" />
|
||||
|
||||
</files>
|
||||
</package>
|
22
.nuget/directxtex_desktop_win10.targets
Normal file
22
.nuget/directxtex_desktop_win10.targets
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<PropertyGroup>
|
||||
<directxtex-LibPath>$(MSBuildThisFileDirectory)..\..\lib\$(Platform)\$(Configuration)</directxtex-LibPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(directxtex-LibPath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>DirectXTex.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>HAS_DIRECTXTEX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
</Project>
|
@ -10,7 +10,7 @@
|
||||
<description>This version is for Universal Windows Platform apps on Windows 10 using Visual Studio 2015 Update 3 or Visual Studio 2017.
|
||||
|
||||
DirectXTex, a shared source library for reading and writing .DDS files, and performing various texture content processing operations including resizing, format conversion, mip-map generation, block compression for Direct3D runtime texture resources, and height-map to normal-map conversion. This library makes use of the Windows Image Component (WIC) APIs. It also includes simple .TGA and .HDR readers and writers since these image file format are commonly used for texture content processing pipelines, but are not currently supported by a built-in WIC codec.</description>
|
||||
<releaseNotes>Matches the October 25, 2018 release on GitHub.</releaseNotes>
|
||||
<releaseNotes>Matches the November 16, 2018 release on GitHub.</releaseNotes>
|
||||
<projectUrl>http://go.microsoft.com/fwlink/?LinkId=248926</projectUrl>
|
||||
<iconUrl>https://github.com/Microsoft/DirectXTex/wiki/X_jpg.jpg</iconUrl>
|
||||
<licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
|
||||
@ -32,6 +32,12 @@ DirectXTex, a shared source library for reading and writing .DDS files, and perf
|
||||
<file target="lib\ARM\Release" src="DirectXTex\Bin\Windows10\ARM\Release\*.lib" />
|
||||
<file target="lib\ARM\Release" src="DirectXTex\Bin\Windows10\ARM\Release\*.pdb" />
|
||||
|
||||
<file target="lib\ARM64\Debug" src="DirectXTex\Bin\Windows10\ARM64\Debug\*.lib" />
|
||||
<file target="lib\ARM64\Debug" src="DirectXTex\Bin\Windows10\ARM64\Debug\*.pdb" />
|
||||
|
||||
<file target="lib\ARM64\Release" src="DirectXTex\Bin\Windows10\ARM64\Release\*.lib" />
|
||||
<file target="lib\ARM64\Release" src="DirectXTex\Bin\Windows10\ARM64\Release\*.pdb" />
|
||||
|
||||
<file target="lib\Win32\Debug" src="DirectXTex\Bin\Windows10\Win32\Debug\*.lib" />
|
||||
<file target="lib\Win32\Debug" src="DirectXTex\Bin\Windows10\Win32\Debug\*.pdb" />
|
||||
|
||||
|
@ -2,5 +2,6 @@
|
||||
<SignConfigXML>
|
||||
<job dest="__OUTPATHROOT__" certSubject="NuGet" jobname="NugetSigningTest">
|
||||
<file src="__INPATHROOT__\directxtex_desktop_2015*.nupkg" signType="CP-401405" dest="__OUTPATHROOT__\directxtex_desktop_2015*.nupkg" />
|
||||
<file src="__INPATHROOT__\directxtex_desktop_win10*.nupkg" signType="CP-401405" dest="__OUTPATHROOT__\directxtex_desktop_win10*.nupkg" />
|
||||
</job>
|
||||
</SignConfigXML>
|
@ -194,6 +194,12 @@ namespace DirectX
|
||||
WIC_FLAGS_IGNORE_SRGB = 0x20,
|
||||
// Ignores sRGB metadata if present in the file
|
||||
|
||||
WIC_FLAGS_FORCE_SRGB = 0x40,
|
||||
// Writes sRGB metadata into the file reguardless of format
|
||||
|
||||
WIC_FLAGS_FORCE_LINEAR = 0x80,
|
||||
// Writes linear gamma metadata into the file reguardless of format
|
||||
|
||||
WIC_FLAGS_DITHER = 0x10000,
|
||||
// Use ordered 4x4 dithering for any required conversions
|
||||
|
||||
@ -528,6 +534,11 @@ namespace DirectX
|
||||
// levels of '0' indicates a full mipchain, otherwise is generates that number of total levels (including the source base image)
|
||||
// Defaults to Fant filtering which is equivalent to a box filter
|
||||
|
||||
HRESULT __cdecl ScaleMipMapsAlphaForCoverage(
|
||||
_In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ size_t item,
|
||||
_In_ float alphaReference, _Inout_ ScratchImage& mipChain);
|
||||
|
||||
|
||||
enum TEX_PMALPHA_FLAGS
|
||||
{
|
||||
TEX_PMALPHA_DEFAULT = 0,
|
||||
|
@ -116,6 +116,233 @@ namespace
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
#if DIRECTX_MATH_VERSION >= 310
|
||||
#define VectorSum XMVectorSum
|
||||
#else
|
||||
inline XMVECTOR XM_CALLCONV VectorSum
|
||||
(
|
||||
FXMVECTOR V
|
||||
)
|
||||
{
|
||||
XMVECTOR vTemp = XMVectorSwizzle<2, 3, 0, 1>(V);
|
||||
XMVECTOR vTemp2 = XMVectorAdd(V, vTemp);
|
||||
vTemp = XMVectorSwizzle<1, 0, 3, 2>(vTemp2);
|
||||
return XMVectorAdd(vTemp, vTemp2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
HRESULT ScaleAlpha(
|
||||
const Image& srcImage,
|
||||
float alphaScale,
|
||||
const Image& destImage)
|
||||
{
|
||||
assert(srcImage.width == destImage.width);
|
||||
assert(srcImage.height == destImage.height);
|
||||
|
||||
ScopedAlignedArrayXMVECTOR scanline(reinterpret_cast<XMVECTOR*>(_aligned_malloc((sizeof(XMVECTOR)*srcImage.width), 16)));
|
||||
if (!scanline)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
const uint8_t* pSrc = srcImage.pixels;
|
||||
uint8_t* pDest = destImage.pixels;
|
||||
if (!pSrc || !pDest)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
const XMVECTOR vscale = XMVectorReplicate(alphaScale);
|
||||
|
||||
for (size_t h = 0; h < srcImage.height; ++h)
|
||||
{
|
||||
if (!_LoadScanline(scanline.get(), srcImage.width, pSrc, srcImage.rowPitch, srcImage.format))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
XMVECTOR* ptr = scanline.get();
|
||||
for (size_t w = 0; w < srcImage.width; ++w)
|
||||
{
|
||||
XMVECTOR v = *ptr;
|
||||
XMVECTOR alpha = XMVectorMultiply(XMVectorSplatW(v), vscale);
|
||||
*(ptr++) = XMVectorSelect(alpha, v, g_XMSelect1110);
|
||||
}
|
||||
|
||||
if (!_StoreScanline(pDest, destImage.rowPitch, destImage.format, scanline.get(), srcImage.width))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
pSrc += srcImage.rowPitch;
|
||||
pDest += destImage.rowPitch;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
void GenerateAlphaCoverageConvolutionVectors(
|
||||
_In_ size_t N,
|
||||
_Out_writes_(N*N) XMVECTOR* vectors)
|
||||
{
|
||||
for (size_t sy = 0; sy < N; ++sy)
|
||||
{
|
||||
const float fy = (sy + 0.5f) / N;
|
||||
const float ify = 1.0f - fy;
|
||||
|
||||
for (size_t sx = 0; sx < N; ++sx)
|
||||
{
|
||||
const float fx = (sx + 0.5f) / N;
|
||||
const float ifx = 1.0f - fx;
|
||||
|
||||
// [0]=(x+0, y+0), [1]=(x+0, y+1), [2]=(x+1, y+0), [3]=(x+1, y+1)
|
||||
vectors[sy * N + sx] = XMVectorSet(ifx * ify, ifx * fy, fx * ify, fx * fy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HRESULT CalculateAlphaCoverage(
|
||||
const Image& srcImage,
|
||||
float alphaReference,
|
||||
float alphaScale,
|
||||
float& coverage)
|
||||
{
|
||||
coverage = 0.0f;
|
||||
|
||||
ScopedAlignedArrayXMVECTOR row0(reinterpret_cast<XMVECTOR*>(_aligned_malloc((sizeof(XMVECTOR)*srcImage.width), 16)));
|
||||
if (!row0)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
ScopedAlignedArrayXMVECTOR row1(reinterpret_cast<XMVECTOR*>(_aligned_malloc((sizeof(XMVECTOR)*srcImage.width), 16)));
|
||||
if (!row1)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
const DWORD flags = 0;
|
||||
const XMVECTOR scale = XMVectorReplicate(alphaScale);
|
||||
|
||||
const uint8_t *pSrcRow0 = srcImage.pixels;
|
||||
if (!pSrcRow0)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
const size_t N = 8;
|
||||
XMVECTOR convolution[N * N];
|
||||
GenerateAlphaCoverageConvolutionVectors(N, convolution);
|
||||
|
||||
size_t coverageCount = 0;
|
||||
for (size_t y = 0; y < srcImage.height - 1; ++y)
|
||||
{
|
||||
if (!_LoadScanlineLinear(row0.get(), srcImage.width, pSrcRow0, srcImage.rowPitch, srcImage.format, flags))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
const uint8_t *pSrcRow1 = pSrcRow0 + srcImage.rowPitch;
|
||||
if (!_LoadScanlineLinear(row1.get(), srcImage.width, pSrcRow1, srcImage.rowPitch, srcImage.format, flags))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
const XMVECTOR* pRow0 = row0.get();
|
||||
const XMVECTOR* pRow1 = row1.get();
|
||||
for (size_t x = 0; x < srcImage.width - 1; ++x)
|
||||
{
|
||||
// [0]=(x+0, y+0), [1]=(x+0, y+1), [2]=(x+1, y+0), [3]=(x+1, y+1)
|
||||
XMVECTOR v1 = XMVectorSaturate(XMVectorMultiply(XMVectorSplatW(*pRow0), scale));
|
||||
XMVECTOR v2 = XMVectorSaturate(XMVectorMultiply(XMVectorSplatW(*pRow1), scale));
|
||||
XMVECTOR v3 = XMVectorSaturate(XMVectorMultiply(XMVectorSplatW(*(pRow0++)), scale));
|
||||
XMVECTOR v4 = XMVectorSaturate(XMVectorMultiply(XMVectorSplatW(*(pRow1++)), scale));
|
||||
|
||||
v1 = XMVectorMergeXY(v1, v2); // [v1.x v2.x --- ---]
|
||||
v3 = XMVectorMergeXY(v3, v4); // [v3.x v4.x --- ---]
|
||||
|
||||
XMVECTOR v = XMVectorPermute<0, 1, 4, 5>(v1, v3); // [v1.x v2.x v3.x v4.x]
|
||||
|
||||
for (size_t sy = 0; sy < N; ++sy)
|
||||
{
|
||||
const size_t ry = sy * N;
|
||||
for (size_t sx = 0; sx < N; ++sx)
|
||||
{
|
||||
v = VectorSum(XMVectorMultiply(v, convolution[ry + sx]));
|
||||
if (XMVectorGetX(v) > alphaReference)
|
||||
{
|
||||
++coverageCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pSrcRow0 = pSrcRow1;
|
||||
}
|
||||
|
||||
float cscale = static_cast<float>((srcImage.width - 1) * (srcImage.height - 1) * N * N);
|
||||
if (cscale > 0.f)
|
||||
{
|
||||
coverage = static_cast<float>(coverageCount) / cscale;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT EstimateAlphaScaleForCoverage(
|
||||
const Image& srcImage,
|
||||
float alphaReference,
|
||||
float targetCoverage,
|
||||
float& alphaScale)
|
||||
{
|
||||
float minAlphaScale = 0.0f;
|
||||
float maxAlphaScale = 4.0f;
|
||||
float bestAlphaScale = 1.0f;
|
||||
float bestError = FLT_MAX;
|
||||
|
||||
// Determine desired scale using a binary search. Hardcoded to 10 steps max.
|
||||
alphaScale = 1.0f;
|
||||
const size_t N = 10;
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
{
|
||||
float currentCoverage = 0.0f;
|
||||
HRESULT hr = CalculateAlphaCoverage(srcImage, alphaReference, alphaScale, currentCoverage);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
const float error = fabsf(currentCoverage - targetCoverage);
|
||||
if (error < bestError)
|
||||
{
|
||||
bestError = error;
|
||||
bestAlphaScale = alphaScale;
|
||||
}
|
||||
|
||||
if (currentCoverage < targetCoverage)
|
||||
{
|
||||
minAlphaScale = alphaScale;
|
||||
}
|
||||
else if (currentCoverage > targetCoverage)
|
||||
{
|
||||
maxAlphaScale = alphaScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
alphaScale = (minAlphaScale + maxAlphaScale) * 0.5f;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3179,3 +3406,75 @@ HRESULT DirectX::GenerateMipMaps3D(
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::ScaleMipMapsAlphaForCoverage(
|
||||
const Image* srcImages,
|
||||
size_t nimages,
|
||||
const TexMetadata& metadata,
|
||||
size_t item,
|
||||
float alphaReference,
|
||||
ScratchImage& mipChain)
|
||||
{
|
||||
if (!srcImages || !nimages || !IsValid(metadata.format) || nimages > metadata.mipLevels || !mipChain.GetImages())
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (metadata.IsVolumemap()
|
||||
|| IsCompressed(metadata.format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format))
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
|
||||
if (srcImages[0].format != metadata.format || srcImages[0].width != metadata.width || srcImages[0].height != metadata.height)
|
||||
{
|
||||
// Base image must be the same format, width, and height
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
float targetCoverage = 0.0f;
|
||||
HRESULT hr = CalculateAlphaCoverage(srcImages[0], alphaReference, 1.0f, targetCoverage);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// Copy base image
|
||||
{
|
||||
const Image& src = srcImages[0];
|
||||
|
||||
const Image *dest = mipChain.GetImage(0, item, 0);
|
||||
if (!dest)
|
||||
return E_POINTER;
|
||||
|
||||
uint8_t* pDest = dest->pixels;
|
||||
if (!pDest)
|
||||
return E_POINTER;
|
||||
|
||||
const uint8_t *pSrc = src.pixels;
|
||||
size_t rowPitch = src.rowPitch;
|
||||
for (size_t h = 0; h < metadata.height; ++h)
|
||||
{
|
||||
size_t msize = std::min<size_t>(dest->rowPitch, rowPitch);
|
||||
memcpy_s(pDest, dest->rowPitch, pSrc, msize);
|
||||
pSrc += rowPitch;
|
||||
pDest += dest->rowPitch;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t level = 1; level < metadata.mipLevels; ++level)
|
||||
{
|
||||
if (level >= nimages)
|
||||
return E_FAIL;
|
||||
|
||||
float alphaScale = 0.0f;
|
||||
hr = EstimateAlphaScaleForCoverage(srcImages[level], alphaReference, targetCoverage, alphaScale);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
const Image* mipImage = mipChain.GetImage(level, item, 0);
|
||||
if (!mipImage)
|
||||
return E_POINTER;
|
||||
|
||||
hr = ScaleAlpha(srcImages[level], alphaScale, *mipImage);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -570,6 +570,7 @@ namespace
|
||||
// Encodes image metadata
|
||||
//-------------------------------------------------------------------------------------
|
||||
HRESULT EncodeMetadata(
|
||||
DWORD flags,
|
||||
_In_ IWICBitmapFrameEncode* frame,
|
||||
const GUID& containerFormat,
|
||||
DXGI_FORMAT format)
|
||||
@ -584,7 +585,7 @@ namespace
|
||||
PROPVARIANT value;
|
||||
PropVariantInit(&value);
|
||||
|
||||
bool sRGB = IsSRGB(format);
|
||||
bool sRGB = ((flags & WIC_FLAGS_FORCE_LINEAR) == 0) && ((flags & WIC_FLAGS_FORCE_SRGB) != 0 || IsSRGB(format));
|
||||
|
||||
value.vt = VT_LPSTR;
|
||||
value.pszVal = const_cast<char*>("DirectXTex");
|
||||
@ -715,7 +716,7 @@ namespace
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hr = EncodeMetadata(frame, containerFormat, image.format);
|
||||
hr = EncodeMetadata(flags, frame, containerFormat, image.format);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
|
@ -2666,7 +2666,7 @@ inline HRESULT D3DX12ParsePipelineStream(const D3D12_PIPELINE_STATE_STREAM_DESC&
|
||||
}
|
||||
#endif // NTDDI_WIN10_RS2
|
||||
|
||||
// Requires the Windows 10 April 2018 Update SDK (17763)
|
||||
// Requires the Windows 10 October 2018 Update SDK (17763)
|
||||
#if defined(NTDDI_WIN10_RS5) && (NTDDI_VERSION >= NTDDI_WIN10_RS5)
|
||||
//------------------------------------------------------------------------------------------------
|
||||
inline bool operator==( const D3D12_CLEAR_VALUE &a, const D3D12_CLEAR_VALUE &b)
|
||||
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Microsoft Corp
|
||||
Copyright (c) 2011-2019 Microsoft Corp
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
|
18
ReadMe.txt
18
ReadMe.txt
@ -3,7 +3,7 @@ DIRECTX TEXTURE LIBRARY (DirectXTex)
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
October 25, 2018
|
||||
November 16, 2018
|
||||
|
||||
This package contains DirectXTex, a shared source library for reading and writing DDS
|
||||
files, and performing various texture content processing operations including
|
||||
@ -15,8 +15,8 @@ processing pipelines, but are not currently supported by a built-in WIC codec.
|
||||
|
||||
This code is designed to build with Visual Studio 2015 Update 3 or Visual Studio 2017.
|
||||
It is recommended that you make use of VS 2015 Update 3, Windows Tools 1.4.1, and the
|
||||
Windows 10 Anniversary Update SDK (14393) or VS 2017 (15.8 update) with the
|
||||
Windows 10 April 2018 Update SDK (17134).
|
||||
Windows 10 Anniversary Update SDK (14393) -or- VS 2017 (15.9 update) with the
|
||||
Windows 10 October 2018 Update SDK (17763).
|
||||
|
||||
DirectXTex\
|
||||
This contains the DirectXTex library. This includes a full-featured DDS reader and writer
|
||||
@ -125,17 +125,23 @@ RELEASE NOTES
|
||||
with the system headers. You can work around these by disabling this switch in the project files which is found
|
||||
in the <ConformanceMode> elements.
|
||||
|
||||
* The VS 2017 projects require the 15.5 update or later. For UWP and Win32 classic desktop projects with the 15.5
|
||||
or 15.6 updates, you need to install the standalone Windows 10 SDK (17134) which is otherwise included in
|
||||
the 15.7/15.8 update. Older VS 2017 updates will fail to load the projects due to use of the <ConformanceMode> element.
|
||||
* The VS 2017 projects require the 15.5 update or later. For UWP and Win32 classic desktop projects with the 15.5 -
|
||||
15.7 updates, you need to install the standalone Windows 10 SDK (17763) which is otherwise included in the 15.8.6 or
|
||||
later update. Older VS 2017 updates will fail to load the projects due to use of the <ConformanceMode> element.
|
||||
If using the 15.5 or 15.6 updates, you will see "warning D9002: ignoring unknown option '/Zc:__cplusplus'" because
|
||||
this switch isn't supported until 15.7. It is safe to ignore this warning, or you can edit the project files
|
||||
<AdditionalOptions> elements.
|
||||
|
||||
* The UWP projects include configurations for the ARM64 platform. These require VS 2017 (15.9 update) to build.
|
||||
|
||||
|
||||
------------------------------------
|
||||
RELEASE HISTORY
|
||||
|
||||
November 16, 2018
|
||||
VS 2017 updated for Windows 10 October 2018 Update SDK (17763)
|
||||
ARM64 platform configurations added to UWP projects
|
||||
|
||||
October 25, 2018
|
||||
Use UTF-8 instead of ANSI for narrow strings
|
||||
Updated D3DX12 internal copy to latest version
|
||||
|
@ -62,6 +62,7 @@ enum COMMANDS
|
||||
CMD_V_STRIP,
|
||||
CMD_MERGE,
|
||||
CMD_GIF,
|
||||
CMD_ARRAY_STRIP,
|
||||
CMD_MAX
|
||||
};
|
||||
|
||||
@ -119,6 +120,7 @@ const SValue g_pCommands[] =
|
||||
{ L"v-strip", CMD_V_STRIP },
|
||||
{ L"merge", CMD_MERGE },
|
||||
{ L"gif", CMD_GIF },
|
||||
{ L"array-strip", CMD_ARRAY_STRIP },
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
|
||||
@ -510,6 +512,7 @@ namespace
|
||||
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-strip or v-strip create a strip image from a cubemap\n");
|
||||
wprintf(L" array-strip creates a strip image from a 1D/2D array\n");
|
||||
wprintf(L" merge create texture from rgb image and alpha image\n");
|
||||
wprintf(L" gif create array from animated gif\n\n");
|
||||
wprintf(L" -r wildcard filename search is recursive\n");
|
||||
@ -958,10 +961,11 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
case CMD_V_STRIP:
|
||||
case CMD_MERGE:
|
||||
case CMD_GIF:
|
||||
case CMD_ARRAY_STRIP:
|
||||
break;
|
||||
|
||||
default:
|
||||
wprintf(L"Must use one of: cube, volume, array, cubearray,\n h-cross, v-cross, h-strip, v-strip\n merge, gif\n\n");
|
||||
wprintf(L"Must use one of: cube, volume, array, cubearray,\n h-cross, v-cross, h-strip, v-strip, array-strip\n merge, gif\n\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1090,6 +1094,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
case CMD_H_STRIP:
|
||||
case CMD_V_STRIP:
|
||||
case CMD_MERGE:
|
||||
case CMD_ARRAY_STRIP:
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1208,6 +1213,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
case CMD_H_STRIP:
|
||||
case CMD_V_STRIP:
|
||||
case CMD_GIF:
|
||||
case CMD_ARRAY_STRIP:
|
||||
if (conversion.size() > 1)
|
||||
{
|
||||
wprintf(L"ERROR: cross/strip/gif output only accepts 1 input file\n");
|
||||
@ -1269,6 +1275,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
case CMD_V_CROSS:
|
||||
case CMD_H_STRIP:
|
||||
case CMD_V_STRIP:
|
||||
case CMD_ARRAY_STRIP:
|
||||
_wmakepath_s(szOutputFile, nullptr, nullptr, fname, L".bmp");
|
||||
break;
|
||||
|
||||
@ -1327,6 +1334,29 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_ARRAY_STRIP:
|
||||
if (_wcsicmp(ext, L".dds") == 0)
|
||||
{
|
||||
hr = LoadFromDDSFile(pConv->szSrc, DDS_FLAGS_NONE, &info, *image);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L" FAILED (%x)\n", hr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info.dimension == TEX_DIMENSION_TEXTURE3D || info.arraySize < 2 || info.IsCubemap())
|
||||
{
|
||||
wprintf(L"\nERROR: Input must be a 1D/2D array\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wprintf(L"\nERROR: Input must be a dds of a 1D/2D array\n");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (_wcsicmp(ext, L".dds") == 0)
|
||||
{
|
||||
@ -1938,6 +1968,71 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_ARRAY_STRIP:
|
||||
{
|
||||
size_t twidth = width;
|
||||
size_t theight = height * images;
|
||||
|
||||
ScratchImage result;
|
||||
hr = result.Initialize2D(format, twidth, theight, 1, 1);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L"FAILED setting up result image (%x)\n", hr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(result.GetPixels(), 0, result.GetPixelsSize());
|
||||
|
||||
auto src = loadedImages.cbegin();
|
||||
auto dest = result.GetImage(0, 0, 0);
|
||||
|
||||
for (size_t index = 0; index < images; ++index)
|
||||
{
|
||||
auto img = (*src)->GetImage(0, index, 0);
|
||||
if (!img)
|
||||
{
|
||||
wprintf(L"FAILED: Unexpected error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Rect rect(0, 0, width, height);
|
||||
|
||||
size_t offsetx = 0;
|
||||
size_t offsety = 0;
|
||||
|
||||
offsety = index * height;
|
||||
|
||||
hr = CopyRectangle(*img, rect, *dest, dwFilter | dwFilterOpts, offsetx, offsety);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L"FAILED building result image (%x)\n", hr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Write array strip
|
||||
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(*dest, fileType, szOutputFile);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L" FAILED (%x)\n", hr);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
std::vector<Image> imageArray;
|
||||
|
@ -101,6 +101,8 @@ enum OPTIONS
|
||||
OPT_COLORKEY,
|
||||
OPT_TONEMAP,
|
||||
OPT_X2_BIAS,
|
||||
OPT_PRESERVE_ALPHA_COVERAGE,
|
||||
OPT_INVERT_Y,
|
||||
OPT_FILELIST,
|
||||
OPT_ROTATE_COLOR,
|
||||
OPT_PAPER_WHITE_NITS,
|
||||
@ -186,6 +188,8 @@ 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 },
|
||||
{ L"nits", OPT_PAPER_WHITE_NITS },
|
||||
@ -757,6 +761,8 @@ 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");
|
||||
|
||||
wprintf(L"\n <format>: ");
|
||||
@ -1121,6 +1127,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];
|
||||
@ -1188,6 +1195,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))
|
||||
@ -1574,15 +1582,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;
|
||||
@ -1660,6 +1680,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)
|
||||
@ -2483,6 +2504,60 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
cimage.reset();
|
||||
}
|
||||
|
||||
// --- Invert Y Channel --------------------------------------------------------
|
||||
if (dwOptions & (DWORD64(1) << OPT_INVERT_Y))
|
||||
{
|
||||
std::unique_ptr<ScratchImage> timage(new (std::nothrow) ScratchImage);
|
||||
if (!timage)
|
||||
{
|
||||
wprintf(L"\nERROR: Memory allocation failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
hr = TransformImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
|
||||
[&](XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t width, size_t y)
|
||||
{
|
||||
static const XMVECTORU32 s_selecty = { { { XM_SELECT_0, XM_SELECT_1, XM_SELECT_0, XM_SELECT_0 } } };
|
||||
|
||||
UNREFERENCED_PARAMETER(y);
|
||||
|
||||
for (size_t j = 0; j < width; ++j)
|
||||
{
|
||||
XMVECTOR value = inPixels[j];
|
||||
|
||||
XMVECTOR inverty = XMVectorSubtract(g_XMOne, value);
|
||||
|
||||
outPixels[j] = XMVectorSelect(value, inverty, s_selecty);
|
||||
}
|
||||
}, *timage);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L" FAILED [inverty] (%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.format == tinfo.format);
|
||||
assert(info.dimension == tinfo.dimension);
|
||||
|
||||
image.swap(timage);
|
||||
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))
|
||||
@ -2499,9 +2574,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)
|
||||
{
|
||||
@ -2627,6 +2704,52 @@ 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 && (info.dimension != TEX_DIMENSION_TEXTURE3D))
|
||||
{
|
||||
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 = ScaleMipMapsAlphaForCoverage(img, info.mipLevels, 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)
|
||||
|
Loading…
Reference in New Issue
Block a user