mirror of
https://github.com/microsoft/DirectXTex
synced 2024-11-21 20:10:05 +00:00
Add EXR source in Auxiliary directory
This commit is contained in:
parent
411ed658e2
commit
5b420edd7a
596
Auxiliary/DirectXTexEXR.cpp
Normal file
596
Auxiliary/DirectXTexEXR.cpp
Normal file
@ -0,0 +1,596 @@
|
|||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// File: DirectXTexEXR.cpp
|
||||||
|
//
|
||||||
|
// DirectXTex Auxillary functions for using the OpenEXR library
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "DirectXTexP.h"
|
||||||
|
|
||||||
|
#include "DirectXTexEXR.h"
|
||||||
|
|
||||||
|
#include <DirectXPackedVector.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <exception>
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Requires the OpenEXR library <http://www.openexr.com/> and ZLIB <http://www.zlib.net>
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic ignored "-Wswitch-enum"
|
||||||
|
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-dynamic-exception-spec"
|
||||||
|
#pragma clang diagnostic ignored "-Wfloat-equal"
|
||||||
|
#pragma clang diagnostic ignored "-Wimplicit-int-conversion"
|
||||||
|
#pragma clang diagnostic ignored "-Wlanguage-extension-token"
|
||||||
|
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||||
|
#pragma clang diagnostic ignored "-Wreserved-id-macro"
|
||||||
|
#pragma clang diagnostic ignored "-Wshadow-field-in-constructor"
|
||||||
|
#pragma clang diagnostic ignored "-Wsign-conversion"
|
||||||
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4244 4996)
|
||||||
|
#include <ImfRgbaFile.h>
|
||||||
|
#include <ImfIO.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static_assert(sizeof(Imf::Rgba) == 8, "Mismatch size");
|
||||||
|
|
||||||
|
using namespace DirectX;
|
||||||
|
using PackedVector::XMHALF4;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class com_exception : public std::exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
com_exception(HRESULT hr) noexcept : result(hr) {}
|
||||||
|
|
||||||
|
const char* what() const noexcept override
|
||||||
|
{
|
||||||
|
static char s_str[64] = {};
|
||||||
|
sprintf_s(s_str, "Failure with HRESULT of %08X", static_cast<unsigned int>(result));
|
||||||
|
return s_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT get_result() const noexcept { return result; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
HRESULT result;
|
||||||
|
};
|
||||||
|
|
||||||
|
class InputStream : public Imf::IStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InputStream(HANDLE hFile, const char fileName[]) :
|
||||||
|
IStream(fileName), m_hFile(hFile)
|
||||||
|
{
|
||||||
|
const LARGE_INTEGER dist = {};
|
||||||
|
LARGE_INTEGER result;
|
||||||
|
if (!SetFilePointerEx(m_hFile, dist, &result, FILE_END))
|
||||||
|
{
|
||||||
|
throw com_exception(HRESULT_FROM_WIN32(GetLastError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_EOF = result.QuadPart;
|
||||||
|
|
||||||
|
if (!SetFilePointerEx(m_hFile, dist, nullptr, FILE_BEGIN))
|
||||||
|
{
|
||||||
|
throw com_exception(HRESULT_FROM_WIN32(GetLastError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream(const InputStream&) = delete;
|
||||||
|
InputStream& operator = (const InputStream&) = delete;
|
||||||
|
|
||||||
|
InputStream(InputStream&&) = delete;
|
||||||
|
InputStream& operator=(InputStream&&) = delete;
|
||||||
|
|
||||||
|
bool read(char c[], int n) override
|
||||||
|
{
|
||||||
|
DWORD bytesRead;
|
||||||
|
if (!ReadFile(m_hFile, c, static_cast<DWORD>(n), &bytesRead, nullptr))
|
||||||
|
{
|
||||||
|
throw com_exception(HRESULT_FROM_WIN32(GetLastError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
const LARGE_INTEGER dist = {};
|
||||||
|
LARGE_INTEGER result;
|
||||||
|
if (!SetFilePointerEx(m_hFile, dist, &result, FILE_CURRENT))
|
||||||
|
{
|
||||||
|
throw com_exception(HRESULT_FROM_WIN32(GetLastError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.QuadPart >= m_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t tellg() override
|
||||||
|
{
|
||||||
|
const LARGE_INTEGER dist = {};
|
||||||
|
LARGE_INTEGER result;
|
||||||
|
if (!SetFilePointerEx(m_hFile, dist, &result, FILE_CURRENT))
|
||||||
|
{
|
||||||
|
throw com_exception(HRESULT_FROM_WIN32(GetLastError()));
|
||||||
|
}
|
||||||
|
return static_cast<uint64_t>(result.QuadPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void seekg(uint64_t pos) override
|
||||||
|
{
|
||||||
|
LARGE_INTEGER dist;
|
||||||
|
dist.QuadPart = static_cast<LONGLONG>(pos);
|
||||||
|
if (!SetFilePointerEx(m_hFile, dist, nullptr, FILE_BEGIN))
|
||||||
|
{
|
||||||
|
throw com_exception(HRESULT_FROM_WIN32(GetLastError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() override
|
||||||
|
{
|
||||||
|
SetLastError(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE m_hFile;
|
||||||
|
LONGLONG m_EOF;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OutputStream : public Imf::OStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OutputStream(HANDLE hFile, const char fileName[]) :
|
||||||
|
OStream(fileName), m_hFile(hFile) {}
|
||||||
|
|
||||||
|
OutputStream(const OutputStream&) = delete;
|
||||||
|
OutputStream& operator = (const OutputStream&) = delete;
|
||||||
|
|
||||||
|
OutputStream(OutputStream&&) = delete;
|
||||||
|
OutputStream& operator=(OutputStream&&) = delete;
|
||||||
|
|
||||||
|
void write(const char c[], int n) override
|
||||||
|
{
|
||||||
|
DWORD bytesWritten;
|
||||||
|
if (!WriteFile(m_hFile, c, static_cast<DWORD>(n), &bytesWritten, nullptr))
|
||||||
|
{
|
||||||
|
throw com_exception(HRESULT_FROM_WIN32(GetLastError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t tellp() override
|
||||||
|
{
|
||||||
|
const LARGE_INTEGER dist = {};
|
||||||
|
LARGE_INTEGER result;
|
||||||
|
if (!SetFilePointerEx(m_hFile, dist, &result, FILE_CURRENT))
|
||||||
|
{
|
||||||
|
throw com_exception(HRESULT_FROM_WIN32(GetLastError()));
|
||||||
|
}
|
||||||
|
return static_cast<uint64_t>(result.QuadPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void seekp(uint64_t pos) override
|
||||||
|
{
|
||||||
|
LARGE_INTEGER dist;
|
||||||
|
dist.QuadPart = static_cast<LONGLONG>(pos);
|
||||||
|
if (!SetFilePointerEx(m_hFile, dist, nullptr, FILE_BEGIN))
|
||||||
|
{
|
||||||
|
throw com_exception(HRESULT_FROM_WIN32(GetLastError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE m_hFile;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
|
||||||
|
//=====================================================================================
|
||||||
|
// Entry-points
|
||||||
|
//=====================================================================================
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Obtain metadata from EXR file on disk
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT DirectX::GetMetadataFromEXRFile(const wchar_t* szFile, TexMetadata& metadata)
|
||||||
|
{
|
||||||
|
if (!szFile)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
char fileName[MAX_PATH] = {};
|
||||||
|
const int result = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, fileName, MAX_PATH, nullptr, nullptr);
|
||||||
|
if (result <= 0)
|
||||||
|
{
|
||||||
|
*fileName = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
|
||||||
|
ScopedHandle hFile(safe_handle(CreateFile2(
|
||||||
|
szFile,
|
||||||
|
GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING,
|
||||||
|
nullptr)));
|
||||||
|
#else
|
||||||
|
ScopedHandle hFile(safe_handle(CreateFileW(
|
||||||
|
szFile,
|
||||||
|
GENERIC_READ, FILE_SHARE_READ,
|
||||||
|
nullptr,
|
||||||
|
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,
|
||||||
|
nullptr)));
|
||||||
|
#endif
|
||||||
|
if (!hFile)
|
||||||
|
{
|
||||||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream stream(hFile.get(), fileName);
|
||||||
|
#else
|
||||||
|
std::wstring wFileName(szFile);
|
||||||
|
std::string fileName(wFileName.cbegin(), wFileName.cend());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
Imf::RgbaInputFile file(stream);
|
||||||
|
#else
|
||||||
|
Imf::RgbaInputFile file(fileName.c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const auto dw = file.dataWindow();
|
||||||
|
|
||||||
|
const int width = dw.max.x - dw.min.x + 1;
|
||||||
|
const int height = dw.max.y - dw.min.y + 1;
|
||||||
|
|
||||||
|
if (width < 1 || height < 1)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
metadata.width = static_cast<size_t>(width);
|
||||||
|
metadata.height = static_cast<size_t>(height);
|
||||||
|
metadata.depth = metadata.arraySize = metadata.mipLevels = 1;
|
||||||
|
metadata.format = DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||||
|
metadata.dimension = TEX_DIMENSION_TEXTURE2D;
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
catch (const com_exception& exc)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
OutputDebugStringA(exc.what());
|
||||||
|
#endif
|
||||||
|
hr = exc.get_result();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(_WIN32) && defined(_DEBUG)
|
||||||
|
catch (const std::exception& exc)
|
||||||
|
{
|
||||||
|
OutputDebugStringA(exc.what());
|
||||||
|
hr = E_FAIL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
catch (const std::exception&)
|
||||||
|
{
|
||||||
|
hr = E_FAIL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
hr = E_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Load a EXR file from disk
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT DirectX::LoadFromEXRFile(const wchar_t* szFile, TexMetadata* metadata, ScratchImage& image)
|
||||||
|
{
|
||||||
|
if (!szFile)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
image.Release();
|
||||||
|
|
||||||
|
if (metadata)
|
||||||
|
{
|
||||||
|
memset(metadata, 0, sizeof(TexMetadata));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
char fileName[MAX_PATH] = {};
|
||||||
|
const int result = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, fileName, MAX_PATH, nullptr, nullptr);
|
||||||
|
if (result <= 0)
|
||||||
|
{
|
||||||
|
*fileName = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
|
||||||
|
ScopedHandle hFile(safe_handle(CreateFile2(
|
||||||
|
szFile,
|
||||||
|
GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING,
|
||||||
|
nullptr)));
|
||||||
|
#else
|
||||||
|
ScopedHandle hFile(safe_handle(CreateFileW(
|
||||||
|
szFile,
|
||||||
|
GENERIC_READ, FILE_SHARE_READ,
|
||||||
|
nullptr,
|
||||||
|
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,
|
||||||
|
nullptr)));
|
||||||
|
#endif
|
||||||
|
if (!hFile)
|
||||||
|
{
|
||||||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream stream(hFile.get(), fileName);
|
||||||
|
#else
|
||||||
|
std::wstring wFileName(szFile);
|
||||||
|
std::string fileName(wFileName.cbegin(), wFileName.cend());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
Imf::RgbaInputFile file(stream);
|
||||||
|
#else
|
||||||
|
Imf::RgbaInputFile file(fileName.c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto const dw = file.dataWindow();
|
||||||
|
|
||||||
|
const int width = dw.max.x - dw.min.x + 1;
|
||||||
|
const int height = dw.max.y - dw.min.y + 1;
|
||||||
|
|
||||||
|
if (width < 1 || height < 1)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if (metadata)
|
||||||
|
{
|
||||||
|
metadata->width = static_cast<size_t>(width);
|
||||||
|
metadata->height = static_cast<size_t>(height);
|
||||||
|
metadata->depth = metadata->arraySize = metadata->mipLevels = 1;
|
||||||
|
metadata->format = DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||||
|
metadata->dimension = TEX_DIMENSION_TEXTURE2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = image.Initialize2D(DXGI_FORMAT_R16G16B16A16_FLOAT,
|
||||||
|
static_cast<size_t>(width), static_cast<size_t>(height), 1u, 1u);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
file.setFrameBuffer(reinterpret_cast<Imf::Rgba*>(image.GetPixels()) - dw.min.x - dw.min.y * width, 1, static_cast<size_t>(width));
|
||||||
|
file.readPixels(dw.min.y, dw.max.y);
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
catch (const com_exception& exc)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
OutputDebugStringA(exc.what());
|
||||||
|
#endif
|
||||||
|
hr = exc.get_result();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(_WIN32) && defined(_DEBUG)
|
||||||
|
catch (const std::exception& exc)
|
||||||
|
{
|
||||||
|
OutputDebugStringA(exc.what());
|
||||||
|
hr = E_FAIL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
catch (const std::exception&)
|
||||||
|
{
|
||||||
|
hr = E_FAIL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
hr = E_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
image.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Save a EXR file to disk
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
_Use_decl_annotations_
|
||||||
|
HRESULT DirectX::SaveToEXRFile(const Image& image, const wchar_t* szFile)
|
||||||
|
{
|
||||||
|
if (!szFile)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (!image.pixels)
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
if (image.width > INT32_MAX || image.height > INT32_MAX)
|
||||||
|
return /* HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) */ static_cast<HRESULT>(0x80070032L);
|
||||||
|
|
||||||
|
switch (image.format)
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
||||||
|
if ((image.rowPitch % 8) > 0)
|
||||||
|
return E_FAIL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DXGI_FORMAT_R32G32B32A32_FLOAT:
|
||||||
|
case DXGI_FORMAT_R32G32B32_FLOAT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return /* HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) */ static_cast<HRESULT>(0x80070032L);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
char fileName[MAX_PATH] = {};
|
||||||
|
const int result = WideCharToMultiByte(CP_UTF8, 0, szFile, -1, fileName, MAX_PATH, nullptr, nullptr);
|
||||||
|
if (result <= 0)
|
||||||
|
{
|
||||||
|
*fileName = 0;
|
||||||
|
}
|
||||||
|
// Create file and write header
|
||||||
|
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
|
||||||
|
ScopedHandle hFile(safe_handle(CreateFile2(
|
||||||
|
szFile,
|
||||||
|
GENERIC_WRITE, 0, CREATE_ALWAYS,
|
||||||
|
nullptr)));
|
||||||
|
#else
|
||||||
|
ScopedHandle hFile(safe_handle(CreateFileW(
|
||||||
|
szFile,
|
||||||
|
GENERIC_WRITE, 0,
|
||||||
|
nullptr,
|
||||||
|
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
|
||||||
|
nullptr)));
|
||||||
|
#endif
|
||||||
|
if (!hFile)
|
||||||
|
{
|
||||||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto_delete_file delonfail(hFile.get());
|
||||||
|
|
||||||
|
OutputStream stream(hFile.get(), fileName);
|
||||||
|
#else
|
||||||
|
std::wstring wFileName(szFile);
|
||||||
|
std::string fileName(wFileName.cbegin(), wFileName.cend());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const int width = static_cast<int>(image.width);
|
||||||
|
const int height = static_cast<int>(image.height);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
Imf::RgbaOutputFile file(stream, Imf::Header(width, height), Imf::WRITE_RGBA);
|
||||||
|
#else
|
||||||
|
Imf::RgbaOutputFile file(fileName.c_str(), Imf::Header(width, height), Imf::WRITE_RGBA);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (image.format == DXGI_FORMAT_R16G16B16A16_FLOAT)
|
||||||
|
{
|
||||||
|
file.setFrameBuffer(reinterpret_cast<const Imf::Rgba*>(image.pixels), 1, image.rowPitch / 8);
|
||||||
|
file.writePixels(height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const uint64_t bytes = image.width * image.height;
|
||||||
|
|
||||||
|
if (bytes > UINT32_MAX)
|
||||||
|
{
|
||||||
|
return /* HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW) */ static_cast<HRESULT>(0x80070216L);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<XMHALF4> temp(new (std::nothrow) XMHALF4[static_cast<size_t>(bytes)]);
|
||||||
|
if (!temp)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
file.setFrameBuffer(reinterpret_cast<const Imf::Rgba*>(temp.get()), 1, image.width);
|
||||||
|
|
||||||
|
auto sPtr = image.pixels;
|
||||||
|
auto dPtr = temp.get();
|
||||||
|
if (image.format == DXGI_FORMAT_R32G32B32A32_FLOAT)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < height; ++j)
|
||||||
|
{
|
||||||
|
auto srcPtr = reinterpret_cast<const XMFLOAT4*>(sPtr);
|
||||||
|
auto destPtr = dPtr;
|
||||||
|
for (int k = 0; k < width; ++k, ++srcPtr, ++destPtr)
|
||||||
|
{
|
||||||
|
const XMVECTOR v = XMLoadFloat4(srcPtr);
|
||||||
|
PackedVector::XMStoreHalf4(destPtr, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
sPtr += image.rowPitch;
|
||||||
|
dPtr += width;
|
||||||
|
|
||||||
|
file.writePixels(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(image.format == DXGI_FORMAT_R32G32B32_FLOAT);
|
||||||
|
|
||||||
|
for (int j = 0; j < height; ++j)
|
||||||
|
{
|
||||||
|
auto srcPtr = reinterpret_cast<const XMFLOAT3*>(sPtr);
|
||||||
|
auto destPtr = dPtr;
|
||||||
|
for (int k = 0; k < width; ++k, ++srcPtr, ++destPtr)
|
||||||
|
{
|
||||||
|
XMVECTOR v = XMLoadFloat3(srcPtr);
|
||||||
|
v = XMVectorSelect(g_XMIdentityR3, v, g_XMSelect1110);
|
||||||
|
PackedVector::XMStoreHalf4(destPtr, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
sPtr += image.rowPitch;
|
||||||
|
dPtr += width;
|
||||||
|
|
||||||
|
file.writePixels(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
catch (const com_exception& exc)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
OutputDebugStringA(exc.what());
|
||||||
|
#endif
|
||||||
|
hr = exc.get_result();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(_WIN32) && defined(_DEBUG)
|
||||||
|
catch (const std::exception& exc)
|
||||||
|
{
|
||||||
|
OutputDebugStringA(exc.what());
|
||||||
|
hr = E_FAIL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
catch (const std::exception&)
|
||||||
|
{
|
||||||
|
hr = E_FAIL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
hr = E_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
delonfail.clear();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
26
Auxiliary/DirectXTexEXR.h
Normal file
26
Auxiliary/DirectXTexEXR.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// File: DirectXTexEXR.h
|
||||||
|
//
|
||||||
|
// DirectXTex Auxillary functions for using the OpenEXR library
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DirectXTex.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace DirectX
|
||||||
|
{
|
||||||
|
HRESULT __cdecl GetMetadataFromEXRFile(
|
||||||
|
_In_z_ const wchar_t* szFile,
|
||||||
|
_Out_ TexMetadata& metadata);
|
||||||
|
|
||||||
|
HRESULT __cdecl LoadFromEXRFile(
|
||||||
|
_In_z_ const wchar_t* szFile,
|
||||||
|
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image);
|
||||||
|
|
||||||
|
HRESULT __cdecl SaveToEXRFile(_In_ const Image& image, _In_z_ const wchar_t* szFile);
|
||||||
|
}
|
@ -29,7 +29,6 @@ option(ENABLE_CODE_ANALYSIS "Use Static Code Analysis on build" OFF)
|
|||||||
option(USE_PREBUILT_SHADERS "Use externally built HLSL shaders" OFF)
|
option(USE_PREBUILT_SHADERS "Use externally built HLSL shaders" OFF)
|
||||||
|
|
||||||
# Includes the functions for loading/saving OpenEXR files at runtime
|
# Includes the functions for loading/saving OpenEXR files at runtime
|
||||||
# NOTE requires adding DirectXTexEXR.h/.cpp source files (vcpkg does this automatically)
|
|
||||||
option(ENABLE_OPENEXR_SUPPORT "Build with OpenEXR support" OFF)
|
option(ENABLE_OPENEXR_SUPPORT "Build with OpenEXR support" OFF)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
@ -107,10 +106,10 @@ endif()
|
|||||||
|
|
||||||
if(ENABLE_OPENEXR_SUPPORT)
|
if(ENABLE_OPENEXR_SUPPORT)
|
||||||
set(LIBRARY_HEADERS ${LIBRARY_HEADERS}
|
set(LIBRARY_HEADERS ${LIBRARY_HEADERS}
|
||||||
DirectXTex/DirectXTexEXR.h)
|
Auxiliary/DirectXTexEXR.h)
|
||||||
|
|
||||||
set(LIBRARY_SOURCES ${LIBRARY_SOURCES}
|
set(LIBRARY_SOURCES ${LIBRARY_SOURCES}
|
||||||
DirectXTex/DirectXTexEXR.cpp)
|
Auxiliary/DirectXTexEXR.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(BUILD_DX11 AND WIN32)
|
if(BUILD_DX11 AND WIN32)
|
||||||
@ -242,6 +241,7 @@ if(BUILD_TOOLS AND WIN32 AND (NOT WINDOWS_STORE))
|
|||||||
|
|
||||||
if(ENABLE_OPENEXR_SUPPORT)
|
if(ENABLE_OPENEXR_SUPPORT)
|
||||||
foreach(t IN LISTS TOOL_EXES)
|
foreach(t IN LISTS TOOL_EXES)
|
||||||
|
target_include_directories(${t} PRIVATE Auxiliary)
|
||||||
target_link_libraries(${t} ${OPENEXR_ILMIMF_LIBRARY})
|
target_link_libraries(${t} ${OPENEXR_ILMIMF_LIBRARY})
|
||||||
target_compile_options(${t} PRIVATE -DUSE_OPENEXR)
|
target_compile_options(${t} PRIVATE -DUSE_OPENEXR)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
@ -119,6 +119,13 @@
|
|||||||
},
|
},
|
||||||
"hidden": true
|
"hidden": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "EXR",
|
||||||
|
"cacheVariables": {
|
||||||
|
"ENABLE_OPENEXR_SUPPORT": true
|
||||||
|
},
|
||||||
|
"hidden": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "MinGW32",
|
"name": "MinGW32",
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
@ -170,6 +177,9 @@
|
|||||||
{ "name": "arm64-Debug-VCPKG" , "description": "MSVC for ARM64 (Debug) using VCPKG", "inherits": [ "base", "ARM64", "Debug", "MSVC", "VCPKG" ] },
|
{ "name": "arm64-Debug-VCPKG" , "description": "MSVC for ARM64 (Debug) using VCPKG", "inherits": [ "base", "ARM64", "Debug", "MSVC", "VCPKG" ] },
|
||||||
{ "name": "arm64-Release-VCPKG", "description": "MSVC for ARM64 (Release) using VCPKG", "inherits": [ "base", "ARM64", "Release", "MSVC", "VCPKG" ] },
|
{ "name": "arm64-Release-VCPKG", "description": "MSVC for ARM64 (Release) using VCPKG", "inherits": [ "base", "ARM64", "Release", "MSVC", "VCPKG" ] },
|
||||||
|
|
||||||
|
{ "name": "x64-Debug-EXR" , "description": "MSVC for x64 (Debug) using VCPKG/OpenEXR", "inherits": [ "base", "x64", "Debug", "MSVC", "VCPKG", "EXR" ] },
|
||||||
|
{ "name": "x64-Release-EXR" , "description": "MSVC for x64 (Release) using VCPKG/OpenEXR", "inherits": [ "base", "x64", "Release", "MSVC", "VCPKG", "EXR" ] },
|
||||||
|
|
||||||
{ "name": "x64-Debug-Clang" , "description": "Clang/LLVM for x64 (Debug) with DX12", "inherits": [ "base", "x64", "Debug", "Clang" ] },
|
{ "name": "x64-Debug-Clang" , "description": "Clang/LLVM for x64 (Debug) with DX12", "inherits": [ "base", "x64", "Debug", "Clang" ] },
|
||||||
{ "name": "x64-Release-Clang" , "description": "Clang/LLVM for x64 (Release) with DX12", "inherits": [ "base", "x64", "Release", "Clang" ] },
|
{ "name": "x64-Release-Clang" , "description": "Clang/LLVM for x64 (Release) with DX12", "inherits": [ "base", "x64", "Release", "Clang" ] },
|
||||||
{ "name": "x86-Debug-Clang" , "description": "Clang/LLVM for x86 (Debug) with DX12", "inherits": [ "base", "x86", "Debug", "Clang" ], "environment": { "CXXFLAGS": "-m32" } },
|
{ "name": "x86-Debug-Clang" , "description": "Clang/LLVM for x86 (Debug) with DX12", "inherits": [ "base", "x86", "Debug", "Clang" ], "environment": { "CXXFLAGS": "-m32" } },
|
||||||
|
@ -23,6 +23,10 @@ These components are designed to work without requiring any content from the leg
|
|||||||
> The majority of the header files here are intended for internal implementation
|
> The majority of the header files here are intended for internal implementation
|
||||||
of the library only (``BC.h``, ``BCDirectCompute.h``, ``DDS.h``, ``DirectXTexP.h``, etc.). Only ``DirectXTex.h`` and ``DirectXTex.inl`` are meant as the 'public' header for the library.
|
of the library only (``BC.h``, ``BCDirectCompute.h``, ``DDS.h``, ``DirectXTexP.h``, etc.). Only ``DirectXTex.h`` and ``DirectXTex.inl`` are meant as the 'public' header for the library.
|
||||||
|
|
||||||
|
* ``Auxiliary\``
|
||||||
|
|
||||||
|
+ Contains optional source files for the DirectXTex library, such as adapter loading functions using the OpenEXR library.
|
||||||
|
|
||||||
* ``Texconv\``
|
* ``Texconv\``
|
||||||
|
|
||||||
+ This DirectXTex sample is an implementation of the [texconv](https://github.com/Microsoft/DirectXTex/wiki/Texconv) command-line texture utility from the DirectX SDK utilizing DirectXTex rather than D3DX.
|
+ This DirectXTex sample is an implementation of the [texconv](https://github.com/Microsoft/DirectXTex/wiki/Texconv) command-line texture utility from the DirectX SDK utilizing DirectXTex rather than D3DX.
|
||||||
|
Loading…
Reference in New Issue
Block a user