3

Let pa be a point at (0.5, y) and pb at (5.5, y). If we draw a line segment from pa to pb we get a 5 pixel segment on x axis. The question is where exactly these pixels are?

According to the OpenGL ES 2.0 specification 3.4.1:

When pa and pb lie on fragment centers, this characterization of fragments reduces to Bresenham’s algorithm with one modification: lines produced in this description are “half-open,” meaning that the final fragment (corresponding to pb) is not drawn.

If we draw a segment from pa to pb we get pixels 1 to 5 (x coordinate). pa is on the centre of the first pixel and pb is on the centre of the 6th one. If we draw from pb to pa we get 2 to 6. This is the result I'm getting on iPhone 4s. But on Android (Nexus 7 and emulator) the result is always 1 to 5 (direction doesn't matter). The drawing code is exactly the same (using NDK).

So the question is which behaviour is a correct one? And what workarounds should I use to have the same result on both systems?

EDIT

On Mac OS if you run the following code (using simple NSOpenGLView subclass):

glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.85f, 0.35f);
float pa = 0.5;
float pb = 5.5;
float y =  5.5;
glOrtho(-50, 50, -50, 50, -1, 1);
glBegin(GL_LINES);
{
    //pa to pb - lower line
    glVertex3f(pa, y, 0.0);
    glVertex3f(pb, y, 0.0);
    ++y;
    //pb to pa - upper line
    glVertex3f(pb, y, 0.0);
    glVertex3f(pa, y, 0.0);
}
glEnd();
glFlush();

You get this result: enter image description here

screen shot

So this is the expected result. And it seems that Nexus 7 has a different interpretation of a spec or I might need to enable some special setting.

EDIT 2:

My emulator wasn't fitting into the screen and it was rescaling screen output and it created an illusion that emulator has the same problem as the device. After taking a screenshot through the DDMS it was obvious that emulator produces the expected result: emulator

But device is producing the following result: nexus_7

To reproduce this replace the contents of gl_code.cpp file with the following code and run hello-gl2 ndk sample project.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Kimi
  • 13,621
  • 9
  • 55
  • 84
  • rasterization depends on the final render target size. Can you confirm you're rendering to a render size that is exactly 100x100 on both the targets? – Bahbar Dec 09 '12 at 10:23
  • also, while I'm at it... can you paste a picture of what you get on the android emulator? – Bahbar Dec 09 '12 at 10:26
  • @Bahbar, please see an updated question. This also has sample code to run and test locally. – Kimi Dec 09 '12 at 13:50
  • but you haven't confirmed that you're rendering to a 100x100 render target on the actual device. I'm asking because this is _not_ a standard device resolution. – Bahbar Dec 09 '12 at 19:37
  • @Bahabar, only mac sample is 100x100, mobile apps have -w/2, w/2, -h/2, h/2 orthographic projection. – Kimi Dec 09 '12 at 22:52

1 Answers1

2

Quoth the spec you linked to:

Because the initial and final conditions of the diamond-exit rule may be difficult to implement, other line segment rasterization algorithms are allowed, subject to the following rules:

  1. The coordinates of a fragment produced by the algorithm may not deviate by more than one unit in either x or y window coordinates from a corresponding fragment produced by the diamond-exit rule.

Thus, it appears to be a legal deviation, unfortunately.

For workarounds, I'd myself try using coordinates such as 0.25 or 0.75 instead of 0.5 if they might produce the same result on both rasterizers.

Or rasterize a single line in the beginning and see which rule your rasterizer is using and adapt all coordinates later to that.

tjltjl
  • 1,479
  • 8
  • 18
  • I was afraid of such answer :) So your advice is altering the geometry for specific devices? – Kimi Dec 11 '12 at 09:49
  • Yes, or trying to find a geometry that they would produce the same answer with (e.g., 0.25 instead of 0.5 as the offset might work). And you can test at runtime so you don't have to test with all possible devices... – tjltjl Dec 11 '12 at 09:51
  • I've played with different offsets with no luck. I'm trying to draw a rectangle outline, and always I get a missing pixel at the corner. How would you test at runtime, by rendering to the texture? – Kimi Dec 11 '12 at 09:56