2014-09-25 28 views
0

好吧,對於那些使用過它的人來說 - 這應該是一個超簡單的問題。使用GetFrontBufferData(),並將屏幕截圖放置在單獨的設備後緩衝區中

我只是在網上尋找一種方法來使用DirectX/Direct3D來獲取更快的截圖,每個人都在談論GetFrontBufferData()以及它有多棒。

我已經打了一段時間,但我開始認爲他們錯誤地使用術語「截圖」......我的電話成功,但我從來沒有得到「截圖」。

所以問題是,你可以實際使用GetFrontBufferData()使整個桌面的截圖REAL,或者是它只是讀出像素前緩衝區內的d3d-的範圍的方式設備的繪圖區域? (在成功的時候,我希望能看到窗口內的繪畫區域做那個老電視 - 在電視裏 - 在電視裏 - 在電視裏 - 在電視裏 - - 一種效果。黑色)

編輯:

所以,我能得到一個屏幕截圖的工作,但似乎無法把我的形象到緩衝區我的應用程序窗口。首先,我認爲這是因爲它們是獨立的設備,但我試圖在正確的設備上創建第二個表面,然後手動複製內容。 (雖然我可能會錯誤地複製它(現在不重要)),但對於正確的設備,調用仍然失敗。

任何想法爲什麼它不會讓我將這個表面應用到我的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:。

哦,那麼顯然你不能對處於D3DPOOL_SYSTEMMEM表面使用StretchRect(),但你必須在D3DPOOL_SYSTEMMEM使用GetFronBufferData()

回答

2

是的,你可以使用GetFrontBufferData捕獲Windows桌面我可以提供這個海報有效的recent question,除非桌面使用的是16位顏色。它可能會讓你對如何正確使用它有所瞭解。

但是,不,這不是GetFrontBufferData的「真正目的」。真正的目的是允許Direct3D遊戲捕獲遊戲截圖,無論遊戲是窗口還是全屏,最重要的是,遊戲是否使用多重抽樣。

GetFrontBufferData並非旨在成爲截取Windows桌面的更好方法。它可能比其他方法更快,但這不是它存在的原因。

+0

嘿,謝謝!我意識到我能夠將屏幕截圖加入我的其他backbuffer是我的主要問題。讓我感到奇怪,在沒有意識到的情況下,我有多少成功的嘗試在截圖之前進行過。 – user980058 2014-09-27 01:26:46