2
\$\begingroup\$

I'm starting to make a game, and the first screen I've made is a very simple loading screen with some centered text.

On starting it up, the text is nicely centered: enter image description here

Then I resize the window, and I get: enter image description here

Why is it stretched? And why has it moved? Looking at my code it looks like everything should be perfectly centered:

public void render(float delta) {
        Gdx.gl.glClearColor(0, 0, 0.2f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        if (Assets.manager.update()) {
            // Eventually change to a main menu or something
        }

        String text = "Loading " + Math.round(Assets.manager.getProgress()) + "%";

        BitmapFont.TextBounds bounds = fnt.getBounds(text);

        batch.begin();
        fnt.draw(batch, text, (Gdx.graphics.getWidth()/2)-(bounds.width/2), (Gdx.graphics.getHeight()/2)-(bounds.height/2));
        batch.end();
    }
\$\endgroup\$
  • \$\begingroup\$ Is your batch using a camera? If so you can probably resize the camera in the LibGDX resize method \$\endgroup\$ – ThorinII Jan 14 '14 at 22:03
4
\$\begingroup\$

I'm not sure if a more specific answer is needed here, but for me to fix this issue I had to adjust the projection matrix on the SpriteBatch. Although destroying the SpriteBatch and recreating it would also work.

So in my constructor I create the camera:

camera = new OrthographicCamera();

Then when the size of the window changes I execute:

camera.setToOrtho(false);
batch.setProjectionMatrix(camera.combined);

The first line causes the camera to recalculate the matrix for the new width/height of the window, and the second line sets the batch's projection matrix to be the same as the cameras, which the origin in the lower left corner.

Another option I suspect would work would be to use:

Matrix4 matrix = new Matrix4();
matrix.setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.setProjectionMatrix(matrix);

If you wanted to specifically set the the coordinates of the origin.

\$\endgroup\$
2
\$\begingroup\$

When you resize a window that you are rendering to, you generally also need to adjust the rendering viewport bounds and potentially the bounds of any intermediate render targets (depending what you are doing with them).

In OpenGL, you can make use of the glViewport function to handle the viewport adjustment. Update it when your window size changes. The values of the graphics API's viewport are used to compute the window-space coordinates of your rendered geometry prior to the rasterization of that geometry, if your viewport bounds (and again, potentially render target bounds, depending) do not match the physical bounds of your window, you'll get distorted results.

If you have any intermediate render targets to resize, this is usually more involved, and usually means having to destroy and recreate the render target at the appropriate size or maintaining a separate set of bounds information allowing you to reuse the target if you decrease the render target size and keep reusing it as long as you don't expand beyond the original (at which case you reallocate and update the bounds). This also may require some clamping on your part within your rendering.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.