Results 1 to 31 of 31

Thread: GDI+ Antialiasing questions, my code

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    GDI+ Antialiasing questions, my code

    I was bored and tried playing around with antialising:

    Name:  sshot.png
Views: 1430
Size:  9.9 KB

    My first question is why does line drawing look so cruddy here?

    My second is why do I sometimes see a flicker, where it looks like the backdrop lines show through one foreground-drawn shape or the other briefly?


    The first might be an error in my code. Or perhaps unrealistic expectations?

    The second may be just a bit of an optical illusion.


    Any input?
    Attached Files Attached Files

  2. #2

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: GDI+ Antialiasing questions, my code

    I have some text flicker too, but that probably results from rounding/truncation errors that stem from the changing "shape" sizes that I base the text positioning on.

  3. #3
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    Re: GDI+ Antialiasing questions, my code

    flicker is because gdi dont have monitor sync.
    that is the reason i moved to direct2d as the flickering/stuttering is getting annoying when dealing with moving objects/animation.

  4. #4
    Hyperactive Member
    Join Date
    Mar 2018
    Posts
    460

    Re: GDI+ Antialiasing questions, my code

    Quote Originally Posted by dilettante View Post
    I have some text flicker too, but that probably results from rounding/truncation errors that stem from the changing "shape" sizes that I base the text positioning on.
    you might try a double buffering solution to avoid the flicker: http://www.vbforums.com/showthread.p...fering-and-GDI

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: GDI+ Antialiasing questions, my code

    It seems to flicker worse than a very similar program that uses VB6's GDI methods instead. But yes, if you want smooth motion then alternatives are obviously better.

    I'm less concerned about animation and flickering than the drawing operations themselves though. I was hoping to get smoother looking lines.

  6. #6
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: GDI+ Antialiasing questions, my code

    Cruddy drawing? For me, it's usually trial & error. May also want to play with GdipSetPixelOffsetMode in conjunction with GdipSetSmoothingMode.

    Flicker. Well, you are performing dozens of rendering operations where each create GDI+ graphics context around your form's hDC and then releases it. I'd imagine that the release method likely triggers a WM_Paint or some other message that indicates DC changed. Is it possible VB is processing these changes, sometimes, before all of them are finished? Also you are toggling AutoRedraw and call CLS. When AutoRedraw is True & CLS is called, VB dumps the previous .Image and creates a new one. Toggling AutoRedraw may also do that. This toggling back & forth along with CLS may be a contributing factor?

    Edited: Others have posted ideas on the flicker. Obviously buffer would be better as could be doing all the drawing in a single graphics context.

    P.S. I did not run your project, am not on a VB machine. Just reviewed your code.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  7. #7
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    Re: GDI+ Antialiasing questions, my code

    even with double buffering its not perfect.
    when i created my game in gdi32, i needed to increase fps to 125 to make it somehow smooth, even then it showed stuttering here and there.
    now with direct2d i use the monitor sync rate (60-70) and its smooth and show no stuttering.
    sure, this kind of program, with lines and some boxes, im sure gdi+ is ok with double buffering, but more stuff you have moving and if you use bitmaps, that will increase the stuttering no matter the fps.

  8. #8

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: GDI+ Antialiasing questions, my code

    Well the Graphics objects are created and destroyed frequently in response to dire warnings not to cache DC handles of VB6 UI elements (Forms, controls, etc.).

    But a lot could be improved by creating/destroying the Graphics object once within an event handler by adding separate calls for that. That is probably a worthwhile optimization in any case, and I could optimize GDI+ Font object creation too by handling StdFont.FontChange for the class's Font Property.

    GdipSetPixelOffsetMode is something I should probably look at too since it probably has a lot of impact on the smoothness of antialiased lines.

  9. #9
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: GDI+ Antialiasing questions, my code

    Quote Originally Posted by dilettante View Post
    Well the Graphics objects are created and destroyed frequently in response to dire warnings not to cache DC handles of VB6 UI elements (Forms, controls, etc.).
    Oh, agreed 100000%

    When I suggested one context, was leaning to something like this: Get GDI+ context on form's hDC, then perform all the drawing in your routine to that context. This would mean maybe having an "Ex" type function that receives a GDI+ context parameter vs an hDC parameter. When all drawing is done, then destroy the context. Tip to clear a context: GdipGraphicsClear. GDI+ can be used as a double buffer too by creating an 24bpp bitmap same size as form doing all the drawing on it, then rendering the final result to the form.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  10. #10
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    Re: GDI+ Antialiasing questions, my code

    when i work with animations, you dont destroy the memorydc after each render, but on exit. the memorydc you keep as long the animation is going,
    you can clear the memorydc after each circle of course.
    i keep in memory everything that i will reuse, and sometimes i also "build" the objects before rendering in the picturebox.
    so, i could create 10 memorydc that contains 10 frames that i will render later, so that only thing i do is a copy bitmap instead of drawing, anti-alias and effects, if possible.

    when using bitblt, u set autoredraw to false, even hdc to false. bitblt will render and refresh the hdc when calling.

    but i recommend using direct2d. dont understand why u keep using gdi and its inferior.

  11. #11

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: GDI+ Antialiasing questions, my code

    Quote Originally Posted by baka View Post
    but i recommend using direct2d. dont understand why u keep using gdi and its inferior.
    I'm not really interested in animation or gaming. At all.

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: GDI+ Antialiasing questions, my code

    This was really just a bit of playing around with antialiasing for drawing a few simple things. I wasn't pretending to create some Great Gdip Solution class for anyone else to use.

    Once I can draw a smooth looking straight line I'll be happy.

  13. #13
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    Re: GDI+ Antialiasing questions, my code

    direct2d is not just for gaming.
    to create a square and/or circle u write:

    DrawRectangle rect , brush , strokewidth, strokestyle
    DrawEllipse ellipse, brush, strokewidth, strokestyle

    i find direct2d easier then gdi+ for this purpose.
    u dont need to think about double buffer or create/destroy.

    if u are scared of testing it, i cant force u. but i would think that an expert like u would want to try just to get experience of it and compare and analyze if direct2d is good or bad and when its good or not to use it.
    its not that we need to use a 3rd party dll/ocx or register anything or closed source, its available in windows 7-10 like gdi32/+

  14. #14

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: GDI+ Antialiasing questions, my code

    Well GdipSetPixelOffsetMode() doesn't seem to change anything no matter what PixelOffsetMode I choose. I may have been expecting too much though.


    I'm just not that interested in Direct2D. If Windows provided a type library I might be more likely to consider it, but probably not even then.

    Most of my programs don't do any significant drawing. I get caught up in a thread here now and then, but that's just for lack of interesting questions to try to help with.

  15. #15
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: GDI+ Antialiasing questions, my code

    Quote Originally Posted by dilettante View Post
    Well GdipSetPixelOffsetMode() doesn't seem to change anything no matter what PixelOffsetMode I choose. I may have been expecting too much though.
    ...
    Yeah, I wondered about that. Running the code and capturing the form, and zooming it in a paint program, I can see the lines are being anti-aliased, it just isn't doing that well at some angles. Perhaps it is just the combination of line color and background color make it hard for the pixel blending choices made, by whatever algorithm is used, to visually look appealing. It might be interesting to try to manually adjust the color of the pixels chosen in the "blend" zones over a short segment of the line where the pixels tend to fade too quickly, or where some pixels appear too bright to see if one could do a better job visually. Of course it would help to know what computation is used to choose the partial pixels colors to determine if there would be a way to improve the calculation for given condition and not make other conditions look worse.

    It seems like this sort of thing might also be subject to the accuracy of the pixel color temperature setting of the monitor. I have a couple of ASUS ProArt "Superior Color Accuracy" monitors (1920x1200) on my desk as a left and right monitor in a three monitor setup, and the center "monitor" is a 43" 4K Smart TV (a cheap Westinghouse one). The lines do appear to anti-alias a little better on the expensive ProArt monitors, but still look like they could be improved.

    I guess a test would be to turn the anti-aliasing off for comparison and see that it probably will look much worse, so the lines are arguably "better" with anti-aliasing on, but probably not as close to the theoretical ideal as we would hope.

  16. #16

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: GDI+ Antialiasing questions, my code

    That may be bang on. I suspected that at least part of the problem stems from color contrast and some lines' angles. They also look (to my eye) slightly smoother when the lines are more than one pixel wide.

    I just thought I had gotten better results in the past but that was long ago and I don't have any of my old code that tried it.

    Another thing I haven't tried is rendering with GDI at twice the resolution and then StretchBlitting down to final size with halftone dithering turned on. Better? Worse? No idea without trying but I thought that gave decent results in the past.

  17. #17

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: GDI+ Antialiasing questions, my code

    Thought I'd post the last code I tested in case anyone sees anything in it.
    Attached Files Attached Files

  18. #18
    Fanatic Member
    Join Date
    Nov 2018
    Posts
    602

    Re: GDI+ Antialiasing questions, my code

    I tried reconstructing your project to do the exact same thing as yours,
    and I get similar results to you.

    Circle and square flicker every once in a while as they move.

    I will try to see if I can figure out how to use a backbuffer.

  19. #19

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: GDI+ Antialiasing questions, my code

    Another silly example, but a static one that isn't trying to layer the drawing.

    The main points being that it cleaned up font handling a little, removed the hDC parameter from drawing calls, and addressed a serious bug:

    GdipDeleteStringFormat was declared with a ByRef argument instead of ByVal. This error means the GDI+ object never got deleted and could have caused access violation crashes. It's a small miracle that the other program wasn't crashing.

    That's what I get for trusting a non-Microsoft information source.

    If anyone wants to play with this code the earlier versions should be avoided or at least corrected.


    Name:  sshot.png
