Matrix operations inaccuracy

Hi,

In my project i have encountered an inaccuracy problem using OpenGL matrix operation as follows :

  1. I wanted to set up the model view matrix with double precision, however when reading it back it appears that the OpenGL implementation lost the precision in the last elements (11-15, last column )
double modelViewInput[16];

modelViewInput[0] = 0.026998661458492279;
modelViewInput[1] = 0.98118263483047485;
modelViewInput[2] = -0.19118513166904449;
modelViewInput[3] = 0.0;
modelViewInput[4] = -0.99963545799255371;
modelViewInput[5] = 0.026500277221202850;
modelViewInput[6] = -0.0051636248826980591;
modelViewInput[7] = 0.0;
modelViewInput[8] = 0.0;
modelViewInput[9] = 0.19125485420227051;
modelViewInput[10] = 0.98154044151306152;
modelViewInput[11] = 0.0;
modelViewInput[12] = 3629409.6552495742;
modelViewInput[13] = -839582.21023714449;
modelViewInput[14] = 162096.94807597355;
modelViewInput[15] = 1.0;

glLoadMatrixd(modelViewInput);

double modelViewOutput[16];
glGetDoublev(GL_MODELVIEW_MATRIX, modelViewOutput);
 
/* the results are :  

modelViewOutput
	[0]	0.026998661458492279	double
	[1]	0.98118263483047485	double
	[2]	-0.19118513166904449	double
	[3]	0.00000000000000000	double
	[4]	-0.99963545799255371	double
	[5]	0.026500277221202850	double
	[6]	-0.0051636248826980591	double
	[7]	0.00000000000000000	double
	[8]	0.00000000000000000	double
	[9]	0.19125485420227051	double
	[10]	0.98154044151306152	double
	[11]	0.00000000000000000	double
	[12]	3629409.7500000000	double
	[13]	-839582.18750000000	double
	[14]	162096.95312500000	double
	[15]	1.0000000000000000	double
*/

The last column used for translation is less precise, even different(not even float casting ) :
[12] 3629409.7500 instead of 3629409.6552495742
[13] -839582.1875 instead of -839582.21023714449
[14] 162096.953125 instead of 162096.94807597355

This cause a degradation in my results. :frowning:

I also tried :
2) glLoadIdentity + glMultMatrixd.
3) glLoadIdentity +
glMultMatrixd(the 4x4 with no translation ) +
glMultMatrixd(the 4x4 translation only ).
4) glLoadIdentity +
glMultMatrixd(the 4x4 with no translation ) +
glTranslatedv(translation vector).

all gave the same results as above.

I am using NVidia Geforce 6800

maybe it’s a driver issue ? :confused:

I would appreciate it if someone will try to run the example and check if it occurs there.

Thanks in advance,
Amit

Hardware internally runs in single precision mode (32bit float).

No reason why double precision input will be converted to single precision only for some of the matrix elements and for the others not.

A Matrix and Vector multiplication output might be converted to single precision, but only after the double precision multiplication. otherwise there wouldn’t be support for double precision matrices.

Amit

No, the matrices you send to OpenGL are immediately converted to floats. Look into some sample implementations, for example www.mesa3d.org contains this code:

void GLAPIENTRY
_mesa_MultMatrixd( const GLdouble *m )
{
   GLint i;
   GLfloat f[16];
   if (!m) return;
   for (i = 0; i < 16; i++)
      f[i] = (GLfloat) m[i];
   _mesa_MultMatrixf( f );
}

Double type entry points are just for user convenience. Just avoid them.

Read some docs about floating point repesentations.
Your least precise results have the biggest absolute values. That’s normal.
Floating point works best in the range [-1.0, 1.0]