mirror of
https://github.com/Blinue/Magpie.git
synced 2026-06-24 02:04:10 +00:00
feat: 支持加载 DDS 纹理
This commit is contained in:
parent
e046401946
commit
5cd798d5c5
3 changed files with 87 additions and 24 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
3
tools/HookTextureResolver/.gitignore
vendored
3
tools/HookTextureResolver/.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
|||
TEXTURE.txt
|
||||
out.txt
|
||||
*.bmp
|
||||
*.tiff
|
||||
*.dds
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue