2011-03-01 12 views
6

SharpDXを使用して、DirectXを使用した単純な迷路のような2Dプログラムを作成しようとしています。など私は迷路の外、壁、廊下のために画面上にレンダリングすることができますビットマップを作成することを終わり、しかし.NETプログラムでSharpDXに画像をロード/作成する

、私はどのようにどちらかの負荷を見つけ出すように見えることはできません既存の画像ファイルをSharpDXライブラリのBitmapクラスに追加する方法、またはそのような新しいBitmapクラスをゼロから作成する方法について説明します。

すべてのクラスはDirectXの種類に直接マッピングされていると言われています。これはもっとDirectXを学ぶ必要があることを意味しますが、私は何かする必要のある簡単な例があることを望んでいました。

新しいビットマップを最初から作成して描画する必要がある場合は、それを行うことができますが、必要なピクセルを得ることは困難ではありませんが、その部分を把握することさえできません。

誰もがSharpDXライブラリの経験があり、私にいくつかの指摘を与えることができますか?

答えて

8

Sharpdxプロジェクトの[Issue]タブに直接質問してください。私はそこからすぐに回答を得ることができます(私は時々ネットからの使用状況をチェックしていることが幸運です) )。これを正式に求めていた場合は、図書館を改善し、問題の記録を問題データベースに保存することができました。

あなたの特定の問題に関しては、使用しているDirectX APIの種類が明確ではありません。私はあなたがDirect2Dを使用していると仮定しますか?

「はい」の場合、ファイルからSharpDX.Direct2D1.Bitmapを直接ロードするAPIはありません(このメソッドをAPIに追加します)。私はちょうどこれを実行しているbitmap sampleをアップロードしました。

/// <summary> 
/// Loads a Direct2D Bitmap from a file using System.Drawing.Image.FromFile(...) 
/// </summary> 
/// <param name="renderTarget">The render target.</param> 
/// <param name="file">The file.</param> 
/// <returns>A D2D1 Bitmap</returns> 
public static Bitmap LoadFromFile(RenderTarget renderTarget, string file) 
{ 
    // Loads from file using System.Drawing.Image 
    using (var bitmap = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(file)) 
    { 
     var sourceArea = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height); 
     var bitmapProperties = new BitmapProperties(new PixelFormat(Format.R8G8B8A8_UNorm, AlphaMode.Premultiplied)); 
     var size = new System.Drawing.Size(bitmap.Width, bitmap.Height); 

     // Transform pixels from BGRA to RGBA 
     int stride = bitmap.Width * sizeof(int); 
     using (var tempStream = new DataStream(bitmap.Height * stride, true, true)) 
     { 
      // Lock System.Drawing.Bitmap 
      var bitmapData = bitmap.LockBits(sourceArea, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); 

      // Convert all pixels 
      for (int y = 0; y < bitmap.Height; y++) 
      { 
       int offset = bitmapData.Stride*y; 
       for (int x = 0; x < bitmap.Width; x++) 
       { 
        // Not optimized 
        byte B = Marshal.ReadByte(bitmapData.Scan0, offset++); 
        byte G = Marshal.ReadByte(bitmapData.Scan0, offset++); 
        byte R = Marshal.ReadByte(bitmapData.Scan0, offset++); 
        byte A = Marshal.ReadByte(bitmapData.Scan0, offset++); 
        int rgba = R | (G << 8) | (B << 16) | (A << 24); 
        tempStream.Write(rgba); 
       } 

      } 
      bitmap.UnlockBits(bitmapData); 
      tempStream.Position = 0; 

      return new Bitmap(renderTarget, size, tempStream, stride, bitmapProperties); 
     } 
    } 
} 

あなたが言ったように、あなたは間違いなくために、どのようにプログラム生のDirectXを理解する必要があるので、SharpDXは、(より高いレベルのAPIを与えている例XNA用とは異なり)、生の低レベルのDirectX APIへのアクセスを与えていますSharpDXを使用する。

0

私がSlimDXを使用していたとき、私は同じ問題(Direct2Dを使用してビットマップを読み込む)を実行し、組み込みループを使わずにコードを少し必要とする同様の解決策を見つけました。それをSharpDXに変換するのは簡単なことでした。 (私は元の場所を教えてほしいが、何年も経っていて、ソースを文書化していないことがわかった。各タイプがどこで定義されているかを正確に知ることができます。また、いくつかのパラメータ(特にPixelFormatのパラメータ)には柔軟性があります。それらと一緒に遊んで、あなたのためにどんな作品を使用します。

 
private Bitmap Load(string filename) 
{ 
    System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(filename); 

    System.Drawing.Imaging.BitmapData bmpData = 
     bmp.LockBits(
      new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), 
      System.Drawing.Imaging.ImageLockMode.ReadOnly, 
      System.Drawing.Imaging.PixelFormat.Format32bppPArgb); 

    SharpDX.DataStream stream = new SharpDX.DataStream(bmpData.Scan0, bmpData.Stride * bmpData.Height, true, false); 
    SharpDX.Direct2D1.PixelFormat pFormat = new SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.B8G8R8A8_UNorm, AlphaMode.Premultiplied); 
    SharpDX.Direct2D1.BitmapProperties bmpProps = new SharpDX.Direct2D1.BitmapProperties(pFormat); 

    SharpDX.Direct2D1.Bitmap result = 
     new SharpDX.Direct2D1.Bitmap(
      m_renderTarget, 
      new SharpDX.Size2(bmp.Width, bmp.Height), 
      stream, 
      bmpData.Stride, 
      bmpProps); 

    bmp.UnlockBits(bmpData); 

    stream.Dispose(); 
    bmp.Dispose(); 

    return result; 
} 

あなたが見ることができるように、それは(関連するSharpDXサンプルプロジェクトで使用されている)アレクサンドルのアプローチとして、多くのビットマップストリームをロックし、代わりに手動で各ピクセルをコピーする、舞台裏コンストラクタ自体がコピーストリームを。私は、アレクサンドルの提案した方法とパフォーマンスを比較していないので、どちらの方法が速いのかは分かりませんが、私の目的には十分速く、コードはきれいです。

(構文強調表示の不足のため申し訳ありません。何らかの理由で<コード>タグがセクションに私のスニペットを壊す)

関連する問題