• Losing row and coloumn 0 when switching to Ortho mode.

    From R.Wieser@21:1/5 to All on Wed Sep 9 17:16:03 2015
    Hello All,

    I'm switching to Ortho mode pretty-much the standard way: from setting the viewport thru setting the projection-matrix mode, setting identity, calling glOrtho, switching back to model-matrix mode and setting identity here too (only difference, I've defined it vertically upside-down, placing the origin
    in the upper-left).

    For the arguments for both of the above I used 0,0 and the with and height returned by the WM_SIZE event.

    After that I did draw a 2D rectangle using a lineloop, with its corners at
    0,0 and 128,128.

    ** The problem is that the top and left lines of that square lineloop are
    not visible, where I think they should be. What is going on here ?

    When I draw the same rectangle starting from 1,1 I do see the upper and left sides, but they are then laying directly against the inner sides of the
    control (the OpenGL canvas is displayed in).

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jean-Christophe@21:1/5 to All on Wed Sep 9 20:01:42 2015
    "R.Wieser" :

    Hello All,

    I'm switching to Ortho mode pretty-much the standard way: from setting the viewport thru setting the projection-matrix mode, setting identity,
    calling
    glOrtho, switching back to model-matrix mode and setting identity here too (only difference, I've defined it vertically upside-down, placing the
    origin
    in the upper-left).

    For the arguments for both of the above I used 0,0 and the with and height returned by the WM_SIZE event.

    After that I did draw a 2D rectangle using a lineloop, with its corners at 0,0 and 128,128.

    ** The problem is that the top and left lines of that square lineloop are
    not visible, where I think they should be. What is going on here ?

    When I draw the same rectangle starting from 1,1 I do see the upper and
    left
    sides, but they are then laying directly against the inner sides of the control (the OpenGL canvas is displayed in).

    Regards,
    Rudy Wieser

    Rudy, if this can help you, the following code displays
    a rectangle with border and partially transparent bgnd
    ( image below, located at the top left of the screen ) http://www.cjoint.com/data/EIiqQXEYaTh_0.jpg

    I didn't try to draw the border _after_ drawing the bgnd,
    anyway note the 'y1+1' and the 'x2-1' bgnd here ...

    void fctDisplayRectBgnd( int x1, int y1, int x2, int y2 )
    {
    glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); // border = white
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glRecti( x1, y1, x2, y2 ); // border
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glColor4f( 0.3f, 0.3f, 0.3f, 0.5f ); // gray-ish bgnd, 0.5 = trensparency
    glRecti( x1, y1+1, x2-1, y2 ); // background
    glDisable(GL_BLEND);
    }

    // HTH

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jean-Christophe@21:1/5 to All on Thu Sep 10 20:18:09 2015
    Rudy,

    Thanks, but that code and image does not show the problem

    Well then, there's no problem anymore, is it ? :-)


    Have you ever tried to use 0,0 for those "x1" and "y1" arguments ?
    If you did, did you still see the upper and left border lines ?
    (or lower and left if you didn't invert the vertical axis like I did)

    Well, thank you for asking me to do it for you.
    x1=0 will cause the left vertical line to disappear, while
    y1=0 will NOT cause the upper horizontal line to disappear,
    and of course the two other lines stays the same as before.

    Since I can put the whole box and its text at any given (x,y)
    position anywhere on the screen, I've got what I wanted,
    n'I like to let some pixels around things to let them 'breathe'.


    (snip)
    Also, I've got a problem with the coordinates of the transparent
    rectangle:
    its "x1" and "y2" are the same as when you draw the boundary, meaning it *should* overlap at least two of those border lines. The odd thing is,
    your image does not show such overlapping ...

    Yes, and I tried several different 'side-effect' values to check it out,
    while setting the backgroud to 'totally opaque' to be able to see
    if it overlaps the border or not.

    For the border rectangle drawn by glRecti( x1, y1, x2, y2 )
    the drawing actually starts at x1 and ends at y2.

    For the bgdn rectangle drawn by glRecti( x1, y1+1, x2-1, y2 )
    the drawing actually starts at x1+1 and ends at y2-1.

    Anyway you can reverse order : draw bgnd first, then the border.

    Cheers

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to Jean-Christophe on Thu Sep 10 11:48:05 2015
    Jean-Christophe,

    Rudy, if this can help you, the following code displays
    a rectangle with border and partially transparent bgnd

    Thanks, but that code and image does not show the problem: Have you ever
    tried to use 0,0 for those "x1" and "y1" arguments ? If you did, did you still see the upper and left border lines ? (or lower and left if you
    didn't invert the vertical axis like I did)

    And try this: Draw a line between x,y and x+1, y+100. The line will need to "step over" to the next horizontal pixel somewhere. If you do not see a
    line with that "step over" halfway down the line you've got the same problem
    I described.

    Also, I've got a problem with the coordinates of the transparent rectangle:
    its "x1" and "y2" are the same as when you draw the boundary, meaning it *should* overlap at least two of those border lines. The odd thing is,
    your image does not show such overlapping ...

    Regards,
    Rudy Wieser


    -- Origional message:
    Jean-Christophe <myadr@is.invalid> schreef in berichtnieuws msprse$8j5$1@speranza.aioe.org...
    "R.Wieser" :

    Hello All,

    I'm switching to Ortho mode pretty-much the standard way: from setting
    the
    viewport thru setting the projection-matrix mode, setting identity,
    calling
    glOrtho, switching back to model-matrix mode and setting identity here
    too
    (only difference, I've defined it vertically upside-down, placing the origin
    in the upper-left).

    For the arguments for both of the above I used 0,0 and the with and
    height
    returned by the WM_SIZE event.

    After that I did draw a 2D rectangle using a lineloop, with its corners
    at
    0,0 and 128,128.

    ** The problem is that the top and left lines of that square lineloop
    are
    not visible, where I think they should be. What is going on here ?

    When I draw the same rectangle starting from 1,1 I do see the upper and left
    sides, but they are then laying directly against the inner sides of the control (the OpenGL canvas is displayed in).

    Regards,
    Rudy Wieser

    Rudy, if this can help you, the following code displays
    a rectangle with border and partially transparent bgnd
    ( image below, located at the top left of the screen ) http://www.cjoint.com/data/EIiqQXEYaTh_0.jpg

    I didn't try to draw the border _after_ drawing the bgnd,
    anyway note the 'y1+1' and the 'x2-1' bgnd here ...

    void fctDisplayRectBgnd( int x1, int y1, int x2, int y2 )
    {
    glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); // border = white
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glRecti( x1, y1, x2, y2 ); // border
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glColor4f( 0.3f, 0.3f, 0.3f, 0.5f ); // gray-ish bgnd, 0.5 =
    trensparency
    glRecti( x1, y1+1, x2-1, y2 ); // background
    glDisable(GL_BLEND);
    }

    // HTH



    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Nobody@21:1/5 to R.Wieser on Fri Sep 11 03:57:01 2015
    On Thu, 10 Sep 2015 21:45:38 +0200, R.Wieser wrote:

    A bit more google-fu lead me to whats probably the answer to that: OpenGL tries to draw, in Ortho mode, its pixels *between* the pixels of the
    screen.

    A projection matrix has nothing to do with pixels. It transforms
    between coordinate systems. The matrices generated by glOrtho and
    gluOrtho2D map the given rectangle to the bounds of the unit cube in
    normalised device coordinates, which are in turn mapped by the viewport transformation to the bounds of the viewport (note: *bounds*, not to the centres of the boundary rows and columns of fragments).

    In short, It looks like my problem started because I was simply not aware
    of OpenGLs method of defining its pixel positions as being on the intersections of the screen-pixel grid instead of in the gridboxes
    themselves (where the screen/videocard places them).

    You appear to have it backwards.

    A fragment (pixel) doesn't have a specific position. It's not a point,
    it's a rectangle. Its corners have specific positions, as does its centre.

    E.g., the lower-left corner of the fragment at the lower-left corner of
    the window is <0,0> in window coordinates. The upper-left corner of
    that fragment is <1,1>, and its centre is <1/2,1/2>. For any fragment, the window coordinates of its corners will be integers, the window coordinates
    of its centre will be <x+1/2,y+1/2> where x and y are integers.

    When rasterising a line of width 1 without anti-alisasing, the fragments
    which are affected are those where the line passes through an inscribed diamond, i.e. the line must pass within a distance of half a fragment from
    the fragment's centre according to the Manhattan (aka taxicab) metric.
    Figure 14.2 in section 14.5.1 of the OpenGL 4.5 specification makes this
    clear (the same figure exists in other versions, but the section numbers
    vary).

    If you rasterise a horizontal or vertical line whose endpoint coordinates
    are integers in window coordinates, the line will run exactly along the boundary between two rows or columns of fragments, and thus be exactly
    half a fragment from the centres of the fragments on either side. The
    result is that the choice of exactly which row or column of fragments is rasterised will be affected by even the smallest rounding error.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to Jean-Christophe on Thu Sep 10 21:45:38 2015
    Jean-Christophe,

    Well then, there's no problem anymore, is it ? :-)

    Well, thats one way to deal with them. :-)

    Well, thank you for asking me to do it for you.

    That was not my intention. I know what the result is on my machine, but thought you might like the be made aware of possibly the same problem on
    yours.

    On the other hand, if you would see the same I did than that would be a
    signal its not just some stupid mistake I made somewhere.

    Hmm. Maybe that suggestion was a mix of a little bit for you, and a little
    bit for me ...

    x1=0 will cause the left vertical line to disappear,

    Ok, so you're loosing the Zero column too.

    while y1=0 will NOT cause the upper horizontal line to disappear,
    and of course the two other lines stays the same as before.

    Hmmm ....

    Since I can put the whole box and its text at any given (x,y)
    position anywhere on the screen, I've got what I wanted,

    I wanted to go a bit further by adding clipping to the textbox, which subsequently caused me all this trouble. :-|

    For the border rectangle drawn by glRecti( x1, y1, x2, y2 )
    the drawing actually starts at x1 and ends at y2.

    For the bgdn rectangle drawn by glRecti( x1, y1+1, x2-1, y2 )
    the drawing actually starts at x1+1 and ends at y2-1.

    Yeah, I noticed that too, and didn't think that was intended or correct.


    A bit more google-fu lead me to whats probably the answer to that: OpenGL
    tries to draw, in Ortho mode, its pixels *between* the pixels of the screen.

    The reason that those lines disappear (on my both left and top, on yours
    only the left) is that the smallest negative rounding error makes the line
    that is supposed to be on X or Y of Zero (but inside OpenGL actualy on 0.5)
    to be rounded to Zero, and thus disappear.

    Its also the reason that vertical line test I mentioned in my previous post here appeared as a straight line: it was actually drawn from x-0.5, y-0.5 to x+1-0.5, y+100-0.5 . And with rounding applied that causes X not to change
    (but for at its very start or end).

    Someone posted setting a translation of 0.5, 0.5 (, 0.0) as a solution, but that will most likely interfere with everything else too.

    My own solution is a bit cruder(?), but still does give good results (the rectangle and the border now do again align using the same coordinates): I
    did set the line width to 2.0 (meaning it will, on a vertical line, draw a pixel left and right of the "OpenGL position" of it being in between both).

    In short, It looks like my problem started because I was simply not aware of OpenGLs method of defining its pixel positions as being on the intersections
    of the screen-pixel grid instead of in the gridboxes themselves (where the screen/videocard places them).

    Or even shorter: Novice problems. :-)

    Regards,
    Rudy Wieser


    -- Origional message:
    Jean-Christophe <myadr@is.invalid> schreef in berichtnieuws mssh7a$4ec$1@speranza.aioe.org...
    Rudy,

    Thanks, but that code and image does not show the problem

    Well then, there's no problem anymore, is it ? :-)

    Have you ever tried to use 0,0 for those "x1" and "y1" arguments ?
    If you did, did you still see the upper and left border lines ?
    (or lower and left if you didn't invert the vertical axis like I did)

    Well, thank you for asking me to do it for you.
    x1=0 will cause the left vertical line to disappear, while
    y1=0 will NOT cause the upper horizontal line to disappear,
    and of course the two other lines stays the same as before.

    Since I can put the whole box and its text at any given (x,y)
    position anywhere on the screen, I've got what I wanted,
    n'I like to let some pixels around things to let them 'breathe'.

    (snip)
    Also, I've got a problem with the coordinates of the transparent
    rectangle:
    its "x1" and "y2" are the same as when you draw the boundary, meaning it *should* overlap at least two of those border lines. The odd thing is,
    your image does not show such overlapping ...

    Yes, and I tried several different 'side-effect' values to check it out, while setting the backgroud to 'totally opaque' to be able to see
    if it overlaps the border or not.

    For the border rectangle drawn by glRecti( x1, y1, x2, y2 )
    the drawing actually starts at x1 and ends at y2.

    For the bgdn rectangle drawn by glRecti( x1, y1+1, x2-1, y2 )
    the drawing actually starts at x1+1 and ends at y2-1.

    Anyway you can reverse order : draw bgnd first, then the border.

    Cheers

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sat Sep 12 14:36:08 2015
    Nobody,

    A projection matrix has nothing to do with pixels.

    I did not say that. That I even mentioned a projection mode was to give
    anyone a chance to do the same thing I did, and (likely) see the same
    results.

    You appear to have it backwards.

    I don't think so, but even if is, does that matter ? The end result of my train of thought is the same you describe. And as long as there is nothing conflicting* with my explanation its as good as any.

    *please tell me if you see any. Although I do not just go along your POV,
    I'd like to keep the/my explanation consistent.

    If you rasterise a horizontal or vertical line whose endpoint
    [snip]

    Yep. Thats what I tried to and, IIRC, even did say somewhere.

    All-in-all, you're using a lot more words to say what I already did: the
    reason OpenGLs pixels sometimes* do not get placed where you think they
    should be is because of a non-alignment of OpenGLs and the physical screen-pixel grid. That non-alignment might be good for a 3D projection,
    but obviously not when using Ortho. So why is it still done that way ?

    *One "fun" thing I observed was when I, in ortho mode, did draw a line loop
    and than a quad ontop of it using the same integer coordinates. Two
    line-loop sides peeped out from under the quad. And pardon me, but that should *not* have happened.

    And by the way, I did try to align those virtual and screen pixel grids by shifting the ortho projection half a pixel both horizontally and vertically. The end result was underwhelming ... :-\

    The only "solution" I can think of is to give a odd-width line a different treatment than a quad, thereby aliviating differences between the line and
    the quad screen results. But I would thouroughly dislike that, as it would
    be nothing more than a clumsy hack.

    By the way, I simply did change the line-width to an even value. Now a
    drawn line from x,y to x+1,y+100 again has that little 'knick' halfway down. :-) Yeah, its not a perfect solution, but its way better than most of the others.

    I'll look into anti-alisassing though.

    Regards,
    Rudy Wieser


    -- Origional message:
    Nobody <nobody@nowhere.invalid> schreef in berichtnieuws pan.2015.09.11.02.57.00.374000@nowhere.invalid...
    On Thu, 10 Sep 2015 21:45:38 +0200, R.Wieser wrote:

    A bit more google-fu lead me to whats probably the answer to that:
    OpenGL
    tries to draw, in Ortho mode, its pixels *between* the pixels of the screen.

    A projection matrix has nothing to do with pixels. It transforms
    between coordinate systems. The matrices generated by glOrtho and
    gluOrtho2D map the given rectangle to the bounds of the unit cube in normalised device coordinates, which are in turn mapped by the viewport transformation to the bounds of the viewport (note: *bounds*, not to the centres of the boundary rows and columns of fragments).

    In short, It looks like my problem started because I was simply not
    aware
    of OpenGLs method of defining its pixel positions as being on the intersections of the screen-pixel grid instead of in the gridboxes themselves (where the screen/videocard places them).

    You appear to have it backwards.

    A fragment (pixel) doesn't have a specific position. It's not a point,
    it's a rectangle. Its corners have specific positions, as does its centre.

    E.g., the lower-left corner of the fragment at the lower-left corner of
    the window is <0,0> in window coordinates. The upper-left corner of
    that fragment is <1,1>, and its centre is <1/2,1/2>. For any fragment, the window coordinates of its corners will be integers, the window coordinates
    of its centre will be <x+1/2,y+1/2> where x and y are integers.

    When rasterising a line of width 1 without anti-alisasing, the fragments which are affected are those where the line passes through an inscribed diamond, i.e. the line must pass within a distance of half a fragment from the fragment's centre according to the Manhattan (aka taxicab) metric.
    Figure 14.2 in section 14.5.1 of the OpenGL 4.5 specification makes this clear (the same figure exists in other versions, but the section numbers vary).

    If you rasterise a horizontal or vertical line whose endpoint coordinates
    are integers in window coordinates, the line will run exactly along the boundary between two rows or columns of fragments, and thus be exactly
    half a fragment from the centres of the fragments on either side. The
    result is that the choice of exactly which row or column of fragments is rasterised will be affected by even the smallest rounding error.


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to ... and this is the second time I h on Mon Sep 14 12:51:51 2015
    Nobody,

    The issue isn't non-alignment, but alignment.

    Que ? Isn't not having the first the latter, and vice verse ? Whats your distinction between the two ?

    But if you want to make a point of it (pun not intended), I would certainly call it an issue of *non* alignment: I work with what I see (whats displayed
    on my screen), and the method used behind the scenes (sorry, pun not
    intended here either :-) ) isn't relevant to me, as long as it gives me the correct results.

    And it isn't ortho versus perspective

    Ehrmm... I can't remember I ever said that, or even where I suggested
    anything like it ...

    ... and this is the second time I have said that.

    it's an issue of the specific case of trying to draw untransformed, orthogonal single pixel lines versus ... pretty much everything else.

    Nope. Although its easier to ignore in a 3D environment (which is often
    quite dynamic, and therefore such an error, if-and-when it appears, is gone before you notice it), it most likely has got the very same problem.

    It works how it does because it makes sense.

    Nope, it doesn't make sense *at all*. I've already given you two examples showing the problems with it, so I have absolutily no idea why you say it
    does. Care to explain (and why you ignore them) ?

    Fudging the math .... Which is rarely the case.

    Only *every time* someone wants to overlay his 3D scene with some 2D info, which I imagine is quite often. In other words, I can't agree with you here either. Sorry.

    That's like saying a coin toss which landed on tails "should have"
    landed on heads.

    I'm sorry, you completely lost me here. You seem to say that, when using
    the same coordinates for both a filled and an open rectangle the chance they will actually overlap will be very, *very* small ?

    In that case the used math/method/implementation is not worth its salt, if
    any. :-(

    For typical OpenGL usage, this isn't a problem.
    ...
    That situation only happens when you go out of your way
    to create it.

    Absolutily. Setting up a basic Ortho projection and than trying to draw a simple rectangle on it with a differently colored border is ofcourse "going outof my way". </sarcasm>

    Which is why OpenGL doesn't try to do it. Being predictable,
    consistent and rational are more important than being "intuitive".

    Lol. The ony "predictable, consistent and rational" about it is that the tiniest rounding error can cause the intended pixel to jump from one to the next screen position.

    The only thing you are telling me here is that you do not mind problems, as long as you know about it and its consistent.

    I personally rather have something "predictable, consistent and rational"
    that does not include 'magic behaviour' and as such also is "intuitive".

    And as time goes on, this issue will become progressively less
    relevant. Even at 1920x1080 (which is about the lowest-
    resolution monitor you can buy nowadays), single-pixel lines
    are barely visible.

    Ah, the old "problem solving" by obsfucation: If you do not see it its not there. Sorry, but I've been "at it" long enough to know that that kind of "solutions" will often come back with a vengeance.


    Bottom line: I've (still) not seen you give any explanation to why placing
    the virtual pixels at the most awkward of places in regard to the physical
    ones is a good idea. I therefore have absolutily no idea why you are definding it.

    And neither have I seen any suggestion to solve the problems caused by it
    .... :-(

    Regards,
    Rudy Wieser

    P.s.
    Ortho projection seems to be a bit of a stepchild: Even drawing simple text
    on it in a "predictable, consistent and rational" way is an exercise in frustration. One font (bitmap) does not honour viewports, another one (3D) gets distorted. Neither is therefore usefull.


    -- Origional message:
    Nobody <nobody@nowhere.invalid> schreef in berichtnieuws pan.2015.09.13.06.17.34.463000@nowhere.invalid...
    On Sat, 12 Sep 2015 14:36:08 +0200, R.Wieser wrote:

    All-in-all, you're using a lot more words to say what I already did: the reason OpenGLs pixels sometimes* do not get placed where you think they should be is because of a non-alignment of OpenGLs and the physical screen-pixel grid. That non-alignment might be good for a 3D
    projection,
    but obviously not when using Ortho. So why is it still done that way ?

    The issue isn't non-alignment, but alignment. And it isn't ortho versus perspective, it's an issue of the specific case of trying to draw untransformed, orthogonal single pixel lines versus ... pretty much everything else.

    It works how it does because it makes sense. The fact that drawing single-pixel orthogonal lines means that you have to think about
    what you're actually doing doesn't detract from that.

    Fudging the math to make that particular case easier would only make sense
    if that particular case was common, and it isn't. It only applies if the primitives being rendered are being positioned based upon the screen's
    pixel grid, and the overall combination of the model-view, projection and viewport transformations happens to be an identity transformation. Which
    is rarely the case.

    *One "fun" thing I observed was when I, in ortho mode, did draw a line
    loop and than a quad ontop of it using the same integer coordinates.
    Two
    line-loop sides peeped out from under the quad. And pardon me, but
    that
    should *not* have happened.

    That's like saying a coin toss which landed on tails "should have" landed
    on heads.

    For a filled primitive, having the edges lie exactly mid-way between two
    rows of pixels is the ideal case, because it's clear-cut which pixels are inside and which pixels are outside. For a line, it's the worst possible case, as each set of pixels has exactly the same strength of claim to
    being on the line.

    For typical OpenGL usage, this isn't a problem. By the time that the 3D coordinates have been subjected to the model-view and projection transformations, projective division, and the viewport transformation, the chances of the resulting line being exactly betwen two rows of pixels are negligible. That situation only happens when you go out of your way
    to create it.

    The only "solution" I can think of is to give a odd-width line a
    different
    treatment than a quad, thereby aliviating differences between the line
    and
    the quad screen results. But I would thouroughly dislike that, as it
    would be nothing more than a clumsy hack.

    Which is why OpenGL doesn't try to do it. Being predictable, consistent
    and rational are more important than being "intuitive".

    And as time goes on, this issue will become progressively less relevant.
    Even at 1920x1080 (which is about the lowest-resolution monitor you can
    buy nowadays), single-pixel lines are barely visible. This is a
    significant problem for legacy software which works in pixel coordinates rather than e.g. a fraction of the window size. And as "4K" displays (4096x2160 or 3840x2160) get cheaper, they'll start becoming the de facto standard for PC monitors.


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Nobody@21:1/5 to All on Tue Sep 15 06:52:45 2015
    On Mon, 14 Sep 2015 12:51:51 +0200, R.Wieser wrote:

    Look, I'm not going to explain the entire OpenGL pipeline in detail, *especially* to someone who is determined to ignore anything which they
    don't want to hear.

    But know this: you will experience exactly the same issue with every
    other modern rendering API (meaning: uses floating-point coordinates with
    an arbitrary affine or projective transformation), whether 2D or 3D.
    OpenGL, DirectX, Cairo, HTML5 Canvas, SVG, PostScript, PDF, ..., they all
    work the same way: rasterisation is based upon pixel centres while pixel
    edges are aligned to integer coordinates.

    If you want an API designed around 1990s VGA hardware, use SDL.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Nobody@21:1/5 to R.Wieser on Sun Sep 13 07:17:35 2015
    On Sat, 12 Sep 2015 14:36:08 +0200, R.Wieser wrote:

    All-in-all, you're using a lot more words to say what I already did: the reason OpenGLs pixels sometimes* do not get placed where you think they should be is because of a non-alignment of OpenGLs and the physical screen-pixel grid. That non-alignment might be good for a 3D projection,
    but obviously not when using Ortho. So why is it still done that way ?

    The issue isn't non-alignment, but alignment. And it isn't ortho versus perspective, it's an issue of the specific case of trying to draw untransformed, orthogonal single pixel lines versus ... pretty much
    everything else.

    It works how it does because it makes sense. The fact that drawing
    single-pixel orthogonal lines means that you have to think about
    what you're actually doing doesn't detract from that.

    Fudging the math to make that particular case easier would only make sense
    if that particular case was common, and it isn't. It only applies if the primitives being rendered are being positioned based upon the screen's
    pixel grid, and the overall combination of the model-view, projection and viewport transformations happens to be an identity transformation. Which
    is rarely the case.

    *One "fun" thing I observed was when I, in ortho mode, did draw a line
    loop and than a quad ontop of it using the same integer coordinates. Two line-loop sides peeped out from under the quad. And pardon me, but that should *not* have happened.

    That's like saying a coin toss which landed on tails "should have" landed
    on heads.

    For a filled primitive, having the edges lie exactly mid-way between two
    rows of pixels is the ideal case, because it's clear-cut which pixels are inside and which pixels are outside. For a line, it's the worst possible
    case, as each set of pixels has exactly the same strength of claim to
    being on the line.

    For typical OpenGL usage, this isn't a problem. By the time that the 3D coordinates have been subjected to the model-view and projection transformations, projective division, and the viewport transformation, the chances of the resulting line being exactly betwen two rows of pixels are negligible. That situation only happens when you go out of your way
    to create it.

    The only "solution" I can think of is to give a odd-width line a different treatment than a quad, thereby aliviating differences between the line and the quad screen results. But I would thouroughly dislike that, as it
    would be nothing more than a clumsy hack.

    Which is why OpenGL doesn't try to do it. Being predictable, consistent
    and rational are more important than being "intuitive".

    And as time goes on, this issue will become progressively less relevant.
    Even at 1920x1080 (which is about the lowest-resolution monitor you can
    buy nowadays), single-pixel lines are barely visible. This is a
    significant problem for legacy software which works in pixel coordinates
    rather than e.g. a fraction of the window size. And as "4K" displays
    (4096x2160 or 3840x2160) get cheaper, they'll start becoming the de facto standard for PC monitors.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Tue Sep 15 12:11:04 2015
    Nobody,

    *especially* to someone who is determined to ignore
    anything which they don't want to hear.

    I'm sorry, but all I hear from you is "you have to like what is as it is",
    with *absolutily no explanation* why the, obviously creating problems,
    method is so good.

    So I will make it simple for you:

    Why is, especially in ortho mode (where the Othto projections width and
    height matches the one of the viewport and thus the rectangle of pixels on
    the screen), an OpenGL (virtual) pixel placed 1) anywhere else than on the screen pixel 2) on the most awkward of mathematical places, where the
    slightest of rounding errors causes on-screen changes ?

    Neither makes sense to me.

    Look, I'm not going to explain the entire OpenGL pipeline in detail,

    AFAICS it has absolutily nothing to do with that, only with how the OpenGL virtual pixel grid is converted into a physical pixel grid.

    But know this: you will experience exactly the same issue
    with every other modern rendering [snip]

    Which means that everyone working with any of those must have experienced
    the same problem I do. Its therefore rather odd that I have not seen every tutorial I've found regarding Ortho projection explaining this problem, and
    how to deal with it.

    As a closing remark: I'm not out to fight *you*. It's just that I cannot accept any "yes, it causes problem, but that is how it works" kind of "just deal with it" answers.

    To be able to accept the problems it causes I need to understand the reason
    why someone designed it that way (most likely to solve a fully other
    problem. But if so which one ?).

    Regards,
    Rudy Wieser


    -- Origional message:
    Nobody <nobody@nowhere.invalid> schreef in berichtnieuws pan.2015.09.15.05.52.44.845000@nowhere.invalid...
    On Mon, 14 Sep 2015 12:51:51 +0200, R.Wieser wrote:

    Look, I'm not going to explain the entire OpenGL pipeline in detail, *especially* to someone who is determined to ignore anything which they
    don't want to hear.

    But know this: you will experience exactly the same issue with every
    other modern rendering API (meaning: uses floating-point coordinates with
    an arbitrary affine or projective transformation), whether 2D or 3D.
    OpenGL, DirectX, Cairo, HTML5 Canvas, SVG, PostScript, PDF, ..., they all work the same way: rasterisation is based upon pixel centres while pixel edges are aligned to integer coordinates.

    If you want an API designed around 1990s VGA hardware, use SDL.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Nobody@21:1/5 to R.Wieser on Wed Sep 16 10:03:10 2015
    On Tue, 15 Sep 2015 12:11:04 +0200, R.Wieser wrote:

    *especially* to someone who is determined to ignore anything which they
    don't want to hear.

    I'm sorry, but all I hear from you is "you have to like what is as it is",

    You don't have to like it, but if you want to use it, you have to make an effort to understand how it works, rather than making assumptions which
    aren't actually true.

    with *absolutily no explanation* why the, obviously creating problems,
    method is so good.

    It's not an "obviously creating problems method". Your problems stem from making incorrect assumptions, not from the the method.

    So I will make it simple for you:

    Why is, especially in ortho mode (where the Othto projections width and height matches the one of the viewport and thus the rectangle of pixels on the screen), an OpenGL (virtual) pixel placed 1) anywhere else than on the screen pixel 2) on the most awkward of mathematical places, where the slightest of rounding errors causes on-screen changes ?

    As I said before: a pixel isn't a point, it's a rectangle. A pixel
    doesn't have a single, specific location.

    To simplify matters, we can forget all about projections, and deal
    directly in window coordinates. Let w and h be the width and height (respectively) of the window in pixels.

    The bottom-left corner of the bottom-left pixel is at the bottom-left
    corner of the window, which is (0,0) in window coordinates.

    Similarly, the top-right corner of the top-right pixel is at the top-right corner of the window, which is (w,h) in window coordinates.

    The top-right corner of the bottom-left pixel is at (1,1) in window coordinates.

    The centre of the bottom-left pixel is at (0.5,0.5) in window coordinates.

    In short, window coordinates map a rectangular region of the screen to a rectangular region of the Euclidean plane. That mapping is continuous
    (i.e. defined over the reals, not the integers). Vertices (and other
    positions, e.g. the raster position used for bitmap operations) are not constrained to integer coordinates.

    In theory, a line or polygon is an infinite set of points, a subset of
    R^2. But a finite set of pixels cannot exactly represent those, so rasterisation has to produce an approximation which attempts to minimise
    the difference between the ideal and the achievable.

    In the absence of anti-aliasing, rasterising a filled polygon affects
    exactly those pixels whose centres lie within the polygon (i.e. within the convex hull of the polygon's vertices).

    There are other rules which could be used, but:

    1. The reason for testing whether a specific point lies within the polygon (rather than e.g. whether *any* part of the pixel lies inside the polygon)
    is that in the case where two polygons share a common edge, any pixel
    along that edge will belong to exactly one of the two polygons. This is of fundamental importance when using read-modify-write operations such as stencilling or glLogicOp(GL_XOR).

    2. The reason for using the pixel's centre is that it is unbiased. Using
    any other location would result in rasterised polygons exhibiting a net
    shift whose magnitude depends upon the raster resolution.

    In the absence of anti-aliasing, rasterising a line segment of width one affects exactly those pixels for which the line intersects a diamond
    inscribed within the pixel, i.e. some point (x,y) on the line segment
    satisfies the constraint |x-xc|+|y-yc|<0.5 where (xc,yc) is the
    coordinates of the pixel centre.

    The main reasons for the diamond rule are a) that it can be efficiently implemented in hardware, and b) that it guarantees that lines do not
    contain gaps.

    And again, the reason for using the pixel's centre is that it is unbiased.
    On average, half of the affected pixels will lie on each side of the line.

    This all works fine in practice, except for one specific case: when you
    draw a line which is either exactly horizontal (i.e. every point on the
    line has the same Y coordinate) or exactly vertical (i.e. every point on the line has the same X coordinate), and the constant coordinate (X or Y)
    happens to be exactly mid-way between pixel centres (i.e. the coordinate
    is an integer).

    In that case, the fact that it's unbiased on average doesn't help because
    the fact that the perpendicular coordinate (X for a vertical line, Y for a horizontal line) is constant, combined with the deterministic nature of computer arithmetic, means that all of the pixels will end up falling on
    the same side of the line.

    Almost anything which involves rounding has pathological cases, and for
    the rasterisation algorithm used by OpenGL (and almost everything else), vertical or horizontal lines with integer window coordinates are the pathological case. For filled polygons, vertical or horizontal edges whose coordinates are an integer plus 0.5 are the pathological case.

    Adding in transformations makes matters slightly worse. If you set an orthographic projection which uses the window's dimensions in pixels, the combination of the (user-defined) orthographic projection and the
    (built-in) viewport transformation should theoretically be an identity transformation. But in practice it will be slightly off because unless x
    is a power of two, x*(1/x) typically won't be exactly 1.0 when using floating-point arithmetic.

    The overall error is sufficiently small that it shouldn't matter in
    practice ... unless you've managed to construct a case where you're consistently hitting the discontinuity in the rounding function.

    In short, this can be summarised with an allegory: a man goes to the
    doctor, and says "Doctor, when I do this ... it hurts"; to which the
    doctor replies "So stop doing it!".

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Nobody@21:1/5 to R.Wieser on Thu Sep 17 11:36:44 2015
    On Wed, 16 Sep 2015 15:56:38 +0200, R.Wieser wrote:

    As I said before: a pixel isn't a point, it's a rectangle. A pixel
    doesn't have a single, specific location.
    ....
    The centre of the bottom-left pixel is at (0.5,0.5) in window
    coordinates.

    Thank you for that explanation. It also indicates a problem when the term "pixel" is used, as lthe ast time you metioned "rectangular pixels" I assumed, from the context, that you ment OpenGLs virtual ones, instead of
    the screens physical ones.

    I don't know what these "virtual pixels" you describe are.

    But a question: If I would use the exact same explanation, but define the origin of the screen as the center* of the top-left pixel, with it ranging from -1/2 pixel to +1/2 pixel, would that make the explanation invalid ?
    If so, why ? If not ....

    OpenGL defines a number of coordinate systems. Coordinates passed to
    OpenGL are interpreted in the coordinate systems which it defines. While
    you can define your own coordinate system for the purpose of exposition,
    I really don't seen any point; it would just create confusion, as you'd continually need to clarify whether you were talking about your coordinate system or OpenGL's.

    * The position of a lamp (or most any single-point lightsource) is
    normally defined as its center, not somewhere on its outside. Why would it
    be different for a pixel ?

    A pixel doesn't have a position. How many times do I have to keep saying
    this?

    A pixel is an area, a subset of R^2 containing an infinite number of
    points, each of which has a distinct position.

    is that in the case where two polygons share a common edge, any pixel
    along that edge will belong to exactly one of the two polygons.

    I think you've here mentioned the reason why a quad drawn ontop of a
    lineloop (ofcourse using the same coordinates for both) does not fully overlap the lineloop: because its *forced* to stop one pixel short of its left/bottom end-coordinates, so it will not overlap an eventual next one.
    A good choice, but not mentioned anywhere and as such not expected. :-\

    The omission of the endpoint is a separate issue, but has a similar origin (certain operations not modifying a pixel multiple times).

    The fact that a rasterised line between two points is neither wholly
    inside nor wholly outside a rasterised polygon containing that edge is
    related to the fact that the same edge can be shared by two different
    polygons (one on each side).

    Which polygon should the line be inside or outside? The answer can't be
    "the one I'm actually drawing" because drawing operations are independent;
    the rasterisation of a line can't change based upon whether or not you
    also draw a polygon using the same vertices.

    2. The reason for using the pixel's centre is that it is unbiased.
    Using any other location would result in rasterised polygons exhibiting
    a net shift whose magnitude depends upon the raster resolution.

    Ehrmmm ... Although I think I understand what problem you are indicating here, wasn't the problem not that OpenGL is *not* using the pixels
    center ?

    No. Your problem is that rasterisation (for both lines and polygons) is
    based upon pixel centers, whose window coordinates are always an integer-plus-a-half, not integers.

    for which the line intersects a diamond inscribed within the pixel

    Yeah, I found that diamond too. Though I have to say that I do not
    quite see how it, in a basic Ortho projection, would affect a
    single-pixel width line drawn from the center of a physical pixel to the center of another physical pixel

    It doesn't. If you draw between pixel centres, you don't have a problem.
    If you draw between pixel corners (i.e. use integer window coordinates),
    the problem occurs.

    because unless x is a power of two, x*(1/x) typically won't be exactly
    1.0 when using floating-point arithmetic.

    And thats *exactly* why an OpenGL pixel should *not* be placed, when
    using a basic ortho projection and integer coordinates, on the border of
    two physical ones.

    Pixels aren't "placed" anywhere; they're areas, not points (I'm starting
    to sound like a stuck gramophone here).

    unless you've managed to construct a case where you're consistently
    hitting the discontinuity in the rounding function.

    Yeah, funny that: I'm using the *most basic* of setups (ortho projection matching the viewport size, integer coordinates for any used vertex),

    Which is exactly what you SHOULDN'T be doing. Integer coordinates
    correspond to the edges and corners of pixels, i.e. the points exactly
    between pixels. Which are the worst points to use if you're trying to draw lines such that specific pixels are affected.

    If you want to render filled polygons, then integer coordinates are ideal
    (i.e. they ensure that the edges don't fall on pixel centres, resulting in
    the inside-ness test being a tie which is decided by rounding error).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Wed Sep 16 15:56:38 2015
    Nobody,

    You don't have to like it, but if you want to use it, you
    have to make an effort to understand how it works

    What did you think I was trying to do ?

    rather than making assumptions which aren't actually true.

    ... and which assumptions would that be ?

    As far as I can tell I did mention facts, and than mentioned why I do not understand why it works/is done that way, as it creates problems.

    Your problems stem from making incorrect assumptions,
    not from the the method.

    Than tell me what those "wrong assumptions" are please. You've hinted at
    that a few times, but I've not seen any specifics (and neither does the
    current post mention them).

    But a remark:
    I've been googeling quite a bit to try to find out whats going on and how to fix it, and one of the things I found was that shifting the whole grid by
    half a pixel horizontally as well as vertically (which I now have mentioned
    a few times before, but not have seen you respond to yet. Why ?) would certainly work for lines, but than would create problems for polygons.

    In short: that "method" you are referring to seems to be made up from at
    least two, which do not even agree with each other ... :-\

    As I said before: a pixel isn't a point, it's a rectangle.
    A pixel doesn't have a single, specific location.
    ....
    The centre of the bottom-left pixel is at (0.5,0.5) in window coordinates.

    Thank you for that explanation. It also indicates a problem when the term "pixel" is used, as lthe ast time you metioned "rectangular pixels" I
    assumed, from the context, that you ment OpenGLs virtual ones, instead of
    the screens physical ones.

    But a question: If I would use the exact same explanation, but define the origin of the screen as the center* of the top-left pixel, with it ranging
    from -1/2 pixel to +1/2 pixel, would that make the explanation invalid ? If so, why ? If not ....

    * The position of a lamp (or most any single-point lightsource) is normally defined as its center, not somewhere on its outside. Why would it be
    different for a pixel ?

    I mean, if its only a problem of definitions than thats easy to solve. :-)

    is that in the case where two polygons share a common edge,
    any pixel along that edge will belong to exactly one of the two
    polygons.

    I think you've here mentioned the reason why a quad drawn ontop of a
    lineloop (ofcourse using the same coordinates for both) does not fully
    overlap the lineloop: because its *forced* to stop one pixel short of its left/bottom end-coordinates, so it will not overlap an eventual next one.
    A good choice, but not mentioned anywhere and as such not expected. :-\

    I assumed that the above non-overlap was an effect of the problem I was/am
    busy with, the non-alignment of the virtual and physical grid, and only
    after a bout of googleing I realized that that might not be the case.

    In other words: one problem solved (but more to go). :-)

    2. The reason for using the pixel's centre is that it is unbiased.
    Using any other location would result in rasterised polygons
    exhibiting a net shift whose magnitude depends upon the raster
    resolution.

    Ehrmmm ... Although I think I understand what problem you are indicating
    here, wasn't the problem not that OpenGL is *not* using the pixels center ?

    for which the line intersects a diamond inscribed within the pixel

    Yeah, I found that diamond too. Though I have to say that I do not quite
    see how it, in a basic Ortho projection, would affect a single-pixel width
    line drawn from the center of a physical pixel to the center of another physical pixel (regardlesss of which coordinates are used). The endpoints would *always* be drawn where they where indicated. Curently I cannot be
    sure of that ...

    because unless x is a power of two, x*(1/x) typically won't
    be exactly 1.0 when using floating-point arithmetic.

    And thats *exactly* why an OpenGL pixel should *not* be placed, when using a basic ortho projection and integer coordinates, on the border of two
    physical ones.

    The overall error is sufficiently small that it shouldn't matter
    in practice ...

    Guess again: Thats how this thread started (read the subject line).

    unless you've managed to construct a case where you're
    consistently hitting the discontinuity in the rounding function.

    Yeah, funny that: I'm using the *most basic* of setups (ortho projection matching the viewport size, integer coordinates for any used vertex), and
    I'm already able to construct that case.

    Let me think about it ..... Nope, I get the strong, almost definite feeling you're bullshitting me here. Sorry.

    In short, this can be summarised with an allegory: a man goes
    to the doctor, and says "Doctor, when I do this ... it hurts"; to
    which the doctor replies "So stop doing it!".

    Well, in my country we use that one as a joke, indicating the non-usability
    of such an answer (which ignores the problem, but only wants to get rid of
    the symptoms). I'm not at all sure if you ment it that way, but I think
    its quite fitting. :-(

    Thanks for your attempt to help me though.

    Regards,
    Rudy Wieser


    -- Origional message:
    Nobody <nobody@nowhere.invalid> schreef in berichtnieuws pan.2015.09.16.09.03.09.421000@nowhere.invalid...
    On Tue, 15 Sep 2015 12:11:04 +0200, R.Wieser wrote:

    *especially* to someone who is determined to ignore anything which they
    don't want to hear.

    I'm sorry, but all I hear from you is "you have to like what is as it
    is",

    You don't have to like it, but if you want to use it, you have to make an effort to understand how it works, rather than making assumptions which aren't actually true.

    with *absolutily no explanation* why the, obviously creating problems, method is so good.

    It's not an "obviously creating problems method". Your problems stem from making incorrect assumptions, not from the the method.

    So I will make it simple for you:

    Why is, especially in ortho mode (where the Othto projections width and height matches the one of the viewport and thus the rectangle of pixels
    on
    the screen), an OpenGL (virtual) pixel placed 1) anywhere else than on
    the
    screen pixel 2) on the most awkward of mathematical places, where the slightest of rounding errors causes on-screen changes ?

    As I said before: a pixel isn't a point, it's a rectangle. A pixel
    doesn't have a single, specific location.

    To simplify matters, we can forget all about projections, and deal
    directly in window coordinates. Let w and h be the width and height (respectively) of the window in pixels.

    The bottom-left corner of the bottom-left pixel is at the bottom-left
    corner of the window, which is (0,0) in window coordinates.

    Similarly, the top-right corner of the top-right pixel is at the top-right corner of the window, which is (w,h) in window coordinates.

    The top-right corner of the bottom-left pixel is at (1,1) in window coordinates.

    The centre of the bottom-left pixel is at (0.5,0.5) in window coordinates.

    In short, window coordinates map a rectangular region of the screen to a rectangular region of the Euclidean plane. That mapping is continuous
    (i.e. defined over the reals, not the integers). Vertices (and other positions, e.g. the raster position used for bitmap operations) are not constrained to integer coordinates.

    In theory, a line or polygon is an infinite set of points, a subset of
    R^2. But a finite set of pixels cannot exactly represent those, so rasterisation has to produce an approximation which attempts to minimise
    the difference between the ideal and the achievable.

    In the absence of anti-aliasing, rasterising a filled polygon affects
    exactly those pixels whose centres lie within the polygon (i.e. within the convex hull of the polygon's vertices).

    There are other rules which could be used, but:

    1. The reason for testing whether a specific point lies within the polygon (rather than e.g. whether *any* part of the pixel lies inside the polygon)
    is that in the case where two polygons share a common edge, any pixel
    along that edge will belong to exactly one of the two polygons. This is of fundamental importance when using read-modify-write operations such as stencilling or glLogicOp(GL_XOR).

    2. The reason for using the pixel's centre is that it is unbiased. Using
    any other location would result in rasterised polygons exhibiting a net
    shift whose magnitude depends upon the raster resolution.

    In the absence of anti-aliasing, rasterising a line segment of width one affects exactly those pixels for which the line intersects a diamond inscribed within the pixel, i.e. some point (x,y) on the line segment satisfies the constraint |x-xc|+|y-yc|<0.5 where (xc,yc) is the
    coordinates of the pixel centre.

    The main reasons for the diamond rule are a) that it can be efficiently implemented in hardware, and b) that it guarantees that lines do not
    contain gaps.

    And again, the reason for using the pixel's centre is that it is unbiased.
    On average, half of the affected pixels will lie on each side of the line.

    This all works fine in practice, except for one specific case: when you
    draw a line which is either exactly horizontal (i.e. every point on the
    line has the same Y coordinate) or exactly vertical (i.e. every point on
    the
    line has the same X coordinate), and the constant coordinate (X or Y)
    happens to be exactly mid-way between pixel centres (i.e. the coordinate
    is an integer).

    In that case, the fact that it's unbiased on average doesn't help because
    the fact that the perpendicular coordinate (X for a vertical line, Y for a horizontal line) is constant, combined with the deterministic nature of computer arithmetic, means that all of the pixels will end up falling on
    the same side of the line.

    Almost anything which involves rounding has pathological cases, and for
    the rasterisation algorithm used by OpenGL (and almost everything else), vertical or horizontal lines with integer window coordinates are the pathological case. For filled polygons, vertical or horizontal edges whose coordinates are an integer plus 0.5 are the pathological case.

    Adding in transformations makes matters slightly worse. If you set an orthographic projection which uses the window's dimensions in pixels, the combination of the (user-defined) orthographic projection and the
    (built-in) viewport transformation should theoretically be an identity transformation. But in practice it will be slightly off because unless x
    is a power of two, x*(1/x) typically won't be exactly 1.0 when using floating-point arithmetic.

    The overall error is sufficiently small that it shouldn't matter in
    practice ... unless you've managed to construct a case where you're consistently hitting the discontinuity in the rounding function.

    In short, this can be summarised with an allegory: a man goes to the
    doctor, and says "Doctor, when I do this ... it hurts"; to which the
    doctor replies "So stop doing it!".


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)