Slight problem with gluProject

I was experimenting a little with z-fighting.

I rendering a couple of large triangles that are coplanar and very close to each other, to observe the z-fighting.

I also wanted to compare the result of gluProject and also my own version of gluProject.

I noticed that there is a difference in the z-fighting pattern between the software method and the hardware, which indicates that there is a difference between the z values.

From what I can see on screen, all pixels fall into place correctly (I switch between software transform and GL at the press of a button), but it could be that the x and y values are also not identical to what the hardware is producing. The hardware always operates with 32 bit floats, right?

Or it could be an error on my part.

When in software mode, I set modelview to identity.
The projection, I setup like this
glOrtho(0.0, Width, 0.0, Height, -1.0, 1.0);

I’m sure it’s a dumb error on my part.

From my experience I know that z values are different if you compare the DEPTH_COMPONENT (z-buffer value) with the z value from gluProject. I assume gluProject is done on the CPU. Not sure if this helps though.

Getting the right results between hardware and software is pretty tricky.

Problems:

  • You get different results if you use individual modelview and projection transformations vs. a composite matrix.

  • HW T&L may perform computations at different precision than your CPU. For example, internal precision for IA32 computations is >32 bits.

  • M*v where M is a 4x4 matrix and V is a 4-component vector is 4 dot products. The order of the individual pieces of the dot product is not explicitly defined, but different orderings can lead to LSB errors.

  • The perspective divide and viewport/depth-range scale may be implemented differently on HW vs. SW.

  • Small differences in X and Y effectively reposition the vertices, which can produce somewhat significant artifacts during Z interpolation/rasterization.

  • SW and HW rasterizers may interpolate differently.

All these factors can lead to small errors in Z between your own code and the driver’s. I wouldn’t invest much effort in making this work. You might want to use abs(a-b)<epsilon instead of an equality test.

These reproducability issues are really hard. Even in pure HW implementaions, there can be problem – witness the need for a “position invariant” option for vertex programs.

Pat