Jump to content
  • Advertisement
Sign in to follow this  
pacemkr

Screenshot system. Desperate for help!!

This topic is 5472 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been on this for a while now and progress is moving really slow. I know that I can use GetFrontBufferData to get a screenshot. However, this is a VERY slow function, it takes nearly a full second on my pc. I refuse to believe that this is the only way to capture a screenshot of a directx applicaiton. What I am trying to implement right now is to get either the render target (GetRenderTarget and GetRenderTargetData) or the back buffer (GetBackBufferData). When I try to save the resulting surface with D3DXSaveSurfaceToFile, I get garbage in the file. The colors kinda looks like what they are supposed to, but the image is all messed up (I can upload a sample). Am I missing something? What I am trying to do: Capture a screenshot of ANOTHER DirectX application. I figure this wont be a problem. Am I wrong? (I have the window handle of that other dx application) I am not extremely familiar with directx, so I might have the wrong idea. First thing I do is initialize a device and use the pointer of another dx application. From that device I attempt to get the various surfaces, which all but the front buffer return some wierd stuff. Here is the code. (very buggy, but I hope you'll get the idea) Please help! Any suggestions/bits of info/comments/anything is greately appreciated. I feel like I read all of internet trying to figure this out. Thanks in advance.
	//define a pointer to d3d object
	LPDIRECT3D9 pD3D = NULL;

	//attemp to get the pointer of a d3d object
    if( NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
        return 1;

	//define a pointer to d3d device
	IDirect3DDevice9 *pDevice;

	//define the present parameters needed to create a device
	D3DPRESENT_PARAMETERS pD3Dpp;

	//fill the parameters with zeros in memory
	ZeroMemory(&pD3Dpp,sizeof(pD3Dpp));
	pD3Dpp.Windowed = TRUE;
	pD3Dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
	
	//attempt to create a new device
	//adapter to use,type of adapter,handle to screencap window,vertex processing must be set,present params,device pointer
	HRESULT res = pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&pD3Dpp,&pDevice);

	//check what was the result
	if(res != D3D_OK)
	{
		//convert HRESULT to a readable error string
		LPCSTR resultString = DXGetErrorString9(res);
		MessageBox(NULL,resultString,NULL,MB_OK);
		MessageBox(NULL,"Device",NULL,MB_OK);
		return 1;
	}

	//create a compatible surface
	//define a surface pointer
	IDirect3DSurface9 *pSurface=0;
	IDirect3DSurface9 *pSurface2=0;

	//initialize the surface with the device
	//res = pDevice->CreateOffscreenPlainSurface(640,480,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&pSurface,NULL);
	res = pDevice->CreateOffscreenPlainSurface(640,480,D3DFMT_X8R8G8B8,D3DPOOL_SYSTEMMEM,&pSurface2,NULL);

	//check what was the result
	if(res != D3D_OK)
	{
		//convert HRESULT to a readable error string
		LPCSTR resultString = DXGetErrorString9(res);
		MessageBox(NULL,resultString,NULL,MB_OK);
		return 1;
	}

	int ticks = GetTickCount();

	//copy the front buffer to surface
	//res = pDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&pSurface);
	res = pDevice->GetRenderTarget(0,&pSurface);
	
	//check what was the result
	if(res != D3D_OK)
	{
		//convert HRESULT to a readable error string
		LPCSTR resultString = DXGetErrorString9(res);
		MessageBox(NULL,resultString,NULL,MB_OK);
		return 1;
	}

	D3DSURFACE_DESC pDesc;

	res = pSurface->GetDesc(&pDesc);

	//check what was the result
	if(res != D3D_OK)
	{
		//convert HRESULT to a readable error string
		LPCSTR resultString = DXGetErrorString9(res);
		MessageBox(NULL,resultString,NULL,MB_OK);
		return 1;
	}

	if(pDesc.Pool == D3DPOOL_DEFAULT)
		MessageBox(NULL,"X",NULL,MB_OK);


	//copy the front buffer to surface
	res = pDevice->GetRenderTargetData(pSurface,pSurface2);
	
	//check what was the result
	if(res != D3D_OK)
	{
		//convert HRESULT to a readable error string
		LPCSTR resultString = DXGetErrorString9(res);
		MessageBox(NULL,resultString,NULL,MB_OK);
		MessageBox(NULL,"TargetData",NULL,MB_OK);
		return 1;
	}

	D3DXSaveSurfaceToFile("C:\\temp.BMP",D3DXIFF_BMP,pSurface2,NULL,NULL);	

	//return success
	return 0;

[Edited by - pacemkr on September 26, 2004 9:28:48 PM]

Share this post


Link to post
Share on other sites
Advertisement
Umm... please include long code in [source] tags. k thanx.

As for your question, I don't think you can do that - since you need a D3DDevice to capture the back buffer, you'd be interfering with the other program's device. (Since a device takes full control over the adapter). So the other program wouldn't render as you were snapping the screen.

I'm not 100% sure on this, though, but that's what I've been told [wink]

Share this post


Link to post
Share on other sites
If you have the window handle, don't do that with D3D to get the screenshot. You can simply use GDI for that.
[edit]
Here's a link that describes how to do it.
[/edit]

Share this post


Link to post
Share on other sites
Sorry about the source tags. =P (fixed it)

Thanks for the info on D3Device. I had a feeling thats the problem.

I went on to use dx instead of GDI, becuase I used GDI (not through DirectShow thogh) in C# and it was still kinda slow, 150 ms if im not mistaking.

I switched to C++ for performance reasons. I guess though DirectShow it will be faster. I'll try it out and post the results.

I need to capture the screen as fast as possible, because eventually I am compiling these shots into video.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!