Antialiased image and capturing video

Started by
3 comments, last by Demirug 17 years, 11 months ago
Hello, I want to capture video from my DirectX application, but I have one problem. I need to access back buffer data. I can do this by creating off screen surface in system memory and in each frame copy back buffer to this surface. Then I can lock my off screen surface to get the pointer to the image. First, I have to create my off screen surface when I start my application: GetD3DDevice()->CreateOffscreenPlainSurface( nWidth, nHeight, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &m_pVideoSurface, NULL ); In each frame I have to get render target: GetD3DDevice()->GetRenderTarget( 0, &pBackBuffer ); And copy data from render target to my off-screen surface (it is not possible to lock render target): GetD3DDevice()->GetRenderTargetData( pBackBuffer, m_pVideoSurface ); And here is my problem - GetRenderTargetData will fail if the render target is multisampled. I was thinking about using method StretchRect which can copy antialiased images, but according to the DirectX documentation I can't copy render target image to the off-screen surface :( Is it possible to retrieve data from my antialiased back buffer? I was also thinking about rendering image to non antialiased surface which could be 2 times bigger than my video and then computing output color based on 4 neighbor pixels (software antialiasing). But this solution is slow and it would be great if I could use GPU antialiasing. Thanks for help. Regards, Tomasz
Advertisement
I can't think of any way of doing what you want with the backbuffer, but GetFrontBufferData() is the proper way of grabbing AA'd screenshots:

Quote:From the SDK documentation:
This method is the only way to capture an antialiased screen shot.


Maybe you should try and go with the front-buffer route? Big problem is that it wont be fast at all, so if you're trying to stream video capture then it may not be suitable...

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

You can try the following:

Create an additional render target with the same size and format as your back buffer but without AA. Now you can use StretchRect to copy and down sample you AA backbuffer to your new non AA target. The last step is to use GetRenderTargetData on the new render target that contains the down sampled image.

jollyjeffers:
Yes, I can use GetFrontBufferData() but in this case my off-screen surface needs to be the same size as my current display mode. In my case, my application is using 16:9 aspect ratio and my desktop is 4:3. That means, that I will have to create bigger off-screen buffer than I want. And also speed of this method is an issue - it is extremely slow.

Demirug:
This is very good idea and much faster than using GetFrontBufferData(). That was exactly what I was looking for - it works perfectly fine for me :) Thank you. I was also trying to create lockable render target surface, but I was able to capture my video with about 0.5FPS, but when I am copying render target surface to off-screen then I can capture with 6-8 FPS. It is much faster :]

Thanks again
Regards,
Tomasz
GetRenderTargetData can be an accelerated operation on modern GFX cards. A Lock/Unlock will never be accelerated. You can check the D3DCAPS3_COPY_TO_SYSTEMMEM caps bit if a card supports it.

This topic is closed to new replies.

Advertisement