2017-08-11 6 views
1

Je ne suis pas familier avec directx, mais j'ai rencontré un problème dans un petit projet, dont une partie implique la capture de données directx. J'espère, ci-dessous, j'ai un sens.Quels facteurs déterminent DXGI_FORMAT?

question générale:

Je voudrais savoir quels facteurs déterminent la DXGI_FORMAT d'une texture dans le backbuffer (hardware ?, OS ?, l'application ?, la version directx?). Et plus important encore, lors de la capture d'une texture à partir du backbuffer, est-il possible de recevoir une texture dans le format désiré en fournissant le format en tant que paramètre, ayant le format automatiquement converti si nécessaire.

sur mon problème Specifics:

Je capture des écrans de jeux à l'aide du logiciel ouvert Broadcaster (OBS) et le processus de les utiliser une bibliothèque spécifique (OpenCV) avant diffusion. J'ai remarqué que, après les mises à jour à la fois Windows et OBS, j'obtiens 'DXGI_FORMAT_R10G10B10A2_UNORM' comme DXGI_FORMAT. C'est un problème pour moi, car pour autant que je sache, OpenCV ne fournit pas un moyen pratique pour construire un objet OpenCV quand les couleurs sont 10bits. Vous trouverez ci-dessous quelques lignes pertinentes du fichier source OBS modifié.

d3d11_copy_texture(data.texture, backbuffer); 
... 
hlog(toStr(data.format)); // prints 24 = DXGI_FORMAT_R10G10B10A2_UNORM 
... 
ID3D11Texture2D* tex; 
bool success = create_d3d11_stage_surface(&tex); 
if (success) { 
    ... 
    HRESULT hr = data.context->Map(tex, subresource, D3D11_MAP_READ, 0, &mappedTex); 
    ... 
    Mat frame(data.cy, data.cx, CV_8UC4, mappedTex.pData, (int)mappedTex.RowPitch); //This creates an OpenCV Mat object. 
               //No support for 10-bit coors. Expects 8-bit colors (CV_8UC4 argument). 
               //When the resulting Mat is viewed, colours are jumbled (Probably because 10-bits did not fit into 8-bits). 

Avant les mises à jour (quand je travaillais sur ce il y a un an), je recevais probablement DXGI_FORMAT = DXGI_FORMAT_B8G8R8A8_UNORM, parce que le code ci-dessus utilisé pour travailler.

Maintenant, je me demande ce qui a changé, et si je peux modifier le code source de OBS pour recevoir des données avec le DXGI_FORMAT souhaité.

La méthode 'create_d3d11_stage_surface' ci-dessus définit le DXGI_FORMAT, mais je ne suis pas sûr si cela signifie 'donnez-moi des données avec ce DXGI_FORMAT' ou 'je sais que vous travaillez avec ce format, donnez-moi ce que vous avez'.

static bool create_d3d11_stage_surface(ID3D11Texture2D **tex) 
{ 
    HRESULT hr; 

    D3D11_TEXTURE2D_DESC desc  = {}; 
    desc.Width      = data.cx; 
    desc.Height     = data.cy; 
    desc.Format = data.format; 
    ... 

J'espère que, redéfinissant la desc.Format avec DXGI_FORMAT_B8G8R8A8_UNORM entraînerait ce format étant passé comme argument dans l'appel ID3D11DeviceContext :: Carte ci-dessus, et j'obtenir des données au format spécifié. Mais ça n'a pas marché.

+0

DXGI_FORMAT d'une texture est spécifié lors de la création de la texture. Vous devrez peut-être "convertir" les données r10g10b10a2 en b8r8g8a8 dans la CPU lorsque vous les introduisez dans OpenCV pour traitement. – VuVirt

+0

J'ai vérifié directxtex mais je pense que l'obtention de l'image d'un autre endroit dans OBS sera plus facile dans mon cas. – poster9238463

Répondre

0

Le choix de la cible de rendu dépend de l'application, mais ils doivent en choisir un en fonction du niveau de fonctionnalité matériel Direct3D. Formats pour rendre les cibles dans swapchains sont affichent généralement des formats SCANOUT:

DXGI_FORMAT_R8G8B8A8_UNORM 
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB 
DXGI_FORMAT_B8G8R8A8_UNORM 
DXGI_FORMAT_B8G8R8A8_UNORM 
DXGI_FORMAT_R10G10B10A2_UNORM 
DXGI_FORMAT_R16G16B16A16_FLOAT 
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM (rare) 

Voir la DXGI documentation pour la liste complète des formats et usages pris en charge par le niveau de fonctionnalité.

Direct3D 11 n'effectue pas de conversions de format lorsque vous copiez des ressources telles que la copie vers des textures de rendu de transfert, donc si vous souhaitez effectuer une conversion de format, vous devrez le faire vous-même. Notez que le code de conversion côté CPU pour tous les formats DXGI se trouve dans DirectXTex.

+0

Donc, dans mon cas, c'est le jeu qui définit le format (basé sur le niveau de fonctionnalité du matériel). – poster9238463

0

C'est l'application qui décide de ce format. Le plus simple serait R8G8B8A8, qui représente simplement les valeurs RVB et alpha. Mais, si le développeur décide qu'il utilisera HDR, le backbuffer sera probablement R11B11G10, car vous pouvez y stocker des données plus précises, sans informations sur le canal alpha. Si le jeu est par exemple en noir et blanc, il n'y a pas besoin de garder tous les canaux RVB dans le tampon arrière, vous pouvez utiliser un format plus simple. J'espère que ça aide.