私はいくつか (8-10) の大きなテクスチャ アトラス (BC1 DDS として保存された約 8192x8192) を持っていますが、それらはかなり小さいディスク容量であり、わずか 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 DEBUG エラーが発生します。「この 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)));
しかし、問題はまだ存在します。ビットマップを正常に作成できますが、それでも大量のメモリを消費します (実際のブロック圧縮サイズの 32MiB ではなく 250MiB+)。
のレンダーターゲットと関係があるのでしょうか?ソフトウェア B8G8R8A8_UNorm DeviceContext レンダー ターゲットを使用しています
EDIT3:
サンプル プロジェクト: https://drive.google.com/file/d/1hCgQnEV9xcTevgdswAiPJNREk1oDgqDC/view?usp=sharing