Question

I'm testing out using a Stage for a main menu with simple button using a NinePatch for the button background.

The code to set this up looks like this:

NinePatch TextButton Setup

NinePatch btnNormal9 = NinePatchHelper.processNinePatchFile("data/button_normal.9.png");

NinePatchDrawable btnNormal9Drawable = new NinePatchDrawable(btnNormal9);

TextButtonStyle style = new TextButtonStyle(btnNormal9Drawable, btnNormal9Drawable, btnNormal9Drawable);
style.font = new BitmapFont();
style.fontColor = new Color(1, 1, 1, 1);

button = new TextButton("Start Game", style);
button.setSize(200, 100);
button.setPosition(0, 0);

stage.addActor(button);


Then in my resize function I'm simply doing this for now:

Resize Code

@Override
public void resize(int width, int height) {
    camera.viewportWidth = width;
    camera.viewportHeight = height;
    camera.update();
}


Regardless of the size of the window (which is the size of the camera viewport), the button should be at (0,0) on the screen and be 200 pixels by 100 pixels.

The NinePatch image ("data/button_normal.9.png") is 26x26 pixels. But cropped to a 24x24 texture with 4px divisions, using this code (taken from here: Loading nine-patch image as a Libgdx Scene2d Button background looks awful):

Create NinePatch

public static NinePatch processNinePatchFile(String filename) {
    final Texture t = new Texture(Gdx.files.internal(filename));
    final int width = t.getWidth() - 2;
    final int height = t.getHeight() - 2;
    return new NinePatch(new TextureRegion(t, 1, 1, width, height), 4, 4, 4, 4);
}


This works fine as long as the window dimensions are an even number, e.g. 640x400 pixels, as in the screenshot below:

enter image description here

However, if the window dimensions are an odd number, e.g. 639x401 pixels, then the NinePatch isn't scaled correctly:

enter image description here

If only the height is an odd number, then the rendering error only occurs in the vertical scaling of the NinePatch, as below:

enter image description here

I don't understand why this is happening, given that the button size and position is hardcoded to be the same in every case, so the NinePatch should be drawn exactly the same.

If anyone can provide any help I'd appreciate it.

Thanks in advance.

Was it helpful?

Solution

Okay I think I realise what's going on, I'm being stupid.

If the dimensions of the screen are odd, then the centre of the screen is no longer an integer pixel value and will instead be a .5 value. This will mean anything drawn at an integer position will be blurry.

The simplest way I can think to fix this is by altering the resize method. If the height or width are odd, set the x or y position of the camera to 0.5 instead of 0, as shown below. This fixes the problem :)

if (width % 2 != 0) guiCamera.position.x = 0.5f;
else guiCamera.position.x = 0f;

if (height % 2 != 0) guiCamera.position.y = 0.5f;
else guiCamera.position.y = 0f;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top