1
\$\begingroup\$

Zooming an OrtographicCamera effectively changes the amount of world units that can be shown in the camera window. Should thus the camera viewport dimensions be correspondingly updated upon zoom? For example,

...
camera.zoom -= 0.01;
camera.viewportWidth *= camera.zoom;
camera.viewportHeight *= camera.zoom;
camera.update();
...

EDIT: Here's the full code:

private float CAMERA_WIDTH = 50;
private float CAMERA_HEIGHT = 50;
camera = new OrthographicCamera(CAMERA_WIDTH,CAMERA_HEIGHT);
camera.position.set(CAMERA_WIDTH / 2, CAMERA_HEIGHT / 2, 0);
camera.update();
// prints 1.0, 50.0, 50.0   --> OK
System.out.println(camera.zoom + ", " + camera.viewportWidth + ", " + camera.viewportHeight);
...

camera.zoom += 0.1;
camera.update();
// prints 1.1, 50.0, 50.0   --> NOT Ok
System.out.println(camera.zoom + ", " + camera.viewportWidth + ", " + camera.viewportHeight);
...

Executive summary: if you need the zoomed camera viewportWidth and viewportHeight, maintain them as separate variables. They must not be changed in the camera otherwise zoom calculation messes up (obviously, since the zoom is relative to the values the camera was created with, so the original values are always needed). If you absolutely want or need to reassign camera.viewportWidth and camera.viewportHeight, you have to reset camera.zoom to 1 immediately after.

\$\endgroup\$
1
\$\begingroup\$

The camera viewport width and height do not need updated after the camera zoom is changed as this is done already inside the update method.

The OrthographicCamera update method:

@Override
public void update (boolean updateFrustum) {
    projection.setToOrtho(zoom * -viewportWidth / 2, zoom * (viewportWidth / 2), zoom * -(viewportHeight / 2), zoom
        * viewportHeight / 2, near, far);
    view.setToLookAt(position, tmp.set(position).add(direction), up);
    combined.set(projection);
    Matrix4.mul(combined.val, view.val);

    if (updateFrustum) {
        invProjectionView.set(combined);
        Matrix4.inv(invProjectionView.val);
        frustum.update(invProjectionView);
    }
}

After your camera has been updated you should then update your rendering system such as spritebatch to use the new values with:

    cam.update();
    batch.setProjectionMatrix(cam.combined);
\$\endgroup\$
5
  • \$\begingroup\$ Indeed, however it doesn't seem to do it automatically for me. I print camera.viewportWidth and camera.viewportHeight after setting the zoom and calling camera.update() and they don't change. I have to manually calculate camera.viewportWidth * camera.zoom and camera.viewportHeight * camera.zoom and explicitly reassign the values to the viewport values, that's why I asked in the first place. \$\endgroup\$ – persson Aug 4 '17 at 9:44
  • \$\begingroup\$ Are you updating your spritebatch to use the newly calculated camera settings? \$\endgroup\$ – dfour Aug 4 '17 at 9:52
  • \$\begingroup\$ I'm not even using the spritebatch for now, see the code I posted. \$\endgroup\$ – persson Aug 4 '17 at 9:54
  • \$\begingroup\$ Ah, yeah those values will not change and do not need to change as they're used as the base width and height internally for the camera object. If you render with spritebatch, the cam.combined matrix will convert the normal viewport values to the required zoomed values and render correctly. \$\endgroup\$ – dfour Aug 4 '17 at 10:01
  • \$\begingroup\$ Ok, I ththought they should be updated by LibGDX but I can live with calculating them manually. In fact I see that they MUST be maintained as separated variables and never reassigned to the original camera.viewportWidth and camera.viewportHeight or Bad Things Would Happen. \$\endgroup\$ – persson Aug 4 '17 at 10:04

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.