nanovg for plugin uis

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Report from the OpenGL front:

I'm sort of off OpenGL again for now. Reasons:
1. I'm using NanoVG and the anti-aliasing is terrible. My wave drawings keep poking outside of their bounding boxes. If I turn off AA, then they are well-behaved, but ugly. Line drawings are not solid, but are made of variegated hues from the actual color to black.
2. As with #1, fonts look awful unless I resize to 150% or more. And even then...
3. I cannot resize my GUI on the fly. This is deep inside PUGL and I'd need to almost completely rewrite it since deep hacks are not working, but this may just be me.
4. PUGL support on the Mac side was slow, buggy and incomplete. I had to redo all of the messaging. It only supports Cocoa views, so 32-bit support does not improve.
5. Windows native support of OGL only goes up to v1.2(?), but not the 2.x needed for NanoVG. As far as I can tell, third-party drivers are required, or GLEW, which is not integrated at all and I'm not interested in chasing it down.

Overall, the OGL look and feel is not as elegant as the native (Cocoa) l&f and not to a level where I would feel comfortable releasing it.
I started on Logic 5 with a PowerBook G4 550Mhz. I now have a MacBook Air M1 and it's ~165x faster! So, why is my music not proportionally better? :(

Post

interesting, thanks for the report. I haven't really got round to trying NanoVG on windows yet, but I have been getting good results on mac with the metal backend.

if I were you I'd relish the opportunity to forget about carbon :-) that's what I'm doing

With the new version of IPlug/IGraphics you can switch between Cairo/NanoVG/AGG.

https://github.com/olilarkin/wdl-ol/tree/iplugquake

Post

Here are the screenshots of Cocoa vs OpenGL. You can see why I'm not happy. :hihi:
Screen Shot 2018-03-21 at 2.06.27 PM.png
Screen Shot 2018-03-21 at 2.06.43 PM.png
You do not have the required permissions to view the files attached to this post.
I started on Logic 5 with a PowerBook G4 550Mhz. I now have a MacBook Air M1 and it's ~165x faster! So, why is my music not proportionally better? :(

Post

syntonica wrote:Here are the screenshots of Cocoa vs OpenGL. You can see why I'm not happy. :hihi:
This doesn't appear to be a fair comparison though: the Cocoa rendering is at double the resolution (or rather the OpenGL image has 2x2 pixels), which suggest that you are on retina-display and not running the OpenGL at native backing scale (which you need to add a flag for if you create your own OpenGL views). It's pretty easy to look a lot better when you have twice the pixel resolution, don't you think? :)

I'm not really going to argue the main point that getting decent quality out of OpenGL is "problematic" for various reasons, but the difference isn't quite as bad as you're making it seem. :D

ps. your font-size is also different and the magnitude of the difference suggests that you're probably specifying point-size for Cocoa and pixels-size for OpenGL; normally displays are treated as about 96dpi (or 192dpi for retina if you're working with native pixels) and a "point" is 1/72th of an inch, so in order to convert from points to pixels you want to scale by 96/72 (=4/3). At these point-sizes that's going to make a surprisingly large difference.

pps. It should be noted that stb_truetype (which I guess is what nanovg is probably using here) doesn't do any hinting, so it tends to look pretty fuzzy at low pixels sizes where at least vertical grid fitting is kinda good idea... but really if it was rendering as retina and with the same font-size to begin with, the fonts would probably look quite fine here. ;)

Post

mystran wrote: This doesn't appear to be a fair comparison though: the Cocoa rendering is at double the resolution (or rather the OpenGL image has 2x2 pixels), which suggest that you are on retina-display and not running the OpenGL at native backing scale (which you need to add a flag for if you create your own OpenGL views). It's pretty easy to look a lot better when you have twice the pixel resolution, don't you think? :)

I'm not really going to argue the main point that getting decent quality out of OpenGL is "problematic" for various reasons, but the difference isn't quite as bad as you're making it seem. :D

