SharpDX 3.0.0 での変更点
SharpDXのメジャーバージョンが3になり、様々な仕様に変更が加えられています。そのひとつに、DirectXSDKのD3DXで提供されていたユーティリティ関数を提供が削除されました。これにより、今まではSharpDXで画像ファイルからテクスチャを直接生成できていましたが、今後はできなくなります。
なぜ画像ファイルの読み込みが削除されたのか
D3DXとして提供されていた画像ファイルの読み込みですが、本家DirectXSDKのほうでも削除される流れになっています。近年、ある機能を提供するライブラリは、その提供する機能に集中するべきである的な考えが広がっており、Direct3D11はGPUを操作し、GPUとの通信や命令の発行のみを担当するようになりました。結果、画像ファイルからテクスチャを生成する機能は削除されることになりました。
ちなみに、OpenGLではもとからテクスチャ読み込みの機能は提供されていませんでした。
DirectXSDKでの代替手段
DirectXSDKから様々なユーティリティ関数が削除されました。その代替先がMicrosoftのブログで示されています。
このブログ記事によると、テクスチャ読み込みはDirectXTexを使えとのことです。
DirectXTexとは
DirectXTexは、DXUTのテクスチャに関する関数を提供するライブラリです。画像ファイルの読み書きや、ノーマルマップの生成、色の変換などのを行えます。
SharpDX/C#ではどうするか
DirectXTexはC++で実装されているので、直接SharpDXから使うことはできません。
SharpDXTexを使う
私の作成したライブラリの宣伝です、はい。
SharpDXTexは、DirectXTexをC++/CLIでラップしたライブラリです。現在開発中ですのでまだ仕様は定まっていませんが、以下のように画像ファイルからテクスチャを生成することができます。
TexMetadata metadata;
var image = ImageUtil.LoadFromWICFile("GeneticaMortarlessBlocks.jpg", WICFlags.None, out metadata);
var texture = TextureUtil.CreateTexture(device, image.GetImages(), image.GetMetadata());
var textureView = new ShaderResourceView(device, texture);
DirectXTexで提供されている全ての機能を提供するつもりです(実装中)。
System.Drawing.Imageで読み込む
SharpDXTexはアーキテクチャに依存するので、ビルド対象のアーキテクチャを切り替える度にSharpDXTexのDLLを変更する必要があります。
もっと気軽に画像ファイルを読み込みたいという方はこの方法を使えばよいでしょう。
とりあえずサンプルコードを貼ります、ペタ。
var image = new System.Drawing.Bitmap("GeneticaMortarlessBlocks.jpg");
var boundsRect = new System.Drawing.Rectangle(0, 0, image.Width, image.Height);
var bitmap = image.Clone(boundsRect, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
var mapSrc = bitmap.LockBits(boundsRect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);
var databox = new[] { new DataBox(mapSrc.Scan0, bitmap.Width * 4, bitmap.Height) };
var textureDesc = new Texture2DDescription()
{
ArraySize = 1,
BindFlags = BindFlags.ShaderResource,
CpuAccessFlags = CpuAccessFlags.None,
Format = Format.B8G8R8A8_UNorm,
Height = bitmap.Height,
Width = bitmap.Width,
MipLevels = 1,
OptionFlags = ResourceOptionFlags.None,
SampleDescription = new SampleDescription(1, 0),
Usage = ResourceUsage.Default
};
var texture = new Texture2D(device, textureDesc, databox);
bitmap.UnlockBits(mapSrc);
var textureView = new ShaderResourceView(device, texture);
もうちょっとまじめにSystem.Drawing.Imageを使いたい方は、DirectXTexのWICTextureLoaderのソースを見てください。画像ファイルのピクセルフォーマットに適したDXGIのフォーマットを選択したりする手法が載っています。
System.Drawing.ImageはBMP、GIF、JPEG、PNG、TIFFに対応します。D3DXと比較するとTGAやDDSがありません。もしTGAやDDSを使いたい場合は、この方法は諦めましょう。
fin