OpenGL rasterization


I’m trying to get my software rasterizer to fill the same pixels as OpenGL, but sometimes it gets a pixel or two wrong.

I’m doing all the transforms on the CPU and just passing OpenGL the clip coordinates with the OpenGL modelview and projection matrices set to identity in order to eliminate the transform stage as a source of the error.

My rasterization algorithm is as follows:

  • Subtract 0.5f from the vertices in order to align with pixel centers
  • Sort the vertices in y
  • Construct edges, converting the y coordinates into integers using ceil(), and adjusting the x coordinates to account for the rounding
  • Step up the edges, interpolating x values, and drawing each scanline, using ceil() to convert the left/right x coordinates into integer coordinates.

This gets pretty close, but doesnt always fill exactly the same pixels as GL. Any help would be appreciated, as I’m relatively new to software rendering. Could it just be floating point inaccuracy, and if so, should I change to fixed point? I can post some code if that would help.


  • Richard

Uhh, fun.

To find the pixels which are touched during scanline conversion you need to follow the rasterization rules in the GL spec (PDF to be found here on the main page somewhere).
Read the chapter 3 about Rasterization (102 pages!) and the first paragraph in the Appendix A about invariance.
You get into trouble if you don’t follow the diamond exit rules for example.
And to make it worse, the behaviour is different for points, lines, and filled faces and knockout is that it’s implementaton dependent.
Different hardware uses different rasterization precision (subpixel precision) to calculate the pixels to be set.
The only constant here is that polygons sharing an edge raster stitch free and never touch a pixel more than once or XOR and blending would break.

You will not be able to succeed for more than one reference implementation.

I am pretty sure the Red Book says somewhere that OpenGL is not a pixel-precise spec. I think you are guarenteed some internal consistancy (for multi-pass rendering, for example), but not between implementations.

Sub-pixel precision for rasterisation can differ between implementations, just like the others said. If you need a guide to exact rasterisation, read the texture mapping articles here .