I'm working on a 2D side-scroller, OpenGL, pixel art. And I'm having trouble getting the pixels to remain square when scrolling the camera. By that I mean, when scrolling the camera at low speed when you have tile pixels being draw at 2x2 scale, you can see some pixels become 3x2 in size rather than 2x2. I've tried different ways of calculating the size of the orthographic projection in order to get the pixels sized correctly, and while they do usually appear correct when stationary, they always wobble while scrolling.

Here is my latest attempt at calculating window size for the orthographic projection:

#define TILE_SIZE 32 // Each tile is 32x32
#define TILE_MIN_HEIGHT 10 // Adjust pixel size to fit at east 10 tiles vertically in the window

float windowRatio = (float)window->width / (float)window->height;
int pixelSize = window->height / TILE_SIZE / TILE_MIN_HEIGHT;
float tileHeight = (float)window->height / (pixelSize * TILE_SIZE);
gameState->windowTileWidth = tileHeight * windowRatio * TILE_SIZE;
gameState->windowTileHeight = tileHeight * TILE_SIZE;

window->orthoProjection = matrix44_createOrthographic2D( gameState->windowTileWidth, gameState->windowTileHeight );`

So far, I've tried all of these in an attempt to eliminate the wobble:

  • Calculate orthographic projection as above, to fix at least 10 tiles vertically, adjusting projection size to fit window ratio.
  • Calculate orthographic projection to exactly fit a 20x10 tile scene, scaling pixels to fit window.
  • Render the scene to a 1:1 scale framebuffer, then blit that buffer to the window to scale it up to desired pixel size.
  • Disable offsetting of texture coordinates (I draw tiles from a texture atlas, and so offset the coordinates by 0.001 inside each quad to eliminate bleed from surrounding textures).

None of these have eliminated the wobbling. Sometimes it is extremely subtle, but still present when examining the movement closely.

What is the correct way to draw a 2D image to the scree with perfect square pixel accuracy, at a given pixel size?