C ++ Direct3D多屏幕捕获 [英] C++ Direct3D Multiple Screen Capture

查看:204
本文介绍了C ++ Direct3D多屏幕捕获的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Direct3D专家您好,



我目前正在使用Direct3D开发一个应用程序,以便捕获我的两个显示器桌面(当然用作扩展桌面)。
以下代码效果很好,但我只能捕获主显示,而不能捕获扩展的桌面(只捕获一个屏幕两次)



我如何将此解决方案调整为双屏幕捕获?



首先,我初始化Direct3D:

  D3DDISPLAYMODE d3dDisplayMode; 
D3DPRESENT_PARAMETERS d3dPresentationParameters; //表示参数(backbufferwidth,height ...)

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

if(pSinfo-> g_pD3D-> GetAdapterDisplayMode(D3DADAPTER_DEFAULT,& d3dDisplayMode)== D3DERR_INVALIDCALL)
返回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-&D; b_dd = OK_bdd OK_b
$ b ;

然后,执行连续屏幕截图并将图像数据保存在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); //测试

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屏幕)开始,但是我不知道如何。



非常感谢



Dylan



解决方案

好的,我现在已经发现了问题



需要注意的重要事项是使用以下命令创建设备:

  pSinfo-> g_pD3D-> CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,& d3dPresentationParameters,& pSinfo-> g_pd3dDevice)$$$$$$) $ p> 

在这里,我正在使用D3DADAPTER_DEFAULT创建一个无法处理其他偏移的设备没错因此,我根据可用屏幕的数量调整了此代码:

  for(i = 0; i  {
pSinfo-> g_pD3D-> CreateDevice(i,D3DDEVTYPE_REF,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,& d3dPresentationParameters,& pSinfo-> g_pd3db $ b))D }


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

解决方案

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

这篇关于C ++ Direct3D多屏幕捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