feat: 支持加载 DDS 纹理

This commit is contained in:
Xu Liu 2021-10-26 23:18:30 +08:00
commit 5cd798d5c5
3 changed files with 87 additions and 24 deletions

View file

@ -1,11 +1,12 @@
#include "pch.h"
#include "TextureLoader.h"
#include <DDSTextureLoader.h>
extern std::shared_ptr<spdlog::logger> logger;
ComPtr<ID3D11Texture2D> TextureLoader::Load(const wchar_t* fileName) {
ComPtr<ID3D11Texture2D> LoadImg(const wchar_t* fileName) {
ComPtr<IWICImagingFactory2> factory = App::GetInstance().GetWICImageFactory();
if (!factory) {
SPDLOG_LOGGER_ERROR(logger, "GetWICImageFactory 失败");
@ -64,7 +65,7 @@ ComPtr<ID3D11Texture2D> TextureLoader::Load(const wchar_t* fileName) {
useFloatFormat = bitsPerPixel > 32 || type == WICPixelFormatNumericRepresentationFixed || type == WICPixelFormatNumericRepresentationFloat;
}
// 转换格式
ComPtr<IWICFormatConverter> formatConverter;
hr = factory->CreateFormatConverter(&formatConverter);
@ -72,7 +73,7 @@ ComPtr<ID3D11Texture2D> TextureLoader::Load(const wchar_t* fileName) {
SPDLOG_LOGGER_ERROR(logger, MakeComErrorMsg("CreateFormatConverter 失败", hr));
return nullptr;
}
WICPixelFormatGUID targetFormat = useFloatFormat ? GUID_WICPixelFormat64bppRGBAHalf : GUID_WICPixelFormat32bppBGRA;
hr = formatConverter->Initialize(frame.Get(), targetFormat, WICBitmapDitherTypeNone, nullptr, 0, WICBitmapPaletteTypeCustom);
if (FAILED(hr)) {
@ -82,7 +83,7 @@ ComPtr<ID3D11Texture2D> TextureLoader::Load(const wchar_t* fileName) {
// 检查 D3D 纹理尺寸限制
UINT width, height;
hr = formatConverter->GetSize(&width, &height);
hr = formatConverter->GetSize(&width, &height);
if (FAILED(hr)) {
SPDLOG_LOGGER_ERROR(logger, MakeComErrorMsg("GetSize 失败", hr));
return nullptr;
@ -137,3 +138,80 @@ ComPtr<ID3D11Texture2D> TextureLoader::Load(const wchar_t* fileName) {
return result;
}
ComPtr<ID3D11Texture2D> LoadDDS(const wchar_t* fileName) {
ComPtr<ID3D11Resource> result;
HRESULT hr = DirectX::CreateDDSTextureFromFileEx(
App::GetInstance().GetRenderer().GetD3DDevice().Get(),
fileName,
0,
D3D11_USAGE_DEFAULT,
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
0,
0,
false,
&result,
nullptr
);
if (FAILED(hr)) {
SPDLOG_LOGGER_INFO(logger, MakeComErrorMsg("CreateDDSTextureFromFile 失败,将尝试不作为渲染目标", hr));
// 第二次尝试,不作为渲染目标
hr = DirectX::CreateDDSTextureFromFileEx(
App::GetInstance().GetRenderer().GetD3DDevice().Get(),
fileName,
0,
D3D11_USAGE_DEFAULT,
D3D11_BIND_SHADER_RESOURCE,
0,
0,
false,
&result,
nullptr
);
if (FAILED(hr)) {
SPDLOG_LOGGER_ERROR(logger, MakeComErrorMsg("CreateDDSTextureFromFile 失败", hr));
return nullptr;
}
}
ComPtr<ID3D11Texture2D> tex;
hr = result.As<ID3D11Texture2D>(&tex);
if (FAILED(hr)) {
SPDLOG_LOGGER_ERROR(logger, MakeComErrorMsg("从 ID3D11Resource 获取 ID3D11Texture2D 失败", hr));
return nullptr;
}
return tex;
}
ComPtr<ID3D11Texture2D> TextureLoader::Load(const wchar_t* fileName) {
std::wstring_view sv(fileName);
size_t npos = sv.find_last_of(L'.');
if (npos == std::wstring_view::npos) {
SPDLOG_LOGGER_ERROR(logger, "文件名无后缀名");
return nullptr;
}
std::wstring_view suffix = sv.substr(npos + 1);
static std::unordered_map<std::wstring_view, ComPtr<ID3D11Texture2D>(*)(const wchar_t*)> funcs = {
{L"bmp", LoadImg},
{L"jpg", LoadImg},
{L"jpeg", LoadImg},
{L"png", LoadImg},
{L"tif", LoadImg},
{L"tiff", LoadImg},
{L"dds", LoadDDS}
};
auto it = funcs.find(suffix);
if (it == funcs.end()) {
SPDLOG_LOGGER_ERROR(logger, "不支持读取该格式");
return nullptr;
}
return it->second(fileName);
}

View file

@ -1,3 +1,4 @@
TEXTURE.txt
out.txt
*.bmp
*.tiff
*.dds

View file

@ -3,24 +3,8 @@ import imageio
import numpy as np
IN_FILE = 'TEXTURE.txt'
OUT_FILE = 'RavuZoomR3Weights.bmp'
OUT_FILE = 'weights.tiff'
weights: np.ndarray = resolve(IN_FILE)
# 将四个分量分别压缩到 [0, 1]
for i in range(4):
minElem = np.amin(weights[:, :, i])
maxElem = np.amax(weights[:, :, i])
print(minElem, maxElem, sep=', ')
weights[:, :, i] = (weights[:, :, i] - minElem) / (maxElem - minElem)
weights = np.round(weights * 65535).astype(np.int)
out = np.zeros((weights.shape[0], weights.shape[1] * 4, 3), dtype=np.uint8)
for i in range(4):
out[:, weights.shape[1] * i: weights.shape[1] * (i + 1), 0] = weights[:, :, i] / 256
out[:, weights.shape[1] * i: weights.shape[1] * (i + 1), 1] = weights[:, :, i] % 256
imageio.imwrite(OUT_FILE, out)
weights = weights.astype(np.float32)
imageio.imwrite(OUT_FILE, weights)