/* * draws and captures the aurora drawing to sketch object, and outputs * sketch as jitter texture object */ public void bang() { // if(debug) post("begin_capture"); texture.call("begin_capture"); // begin capturing // if(debug) post("draw"); draw(); // draw aurora to sketch // if(debug) post("end_capture"); texture.call("end_capture"); // end capturing // if(debug) post("draw"); texture.call("draw"); // to output texture? outlet(0, "jit_gl_texture", texture.getAttr("name")); // output texture }
// function that draws already calculated pattern public void drawPaisley(int _i, float _x, float _y, float _sx, float _sy, boolean calc) { if (calc) renderDrawPaisley(_i, _x, _y, _sx, _sy); else { float _mirror = mMirrorDistance * _sx; for (int e = 0; e < eNum; e++) { float _dir = 1; // mirror x values in opposite direction // mirror the bezier for (int m = 0; m < 2; m++) { if (m == 0 || (m == 1 && _mirrored)) { if (m == 1) _dir *= -1; // --- - - - - - - - - --- - -draw BEZIER - - - -- - - -- - -- - -- -- -- - ---- sketch.call("glcolor", pColor()); // same color for all patterns sketch.call("glbegin", "tri_strip"); for (int i = 0; i <= bSlices; i++) { // x + _mirror*_dir + bezierPoint[_t][0]*_sx*_dir + _offOutside[0]*_sx*_dir; // y + bezierPoint[_t][1]*_sy + _offOutside[1]*_sy float x1 = _x + _mirror * _dir + masterBezierOffset[e][i][0][0] * _sx * _dir; float y1 = _y + masterBezierOffset[e][i][0][1] * _sy; float z1 = 0; float x2 = _x + _mirror * _dir + masterBezierOffset[e][i][1][0] * _sx * _dir; float y2 = _y + masterBezierOffset[e][i][1][1] * _sy; float z2 = 0; sketch.call( "glvertex", new Atom[] {Atom.newAtom(x1), Atom.newAtom(y1), Atom.newAtom(z1)}); sketch.call( "glvertex", new Atom[] {Atom.newAtom(x2), Atom.newAtom(y2), Atom.newAtom(z2)}); } sketch.call("glend"); } // --- - - - - - - - - --- - - --end drawing -- - - -- - -- - -- -- -- - ---- - } } } }
public void bang() { sketch.send("reset"); sweep.update(); sweep.draw(); for (SeqNode n : nodes) { n.update(mousecoord, sweep.getRad()); n.draw(); } }
public void fsaa(int v) { sketchFsaa = (v == 1) ? 1 : 0; sketch.setAttr("fsaa", sketchFsaa); }
public void antialias(int v) { sketchAntialias = (v == 1) ? 1 : 0; sketch.setAttr("antialias", sketchAntialias); }
public void blendMode(int b1, int b2) { sketchBlendMode1 = b1; sketchBlendMode2 = b2; sketch.setAttr("blend_mode", new Atom[] {Atom.newAtom(b1), Atom.newAtom(b2)}); }
public void blendEnable(int v) { sketchBlendEnable = (v == 1) ? 1 : 0; sketch.setAttr("blend_enable", sketchBlendEnable); }
public void depthEnable(int v) { sketchDepthEnable = (v == 1) ? 1 : 0; sketch.setAttr("depth_enable", sketchDepthEnable); }
public void resize(int x, int y) { texture_width = x; texture_height = y; texture.setAttr("dim", new Atom[] {Atom.newAtom(texture_width), Atom.newAtom(texture_height)}); if (debug) post("resized to " + x + " " + y); }
/* draw n-grade bezier with strokewidth that converges at endpoints */ public void drawBezier( int _i, float x, float y, float[][] points, float w, float _sx, float _sy) { int slices = bSlices; // TODO calculate slices based on curve length ? float _add = 1.f / (float) (slices); // defines segments of curve /* calculate all bezier points and their offset vectors beforehand */ float[][] bezierPoint = new float[slices + 1][3]; float[][] offsetVector = new float[slices + 1][3]; // calculate all points along the bezier curve for (int _t = 0; _t <= slices; _t++) { float t = _t * _add; bezierPoint[_t] = P(t, points); } // calculate vector perpendicular to the line connecting the previous and next bezier point for (int _t = 0; _t <= slices; _t++) { if (_t == 0) offsetVector[_t] = perpendicularVector(bezierPoint[_t], bezierPoint[_t + 1]); else if (_t == slices) offsetVector[_t] = perpendicularVector(bezierPoint[_t - 1], bezierPoint[_t]); else offsetVector[_t] = perpendicularVector(bezierPoint[_t - 1], bezierPoint[_t + 1]); } // calculate offsetPoints before drawing. float _scw = w; float[][][] bezierOffset = new float[slices + 1][2][3]; // hold offset points on both sides of curve float _mirror = mMirrorDistance * _sx; float _dir = 1; // mirror x values in opposite direction // mirror the bezier for (int m = 0; m < 2; m++) { if (m == 0 || (m == 1 && _mirrored)) { if (m == 1) _dir *= -1; for (int _t = 0; _t <= slices; _t++) { float t = _t * _add; _scw = restrict(halfCircle(t) * w, 0.01f, 100f); float[] _offOutside = scaleVector(offsetVector[_t], _scw); float[] _offInside = scaleVector(offsetVector[_t], -_scw); bezierOffset[_t][0][0] = x + _mirror * _dir + bezierPoint[_t][0] * _sx * _dir + _offOutside[0] * _sx * _dir; bezierOffset[_t][1][0] = x + _mirror * _dir + bezierPoint[_t][0] * _sx * _dir + _offInside[0] * _sx * _dir; bezierOffset[_t][0][1] = y + bezierPoint[_t][1] * _sy + _offOutside[1] * _sy; bezierOffset[_t][1][1] = y + bezierPoint[_t][1] * _sy + _offInside[1] * _sy; bezierOffset[_t][0][2] = -0.f; bezierOffset[_t][1][2] = -0.f; } // --- - - - - - - - - --- - -draw BEZIER - - - -- - - -- - -- - -- -- -- - ---- // sketch.call("glcolor", pColor(_i)); // patterns individual color sketch.call("glcolor", pColor()); // same color for all patterns sketch.call("glbegin", "tri_strip"); for (int i = 0; i <= slices; i++) { sketch.call( "glvertex", new Atom[] { Atom.newAtom(bezierOffset[i][0][0]), Atom.newAtom(bezierOffset[i][0][1]), Atom.newAtom(bezierOffset[i][0][2]) }); // if(i!=0 && i!=slices) // don't draw the first and last point twice! sketch.call( "glvertex", new Atom[] { Atom.newAtom(bezierOffset[i][1][0]), Atom.newAtom(bezierOffset[i][1][1]), Atom.newAtom(bezierOffset[i][1][2]) }); } sketch.call("glend"); } // --- - - - - - - - - --- - - --end drawing -- - - -- - -- - -- -- -- - ---- - } }
/* draw aurora to jitter sketch object */ public void draw() { if (animation) randomize(noiseFactor / 100.f, returnFactor / 100.f); if (bgFading) { bgFadeCounter++; float fadeStep = bgFadeCounter * 1.f / (float) bgFadeTime; if (debug) post("fadestep " + fadeStep + " counter " + bgFadeCounter); bgColor[0] = bgColorFade1[0] + (bgColorFade2[0] - bgColorFade1[0]) * fadeStep; bgColor[1] = bgColorFade1[1] + (bgColorFade2[1] - bgColorFade1[1]) * fadeStep; bgColor[2] = bgColorFade1[2] + (bgColorFade2[2] - bgColorFade1[2]) * fadeStep; if (bgFadeCounter >= bgFadeTime) { // reached end of fade bgColor[0] = bgColorFade2[0]; bgColor[1] = bgColorFade2[1]; bgColor[2] = bgColorFade2[2]; bgFading = false; } } // if(debug) post("reset"); sketch.call("reset"); sketch.call( "glclearcolor", new Atom[] { Atom.newAtom(bgColor[0]), Atom.newAtom(bgColor[1]), Atom.newAtom(bgColor[2]), Atom.newAtom(bgColor[3]) }); sketch.call("glclear"); // if(debug) post("line_smooth"); if (lineSmooth) sketch.call("glenable", "line_smooth"); else sketch.call("gldisable", "line_smooth"); // create local variables, to avoid conflict when life-updating // variables while rendering float _size[] = new float[2]; // size from origin float _scale[] = new float[2]; float _pos[] = new float[2]; // origin position float _grid[] = new float[2]; for (int i = 0; i < 2; i++) { // only need x and y values mSize[i] = (morphing) ? mSize[i] += (pSize[i] - mSize[i]) * slew : pSize[i]; _size[i] = mSize[i]; mScale[i] = (morphing) ? mScale[i] += (pScale[i] - mScale[i]) * slew : pScale[i]; _scale[i] = mScale[i] * scaleMult; mPos[i] = (morphing) ? mPos[i] += (pPos[i] - mPos[i]) * slew : pPos[i]; _pos[i] = mPos[i]; mGrid[i] = (morphing) ? mGrid[i] += (pGrid[i] - mGrid[i]) * slew : pGrid[i]; _grid[i] = mGrid[i]; } int _slices = bSlices; mMirrorDistance = (morphing) ? mMirrorDistance += (mirrorDistance - mMirrorDistance) * slew : mirrorDistance; // new drawing loop, create 16x9 grid and only draw if item is within frame float borderx = -_grid[0] * cols / 2.f; float bordery = _grid[1] * rows / 2.f; float wratio = 0.1f + (float) texture_width / (float) texture_height; float hratio = 0.1f + 1.f; // add 0.1f to avoid on/off flickr on edges float flip = 1.f; int count = 0; // to calculate how many patterns are actually displayed for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { int id = r * cols + c; if (displayed[id]) { float _x = borderx + c * _grid[0]; _x += (r % 2 == 0) ? _grid[0] / 2.f : 0; // each second is shifted to the right float _y = bordery - r * _grid[1]; flip = (r % 2 == 0) ? 1f : -1f; _x *= _size[0]; _y *= _size[1]; if (_x >= -wratio && _x <= wratio && _y >= -hratio + cutOff * 2 && _y <= hratio) { count++; if (displayMode == 1) { // twin flip *= flipTwin ? -1.f : 1.f; drawPaisley( id, (_pos[0] + _x), (_pos[1] + _y - _grid[1] * _size[1]), _scale[0] * _size[0], _scale[1] * flip * _size[1], activated[id] && precalc); drawPaisley( id, (_pos[0] + _x), (_pos[1] + _y), _scale[0] * _size[0], _scale[1] * flip * -1 * _size[1], activated[id] && precalc); } else { drawPaisley( id, (_pos[0] + _x), (_pos[1] + _y), _scale[0] * _size[0], _scale[1] * flip * _size[1], activated[id] && precalc); } } } } } // post("drawing "+count+" patterns"); // if(debug) post("drawimmediate"); // call drawimmediate, to execute drawing of sketch object // try { sketch.call("drawimmediate"); // } catch(Exception e) { // if(debug) post("drawimmediate error: "+e); // } // if(debug) post("after drawimmediate"); }
// notifyDeleted is called by the Max application // when the user deletes your external from a Max patch // or closes a Max patch of which your Java extern // is a member. public void notifyDeleted() { // free max peers. otherwise these will persist for a while // until the garbage collector feels like cleaning up texture.freePeer(); sketch.freePeer(); }
/* instantiate mxj with render context as argument */ public FigurePaisley(String rc) { context = rc; // render context declareIO(2, 2); // declare 2 inlets, 1 outlet of DataTypes.ALL // assist message for inlets and outlets (mouse hover) setInletAssist(new String[] {"bang to compute and draw", "input settings"}); setOutletAssist( new String[] {"outputs jit.gl.texture object", "connect to thispatcher for gui updating"}); // instantiate Jitter sketch object sketch = new JitterObject("jit.gl.sketch"); sketch.setAttr("drawto", context); sketch.setAttr("depth_enable", sketchDepthEnable); sketch.setAttr("blend_enable", sketchBlendEnable); sketch.setAttr("blend_mode", new Atom[] {Atom.newAtom(6), Atom.newAtom(7)}); sketch.setAttr("antialias", sketchAntialias); sketch.setAttr( "glclearcolor", new Atom[] {Atom.newAtom(0.), Atom.newAtom(1.), Atom.newAtom(0.), Atom.newAtom(1.)}); sketch.setAttr("fsaa", sketchFsaa); sketch.send("automatic", 0); /* * set to not-automatic, to be able to use * begin_capture and drawimmediate for * capturing jit.gl.sketch as texture */ // instantiate Jitter texture object texture = new JitterObject("jit.gl.texture"); texture.setAttr("drawto", context); texture.setAttr("dim", new Atom[] {Atom.newAtom(texture_width), Atom.newAtom(texture_height)}); masterPattern = new float[eNumMax][bNum][3]; // even though we only use xy, keep xyz for consistency patternNoise = new float[pNumMax][eNumMax][bNum][3]; mPatternNoise = new float[pNumMax][eNumMax][bNum][3]; masterWidth = new float[eNumMax]; mMasterWidth = new float[eNumMax]; widthNoise = new float[pNumMax][eNumMax]; mWidthNoise = new float[pNumMax][eNumMax]; ePoints = new int[eNumMax]; eAnchor = new int[eNumMax]; activated = new boolean[pNumMax]; displayed = new boolean[pNumMax]; patternColor = new float[pNumMax][3]; for (int e = 0; e < eNumMax; e++) { masterWidth[e] = 0.05f; mMasterWidth[e] = 0.05f; ePoints[e] = bNum; eAnchor[e] = 0; for (int b = 0; b < bNum; b++) {} } for (int p = 0; p < pNumMax; p++) { for (int e = 0; e < eNumMax; e++) { for (int b = 0; b < bNum; b++) { mPatternNoise[p][e][b] = new float[] {0.f, 0.f, 0.f}; } mWidthNoise[p][e] = 0.f; } activated[p] = false; displayed[p] = true; for (int c = 0; c < 3; c++) patternColor[p][c] = 1.f; } for (int i = 0; i < 5; i++) activate(theActive[i], 1); createMasterPaisley(); randomize(0.1f, 0.f); display(displayMode); }
public void notifyDeleted() { sketch.freePeer(); }