Jump to content
  • Advertisement
Sign in to follow this  

Read and write to backbuffer: Problem adding transparent overlay sprite

This topic is 3041 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'm looking for a way to create a whole-scene motion blur effect without any control over a DirectX 9 application. My approach is to hook the d3d9.dll calls, accumulate some frames from the back buffer to textures and then render multiple transparent sprites using those "screenshots" to modify the back buffer render target when a call the EndScene() occurs.

So, my first steps were simply to take a screenshot, save it in a texture and then display it as a transparent overlay using a ID3DXSprite. I was successful in replacing the back buffer with my own surface using StretchRect() but the transparency is crucial to produce the desired effect here so I have to go through textures and sprites. However, after trying a lot of stuff and getting some low-performance solutions, I could not make it work. Hope you can help!

I'm doing the following before a call to EndScene() if a screenshot is requested:

1. Obtain the back buffer surface:

device->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO, &CaptureBuffer);

2. Create my screenshot texture in SYSTEM memory pool using back buffer dimensions:

D3DXCreateTexture(device, SurfaceDesc.Width, SurfaceDesc.Height, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &mScreenShotTexture);

3. Create my overlay texture in the DEFAULT pool:

D3DXCreateTexture(device, SurfaceDesc.Width, SurfaceDesc.Height, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &mOverlayTexture);

4. Get the surface on level 0 from the screen shot texture:

LPDIRECT3DSURFACE9 lScreenShotSurface;
mScreenShotTexture->GetSurfaceLevel(0, &lScreenShotSurface);

5. Get render target data from back buffer to the texture surface:

device->GetRenderTargetData(CaptureBuffer, lScreenShotSurface);

6. Update the overlay texture in the DEFAULT pool with the screen shot texture in the SYSTEM pool:

device->UpdateTexture(mScreenShotTexture, mOverlayTexture);

7. Release resources:


8. Draw the sprite using the overlay texture with custom transparency value:

D3DXCreateSprite(pDevice, &mOverlaySprite);
mOverlaySprite->Draw(mOverlayTexture, NULL, NULL, NULL, D3DCOLOR_RGBA(255,255,255,alpha));

Every function succeeds and I can even save the screenshot in a JPEG file on every step using D3DXSaveTextureToFile(). However, nothing appears on screen. The odd things is that if I replace step 5 by a call to D3DXLoadSurfaceFromFile(), it will work perfectly. That means that saving and then loading back the texture would work but then you can guess the performance issue if I want to use this to make my motion blur effect! Following that idea, I've tried using D3DXSaveSurfaceToFileInMemory() and D3DXLoadSurfaceFromFileInMemory() with an ID3DXBuffer but it didn't work either (well it succeeded but nothing appeared)...

I've read a lot to try to understand what the D3DXLoadSurfaceFromFile() method does that GetRenderTargetData() and D3DXSaveSurfaceToFileInMemory() doesn't but I found out nothing. I've also tried playing with LockRect() and dirty rectangles but nothing seems to do the trick...

Any help would be greatly welcomed to resolve this challenge! Maybe I'm missing something? Any idea how to do this in a different way?

Thanks in advance!

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!