@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
259 lines • 9.12 kB
TypeScript
import { type TgdCamera } from "../camera";
import { TgdInputs } from "../input";
import { TgdTime } from "../time";
import type { TgdPainterFunction } from "../types/painter";
import { TgdEvent } from "../event";
import { TgdPainterGroup } from "../painter/group";
import type { TgdAnimation } from "../types/animation";
import { Console } from "./console";
import { UniformBufferObjectsManager } from "./ubo-manager";
import { WebglParams } from "./webgl-params";
import { TgdExtensions } from "./extensions";
/**
* You can pass all the attributes of the [WebGL2ContextAttributes](https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext)
* object.
* @see {@link TgdContext}
*/
export type TgdContextOptions = WebGLContextAttributes & {
/**
* You can override the behaviour for when a resize event occurs,
* by providing a callback `onResize(...)`.
*
* By default, this is what will happen:
* ```
* gl.canvas.width = width
* gl.canvas.height = height
* gl.viewport(0, 0, width, height)
* ```
*/
onResize?(this: void, context: TgdContext, width: number, height: number): void;
name?: string;
camera?: TgdCamera;
/**
* Function to initialize the context.
*
* If defined, it will be automatically called at the end of the construction process
* and after a WebGL context restore.
*/
initialize?: (context: TgdContext) => void;
/**
* Size of a pixel.
* - Use values over 1.0 for retina screens.
* - Under 1, you will start to have pixelated render.
*
* Defaut to 1.
*
* If you give a null or negative value, `globalThis.devicePixelRatio`
* will be used.
*/
resolution?: number;
/**
* TGD will write error and warning messages to the console
* in case of problems and if `verbose` is set to `true`.
*
* Defaults to `true`.
*/
verbose?: boolean;
};
/**
* This class gives you a [WebGL2RenderingContext](https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext) for a given canvas,
* through its public readonly attribute `gl`.
*
* It also takes care of the canvas resizing and the animation frames.
*
* @example
* ```
* import { TgdContext, TgdPainterClear } from "@tgd"
*
* export function paint(canvas: HTMLCanvasElement) {
* const ctx = new TgdContext(canvas)
* const clear = new TgdPainterClear(ctx, { color: [1, 0.667, 0, 1] })
* ctx.add(clear)
* ctx.paint()
* }
* ```
*/
export declare class TgdContext extends TgdPainterGroup {
readonly canvas: HTMLCanvasElement | OffscreenCanvas;
readonly options: Readonly<TgdContextOptions>;
private static incrementalId;
/**
* Ratio of the resolution in physical pixels to the resolution in CSS pixels
* for the current display device.
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio
*/
static get devicePixelRatio(): number;
readonly name: string;
readonly extensions: TgdExtensions;
/**
* TGD will write error and warning messages to the console
* in case of problems and if `verbose` is set to `true`.
*/
verbose: boolean;
readonly console: Console;
readonly virtualTime: TgdTime;
readonly inputs: TgdInputs;
readonly webglParams: WebglParams;
readonly implementationColorReadFormat: number;
readonly implementationColorReadType: number;
readonly eventResize: TgdEvent<{
width: number;
height: number;
}>;
/**
* Dispatched when everything has been painted.
*/
readonly eventPaint: TgdEvent<TgdContext>;
/**
* Dispatched before anything is painted.
*/
readonly eventPaintEnter: TgdEvent<TgdContext>;
/**
* Dispathed everytime we play or pause the main animation loop (`TgdContext.play()`, `TgdContext.pause()`).
*/
readonly eventPlayingChange: TgdEvent<boolean>;
/**
* When the browser decides to destroy the context.
* @see https://wikis.khronos.org/webgl/HandlingContextLost
*/
readonly eventWebGLContextLost: TgdEvent<TgdContext>;
/**
* At the point that setupWebGLStateAndResources is called the browser
* has reset all state to the default WebGL state and all previously
* allocated resources are invalid. So, you need to re-create textures,
* buffers, framebuffers, renderbuffers, shaders, programs,
* and setup your state (clearColor, blendFunc, depthFunc, etc...)
* @see https://wikis.khronos.org/webgl/HandlingContextLost
*/
readonly eventWebGLContextRestored: TgdEvent<TgdContext>;
resolution: number;
readonly uniformBufferObjects: UniformBufferObjectsManager;
private _gl;
/**
* If this function is set, it will be called once at the end of the next repaint.
* This is useful for snapshots.
*/
private doSnapshot;
private _camera;
private _width;
private _height;
private _fps;
private _aspectRatio;
private _aspectRatioInverse;
private readonly observer;
private paintingIsOngoing;
private paintingIsQueued;
private isPlaying;
private requestAnimationFrame;
private lastTimeInSec;
private readonly animationManager;
private readonly readPixelColor;
private readonly initialize?;
private readonly oneTimePainters;
/**
* @param canvas The canvas to which attach a WebGL2 context.
* @see {@link TgdContextOptions}
*/
constructor(canvas: HTMLCanvasElement | OffscreenCanvas, options?: Readonly<TgdContextOptions>);
viewportExec(action: () => void, viewport: Partial<{
x: number;
y: number;
width: number;
height: number;
}>): void;
get gl(): WebGL2RenderingContext;
get fps(): number;
get time(): number;
get camera(): TgdCamera;
set camera(camera: TgdCamera);
/**
* Check if the last WebGL command has returned an error.
* If an error has been found, output `caption` to the console (if verbose is true)
* and execute `action()`.
* Do not use this function in a loop because it is slow.
* @returns `true` is an error has been detected.
*/
checkError(caption: string, action?: () => void): boolean;
animSchedule(...animations: TgdAnimation[]): TgdAnimation[];
animCancel(animation: TgdAnimation): void;
animCancelArray(animations: TgdAnimation[]): void;
animDebug(caption?: string): void;
get width(): number;
private set width(value);
get height(): number;
private set height(value);
get aspectRatio(): number;
get aspectRatioInverse(): number;
set aspectRatio(aspectRatio: number);
/**
* Is the animation playing?
*/
get playing(): boolean;
/**
* If `playing` is true, the method `paint()` will be called
* for every animation frame.
* @see paint()
*/
set playing(value: boolean);
/**
* Start the animation.
* You can achieve the same result with `context.playing = true`.
*
* @see playing
*/
play(): void;
/**
* Pause the animation.
* You can achieve the same result with `context.playing = false`.
*
* @see playing
*/
pause(): void;
takeSnapshot(): Promise<HTMLImageElement>;
lookupWebglConstant(value: number): string;
/**
* Helper to test a context lost situation.
* @param restorationDelayInMilliseconds Time, in milliseconds, before the context is restored.
*/
loseContext(restorationDelayInMilliseconds?: number): void;
/**
* Most of the painters rely on the current viewport which is based on the canvas size.
* But if you want to paint in a framebuffer, you may want to use the texture widt/height
* instead.
*/
paintInCustomSize(width: number, height: number, paint: () => void): void;
private setCurrentSize;
/**
* When you need a painter to be painted only one time.
*
* These painters will be painted before all the recurrent ones during next repaint.
* The main purpose of this function is to use it with framebuffers that will
* update textures that could be used in normal paintings.
*/
readonly paintOneTime: (...painters: Array<{
paint: TgdPainterFunction;
}>) => void;
/**
* Trigger the painters to render the scene.
*/
readonly paint: () => void;
private now;
private readonly actualPaint;
/**
* Read the color of a pixel as a Uint8Array of size 4.
*
* Don't forget to use `preserveDrawingBuffer: true` in the creation options
* of the WebGL context.
*
* @param xScreen From -1 (left) to +1 (right)
* @param yScreen From -1 (bottom) to +1 (top)
* @returns The color of a pixel
*/
readPixel(xScreen: number, yScreen: number): Readonly<Uint8Array>;
delete({ preserveContextLostEvents, }?: {
preserveContextLostEvents?: boolean;
}): void;
private readonly createWebGLContext;
private stateReset;
}
//# sourceMappingURL=context.d.ts.map