Hide overflow content

Hi,

is there more effective way to hide overflow content than using RenderTarget2D? What I mean is scrollable content or something like overflow: hidden in CSS. The way I do it now is creating RenderTarget2D with specific size and then render content inside of it, but I’ve read that there shouldn’t be many render targets cause it kills GPU. What to do if I want many such windows (scrollable text, inventory items list, etc.)

// Draw 10 different containers
RenderTarget2D[] containers = new RenderTarget2D[10];
for (int i = 0; i < 10; i++) {
    containers[i] = new RenderTarget2D(device, 100, 100);
    device.setRenderTarget(containers[i]);
    device.clear(...)
    spriteBatch.Begin(...)
    // Draw content inside of container
    spriteBatch.End();
}

// Draw containers onto screen
device.setRenderTarget(null);
device.clear(...)
spriteBatch.Begin(...)
for (int i = 0; i < 10; i++)
    spriteBatch.Draw(containers[i], new Vector(x, y), Color.White);
spriteBatch.End();

Additional example is nesting. I’ve got 2 rectangles - black and blue. On image A - they’ve got opacity 1. On image B both of them have opacity equal 0.5. As you can see, they overlap - both are visible. What I want to achieve is C - there is invisible container with those rectangles as children. Rectangles got opacity 1 but container has 0.5, thus they do not overlap. Is there a effective way to achieve this effect without using too many RenderTarget2D?

You can use Viewport to clip whatever you’re drawing to a specific region.

https://docs.monogame.net/api/Microsoft.Xna.Framework.Graphics.Viewport.html

set graphics.GraphicsDevice.Viewport to whatever mask you’d like. Be sure to cache its value beforehand and set it back after drawing your “clipped” content. Note: this will change your X/Y when drawing (i.e. drawing something at 0, 0 via SpriteBatch would draw it in the top of left of your viewport, not your screen)

Hmm, okay, but it shuts down my ability to rotate whole container (I can rotate sprites individually inside of Viewport but it will cut them) or set opacity to the container itself (example C on the image above) :thinking:

For those requirements I’d turn to RenderTarget. Not a great plan to be creating/GCing RTs in a loop every frame. Preferred method imho is to gen your RTs when loading content, then re-use those instances in game loop. Manually dispose when appropriate.

Check out GraphicsDevice.ScissorRectangle. I may help for what you’re searching for and it will not modify the viewport whatsoever. Just set the clipping rectangle and everything outside of it will not be drawn in subsequent drawcalls (until you unset the scissor test)

I use it heavily for my UI Code whenever it’s needed that a nested control does not overflow out of its parents area

of course this will only work for AABB regions.

Another option would be to make use of the stencil buffer, you’d just need to sort the draw calls properly - that way you have the ability of masking per pixel