Хорошо, так что для тех, кто использовал его много - это должен быть легкий вопрос SUPER.с использованием GetFrontBufferData(), и скриншот места в отдельном устройстве backbuffer
Я просто искал в Интернете способ использовать DirectX/Direct3D для более быстрого скриншота, и все говорили о GetFrontBufferData() и о том, как это было замечательно.
Я немного набросился на него, но я начинаю думать, что они неправильно используют термин «скриншот» ... Мой звонок преуспевает, но я никогда не получаю «скриншот».
Так вопрос является, вы можете на самом деле использовать GetFrontBufferData(), чтобы сделать реальный скриншот всего рабочего стола, или это просто способ чтения пикселей из переднего буфера в пределах вашего d3d- область рисования устройства?
(После успеха я бы ожидал увидеть область чертежа в моем окне, чтобы сделать это старое телевидение в телевизоре в телевизоре в телевизионном эффекте. черный)
Edit:.
Итак, я был в состоянии получить снимок экрана, чтобы работать, но не могу поставить мое изображение в буфер для моего окна приложения.
Сначала я думал, что это были разные устройства, но я попытался создать вторую поверхность на правильном устройстве и затем вручную скопировать содержимое. (Хотя я могу скопировать его неправильно ((не важно сейчас)), вызов на растяжку по-прежнему не подходит для правильного устройства.
Любая идея, почему это не позволит мне применить эту поверхность к моему backbuffer ???
D3DDISPLAYMODE d3dDisplayMode;
D3DPRESENT_PARAMETERS d3dPresentationParameters;
if((d3d=Direct3DCreate9(D3D_SDK_VERSION))==NULL)
exit(1);
D3DCAPS9 d3dcps;
d3d->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&d3dcps);
DWORD targets = d3dcps.NumSimultaneousRTs;
// TODO:^make a way for user to select one from this and put it into i
DWORD i=D3DADAPTER_DEFAULT;
if(d3d->GetAdapterDisplayMode(i,&d3dDisplayMode)==D3DERR_INVALIDCALL)
exit(1);
ZeroMemory(&d3dPresentationParameters,sizeof(D3DPRESENT_PARAMETERS));//Fills a block of memory with zeros.
d3dPresentationParameters.Windowed = TRUE;
d3dPresentationParameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
d3dPresentationParameters.BackBufferFormat = d3dDisplayMode.Format;//d3dDisplayMode.Format;//D3DFMT_A8R8G8B8;
d3dPresentationParameters.BackBufferCount = 1;
d3dPresentationParameters.BackBufferHeight = d3dDisplayMode.Height;
d3dPresentationParameters.BackBufferWidth = d3dDisplayMode.Width;
d3dPresentationParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dPresentationParameters.MultiSampleQuality = 0;
d3dPresentationParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dPresentationParameters.hDeviceWindow = hwDesktop;
d3dPresentationParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
d3dPresentationParameters.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
if(d3d->CreateDevice(i,D3DDEVTYPE_HAL,hwDesktop,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dPresentationParameters,&d3dcdev) != D3D_OK)
exit(1);
if(d3dcdev->CreateOffscreenPlainSurface(d3dDisplayMode.Width,d3dDisplayMode.Height,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&sfScrn, NULL) != D3D_OK)
exit(1);
if(d3dcdev->GetFrontBufferData(0,sfScrn) != D3D_OK)
exit(1);
// we now have a screenshot in sfScrn.
// let's render it to a separate device in our app window!
d3dPresentationParameters.hDeviceWindow = hwDrawArea;
if(d3d->CreateDevice(i,D3DDEVTYPE_HAL,hwDrawArea,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dPresentationParameters,&d3drdev) != D3D_OK)
exit(1);
d3drdev->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&sfBackBuffer);
if(d3drdev->CreateOffscreenPlainSurface(d3dDisplayMode.Width,d3dDisplayMode.Height,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&sfTransfer, NULL) != D3D_OK)
exit(1);
D3DLOCKED_RECT lockedRectScrn, lockedRectTransfer;
ZeroMemory(&lockedRectScrn, sizeof(D3DLOCKED_RECT));
ZeroMemory(&lockedRectTransfer, sizeof(D3DLOCKED_RECT));
if(sfScrn->LockRect(&lockedRectScrn,NULL,D3DLOCK_READONLY) != D3D_OK
|| sfTransfer->LockRect(&lockedRectTransfer,NULL,0) != D3D_OK)
exit(1);
memcpy((BYTE*)lockedRectTransfer.pBits,(BYTE*)lockedRectScrn.pBits,lockedRectScrn.Pitch*d3dDisplayMode.Height);
sfScrn->UnlockRect();
sfTransfer->UnlockRect();
while(true)
{
if(d3drdev != NULL)
{
d3drdev->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(75,0,0),1.0f,0);
if(D3D_OK!=d3drdev->StretchRect(sfTransfer,NULL,sfBackBuffer,NULL,D3DTEXF_NONE))
{
MessageBox(NULL,"failed to use stretchrect","",0);
exit(1);
}
if(d3drdev->BeginScene())
{
d3drdev->EndScene();
}
d3drdev->Present(NULL,NULL,NULL,NULL);
}
}
Edit2:..
о Таким образом, очевидно, вы не можете использовать StretchRect() на поверхностях, находящихся в D3DPOOL_SYSTEMMEM, но вы должны использовать GetFronBufferData() на D3DPOOL_SYSTEMMEM
Эй, спасибо! Я понял, что моя способность получить скриншот в моем другом бэкбуфере - моя главная проблема. Заставляет меня задаться вопросом, сколько успешных попыток у меня было на скриншоте раньше, не осознавая этого. – user980058