Using jit.submatrix in Javascript

    Oct 17 2011 | 3:09 pm
    I am trying to use the matrixcalc() method on a jit.submatrix inside a Javascript and it seems not to behave as I expect.
    The goal of this little project is to take text and convert it into a texture for further use (rotation/translation/scaling) in OpenGL, all using procedural Javascript coding.
    Here's the code in question
    var matrix	= new JitterObject("jit.matrix"),
        render	= new JitterObject("",,
        text2d	= new JitterObject("",,
        findbounds	= new JitterObject("jit.findbounds"),
        submatrix	= new JitterObject("jit.submatrix");
    // Prepare up OpenGL context ( and jit.matrix)
    render.erase_color = [0, 0, 0, 1];
    render.blend_enable = 1;
    matrix.dim = [500, 28];
    // Set up text (
    text2d.color = [1, 1, 1, 1];
    text2d.position = render.screentoworld(0, 14);
    text2d.text("Testing a text");
    // Render the text
    	// Let jit.findbounds do its stuff
    findbounds.min = [.5, .5, .5, .5];
    findbounds.max = [1, 1, 1, 1];
    // findbounds.boundmin and findbounds.boundmax now have the dimensions of the text
    // Set up submatrix and process main matrix
    submatrix.offset = [findbounds.boundmin[0], findbounds.boundmin[1]];
    submatrix.dim	=  [findbounds.boundmax[0] - findbounds.boundmin[0],
    		    findbounds.boundmax[1] - indbounds.boundmin[1] ];
    // Variables texMatrix and textureID are declared globally
    texMatrix = new JitterObject("jit.matrix", 4, "char", submatrix.dim[0], submatrix.dim[1]);
    submatrix.matrixcalc(matrix, texMatrix); // Is this working?
    textureID = + "Tex";
    outlet(0, "render", "texture", textureID, "jit_matrix",;
    This takes some inspiration from Vanille Béchamel's example of measuring the start and end of rendered text inside Javascript. I am trying to extend that to create a submatrix that is just the area of the original matrix containing that text so that I can use it as a texture. The point of *that* exercise being that rendering text has been significantly slowing down my redraw rate in 3D scenes using several texts, and using textures in OpenGL land is supposed to give better performance.
    Any suggestions?

    • Oct 17 2011 | 3:13 pm
      PS: I noticed some work with jit.submatrix in Wes Smith's Lua announcement (now merely 4 years old), where he uses a frommatrix() method instead of matrixcalc(). I'm not sure if this is a Lua peculiarity or if this might be applicable to Javascripting.
      I'm not finding any documentation on this, am I missing something obvious?
    • Oct 17 2011 | 4:25 pm
      Hi Peter, jit.submatrix doesn't exist in JavaScript with Jitter. It was in the I released years ago as a beta as you astutely noted, but I had to do quite a bit of work to get that to happen. The situation for jit.submatrix is quite a bit different than what it is for the other 100+ jitter objects that are easily wrap-able in a scripting environment. In the official release of included in Max6, jit.submatrix is no more.
      That said, it should be possible to make a jit.submatrix-like interface in JS or Lua using jit.matrix and the dst-/src-dim attributes, the only difference being that there would need to be a temp buffer for the submatrix, which is not such a terrible cost IMHO.
    • Oct 18 2011 | 1:59 pm
      Thanks, Wes, even if that isn't quite the news I had hoped for.
      I'm confident that I could build a jit.submatrix lookalike using the C API, having done something similar a few years ago for the BIX project. The Javascript API does not, I think, expose as much of the innards of Jitter data structures. But if you say it can be done, I'm game to take a stab at it.
      Would you have the time to sketch out any more of the nitty-gritty involved? I know y'all're very busy with Max 6, but I would be grateful for any pointers. There's still lots of the Javascript/Jitter world where I don't my way around as well.
      Best -- P.
    • Oct 18 2011 | 9:43 pm
      Here's something to get you started.
    • Oct 19 2011 | 10:13 am
      Thank you, Jesse! This is a big help.
    • Oct 28 2011 | 10:10 am
      Further unto… I've got the code now working, but the rendered text looks really awful. I'll attach examples of rendering directly to the screen ("Happiness") and by generating an intermediary matrix (as above -- "Dynamics). Rendering directly to screen looks much better but kills the redraw rate (a half-dozen texts can cut FPS from 33 to about half that).
      For the record, I modified the code from my first posting as follows (everything up to the jit.findbounds methods is the same).
      // Set up texture matrix and process main matrix
      var d = [findbounds.boundmax[0], findbounds.boundmax[1]]
      this.texMatrix = new JitterObject("jit.matrix", 4, "char", d[0], d[1]);
      this.texMatrix.usesrcdim	= 1;
      this.texMatrix.srcdimstart	= [findbounds.boundmin[0], findbounds.boundmin[1]];
      this.texMatrix.srcdimend	= d;
      // The following works but is inefficient.
      for(var i = 0; i < this.texMatrix.dim[0]; i++) for (var j = 0; j < this.texMatrix.dim[1]; j++) {
      	var cell = this.texMatrix.getcell(i, j);
      	cell[0] = (cell[1] > 50) ? 255 : cell[1];	// Arbitrary threshhold but works reasonably well for my purposes.
      	this.texMatrix.setcell2d(i, j, cell);
      this.textureID = + "Tex";
      outlet(0, "render", "texture", this.textureID, "jit_matrix",;
      Any suggestions for how to get the text to render more sharply than this?
    • Oct 28 2011 | 11:25 am
      OK, found a solution for this. Basically, I render the text to a matrix at double the font size I actually want it, then scale the texture back down by 50% when drawing to screen. Not sure why this trick should be necessary, but it works. And performance stays pretty hip.
      To render smaller font sizes a factor of 4 works even better.
    • Oct 27 2015 | 10:52 am
      Hi all, I was looking to do something similar, but to copy to a subregion of a destination matrix as well. I posted separately, link below, but I thought I'd link here as well in case someone stumbles across this post looking for a similar answer.