<!DOCUMENT HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">

<html>

<head>
<meta http-equiv="Content-Language" content="ja">
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<link rel="stylesheet" type="text/css" href="../../default.css">
<title>GDI+ with Direct3D9</title>
</head>

<body>
<!--#include virtual="../../menu2.html"-->
<div class="contents">
<h4>contents</h4>
<ol>
	<li><a href="#sample">サンプル</a></li>
	<li><a href="#GetDC">GetDC()について補足</a></li>
</ol>
</div>

<h1>GDI+ with Direct3D9</h1>
<div>
	<p>
		DirectX9 になって、IDirect3DSurface9::GetDC() が追加されました。
		しかし、GDI ではαチャネルを扱うことができないことが問題です。
		どうせデバイスコンテキストを取得できるのは、
		マネージドまたはシステムメモリ上のサーフェイスのみなのですから、
		LockRect() して GDI+ を利用したほうが便利です。
	</p>
</div>

<h2 id="sample">サンプル</h2>
<div>
<p>
	実際のコードで示すとこんな感じ。
	DirectX8以前でも問題なくつかえますね。
	ただし、GDI+1.0は16bitカラーに対応していないようなので、そこだけ注意が必要です。
</p>

<pre><code>// フォーマットマッピング
Gdiplus::PixelFormat D3D_to_GDI(D3DFORMAT format)
{
  switch(format)
  {
  case D3DFMT_P8          : return PixelFormat8bppIndexed;
  case D3DFMT_L16         : return PixelFormat16bppGrayScale;
  case D3DFMT_R5G6B5      : return PixelFormat16bppRGB565;
  case D3DFMT_X1R5G5B5    : return PixelFormat16bppRGB555;
  case D3DFMT_A1R5G5B5    : return PixelFormat16bppARGB1555;
  case D3DFMT_R8G8B8      : return PixelFormat24bppRGB;
  case D3DFMT_X8R8G8B8    : return PixelFormat32bppRGB;
  case D3DFMT_A8R8G8B8    : return PixelFormat32bppARGB;
  case D3DFMT_A16B16G16R16: return PixelFormat64bppARGB;
  default                 : return PixelFormatUndefined;
  }
}

IDirect3DTexture9* pTexture; // 対象テクスチャ

DWORD level = 0;
D3DSURFACE_DESC desc;
m_pTexture->GetLevelDesc(level, &desc);
D3DLOCKED_RECT bits;
m_pTexture->LockRect(level, &bits, NULL, 0);
{  // ~Bitmap() → UnlockRect() の順が望ましいため、スコープを切る
  Bitmap bitmap(desc.Width, desc.Height, bits.Pitch, D3D_to_GDI(desc.Format), (BYTE*)bits.pBits);
  Graphics graphics(bitmap);
  // graphics を使う……
  graphics.Flush(); // 念のため
}
m_pTexture->UnlockRect(level);</code></pre>
</div>

<h2 id="GetDC">GetDC()について補足</h2>
<div>
	<p>
		GetDC() ⇒ Graphics(HDC hDC) は使えないかということなのですが、
		αが使えないGDIの問題点を引きずってしまうため、ほとんどメリットはありません。
		一応試したところ、XP組み込みのGDI+では、IDirect3DSurface9::GetDC()で取得したHDCからGdiplus::Graphicsを作成することはでき		ますが、そのときDirect3D7が初期化されています。
		もしかしたら、内部的にはirect3D7が使用されているのかもしれません。
		しかも、D3D7/D3D9ともに終了時にメモリリークが報告されます。
		この方法は使わないほうが良さそうです。
	</p>
</div>

<hr>
<!--#config timefmt="%Y/%m/%d"-->
<p align="right"><!--#echo var='LAST_MODIFIED'--></p>

</body>
</html>
