Pixel-Perfect 2D rendering with OpenGL

Can an OpenGL scene be tweaked to provide perfect pixel rendering and lens flare? I noticed that scene creation happens:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, width, height, 0.0, 0.0, 1.0);

      

And then draw the pixel using:

glBegin(GL_POINTS);
glVertex2i(0, 0);
glEnd();

      

Doesn't consistently draw it at the top left pixel on every hardware configuration (sometimes it's one pixel to the left or one below the top left corner). I realize this is probably due to different OpenGL graphics driver implementations, but is there a way to do it so that the top left pixel is (0,0) and the bottom right (width-1, height-1) consistently? It seems odd that this is not standardized ...

I've seen some "hacks" that use translation (0.375, 0.375) or (0.5, 0.5), but this also seems to solve it for some configurations and not others.

+3


source to share


2 answers


edit : dang, this is the translation. Updated.

You should also consider that pixels are sized too. This is what "hacks translate" to. If the leftmost pixel is to have a center coordinate 0.0

, then its left border is at -0.5

- and that's where the clipping plane should be. Likewise, if the rightmost pixel should have a center coordinate width - 1

, then its right border is at (width - 1) + 0.5

- and that's where that clipping plane should be.

So try:



glOrtho(-0.5, (width - 1) + 0.5, (height - 1) + 0.5, -0.5, 0.0, 1.0);

      

So where does the translation come from.

+5


source


On first check that it seems like it should work, and that if the implementations are pixel-compensated, I suspect they might be out of specification. However, it can also be the result of the view being upside down and some inaccuracies creeping in and causing a rounding problem. I'm not sure what the matter is, but if I wanted to do pixel rendering, I wouldn't start by introducing an unnecessary transform.

Most likely, anyway, I would completely avoid the fixed function pipeline, and just make sure I am calculating the correct coordinates in the vertex shader using my own transforms. So my first suggestion is a modern programmable pipeline puts you in much more control over what happens.

If not, at least try to get things right and see if that does what the various platforms you're targeting are a little more consistent.



Alternatively, and I find this a little hacky, but sometimes these things are necessary - you can check it and shift your coordinates accordingly with a transform (i.e. draw a pixel and read it back to see, in the right place, and if no, where will he go). Of course, you can simply make the problem worse.

I wouldn't do too much tinkering with the subpixel offsets here, chances are you'll just imagine more cases where the pixels are no longer displayed 1: 1 the way you want.

+1


source







All Articles