3
\$\begingroup\$

So I want my game to draw to a specific "optimal" size and then be stretched to fit screens that are a different size. I'm using LibGDX and figured that I could just draw everything to a FrameBuffer and then resize that buffer to the appropriate size when drawing it to the actual display. However, my method does not work, it just results in a black screen with the top right quarter of the screen white.
Intermediary is the FBO, interMatrix is a Matrix4 object, and camera is an OrthographicCamera.

    @Override
public void render()
{
    // update actors
    currentStage.act();

    //render to intermediary buffer
    batch.setProjectionMatrix(interMatrix);

    intermediary.begin();
    batch.begin();

    currentStage.draw();

    batch.flush();
    intermediary.end();

    //resize to actual width and height
    Sprite s = new Sprite(intermediary.getColorBufferTexture());
    s.flip(true, false);

    batch.setProjectionMatrix(camera.combined);

    batch.draw(s.getTexture(), 0, 0, width, height);

    batch.end();
}

These are the constructors for the above mentioned objects (GAME_WIDTH and HEIGHT are the "optimal" settings, width and height are the actual sizes, which are the same when running on desktop). intermediary = new FrameBuffer(Format.RGBA8888, GAME_WIDTH, GAME_HEIGHT, false);

    interMatrix = new Matrix4();
    camera = new OrthographicCamera(width, height);

    interMatrix.setToOrtho2D(0, 0, GAME_WIDTH, GAME_HEIGHT);

Is there a better way of doing this or is this a viable option and how do I fix what I have?

Edit
So I changed some things around and it mostly works. This is my code now:

        sv = new StretchViewport(GAME_WIDTH, GAME_HEIGHT);
    currentStage = new StageMainMenu(sv);
}

@Override
public void render()
{
    // update actors
    currentStage.act();

    //render
    currentStage.draw();
}

However this results in some peculiar behavior when changing the window size, that I can't explain. This is what happens:
Flickering Double
There should only be one "Press me!" button. The top button of the two does not seem to be scaled correctly and also flickers, but it should not be showing up at all...

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

There's no need to use a framebuffer for this, as you're already using a Scene2D, which automatically does the proper scaling for you.

You may be asking "LOL I've been using it all this time and haven't seen a single stretching!"

It is easy, when you create your Stage, instead of instantiating it with

stage = new Stage(new ScreenViewport());

do:

stage = new Stage(new StretchViewport(optimalWidth, optimalHeight));
stage = new Stage(new FitViewport(optimalWidth, optimalHeight)); //Or this

Play around with it, each viewport kind behaves differently, and only with testing you'll know what's best for your game.

For more info, take a look at Scene2D page on LibGDX wiki

Now for custom drawing (say you want a spriteBatch doing thing besides the Stage2D, just like your code suggests), use and abuse these functions:

This is it! Now you may have enough info, good luck on your way!

EDIT:

This should belong to another question, but anyway, you're forgetting to clear the screen :P Try this way:

public void render()
{
    // update actors
    currentStage.act();

    //render
    Gdx.gl20.glClearColor(backColor.r, backColor.g, backColor.b, 0.0f);
    Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
    currentStage.draw();
}

(If it doesn't work, try changing gl20 to gl10 or gl30. It depends on the version of GLES you're using)

\$\endgroup\$
3
  • \$\begingroup\$ I updated my question, please look at it, I still need some help :3 \$\endgroup\$ Commented Jun 13, 2014 at 20:51
  • \$\begingroup\$ @StrongJoshua updated answer :) \$\endgroup\$ Commented Jun 14, 2014 at 1:16
  • \$\begingroup\$ It works :D Wish I could upvote your answer, but I don't have enough rep :/ \$\endgroup\$ Commented Jun 14, 2014 at 4:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .