Wednesday, 18 September 2013

Why does my libGDX resize code break camera.unproject?

Why does my libGDX resize code break camera.unproject?

I'm using the following code in my resize method to maintain aspect ratio
across multiple screen sizes:
@Override
public void resize(int width, int height)
{
float aspectRatio = (float)width / (float)height;
float scale = 1f;
Vector2 crop = new Vector2(0, 0);
if (aspectRatio > globals.ASPECT_RATIO)
{
scale = (float)height / (float)globals.VIRTUAL_HEIGHT;
crop.x = (width - globals.VIRTUAL_WIDTH * scale) / 2f;
}
else if (aspectRatio < globals.ASPECT_RATIO)
{
scale = (float)width / (float)globals.VIRTUAL_WIDTH;
crop.y = (height - globals.VIRTUAL_HEIGHT * scale) / 2f;
}
else
{
scale = (float)width / (float)globals.VIRTUAL_WIDTH;
}
float w = (float)globals.VIRTUAL_WIDTH * scale;
float h = (float)globals.VIRTUAL_HEIGHT * scale;
viewport = new Rectangle(crop.x, crop.y, w, h);
}
VIRTUAL_WIDTH, VIRTUAL_HEIGHT and ASPECT_RATIO are set as follows:
public final int VIRTUAL_WIDTH = 800;
public final int VIRTUAL_HEIGHT = 480;
public final float ASPECT_RATIO = (float)VIRTUAL_WIDTH /
(float)VIRTUAL_HEIGHT;
This works perfectly with regards to maintaining the correct ratio when
the screen size changes. However, camera.uproject (which I call before all
touch events) doesn't work properly - touch positions are not correct when
the resize code changes the screen size to anything other than 800x480.
Here's how I setup my camera in my create() method:
camera = new OrthographicCamera(globals.VIRTUAL_WIDTH,
globals.VIRTUAL_HEIGHT);
camera.setToOrtho(true, globals.VIRTUAL_WIDTH, globals.VIRTUAL_HEIGHT);
And this is the start of my render() method:
camera.update();
Gdx.graphics.getGL20().glViewport((int)viewport.x, (int)viewport.y,
(int)viewport.width, (int)viewport.height);
Gdx.graphics.getGL20().glClearColor(0, 0, 0, 1);
Gdx.graphics.getGL20().glClear(GL20.GL_COLOR_BUFFER_BIT);
If I ignore the resize code and set the glViewport method call to
Gdx.graphics.getWidth() and Gdx.graphics.getHeight(), camera.unproject
works, but I obviously lose the maintaining of the aspect ratio. Anyone
have any ideas?
Here's how I perform the unproject on my touch events:
private Vector3 touchPos = new Vector3(0, 0, 0);
public boolean touchDown (int x, int y, int pointer, int newParam)
{
touchPos.x = x;
touchPos.y = y;
touchPos.z = 0;
camera.unproject(touchPos);
//touch event handling goes here...
}

No comments:

Post a Comment