UNPKG

@tolokoban/tgd

Version:

ToloGameDev library for WebGL2

259 lines 9.12 kB
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