2014-09-05 25 views
5
esperti

Ciao Direct3D schermo multiplo,C++ Direct3D Cattura

Attualmente sto sviluppando un'applicazione con Direct3D al fine di catturare il mio desktop due monitor (usato come tavolo esteso naturalmente). Il seguente codice funziona bene, ma io sono solo in grado di catturare lo schermo principale e non il desktop esteso (solo uno schermo viene catturato due volte)

Come posso adattare questa soluzione per una cattura doppio schermo?

Prima di tutto, ho inizializzare Direct3D:

D3DDISPLAYMODE   d3dDisplayMode; 
D3DPRESENT_PARAMETERS d3dPresentationParameters; //Presentation parameters (backbufferwidth, height...) 

if((pSinfo->g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)) == NULL) 
    return FALSE; 

if(pSinfo->g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3dDisplayMode) == D3DERR_INVALIDCALL) 
    return FALSE; 

ZeroMemory(&d3dPresentationParameters,sizeof(D3DPRESENT_PARAMETERS)); 
d3dPresentationParameters.Windowed = TRUE; 
d3dPresentationParameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; 
d3dPresentationParameters.BackBufferFormat = d3dDisplayMode.Format; 
d3dPresentationParameters.BackBufferHeight = gScreenRect.bottom = d3dDisplayMode.Height; 
d3dPresentationParameters.BackBufferWidth = gScreenRect.right = d3dDisplayMode.Width; 
d3dPresentationParameters.MultiSampleType = D3DMULTISAMPLE_NONE; 
d3dPresentationParameters.SwapEffect= D3DSWAPEFFECT_DISCARD; 
d3dPresentationParameters.hDeviceWindow = hWnd; 
d3dPresentationParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; 
d3dPresentationParameters.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 

pSinfo->uiWidth = d3dDisplayMode.Width; 
pSinfo->uiHeight = d3dDisplayMode.Height; 

if(pSinfo->g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING ,&d3dPresentationParameters,&pSinfo->g_pd3dDevice) != D3D_OK) 
    return FALSE; 

E poi, il ciclo che svolgono le immagini continue e salvare i dati di immagine in pData:

while(1) 
{ 
    pSinfo->g_pd3dDevice->GetRenderTarget(0, &pSinfo->pRenderSurface); 
    pSinfo->g_pd3dDevice->CreateOffscreenPlainSurface(pSinfo->uiWidth, pSinfo->uiHeight, pSinfo->d3dFormat, D3DPOOL_SYSTEMMEM, &pSinfo->pRenderSurface, NULL); 
    pSinfo->g_pd3dDevice->GetFrontBufferData(0, pSinfo->pRenderSurface); 

    //D3DXSaveSurfaceToFile("Desktop.bmp", D3DXIFF_BMP, pSinfo->pRenderSurface,NULL, NULL); //Test 

    ZeroMemory(&pSinfo->lockedRect, sizeof(D3DLOCKED_RECT)); 
    pSinfo->pRenderSurface->LockRect(&pSinfo->lockedRect,NULL, D3DLOCK_READONLY); 

    memcpy((BYTE*)pSinfo->pData, (BYTE*)pSinfo->lockedRect.pBits, (pSinfo->uiWidth) * pSinfo->uiHeight * pSinfo->uiBitsPerPixels/8); 

    pSinfo->pRenderSurface->UnlockRect(); 
    //InvalidateRect(((CMainFrame*)(pApp->m_pMainWnd))->m_hWnd,NULL,false); 
    pSinfo->pRenderSurface->Release(); 
} 

Per maggiore chiarezza circa il problema che ho e la soluzione:

Ho i due monitor con il mio desktop Windows esteso. quando catturo lo schermo ho due schermate con la schermata principale e quello che voglio è uno screenshot della schermata principale e l'altro con lo schermo esteso.

Immagino di dover impostare un parametro da qualche parte per indicare che il desktop esteso inizia a Point.x = 1920 (per schermo 1080p) ma non so come.

Grazie mille per il vostro aiuto!

Dylan

Screen Scheme

+0

Che cosa è esattamente questo codice facendo nel caso in cui si dispone di più monitor? Cosa vuoi esattamente che faccia? –

+0

Questo codice crea uno screenshot del mio desktop e quindi memorizzo le schermate in un file in cui posso riprodurle come se fosse un video. Durante la riproduzione degli screenshot, ho le mie due schermate ma è lo stesso contenuto (l'applicazione visualizza la stessa schermata due volte). Quello che voglio è avere l'intero schermo esteso –

+0

http://msdn.microsoft.com/en-us/library/windows/desktop/bb206364(v=vs.85).aspx – Brandon

risposta

0

Va bene, ho trovato il problema in questo momento.

La cosa importante da notare è la creazione Dispositivo con:

pSinfo->g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING ,&d3dPresentationParameters,&pSinfo->g_pd3dDevice) != D3D_OK) 

Qui stavo creando un dispositivo con D3DADAPTER_DEFAULT che non prendersi cura di altri display. Pertanto, ho adattato il codice a seconda del numero di schermate disponibili:

for (i = 0; i < NUMBER_OF_DISPLAYS; i++) 
{ 
    pSinfo->g_pD3D->CreateDevice(i,D3DDEVTYPE_REF,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING ,&d3dPresentationParameters,&pSinfo->g_pd3dDevice) != D3D_OK) 
}