This is my first post here and am happy to be a member of your forum. I am not new to Programming but am very new to Mono game. I expect this has been asked before, however.
I am using C# and am beginning an old school style Star Trek game and cant seem to find a tutorial that shows me how I can have multiple clipped viewports within the one game. Obviously a Star Trek Game needs for example a scanner screen, an on screen area to send maps or star fields to, whatever I can come up with. Can any of you good folk point me in the direction of a suitable tutorial or example?
I think you should look at Nez and Myra. They have full UI frameworks, with viewports and widows and UI and focusing. Myra is a bit like WPF, which might be useful if MAUI actually replaced xamarin and you are doing mobile . Nez and Myra shold work on any systems.
When I do this I usually use the RenderTarget2D class, drawing the separate areas to rendertargets first and then drawing the rendertargets to the screen. However it seems this can also be done with the ViewPort class as well.
A similar topic discussing this can be found here:
Clearly I am missing the point here I do that quite a bit lol
I feel if I can nut out my error I can use the default C# template for the full screen window
and add render targets as needed I will be good to go.
Here is my code in full, it really is just the Vis Stud 2019 Mono game template with a few added lines from the link above,
public class Game1 : Game
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
const int onScreenWidth = 800;
const int onScreenHeight = 400;
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
// TODO: Add your initialization logic here
protected override void Initialize()
// Full Screen
_graphics.PreferredBackBufferWidth = 1920;
_graphics.PreferredBackBufferHeight = 1080;
// on screen window 800 x 400
var onScreenDevice = _graphics.GraphicsDevice;
onScreen = new RenderTarget2D(onScreenDevice, onScreenWidth, onScreenHeight, false, onScreenDevice.DisplayMode.Format, DepthFormat.Depth24);
// mSpriteBatch = new SpriteBatch(device);
// TODO: use this.Content to load your game content here
protected override void LoadContent()
_spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: Add your update logic here
protected override void Update(GameTime gameTime)
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
// TODO: Add your drawing code here
protected override void Draw(GameTime gameTime)
_graphics.GraphicsDevice.SetRenderTarget(onScreen); // <--- This is the line that kills all
Sorry for the lengthy post, I think I was an ENT in a past life
If you follow all the steps in that post it should work, but it won’t work with just that line on it’s own. Currently you are switching to an off screen rendertarget but are not switching back to the backbuffer for the final draw to the screen.
The line GraphicsDevice.SetRenderTarget(null) will be needed to unset the rendertarget before base.Draw.
Edit: Just to be clear the post I was referring to was by kosmonautgames where they posted this:
A render target is basically a texture2d. Using multiple render targets will come in handy for doing effects (lighting shadows etc) but it does come at a performance cost when switching between render targets (especially on computers with integrated graphics cards) so dont go using a seperate rendertarget for seperate components. Ideally a max of 5 or 6 through a frame draw would be the most you want to use.
A render target is also handy for scaling your game to different monitor sizes. Draw your game at 1920x1080 for example to a second rendertarget. Then scale that rendertarget to your monitor and add black bars if the asoect ratio is not 16:9
Also when creating a render target, if your planning on switching to it multiple times per frame, when creating it you can set it to preserve contents. (This also comes at a performance cost) switching to a render target will clear it
The set rendertarget by default is null. This means any drawing is done to the screen. So if you want to draw to another rendertarget at the start of the draw call you need to setrendertarget(YourRenderTarget)
Then once everythings drawn, you need to set the rendertarget back to null, so your drawing to the screen. Because a rendertarget is basically a texture2d, you can then call soritebatch.draw using YourRenderTarget as the texture2d
Regarding drawing things on seoerate parts of the screen for UI (windows displaying different parts of the game etc) viewports is the way to go. There is little performance cost, and viewports will also automatically clip any over draw. If you need some simple examples let me know and i can dig some up