0

我有几个(8-10)大纹理图集(大约 8192x8192 保存为 BC1 DDS),但它们的磁盘空间相当小,只有 32MiB。

问题是,当我使用 WIC 加载这些文件时,它们会失去块压缩并占用多达 256MiB 的 RAM,根据消息来源,这不应该发生

这是我加载文件的 C# SharpDX 代码:

public Bitmap LoadBitmap(string path) {
    Bitmap m;

    using (BitmapDecoder d = new BitmapDecoder(imagingFactory, $"plugins/HDPatch/{path}", Guid.Empty, SharpDX.IO.NativeFileAccess.Read, DecodeOptions.CacheOnDemand)) {
        DdsDecoder decoder = d.QueryInterface<DdsDecoder>();
        decoder.GetFrame(0, 0, 0, out BitmapFrameDecode frame);
        m = SharpDX.Direct2D1.Bitmap.FromWicBitmap(_target, frame);//_target.CreateBitmap(converter, new BitmapProperties());
        decoder.Dispose();
        frame.Dispose();
    }

    return m;
}

我是否需要更改某些内容,还是应该使用与 WIC 不同的加载方法?

我查看了DdsFrameDecode.CopyBlocks (+ ID2D1Bitmap::CopyFromMemory ) 方法,但我不知道它是如何工作的..(我的步幅到底是什么,我从哪里得到这些信息)

编辑:

所以 BitmapFrameDecode 给了我一个 32bppPBGRA 的 PixelFormat

如果我从该 BitmapFrameDecode 查询 DDSFrameDecode,我会从 DdsFrameDecode 中获得 BC1_UNorm 格式。DdsDecoder 还报告带有 DdsAlphaModePremultiplied 的纹理和 BC1_UNorm 的 DxgiFormat。

但是当我在 BitmapProperties 中强制使用 BC1_UNorm 的像素格式时,我得到了 D2D 调试错误:“传递给此 API 的像素格式与 IWICBitmapSource 的像素格式不兼容”

EDIT2:我想出了如何使用 CopyBlocks

    SharpDX.DataStream stream = new 
    SharpDX.DataStream(test2.FormatInfo.BytesPerBlock * test2.SizeInBlocks.Width * test2.SizeInBlocks.Height, true, true);
    test2.CopyBlocks(null, test2.FormatInfo.BytesPerBlock * test2.SizeInBlocks.Width, stream);
    m = new Bitmap(_target, new SharpDX.Size2(decoder.Parameters.Width, decoder.Parameters.Height), stream, test2.FormatInfo.BytesPerBlock * test2.FormatInfo.BlockWidth, new BitmapProperties(new PixelFormat(SharpDX.DXGI.Format.BC1_UNorm, AlphaMode.Premultiplied)));

但问题仍然存在。它可以成功创建位图,但仍然消耗大量内存(250MiB+ 而不是实际块压缩大小 32MiB)

它可能与渲染目标有关吗?我使用软件 B8G8R8A8_UNorm DeviceContext 渲染目标

编辑3:

示例项目:https ://drive.google.com/file/d/1hCgQnEV9xcTevgdswAiPJNREk1oDgqDC/view?usp=sharing

4

0 回答 0