ps. your font-size is also different and the magnitude of the difference suggests that you're probably specifying point-size for Cocoa and pixels-size for OpenGL; normally displays are treated as about 96dpi (or 192dpi for retina if you're working with native pixels) and a "point" is 1/72th of an inch, so in order to convert from points to pixels you want to scale by 96/72 (=4/3). At these point-sizes that's going to make a surprisingly large difference.

pps. It should be noted that stb_truetype (which I guess is what nanovg is probably using here) doesn't do any hinting, so it tends to look pretty fuzzy at low pixels sizes where at least vertical grid fitting is kinda good idea... but really if it was rendering as retina and with the same font-size to begin with, the fonts would probably look quite fine here. ;)
To me, they look stone cold sober vs a fifth of your favorite brown liquor. You can see the waves slopping out of their boxes due to AA, which I've since fixed by scaling the height by .9. Not sure what to do about the white borders that aren't so white.

My font sizes are identical! The GUI code is the same. And as for HDPI, I've looked at it from my end, the Cocoa OpenGL View end and from the OGL end. I can't make it look any better except by upscaling the actual plugin size to 125% or higher. But even at 200%, the fonts are still a little fuzzy...

Maybe I should get a stick and poke at the AA code?
I started on Logic 5 with a PowerBook G4 550Mhz. I now have a MacBook Air M1 and it's ~165x faster! So, why is my music not proportionally better? :(

Post

In my experience the only way to get good AA is to use either super-sampling or MSAA. The problem is that most GPUs just don't support enough MSAA to get good looking results (eg. 16x is probably just about the minimum worth even thinking about). So you end up with these libraries that try to fake it by using some sort of feathering and while that works fine for simple convex shapes, it just makes a mess out of anything more complex (most notably stroked curves).

I think even Skia still renders coverage masks on the CPU (at least if NVpath is not available) and just uploads those as textures to then perform shading/composition on the GPU. The thing is, high quality coverage calculation actually takes a whole lot less computation if you can perform it using a serial algorithm (which .. GPUs are terrible at).

But hey... it's a "graphics" card, it has to be good for 2D as well, right?

Post

I can't say I share any of your experience with unpleasant rendering with nanovg. I would post some screenshots but I haven't got text rendering to show yet.

check out VCVRack - that doesn't have such unpleasantness

on mac I am using MetalNanoVG which seems to work very well. I haven't had to do any faffing around with opengl contexts etc. It just works seamlessly, pretty much like it were an NSView.

https://github.com/ollix/MetalNanoVG

https://github.com/olilarkin/wdl-ol/blo ... ew.mm#L222

Post

I just did a quick test. The font looks bad because the font IS bad! A different sans font looked fine-ish... Weird. :roll: :lol:

I will wait for IPlug to stabilise before I move over (if I can). I handle all my own GUI drawing and events and my engine may not be compatible.
I started on Logic 5 with a PowerBook G4 550Mhz. I now have a MacBook Air M1 and it's ~165x faster! So, why is my music not proportionally better? :(

Post

syntonica wrote:I just did a quick test. The font looks bad because the font IS bad! A different sans font looked fine-ish... Weird. :roll: :lol:
Well, not all fonts look that great at small pixel sizes. Anyway, thanks to the fact that stb_truetype doesn't round the font size to pixels (unlike most font engines) you could also try to improve the legibility by tweaking the size very slightly to see if you can find a "magic size" that happens to align nicely with the pixel grid. That won't work with all fonts, but for some it might do wonders.

Post

syntonica wrote:I have a branch of my code using nanoVG in an attempt to have one code base for Mac AND Pc. It's truly awful looking right now--8-bit graphics, but without the charm. I've supplemented with a few other bits and bobs of code, but I still am missing mouse overs, which I need for tool tips.

