commit b33d2fed46d864b95035177dce4756eb6fc11365
parent abbe9ac04d23ef2e2de18cf4048f8db01c6a7146
Author: Adam M <aemalone@gmail.com>
Date: Sun, 12 Apr 2020 17:20:31 -0500
drolypaw will paw without clearing each frame
Diffstat:
5 files changed, 262 insertions(+), 176 deletions(-)
diff --git a/src/ComputerscareBlank.cpp b/src/ComputerscareBlank.cpp
@@ -175,14 +175,14 @@ struct PNGDisplay : TransparentWidget {
} else if (blankModule->imageFitEnum == 2) { //fit height
blankModule->zoomY = blankModule->height / imgHeight;
blankModule->zoomX = blankModule->zoomY;
- blankModule->xOffset=0;
- blankModule->yOffset=0;
+ blankModule->xOffset = 0;
+ blankModule->yOffset = 0;
}
- else if(blankModule->imageFitEnum ==3) {
+ else if (blankModule->imageFitEnum == 3) {
}
-
+
}
void draw(const DrawArgs &args) override {
if (blankModule && blankModule->loadedJSON) {
@@ -190,8 +190,8 @@ struct PNGDisplay : TransparentWidget {
img = nvgCreateImage(args.vg, blankModule->path.c_str(), 0);
nvgImageSize(args.vg, img, &imgWidth, &imgHeight);
imgRatio = ((float)imgWidth / (float)imgHeight);
-
- if(path != "empty") {
+
+ if (path != "empty") {
setZooms();
}
path = blankModule->path;
@@ -202,7 +202,7 @@ struct PNGDisplay : TransparentWidget {
setZooms();
}
lastEnum = blankModule->imageFitEnum;
- if (!path.empty() && path!="empty") {
+ if (!path.empty() && path != "empty") {
nvgBeginPath(args.vg);
NVGpaint imgPaint;
nvgScale(args.vg, blankModule->zoomX, blankModule->zoomY);
diff --git a/src/ComputerscareDrolyPaw.cpp b/src/ComputerscareDrolyPaw.cpp
@@ -37,18 +37,18 @@ struct DrolyPaw : Module {
float lastScramble = 0;
int A = 31;
- int B = 32;
+ int B = 32;
int C = 29;
int D = 2;
DrolyPaw() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
- const float timeBase = (float) BUFFER_SIZE / 6;
+ const float timeBase = (float) BUFFER_SIZE / 6;
- for(int i = 0; i < 16; i++) {
- cmap[i]=i;
- }
+ for (int i = 0; i < 16; i++) {
+ cmap[i] = i;
+ }
configParam(TIME_PARAM, 6.f, 16.f, 14.f, "Time", " ms/div", 1 / 2.f, 1000 * timeBase);
@@ -56,22 +56,22 @@ struct DrolyPaw : Module {
configParam(OFFSET, -5.f, 5.f, 0.f, "Input Offset", " Volts");
configParam(SCRAMBLE, -10.f, 10.f, 0.f, "Scrambling");
- configParam(DRAW_MODE,0.f,64.f,0.f,"Draw Mode");
-
+ configParam(DRAW_MODE, 0.f, 64.f, 1.f, "Draw Mode");
+
}
void onReset() override {
//std::memset(bufferX, 0, sizeof(bufferX));
}
void updateScramble(float v) {
- for(int i = 0; i < 16; i++) {
- cmap[i] = (i*A+B+(int)std::floor(v*1010.1))%16;
+ for (int i = 0; i < 16; i++) {
+ cmap[i] = (i * A + B + (int)std::floor(v * 1010.1)) % 16;
}
}
void checkScramble() {
float xx = params[SCRAMBLE].getValue();
- if(lastScramble != xx) {
- lastScramble= xx;
+ if (lastScramble != xx) {
+ lastScramble = xx;
updateScramble(xx);
}
}
@@ -89,7 +89,7 @@ struct DrolyPaw : Module {
this->channelsX = channelsX;
}
- if(cnt > 4101) {
+ if (cnt > 4101) {
checkScramble();
cnt = 0;
@@ -104,10 +104,10 @@ struct DrolyPaw : Module {
if (inputs[X_INPUT].isConnected()) {
for (int c = 0; c < 16; c++) {
- //bufferX[c][bufferIndex] = inputs[X_INPUT].getVoltage(std::min(cmap[c], this->channelsX)) * trimVal + offsetVal + 99 + (1071 * cmap[c]) % 19;
+ bufferX[c][bufferIndex] = inputs[X_INPUT].getVoltage(std::min(cmap[c], this->channelsX)) * trimVal + offsetVal;
//bufferX[c][bufferIndex]=inputs[X_INPUT].getVoltage(cmap[c]);
//bufferX[c][bufferIndex]=inputs[X_INPUT].getVoltage(c);
- bufferX[c][bufferIndex]=inputs[X_INPUT].getVoltage(c)*trimVal+offsetVal;
+ //bufferX[c][bufferIndex]=inputs[X_INPUT].getVoltage(c)*trimVal+offsetVal;
}
}
else {
@@ -136,181 +136,161 @@ struct DrolyPaw : Module {
}
+ float bget(int ch) {
+ return bufferX[ch % 16][0];
+ }
+ float bgetf(int ch) {
+ return bufferX[(ch * ch + 910) % 16][(ch * ch * ch - ch * ch + 10101) % BUFFER_SIZE];
+ }
+
+
void trigger() {
bufferIndex = 0;
frameIndex = 0;
}
};
+struct NoClearWidget : FramebufferWidget {
+ NoClearWidget() {
+ FramebufferWidget();
+ }
+ void step() override {
+ // Render every frame
+ dirty = true;
+ FramebufferWidget::step();
+ }
+ /** Draws to the framebuffer.
+ Override to initialize, draw, and flush the OpenGL state.
+ */
+ void drawFramebuffer() override {
+ NVGcontext* vg = APP->window->vg;
+
+ float pixelRatio = fbSize.x * oversample / fbBox.size.x;
+ nvgBeginFrame(vg, fbBox.size.x, fbBox.size.y, pixelRatio);
+
+ // Use local scaling
+ nvgTranslate(vg, -fbBox.pos.x, -fbBox.pos.y);
+ nvgTranslate(vg, fbOffset.x, fbOffset.y);
+ nvgScale(vg, fbScale.x, fbScale.y);
+
+ DrawArgs args;
+ args.vg = vg;
+ args.clipBox = box.zeroPos();
+ args.fb = fb;
+ Widget::draw(args);
+
+ glViewport(0.0, 0.0, fbSize.x * oversample, fbSize.y * oversample);
+ //glClearColor(0.0, 0.0, 0.0, 0.0);
+ // glClearColor(0.0, 1.0, 1.0, 0.5);
+ //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ nvgEndFrame(vg);
+
+ // Clean up the NanoVG state so that calls to nvgTextBounds() etc during step() don't use a dirty state.
+ nvgReset(vg);
+ }
+};
-
-
-struct DrolyPawDisplay : TransparentWidget {
+struct DrolyPawDisplay : FramebufferWidget {
DrolyPaw *module;
-
-
- DrolyPawDisplay() {
+ void step() override {
+ // Render every frame
+ dirty = true;
+ FramebufferWidget::step();
}
-void drawThingie(const DrawArgs &args, float buffer[16][BUFFER_SIZE]) {
- DrawHelper draw = DrawHelper(args.vg);
- Points pts = Points();
- if(module->params[DrolyPaw::DRAW_MODE].getValue()==0) {
- pts.triangle(Vec(60,60),Vec(buffer[0][0],buffer[1][0]));
-
- pts.offset(Vec(67.5,190));
- for(int i = 0; i < 4; i++) {
- pts.offset(Vec(buffer[2][0],buffer[3][0]));
- draw.drawShape(pts.get());
+ /*DrolyPawDisplay() {
+ FramebufferWidget();
+ }*/
+ void drawThingie(const DrawArgs &args, float buffer[16][BUFFER_SIZE]) {
+ DrawHelper draw = DrawHelper(args.vg);
+ Points pts = Points();
+ nvgTranslate(args.vg, 67.5, 190);
+ int mode = module->params[DrolyPaw::DRAW_MODE].getValue();
+ if (mode == 0) {
+ for (int i = 0; i < 4; i++) {
+ pts.triangle(Vec(buffer[i * 4][0] * 10, buffer[i * 4 + 1][0] * 10), Vec(buffer[i * 4 + 2][0] * 3, buffer[i * 4 + 3][0] * 3));
+ pts.offset(Vec(buffer[(i * 11 + 3) % 16][0], buffer[(i * 3 + 11) % 16][0]));
+ draw.drawShape(pts.get(), draw.sincolor(buffer[0][0]+i*buffer[1][0]));
+ }
+ }
+ else if (mode == 1) {
+ pts.spray(100);
+ pts.scale(Vec(buffer[2][0]*buffer[0][0], buffer[2][0]*buffer[1][0]));
+ draw.drawDots(pts.get(), draw.sincolor(random::uniform()), 2.f);
+ }
+ else {
+ int nx = (mode * 17) % 10;
+ int ny = (mode * 11 + 3) % 10;
+ pts.grid(nx, ny, Vec(buffer[2][0] * 10, buffer[1][0] * 10));
+ Points rTheta = Points();
+ rTheta.linear(nx * ny, Vec(30, 0), Vec(buffer[3][0], buffer[0][0]));
+ draw.drawLines(pts.get(), rTheta.get(), draw.sincolor(buffer[0][0]), 2);
}
-
}
-}
-void drawThingie(const DrawArgs &args) {
-
-}
- void drawStickFigure(const DrawArgs &args, float A, float B, float C, float D, float E, float F, float G, float H, float I, float J, float K, float L, float M, float N, float O, float P) {
-
- nvgStrokeColor(args.vg, COLOR_COMPUTERSCARE_GREEN);
-
- nvgLineJoin(args.vg, NVG_ROUND);
-
- float h = 0.5 + 0.25 * sin(C / 2) + 0.25 * sin(K / 3); //face hue
- float s = 0.5 + 0.32 * sin(B / 3 - 33.21 - D / 2); //face saturation
- float l = 0.5 + 0.35 * sin(E / 2); //face lightness
-
- NVGcolor faceColor = nvgHSLA(h, s, l, 0xff);
-
- nvgFillColor(args.vg, faceColor);
- nvgStrokeWidth(args.vg, 3.2);
-
- float size = 1+sin(O-29)/4;
-
- //crotch
- float cx = 62*(1+(sin(E+F)-sin(P+O/2+50))/40000);
- float cy = 210*(1+(sin(A+G-12)-sin(P+H/2))/11000);
-
- //thigh spread, length, direction
- float thighSpread = (2+sin(J+I+K)-sin(A-N/2))/4;
- float thighLength = 50*(1+(sin(C-100+F+K*2)+sin(C+L-10))/6);
- float thighDirection = (sin(J+O-211)-sin(P*2+I)-sin(B+K))/2;
-
-
- //ankle spread,length,direction
- float ankleSpread = (2+sin(O-B)/2+sin(F+2)/2+sin(P-E-D+19.2))/13;
- float ankleLength = thighLength*(1+(sin(F+A+J-K/2+9))/9);
- float ankleDirection = 3*M_PI/2+(3+sin(J+M-L-101)-sin(P-B+22)-sin(H))/8;
-
- float leftKneeArg = 3*M_PI/2 +thighDirection + thighSpread;
- float rightKneeArg = 3*M_PI/2 +thighDirection - thighSpread;
-
-
- float leftAnkleArg = ankleDirection+ankleSpread;
- float rightAnkleArg = ankleDirection-ankleSpread;
-
-
- float leftKneeX=cx+thighLength*cos(leftKneeArg);
- float leftKneeY=cy-thighLength*sin(leftKneeArg);
+ void drawThingie(const DrawArgs &args) {
- float leftAnkleX = leftKneeX+ankleLength*cos(leftAnkleArg);
- float leftAnkleY = leftKneeY-ankleLength*sin(leftAnkleArg);
-
- float rightKneeX=cx+thighLength*cos(rightKneeArg);
- float rightKneeY=cy-thighLength*sin(rightKneeArg);
-
- float rightAnkleX = rightKneeX+ankleLength*cos(rightAnkleArg);
- float rightAnkleY = rightKneeY-ankleLength*sin(rightAnkleArg);
-
-
- nvgBeginPath(args.vg);
-
-
- nvgMoveTo(args.vg, leftAnkleX,leftAnkleY);
- nvgLineTo(args.vg, leftKneeX,leftKneeY);
- nvgLineTo(args.vg, cx,cy);
- nvgLineTo(args.vg, rightKneeX,rightKneeY);
- nvgLineTo(args.vg, rightAnkleX,rightAnkleY);
-
- //nvgClosePath(args.vg);
- nvgStroke(args.vg);
-
-
- //torso length,direction
- float torsoLength=thighLength*(1.4+(sin(A-12))/4);
- float torsoDirection=M_PI/2+sin(D)/2;
-
- float neckX = cx+torsoLength*cos(torsoDirection);
- float neckY = cy-torsoLength*sin(torsoDirection);
-
- nvgBeginPath(args.vg);
- nvgMoveTo(args.vg,cx,cy);
- nvgLineTo(args.vg,neckX,neckY);
- nvgStroke(args.vg);
-
- float armLength=torsoLength*(2+(sin(N+14)-sin(P-L-3))/2)/4;
- float forearmLength=armLength*(1+(2+(sin(F+B+2)-sin(E)))/300);
- float armDirection=3*M_PI/2+0.2*(sin(C-M));
- float armSpread=sin(B+P-A)+sin(N-J);
-
- float leftElbowArg=armDirection+armSpread;
- float rightElbowArg=armDirection-armSpread;
-
- float leftHandArg=sin(E+22+A-4);
- float rightHandArg=sin(F+22-B);
-
- float leftElbowX = neckX+armLength*cos(leftElbowArg);
- float leftElbowY = neckY-armLength*sin(leftElbowArg);
-
- float leftHandX=leftElbowX+forearmLength*cos(leftHandArg);
- float leftHandY=leftElbowY-forearmLength*sin(leftHandArg);
-
- float rightElbowX = neckX+armLength*cos(rightElbowArg);
- float rightElbowY = neckY-armLength*sin(rightElbowArg);
-
- float rightHandX=rightElbowX+forearmLength*cos(rightHandArg);
- float rightHandY=rightElbowY-forearmLength*sin(rightHandArg);
-
- nvgBeginPath(args.vg);
- nvgMoveTo(args.vg,neckX,neckY);
- nvgLineTo(args.vg,leftElbowX,leftElbowY);
- nvgLineTo(args.vg,leftHandX,leftHandY);
- nvgStroke(args.vg);
-
- nvgBeginPath(args.vg);
- nvgMoveTo(args.vg,neckX,neckY);
- nvgLineTo(args.vg,rightElbowX,rightElbowY);
- nvgLineTo(args.vg,rightHandX,rightHandY);
- nvgStroke(args.vg);
-
- float headHeight = torsoLength*(0.5+sin(H-E-I-D)/9-sin(F+B-C+E)/7);
- float headWidth = headHeight*(0.6+sin(I+D-M/2)/7+sin(G/2+J-10)/6);
- float headAngle = M_PI/2 + (sin(C+A)/6+sin(D+G)/9);
-
- float headRotation=sin(C+A)/2+sin(M/2)/3;
-
- nvgBeginPath(args.vg);
-
- nvgTranslate(args.vg, neckX, neckY);
- nvgRotate(args.vg,headRotation);
- nvgEllipse(args.vg, 0,-headHeight,headWidth,headHeight);
-
- nvgFill(args.vg);
- nvgStroke(args.vg);
-
-
- nvgResetScissor(args.vg);
- //nvgRestore(args.vg);
}
-
- void draw(const DrawArgs &args) override {
+ void drawFramebuffer() override {
+ NVGcontext* vg = APP->window->vg;
+
+ float pixelRatio = fbSize.x * oversample / fbBox.size.x;
+ nvgBeginFrame(vg, fbBox.size.x, fbBox.size.y, pixelRatio);
+
+ // Use local scaling
+ nvgTranslate(vg, -fbBox.pos.x, -fbBox.pos.y);
+ nvgTranslate(vg, fbOffset.x, fbOffset.y);
+ nvgScale(vg, fbScale.x, fbScale.y);
+
+ DrawArgs args;
+ args.vg = vg;
+ args.clipBox = box.zeroPos();
+ args.fb = fb;
+ //Widget::draw(args);
if (!module) {
drawThingie(args);
}
else {
drawThingie(args, module->bufferX);
}
+
+ glViewport(0.0, 0.0, fbSize.x * oversample, fbSize.y * oversample);
+ //glClearColor(0.0, 0.0, 0.0, 0.0);
+ // glClearColor(0.0, 1.0, 1.0, 0.5);
+ //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ nvgEndFrame(vg);
+
+ // Clean up the NanoVG state so that calls to nvgTextBounds() etc during step() don't use a dirty state.
+ nvgReset(vg);
}
};
+struct DrolyGLDisplay : OpenGlWidget {
+ DrolyPaw *module;
+ DrolyGLDisplay() {
+
+ }
+
+ void drawFramebuffer() override {
+ float a = module->bufferX[0][0];
+ float b = module->bufferX[1][0];
+ float c = module->bufferX[2][0];
+ glViewport(0.0, 0.0, fbSize.x, fbSize.y);
+ glClearColor(a * 2, b * 2, c * 2, 1.0);
+ //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(a, fbSize.x, 0.0, fbSize.y, -1.0, 1.0);
+
+ glBegin(GL_TRIANGLES);
+ glColor3f(a / 10, b / 10, c / 10);
+ glVertex3f(fbSize.x / 2 + b * 10, fbSize.y / 2 + c * 10, a * 10);
+ glColor3f(0, 1, 0);
+ glVertex3f(fbSize.x / 2 + c * 10, 0, 0);
+ glColor3f(0, 0, 1);
+ glVertex3f(0, fbSize.y / 2 + b * 10, 0);
+ glEnd();
+ }
+};
struct DrolyPawWidget : ModuleWidget {
@@ -321,12 +301,20 @@ struct DrolyPawWidget : ModuleWidget {
{
ComputerscareSVGPanel *panel = new ComputerscareSVGPanel();
panel->box.size = box.size;
- panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, "res/ComputerscareFolyPacePanel.svg")));
+ panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, "res/ComputerscareStolyFickPigurePanel.svg")));
addChild(panel);
}
{
+ DrolyGLDisplay *gl = new DrolyGLDisplay();
+ gl->module = module;
+ gl->box.pos = Vec(0, 0);
+ gl->box.size = Vec(box.size.x, box.size.y);
+ //addChild(gl);
+ }
+
+ {
DrolyPawDisplay *display = new DrolyPawDisplay();
display->module = module;
display->box.pos = Vec(0, 0);
@@ -334,11 +322,13 @@ struct DrolyPawWidget : ModuleWidget {
addChild(display);
}
+
addInput(createInput<PointingUpPentagonPort>(Vec(1, 353), module, DrolyPaw::X_INPUT));
addParam(createParam<SmallKnob>(Vec(31, 357), module, DrolyPaw::TRIM));
addParam(createParam<SmoothKnob>(Vec(51, 353), module, DrolyPaw::OFFSET));
addParam(createParam<ScrambleKnob>(Vec(81, 357), module, DrolyPaw::SCRAMBLE));
+ addParam(createParam<MediumDotSnapKnob>(Vec(101, 354), module, DrolyPaw::DRAW_MODE));
}
diff --git a/src/drawFunctions.hpp b/src/drawFunctions.hpp
@@ -37,6 +37,48 @@ struct DrawHelper {
}
nvgRestore(vg);
}
+ void drawDots(std::vector<Vec> points,NVGcolor fillColor=BLACK,float thickness=1.f) {
+ unsigned int n = points.size();
+ //nvgSave(vg);
+ // nvgBeginPath(vg);
+ nvgBeginPath(vg);
+ //nvgStrokeColor(vg, fillColor);
+ //nvgStrokeWidth(vg, thickness);
+ nvgFillColor(vg,fillColor);
+
+ //nvgMoveTo(vg, 0,0);
+ for (unsigned int i = 0; i < n; i++) {
+ nvgCircle(vg, points[i].x, points[i].y,thickness);
+ }
+
+ nvgClosePath(vg);
+ nvgFill(vg);
+ /*if (thickness > 0) {
+ nvgStroke(vg);
+ }*/
+ //nvgStroke(vg);
+ // nvgRestore(vg);
+ }
+ void drawLines(std::vector<Vec> points, std::vector<Vec> rTheta,NVGcolor strokeColor=BLACK,float thickness=1.f) {
+ unsigned int n = points.size();
+ nvgSave(vg);
+ // nvgBeginPath(vg);
+ nvgBeginPath(vg);
+ nvgStrokeColor(vg, strokeColor);
+ nvgStrokeWidth(vg, thickness);
+
+ //nvgMoveTo(vg, 0,0);
+ for (unsigned int i = 0; i < n; i++) {
+ nvgMoveTo(vg,points[i].x,points[i].y);
+ nvgLineTo(vg,points[i].x+rTheta[i].x*cos(rTheta[i].y),points[i].y+rTheta[i].x*sin(rTheta[i].y));
+ //nvgClosePath(vg);
+ }
+ nvgStroke(vg);
+ nvgRestore(vg);
+ }
+ NVGcolor sincolor(float t,std::vector<int> omega={1,2,3}) {
+ return nvgRGB(127*(1+sin(t*omega[0])),127*(1+sin(t*omega[1])),127*(1+sin(t*omega[2])));
+ }
};
}
}
\ No newline at end of file
diff --git a/src/pointFunctions.hpp b/src/pointFunctions.hpp
@@ -8,7 +8,12 @@ struct Points {
Points() {
}
-
+ void linear(int num, Vec offset,Vec slope) {
+ points.resize(num);
+ for(int i = 0; i < num; i++) {
+ points[i] = Vec(offset.x+slope.x*i/num,offset.y+slope.y*i/num);
+ }
+ }
void grid(int numx,int numy, Vec size) {
int N = numx*numy;
points.resize(N);
@@ -24,11 +29,31 @@ struct Points {
points[1] = b;
points[2] = b.plus(cMinusB);
}
+ void spray(int n) {
+ points.resize(n);
+ for(int i =0; i < n; i++) {
+ points[i] = Vec(random::normal(),random::normal());
+ }
+ }
void offset(Vec dz) {
for(unsigned int i = 0; i < points.size(); i++) {
points[i] = points[i].plus(dz);
}
}
+ void scale(Vec s) {
+ for(unsigned int i = 0; i < points.size(); i++) {
+ points[i] = points[i].mult(s);
+ }
+ }
+ void waveBlob() {
+
+ }
+ void wtf(float buf[16][512]) {
+ int n = buf[0][0]*(1+buf[1][0]);
+ for(int i = 0; i < n; i++) {
+ points.push_back(Vec(i,i));
+ }
+ }
std::vector<Vec> get() {
return points;
}
diff --git a/src/waveblob.hpp b/src/waveblob.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+namespace rack {
+namespace app {
+struct Waveblob {
+
+ std::vector<Vec> trigs;
+ Points points;
+ int numPoints;
+ Waveblob(int n=200) {
+ numPoints=n;
+ makeTrigs();
+ }
+ void makeTrigs() {
+ trigs.resize(numPoints);
+ float omega=2*M_PI/numPoints;
+ for(int i = 0; i < numPoints) {
+ numPoints.push_back(Vec(cos(omega*i),sin(omega*i)));
+ }
+ }
+ Points eval(float time) {
+ //points.
+ }
+
+
+};
+}
+}
+\ No newline at end of file