Direct3D:IDIRECT3DSURFACE9(デフォルトプール)からシステムメモリビットマップを取得する効率的な方法?
-
09-10-2019 - |
質問
idirect3dsurface9、デフォルトプール、yuv形式があります。それからビットマップビットを効率的に取得するにはどうすればよいですか?現時点で私:
- レンダリングターゲットを作成します:
device->CreateRenderTarget(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &render_target, NULL)
- yuvをRGB32に変換します:
device->StretchRect(videomem_surf, NULL, render_target_, NULL, D3DTEXF_NONE)
(完全な長方形、ストレッチなし)
- システムメモリにプレーンオフスクリーン表面を作成します
device->CreateOffscreenPlainSurface(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &sysmem_offscreen_surf, NULL)
- Video Memからsysmemにデータをコピーします。
device->GetRenderTargetData(render_target, sysmem_offscreen_surface)
- オフスクリーン表面からgetDC、互換性のあるDCと互換性のあるビットマップ、オフスクリーンSufrace DCから互換性のあるDCにBitbltを作成し、getDibits()によって私のバッファーにビットマップビットをコピーします
これは、元の表面からターゲットをレンダリングし、次にオフスクリーン表面に、次に互換性のあるビットマップに、そして最後に私のバッファーまで、非常に多くのコピーのために、少し頭上に見えます。これをどのように改善できますか?
ありがとう
解決
あなたが作成するので、ターゲットをロック可能モードでレンダリングします(6番目のパラメーター CreateRenderTarget
)、レンダリングターゲットをロックできます LockRect
そこから直接データをコピーします。
MSDNは、ロック可能なレンダリングターゲットを使用することをお勧めしません。 言う:
レンダリングターゲットへの読み取りアクセスが必要な場合は、ロック可能なレンダリングターゲットの代わりにgetRenderTargetDataを使用します。
したがって、別の方法は電話することです GetRenderTargetData
オフスクリーンの表面に、次に(DCとビットマップを使用する代わりに)オフスクリーン表面をロックします。
他のヒント
同様に、インタージェイが指摘しているように...あなたはほとんど「正しい」方法で物事をしています。
明らかな改善点は、CreaterEnderTargetを呼び出し、OffScreenPlainsurfaceを一度Createしてから複数回再利用することです。ビットを取り戻す最速の方法は、表面を直接ロックすることです。
さらに、ビデオのようなものでこれをリアルタイムで行う必要がある場合は、おそらく一連の表面(両方のタイプ)をセットアップする方が良いでしょう。次に、複数のYUVフレームをCreaterEnderTarget'Dサーフェスにロードしてから、配列を埋めたら、最初のものをOffScreenPlainsSurfaceにコピーしてロックできます。
このようにして、より多くのコマンドをパイプラインにし、ロックを呼び出してパイプラインの同期を強制するのを止めます(つまり、ロックしている表面は、パイプラインの同期を引き起こす前に準備ができている必要があります)。