Flaw in OpenGL line rasterization

Line rasterization will make one pixel error. See graph http://bbs.chinagamedev.net/attachment.php?attachmentid=3356&stc=1.

There are many lines exceeding X axis, though they have the end point with Y=0.

Please look at the following data. Half of them have the end point with Y=0:
0.089999999999999997,0.000000000000000000 - 0.100000000000000010,0.010000000000000009
0.095000000000000001,0.000000000000000000 - 0.100000000000000010,0.005000000000000004

Why they like exceeding X axis?
How can I solve this issue?

Thaks in advance.

======== bd3e028
0.000000000000000014,0.095000000000000015 - 0.005000000000000018,0.100000000000000020
-0.000000000000000014,0.089999999999999983 - 0.010000000000000023,0.100000000000000020
0.000000000000000000,0.085000000000000006 - 0.015000000000000013,0.100000000000000020
0.000000000000000000,0.080000000000000002 - 0.020000000000000018,0.100000000000000020
0.000000000000000000,0.074999999999999997 - 0.025000000000000022,0.100000000000000020
0.000000000000000000,0.070000000000000007 - 0.030000000000000013,0.100000000000000020
0.000000000000000000,0.065000000000000002 - 0.035000000000000017,0.100000000000000020
0.000000000000000000,0.059999999999999998 - 0.040000000000000022,0.100000000000000020
0.000000000000000000,0.055000000000000000 - 0.045000000000000019,0.100000000000000020
0.000000000000000007,0.050000000000000010 - 0.050000000000000017,0.100000000000000020
-0.000000000000000007,0.044999999999999991 - 0.055000000000000021,0.100000000000000020
0.000000000000000000,0.040000000000000001 - 0.060000000000000019,0.100000000000000020
0.000000000000000000,0.035000000000000003 - 0.065000000000000016,0.100000000000000020
0.000000000000000000,0.029999999999999999 - 0.070000000000000021,0.100000000000000020
0.000000000000000003,0.025000000000000005 - 0.075000000000000011,0.100000000000000020
0.000000000000000000,0.020000000000000000 - 0.080000000000000016,0.100000000000000020
0.000000000000000000,0.014999999999999999 - 0.085000000000000020,0.100000000000000020
0.000000000000000000,0.010000000000000000 - 0.090000000000000024,0.100000000000000020
0.000000000000000000,0.005000000000000000 - 0.095000000000000015,0.100000000000000020
0.000000000000000000,0.000000000000000000 - 0.100000000000000020,0.100000000000000020
0.005000000000000000,0.000000000000000000 - 0.100000000000000020,0.095000000000000015
0.010000000000000000,0.000000000000000000 - 0.100000000000000010,0.090000000000000011
0.014999999999999999,0.000000000000000000 - 0.100000000000000010,0.085000000000000006
0.020000000000000000,0.000000000000000000 - 0.100000000000000010,0.080000000000000002
0.025000000000000001,0.000000000000000000 - 0.100000000000000010,0.075000000000000011
0.029999999999999999,0.000000000000000000 - 0.100000000000000010,0.070000000000000007
0.035000000000000003,0.000000000000000000 - 0.100000000000000010,0.065000000000000002
0.040000000000000001,0.000000000000000000 - 0.100000000000000010,0.060000000000000005
0.044999999999999998,0.000000000000000000 - 0.100000000000000010,0.055000000000000014
0.050000000000000003,0.000000000000000000 - 0.100000000000000010,0.050000000000000010
0.055000000000000000,0.000000000000000000 - 0.100000000000000010,0.045000000000000005
0.059999999999999998,0.000000000000000000 - 0.100000000000000010,0.040000000000000008
0.065000000000000002,0.000000000000000000 - 0.100000000000000010,0.035000000000000010
0.070000000000000007,0.000000000000000000 - 0.100000000000000010,0.029999999999999999
0.074999999999999997,0.000000000000000000 - 0.100000000000000010,0.025000000000000012
0.080000000000000002,0.000000000000000000 - 0.100000000000000010,0.020000000000000007
0.085000000000000006,0.000000000000000000 - 0.100000000000000010,0.015000000000000001
0.089999999999999997,0.000000000000000000 - 0.100000000000000010,0.010000000000000009
0.095000000000000001,0.000000000000000000 - 0.100000000000000010,0.005000000000000004

What the hell are these numbers ? We’re not reading your mind, you know.

Anyway, they look extremely small. So small that in float32, you’re bound to having accuracy issues. Even if you process them in doubles on your CPU, they’re likely converted to floats on your video card.

Y.

See next reply please

Thank you for your reply.

These numbers are coordinates of the lines.

I’ve just found a new characteristic of the rasterization. The lines will result positive rasterization errors as well as negative errors.

See the graph http://img1n.soufun.com/bbs/2005_02/24/1109235442897.gif or http://img1.soufun.com/bbs/2005_02/24/1109235801749.gif. Sorry for last inaccessable graph. Corresponding codes are at the end of this reply (APPENDIX A).

In this graph, position A shows the positive error, because the pixel shows a positive offset from it’s ideal position. And position B shows the negative error. So the method I found in MSDN (See APENDIX B) has no use. Because the whole the errors range 3 pixels and it leads no use of method of offset half-pixel.

Thank you again for your reply. I wonder if I expressed myself correctly.

APENDIX A:
real64 a=0.01, b=0.2, a1=0.02, a2=0.03, step=0.005;
a = step;
glLineWidth(1.0f);
glBegin(GL_LINES);
glVertex2d(0, b10);
glVertex2d(b
10, 0);

	while(a little than b)
	{
		glVertex2d(0, a);
		glVertex2d(a, 0);
		a += step;
	}

	a = b;
	while(a little than 2*b)
	{
		glVertex2d(a, 0);
		glVertex2d(a+b, b);
		a+=step;
	}
glEnd();

APPENDIX B:

To obtain exact two-dimensional rasterization, carefully specify both the orthographic projection and the vertices of the primitives that are to be rasterized. Specify the orthographic projection with integer coordinates, as shown in the following example:
gluOrtho2D(0, width, 0, height);
The parameters width and height are the dimensions of the viewport. Given this projection matrix, place polygon vertices and pixel image positions at integer coordinates to rasterize predictably. For example, glRecti(0, 0, 1, 1) reliably fills the lower-left pixel of the viewport, and glRasterPos2i(0, 0) reliably positions an unzoomed image at the lower-left pixel of the viewport. However, point vertices, line vertices, and bitmap positions should be placed at half-integer locations. For example, a line drawn from (x (1) , 0.5) to (x (2) , 0.5) will be reliably rendered along the bottom row of pixels in the viewport, and a point drawn at (0.5, 0.5) will reliably fill the same pixel as glRecti(0, 0, 1, 1).

An optimum compromise that allows all primitives to be specified at integer positions, while still ensuring predictable rasterization, is to translate x and y by 0.375, as shown in the following code sample. Such a translation keeps polygon and pixel image edges safely away from the centers of pixels, while moving line vertices close enough to the pixel centers.

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity( );
gluOrtho2D(0, width, 0, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity( );
glTranslatef(0.375, 0.375, 0.0);
/* render all primitives at integer positions */