Views: 868
Size:  44.5 KB

    Shows that thicker lines antialias a bit more acceptably.


    BTW: The attachment is large because of the backdrop image it is using.
    Attached Files Attached Files
    Last edited by dilettante; Feb 6th, 2019 at 01:13 PM.

  20. #20

  21. #21

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: GDI+ Antialiasing questions, my code

    The crashes I experienced were all access violations 0xC0000005, most likely because an address in the program taken as an object address by GDI+ sent it off to limbo.

    I didn't mean to imply that a leak caused a crash.

    However from what I can find in the documentation cleaning these up is pretty important too. You don't see a lot on this because they don't say much about the Flat API at all. Using the class-based API deals with that through implicit operations when the class instances are destroyed.

  22. #22

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: GDI+ Antialiasing questions, my code

    I sort of expected all of my questions here to be pretty old hat and almost too embarrassing to ask. I don't work with graphics much but I had the impression that GDI and GDI+ APIs were both heavily used by VB6 programmers who do.

  23. #23
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: GDI+ Antialiasing questions, my code

    I would say GDI, yeah, but GDI+ is a bit more recent so not as heavily used at this point by comparison. I haven't done any development with GDI+ and VB6, and most posts that I might answer concerning VB6 and GDI or built in graphics capability is primarily based on stuff I did 10 years or more ago.

  24. #24
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    Re: GDI+ Antialiasing questions, my code

    gdi+ is cpu hungry and because of that people tend to search some something else or gdi32 when dealing with animation.
    when i used gdi, the gdi+ part is mostly used for loading/saving and pre-work while gdi32 is used to render as its much faster.

    when you work with graphics, you want something that you can depend on, that can do things fast and with good quality.
    but to just show a picture, we dont need gdi+, and to use alpha, gdi32 is good enough.
    gdi+ is too good to do simple stuff and too bad to do complex stuff.

    programming is time and to put that much work into something that is limited and slow is a waste of time.

    the vb6 community have lost a lot of programmers because of the limitations of gdi.
    direct2d is quite amazing but too late, i feel theres only a few that is using it and its a pity.
    i mean, a lot of you have knowledge of gdi32/plus and u feel its enough, no reason learning direct2d now.
    if we did have the typelib many years ago, im sure we would discuss direct2d issues not gdi+.

  25. #25
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: GDI+ Antialiasing questions, my code

    Given that D2D is an API that is COM based, it's actually easier to use in VB6 than in C++. (The resource management part is automatically handled) No need to wrap a flat API, like they did with GDI+ and .NET.

  26. #26
    Fanatic Member
    Join Date
    Nov 2018
    Posts
    602

    Re: GDI+ Antialiasing questions, my code

    Attached is my attempt at recreating dilettante's GDI+ project using a backbuffer.

    I'm not even sure I did/use the backbuffer correctly.

    I've been staring at the animation so long I'm going a bit cross-eyed, but I think the flickering disappears (not definitively sure).
    What I have added however, is a "tearing" of the moving objects, and this looks a lot worse.

    Maybe someone else can add something to this?
    Attached Files Attached Files

  27. #27

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: GDI+ Antialiasing questions, my code

    I see the tearing, but its source isn't obvious to me.

    Could it be from not rendering the "foreground" drawing in the Paint event?

  28. #28
    Fanatic Member
    Join Date
    Nov 2018
    Posts
    602

    Re: GDI+ Antialiasing questions, my code

    I see the tearing, but its source isn't obvious to me.

    Could it be from not rendering the "foreground" drawing in the Paint event?
    I just now tried calling DynPaint in Form_Paint...

    No change to rendering ("tearing" still occurs)

  29. #29
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: GDI+ Antialiasing questions, my code

    Quote Originally Posted by dilettante View Post
    GdipDeleteStringFormat was declared with a ByRef argument instead of ByVal. This error means the GDI+ object never got deleted and could have caused access violation crashes. It's a small miracle that the other program wasn't crashing.
    FYI, I just reminded myself that SSPI/Schannel uses *8-byte handles* which are passed *ByRef*. . . I find this extremely bizarre and have never seen other APIs using anything remotely similar.

    cheers,
    </wqw>

  30. #30
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,673

    Re: GDI+ Antialiasing questions, my code

    But a lot could be improved by creating/destroying the Graphics object once within an event handler by adding separate calls for that.
    Sometimes you can get the strange bugs when for example you create a buffer HDC at startup and the associated graphics object. When you need to resize the bitmap you need to recreate the compatible bitmap and select it again to the HDC but these changes isn't reflected in the graphics and you need to recreate it once again.

  31. #31
    Fanatic Member
    Join Date
    Nov 2018
    Posts
    602

    Re: GDI+ Antialiasing questions, my code

    So I added another memory DC to the project, not to make it faster,
    but so that I could have only one memory DC to flip to screen.

    I added a command button to do this from.

    Clicking this button at different intervals, one can see that sometimes the image is "torn" and sometimes not.
    If you get into a rhythm when clicking, you can get image to always "tear" or never "tear".

    This says to me that "tearing" (in this project anyway) is not a function of GDI+ drawing speed,
    but rather when it is drawn.
    From my reading on the web, if drawing takes place during a monitor refresh, tearing will occur.

    So solution would be to control when drawing (flipping of memory DC to screen) takes place.

    I was thinking, if something like InvalidateRect function was used,
    Windows might put the event in a queue and Windows might take responsibility of timing,
    and time it so it takes place after a Monitor refresh and not during one???

    There is a good conversation here: http://www.vbforums.com/showthread.p...Animation-Loop

    Our own baka is OP and he marks as resolved.
    Tanner_H offers some interesting info and advice in posts #30, #32, & #34

    ps How do you guys embed a web link inside a word like "here:" ?
    Attached Files Attached Files
    Last edited by mms_; Feb 7th, 2019 at 11:07 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width