I compiled my synth on mac and found that the GUI looked pretty blurry. Further investigation showed that the GUI is much bigger than anticipated:
I force the entire GUI to be 800x600 pixels at all times, with bitmaps the exact size they need to be. Yet the GUI is almost screen-filling on a 2560x1600 display. Is this some sort of OS-feature to prevent tiny GUIs?
JUCE’s coordinate system uses logical pixels, so your 800x600 will be scaled up by the scale factor of the user’s display. You can get the scale factor using something like:
if you really need to deal with physical pixels.
Ok I was completely unaware of this. I have a few followup questions:
So in other words there is no way to avoid blurry bitmaps ever…?
Do I have some control over how interpolation is done? Right now the scale factor is 2, and the whole thing looks way blurry compared to a lower DPI display with scale factor 1.
Can I use this somehow to hassle-free scale my UI? I avoided UI scaling like the plague, thinking I’d have to rescale every sprite myself and would run into numerous issues along the way (including blur, lol). Now that the cat is out of the bag, I might as well embrace this feature?
There are a few ways to avoid blurry art assets:
- Use oversized starting images and/or mipmap type multiple images (makes resulting plugin bigger, but is probably the easiest thing to do).
- Write custom scaling to scale up the images prior to display (e.g. on resize or even earlier if poss). The way projects I’ve worked on have done this is to just upsample the image to a second image and then use the same old Graphics& methods to draw the bigger source image.
My personal favorite is to use vector graphics to draw controls with a smattering of SVGs for icons and any other fiddly paths. SVG load to drawable does not support every feature that SVG does.
How would I draw higher resolution images? Let’s take my backdrop as an example: It is a .png file with the exact dimensions as the editor component (800x600). If I were to upscale it to 1600x1200 and draw it, it would obviously only show the top-left quarter in my screen since it’s too big.
Assuming you’re using a Drawable, see
Note that this is not “Transform To Fit”, but “SET transform to fit”.
Under the hood, it uses an
AffineTransform. These are kind of like a lens applied to the graphics as it draws something, rather than a way of transforming something before it is drawn.
Graphics::drawImageTransformed if you’re using images directly.
Ok, thanks for your answer! I guess applying an affine transform on each call isn’t cheap (matrix transform each pixel of the entire way too big image to a smaller version on each paint call if I’m not mistaken.)
I also just found out about the
Graphics::setImageResampligQuality() function, which let’s you choose from three interpolation levels: None, bilinear and bicubic. Funny enough, on an exactly 2x scaled screen no interpolation might be my best bet.
Anyway I have some options to go from here and will experiment!
Ok I have one more question regarding this:
If I set the interpolation to “none” the result is waayyy better than the other two. I know this is due to the scaling factor being exactly 2 and for fractional scaling factors things will look much different.
Is it even common to have other scaling factors? I searched for a bit and couldn’t find a way to change it on either OS.
Because if I’m dealing with a factor of 1 or 2, I might as well leave it at no interpolation…
On Windows 10 (and maybe 8 as well) you can set the display scaling to at least 100%, 125%, 150%, and 175%. Sometimes you can also set it to 200% and more, or to some less common factors.
Ok then I guess I’ll just check in the beginning, use “none” for integer values and “high” else.
Thanks for your help!