Direct3D: moyen efficace pour obtenir bitmap mémoire système à partir IDirect3DSurface9 (pool par défaut)?
-
09-10-2019 - |
Question
Je IDirect3DSurface9, piscine défaut, le format YUV. Comment puis-je obtenir efficacement bitmap bits à partir de ce? Au I moment:
- créer render target:
device->CreateRenderTarget(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &render_target, NULL)
- convertir YUV en RGB32:
device->StretchRect(videomem_surf, NULL, render_target_, NULL, D3DTEXF_NONE)
(Rectangle complet, étirage no)
- créer de surface hors écran plaine dans la mémoire système
device->CreateOffscreenPlainSurface(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &sysmem_offscreen_surf, NULL)
- données de copie de la vidéo à mem sysmem:
device->GetRenderTargetData(render_target, sysmem_offscreen_surface)
- GetDC de surface hors écran, créer bitmap DC et compatible compatible, BitBlt de offscreen sufrace DC à DC compatible et copier les bits bitmap à mon tampon par GetDIBits ()
cela ressemble un peu de frais généraux, à cause de tant de copie: de la surface d'origine pour rendre cible, puis à la surface hors-champ, puis bitmap compatible, puis enfin à mon tampon. Comment cela peut-il être amélioré?
Merci
La solution
Puisque vous vous créez un rendu cible en mode fermant à clé (6ème paramètre à CreateRenderTarget
), vous pouvez verrouiller la cible de rendu avec LockRect
et copier les données directement à partir de là.
MSDN ne recommande pas d'utiliser des cibles rendre fermant à clé, et
Autres conseils
Bien que les points interjay out ... vous faites presque les choses de la façon "correcte".
Les améliorations évidentes sont d'appeler CreateRenderTarget et CreateOffscreenPlainSurface une fois, puis les réutiliser plusieurs fois. Le moyen le plus rapide d'obtenir les bits serait revenir en arrière directement LockRect la surface.
En outre, si vous besoin de faire cela en temps réel sur quelque chose comme la vidéo, il serait probablement préférable de mettre en place un réseau de surfaces (deux types). Vous pouvez ensuite charger plusieurs images YUV sur la surface CreateRenderTarget'd puis une fois que vous avez rempli le tableau puis copiez le premier à la OffscreenPlainSurface et le verrouiller.
De cette façon vous permettre plusieurs des commandes à pipeline et d'arrêt vous demandant de verrouillage et d'une synchronisation de la canalisation (à savoir la surface vous verrouillage est prête avant de procéder qui provoque une synchronisation de pipeline).