Rendering To Textures in Beta2

I used Texture2D's heavily with the usage RenderTarget, however in Beta 2 its like a whole new API.

I understand that Surface no longer exists and RenderTarget/2D should be used. The problem is, the whole mentality is backwards compared to what im used to.

From what I see I should create a RenderTarget2D and set that as a render target, then do rendertarget.GetTexture() if I want to set it. Thats fine.

However, how do I copy between render targets

There is no StretchRect or equivelent function I can see, which I used alot before. Surely I dont have to go about getting a texture, setting it, creating a 'copy' effect, setting a new render target, resolving the new render target just to copy from one to another

Is there no alternative to StretchRect If not its a sad loss that makes things cumbersome, or even tiresome now.




Answer this question

Rendering To Textures in Beta2

  • WinFormsUser13232

    Sorry, but im still lost with this.

    I have a brightpass and bloom post process effect.

    I need to get the current backbuffer into a RenderTarget2D...



  • Webbert

    Ok, now the render target cache/stack makes more sense. But why isnt there a mthod for copying from one RenderTarget to another, you could have used LoadSurfaceFromSurface or StretchRect, now we have to render to a full screen quad to do it

  • juanraul

    All of those things except extracting cubemap surfaces into a 2D texture sound like you can do them using ResolveBackBuffer.

    "Resolve" basically just means "copy current backbuffer contents to a texture".

    The reason you can only do this from a backbuffer, and not copy any arbitrary texture into some other texture, is that on Xbox there is only one current backbuffer, which lives in special memory on the GPU. All rendering happens into this special memory, and the only thing you can do at the end is to copy the results back into a regular texture. We looked at trying to implement Windows Direct3D9 style semantics on Xbox, but realised that was going to be way too slow and unpredictable to be useful, wheras with the current API, we can make things both consistent and fast on both platforms.

    To copy a Texture2D into a cubemap, you can create a RenderTargetCube, set one of its faces as the active rendertarget, draw your Texture2D as a fullscreen quad, then ResolveRenderTarget to get the result back into the cubemap. On Xbox that will actually do a copy from the special framebuffer memory, while on Windows it will generally just be able to share the underlying rendertarget memory so no extra copying is required.


  • Pimpom

     Shawn Hargreaves - MSFT wrote:
    Yes, the rendertarget API is very different in beta 2. The way we are doing things now is much closer to how the Xbox hardware works, and we had to make these changes to get things working in a crossplatform way.

    You're right, there is no StretchRect any more. You have to Resolve a rendertarget after you are done drawing into it to make the data available as a texture. That's how the Xbox hardware works, as as a neat benefit of emulating this on Windows, the new API makes multisampled rendertargets work much more reliably and consistently than they used to.

    Why are you needing to copy between rendertargets, btw

    We were using SretchRect to copy from the BackBuffer to a texture for some post process effects.

    Also used it to get into the correct format for heightmap processing.

    Also for extracting cubmap surfaces into a Texture2D, and visa versa.

    And yes, also for taking SnapShots of the scene (screenshots).

    As you can see we use it quite alot. If it's not possible to get texture2D surfaces and copy between them, can you at least post a little of equivelent of how to do it via the new RenderTarget2D and Resolve function

     

     



  • SpaceCadet

    I've seen some code lurking around that uses StretchRect to capture screenshots. I have code in my "utility library", posted on my site, that captures screenshots without using StretchRect. It will only work on Windows, but then that's the only time you'd capture a screenshot anyway.


  • Farrokh Moori

    That's primarily for Xbox compatibility. The full screen quad method works consistently (and fast) on both Windows and Xbox, while Xbox doesn't have any way to do StretchRect or LoadSurfaceFromSurface with decent performance.


  • walking fish

    Like in the previous post - the rendertarget2d is receiving the rendering calls. Call SetRenderTarget before calling Clear, Draw, etc. When you're done drawing into the RenderTarget2D, call ResolveRenderTarget and then use the texture from the render target object (obtained by calling GetTexture() on the object) as an input to your next pass (which you probably want to render to another render target, or to the implicit render target, i.e. the back buffer, by calling SetRenderTarget(0, null)).



  • e_LA

    Most often you will probably want to use custom rendertargets rather than the default backbuffer: you get a lot more control that way. The pattern here is:

    - Set destination rendertarget
    - Draw fullscreen quad using source rendertarget texture
    - ResolveRenderTarget
    - Unset rendertarget

    If the thing you want to resolve to happens to be the same size as the backbuffer,
    you don't need to use rendertargets at all:

    - Create a texture with the ResolveTarget usage
    - Render fullscreen quad to backbuffer
    - ResolveBackBuffer, passing it your texture

    That's sometimes a bit more direct, but less flexible. There won't be any perf difference between the two approaches.


  • John123

    You can't get the backbuffer into a RenderTarget2D.

    If you really want to have the rendered scene in a RenderTarget2D, you need to render it into that rendertarget, then ResolveRenderTarget when you are done.

    If you want to render into the main backbuffer, use ResolveBackBuffer, which resolves into a regular texture, not a RenderTarget2D.


  • mroctober

    Yes, the rendertarget API is very different in beta 2. The way we are doing things now is much closer to how the Xbox hardware works, and we had to make these changes to get things working in a crossplatform way.

    You're right, there is no StretchRect any more. You have to Resolve a rendertarget after you are done drawing into it to make the data available as a texture. That's how the Xbox hardware works, as as a neat benefit of emulating this on Windows, the new API makes multisampled rendertargets work much more reliably and consistently than they used to.

    Why are you needing to copy between rendertargets, btw


  • ICP-Fan

    One correction to Shawn's post: If you're running in our Game, then we call Present for you in base.EndDraw, so no need to do that either.

  • Alexander Petukhov

    I just posted a code snippet on how to use render targets in Beta 2 in this topic: http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=882859&SiteID=1

    To copy between render targets, you could use a SpriteBatch to render the data from one render target (obtained with GetTexture) onto another render target. I don't know if this will give you any good performance though, but it's worth a shot.



  • Marimuthu_r

    Wait, so if I want to copy from one RenderTarget2D/Texture2D to another I do this:

    Set RenderTarget B on the device

    Set RenderTarget A Texture

    Draw a Full Screen Quad

    ResolveRenderTarget B;

    Set Device render target to NULL;

    use Render Target B Texture whever I want

    OR

    Set RenderTarget B on the device

    ResolveBackbuffer into texture

    Set Device render target to NULL;

    use texture wherever I like

     

    Which one is correct or best



  • Tatworth

    Ok, one more question. Does ResolveBackBuffer() copy the real 'hidden' backbuffer into a texture, or only from the last RenderTarget2D you set

    If its not the hidden backbuffer im stuck again.



  • Rendering To Textures in Beta2