Way to truly non anti-antialiased lines using jgraphics

    Aug 17 2011 | 11:39 am
    I'm trying to do some work with jgraphics and opengl and I'm having trouble matching results in the two.
    One question that has arisen is:
    Can I get truly non anti-aliased lines with jgraphics?
    I am calling jgraphics_line_draw_fast, which claims to not be anti-aliased, but is clearly not. I'm drawing a grid, and I think a sharp edge might be preferable. Any way to do this?

    • Aug 17 2011 | 3:01 pm
      I am painting non-antialiased vertical lines simply via jgraphics_move_to and jgraphics_line_to, with linewidth = 1., provided that the x value is half-integer. For instance, if my x is, say, 144.96, I simply round it to the 144.5.
      I'm doing the same for horizontal lines (rounding y value to the nearest half-integer value), and it works as well, so you should be able to paint a grid just by using half-integer pixel positions.
    • Aug 17 2011 | 6:21 pm
      Yes, I run into the same problem a while ago.
      jgraphics_line_draw_fast() promises to be anti-aliased already, but it's not so. Probably a bug in the function or in the comments documenting the function...
      The strategy I usually adopt is something like:
      for (i = 0; i < num_lines; ++i) {
          double pos = floor(height / num_lines) + 0.5;
          jgraphics_line_draw_fast(context, 0.0, pos, rect.width, pos, 1.0);
      However, my concern is that it would be more efficient if jgraphics_line_draw_fast() was already anti-aliased, since there would be no need to make the values rounded to half integer and the function itself would run faster...
      I remember running some comparison tests to see if it was faster to draw lines with:
      I found there was no significant difference between the two and as a matter of fact I believe that jgraphics_line_draw_fast() calls the jgraphics_move_to(); jgraphics_line_to(); jgraphics_stroke(); combo under the hood.
      But of course I have no access to the source code so I am just speculating...
      Hope this helps.
      - Luigi
    • Aug 18 2011 | 9:01 am
      Thanks guys. I may look into that, but it does not seem very elegant.
      I assume that the result looking anti-aliased is simply a consequence of the anti-aliasing method, and I would be slightly concerned about this behaviour potentially changing.... however, if this is the only way I may have to adopt it to deal with the issues I am currently having.
      FWIW the speed is not a great concern in the jgraphics method as in general it is slow - hence the inclusion of an alternative onpengl method, but the issue now is that I cannot exactly replicate line behaviour in certain alpha situations with anti-aliasing on in both environments. Drawing non-antialised for some of the task may relieve this issue for me....
    • Aug 18 2011 | 9:03 am
      Also - would either of you happen to know (or be able to quickly check) what happens:
      A - when you zoom in?
      B - when the object is not placed at an integer position?
      I assume this method you describe may well breakdown in these cases.
    • Aug 18 2011 | 7:21 pm
      Hi AlexHarker,
      my method (which is exactly Luigi's method) does not work when you zoom in, but it works if the object is not placed at an integer position. That's quite surprising to me as well, though, and I don't have a real explanation of why it works.
      And yes: a truly non-antialiased line function would be welcome :)
    • Aug 18 2011 | 10:18 pm
      Hi guys,
      A - When you zoom in, Max does a matrix transform of the patcher window to scale it and show it at the desired zoom size. So even if you use a truly non-antialiased method to draw your object, the grid lines will be antialiased by the matrix transform anyway. All line points will be multiplied by a certain factor and they will no longer fall on half-pixel values. As a 3rd party programmer you really don't have any control over this. If you check the standard distribution object that implement some kind of grid line drawing (scope~, plane~, filtergraph~, etc...) you will notice the are all antialiased when the zoom level is not 100%.
      B - The above code will not break when the object is placed at non-integer position, because pixels will always fall on .5 values (it's kind of a brute-force approach)
      But I am curious of what Alex is trying to do exactly... Are you trying to use OpenGL to draw lines faster than the JGraphics API would allow?
      - Luigi
    • Aug 18 2011 | 10:26 pm
      Hi Luigi,
      I'm not sure about the first point - my experience is a little different from that - at high zoom you can actually draw much finer lines - it seems just that jgraphics handles the scaling of "points" before drawing to the screen, rather than scaling a rasterised image - after all it is supposed to be a vector graphic - not a scaled bitmap - maybe I'm wrong on this though.
      And yes, I'm using opengl to draw faster than jgraphics using a FBO and then grabbing the pixels and drawing the result with jgraphics. The issue I'm starting from is to do with alpha and line blending behaviour in opengl that seems incorrect. In the case of the grid I am drawing one solution in opengl is not to anti-alias - then everything is fine. That doesn't work for some other lines I need to do, so it's not a total solution to my problem, which ideally would result in two draw routines (jgraphics/opengl) that look identical (or close) under all conditions.