2014-09-05 74 views
5

你好Direct3D的专家,C++ Direct3D的多屏幕捕捉

我目前正在开发与Direct3D的应用程序,以捕捉我的两个显示器的桌面(作为当然的扩展桌面)。 下面的代码运行良好,但我只能捕获主显示器而不是扩展桌面(只有一个屏幕被捕获两次)

我该如何适应此解决方案以进行双屏幕捕获?

首先,我初始化的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; 

然后,这在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(); 
} 

关于这个问题我已经更清晰和解决方案:

我有我的扩展的Windows桌面两个显示器。捕获屏幕时,我有两个主屏幕截图,我想要的是主屏幕的一个屏幕截图,另一个屏幕是扩展屏幕。

我想我必须在某处设置一个参数,指出扩展桌面从Point.x = 1920开始(对于1080p屏幕),但我只是不知道如何。

非常感谢您的帮助!

迪伦

Screen Scheme

+0

如果您有多个显示器,该代码的作用究竟如何?你想要它做什么? – 2014-09-05 09:06:39

+0

此代码制作了我的桌面屏幕截图,然后我将屏幕截图存储到一个可以重播它们的文件,因为它是一个视频。重播屏幕截图时,我有两个屏幕,但内容相同(应用程序显示两次相同的屏幕)。我想要的是整个扩展屏幕 – 2014-09-05 09:13:42

+0

http://msdn.microsoft.com/en-us/library/windows/desktop/bb206364(v=vs.85).aspx – Brandon 2014-09-05 11:10:49

回答

0

好吧,我现在发现了问题。

重要的是要注意与设备创建:

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

这里我创建与D3DADAPTER_DEFAULT设备不采取其他显示器的照顾。因此,我已根据可用屏幕的数量调整了此代码:

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) 
}