You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.0KB

  1. #include <app/LightWidget.hpp>
  2. #include <color.hpp>
  3. #include <settings.hpp>
  4. namespace rack {
  5. namespace app {
  6. void LightWidget::draw(const DrawArgs& args) {
  7. drawBackground(args);
  8. // Child widgets
  9. Widget::draw(args);
  10. }
  11. void LightWidget::drawLayer(const DrawArgs& args, int layer) {
  12. if (layer == 1) {
  13. // Use the formula `lightColor * (1 - dest) + dest` for blending
  14. nvgGlobalCompositeBlendFunc(args.vg, NVG_ONE_MINUS_DST_COLOR, NVG_ONE);
  15. drawLight(args);
  16. drawHalo(args);
  17. }
  18. Widget::drawLayer(args, layer);
  19. }
  20. void LightWidget::drawBackground(const DrawArgs& args) {
  21. float radius = std::min(box.size.x, box.size.y) / 2.0;
  22. nvgBeginPath(args.vg);
  23. nvgCircle(args.vg, radius, radius, radius);
  24. // Background
  25. if (bgColor.a > 0.0) {
  26. nvgFillColor(args.vg, bgColor);
  27. nvgFill(args.vg);
  28. }
  29. // Border
  30. if (borderColor.a > 0.0) {
  31. nvgStrokeWidth(args.vg, 0.5);
  32. nvgStrokeColor(args.vg, borderColor);
  33. nvgStroke(args.vg);
  34. }
  35. }
  36. void LightWidget::drawLight(const DrawArgs& args) {
  37. // Foreground
  38. if (color.a > 0.0) {
  39. float radius = std::min(box.size.x, box.size.y) / 2.0;
  40. nvgBeginPath(args.vg);
  41. nvgCircle(args.vg, radius, radius, radius);
  42. nvgFillColor(args.vg, color);
  43. nvgFill(args.vg);
  44. }
  45. }
  46. void LightWidget::drawHalo(const DrawArgs& args) {
  47. // Don't draw halo if rendering in a framebuffer, e.g. screenshots or Module Browser
  48. if (args.fb)
  49. return;
  50. const float halo = settings::haloBrightness;
  51. if (halo == 0.f)
  52. return;
  53. // If light is off, rendering the halo gives no effect.
  54. if (color.r == 0.f && color.g == 0.f && color.b == 0.f)
  55. return;
  56. math::Vec c = box.size.div(2);
  57. float radius = std::min(box.size.x, box.size.y) / 2.0;
  58. float oradius = radius + std::min(radius * 4.f, 15.f);
  59. nvgBeginPath(args.vg);
  60. nvgRect(args.vg, c.x - oradius, c.y - oradius, 2 * oradius, 2 * oradius);
  61. NVGcolor icol = color::mult(color, halo);
  62. NVGcolor ocol = nvgRGBA(0, 0, 0, 0);
  63. NVGpaint paint = nvgRadialGradient(args.vg, c.x, c.y, radius, oradius, icol, ocol);
  64. nvgFillPaint(args.vg, paint);
  65. nvgFill(args.vg);
  66. }
  67. } // namespace app
  68. } // namespace rack