Why is the desktop in the front buffer?

Started by
7 comments, last by ddlox 3 years, 4 months ago

I use DirectX 9. I'm creating not a full-screen app. Why is it that when I get data from the front buffer, it turns out to be the desktop + window, and not the result of the window rendering? Are these some features of DirectX 9? I don't really understand why it was necessary to save the desktop with the window to the front buffer.

I'll have two number 9s, a number 9 large, a number 6 with extra dip, a number 7, two number 45s, one with cheese, and a large soda.

Advertisement

Hmm, not sure. Can you share the code you are using for the creation of your swap chain? Namely, the D3DPRESENT_PARAMETERS structure initialization, and device creation?

My first thought is you are somehow giving that structure's hDeviceWindow member a handle to the desktop acquired via GetDesktopWindow() but that's just guessing.

Without providing a render target, the render call automatically captures desktop into frame buffer. Make sure all your render calls have a valid render target.

HWND window = CreateWindowExW(0, L"Render", L"Render", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, Width, Height, 0, 0, hInstance, nullptr);

PresentParameters.Windowed = windowed;
PresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
PresentParameters.hDeviceWindow = window;
PresentParameters.BackBufferFormat = D3DFMT_A8R8G8B8;
PresentParameters.BackBufferCount = 1;
PresentParameters.BackBufferWidth = size.X;
PresentParameters.BackBufferHeight = size.Y;
PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
PresentParameters.EnableAutoDepthStencil = true;
PresentParameters.AutoDepthStencilFormat = D3DFMT_D24X8;
PresentParameters.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE;
PresentParameters.MultiSampleQuality = multiSampleQuality;
		

ThrowIfFailed(direct->CreateDevice(0, D3DDEVTYPE_HAL, window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &PresentParameters, &Device));

ThrowIfFailed(Device->CreateOffscreenPlainSurface(PresentParameters.BackBufferWidth, PresentParameters.BackBufferHeight, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &temp, nullptr);
ThrowIfFailed(Device->GetFrontBufferData(0, temp));

I'll have two number 9s, a number 9 large, a number 6 with extra dip, a number 7, two number 45s, one with cheese, and a large soda.

@mr.otakhi I don't change the target during the entire rendering process.

I'll have two number 9s, a number 9 large, a number 6 with extra dip, a number 7, two number 45s, one with cheese, and a large soda.

GetFrontBufferData captures the whole screen whether you are in windowed mode or not (full-screen):

MSDN doc quote:

The data is returned in successive rows with no intervening space, starting from the vertically highest row on the device's output to the lowest.

so if you just want the content of your window then you should use GetBackBuffer( ) (or GetRenderTargetData( ) if you have a target set) before the call to device9::Present( ):

//pseudo

void create_pic_shot()
{	
	LPDIRECT3DSURFACE9	temp = NULL; 	
	
	// using D3DPOOL_DEFAULT, 32b argb
	
	ThrowIfFailed(Device->CreateOffscreenPlainSurface(PresentParameters.BackBufferWidth, PresentParameters.BackBufferHeight, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &temp, nullptr);

	HRESULT hr = Device->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&temp);		
	if (hr != D3D_OK)	
	{		
		// do error handling etc...		
		temp->Release(); 
		return;	
	}			
		
	D3DXSaveSurfaceToFile("c:\\foo\\pic_shot.bmp",D3DXIFF_BMP,temp,NULL,NULL); 	
	temp->Release(); 
}

void main( )
{
	bool take_pic_shot = true;
	
   ...begin()
   		device->clear( )
   		render stuff( )
		if (take_pic_shot)
			create_pic_shot( )
   		device->present( )
   ...end()
}

have fun ?

@ddlox I have anti-aliasing enabled. When it works, it is impossible to get data from the render target.

I'll have two number 9s, a number 9 large, a number 6 with extra dip, a number 7, two number 45s, one with cheese, and a large soda.

who_say_pawno said:
I have anti-aliasing enabled.

ah ok, understood, in this case, GetFrontBufferData( ) is the only way you can capture your screenshot with AA. I would then suggest running your app in full screen mode and capturing that way. There is no other way that I know of that can avoid the desktop and the win frame when AA is on;

that's it… all the best ?

This topic is closed to new replies.

Advertisement