Browse Source

Render rails in a framebuffer

tags/v0.3.0
Andrew Belt 7 years ago
parent
commit
1af22f1a12
5 changed files with 82 additions and 45 deletions
  1. +8
    -0
      include/app.hpp
  2. +1
    -0
      include/widgets.hpp
  3. +52
    -0
      src/app/RackRail.cpp
  4. +15
    -45
      src/app/RackWidget.cpp
  5. +6
    -0
      src/widgets/FramebufferWidget.cpp

+ 8
- 0
include/app.hpp View File

@@ -20,6 +20,9 @@ struct Scene;
//////////////////// ////////////////////


// A 1U module should be 15x380. Thus the width of a module should be a factor of 15. // A 1U module should be 15x380. Thus the width of a module should be a factor of 15.
#define RACK_GRID_WIDTH 15
#define RACK_GRID_HEIGHT 380

struct Model; struct Model;
struct ModuleWidget : OpaqueWidget { struct ModuleWidget : OpaqueWidget {
Model *model = NULL; Model *model = NULL;
@@ -79,6 +82,7 @@ struct WireWidget : OpaqueWidget {
}; };


struct RackWidget : OpaqueWidget { struct RackWidget : OpaqueWidget {
FramebufferWidget *rails;
// Only put ModuleWidgets in here // Only put ModuleWidgets in here
Widget *moduleContainer; Widget *moduleContainer;
// Only put WireWidgets in here // Only put WireWidgets in here
@@ -100,6 +104,10 @@ struct RackWidget : OpaqueWidget {
void onMouseDown(int button); void onMouseDown(int button);
}; };


struct RackRail : TransparentWidget {
void draw(NVGcontext *vg);
};

struct Panel : TransparentWidget { struct Panel : TransparentWidget {
NVGcolor backgroundColor; NVGcolor backgroundColor;
NVGcolor borderColor; NVGcolor borderColor;


+ 1
- 0
include/widgets.hpp View File

@@ -206,6 +206,7 @@ struct FramebufferWidget : virtual Widget {
~FramebufferWidget(); ~FramebufferWidget();
void step(); void step();
void draw(NVGcontext *vg); void draw(NVGcontext *vg);
int getImageHandle();
}; };


struct QuantityWidget : virtual Widget { struct QuantityWidget : virtual Widget {


+ 52
- 0
src/app/RackRail.cpp View File

@@ -0,0 +1,52 @@
#include "app.hpp"


namespace rack {

void RackRail::draw(NVGcontext *vg) {
const float railHeight = RACK_GRID_WIDTH;

// Background color
nvgBeginPath(vg);
nvgRect(vg, 0.0, 0.0, box.size.x, box.size.y);
nvgFillColor(vg, nvgRGBf(0.2, 0.2, 0.2));
nvgFill(vg);

// Rails
nvgFillColor(vg, nvgRGBf(0.85, 0.85, 0.85));
nvgStrokeWidth(vg, 1.0);
nvgStrokeColor(vg, nvgRGBf(0.7, 0.7, 0.7));
float holeRadius = 3.5;
for (float railY = 0; railY < box.size.y; railY += RACK_GRID_HEIGHT) {
// Top rail
nvgBeginPath(vg);
nvgRect(vg, 0, railY, box.size.x, railHeight);
for (float railX = 0; railX < box.size.x; railX += RACK_GRID_WIDTH) {
nvgCircle(vg, railX + RACK_GRID_WIDTH / 2, railY + railHeight / 2, holeRadius);
nvgPathWinding(vg, NVG_HOLE);
}
nvgFill(vg);

nvgBeginPath(vg);
nvgMoveTo(vg, 0, railY + railHeight - 0.5);
nvgLineTo(vg, box.size.x, railY + railHeight - 0.5);
nvgStroke(vg);

// Bottom rail
nvgBeginPath(vg);
nvgRect(vg, 0, railY + RACK_GRID_HEIGHT - railHeight, box.size.x, railHeight);
for (float railX = 0; railX < box.size.x; railX += RACK_GRID_WIDTH) {
nvgCircle(vg, railX + RACK_GRID_WIDTH / 2, railY + RACK_GRID_HEIGHT - railHeight + railHeight / 2, holeRadius);
nvgPathWinding(vg, NVG_HOLE);
}
nvgFill(vg);

nvgBeginPath(vg);
nvgMoveTo(vg, 0, railY + RACK_GRID_HEIGHT - 0.5);
nvgLineTo(vg, box.size.x, railY + RACK_GRID_HEIGHT - 0.5);
nvgStroke(vg);
}
}


} // namespace rack

+ 15
- 45
src/app/RackWidget.cpp View File

@@ -8,8 +8,6 @@


namespace rack { namespace rack {


static Vec rackGridSize = Vec(15, 380);



struct WireContainer : TransparentWidget { struct WireContainer : TransparentWidget {
void draw(NVGcontext *vg) { void draw(NVGcontext *vg) {
@@ -25,6 +23,12 @@ struct WireContainer : TransparentWidget {
}; };


RackWidget::RackWidget() { RackWidget::RackWidget() {
rails = new FramebufferWidget();
RackRail *rail = new RackRail();
rail->box.size = Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
rails->addChild(rail);
rails->box.size = rail->box.size;

moduleContainer = new Widget(); moduleContainer = new Widget();
addChild(moduleContainer); addChild(moduleContainer);


@@ -33,6 +37,7 @@ RackWidget::RackWidget() {
} }


RackWidget::~RackWidget() { RackWidget::~RackWidget() {
delete rails;
} }


void RackWidget::clear() { void RackWidget::clear() {
@@ -241,12 +246,12 @@ void RackWidget::fromJson(json_t *rootJ) {


void RackWidget::repositionModule(ModuleWidget *module) { void RackWidget::repositionModule(ModuleWidget *module) {
// Create possible positions // Create possible positions
int x0 = roundf(module->requestedPos.x / rackGridSize.x);
int y0 = roundf(module->requestedPos.y / rackGridSize.y);
int x0 = roundf(module->requestedPos.x / RACK_GRID_WIDTH);
int y0 = roundf(module->requestedPos.y / RACK_GRID_HEIGHT);
std::vector<Vec> positions; std::vector<Vec> positions;
for (int y = maxi(0, y0 - 2); y < y0 + 2; y++) { for (int y = maxi(0, y0 - 2); y < y0 + 2; y++) {
for (int x = maxi(0, x0 - 40); x < x0 + 40; x++) { for (int x = maxi(0, x0 - 40); x < x0 + 40; x++) {
positions.push_back(Vec(x * rackGridSize.x, y * rackGridSize.y));
positions.push_back(Vec(x * RACK_GRID_WIDTH, y * RACK_GRID_HEIGHT));
} }
} }


@@ -275,6 +280,8 @@ void RackWidget::repositionModule(ModuleWidget *module) {
} }


void RackWidget::step() { void RackWidget::step() {
rails->step();

// Resize to be a bit larger than the ScrollWidget viewport // Resize to be a bit larger than the ScrollWidget viewport
assert(parent); assert(parent);
assert(parent->parent); assert(parent->parent);
@@ -301,50 +308,13 @@ void RackWidget::step() {
} }


void RackWidget::draw(NVGcontext *vg) { void RackWidget::draw(NVGcontext *vg) {
// Draw rails
nvgBeginPath(vg); nvgBeginPath(vg);
nvgRect(vg, 0.0, 0.0, box.size.x, box.size.y); nvgRect(vg, 0.0, 0.0, box.size.x, box.size.y);

// Background color
nvgFillColor(vg, nvgRGBf(0.2, 0.2, 0.2));
NVGpaint paint = nvgImagePattern(vg, rails->box.pos.x, rails->box.pos.y, rails->box.size.x, rails->box.size.y, 0.0, rails->getImageHandle(), 1.0);
nvgFillPaint(vg, paint);
nvgFill(vg); nvgFill(vg);


// Rails
// TODO Put this in a framebuffer cache and tile
const float railHeight = 15;
nvgFillColor(vg, nvgRGBf(0.85, 0.85, 0.85));
nvgStrokeWidth(vg, 1.0);
nvgStrokeColor(vg, nvgRGBf(0.7, 0.7, 0.7));
float holeRadius = 3.5;
for (float railY = 0; railY < box.size.y; railY += rackGridSize.y) {
// Top rail
nvgBeginPath(vg);
nvgRect(vg, 0, railY, box.size.x, railHeight);
for (float railX = 0; railX < box.size.x; railX += rackGridSize.x) {
nvgCircle(vg, railX + rackGridSize.x / 2, railY + railHeight / 2, holeRadius);
nvgPathWinding(vg, NVG_HOLE);
}
nvgFill(vg);

nvgBeginPath(vg);
nvgMoveTo(vg, 0, railY + railHeight - 0.5);
nvgLineTo(vg, box.size.x, railY + railHeight - 0.5);
nvgStroke(vg);

// Bottom rail
nvgBeginPath(vg);
nvgRect(vg, 0, railY + rackGridSize.y - railHeight, box.size.x, railHeight);
for (float railX = 0; railX < box.size.x; railX += rackGridSize.x) {
nvgCircle(vg, railX + rackGridSize.x / 2, railY + rackGridSize.y - railHeight + railHeight / 2, holeRadius);
nvgPathWinding(vg, NVG_HOLE);
}
nvgFill(vg);

nvgBeginPath(vg);
nvgMoveTo(vg, 0, railY + rackGridSize.y - 0.5);
nvgLineTo(vg, box.size.x, railY + rackGridSize.y - 0.5);
nvgStroke(vg);
}

Widget::draw(vg); Widget::draw(vg);
} }




+ 6
- 0
src/widgets/FramebufferWidget.cpp View File

@@ -81,5 +81,11 @@ void FramebufferWidget::draw(NVGcontext *vg) {
// nvgFill(vg); // nvgFill(vg);
} }


int FramebufferWidget::getImageHandle() {
if (!internal->fb)
return -1;
return internal->fb->image;
}



} // namespace rack } // namespace rack

Loading…
Cancel
Save