Jump to content
  • Advertisement
Sign in to follow this  
hlee

How to save a scene in higher resolution?

This topic is 2167 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


D3D definitely supports rendering to targets that are bigger than the screen. I suspect your problem is one of:

You are absolutely right about the depth buffer.  After creating a depth stencil surface that matches the render target I can now get the full frame.  Thank you so much!

 

However, MultiSampleType must be set to D3DMULTISAMPLE_NONE for the render target, otherwise the GetRenderTargetData would return D3DERR_INVALIDCALL.  Without multisample I might as well just capture the screen with a lower resolution but with anti-aliasing.  Is there a way to use multisample in this method?

Share this post


Link to post
Share on other sites
Advertisement

Well, I don't know what extra advice to give you that hasn't been said before, but you have inspired me to add a super screenshot mode to my engine. A special hotkey that when pressed will save a superb quality screenshot with normal or super-high quality/resolution. I'm estimating that at the highest quality setting the engine will consume about 2 GiB or RAM and spend 5-10 second creating one screenshot smile.png.

 

I'll let you know how it turns out.

Edited by DwarvesH

Share this post


Link to post
Share on other sites

Great.  Let me know how you do it and if you can turn on anti-aliasing in the high resolution screenshot.

Share this post


Link to post
Share on other sites

If you look at the documentation for GetRenderTargetData() you'll see:

 

 

This method will fail if:

  • The render target is multisampled.

 

The standard solution to that is to use StretchRect() to copy it to a non-multisampled render target.

 

However in your case I'd just increase the resolution and downsize the result in some image editing software - you'll get better quality that way.

Share this post


Link to post
Share on other sites


The standard solution to that is to use StretchRect() to copy it to a non-multisampled render target.

That's it!  This is what works:

1. Create a large multisampled RT, called it RT1, along with a depth buffer

2. Render the scene to RT1

3. Create a non-multisampled RT, called it RT2, the same size as RT1

4. StretchRect RT1 to RT2

5. Use GetRenderTargetData to copy RT2 to an OffscreenPlainSurce

6. Use D3DXSaveSurfaceToFile to save the OffscreenPlainSurce

 

Now I get a high resolution, multiampled scene.  Thanks so much, Adam!

 

But why does it have to be so cumbersome?  Why can't D3DXSaveSurfaceToFile save a mutisampled RT directly?

Share this post


Link to post
Share on other sites

The way multisampling works is that D3D internally creates an extra large render target and depth buffer (e.g. for 4X it's double the width and height).

 

However, when rendering to it the pixel shader isn't re-run for each extra pixel, but the depth test is. That gives significantly better performance than rendering to a double sized render target, at the cost of a bit of quality - it won't solve aliasing that's caused by the shader, which manually rendering at double the size then downsizing will do.

 

There's usually also some hardware trickery in there to accelerate the common case where all of the antialiased samples for one output pixel are identical by storing the data a bit differently.

 

The shader aliasing is why I said you want to just render to a bigger texture and downsize it yourself. Doing that also means you need less GPU memory.

 

The reason you need the StretchRect() step is that the GPU needs to decode and downsize the extra large render target to an antialiased one of the right size before you can read it back with either a shader or the CPU.

Share this post


Link to post
Share on other sites

StrechRect will work, but will probably perform poorly. You are effectively using SSAA at this point and there is a good reason most games don't offer this option.

 

But since you want to capture screenshots, I would recommend rendering your high resolution texture as a full screen quad and using high quality down-sampling filter implemented in the pixel shader. Or do it in an external program once the screenshot is saved.

Share this post


Link to post
Share on other sites

5. Use D3DXSaveTextureToFile to save RT2 directly to a file

D3DXSaveTextureToFile complains that RT2 is not a texture.  If I'd created RT2 as a texture then StrectRec would complain that RT2 is not a IDirect3DSurface9.  How can I make it to work?

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!