Traditionally, GUIs for VST/AU plugins have been created using pre-rendered graphic images, typically in the form of a large background image and any number of smaller image files used for knobs and the like. Allowing these image files to be loaded at run-time made it possible for users to substitute their own images, thus changing the GUI's appearance. This process (also widely used for games) has come to be known as “skinning”, with each collection of files called a “skin”. (See also Skin_(computing) and Theme_(computing).)
The present version of SARAH provides for a minimalist skinning approach—just a single background image—the technique, limitations, and philosophy of which are discussed below. For details about how to create your own SARAH skin, go to https://github.com/getdunne/SARAH/tree/master/Skinning, and look in the Skinning folder in the source code.
If the user does not provide a sarah.png image in their Desktop folder at run-time, the present SARAH code defaults to generating a “pure-vector” GUI, where all elements are software-generated. This should work on any computer, and based on tidbits I have read, it should also scale automatically on Retina-screen Macs. Unfortunately I don't have a Retina Mac at the moment, so I can't test this.
The code still includes support for a default background image, compiled in to the executable using JUCE's BinaryData mechanism. This will only be used if you change the default value of useBackgroundImage to true in the constructor in PluginEditor.cpp.
Using pre-rendered images has only one real drawback: Because computer displays have different pixel densities, the GUI may appear too small on the higher-density displays. Standard LCD screens have about 100 pixels per inch (ppi, aka dpi or “dots per inch”). Apple's famous “retina displays” are about 220 ppi—approximately double the standard density. Dell's newest 8K “ultrasharp” screens are 280 ppi, and the newest phones and tablets are pushing into the 300-400 ppi range and beyond.
The advent of high-ppi displays, together with the more prosaic problem of aging users requiring larger GUIs just so they can see them clearly, has led to tremendous interest in so-called “vector graphics”, where all elements of the GUI are rendered at run-time, at whatever scale is desired. JUCE's Component graphics classes are all vector-based, and mostly seem to work well on Macs with both standard and Retina displays, but it appears that support for GUI scaling on Windows has been problematic—see e.g. https://forum.juce.com/t/ui-scaling-on-windows-4k/21342/11. I think it's fair to say that vector GUI scaling remains at least semi-problematic in JUCE.
The traditional raster GUI approach, however old-fashioned it may seem, has a number of advantages:
A lot of people like to hate on skeuomorphic GUI designs, but I happen to think they work quite well for audio plugins, for two reasons:
This is not to say that there are not good, bad, and downright ugly skeuomorphic GUI designs around. But imagine if you will, a large screen full of plugin GUIs that all look like Windows apps from the 1980s. How would you find your way around? How could you tell one from another?
Building GUIs out of pre-rendered raster graphic images supports an efficient and sensible division of labour between programmers, whose primary concern is making software work, and designers, whose primary concern is making it look good. Taking the extra step to allow such images to be found and loaded at run-time makes a program or plugin skinnable, allowing ordinary users to further develop the GUI design. This is particularly beneficial in open-source and community-developed software, where the original developer's resources may be very limited, and enthusiastic users can contribute design ideas which the developer might never have thought of.
It's easy to say that highly-detailed graphics need not burden the CPU of the host system, since modern GPUs have become so powerful, but it is quite another thing to program a system to ensure that this is the case. It's worth noting that in the world of interactive games—where CPU and GPU efficiency are pursued relentlessly—pre-rendered graphic “assets” are used extensively.
Any discussion of “efficiency” must begin with careful consideration of what we should aim to optimize, which often comes down to whose time should be optimized. Software is expensive to develop and maintain, and there has been a very sensible trend to optimize programmer time, even at the expense of run-time CPU efficiency, because in relative terms, programmers are expensive and computer power is cheap. (See also The API Guessing Game.)