Viewport in Monogame

Let's making some practices about use of viewports with Monogame. In my definition, Viewport provides relative rendering area for programmers. I think, it can be useful for making user interface. I tried to create some ui library, but it failed. Let's learn how to use Monogame at first.

In Monogame, we have already a default viewport. It represents whole screen. 

(x = 0, y =  0, width = screen_width, height=screen_size)

Let's create our first viewport. I created a new project as Monogame project, and I create viewport called newViewport in Initialize method in the Game class. But also we need to store our default viewport, because we need it:


newViewport = new Viewport();
newViewport.X = 50;
newViewport.Y = 50;
newViewport.Width = 100;
newViewport.Height = 75;

defaultViewport = GraphicsDevice.Viewport;
If we want to draw on this viewport we have to activate it at first: Because the current viewport is the default viewport. We need to activate it in render method. Then we can draw some objects on newViewport:
protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);



    GraphicsDevice.Viewport = newViewport;
    GraphicsDevice.Clear(Color.Red); // it will not work as expected 

    // render somethings on this viewport 


    // then back to the default viewport
    GraphicsDevice.Viewport = defaultViewport;


    base.Draw(gameTime);
}
After that, all screen filled by red. Because Clear method clear the buffers. This causes for all screen. But if you want to background color in viewport area, we can use RenderTarget2D for that. Let's create RenderTarget2D too in Initialize method:
newViewportTarget = new RenderTarget2D(
        GraphicsDevice,
        newViewport.Width,
        newViewport.Height
    );
So let's go in the render side. It can confuse your mind, or may not. However I confused. So instead of going deep, I'm going to be a little result-oriented. As a result, asking "why" questions is not allowed. Where we were? Rendertarget2D!. We will use RenderTarget2D for each viewport. RenderTarget is a new back buffer for us. So we can use Clear method finally. Firstly we will set rendertarget, we will clear the rendertarget and then render somethings on it and then change the rendertarget or set as null to return default backbuffer, and same steps will be start for them too:
protected override void Draw(GameTime gameTime)
{

    // red area
    GraphicsDevice.SetRenderTarget(newViewportTarget);
    GraphicsDevice.Clear(Color.Red);

    // background area
    GraphicsDevice.SetRenderTarget(null);
    GraphicsDevice.Clear(Color.CornflowerBlue);

    

    
    // draw rendertargets with related viewports

    GraphicsDevice.Viewport = newViewport;

    _spriteBatch.Begin();
    _spriteBatch.Draw(newViewportTarget, new Rectangle(0, 0, newViewport.Width, newViewport.Height), Color.White);
    _spriteBatch.End();
    
    // then back to the default viewport
    GraphicsDevice.Viewport = defaultViewport;

    

    base.Draw(gameTime);
}
Let's look at the result:
This is fair. In my opinion, this features are not enough to create complex, advances to create ui. But it's enough to make useful ui.

No comments:

Post a Comment