I’ve found that there are problems when drawing on Rack’s layer 1
if a path contains a sub-path with reverse (NVG_HOLE
) path winding.
Background
For those unfamiliar with path winding in nanovg, it can be used to specify holes in objects. For example, this renders a simple donut shape, where the donut’s hole is half the radius of the donut:
nvgBeginPath(args.vg);
nvgCircle(args.vg, 0, 0, 10);
nvgCircle(args.vg, 0, 0, 5);
nvgPathWinding(args.vg, NVG_HOLE);
nvgFill(args.vg);
Donut-like shapes are a requirement for rendering halos on my ring lights.
Scenario A
The problem occurs under the following condition:
- A sub-path with
NVG_HOLE
winding is drawn onlayer 1
- The error does not occur if this path is moved to either
draw()
ordrawLayer() (if layer == 0)
- The error does not occur if this path is moved to either
Symptoms
When an overlay (like a Rack menu) is rendered above the hole-bearing layer-1 path, interference is visible on the overlay.
At first I thought I was seeing widget box boundaries, but later testing revealed it is an error in the outer border (stroke?) of the sub-path which precedes the NVG_HOLE
winding. (The outer radial gradient here is housed in a rect.)
Scenario B
The criteria for Scenario A must be met, then:
- First instantiate a module which contains a hole-bearing layer-1 widget.
- Then instantiate Fundamental VCA.
- Reduce VCA level to zero, or otherwise turn-off its light by patching 0V into the CV input.
- Ensure the VCA remains on-screen along with your test module, to ensure they are both rendered.
Symptoms
What happens here is that the color of the light which was just turned off (the VCA’s slider) is “picked up” and rendered at the aforementioned boundaries.
In the following image, the two modules to the right of the VCA were added to the scene after the VCA. The two on the left were added before.
This color is certainly being pulled from the VCA’s light, because it was previously different, and it occurs with some other modules too:
Further
I’ve created a repository on GitHub with a test plugin, test modules, and test widgets. Two of the widgets (MonsterSquare
and MonsterCircle
) are designed to make the error as obvious as possible. This is accomplished by nesting many alternating NVG_SOLID
and NVG_HOLE
sub-paths:
These monstrous widgets helped to reveal a strange interaction: if the widgets are overlayed, the boxes (rather than the paths) of widgets on modules added to the scene later “temporarily fix” the error in widgets on modules added earlier:
Considering the hectic schedule of VCV at the moment, the difficulty in debugging this, and the fact that this presently only affects my plugin (maybe), I don’t anticipate that this is on the list for fixing prior to Rack 2 release. So, because I’ve got some time on my hands at present, I’m doing what I can to figure it out. Any help would be greatly appreciated!