locked
Drawing problems with RenderTarget2D RRS feed

  • Question

  • Hi,

    I have problem with drawing Texture2D on RenderTarget2D. If I rendering direct with:

    Engine.dev.SetRenderTarget(0, Nothing)

    everything is ok (like on this picture in top:  http://www.euroregin.net/heho/problem.jpg), but while I want to store rendered image on RenderTarget2D and I use:

    Engine.dev.SetRenderTarget(0, myRenderTarget)

    and then after rendering:

    Engine.dev.ResolveRenderTarget(0)

    Engine.dev.SetRenderTarget(0, Nothing)

    spriteBatch.Begin(SpriteBlendMode.AlphaBlend)

    spriteBatch.Draw(myRenderTarget.GetTexture(), New Vector2(0, 0), Graphics.Color.White)

    spriteBatch.End()

    Result will look strange like in bottom of picture:

     http://www.euroregin.net/heho/problem.jpg

    Why it's happening? What should I do for render it properly like in first case?

    Thx for help and sorry for my bad English

    Thursday, January 4, 2007 8:40 AM

Answers

  • Correct me if I'm wrong, but sounds like what you want to do is render text messages to the render target, then render it to the backbuffer.

    If so, you can use alpha test instead of alpha blending when you render messages to the render target. Then render that render target to the backbuffer with alpha blending.

    Here is code snipet to do that:

                // Font rendering to the render target.
                sb.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);
                graphics.GraphicsDevice.RenderState.AlphaTestEnable = true;
                graphics.GraphicsDevice.RenderState.ReferenceAlpha  = 0;
                graphics.GraphicsDevice.RenderState.AlphaFunction   = CompareFunction.Greater;

                // Render fonts with alpha test
                ....

                sb.End();

                // Render to the backbuffer.
                graphics.GraphicsDevice.ResolveRenderTarget(0);
                graphics.GraphicsDevice.SetRenderTarget(0, null);
                sb.Begin();
                sb.Draw(tex.GetTexture, New Vector2(0, 0), Color.White)
                sb.End();

    Key point is you have to specify SpriteSortMode.Immediate to overwrite render states. If you set other than SpriteSortMode.Immediate, SpriteBatch sets render states inside of SpriteBatch.End().

     

     

     

    Friday, January 5, 2007 12:52 AM

All replies

  • Thanks for answer, but it isn't probably my case. If you look closer on that picture (http://euroregin.net/heho/problem.jpg), you can see that "bottom version of text" is same, except that some pixels are less visible (after few same operations text almost disappear). So in my opinion it have to be something with alphablending, but I realy don't know why it's happening :(
    Thursday, January 4, 2007 2:31 PM
  • My guess is you are doing alpha blending twice.

    Say, You have a white (1,1,1) colored object with alpha value 0.5 and a render target that is filled by black. First time you render that object to render target, result becomes gray (0.5, 0.5, 0.5) colored object and also it stored alpha value to render target too.

    Now, when you use that render target as a texture with alpha blending, result becomes darkened gray (0.25, 0.25, 0.25) colored object.

    If this is the case, make sure you do alpha blending only once.

    Thursday, January 4, 2007 7:17 PM
  • Unfortunately that's not the problem. I created completely new project but everything is same:

    Protected Overrides Sub LoadGraphicsContent(ByVal loadAllContent As Boolean)

    If loadAllContent Then

    FontsLoad()

    tex = New RenderTarget2D(graphics.GraphicsDevice, 512, 256, 1, SurfaceFormat.Color, MultiSampleType.None, 0)

    sb = New SpriteBatch(graphics.GraphicsDevice)

    End If

    End Sub

    Protected Overrides Sub Draw(ByVal GameTime As GameTime)

    graphics.GraphicsDevice.Clear(Color.Navy)

  • graphics.GraphicsDevice.SetRenderTarget(0, tex)

  •  graphics.GraphicsDevice.Clear(Color.TransparentWhite)

    font_verdana16.DrawString(10, 10, Color.White, "FPS:" & FPS)

    font_verdana8.DrawString(10, 40, Color.White, String.Format("Mouse X={0} Y={1}", Mouse.GetState.X, Mouse.GetState.Y))

  •  graphics.GraphicsDevice.ResolveRenderTarget(0)

  •  graphics.GraphicsDevice.SetRenderTarget(0, Nothing)

  •  sb.Begin()

  •  sb.Draw(tex.GetTexture, New Vector2(0, 0), Color.White)

  •  sb.End()

    MyBase.Draw(GameTime)

    End Sub

    If I remove lines with

  • , everything is normal. Pls help

Thursday, January 4, 2007 9:32 PM
  • Do you clear the back buffer before you draw with the SpriteBatch?
    Thursday, January 4, 2007 10:32 PM
  • I used:

    graphics.GraphicsDevice.Clear(Color.Navy)

    Is that correct?

    Thursday, January 4, 2007 10:42 PM
  • SpriteBatch.Begin() method is equivalent as below.

    SpriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.None)

    So, you are doing alpha blending when you render to the backbuffer. And, i assume your font drawing uses SpriteBatch too (Another alpha blending).

    I've confirmed that same symptoms occurred with your code. And that symptoms is gone when i use SpriteBatch.Begin(SpriteBlendMode.None) and change clear color from TransparentWhite to Navy.

     

     

    Thursday, January 4, 2007 10:44 PM
  • That's true, but that's the problem. I need to draw it with AlphaBlending but I don't want to merge color of rendered text with color of transparent pixels on RenderTarget2D. How can I do that? Is it even possible?
    Thursday, January 4, 2007 10:56 PM
  • Correct me if I'm wrong, but sounds like what you want to do is render text messages to the render target, then render it to the backbuffer.

    If so, you can use alpha test instead of alpha blending when you render messages to the render target. Then render that render target to the backbuffer with alpha blending.

    Here is code snipet to do that:

                // Font rendering to the render target.
                sb.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);
                graphics.GraphicsDevice.RenderState.AlphaTestEnable = true;
                graphics.GraphicsDevice.RenderState.ReferenceAlpha  = 0;
                graphics.GraphicsDevice.RenderState.AlphaFunction   = CompareFunction.Greater;

                // Render fonts with alpha test
                ....

                sb.End();

                // Render to the backbuffer.
                graphics.GraphicsDevice.ResolveRenderTarget(0);
                graphics.GraphicsDevice.SetRenderTarget(0, null);
                sb.Begin();
                sb.Draw(tex.GetTexture, New Vector2(0, 0), Color.White)
                sb.End();

    Key point is you have to specify SpriteSortMode.Immediate to overwrite render states. If you set other than SpriteSortMode.Immediate, SpriteBatch sets render states inside of SpriteBatch.End().

     

     

     

    Friday, January 5, 2007 12:52 AM
  • That's exactly what I was looking for. Thank you for solution and explanation, I appreciate your help.
    Friday, January 5, 2007 1:04 AM