[SOLVED][libgdx] Scaling; stretched pixels at different aspect ratios

I’m trying to scale my game’s screen to compensate for different aspect ratios. I’ve followed this tutorial: http://blog.acamara.es/2012/02/05/keep-screen-aspect-ratio-with-different-resolutions-using-libgdx/ and have been mildly successful. It properly scales and applies letterboxing, but at most resolutions, unless it’s a perfectly divisible by itself resolution (480/270, 960/540, etc…) of 16:9 aspect ratio, some of the pixels stretch across the screen looking very ugly as seen below:


Pixels stretching at 800x480 (Galaxy S2 resolution)


Pixels not stretching at 960/540; double the resolution of the virtual resolution the game is programmed in.

The code I’m using for the camera:
http://pastebin.com/92GkkUjD
PetsimGame.CAMERA_HEIGHT and _WIDTH are the virtual screen sizes hardcoded at 480 and 270 respectively.

Can anyone shine some light on my delima. I’ve been try to debug this one for quite a while with little luck and I’ve gotten at least this far. Any help would be appreciated!

It looks like normal behavior to me. 480/800 = 0.6 while 540/960 = 0.5625. You can see there’s different value here. There are 2 common solutions to fix this: you fill the width and leave blank space for height, and vice versa. Yours is the first one, that’s why you have unfilled draw on the first pic.

The unfilled draw is intentional (hence, letterboxing). My concern though is the stretching of the pixels on the screen. If you’ll notice, on the first screen there is stretching in half the pixels on each sprite caused by resizing them to upsize them. This doesn’t seem to happen ONLY when it resizes at 1x, 2x, 3x, etc… But does when it’s resized at any other rate.

I’m kinda confused by the titles. Maybe you mean “wrong zoom scale”?

float aspectRatio = (float)width/(float)height;
System.out.println((float)16/(float)9 + " and " + aspectRatio);
float scale = 1f;
Vector2 crop = new Vector2(0f, 0f);
               
if (aspectRatio > PetsimGame.ASPECT_RATIO) {
        scale = (float)height/(float)PetsimGame.CAMERA_HEIGHT;
        crop.x = (width - PetsimGame.CAMERA_WIDTH * scale) / 2.0f;
} else if (aspectRatio < PetsimGame.ASPECT_RATIO) {
        scale = (float)width / (float)PetsimGame.CAMERA_WIDTH;
        crop.y = (height - PetsimGame.CAMERA_HEIGHT * scale) / 2.0f;
} else {
        scale = (float)width/(float)PetsimGame.CAMERA_WIDTH;
}
               
float w = (float)PetsimGame.CAMERA_WIDTH * scale;
float h = (float)PetsimGame.CAMERA_HEIGHT * scale;
viewport = new Rectangle(crop.x, crop.y, w, h);

you are keeping your scale set to 1.

Rebirth: I suppose it should be described as “pixels stretching warps the graphics in the first screenshot but not the second”. Thus the titles being StretchedCausingPixelWarping and StrechedCausingNoWarp.

supaFool: The scale changes in the code depending on the vitual aspect ratio and the actual aspect ratio. The scale becomes either the virtual width divided by the actual width or virtual height divided by actual height.

but isn’t it getting reset to 1 before the if statement, i might be wrong, i don’t know what your code looks like, but if you are using that if statement in a method, then it looks like it is getting set to 1 before it checks