I've been chasing a bug for some days now, and wonder if anybody has an idea what could be wrong.
It works most of the time, see attachment (no source yet, it's confused and huge). But sometimes I see that only a small 20x20 square in the upper left corner is being painted (correctly btw).
Size of the controls is OK, size of the two bitmaps involved is OK, too - checked with e.g.
invoke GetObject, APs.apBitmap, BITMAP, addr info
invoke GetObject, APs.apBitmap2, BITMAP, addr info
invoke GetClientRect, hCtrl, addr rc
GdiPlus calls do not report errors, Gdi calls are fine, too.
No significant leak (if any).
No heap corruption.
No crashes under the hood.
Sometimes the mouse cursor turns into a black square the same size as the painted little square.
The six controls have WS_THICKFRAME, sizing them has no effect. But when sizing the main window, it frequently starts working properly!
Has anybody seen something similar?
Something to do with clipping or the z-order of the controls maybe?
Although just seen it now, moving around it showed part of a cursor and some other stuff. I would guess it might be related to a size of a bitmap or dc. Seen similar corruption when i have overlooked the size of the bitmap / dc being blitted - in effect had some extra space in memory that probably got filled with random stuff.
Thanks, fearless. Yes, that is worth investigating.
In the meantime, I made some tests on my Win10 machine, and it gives me ValueOverflow for one call gdi+ call:
invGdip GdipDrawLinesI, GraphObj, gdiPenOrBrush, edx, ecx ; *graphics, *pen, *points, INT count
Checked twice, all is fine, if I reduce the count by one the last piece of the lines is missing :sad:
I'll keep you posted :smiley:
After that program messes cursor, reset it to default from main.cpl -> Pointers -> Use default
or Control Panel -> All Control Panel Items -> Mouse -> Pointers -> Use default
Thanks, Timo. Yes indeed, the text selection cursor gets affected. I've checked the BitBlts using this code:
sub esp, BITMAP
mov esi, esp
invoke GetCurrentObject, BeginPtDC, OBJ_BITMAP
.if Zero?
fdeb 1, "Bad object", $Err$()
.else
invoke GetObject, APs.apBitmap, BITMAP, esi
fdeb 4, "bm1", [esi.BITMAP].bmWidth, APs.apRectL.right, [esi.BITMAP].bmHeight, APs.apRectL.bottom
mov eax, [esi.BITMAP].bmWidth
sub eax, APs.apRectL.right
.if Sign?
fdeb 1, "Gotcha A", eax
.endif
invoke GetObject, APs.apBitmap2, BITMAP, esi
fdeb 4, "bm2", [esi.BITMAP].bmWidth, [esi.BITMAP].bmHeight
mov eax, [esi.BITMAP].bmWidth
sub eax, APs.apRectL.right
.if Sign?
fdeb 1, "Gotcha B", eax
.endif
.endif
add esp, BITMAP
pop edi
pop esi
invnz BitBlt, BeginPtDC, 0, 0, APs.apRectL.right, APs.apRectL.bottom, PtDC, 0, 0, SRCCOPY
All fine, the bitmaps are big enough :rolleyes:
The program doesn't render correctly for me on startup - just an icon-sized square in each panel's corner. Minimize-restore should cause a full repaint, but nothing appears to change.
Resizing the window provides some interesting clues: the 'icons' drawn in the corners appear to be bitmaps drawn from GDI memory; as the size of the window changes, the bitmap that is drawn walks through various system bitmaps/icons as if it were an image-list (they are drawn correctly and not at random offsets, so it's more likely they're indexed, or at least at some size-multiple offsets.)
Things to investigate:
- Check that you are doing a full repaint (clear the background with a non-null brush.)
- The corner-icon looks like some kind of corrupted index/offset value, so check all pushes & pops are balanced, also values in structures passed to drawing functions.
- Build a 100% new version (no copy-pasting!), starting with the absolute minimum, adding parts until the problem appears (or doesn't, because it was a stupid typo somewhere.)
Thanks a lot, Tedd. I will keep you posted.
Version 2 - one fat bug is fixed! Grateful for feedback on remaining problems.
Now it works in old Windows 7 :thumbsup:
Hi JJ
Unfortunately Win10 sees your exe as infected by a trojan. :undecided:
I got this when running
Biterider
so what was the issue that was causing the paint bug?
Hi jj2007,
I have an unusual behavior in the form of window teleportation :azn:
Thanks to everybody :smiley:
The 'fat' issue was a DeleteObject with a random argument: a local variable that should have been zero but was filled elsewhere with the width of the control. So DeleteObject, 300 (for example) deleted things owned by the system.
It works without crashes or duplicates now, see attachment - at least on Win7-64. On Win10 and on Win XP (!), some of the semi-transparent lines to not get painted; in addition, an invoke GetCurrentObject, DC, OBJ_BITMAP returns zero (on Win10 but not on Win7 or XP), but that seems not to affect the painting, so I guess (and it's no more than a guess right now) that Win7 has a default bitmap loaded while W10 and XP don't.
I have other multiple artifacts, from unusual white squares to full lamination :azn: the example is repeated every time you start, to see this, it is enough to switch the size of the internal windows, focus the mouse on the desktop, and re-activate the program window, continuing to resize the windows inside.
Does it make sense to use double buffering? During redrawing, I can observe quadratic flicker in the center of each of the inner windows.
Hi
V3 seems to work on Win10 (64). I did not get the artifacts described by LiaoMi on my machine.
Biterider
The graphics break down after a while and sometimes since launch, even if you don't touch the windows inside, changing only the main window, the picture looks a little different, but the imprint is obvious.
Thanks, LiaoMi and Biterider. It seems I need to take a thorough look at it again...
New version - the painting should work on Win10 and WinXP now :skrewy:
Quote from: jj2007 on June 03, 2019, 10:03:29 PM
New version - the painting should work on Win10 and WinXP now :skrewy:
Hi jj2007,
I know you hate me already :greensml:, I must say that the program works much better now, since distortions occur less frequently .. I notice that the error occurs when I switch focus to other programs .. and the first time during the start, a white square appears, sometimes, in this white square, I see my cursor on a black background..
Quote from: LiaoMi on June 03, 2019, 10:25:52 PMI know you hate me already :greensml:
No, I am really grateful for your testing :thumbsup:
At least now it paints the lines on Win10 and WinXP - on Win7-64, that always worked. Guess what was the error that caused ValueOverflow...? GdipDrawLinesI wants a fresh FPU, a simple fninit solved the problem. Obviously an undocumented "feature".
Here is version 4 - one more little glitch fixed.
Hi JJ
I could not see any glitches, but the console window shows the following when sizing the complete window.
Biterider
Thanks, Biterider - it's fixed in the previous post, version 4.
1. While the map is displayed, when the inner window is resized, flicker occurs, associated with moving the actual image to the upper left corner, so a complete redrawing is performed. I see three frames of resizing, the first resizing, in the second a window with a new size but the old picture, the third is the final transformation of the picture (after checking this effect is visible on all windows).
2. Sphere when resizing sticks on the mouse
3. At the first start and quickly changing the size, distortions appear
4. When you repeatedly resize the window, the yellow sphere disappears
The effect of the destruction of the picture is almost imperceptible, but it occurs after the black square is displayed in the corner of each of the mini windows. This black square on the left always displays the elements of an another window, depending on the focus of the mouse.
Thanks a lot, that will keep me busy for a while, I'm afraid... :sad:
Quote from: jj2007 on June 03, 2019, 11:39:58 PM
Thanks a lot, that will keep me busy for a while, I'm afraid... :sad:
I think it's all the consequences of a single error in the code, because everything works perfectly, but suddenly, after a noticeable failure, subsequent distortion occurs. Here is the new effect at the start, immediately after the start, I did not have time to do anything, duplicates were displayed at the moment when interacting with the cursor ... Probably some kind of confusion with handlers, because Your program can duplicate pictures of third-party applications.
Thanks a lot, LiaoMo :thup:
Version 5 - one more bug fixed, which was triggered by the tooltip that appears when hovering over the map, or clicking into a country. The culprit, btw, was a non-initialised local variable.
It works fine now on my Win7 and Win10 machines. Working memory is stable, no leaks. In the XP VM, the Chinese text is not displayed, otherwise it works even there. There is a bit of flicker when resizing the entire window, but that is unavoidable, it seems.
Hitting H activates the animated GIF. You may have to resize the window to see it. On WinXP only, if you size it to a very small width and the GIF is active, it will complain about a ValueOverflow. No such problem on Win7 and Win10.
Grateful for feedback.
Hi JJ
On my Win10/64 machine I didn't see any problems. Hitting "H" I got
QuoteinvRect
eax 1
$Err$() Der Vorgang wurde erfolgreich beendet.__
Rockphorr -1
invRect
eax 1
$Err$() Der Vorgang wurde erfolgreich beendet.__
Rockphorr 0
several times, but I don't know what it should mean...
Biterider
JJ,
In XP you may have to install the east asian fonts.
@BiteRider: just a remainder from debugging, everything OK
@Hutch: yes, but I don't care for the VM, it's just for verifying if my stuff is still running on XP
Thanks to everybody who helped me chase these bugs :thumbsup:
Not sure how it's supposed to be but
- animation only shows after mouseover.
- dragging left/up puts it behind the existing pic, dragging down/right puts it in front.
Quote from: jj2007 on June 08, 2019, 01:16:06 PM
Version 5 - one more bug fixed, which was triggered by the tooltip that appears when hovering over the map, or clicking into a country. The culprit, btw, was a non-initialised local variable.
It works fine now on my Win7 and Win10 machines. Working memory is stable, no leaks. In the XP VM, the Chinese text is not displayed, otherwise it works even there. There is a bit of flicker when resizing the entire window, but that is unavoidable, it seems.
Hitting H activates the animated GIF. You may have to resize the window to see it. On WinXP only, if you size it to a very small width and the GIF is active, it will complain about a ValueOverflow. No such problem on Win7 and Win10.
Grateful for feedback.
Hi jj2007,
now everything works as it should :azn: :thup:, looks very solid, but I have three little things ...
1. in the bottom right, on both sides the last digits go beyond the window (Image 1)
2. when resizing the window holding the lower right corner, the yellow sphere breaks its shape (despite the fact that the effect is temporary, but until the next drawing it remains to hang so - Image 2 )
3. If you change the size to the minimum square, then the window size handler is broken, it is expressed in the fact that if you try to grab the right side of the window, then the window will assume that you are holding the left side of the window, in this case, change the window to its original state is impossible (An example of a testing window can be seen in the picture - Image 3)
Except for the above, everything works just super! :thumbsup: :eusa_dance:
PS - Did you use GDI+?
Quote from: LiaoMi on June 08, 2019, 06:15:09 PMnow everything works as it should :azn: :thup:, looks very solid, but I have three little things ...
1. in the bottom right, on both sides the last digits go beyond the window (Image 1)
Right. Can be fixed manually (there is a "margins" argument), or I will have to check somehow how long the last number will be. But that would be an overkill :sad:
Quote2. when resizing the window holding the lower right corner, the yellow sphere breaks its shape (despite the fact that the effect is temporary, but until the next drawing it remains to hang so - Image 2 )
Yes indeed. Funny, but it happens only when you reduce the width to an extent that the graph itself becomes useless. Will see if a check is worth the effort.
Quote3. If you change the size to the minimum square, then the window size handler is broken, it is expressed in the fact that if you try to grab the right side of the window, then the window will assume that you are holding the left side of the window, in this case, change the window to its original state is impossible (An example of a testing window can be seen in the picture - Image 3)
That is because a control seems to have no minimum size, and the WS_THICKFRAME borders start overlapping in some sense. You can see only because I use the thickframe style here for testing, in a normal program one wouldn't use that style for a tiny control. The main window does not allow shrinking it so much.
QuoteExcept for the above, everything works just super! :thumbsup: :eusa_dance:
PS - Did you use GDI+?
Thanks :smiley:
And yes, that is Gdi+ for the plot lines and the sphere (the circle). The quality is so much better than the ragged lines of plain GDI. Transparency is a by-product, rarely useful, but with the beach background it looks quite ok.
Again, thanks to everybody - I will soon release a new version showing how to produce such a plot. For example:
GuiControl Emissions, "canvas", x333, w333, WS_THICKFRAME, h500 ; x333 means "x at 33.3% of width"
GuiControl TheMap, "canvas", x666, w333, h500, WS_THICKFRAME
.... code to load other controls ....
Event CanvasPaint
Switch_ ecx ; ID returned in ecx
Case_ Emissions
ArrayPlot RgbCol(100, 255, 100) ; init & set background
SetAxisX "Year", s 1880, d 5/10, grid 1, format "%i" ; s=start value, d=difference betw. gridlines, grid pen
SetAxisY "CO2 emissions", s 0.0, d 1000/2, grid 1, format "%i", peng hPenGrid
ArrayPlot gem(XY), RgbCol(255, 0, 0), lines=2, 00050401h ; plot the data, set line colour & size, margins xtrb
ArrayPlot exit, "CO2 emissions" ; finish with a title
Case_ TheMap
ArrayPlot RgbCol(204, 222, 255) ; init and set background colour
PaintMap RgbCol(127, 127, 127), lines=2 ; map with grey borders 2px thick
ArrayPlot exit, "Europe"
Endsw_The
gem(XY) that gets plotted is a REAL4 array read from a text file embedded in the resources with ID 110 via
StringToArray 110, gem() As REAL4, staHasText
The text file looks basically like this:
Year CO2 https://datahub.io/core/co2-fossil-global#resource-global
1880 236 Million metric tons of C
1881 243 http://cdiac.ess-dive.lbl.gov/ftp/ndp030/CSV-FILES/global.1751_2014.csv
1882 256
...
2008 8783
2009 8740
2010 9167 vv interpolated using EDGAR vv
2011 9437
2012 9556
2013 9722
2014 9845
2015 9843
2016 9879
2017 9994
QuoteAnd yes, that is Gdi+ for the plot lines and the sphere (the circle).
You can try to use
InterpolationMode, under the links below you can find an example and the algorithms of rendering, the example in CSharp language can also be applied to c++ ...
Custom AntiAliasing with GDI+ https://www.codeproject.com/Articles/9184/Custom-AntiAliasing-with-GDI (https://www.codeproject.com/Articles/9184/Custom-AntiAliasing-with-GDI)
Using Interpolation Mode to Control Image Quality During Scaling - https://docs.microsoft.com/en-us/windows/desktop/gdiplus/-gdiplus-using-interpolation-mode-to-control-image-quality-during-scaling-use (https://docs.microsoft.com/en-us/windows/desktop/gdiplus/-gdiplus-using-interpolation-mode-to-control-image-quality-during-scaling-use)
PixelBox: A PictureBox with configurable InterpolationMode - https://www.codeproject.com/Articles/717312/PixelBox-A-PictureBox-with-configurable-Interpolat (https://www.codeproject.com/Articles/717312/PixelBox-A-PictureBox-with-configurable-Interpolat)
Examples can be taken here - https://www.solidfiles.com/v/nGWzmr77QRy73 (https://www.solidfiles.com/v/nGWzmr77QRy73)
The Custom Antialiasing AlgorithmTo produce a higher quality image than native GDI+ antialiasing, I use the following algorithm.// Make a 4X offscreen bitmap, power of 2's are important because
// interpolating other size images takes significantly longer.
Bitmap offscreen = new Bitmap(bounds.Width*4, bounds.Height*4);
Graphics ofg = Graphics.FromImage(offscreen);
//Update transform for additional pixels
Matrix t = m.Clone();
t.Translate(-bounds.Left, -bounds.Top, MatrixOrder.Append);
t.Scale(4.0f, 4.0f, MatrixOrder.Append);
//Do Paint
Paint(ofg, t);
//Stretch blit the rendered image to the actual image
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(offscreen, bounds, 0, 0, offscreen.Width, offscreen.Height,
GraphicsUnit.Pixel);
1. Construct an off-screen bitmap that is 2, 4 or 8 times larger that the image I intend to output. It is important to use a power of 2 for the offscreen bitmap.
2. Draw the vector images scaled appropriately for the larger offscreen bitmap.
3. Use Graphics.DrawImage with InterpolationMode set to HighQualityBicubic when stretch bliting the image to the smaller value.;--------------------------------------------------------------------------
; Interpolation modes
;--------------------------------------------------------------------------
InterpolationMode TYPEDEF DWORD ;enum
;InterpolationMode UNION DEFALIGNMASM
InterpolationModeInvalid EQU <QualityModeInvalid >
InterpolationModeDefault EQU <QualityModeDefault >
InterpolationModeLowQuality EQU <QualityModeLow >
InterpolationModeHighQuality EQU <QualityModeHigh >
InterpolationModeBilinear EQU <0H>
InterpolationModeBicubic EQU <01H>
InterpolationModeNearestNeighbor EQU <02H>
InterpolationModeHighQualityBilinear EQU <03H>
InterpolationModeHighQualityBicubic EQU <04H>
;InterpolationMode ENDS
;API
GdipSetInterpolationMode PROTO graphics:XMASM ,interpolationMode:DWORD
;API
GdipGetInterpolationMode PROTO graphics:XMASM ,interpolationMode:XMASM
;API
Another similar topic ... http://www.asmcommunity.net/forums/topic/?id=20654 (http://www.asmcommunity.net/forums/topic/?id=20654) with
invoke GdipSetInterpolationMode,grafico,InterpolationModeHighQualityBilinear ; equ 6 I am working on a program that loads jpeg's pictures and display then in a static control which works fine, but I need to create a resized second picture so you can view it a control and the control doesn't have to resize to the full size of the picture. I found acouple of samples but they are all in .NET, C++ which I don't know how to use, so here is the code i have!
; Create VB Picture box to draw imagen later On
INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,addr StaticClass, NULL,SS_BITMAP or WS_CHILD or WS_VISIBLE,\
10, 50, 350,350, hWnd, NULL, hInstance, NULL
; Save Control handle for later use
mov hImageTestL,eax
; Convert Image Filename to Wide character other wise it will return error
invoke MultiByteToWideChar,CP_OEMCP,MB_PRECOMPOSED,addr NombreArchivo,-1,addr NombreW,255
; Load image from file and save bitmap to imagen1
invoke GdipLoadImageFromFile,ADDR NombreW,ADDR imagen1
; Get original image pixel format (usually 32 Bit color) and save it to lFormat
invoke GdipGetImagePixelFormat,imagen1,addr lFormat
; Get original image Width and save it to sngWidth
invoke GdipGetImageWidth,imagen1,addr sngWidth
; Get original image Height and save it to sngHeight
invoke GdipGetImageHeight,imagen1,addr sngHeight
; Set W variable to 400 (pixels) this would be new picture width
mov W,400
; Set H variable to 400 (pixels) this would be new picture height
mov H,400
; C++ Bitmap::Bitmap(width, height, format) Create new bitmap with widht and height just set and same pixel format as the original image and save it to imagen2
invoke GdipCreateBitmapFromScan0,W,H,0,lFormat,0,addr imagen2
; Set graphic interpolation mode to high quality output
; Shrink the image using low-quality interpolation.(InterpolationModeNearestNeighbor)
; Shrink the image using medium-quality interpolation. (InterpolationModeHighQualityBilinear)
; Shrink the image using high-quality interpolation. (InterpolationModeHighQualityBicubic)
invoke GdipSetInterpolationMode,grafico,InterpolationModeHighQualityBilinear ; equ 6
; Get original image Horizontal resolution and save it to HorRes variable
invoke GdipGetImageHorizontalResolution,imagen1,addr HorRes
; Get original image Vertical resolution and save it to VerRes variable
invoke GdipGetImageVerticalResolution,imagen1,addr VerRes
; Set new image vertical and horizontal resolution to match orignal image resolution
invoke GdipBitmapSetResolution,imagen2,HorRes,VerRes
; Create new graphics object from new image
invoke GdipGetImageGraphicsContext,imagen2,addr grafico
; RGB 0,0,0
; Set image background to Black color
invoke GdipGraphicsClear,grafico,0
; Draw resized original image to graphic object of new bitmap
invoke GdipDrawImageRectI,grafico,imagen1,0,0,W,H
; Destroy orignal image
invoke GdipDisposeImage,imagen1
; Delete new image graphic object
invoke GdipDeleteGraphics,grafico
; Create standard GDI Bitmap from Gdi+ Bitmap and save bitmap handle in hBitmap variable
; If you want to rotate image use:
;invoke GdipImageRotateFlip,imagen2,Rotate90FlipNone
invoke GdipCreateHBITMAPFromBitmap,imagen2,addr hBitmap,0
; Set VB Picture box control image to our new resized image
invoke SendMessage,hImageTestL,STM_SETIMAGE,IMAGE_BITMAP,hBitmap
InterpolationMode takes graphics to a new level :thup:
:eusa_boohoo: to test the interpolation method, I suggest using the example below, you can even try variations of the interpolation mapping, as it is done in the example with CSharp, the display quality of the custom algorithm will be many times better. Simple lines should look better as in the examples above. It remains to add interpolation methods ...
jj2007
last note, when I maximize the window, the yellow circle disappears (program start -> maximize window -> circle disappeared)
PS
fascinating example :rolleyes:
gdiplus_doublebuffer.zip
Hi LiaoMi,
Attached my version of the "gangster" - honestly, I don't see a big difference...
GuiParas equ "Hello jj2007", x680, w680, h740, m0, bnone
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl Shooter, "canvas"
Event CanvasPaint
invoke GetClientRect, hShooter, addr rc_
invoke FillRect, PtDC, addr rc_, rv(GetStockObject, BLACK_BRUSH)
GuiImage 100, fit
GuiEnd
(http://www.jj2007.eu/images/Shooters.jpg)
:biggrin: I also dont see, because the example has not yet been modified by the technique - The Custom Antialiasing Algorithm, but this example can be taken as a basis for testing ... "gangster" - This is not a ready-made example!
The difference will be noticeable :azn:
Picture example ...
InterpolationMode.Low
(https://www.codeproject.com/KB/miscctrl/717312/InterpolationMode.Low.png)
InterpolationMode.HighQualityBilinear
(https://www.codeproject.com/KB/miscctrl/717312/InterpolationMode.HighQualityBilinear.png)
InterpolationMode.HighQualityBicubic
(https://www.codeproject.com/KB/miscctrl/717312/InterpolationMode.HighQualityBicubic.png)
Vector graphics example
GDI+NoAntiAlias - GDI+AntiAlias - GDI+CustomAntiAlias
(https://i.imgur.com/zCPZpik.png) (https://i.imgur.com/UJvLTMq.png) (https://i.imgur.com/IkPlTBR.png)
the result is obvious, the custom algorithm is perfect, almost like maсOS graphics :biggrin:
It definitely looks good :thumbsup:
Attached is one more version of my plot program, with a handful of minor changes. Inter alia, I added a statusbar which shows the name of the country when you click into the map. Source of the handler:
Event Message
If_ uMsg_==WM_MAPCLICKED && MapRegion>=0 Then SetWin$ hSBar="You clicked on "+MapRegion$
With the GSL interface, it can handle also plots of Bessel lines:
(http://www.jj2007.eu/images/BesselPlot.png)
Source: gsl double gsl_sf_bessel_J0(double x)
gsl double gsl_sf_bessel_Jn (int n, double x)
gsl_INIT
Dim Bessel0() As REAL8
Dim Bessel1() As REAL8
Dim Bessel2() As REAL8
xor ecx, ecx ; array index
SetGlobals fct:REAL8
For_ fct=-10.0 To 40.0 Step 0.02
SetFloat Bessel0(ecx)=gsl_sf_bessel_J0(fct)
SetFloat Bessel1(ecx)=gsl_sf_bessel_Jn(1, fct)
SetFloat Bessel2(ecx)=gsl_sf_bessel_Jn(-3, fct)
inc ecx
Next
GuiControl Bessel, "canvas"
Event CanvasPaint
ArrayPlot RgbCol(240, 240, 240) ; init with window (or control) handle and background colour
ArrayPlot Bessel0(), RgbCol(255, 255, 222, 222), bars=1, 02020202h ; red; transparency!
ArrayPlot Bessel0(), RgbCol(100, 255, 0, 0), lines=2 ; red lines
ArrayPlot Bessel1(), RgbCol(255, 0, 255, 0), lines=2 ; green opaque lines
ArrayPlot Bessel2(), RgbCol(100, 0, 0, 255), 0 ; blue dots
ArrayPlot exit, 0300000032#T "GSL: Regular cylindrical Bessel functions" ; finish with a title
An example of the anti-aliasing taken from the Bessel plot - it works much better for lines than for a line of dots:
(http://www.jj2007.eu/images/AntiAliasing.png)
Here is what the attached proggie should show. If it doesn't, let me know :badgrin:
(http://www.jj2007.eu/images/Plot6.png)
Hi JJ
There are still some problems. When opening the application. it complains about a missing "clouds.jpg" file. When stretching the plots horizontally, the last tick of the X-axis falls too far away from the axis.
Biterider
Hi jj2007,
1. Image 1 - the bottom text is moved to the middle when the window is maximized.
2. Image 2 - the yellow circle disappears when the window is maximized.
3. Image 3 - picture not found + oddities when opening the first chart.
4. Image 3 - the second graph shows the dates, after some time they disappear.
5. Image 5 + Image 7 - Something strange is happening with the background image in two cases, when hovering the mouse and maximizing the window size.
6. Image 6 - old oval shift effect.
QuoteAn example of the anti-aliasing taken from the Bessel plot - it works much better for lines than for a line of dots:
What kind of anti-aliasing was used?
On the comparison above was used -
Custom Antialiasing AlgorithmThe Custom Antialiasing Algorithm
1. Construct an off-screen bitmap that is 2, 4 or 8 times larger that the image I intend to output. It is important to use a power of 2 for the offscreen bitmap.
2. Draw the vector images scaled appropriately for the larger offscreen bitmap.
3. Use Graphics.DrawImage with InterpolationMode set to HighQualityBicubic when stretch bliting the image to the smaller value.
The technique Custom Antialiasing above should process points, lines, pictures with equally high quality.
Left Std - Right Custom (You can see soft geometric smoothing in the picture) :thup:
(https://i.imgur.com/ke2ebLp.png)
Quote from: Biterider on June 10, 2019, 03:59:23 PMWhen opening the application. it complains about a missing "clouds.jpg" file. When stretching the plots horizontally, the last tick of the X-axis falls too far away from the axis.
Oops, I forgot that Clouds.jpg was a local file. It's now embedded in the rc section, see new attachment above. Re stretching, yes, there may be glitches, but usually such graphs are optimised for one size anyway. The margins can be adjusted manually if needed.
Quote from: LiaoMi on June 10, 2019, 08:14:21 PM
1. Image 1 - the bottom text is moved to the middle when the window is maximized.
2. Image 2 - the yellow circle disappears when the window is maximized.
3. Image 3 - picture not found + oddities when opening the first chart.
4. Image 3 - the second graph shows the dates, after some time they disappear.
5. Image 5 + Image 7 - Something strange is happening with the background image in two cases, when hovering the mouse and maximizing the window size.
6. Image 6 - old oval shift effect.
1: yes, it's at a fixed offset; normally not a problem because it should be on top, and centered by default.
2: I noticed that on Win10, too. Very odd.
3: see new attachment above
4: you mean the date in the statusbar? That is by design
5: this is indeed odd, thanks for pointing it out; it looks ok when sizing the entire window, though.
6: works on Win7, but I'll what I can do.
Thanks again :thup:
QuoteQuoteAn example of the anti-aliasing taken from the Bessel plot - it works much better for lines than for a line of dots:
What kind of anti-aliasing was used?
gdi+ GdipSetSmoothingMode, GraphObj, SmoothingModeHighQuality
I am not against better anti-aliasing techniques, but I don't want third party libraries. Also, reserving a fat bitmap for StretchBlt'ing it down is not my favourite approach, I like to keep it small and light. However, if you have a magic procedure that smoothes a Gdi+ bitmap and can be added easily, it would be interesting.
Quote from: jj2007 on June 10, 2019, 08:47:58 PM
gdi+ GdipSetSmoothingMode, GraphObj, SmoothingModeHighQuality
I am not against better anti-aliasing techniques, but I don't want third party libraries. Also, reserving a fat bitmap for StretchBlt'ing it down is not my favourite approach, I like to keep it small and light. However, if you have a magic procedure that smoothes a Gdi+ bitmap and can be added easily, it would be interesting.
:thumbsup:
GdipSetSmoothingMode great technique, have you tried other options - SmoothingModeAntiAlias8x8? Instead SmoothingModeHighQuality ...
GdipSetSmoothingMode hGraphics, SmoothingModeAntiAlias8x8
typedef enum SmoothingMode {
SmoothingModeInvalid,
SmoothingModeDefault,
SmoothingModeHighSpeed,
SmoothingModeHighQuality,
SmoothingModeNone,
SmoothingModeAntiAlias,
SmoothingModeAntiAlias8x4,
SmoothingModeAntiAlias8x8
} ;
SmoothingMode Enumeration https://docs.microsoft.com/en-us/windows/desktop/api/gdiplusenums/ne-gdiplusenums-smoothingmode (https://docs.microsoft.com/en-us/windows/desktop/api/gdiplusenums/ne-gdiplusenums-smoothingmode)
I understand you very well, but for graceful graphics you can lose a bit in speed :azn:, this is done in mobile phone applications.
GDI+AntiAlias - 0.021s
GDI+CustomAntiAlias - 0.151s (average speed 7 times slower - considering that the displayed number of points is more than 10,000, on small sizes it may even be imperceptible)
In any case, this option can be simply discussed ... what kind of additional libraries do you mean? All functions are related to GDI plus standard .. no third party libraries should be used or did i miss something?
QuoteHowever, if you have a magic procedure that smoothes a Gdi+ bitmap and can be added easily, it would be interesting.
Does not fit to the role of a magical procedure, but I found this example (pure assembler source code) ... The example produces the same logic with a simple picture, where the picture is large and should be reduced in size, using interpolation technique.
In the vector example, we create an enlarged image, and then compress it in this way. At the same time receiving very high quality!
If you use two methods (SmoothingModeAntiAlias8x8 + interpolation) at once, it may be cool at all, usually both methods are used simultaneously
GdipCreateFromHDC(Tmp.DC, Context);
GdipSetSmoothingMode(Context, SmoothingModeAntiAlias8x8);
GdipSetCompositingMode(Context, CompositingModeSourceCopy);
GdipSetInterpolationMode(Context, InterpolationModeHighQualityBicubic);
This property is still active :arrow_down:
Quote3. If you change the size to the minimum square, then the window size handler is broken, it is expressed in the fact that if you try to grab the right side of the window, then the window will assume that you are holding the left side of the window, in this case, change the window to its original state is impossible
If you change the size of the first chart window, then when you hover the mouse on the third window, the picture changes to the same size as in the first window :skrewy: (image 1 + image 2)
Both problems should be solved now, please try again :thup:
SmoothingModeAntiAlias8x8 sounds nice, but I never saw a difference. Perhaps in Gdi+ 1.1, but how to get it to work?
Quote from: jj2007 on June 10, 2019, 11:59:44 PM
Both problems should be solved now, please try again :thup:
SmoothingModeAntiAlias8x8 sounds nice, but I never saw a difference. Perhaps in Gdi+ 1.1, but how to get it to work?
8th version works great! :thumbsup: Now we can write programs for forex exchanges :eusa_dance:
invoke GdipCreateFromHDC,[ps.hdc],hGraphics
invoke GdipSetSmoothingMode,hGraphics,SmoothingModeAntiAlias8x8
invoke GdipGraphicsClear,hGraphics,0ffffffffh
invoke GdipDrawEllipseI,hGraphics,hPen,100,100,200,200
invoke GdipDeleteGraphics,hGraphics
You are right there are problems with the version ... But who in our time uses the old version of Gdiplus? I'll try to use a newer version .. Below you can download an interesting example of a clock :biggrin:
QuoteSmoothingMode TYPEDEF DWORD ;enum
;SmoothingMode UNION DEFALIGNMASM
SmoothingModeInvalid EQU <QualityModeInvalid >
SmoothingModeDefault EQU <QualityModeDefault >
SmoothingModeHighSpeed EQU <QualityModeLow >
SmoothingModeHighQuality EQU <QualityModeHigh >
SmoothingModeNone EQU <0H>
SmoothingModeAntiAlias EQU <01H>
IF ( GDIPVER GE 00110h)
SmoothingModeAntiAlias8x4 EQU <SmoothingModeAntiAlias >
SmoothingModeAntiAlias8x8 EQU <02H> ;(GDIPVER >= 0x0110)
ENDIF
;SmoothingMode ENDS
Some time ago I tried to use a newer gdi+ version but no luck. With a proper manifest, it should load. However, apparently nobody ever succeeded in making it work, see e.g. Is SmoothingModeAntiAlias8x8 available? (https://microsoft.public.win32.programmer.gdi.narkive.com/g0IwVpQC/is-smoothingmodeantialias8x8-available) (yes it is, see replies further down)
Quote from: jj2007 on June 11, 2019, 01:54:17 AM
Some time ago I tried to use a newer gdi+ version but no luck. With a proper manifest, it should load. However, apparently nobody ever succeeded in making it work, see e.g. Is SmoothingModeAntiAlias8x8 available? (https://microsoft.public.win32.programmer.gdi.narkive.com/g0IwVpQC/is-smoothingmodeantialias8x8-available)
P.S.: GOTCHA! See attachment. Press Q repeatedly to see various smoothing modes. There is a tiny difference between 8x4 and 8x8, visible in particular in the lower right corner control :tongue:
:biggrin: You revealed a secret! :thumbsup: The difference is almost invisible, I also made an example ...
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32"
name="Microsoft.Windows.GdiPlus"
processorArchitecture="*"
version="1.1.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"/>
</dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates app support for Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!--The ID below indicates app support for Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--The ID below indicates app support for Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!--The ID below indicates app support for Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!--The ID below indicates app support for Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>
+
GDIPVER equ 0x0110
include C:\masm64\VS2017\include_x86_x64\translate32.inc
include C:\masm64\sdkrc100\um\windows.inc
include C:\masm64\sdkrc100\um\gdiplusinit.inc
include C:\masm64\sdkrc100\um\gdiplusflat.inc
include C:\masm64\sdkrc100\um\gdiplusenums.inc
include C:\masm64\sdkrc100\um\CommCtrl.inc
includelib gdiplus.lib
includelib user32.lib
includelib kernel32.lib
includelib ComCtl32.lib
+
invoke GdipSetSmoothingMode, hGraphics, SmoothingModeAntiAlias8x8;SmoothingModeAntiAlias8x8;SmoothingModeHighQuality
invoke GdipSetInterpolationMode,hGraphics,InterpolationModeHighQualityBicubic
In my case, the difference is completely invisible, where api dont return errors ... The project can be downloaded below and as a result, we can achieve perfect smoothing with tricks only, one of which is a custom anti-aliasing option, which is not suitable due to slow speed. I do not know other tricks, but I will finish the custom version :skrewy:
That is one of the first good clocks I have seen. :thumbsup:
Just for fun, I added another test: Press I for interpolation mode, Q for quality, and H for haha
When going from 8x4 to 8x8, watch the upper part of the blue dot in the upper left corner control.
Btw Gdi+ version 1.1.0.0 gets loaded on Win7-64 independently of the manifest.
:biggrin: :biggrin: :biggrin:
I'm going crazy about the smoothing technique in GDI, I present to your attention another technique ..
Xiaolin Wu's line algorithm -
https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithmAnti-aliased Line | Xiaolin Wu's algorithm https://www.geeksforgeeks.org/anti-aliased-line-xiaolin-wus-algorithm/ (https://www.geeksforgeeks.org/anti-aliased-line-xiaolin-wus-algorithm/) (There are many other algorithms on the site with examples and descriptions - the site is very good)
lib files for project, no dependency on external libraries ...
SFML 2.5.1 https://www.sfml-dev.org/download/sfml/2.5.1/ (https://www.sfml-dev.org/download/sfml/2.5.1/)
The example demonstrates the line algorithm, but besides that I attached an algorithm for circles (Xiaolin Wu's ANTI-ALIASED CIRCLE GENERATION.pdf) ... The release folder contains the executable file, to draw the lines you need to click on the mouse.
Xiaolin Wu's ANTI-ALIASED CIRCLE GENERATION - https://www.solidfiles.com/v/gnwB4PnvKBngV (https://www.solidfiles.com/v/gnwB4PnvKBngV)
QuoteThat is one of the first good clocks I have seen. :thumbsup:
:biggrin: :thup:
It's time to look at the source - 40 lines of code :smiley: (http://masm32.com/board/index.php?topic=7722.msg86674#msg86674)
Quote from: jj2007 on June 11, 2019, 06:29:06 PM
It's time to look at the source - 40 lines of code :smiley: (http://masm32.com/board/index.php?topic=7722.msg86674#msg86674)
:thumbsup: looks great!
We continue the epic with anti-aliasing :tongue:
NVIDIA
DLSS AI-Powered Anti-Aliasing In Action For Great Visuals And Performance https://www.youtube.com/watch?v=x-mVK3mj_xk (https://www.youtube.com/watch?v=x-mVK3mj_xk)
:arrow_right: There is an AI-example (
cuda neural network.zip) on the forum which should define letters, what if instead of letters, use limited geometric space ?! For use in adjusting the smoothing pattern ... :icon_idea:
DLSS, Is it Upscaling, Super Sampling, or Anti Aliasing?? - https://www.reddit.com/r/nvidia/comments/9a55pk/dlss_is_it_upscaling_super_sampling_or_anti/ (https://www.reddit.com/r/nvidia/comments/9a55pk/dlss_is_it_upscaling_super_sampling_or_anti/)
NVIDIA researchers Marco Salvi and Anjul Patney trained a neural network to recognize these artifacts and replace those pixels with smooth anti-aliased pixels. The AI-based technology produces sharper images than existing algorithms.
(https://blogs.nvidia.com/wp-content/uploads/2017/07/ai-antialiasing.png)
The left inset shows an aliased image that is jaggy and pixelated. NVIDIA's AI anti-aliasing algorithm produced the larger image and inset on the right by learning the mapping from aliased to anti-aliased images. Image courtesy of Epic Games.Nvidia DLSS: An Early Investigation Deep Learning Super-Sampling - https://www.techspot.com/article/1712-nvidia-dlss/ (https://www.techspot.com/article/1712-nvidia-dlss/)
Nvidia DLSS analysis: how AI tech can make PC games run 40 per cent faster - https://www.eurogamer.net/articles/digitalfoundry-2018-dlss-turing-tech-analysis (https://www.eurogamer.net/articles/digitalfoundry-2018-dlss-turing-tech-analysis)
:arrow_right: The clock example can be combined with the example of Xiaolin.zip, in this way we can compare the implementation of the clock in different ways ... I think a very interesting idea! :icon_idea:
Xiaolin Wu circle algorithm renders circle with holes inside https://stackoverflow.com/questions/54594822/xiaolin-wu-circle-algorithm-renders-circle-with-holes-inside (https://stackoverflow.com/questions/54594822/xiaolin-wu-circle-algorithm-renders-circle-with-holes-inside)
Anti-Aliased Curve Algorithms (Java Source Code) - http://www.landkey.net/d/antialiased/wu4_RF/ (http://www.landkey.net/d/antialiased/wu4_RF/)
1. "Wu-style" circle anti-aliased algorithm. Source. Demo.
2. "Linear-constraint" circle algoritm. Source. Demo.
3. Implicit curve anti-aliased algorithm. Draft. Source. Concept-Demo.
Fast, Antialiased Circles and Ellipses from Xiaolin Wu's concepts - https://yellowsplash.wordpress.com/2009/10/23/fast-antialiased-circles-and-ellipses-from-xiaolin-wus-concepts/ (https://yellowsplash.wordpress.com/2009/10/23/fast-antialiased-circles-and-ellipses-from-xiaolin-wus-concepts/)
(https://yellowsplash.files.wordpress.com/2009/10/ellipses.png)
C# implementation Bresenham and Xiaolin wu's algorithms - https://github.com/nejcgalof/Rasterization (https://github.com/nejcgalof/Rasterization)
Quote from: jj2007 on June 11, 2019, 08:05:40 AM
Just for fun, I added another test: Press I for interpolation mode, Q for quality, and H for haha
When going from 8x4 to 8x8, watch the upper part of the blue dot in the upper left corner control.
Btw Gdi+ version 1.1.0.0 gets loaded on Win7-64 independently of the manifest.
Hi jj2007,
everything is clear with anti-aliasing now ... now interpolation method .. it seems to me that I did not correctly use the interpolation technique, description from the documentation:
The InterpolationMode enumeration specifies the algorithm that is used when images are scaled or rotated. This enumeration is used by the Graphics::GetInterpolationMode and Graphics::SetInterpolationMode methods of the Graphics class.
InterpolationMode Enumeration https://docs.microsoft.com/en-us/windows/desktop/api/gdiplusenums/ne-gdiplusenums-interpolationmode (https://docs.microsoft.com/en-us/windows/desktop/api/gdiplusenums/ne-gdiplusenums-interpolationmode)
PlotMyDataV9.zip - I tested the interpolation method and could not see the difference in the picture, when I press the letter "I" and watch the clouds change, nothing happens ... this method depends on the implementation. The example (GDIPlus_GdipSetInterpolationMode.zip) on page three correctly demonstrates the interpolation technique. If you read a picture from a resource file, and then you change the size of the picture, then at this moment the interpolation method should work. I think the clouds should be smoothed, it all depends on how you redraw each graphic, whether vector graphics are processed with a picture or separately. Two options come to mind, the method should be applied to the image, or to the finished drawn graphics, this is clearly logically incorrect. Therefore, in your case, the method can only be applied to images, where for vector graphics it is necessary to create a custom GDI method, otherwise there is no size transformation. Maybe I still dont know something about the interpolation method, but my thoughts come to this conclusion.
:arrow_right:
Another opportunity for a new kind of graphics .. :icon_idea: - theoretically, the interpolation method can be used to plot the time frequency diagrams
Time–frequency analysis - https://en.wikipedia.org/wiki/Time%E2%80%93frequency_analysis (https://en.wikipedia.org/wiki/Time%E2%80%93frequency_analysis)
(https://neuroimage.usc.edu/forums/uploads/default/original/1X/85d3cc9a5a3c9c9b9249637f7c0c9cda63e76459.png)
(https://i.imgur.com/qZziUyC.png)
(https://i.imgur.com/JeegIDM.png)
Interpolation - https://en.wikipedia.org/wiki/Interpolation (https://en.wikipedia.org/wiki/Interpolation)
(https://i.imgur.com/GJKCxjY.png)
(https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Comparison_of_1D_and_2D_interpolation.svg/512px-Comparison_of_1D_and_2D_interpolation.svg.png)
Very interesting thread,so maybe you could draw faster and rougher and apply hardware accelerated supersmooth antialias?
Also has some kind of paintbug,maybe handle all kinds of messages and first repaint when dragging windows
Hi,
going through all the smoothing options, here are the main techniques that I discovered:
1. Neural network based anti-aliasing - the main goal is speed optimization while improving quality
2. Manual rendering algorithms to optimize the smoothing, the pixels are drawn by hand.
3. A technique that uses image scaling, partially used in neural networks, the main disadvantage is massive memory usage and delay in drawing. For quick work, a compromise is required between the combination of the neural network and the size of the picture.
4. Windows built-in methods
5. Combination of several methods at once.
A couple more implementations:
Scanline edge-flag algorithm for antialiasing - http://mlab.uiah.fi/~kkallio/antialiasing/ (http://mlab.uiah.fi/~kkallio/antialiasing/)
Intel AVX Realization of Lanczos Interpolation in Intel IPP 2D Resize Transform - https://software.intel.com/sites/default/files/m/d/4/1/d/8/Intel_AVX_Realization_of_Lanczos_Interpolation_in_Intel_IPP_2D_Resize_Transform_WP.pdf (https://software.intel.com/sites/default/files/m/d/4/1/d/8/Intel_AVX_Realization_of_Lanczos_Interpolation_in_Intel_IPP_2D_Resize_Transform_WP.pdf)
I decided to try "Lanczos Interpolation" method, how can I effectively replace the _mm256_permute2_ps instructions ?!
XOP instruction set
VPERMIL2PS Permute Two-Source Single-Precision Floating-Point
Opcode/Instruction - VEX.NDS.256.66.0F3A.W1 48 /r /is4
VPERMIL2PS ymm1, ymm2, ymm3,ymm4/m256, imz2
Description - Permute single-precision floatingpoint values in ymm2 and ymm3 using controls from ymm4/mem,
the results are stored in ymm1 with selective zero-match controls.
Recent Intel(R) AVX Architectural Changes - Removed: VPERMIL2PS and VPERMIL2PD The compiler does not support the VPERMIL2PD and VPERMIL2PS instructions in the assembler.
https://software.intel.com/en-us/forums/intel-isa-extensions/topic/283576 (https://software.intel.com/en-us/forums/intel-isa-extensions/topic/283576)
IIRC vpermil2ps (_mm256_permute2_ps) was removed from the AVX specs at the same time than FMA4 was replaced by FMA3, vpermil2ps is now part of AMD's XOP (to be featured inupcoming Bulldozer products along FMA4), AFAIK no Intel CPU has been announced with support for it, though it looks like you want to shift values between the 2 128-bit lanes and I'm afraid there isn't any fast option available in standard AVX, yet