Framebuffers
Framebuffers let you render offscreen and use the result later. They are useful for multi-pass effects, feedback loops, cached render passes, readback, and shader workflows. (@_@)
Create them with createFramebuffer().
Create a framebuffer
let fb;
t.setup(() => {
fb = t.createFramebuffer({
width: t.grid.cols,
height: t.grid.rows,
});
});Framebuffer width and height are in grid cells. If width or height is omitted from the options object, that dimension uses the current textmode grid size.
Render offscreen
t.draw(() => {
fb.begin();
t.clear();
t.char("A");
t.charColor(255, 120, 80);
t.rect(20, 10);
fb.end();
t.background(0);
t.rotateZ(t.frameCount);
t.image(fb);
});Everything between begin() and end() renders into the framebuffer instead of the active layer.
Draw a framebuffer
Framebuffers can be drawn with image():
t.image(fb);
t.image(fb, 40, 20);The optional width and height scale the framebuffer result in grid cells.
Multi-pass rendering
Use multiple framebuffers when one pass should feed another:
fbA.begin();
t.clear();
t.char("*");
t.rect(20, 10);
fbA.end();
fbB.begin();
t.shader(waveShader);
t.setUniform("u_source", fbA.textures[0]);
t.image(fbA);
t.shader(null);
fbB.end();
t.image(fbB);For feedback effects, ping-pong between two framebuffers so the current frame can sample the previous result.
Read and resize
readPixels() reads framebuffer data when you need CPU-side inspection or export support:
const pixels = fb.readPixels();resize() updates framebuffer dimensions:
fb.resize(t.grid.cols, t.grid.rows);Call dispose() when a manually created framebuffer is no longer needed.