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.

86 lines
2.0KB

  1. #include "widgets.hpp"
  2. #include "gui.hpp"
  3. #include <GL/glew.h>
  4. #include "../ext/nanovg/src/nanovg_gl.h"
  5. #include "../ext/nanovg/src/nanovg_gl_utils.h"
  6. namespace rack {
  7. struct FramebufferWidget::Internal {
  8. NVGLUframebuffer *fb = NULL;
  9. Rect box;
  10. ~Internal() {
  11. setFramebuffer(NULL);
  12. }
  13. void setFramebuffer(NVGLUframebuffer *fb) {
  14. if (this->fb)
  15. nvgluDeleteFramebuffer(this->fb);
  16. this->fb = fb;
  17. }
  18. };
  19. FramebufferWidget::FramebufferWidget() {
  20. internal = new Internal();
  21. }
  22. FramebufferWidget::~FramebufferWidget() {
  23. delete internal;
  24. }
  25. void FramebufferWidget::step() {
  26. // Step children before rendering
  27. Widget::step();
  28. // Render the scene to the framebuffer if dirty
  29. if (dirty) {
  30. internal->box.pos = padding.neg();
  31. internal->box.size = box.size.plus(padding.mult(2));
  32. Vec fbSize = internal->box.size.mult(gPixelRatio);
  33. assert(fbSize.isFinite());
  34. internal->setFramebuffer(NULL);
  35. NVGLUframebuffer *fb = nvgluCreateFramebuffer(gVg, fbSize.x, fbSize.y, NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY);
  36. if (!fb)
  37. return;
  38. internal->setFramebuffer(fb);
  39. nvgluBindFramebuffer(fb);
  40. glViewport(0.0, 0.0, fbSize.x, fbSize.y);
  41. glClearColor(0.0, 0.0, 0.0, 0.0);
  42. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  43. nvgBeginFrame(gVg, fbSize.x, fbSize.y, gPixelRatio);
  44. nvgScale(gVg, gPixelRatio, gPixelRatio);
  45. nvgTranslate(gVg, padding.x, padding.y);
  46. Widget::draw(gVg);
  47. nvgEndFrame(gVg);
  48. nvgluBindFramebuffer(NULL);
  49. dirty = false;
  50. }
  51. }
  52. void FramebufferWidget::draw(NVGcontext *vg) {
  53. if (!internal->fb)
  54. return;
  55. // Draw framebuffer image
  56. nvgBeginPath(vg);
  57. nvgRect(vg, internal->box.pos.x, internal->box.pos.y, internal->box.size.x, internal->box.size.y);
  58. NVGpaint paint = nvgImagePattern(vg, internal->box.pos.x, internal->box.pos.y, internal->box.size.x, internal->box.size.y, 0.0, internal->fb->image, 1.0);
  59. nvgFillPaint(vg, paint);
  60. nvgFill(vg);
  61. // For debugging bounding box of framebuffer image
  62. // nvgFillColor(vg, nvgRGBA(255, 0, 0, 64));
  63. // nvgFill(vg);
  64. }
  65. } // namespace rack