Also, mousing is not very responsive at all, making it difficult to turn knobs and drag sliders. Efficiency-wise, it appears to use the same number of CPU cycles as the native GUI.

At this point, I've pretty much abandoned the idea and am steeling myself to learn Windows GDI... :?
Voxengo UIs simply use blitting of buffers, very simple no much GDI knowledge is needed. Then UI is split in sectors which are drawn in multi-threaded manner (3 threads usually), works quite efficient overall with little problem reports (the only reports come from Mac and they are not very consistent for debugging).

And yes, we have real-time resizing as well, still all works on processor, no acceleration. When we tried OpenGL, the overhead to draw all these small button edges and all was immense, CPU load was about the same as just drawing into the buffer. Maybe for 8K OpenGL would be useful, but it's a question whether or not 8K will be widely adopted ever.
Image

Post

Aleksey Vaneev wrote:
syntonica wrote: At this point, I've pretty much abandoned the idea and am steeling myself to learn Windows GDI... :?
Voxengo UIs simply use blitting of buffers, very simple no much GDI knowledge is needed. Then UI is split in sectors which are drawn in multi-threaded manner (3 threads usually), works quite efficient overall with little problem reports (the only reports come from Mac and they are not very consistent for debugging).

And yes, we have real-time resizing as well, still all works on processor, no acceleration. When we tried OpenGL, the overhead to draw all these small button edges and all was immense, CPU load was about the same as just drawing into the buffer. Maybe for 8K OpenGL would be useful, but it's a question whether or not 8K will be widely adopted ever.
I've solved all those issues, but at the end of the day, the OpenGL version is just too plain ugly to me, even at the larger sizes. The native Cocoa version looks crisp and elegant (to me). The GUI CPU load was still relatively the same since the CPU still has to do all the fancy backflips to make the shapes and turn the fonts into bitmaps, etc.

I finally finished cobbling together a GDI version that will probably compile with 500+ errors. :D I think that, in the end, this will be the better solution. Once I get it running (ha! I have a real Windows 10 laptop coming to do the final touches with) I will have a complete GUI engine that I can continue to use for further cross platform projects.

I hope to have a live GUI showing in a day or two. The weather snapped freezing again, so I have to stay inside and code. :hihi:
I started on Logic 5 with a PowerBook G4 550Mhz. I now have a MacBook Air M1 and it's ~165x faster! So, why is my music not proportionally better? :(

Post

GDI will also start to seem inadequate if you need translucent painting. Try this instead https://msdn.microsoft.com/en-us/librar ... s.85).aspx

On the other hand, I think the font problem with OpenGL should be solvable. Perhaps the textures you use are not large enough? Or perhaps you can render at a size larger than the actual window size and then resample or maybe there are other antialiasing options? I haven't experimented with these so I cannot say, but it seems odd that OpenGL should look so ugly without any solution at all.

edit: I remember a buffer sharing problem between different versions of DirectX, so if you use Direct2D be sure to test it with as many hosts as possible.
~stratum~

Post

stratum wrote:GDI will also start to seem inadequate if you need translucent painting.
The only useful GDI "drawing" operation in my opinion is SetDIBitsToDevice, which is useful for copying a software rendered UI into a window. Just about everything else about GDI is just total waste of time. Even the font rendering is so ugly it makes you puke.

Post

mystran wrote:. Even the font rendering is so ugly it makes you puke.
I haven't used it recently so how ugly it was, I don't remember, but it's probably better than the OpenGL drawings above.
~stratum~

Post

mystran wrote: The only useful GDI "drawing" operation in my opinion is SetDIBitsToDevice, which is useful for copying a software rendered UI into a window. Just about everything else about GDI is just total waste of time. Even the font rendering is so ugly it makes you puke.
Same here, only using SetDIBitsToDevice.
Checkout our VST3/VST2/AU/AAX/LV2:
Inner Pitch | Lens | Couture | Panagement | Graillon

Post Reply

Return to “DSP and Plugin Development”