Skip to content

Instantly share code, notes, and snippets.

@limzykenneth
Last active February 5, 2024 22:21
Show Gist options
  • Save limzykenneth/37b52c2bed719a211d7d9f24eb6d47cd to your computer and use it in GitHub Desktop.
Save limzykenneth/37b52c2bed719a211d7d9f24eb6d47cd to your computer and use it in GitHub Desktop.
p5.js JSDoc Tests
/**
* @module Rendering
* @requires constants
*/
/**
* An object that one can draw to and then read as a texture. While similar
* to a p5.Graphics, using a p5.Framebuffer as a texture will generally run
* much faster, as it lives within the same WebGL context as the canvas it
* is created on. It only works in WebGL mode.
*
* @class Framebuffer
* @alias p5.Framebuffer
* @constructor
* @param {p5.Graphics|p5} target A p5 global instance or p5.Graphics
* @param {Object} [settings] A settings object
* @property {Number[]} pixels
*/
export class Framebuffer {
constructor() {
/**
* A <a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
* /Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>
* containing the values for all the pixels in the Framebuffer.
*
* Like the <a href="#/p5/pixels">main canvas pixels property</a>, call
* <a href="#/p5.Framebuffer/loadPixels">loadPixels()</a> before reading
* it, and call <a href="#/p5.Framebuffer.updatePixels">updatePixels()</a>
* afterwards to update its data.
*
* Note that updating pixels via this property will be slower than
* <a href="#/p5.Framebuffer/begin">drawing to the framebuffer directly.</a>
* Consider using a shader instead of looping over pixels.
*
* @type {Number[]}
* @public
*/
this.pixels = [];
}
/**
* Resizes the framebuffer to the given width and height.
*
* @param {Number} width
* @param {Number} height
*
* @example
* <div>
* <code>
* let framebuffer;
* function setup() {
* createCanvas(100, 100, WEBGL);
* framebuffer = createFramebuffer();
* noStroke();
* }
*
* function mouseMoved() {
* framebuffer.resize(
* max(20, mouseX),
* max(20, mouseY)
* );
* }
*
* function draw() {
* // Draw to the framebuffer
* framebuffer.begin();
* background(255);
* normalMaterial();
* sphere(20);
* framebuffer.end();
*
* background(100);
* // Draw the framebuffer to the main canvas
* image(framebuffer, -width/2, -height/2);
* }
* </code>
* </div>
*
* @alt
* A red, green, and blue sphere is drawn in the middle of a white rectangle
* which starts in the top left of the canvas and whose bottom right is at
* the user's mouse
*/
resize(width, height) {
}
/**
* Gets or sets the pixel scaling for high pixel density displays. By
* default, the density will match that of the canvas the framebuffer was
* created on, which will match the display density.
*
* Call this method with no arguments to get the current density, or pass
* in a number to set the density.
*
* @param {Number} [density] A scaling factor for the number of pixels per
* side of the framebuffer
*/
pixelDensity(density) {
}
/**
* Gets or sets whether or not this framebuffer will automatically resize
* along with the canvas it's attached to in order to match its size.
*
* Call this method with no arguments to see if it is currently auto-sized,
* or pass in a boolean to set this property.
*
* @param {Boolean} [autoSized] Whether or not the framebuffer should resize
* along with the canvas it's attached to
*/
autoSized(autoSized) {
}
/**
* Checks the capabilities of the current WebGL environment to see if the
* settings supplied by the user are capable of being fulfilled. If they
* are not, warnings will be logged and the settings will be changed to
* something close that can be fulfilled.
*
* @private
*/
_checkIfFormatsAvailable() {
}
/**
* Creates new textures and renderbuffers given the current size of the
* framebuffer.
*
* @private
*/
_recreateTextures() {
}
/**
* To create a WebGL texture, one needs to supply three pieces of information:
* the type (the data type each channel will be stored as, e.g. int or float),
* the format (the color channels that will each be stored in the previously
* specified type, e.g. rgb or rgba), and the internal format (the specifics
* of how data for each channel, in the aforementioned type, will be packed
* together, such as how many bits to use, e.g. RGBA32F or RGB565.)
*
* The format and channels asked for by the user hint at what these values
* need to be, and the WebGL version affects what options are avaiable.
* This method returns the values for these three properties, given the
* framebuffer's settings.
*
* @private
*/
_glColorFormat() {
}
/**
* To create a WebGL texture, one needs to supply three pieces of information:
* the type (the data type each channel will be stored as, e.g. int or float),
* the format (the color channels that will each be stored in the previously
* specified type, e.g. rgb or rgba), and the internal format (the specifics
* of how data for each channel, in the aforementioned type, will be packed
* together, such as how many bits to use, e.g. RGBA32F or RGB565.)
*
* This method takes into account the settings asked for by the user and
* returns values for these three properties that can be used for the
* texture storing depth information.
*
* @private
*/
_glDepthFormat() {
}
/**
* A method that will be called when recreating textures. If the framebuffer
* is auto-sized, it will update its width, height, and density properties.
*
* @private
*/
_updateSize() {
}
/**
* Called when the canvas that the framebuffer is attached to resizes. If the
* framebuffer is auto-sized, it will update its textures to match the new
* size.
*
* @private
*/
_canvasSizeChanged() {
}
/**
* Called when the size of the framebuffer has changed (either by being
* manually updated or from auto-size updates when its canvas changes size.)
* Old textures and renderbuffers will be deleted, and then recreated with the
* new size.
*
* @private
*/
_handleResize() {
}
/**
* Creates and returns a new
* <a href="#/p5.FramebufferCamera">p5.FramebufferCamera</a> to be used
* while drawing to this framebuffer. The camera will be set as the
* currently active camera.
*
* @returns {p5.Camera} A new camera
*/
createCamera() {
}
/**
* Given a raw texture wrapper, delete its stored texture from WebGL memory,
* and remove it from p5's list of active textures.
*
* @param {p5.FramebufferTexture} texture
* @private
*/
_deleteTexture(texture) {
}
/**
* Removes the framebuffer and frees its resources.
*
* @example
* <div>
* <code>
* let framebuffer;
* function setup() {
* createCanvas(100, 100, WEBGL);
* }
*
* function draw() {
* const useFramebuffer = (frameCount % 120) > 60;
* if (useFramebuffer && !framebuffer) {
* // Create a new framebuffer for us to use
* framebuffer = createFramebuffer();
* } else if (!useFramebuffer && framebuffer) {
* // Free the old framebuffer's resources
* framebuffer.remove();
* framebuffer = undefined;
* }
*
* background(255);
* if (useFramebuffer) {
* // Draw to the framebuffer
* framebuffer.begin();
* background(255);
* rotateX(frameCount * 0.01);
* rotateY(frameCount * 0.01);
* fill(255, 0, 0);
* box(30);
* framebuffer.end();
*
* image(framebuffer, -width/2, -height/2);
* }
* }
* </code>
* </div>
*
* @alt
* A rotating red cube blinks on and off every second.
*/
remove() {
}
/**
* Begin drawing to this framebuffer. Subsequent drawing functions to the
* canvas the framebuffer is attached to will not be immediately visible, and
* will instead be drawn to the framebuffer's texture. Call
* <a href="#/p5.Framebuffer/end">end()</a> when finished to make draw
* functions go right to the canvas again and to be able to read the
* contents of the framebuffer's texture.
*
* @example
* <div>
* <code>
* let framebuffer;
* function setup() {
* createCanvas(100, 100, WEBGL);
* framebuffer = createFramebuffer();
* noStroke();
* }
*
* function draw() {
* // Draw to the framebuffer
* framebuffer.begin();
* background(255);
* translate(0, 10*sin(frameCount * 0.01), 0);
* rotateX(frameCount * 0.01);
* rotateY(frameCount * 0.01);
* fill(255, 0, 0);
* box(50);
* framebuffer.end();
*
* background(100);
* // Draw the framebuffer to the main canvas
* image(framebuffer, -50, -50, 25, 25);
* image(framebuffer, 0, 0, 35, 35);
* }
* </code>
* </div>
*
* @alt
* A video of a floating and rotating red cube is pasted twice on the
* canvas: once in the top left, and again, larger, in the bottom right.
*/
begin() {
}
/**
* When making a p5.Framebuffer active so that it may be drawn to, this method
* returns the underlying WebGL framebuffer that needs to be active to
* support this. Antialiased framebuffers first write to a multisampled
* renderbuffer, while other framebuffers can write directly to their main
* framebuffers.
*
* @private
*/
_framebufferToBind() {
}
/**
* Ensures that the framebuffer is ready to be drawn to
*
* @private
*/
_beforeBegin() {
}
/**
* Ensures that the framebuffer is ready to be read by other framebuffers.
*
* @private
*/
_beforeEnd() {
}
/**
* After having previously called
* <a href="#/p5.Framebuffer/begin">begin()</a>, this method stops drawing
* functions from going to the framebuffer's texture, allowing them to go
* right to the canvas again. After this, one can read from the framebuffer's
* texture.
*/
end() {
}
/**
* Run a function while drawing to the framebuffer rather than to its canvas.
* This is equivalent to calling `framebuffer.begin()`, running the function,
* and then calling `framebuffer.end()`, but ensures that one never
* accidentally forgets `begin` or `end`.
*
* @param {Function} callback A function to run that draws to the canvas. The
* function will immediately be run, but it will draw to the framebuffer
* instead of the canvas.
*
* @example
* <div>
* <code>
* let framebuffer;
* function setup() {
* createCanvas(100, 100, WEBGL);
* framebuffer = createFramebuffer();
* noStroke();
* }
*
* function draw() {
* // Draw to the framebuffer
* framebuffer.draw(function() {
* background(255);
* translate(0, 10*sin(frameCount * 0.01), 0);
* rotateX(frameCount * 0.01);
* rotateY(frameCount * 0.01);
* fill(255, 0, 0);
* box(50);
* });
*
* background(100);
* // Draw the framebuffer to the main canvas
* image(framebuffer, -50, -50, 25, 25);
* image(framebuffer, 0, 0, 35, 35);
* }
* </code>
* </div>
*
* @alt
* A video of a floating and rotating red cube is pasted twice on the
* canvas: once in the top left, and again, larger, in the bottom right.
*/
draw(callback) {
}
/**
* Call this befpre updating <a href="#/p5.Framebuffer/pixels">pixels</a>
* and calling <a href="#/p5.Framebuffer/updatePixels">updatePixels</a>
* to replace the content of the framebuffer with the data in the pixels
* array.
*/
loadPixels() {
}
/**
* Get a region of pixels from the canvas in the form of a
* <a href="#/p5.Image">p5.Image</a>, or a single pixel as an array of
* numbers.
*
* Returns an array of [R,G,B,A] values for any pixel or grabs a section of
* an image. If the Framebuffer has been set up to not store alpha values, then
* only [R,G,B] will be returned. If no parameters are specified, the entire
* image is returned.
* Use the x and y parameters to get the value of one pixel. Get a section of
* the display window by specifying additional w and h parameters. When
* getting an image, the x and y parameters define the coordinates for the
* upper-left corner of the image, regardless of the current <a href="#/p5/imageMode">imageMode()</a>.
*
* @param {Number} x x-coordinate of the pixel
* @param {Number} y y-coordinate of the pixel
* @param {Number} w width of the section to be returned
* @param {Number} h height of the section to be returned
* @return {p5.Image} the rectangle <a href="#/p5.Image">p5.Image</a>
*/
/**
* @return {p5.Image} the whole <a href="#/p5.Image">p5.Image</a>
*/
/**
* @param {Number} x
* @param {Number} y
* @return {Number[]} color of pixel at x,y in array format [R, G, B, A]
*/
get(x, y, w, h) {
}
/**
* Call this after initially calling <a href="#/p5.Framebuffer/loadPixels">
* loadPixels()</a> and updating <a href="#/p5.Framebuffer/pixels">pixels</a>
* to replace the content of the framebuffer with the data in the pixels
* array.
*
* This will also clear the depth buffer so that any future drawing done
* afterwards will go on top.
*
* @example
* <div>
* <code>
* let framebuffer;
* function setup() {
* createCanvas(100, 100, WEBGL);
* framebuffer = createFramebuffer();
* }
* function draw() {
* noStroke();
* lights();
*
* // Draw a sphere to the framebuffer
* framebuffer.begin();
* background(0);
* sphere(25);
* framebuffer.end();
*
* // Load its pixels and draw a gradient over the lower half of the canvas
* framebuffer.loadPixels();
* for (let y = height/2; y < height; y++) {
* for (let x = 0; x < width; x++) {
* const idx = (y * width + x) * 4;
* framebuffer.pixels[idx] = (x / width) * 255;
* framebuffer.pixels[idx + 1] = (y / height) * 255;
* framebuffer.pixels[idx + 2] = 255;
* framebuffer.pixels[idx + 3] = 255;
* }
* }
* framebuffer.updatePixels();
*
* // Draw a cube on top of the pixels we just wrote
* framebuffer.begin();
* push();
* translate(20, 20);
* rotateX(0.5);
* rotateY(0.5);
* box(20);
* pop();
* framebuffer.end();
*
* image(framebuffer, -width/2, -height/2);
* noLoop();
* }
* </code>
* </div>
*
* @alt
* A sphere partly occluded by a gradient from cyan to white to magenta on
* the lower half of the canvas, with a 3D cube drawn on top of that in the
* lower right corner.
*/
updatePixels() {
}
}
@limzykenneth
Copy link
Author

npx documentation build ./test-class.js -o docs/p5.Framebuffer.json -a "public" -a "private" -a "protected" -a "undefined

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment