6

Hello Direct3D experts,

I am currently developing an application with Direct3D in order to capture my two monitors desktop (used as extended desktop of course). The following code works well but I am just able to capture the primary display and not the extended desktop (just one screen is captured twice)

How can I adapt this solution for a dual screen capture ?

First of all, I initialize 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;

And then, the loop which perform continuous screenshots and save image data 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();
}

For more clarity about the problem I have and the solution:

I have the two monitors with my extended windows desktop. when capturing the screen I have two screenshots with the main screen and what I want is one screenshot of the main screen and one other with the extended screen.

I guess I have to set up a parameter somewhere indicating that the extended desktop starts at Point.x = 1920 (for 1080p screen) but I just don't know how.

Thank you so much for your help !

Dylan

Screen Scheme

5
  • What exactly is this code doing in case you have multiple monitors? What exactly do you want it to do? Commented Sep 5, 2014 at 9:06
  • This code makes a screenshot of my desktop and then I store the screenshots into a file where I can replay them as it was a video. When replaying the screenshots, I have my two screens but it is the same content (The application displays the same screen twice). What I want is to have the entire extended screen Commented Sep 5, 2014 at 9:13
  • msdn.microsoft.com/en-us/library/windows/desktop/… Commented Sep 5, 2014 at 11:10
  • @Brandon thank you for the link, I've already checked out this one. Unfortunately I do not understand how this works because if I reset one Device, I have to re-create it later in order to use it again, am I right ? Commented Sep 5, 2014 at 11:22
  • The line: pSinfo->g_pd3dDevice->GetRenderTarget(0, &pSinfo->pRenderSurface); is not required. Commented Oct 26, 2015 at 18:35

1 Answer 1

3

All right, I've found the problem right now.

The important thing to notice is the Device Creation with :

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

Here I was creating a device with D3DADAPTER_DEFAULT which do not take care of other displays. Therefore, I've adapted this code depending of the number of available screens:

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 )
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.