Black screen when drawing to a RenderTarget2D in Android

When drawing the render target, the output is black. This only happens on the Android device. When drawing the render target to both the Windows console and to the Android emulator, the screen draws correctly. So I am not quite sure what the problem could be. It also works if I draw directly to the backbuffer without the rendertarget. Here is the pseudo code of my render target:

private RenderTarget2D _mainTarget;

public void ResetViewport()
{
_mainTarget = new RenderTarget2D(
               Game.GraphicsDevice,
               (int)(Game.GraphicsDevice.PresentationParameters.BackBufferWidth / GameConfig.VirtualScale * 2),
               (int)(Game.GraphicsDevice.PresentationParameters.BackBufferHeight / GameConfig.VirtualScale * 2),
               false,
               Game.GraphicsDevice.PresentationParameters.BackBufferFormat,
               DepthFormat.Depth24Stencil8,
               8,
               RenderTargetUsage.DiscardContents
               );
}

public void Draw (GameTime gametime)
{
Game.GraphicsDevice.SetRenderTarget(_mainTarget);
Game.GraphicsDevice.Clear(Color.Black);

//Draw to RenderTarget....

Game.GraphicsDevice.SetRenderTarget(null);

_spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, SamplerState.PointClamp);
_spriteBatch.Draw(_mainTarget, new Rectangle(0, 0, (int)(GameConfig.VirtualWidth * GameConfig.VirtualScale),
       (int)(GameConfig.VirtualHeight * GameConfig.VirtualScale)), Color.White);
_spriteBatch.End();
}

This is what the output looks like (left) and also what it looks like on the Android emulator (right) (which is also similar to the Windows console). Note that the on screen controls are drawn with another spritebatch draw directly after the call to draw the RenderTarget.

I think the problem is that you’re setting the render target, then clearing to black. Try clearing to transparent instead. Note that you’ll still probably want to clear to black when you switch back to your default target.

I’ve run into this before but it was a while ago and I’m having trouble remembering the details. I feel like I had to do something tricky with the clear, but I’m not sure. Try just using the transparent colour for clear for now and if it doesn’t work, let me know and I’ll go digging through some code :smiley:

I went and dug through my code anyway because this stuck out for me. Do try setting the colour to transparent first because that’s the easiest thing.

Having said that, I seem to recall that using that wasn’t working for me on Android for older phones. It actually worked just fine on my test phone, but older hardware seemed to have an issue. It was actually something a buddy pointed out to me during testing. I actually found the bug report he submitted and it sounds eerily similar to this issue.

I was able to work around it by manually setting the texture data to Color.Transparent when the render target was created with the following code…

        private void ClearBuffer(ITexture2D texture, Color clearColour)
        {
            Color[] data = new Color[texture.Width * texture.Height];
            for (int i = 0; i < data.Length; i++)
                data[i] = clearColour;
            texture.SetData<Color>(data);
        }

Thanks for the response Trinith. I tried changing the clear color to transparent without luck. I even changed the clear color to MonoGameOrange, but the screen is still black. So I do not think it has anything to do with the Clear method.

Yea I suspected as much with the clear colour, but it was worth a shot!

Did you try the ClearBuffer method I posted above? In your ResetViewPort method that you posted, right after you create the new RenderTarget2D object, call ClearBuffer with that object and Color.Transparent.

For me, that’s what made the difference. I’m not 100% convinced that we have the same problem, but it’s always worth a shot! :slight_smile:

Which version of mg are you using?
Have you tried a rt without multisampling?

Also what is the size of .BackBufferWidth .BackBufferHeight and GameConfig.VirtualScale?
Normally you will get an error if you try to create atexture langer that what the gpu support, and multisampling will fallback to the next supported level, but who knows…

I am still using MonoGame 3.6. I had too many issues with 3.7 that I have not gone back to it. I tried manually setting the backbuffers to a fixed value, such as 400x800, but the results were the same.

As an update. I changed the initialization of the render target to the following:

_mainTarget = new RenderTarget2D(
                Game.GraphicsDevice,
                (int)(Game.GraphicsDevice.PresentationParameters.BackBufferWidth / GameConfig.VirtualScale * 2),
                (int)(Game.GraphicsDevice.PresentationParameters.BackBufferHeight / GameConfig.VirtualScale * 2),
                );

and it seems to have worked. So you may be right that the multisampling was the issue.