Stage API changes: Viewport added

noone had a great idea, to provide a Viewport class for determining how world coordinates are scaled to screen coordinates. This was already possible using Camera of course, but it was not noob friendly. Viewport is standalone and just manages a Camera. This means any app that uses Camera can use Viewport to control the strategy for scaling the world to the screen. For example, maybe you want to stretch the world to the screen, or scale it up without changing the aspect ratio by using black bars.

After a couple iterations we’ve now integrated the Viewport class. It’s quite slick, you just pick from one of the ready made Viewport implementations and you’re good to go. See the nice wiki page for docs.

Here’s where I tell you about the pain you are in for! It makes sense for Stage to have a Viewport instead of a Camera (remember Viewport has a Camera). This makes controlling scaling for scene2d super easy, but the bad part is Stage had to change. Instead of telling the Stage the viewport size, you give it a Viewport instance that does what you want.

If your old Stage construction code looked like this:

Then you need to change it to:

If your old code looked like this:

Then you need to change it to:

There is another important change, resize used to look like:

Now you’ll do this:

The boolean centers the camera if true (only really needed for UIs). It can be omitted, which is the same as false.

The other changes that may affect you are where you are using the Stage’s Camera. You can use stage.getViewport().getCamera(), but note that Viewport has project/unproject methods that should be used instead, since they take the viewport into account.

Not too bad for you guys I hope!

15 thoughts on “Stage API changes: Viewport added

  1. I’m just learning and didn’t find it difficult, and the resize() is much better for keeping the aspect ratio.

    Now that I’ve done a test I’m going to update my project and make the changes.

  2. I am missing the keepApsectRatio with getGutterWidth() for resizing like this:
    stage.setViewport(Config.width,Config.height,true);
    stage.getCamera().translate(-stage.getGutterWidth(), -stage.getGutterHeight(), 0);

  3. Wow, for years I have been calculating the gutter witdth/height myself not knowing there is a function for that in libGDX. ๐Ÿ™‚ I have to look into the libGDX code more.

  4. To be honest I don’t like such breaking changes without any way to use the old version. I will give it a try later, but it might cause a lot of pain for older projects.

  5. Hello.

    I’m cofunsing about this feature. I work with Stage, and I make my own class from Stage and I use some methods setCamera() and SetRotation() for move the viewport so I can move arround the scene and rotate it, always with the player as center of view. With thes new Viewport this features works fine ….. but, I have a zoom property that dosn’t work ๐Ÿ™

    In my code, when I set the dimensions of the viewPort, I save the CameraW and CameraH, and I apply the zoomfactor for setting in the viewPort

    Like this:

    public float factorZoom = 1.0f, factorZoomInc = 1.0f;
    protected float CameraW = 800.0f; // this values really set in the main Class via configuration
    protected float CameraH = 480.0f;
    public void setView(float w, float h, boolean keepAspect)
    {
    CameraW = w * factorZoom;
    CameraH = h * factorZoom;
    setViewport(CameraW, CameraH, keepAspect); // this call the Stage.setViewport
    }

    So when I setup the zoom really I modiffy the dimension of the viewport, and this will open or close the viewport of the camera

    But now, whith the viewport changes

    // first, I need to configure the StretchVieport (again 800 and 480 wil be configured later)
    public GdxStage()
    {
    super(new StretchViewport(800, 480));
    }

    public void setView(float w, float h, boolean keepAspect)
    {
    CameraW = w * factorZoom;
    CameraH = h * factorZoom;
    // We lost the ‘setViewPort’ method !!!
    getViewport().update((int)CameraW, (int)CameraH, false);
    }

    this donst work in the same mode … the viewport always is (800,480) and this scale this viewport in the screen, with 0,0 as point of view

    I was trying how I can solve this problem, and I think the best method is changing the viewport dorectly in the camera vector:

    public void setView(float w, float h, boolean keepAspect)
    {
    CameraW = w * factorZoom;
    CameraH = h * factorZoom;
    getCamera().viewportWidth = CameraW;
    getCamera().viewportHeight = CameraH;
    }
    And now works as again
    take a look at this video with the results of this changes …

    https://vimeo.com/90398139

  6. The problem with this change is that the default Viewport.update calls Gdx.gl.glViewport. I know they are called Viewport objects, but this unnecessarily couples the OpenGL viewport setting, preventing you from using multiple stages with different resolutions. For example, with 0.9.9 you could use one stage for text at the window resolution and another at a virtual resolution for other actor display. Now you have to hack around update order, etc. because of the forced glViewport call.

  7. I have the same problem, I went back to the old libgdx. I don’t want to spend hours and days trying to figure out gradle.. something I don’t need.

Leave a Reply

Your email address will not be published.