Simple orthographic camera controls

Just built a basic orthographic/2D camera control:


  • panning with mouse (cursor stays at the same world position while panning)
  • zooming (cursor stays at the same world position while zooming, i.e. “zoom into the mouse cursor”)
  • centering the view onto a given point


  • Provides methods onMouseDown/onMouseUp/onMouseMove to make wiring with your preferred windowing framework (for example GLFW with LWJGL3 or simple Java2D) really easy
  • obtain the view-projection matrix to submit to a shader or the GL fixed-function pipeline, or use with Java 2D and its AffineTransform
  • (more info on the JavaDocs of the class)

Example with LWJGL3/GLFW:

Added support for rotation:

  • left mouse button is now for panning
  • right mouse button selects the rotation center and moving the mouse (beyond the minimum rotation circle radius) rotates the view
  • middle mouse button resets rotation (with mouse position as rotation center)

Interface of the onMouseDown/onMouseUp methods now have a “button” parameter, which is 0 = left, 1 = right, 2 = middle (just like the GLFW button mappings)

Post a video of a demo :point:

Here you go :slight_smile:


When I did something similar for the SpriteEngine for Cas, the target scale was pow(constant, targetZoomLevel), the actual scale was a float which converged to targetZoomLevel over time: pow(contant, currentZoomLevel), where currentZoomLevel simply linearly approached or accelerated to targetZoomLevel. Using this approach you get smooth zooming across arbitrary orders of magnitude in linear time, similar to, say, zooming in Google Maps.

Yeah, it is the same here: When calling [icode]zoom(factor)[/icode] it does: [icode]targetScale *= factor[/icode] within the camera.
When the client uses the scroll wheel tick to zoom (as in the example), he would use something like:

if (tick < 0)

It’s not smooth :slight_smile: (changing the zoom level at 60fps)

Ohh… that’s what you meant! That’s right. Thanks! :slight_smile: Gonna think about adding it.

And with 1.1 or 1.0/1.1 you easily get into inaccuracies in the zoom factors, accumulating errors (you might be zooming in/out for hours, ingame), which will ultimately cause off-by-one rendering issues where sprite-texels drift into unwanted neighbouring screen-pixels.

When the scrollwheel only controls an integer, and a float is converging to it (and actually reaching it, with a bit of nudging), it will always end up at exact zoom-levels in arbitrary orders of magnitude.