diff --git a/.gitignore b/.gitignore index bc838dba..06cf9e38 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ node_modules/* coverage/* bench/*.html www +dist diff --git a/dist/regl.d.ts b/dist/regl.d.ts deleted file mode 100644 index 64925c85..00000000 --- a/dist/regl.d.ts +++ /dev/null @@ -1,1747 +0,0 @@ -// Type definitions for regl 2.0.0 -// Project: regl -// Definitions by: Stepan Stolyarov , David Schneider - -/*~ Note that ES6 modules cannot directly export callable functions. - *~ This file should be imported using the CommonJS-style: - *~ - *~ ```typescript - *~ import REGL = require('regl'); - *~ ``` - *~ - *~ Refer to the documentation to understand common - *~ workarounds for this limitation of ES6 modules. - */ - -/*~ This module is a UMD module that exposes a global function `createREGL`. */ -export as namespace createREGL; - -export = REGL; - -/** - * Creates a full screen canvas element and a WebGL rendering context. - */ -declare function REGL(): REGL.Regl; - -/** - * Creates a WebGL rendering context using an element selected by `selector`. - * This may be: - * 1) an existing HTMLCanvasElement - * 2) an element that contains a canvas - * 3) an element in which you'd like `regl` to create a canvas - * - * @param selector an argument to `document.querySelector` - */ -declare function REGL(selector: string): REGL.Regl; - -/** - * Creates a canvas element and a WebGL rendering context in a given container element. - * - * @param container an HTML element - */ -declare function REGL(container: HTMLElement): REGL.Regl; - -/** - * Creates a WebGL rendering context using a `` element. - * - * @param canvas HTML canvas element - */ -declare function REGL(canvas: HTMLCanvasElement): REGL.Regl; - -/** - * Wraps an existing WebGL rendering context. - * - * @param gl WebGL rendering context - */ -declare function REGL(gl: WebGLRenderingContext): REGL.Regl; - -/** - * Creates a WebGL according to specified `options` - */ -declare function REGL(options: REGL.InitializationOptions): REGL.Regl; - -declare namespace REGL { - /** - * `Regl` represents the object/function returned from the `REGL` constructor. It exposes the - * entire public interface of the `regl` library. - */ - export interface Regl { - /** - * The context creation attributes passed to the WebGL context constructor. - */ - readonly attributes: WebGLContextAttributes; - /** - * `regl` is designed in such a way that you should never have to directly access the underlying - * WebGL context. However, if you really absolutely need to do this for some reason (for example - * to interface with an external library), you can still get a reference to the WebGL context - * via the property `_gl`. - */ - readonly _gl: WebGLRenderingContext; - /** - * `regl` exposes info about the WebGL context limits and capabilities via the `limits` object. - */ - readonly limits: REGL.Limits; - /** - * `regl` tracks several metrics for performance monitoring. These can be read using the `stats` object. - */ - readonly stats: REGL.Stats; - - /** - * Creates a new REGL command. The resulting command, when executed, - * will set a WebGL state machine to a specified `state`. - */ - < - Uniforms extends {} = {}, - Attributes extends {} = {}, - Props extends {} = {}, - OwnContext extends {} = {}, - ParentContext extends REGL.DefaultContext = REGL.DefaultContext - >( - drawConfig: REGL.DrawConfig, - ): REGL.DrawCommand; - - /** - * Clears selected buffers to specified values. - * If an option is not present, then the corresponding buffer is not cleared. - * Relevant WebGL API: `gl.clear` - */ - clear(options: REGL.ClearOptions): void; - - /* Reading pixels */ - - /** - * Read entire screen. - * NB: Reading into a Float32Array requires OES_texture_float. - */ - read(): T; - - /** - * Read entire screen into an existing TypedArray. - * NB: Reading into a Float32Array requires OES_texture_float. - */ - read(data: T): T; - - /** - * Read a selected region of screen or framebuffer. - * NB: Reading into a Float32Array requires OES_texture_float. - */ - read(options: REGL.ReadOptions): T; - - /** - * Dynamic variable binding - * - * `prop`, `context`, and `this` generate DynamicVariables, which can be used as values in a - * REGL.DrawConfig object. A DynamicVariable is an abstraction that will render a value only - * when the DrawCommand with which it's associated is invoked. - */ - - /* Retrieve the property `name` passed when the draw command is executed. */ - prop(name: Key): DynamicVariable; - /* Retrieve the context property `name` when the draw command is executed. */ - context(name: K): DynamicVariable; - /* Retrieve the property `name` of the object in whose context the draw command is executing. */ - this(name: Key): DynamicVariable; - - /* Drawing */ - - /** Executes an empty draw command. */ - draw(): void; - - /* Resource creation */ - - /** Creates an empty buffer of length `length`. */ - buffer(length: number): REGL.Buffer; - /** Creates a buffer with the provided `data`. */ - buffer(data: REGL.BufferData): REGL.Buffer; - /** Creates a buffer using creation `options`. */ - buffer(options: REGL.BufferOptions): REGL.Buffer; - - /* Creates an Elements object with the provided `data`. */ - elements(data: REGL.ElementsData): REGL.Elements; - /* Creates an Elements object using creation `options`. */ - elements(options: REGL.ElementsOptions): REGL.Elements; - - /* Creates a 2D Texture of dimensions 1 x 1. */ - texture(): REGL.Texture2D; - /* Creates a 2D Texture of dimensions `radius` x `radius`. */ - texture(radius: number): REGL.Texture2D; - /* Creates a 2D Texture of dimensions `width` x `height`. */ - texture(width: number, height: number): REGL.Texture2D; - /* Creates a 2D Texture using the provided `data`. */ - texture(data: REGL.TextureImageData): REGL.Texture2D; - /* Creates a 2D Texture using creation `options`. */ - texture(options: REGL.Texture2DOptions): REGL.Texture2D; - - /* Creates a cube-map texture with faces of dimensions 1 x 1. */ - cube(): REGL.TextureCube; - /* Creates a cube-map texture with faces of dimensions `radius` x `radius`. */ - cube(radius: number): REGL.TextureCube; - /* Creates a cube-map texture using the provided image data for the six faces. */ - cube( - posXData: REGL.TextureImageData, negXData: REGL.TextureImageData, - posYData: REGL.TextureImageData, negYData: REGL.TextureImageData, - posZData: REGL.TextureImageData, negZData: REGL.TextureImageData - ): REGL.TextureCube; - /* Creates a cube-map texture using the provided creation options for the six faces. */ - cube( - posXOptions: REGL.Texture2DOptions, negXOptions: REGL.Texture2DOptions, - posYOptions: REGL.Texture2DOptions, negYOptions: REGL.Texture2DOptions, - posZOptions: REGL.Texture2DOptions, negZOptions: REGL.Texture2DOptions, - ): REGL.TextureCube; - /* Creates a cube-map texture using creation `options`. */ - cube(options: REGL.TextureCubeOptions): REGL.TextureCube; - - /* Creates a Renderbuffer of dimensions 1 x 1. */ - renderbuffer(): REGL.Renderbuffer; - /* Creates a Renderbuffer of dimensions `radius` x `radius`. */ - renderbuffer(radius: number): REGL.Renderbuffer; - /* Creates a Renderbuffer of dimensions `width` x `height`. */ - renderbuffer(width: number, height: number): REGL.Renderbuffer; - /* Creates a Renderbuffer using creation `options`. */ - renderbuffer(options: REGL.RenderbufferOptions): REGL.Renderbuffer; - - /* Creates a Framebuffer of dimensions 1 x 1. */ - framebuffer(): REGL.Framebuffer2D; - /* Creates a Framebuffer of dimensions `radius` x `radius`. */ - framebuffer(radius: number): REGL.Framebuffer2D; - /* Creates a Framebuffer of dimensions `width` x `height`. */ - framebuffer(width: number, height: number): REGL.Framebuffer2D; - /* Creates a Framebuffer using creation `options`. */ - framebuffer(options: REGL.FramebufferOptions): REGL.Framebuffer2D; - - /* Creates a FramebufferCube whose faces have dimensions 1 x 1. */ - framebufferCube(): REGL.FramebufferCube; - /* Creates a FramebufferCube whose faces have dimensions `radius` x `radius`. */ - framebufferCube(radius: number): REGL.FramebufferCube; - /* Creates a FramebufferCube using creation `options`. */ - framebufferCube(options: REGL.FramebufferCubeOptions): REGL.FramebufferCube; - - /* Creates a vertex array object */ - vao(attributes: REGL.AttributeState[] | REGL.VertexArrayOptions) : REGL.VertexArrayObject; - - /* Events and listeners */ - - /** - * Registers a `callback` to be called on each animation frame. - * - * This method integrates with `requestAnimationFrame` and context loss - * events. It also calls `gl.flush` and drains several internal buffers, - * so you should try to do all your rendering to the drawing buffer within - * the frame callback. - */ - frame(callback: REGL.FrameCallback): REGL.Cancellable; - - /** - * Registers a handler function to be called when the associated `regl` event is fired. - */ - on(type: 'frame', callback: REGL.FrameCallback): REGL.Cancellable - on(type: 'lost' | 'restore' | 'destroy', callback: () => void): REGL.Cancellable; - - /** - * Test if an extension is present. Argument is case insensitive. - * - * For more information on WebGL extensions, see the WebGL extension registry. - * - * Relevant WebGL APIs - * - * - [WebGL Extension Registry](https://www.khronos.org/registry/webgl/extensions/) - * - gl.getExtension - * - gl.getSupportedExtensions - * - * @param name case-insensitive name of WebGL extension - */ - hasExtension(name: string): boolean; - - /** - * Updates the values of internal times and recalculates the size of viewports. - */ - poll(): void; - - /** - * Returns Total time elapsed since regl was initialized in seconds. - */ - now(): number; - - /** - * Destroys the gl context and releases all associated resources. - */ - destroy(): void; - - /** - * `regl` is designed in such a way that you should never have to directly access the underlying - * WebGL context. However, if you really absolutely need to do this for some reason (for example - * to interface with an external library), you can still get a reference to the WebGL context - * via the property `REGL._gl`. Note, though, that if you have changed the WebGL state, you must - * call `_refresh` to restore the `regl` state in order to prevent rendering errors. - */ - _refresh(): void; - } - - interface InitializationOptions { - /** A reference to a WebGL rendering context. (Default created from canvas) */ - gl?: WebGLRenderingContext; - /** An HTML canvas element or a selector string to find this element. (Default created and appended to container)*/ - canvas?: string | HTMLCanvasElement; - /** A container element into which regl inserts a canvas or a selector string to find this element. (Default document.body) */ - container?: string | HTMLElement; - /** The context creation attributes passed to the WebGL context constructor. */ - attributes?: WebGLContextAttributes; - /** A multiplier which is used to scale the canvas size relative to the container. (Default window.devicePixelRatio) */ - pixelRatio?: number; - /** A list of extensions that must be supported by WebGL context. Default [] */ - extensions?: string | string[]; - /** A list of extensions which are loaded opportunistically. Default [] */ - optionalExtensions?: string | string[]; - /** If set, turns on profiling for all commands by default. (Default false) */ - profile?: boolean; - /** An optional callback which accepts a pair of arguments, (err, regl) that is called after the application loads. If not specified, context creation errors throw */ - onDone?: (err: Error | null, regl?: Regl) => void; - } - - interface DefaultContext { - /** The number of frames rendered */ - readonly tick: number; - /** Total time elapsed since regl was initialized in seconds */ - readonly time: number; - /** Width of the current viewport in pixels */ - readonly viewportWidth: number; - /** Height of the current viewport in pixels */ - readonly viewportHeight: number; - /** Width of the WebGL context drawing buffer */ - readonly drawingBufferWidth: number; - /** Height of the WebGL context drawing buffer */ - readonly drawingBufferHeight: number; - /** The pixel ratio of the drawing buffer */ - readonly pixelRatio: number; - } - - type UserContext< - ParentContext extends REGL.DefaultContext, - OwnContext extends {}, - Props extends {} - > = { - [Key in keyof OwnContext]: MaybeDynamic; - }; - - interface Cancellable { - cancel(): void; - } - - /** - * A handler function invoked when `regl` fires the "frame" event. It is passed the default Context. - */ - type FrameCallback = (context: REGL.DefaultContext) => void; - - interface DynamicVariable { - /** - * This type is supposed to be opaque. Properties are listed only because TS casts _anything_ to `DynamicVariable`. - * The type parameter `Return`, though unused in the body of the interface, is useful as a - * marker to ensure the correct type is rendered when the associated `DrawCommand` is invoked. - */ - readonly id: number; - readonly type: number; - readonly data: string; - } - - type DynamicVariableFn< - Return, - Context extends REGL.DefaultContext = REGL.DefaultContext, - Props extends {} = {} - > = - (context: Context, props: Props, batchId: number) => Return; - - type MaybeDynamic = - Type | - DynamicVariable | - DynamicVariableFn; - - type MaybeNestedDynamic = - { [K in keyof Type]: MaybeDynamic }; - - interface ClearOptions { - /** - * RGBA values (range 0-1) to use when the color buffer is cleared. Initial value: [0, 0, 0, 0]. - * Relevant WebGL API: `gl.clearColor` - */ - color?: REGL.Vec4; - /** - * Depth value (range 0-1) to use when the depth buffer is cleared. Initial value: 1. - * Relevant WebGL API: `gl.clearDepth` - */ - depth?: number; - /** - * The index used when the stencil buffer is cleared. Initial value: 0. - * Relevant WebGL API: `gl.clearStencil` - */ - stencil?: number; - /** - * Sets the target framebuffer to clear (if unspecified, uses the current framebuffer object). - * Relevant WebGL API: `gl.bindFrameBuffer` - */ - framebuffer?: REGL.Framebuffer | null; - } - - interface ReadOptions { - /** An optional TypedArray which gets the result of reading the pixels. (Default: `null`, i.e. return a new TypedArray) */ - data?: T | null; - /** The x-offset of the upper-left corner of the rectangle in pixels. (Default: `0`) */ - x?: number; - /** The y-offset of the upper-left corner of the rectangle in pixels. (Default: `0`) */ - y?: number; - /** The width of the rectangle in pixels. (Default: current framebuffer width) */ - width?: number; - /** The height of the rectangle in pixels (Default: current framebuffer height) */ - height?: number; - /** Sets the framebuffer to read pixels from. (Default: currently bound framebuffer) */ - framebuffer?: REGL.Framebuffer; - } - - /** - * Commands can be nested using scoping. If a `DrawCommand` is passed a `CommandBodyFn`, then the - * `DrawCommand` is evaluated and its state variables are saved as the defaults for all - * `DrawCommand`s invoked within the `CommandBodyFn`. - * - * @param context REGL context - * @param props additional parameters of a draw call - * @param batchId index of a command in a batch call - */ - type CommandBodyFn< - Context extends REGL.DefaultContext = REGL.DefaultContext, - Props extends {} = {} - > = (context: Context, props: Props, batchId: number) => void; - - /** - * Draw commands are the fundamental abstraction in regl. A draw command wraps up all of the WebGL - * state associated with a draw call (either drawArrays or drawElements) and packages it into a - * single reusable function. - */ - interface DrawCommand< - Context extends REGL.DefaultContext = REGL.DefaultContext, - Props extends {} = {} - > { - readonly stats: REGL.CommandStats; - - /** Run a command once. */ - (body?: REGL.CommandBodyFn): void; - /** Run a command `count` times. */ - (count: number, body?: REGL.CommandBodyFn): void; - /** Run a command with props. */ - (props: Partial, body?: REGL.CommandBodyFn): void; - /** Run a command batch. */ - (props: Array>, body?: REGL.CommandBodyFn): void; - } - - interface DrawConfig< - Uniforms extends {} = {}, - Attributes extends {} = {}, - Props extends {} = {}, - OwnContext extends {} = {}, - ParentContext extends REGL.DefaultContext = REGL.DefaultContext - > { - - /* Shaders */ - - /** Source code of vertex shader */ - vert?: MaybeDynamic; - /** Source code of fragment shader */ - frag?: MaybeDynamic; - - /** - * Object mapping user-defined keys to user-defined values to be accessed via `DynamicVariable`s - * or `DynamicVariableFn`s elsewhere in the `DrawConfig` or in scoped `DrawCommand`s. - * Context variables in `regl` are computed before any other parameters and can also be passed - * from a scoped command to any sub-commands. - * Both `DynamicVariable`s and `DynamicVariableFn`s can be used as values in the context object, - * making it possible to define new context properties derived from existing context properties - * or from `props`. - */ - context?: REGL.UserContext, - - /** - * Object mapping names of uniform variables to their values. - * To specify uniforms in GLSL structs use the fully qualified path with dot notation. - * example: `'nested.value': 5.3` - * To specify uniforms in GLSL arrays use the fully qualified path with bracket notation. - * example: `'colors[0]': [0, 1, 0, 1]` - * - * Related WebGL APIs - * - * - gl.getUniformLocation - * - gl.uniform - */ - uniforms?: REGL.MaybeDynamicUniforms, - - /** - * Object mapping names of attribute variables to their values. - * - * Related WebGL APIs - * - * - gl.vertexAttribPointer - * - gl.vertexAttrib - * - gl.getAttribLocation - * - gl.vertexAttibDivisor - * - gl.enableVertexAttribArray, gl.disableVertexAttribArray - */ - attributes?: REGL.MaybeDynamicAttributes, - - /** - * Configuration of vertex array object - */ - vao?: REGL.MaybeDynamic, - - /* Drawing */ - - /** - * Sets the primitive type. (Default: 'triangles', or inferred from `elements`) - */ - primitive?: MaybeDynamic; - /** - * Number of vertices to draw. (Default: 0, or inferred from `elements`) - */ - count?: MaybeDynamic; - /** - * Offset of primitives to draw. (Default: 0, or inferred from `elements`) - */ - offset?: MaybeDynamic; - /** - * Number of instances to draw. (Default: 0) - * - * Only applicable if the `ANGLE_instanced_arrays` extension is present. - */ - instances?: MaybeDynamic; - /** - * Element array buffer. (Default: `null`) - * - * Elements must be either an instance of REGL.Elements or else the arguments to REGL.Elements. - * If `elements` is specified while `primitive`, `count` and `offset` are not, - * then these values may be inferred from the state of the element array buffer. - */ - elements?: MaybeDynamic< - REGL.Elements | ElementsData | ElementsOptions | null, - ParentContext & OwnContext, - Props - >; - - /* Render target */ - - /** - * A framebuffer to be used as a target for drawing. (Default: `null`) - * Passing null sets the framebuffer to the drawing buffer. - * Updating the render target will modify the viewport. - * - * Related WebGL APIs - * - * - [gl.bindFramebuffer](https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindFramebuffer.xml) - */ - framebuffer?: MaybeDynamic; - - /* Profiling */ - - /** - * If set, turns on profiling for this command. (Default: `false`) - * Profiling stats can be accessed via the `stats` property of the `DrawCommand`. - */ - profile?: MaybeDynamic; - - /* Depth buffer */ - - /** - * Related WebGL APIs - * - * - gl.depthFunc - * - gl.depthMask - * - gl.depthRange - */ - depth?: MaybeDynamic; - - /* Blending */ - - /** - * Related WebGL APIs - * - * - gl.blendEquationSeparate - * - gl.blendFuncSeparate - * - gl.blendColor - */ - blend?: MaybeDynamic; - - /* Stencil */ - - /** - * Related WebGL APIs - * - * - gl.stencilFunc - * - gl.stencilMask - * - gl.stencilOpSeparate - */ - stencil?: MaybeDynamic; - - /* Polygon offset */ - - /** - * Related WebGL APIs - * - * - gl.polygonOffset - */ - polygonOffset?: MaybeDynamic; - - /* Culling */ - - cull?: MaybeDynamic; - - /* Front face */ - - /* Sets gl.frontFace. Default: 'ccw' */ - frontFace?: MaybeDynamic; - - /* Dithering */ - - /* Toggles `gl.DITHER`. Default: false */ - dither?: MaybeDynamic; - - /* Line width */ - - /* Sets `gl.lineWidth`. Default: 1 */ - lineWidth?: MaybeDynamic; - - /* Color mask */ - - /* Sets `gl.colorMask`. Default: [true, true, true, true] */ - colorMask?: MaybeDynamic; - - /* Sample coverage */ - - sample?: MaybeDynamic; - - /* Scissor */ - - scissor?: MaybeNestedDynamic; - - /* Viewport */ - - /** - * Sets `gl.viewport`. Default: {} - * Updating `viewport` will modify the context variables `viewportWidth` and `viewportHeight`. - */ - viewport?: MaybeDynamic; - } - - type PrimitiveType = - /** gl.POINTS */ - "points" | - /** gl.LINES */ - "lines" | - /** gl.LINE_STRIP */ - "line strip" | - /** gl.LINE_LOOP */ - "line loop" | - /** gl.TRIANGLES */ - "triangles" | - /** gl.TRIANGLE_STRIP */ - "triangle strip" | - /** gl.TRIANGLE_FAN */ - "triangle fan"; - - type Uniform = - boolean | - number | - boolean[] | - number[] | - Float32Array | - Int32Array; - - interface Uniforms { - [name: string]: Uniform; - } - - type MaybeDynamicUniforms< - Uniforms extends REGL.Uniforms, - Context extends REGL.DefaultContext, - Props extends {} - > = { - [Key in keyof Uniforms]: MaybeDynamic|MaybeDynamic[]; - } - - type AttributeState = - ConstantAttribute | - AttributeConfig | - REGL.Buffer | - REGL.BufferData; - - type Attribute = - number | - AttributeState; - - interface Attributes { - [name: string]: Attribute; - } - - type MaybeDynamicAttributes< - Attributes extends REGL.Attributes, - Context extends REGL.DefaultContext, - Props extends {} - > = { - [Key in keyof Attributes]: MaybeDynamic; - } - - interface ConstantAttribute { - constant: number | number[]; - } - - interface AttributeConfig { - /** A REGLBuffer wrapping the buffer object. (Default: null) */ - buffer?: REGL.Buffer|undefined|null|false; - /** The offset of the vertexAttribPointer in bytes. (Default: 0) */ - offset?: number|undefined; - /** The stride of the vertexAttribPointer in bytes. (Default: 0) */ - stride?: number|undefined; - /** Whether the pointer is normalized. (Default: false) */ - normalized?: boolean; - /** The size of the vertex attribute. (Default: Inferred from shader) */ - size?: number|undefined; - /** Sets gl.vertexAttribDivisorANGLE. Only supported if the ANGLE_instanced_arrays extension is available. (Default: 0) */ - divisor?: number|undefined; - /** Data type for attribute */ - type?: 'uint8'|'uint16'|'uint32'|'float'|'int8'|'int16'|'int32'; - } - - interface DepthTestOptions { - /* Toggles `gl.enable(gl.DEPTH_TEST)`. Default: true */ - enable?: boolean; - /* Sets `gl.depthMask`. Default: true */ - mask?: boolean; - /* Sets `gl.depthRange`. Default: [0, 1] */ - range?: [number, number]; - /* Sets `gl.depthFunc`. Default: 'less' */ - func?: REGL.ComparisonOperatorType; - } - - type ComparisonOperatorType = - /* `gl.NEVER` */ - "never" | - /* `gl.ALWAYS` */ - "always" | - /* `gl.LESS` */ - "less" | "<" | - /* `gl.LEQUAL` */ - "lequal" | "<=" | - /* `gl.GREATER` */ - "greater" | ">" | - /* `gl.GEQUAL` */ - "gequal" | ">=" | - /* `gl.EQUAL` */ - "equal" | "=" | - /* `gl.NOTEQUAL` */ - "notequal" | "!="; - - interface BlendingOptions { - /* Toggles `gl.enable(gl.BLEND)`. Default: false */ - enable?: boolean; - /** - * `equation` can be either a string or an object with the fields {rgb, alpha}. - * The former corresponds to `gl.blendEquation` and the latter to `gl.blendEquationSeparate`. - * Default: 'add' - */ - equation?: REGL.BlendingEquation | REGL.BlendingEquationSeparate; - /** - * `func` can be an object with the fields {src, dst} or {srcRGB, srcAlpha, dstRGB, dstAlpha}, - * with the former corresponding to gl.blendFunc and the latter to gl.blendFuncSeparate. - * Default: { src: 'src alpha', dst: 'one minus src alpha' } - */ - func?: REGL.BlendingFunctionCombined | REGL.BlendingFunctionSeparate; - /* Sets `gl.blendColor` */ - color?: REGL.Vec4; - } - - interface BlendingEquationSeparate { - rgb: REGL.BlendingEquation; - alpha: REGL.BlendingEquation; - } - - type BlendingEquation = - /* `gl.FUNC_ADD` */ - "add" | - /* `gl.FUNC_SUBTRACT` */ - "subtract" | - /* `gl.FUNC_REVERSE_SUBTRACT` */ - "reverse subtract" | - /* `gl.MIN_EXT`, requires `EXT_blend_minmax` */ - "min" | - /* `gl.MAX_EXT`, requires `EXT_blend_minmax` */ - "max"; - - interface BlendingFunctionCombined { - src: REGL.BlendingFunction; - dst: REGL.BlendingFunction; - } - - interface BlendingFunctionSeparate { - srcRGB: REGL.BlendingFunction; - srcAlpha: REGL.BlendingFunction; - dstRGB: REGL.BlendingFunction; - dstAlpha: REGL.BlendingFunction; - } - - type BlendingFunction = - /* `gl.ZERO` */ - "zero" | 0 | - /* `gl.ONE` */ - "one" | 1 | - /* `gl.SRC_COLOR` */ - "src color" | - /* `gl.ONE_MINUS_SRC_COLOR` */ - "one minus src color" | - /* `gl.SRC_ALPHA` */ - "src alpha" | - /* `gl.ONE_MINUS_SRC_ALPHA` */ - "one minus src alpha" | - /* `gl.DST_COLOR` */ - "dst color" | - /* `gl.ONE_MINUS_DST_COLOR` */ - "one minus dst color" | - /* `gl.DST_ALPHA` */ - "dst alpha" | - /* `gl.ONE_MINUS_DST_ALPHA` */ - "one minus dst alpha" | - /* `gl.CONSTANT_COLOR` */ - "constant color" | - /* `gl.ONE_MINUS_CONSTANT_COLOR` */ - "one minus constant color" | - /* `gl.CONSTANT_ALPHA` */ - "constant alpha" | - /* `gl.ONE_MINUS_CONSTANT_ALPHA` */ - "one minus constant alpha" | - /* `gl.SRC_ALPHA_SATURATE` */ - "src alpha saturate"; - - interface StencilOptions { - /* Toggles `gl.enable(gl.STENCIL_TEST)`. Default: false */ - enable?: boolean; - /* Sets `gl.stencilMask`. Default: -1 */ - mask?: number; - /* Sets `gl.stencilFunc`. Default: { cmp: 'always', ref: 0, mask: -1 } */ - func?: REGL.StencilFunction; - /** - * Sets `gl.stencilOpSeparate` for front face. - * Default: { fail: 'keep', zfail: 'keep', zpass: 'keep' } - */ - opFront?: REGL.StencilOperation; - /** - * Sets `gl.stencilOpSeparate` for back face. - * Default: { fail: 'keep', zfail: 'keep', zpass: 'keep' } - */ - opBack?: REGL.StencilOperation; - /* Sets opFront and opBack simultaneously (`gl.stencilOp`). */ - op?: REGL.StencilOperation; - } - - interface StencilFunction { - /* comparison function */ - cmp: REGL.ComparisonOperatorType; - /* reference value */ - ref: number; - /* comparison mask */ - mask: number; - } - - interface StencilOperation { - /* The stencil operation applied when the stencil test fails. */ - fail: REGL.StencilOperationType; - /* The stencil operation applied when the stencil test passes and the depth test fails. */ - zfail: REGL.StencilOperationType; - /* The stencil operation applied when when both stencil and depth tests pass. */ - zpass: REGL.StencilOperationType; - } - - type StencilOperationType = - /* `gl.ZERO` */ - "zero" | - /* `gl.KEEP` */ - "keep" | - /* `gl.REPLACE` */ - "replace" | - /* `gl.INVERT` */ - "invert" | - /* `gl.INCR` */ - "increment" | - /* `gl.DECR` */ - "decrement" | - /* `gl.INCR_WRAP` */ - "increment wrap" | - /* `gl.DECR_WRAP` */ - "decrement wrap"; - - interface PolygonOffsetOptions { - /* Toggles `gl.enable(gl.POLYGON_OFFSET_FILL)`. Default: false */ - enable?: boolean; - /* Sets `gl.polygonOffset`. Default: { factor: 0, units: 0 } */ - offset?: REGL.PolygonOffset; - } - - interface PolygonOffset { - factor: number; - units: number; - } - - interface CullingOptions { - /* Toggles `gl.enable(gl.CULL_FACE)`. Default: false */ - enable?: boolean; - /* Sets `gl.cullFace`. Default: 'back' */ - face?: REGL.FaceOrientationType; - } - - type FaceOrientationType = - /* `gl.FRONT` */ - "front" | - /* `gl.BACK` */ - "back"; - - type FaceWindingType = - /* `gl.CW` */ - "cw" | - /* `gl.CCW` */ - "ccw"; - - interface SamplingOptions { - /** Toggles `gl.enable(gl.SAMPLE_COVERAGE)`. Default: false */ - enable?: boolean; - /** Toggles `gl.enable(gl.SAMPLE_ALPHA_TO_COVERAGE)`. Default: false */ - alpha?: boolean; - /** Sets `gl.sampleCoverage`. Default: { value: 1, invert: false } */ - coverage?: REGL.SampleCoverage; - } - - interface SampleCoverage { - value: number; - invert: boolean; - } - - interface ScissorOptions { - /* Toggles gl.enable(gl.SCISSOR). Default: false */ - enable?: boolean; - /* Sets `gl.SCISSOR`. Default: {} */ - box?: REGL.BoundingBox; - } - - interface BoundingBox { - /* left coordinate of the box; Default: 0 */ - x?: number; - /* top coordiante of the box; Default: 0 */ - y?: number; - /* width of the box; Default: framebuffer width - `x` */ - width?: number; - /* height of the box; Default: framebuffer height - `y` */ - height?: number; - } - - /* - * Resources - */ - - /** - * A *resource* is a handle to a GPU resident object, like a texture, FBO or buffer. - */ - interface Resource { - /** - * relevant WebGL APIs: - * - `gl.deleteBuffer` - * - `gl.deleteTexture` - * - `gl.deleteRenderbuffer` - * - `gl.deleteFramebuffer` - */ - destroy(): void; - } - - interface VertexArrayObject extends REGL.Resource { - (attributes:REGL.AttributeState[] | REGL.VertexArrayOptions) : REGL.VertexArrayObject; - } - - interface Buffer extends REGL.Resource { - /** - * Wraps a WebGL array buffer object. - */ - readonly stats: { - /** The size of the buffer in bytes. */ - size: number; - } - - /** - * Reinitializes the buffer with the new content. - * Relevant WebGL API: `gl.bufferData` - */ - (data: REGL.BufferData): REGL.Buffer; - (options: REGL.BufferOptions): REGL.Buffer; - - /** - * Update a portion of the buffer, optionally starting at byte offset `offset`. - * Relevant WebGL API: `gl.bufferSubData` - */ - subdata(data: REGL.BufferData, offset?: number): REGL.Buffer; - subdata(options: REGL.BufferOptions, offset?: number): REGL.Buffer; - } - - interface BufferOptions { - /** The data for the vertex buffer. Default: null */ - data?: REGL.BufferData | null; - /** If `data` is `null` or not present reserves space for the buffer. Default: 0 */ - length?: number; - /** Sets array buffer usage hint. Default: 'static' */ - usage?: REGL.BufferUsageHint; - /** Data type for vertex buffer. Default: 'uint8' */ - type?: REGL.BufferDataType; - } - - type BufferData = - number[] | - number[][] | - Uint8Array | - Int8Array | - Uint16Array | - Int16Array | - Uint32Array | - Int32Array | - Float32Array; - - type BufferUsageHint = - /** gl.DRAW_STATIC */ - "static" | - /** gl.DYNAMIC_DRAW */ - "dynamic" | - /** gl.STREAM_DRAW */ - "stream"; - - type BufferDataType = - /** gl.UNSIGNED_BYTE */ - "uint8" | - /** gl.BYTE */ - "int8" | - /** gl.UNSIGNED_SHORT */ - "uint16" | - /** gl.SHORT */ - "int16" | - /** gl.UNSIGNED_INT */ - "uint32" | - /** gl.INT */ - "int32" | - /** gl.FLOAT */ - "float32" | "float"; - - interface Elements extends REGL.Resource { - /** - * Wraps a WebGL element array buffer object. - */ - - /** - * Reinitializes the element buffer with the new content. - * Relevant WebGL API: `gl.bufferData` - */ - (data: REGL.ElementsData): REGL.Elements; - (options: REGL.ElementsOptions): REGL.Elements; - - /** - * Update a portion of the element buffer, optionally starting at byte offset `offset`. - * Relevant WebGL API: `gl.bufferSubData` - */ - subdata(data: REGL.ElementsData, offset?: number): REGL.Elements; - subdata(options: REGL.ElementsOptions, offset?: number): REGL.Elements; - } - - interface ElementsOptions { - /** The data of the element buffer. (Default: null) */ - data?: REGL.ElementsData | null; - /** Usage hint (see gl.bufferData). (Default: 'static') */ - usage?: REGL.BufferUsageHint; - /** Length of the element buffer in bytes. (Default: 0, or inferred from `data`) */ - length?: number; - /** Default primitive type for element buffer. (Default: 0, or inferred from `data`) */ - primitive?: REGL.PrimitiveType; - /** Data type for element buffer. (Default: 'uint8') */ - type?: REGL.ElementsDataType; - /** Vertex count for element buffer. (Default: 0, or inferred from `data`) */ - count?: number; - } - - type ElementsData = - number[] | - number[][] | - Uint8Array | - Uint16Array | - Uint32Array; - - type ElementsDataType = - "uint8" | - "uint16" | - "uint32"; - - interface VertexArrayOptions { - attributes: AttributeState[]; - elements?: REGL.Elements | REGL.ElementsOptions | REGL.ElementsData | null; - count?:number; - offset?:number; - primitive?:PrimitiveType; - instances?:number; - } - - interface Texture extends Resource { - readonly stats: { - /** Size of the texture in bytes. */ - size: number; - } - - /** Width of texture. */ - readonly width: number; - /** Height of texture. */ - readonly height: number; - /** Texture format. */ - readonly format: REGL.TextureFormatType; - /** Texture data type. */ - readonly type: REGL.TextureDataType; - /** Texture magnification filter. */ - readonly mag: REGL.TextureMagFilterType; - /** Texture minification filter. */ - readonly min: REGL.TextureMinFilterType; - /** Texture wrap mode on S axis. */ - readonly wrapS: REGL.TextureWrapModeType; - /** Texture wrap mode on T axis. */ - readonly wrapT: REGL.TextureWrapModeType; - } - - type TextureFormatType = - /* `gl.ALPHA`; channels: 1; types: 'uint8', 'half float', 'float' */ - "alpha" | - /* `gl.LUMINANCE`; channels: 1; types: 'uint8', 'half float', 'float' */ - "luminance" | - /* `gl.LUMINANCE_ALPHA`; channels: 2; types: 'uint8', 'half float', 'float' */ - "luminance alpha" | - /* `gl.RGB`; channels: 3; types: 'uint8', 'half float', 'float' */ - "rgb" | - /* `gl.RGBA`; channels: 4; types: 'uint8', 'half float', 'float' */ - "rgba" | - /* `gl.RGBA4`; channels: 4; types: 'rgba4' */ - "rgba4" | - /* `gl.RGB5_A1`; channels: 4; types: 'rgba5 a1' */ - "rgb5 a1" | - /* `gl.RGB565`; channels: 3; types: 'rgb565' */ - "rgb565" | - /* `ext.SRGB`; channels: 3; types: 'uint8', 'half float', 'float' */ - "srgb" | - /* `ext.RGBA`; channels: 4; types: 'uint8', 'half float', 'float' */ - "srgba" | - /* `gl.DEPTH_COMPONENT`; channels: 1; types: 'uint16', 'uint32' */ - "depth" | - /* `gl.DEPTH_STENCIL`; channels: 2; 'depth stencil' */ - "depth stencil" | - /* `ext.COMPRESSED_RGB_S3TC_DXT1_EXT`; channels: 3; types: 'uint8' */ - "rgb s3tc dxt1" | - /* `ext.COMPRESSED_RGBA_S3TC_DXT1_EXT`; channels: 4; types: 'uint8' */ - "rgba s3tc dxt1" | - /* `ext.COMPRESSED_RGBA_S3TC_DXT3_EXT`; channels: 4; types: 'uint8' */ - "rgba s3tc dxt3" | - /* `ext.COMPRESSED_RGBA_S3TC_DXT5_EXT`; channels: 4; types: 'uint8' */ - "rgba s3tc dxt5" | - /* `ext.COMPRESSED_RGB_ATC_WEBGL`; channels: 3; types: 'uint8' */ - "rgb atc" | - /* `ext.COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL`; channels: 4; types: 'uint8' */ - "rgba atc explicit alpha" | - /* `ext.COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL`; channels: 4; types: 'uint8' */ - "rgba atc interpolated alpha" | - /* `ext.COMPRESSED_RGB_PVRTC_4BPPV1_IMG`; channels: 3; types: 'uint8' */ - "rgb pvrtc 4bppv1" | - /* `ext.COMPRESSED_RGB_PVRTC_2BPPV1_IMG`; channels: 3; types: 'uint8' */ - "rgb pvrtc 2bppv1" | - /* `ext.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG`; channels: 4; types: 'uint8' */ - "rgba pvrtc 4bppv1" | - /* `ext.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG`; channels: 4; types: 'uint8' */ - "rgba pvrtc 2bppv1" | - /* `ext.COMPRESSED_RGB_ETC1_WEBGL`; channels: 3; types: 'uint8' */ - "rgb etc1"; - - type TextureDataType = - /* `gl.UNSIGNED_BYTE` */ - "uint8" | - /* `gl.UNSIGNED_SHORT` */ - "uint16" | - /* `gl.UNSIGNED_INT` */ - "uint32" | - /* `gl.FLOAT` */ - "float" | "float32" | - /* `ext.HALF_FLOAT_OES` */ - "half float" | "float16"; - - /* Related WebGL API: `gl.MAG_FILTER` */ - type TextureMagFilterType = - /* `gl.NEAREST` */ - "nearest" | - /* `gl.LINEAR` */ - "linear"; - - /* Related WebGL API: `gl.MIN_FILTER` */ - type TextureMinFilterType = - /* `gl.NEAREST` */ - "nearest" | - /* `gl.LINEAR` */ - "linear" | - /* `gl.LINEAR_MIPMAP_LINEAR` */ - "linear mipmap linear" | "mipmap" | - /* `gl.NEAREST_MIPMAP_LINEAR` */ - "nearest mipmap linear" | - /* `gl.LINEAR_MIPMAP_NEAREST` */ - "linear mipmap nearest" | - /* `gl.NEAREST_MIPMAP_NEAREST` */ - "nearest mipmap nearest"; - - type TextureWrapModeType = - /* `gl.REPEAT` */ - "repeat" | - /* `gl.CLAMP_TO_EDGE` */ - "clamp" | - /* `gl.MIRRORED_REPEAT` */ - "mirror"; - - interface Texture2D extends Texture { - /* Reinitializes the texture in place with dimensions 1 x 1. */ - (): REGL.Texture2D; - /* Reinitializes the texture in place with dimensions `radius` x `radius`. */ - (radius: number): REGL.Texture2D; - /* Reinitializes the texture in place with dimensions `width` x `height`. */ - (width: number, height: number): REGL.Texture2D; - /* Reinitializes the texture in place using the provided `data`. */ - (data: REGL.TextureImageData): REGL.Texture2D; - /* Reinitializes the texture in place using creation `options`. */ - (options: REGL.Texture2DOptions): REGL.Texture2D; - - /** - * Replaces the part of texture with new data. - * - * @param data image data object, similar to arguments for the texture constructor - * @param x horizontal offset of the image within the texture (Default: `0`) - * @param y vertical offset of the image within the texture (Default: `0`) - * @param level mipmap level of the texture to modify (Default: `0`) - */ - /* Replaces the area at offset `x` (default: 0), `y` (default: 0), with `data`. */ - subimage(data: REGL.TextureImageData, x?: number, y?: number, level?: number): REGL.Texture2D; - /* Replaces a subset of the image using creation `options`. */ - subimage(options: Texture2DOptions, x?: number, y?: number, level?: number): REGL.Texture2D; - - /** Resizes the texture to `radius` x `radius`. */ - resize(radius: number): REGL.Texture2D; - /** Resizes the texture to dimensions `width` x `height`. */ - resize(width: number, height: number): REGL.Texture2D; - } - - interface Texture2DOptions { - /* Sets `width`, `height` and, optionally, `channels`. */ - shape?: [number, number] | [number, number, REGL.TextureChannelsType]; - /* Sets both width and height to the same value. */ - radius?: number; - /* Width of texture. Default: 0 */ - width?: number; - /* Height of texture. Default: 0 */ - height?: number; - /** - * Sets the number of color channels for the texture format. - * It can be used as an alternative to `format`. - * Default: null - */ - channels?: REGL.TextureChannelsType | null; - /** - * The following properties, `data` and `copy` are mutually exclusive. - */ - /* Image data for the texture. Default: null */ - data?: REGL.TextureImageData | null; - /* Create texture by copying the pixels in the current frame buffer. Default: false */ - copy?: boolean; - - /* Sets magnification filter. Default: 'nearest' */ - mag?: REGL.TextureMagFilterType; - /* Sets minification filter. Default: 'nearest' */ - min?: REGL.TextureMinFilterType; - /* Sets wrap mode for both axes, either to the same value, or independently, `[wrapS, wrapT]` */ - wrap?: REGL.TextureWrapModeType | [REGL.TextureWrapModeType, REGL.TextureWrapModeType]; - /* Sets wrap mode on S axis. Default: 'clamp' */ - wrapS?: REGL.TextureWrapModeType; - /* Sets wrap mode on T axis. Default: 'clamp' */ - wrapT?: REGL.TextureWrapModeType; - /* Sets number of anisotropic samples; requires `EXT_texture_filter_anisotropic`. Default: 0 */ - aniso?: number; - /* Determines the format of the texture and possibly also the type. Default: 'rgba' */ - format?: REGL.TextureFormatType; - /** - * Texture type. - * In many cases type can be inferred from the format and other information in the texture. - * However, in some situations it may still be necessary to set it manually. - * Default: 'uint8' - */ - type?: REGL.TextureDataType; - - /** - * If boolean, then it sets whether or not we should regenerate the mipmaps. - * - * If a string, it allows you to specify a hint to the mipmap generator. - * If a hint is specified, then also the mipmaps will be regenerated. - * - * Finally, mipmap can also be an array of arrays. In this case, every subarray will be one of - * the mipmaps, and you can thus use this option to manually specify the mipmaps of the image. - * - * Default: false - */ - mipmap?: boolean | REGL.TextureMipmapHintType | number[][]; - /* Flips textures vertically when uploading. Default: false */ - flipY?: boolean; - /* Sets unpack alignment per row. Default: 1 */ - alignment?: REGL.TextureUnpackAlignmentType; - /* Premultiply alpha when unpacking. Default: false */ - premultiplyAlpha?: boolean; - /* Sets the WebGL color space flag for pixel unpacking. Default: 'none' */ - colorSpace?: REGL.TextureColorSpaceType; - } - - type TextureImageData = - number[] | - number[][] | - number[][][] | - ArrayBufferView | - REGL.NDArrayLike | - HTMLImageElement | - HTMLVideoElement | - HTMLCanvasElement | - CanvasRenderingContext2D; - - /** - * An N-dimensional array, as per `scijs/ndarray`. - */ - interface NDArrayLike { - shape: number[]; - stride: number[]; - offset: number; - data: number[] | ArrayBufferView; - } - - type TextureMipmapHintType = - /* `gl.DONT_CARE` */ - "don't care" | "dont care" | - /* `gl.NICEST` */ - "nice" | - /* `gl.FASTEST` */ - "fast"; - - type TextureColorSpaceType = - /* `gl.NONE` */ - "none" | - /* gl.BROWSER_DEFAULT_WEBGL` */ - "browser"; - - type TextureChannelsType = 1 | 2 | 3 | 4; - - /* Related WebGL API: `gl.pixelStorei` */ - type TextureUnpackAlignmentType = - /* byte-alignment */ - 1 | - /* rows aligned to even-numbered bytes */ - 2 | - /* word-alignment */ - 4 | - /* rows start on double-word boundaries */ - 8; - - interface TextureCube extends Texture { - /* Reinitializes the texture in place with faces of dimensions 1 x 1. */ - (): REGL.TextureCube; - /* Reinitializes the texture in place with faces of dimensions `radius` x `radius`. */ - (radius: number): REGL.TextureCube; - /* Reinitializes the texture in place using the provided image data for the six faces. */ - ( - posXData: REGL.TextureImageData, negXData: REGL.TextureImageData, - posYData: REGL.TextureImageData, negYData: REGL.TextureImageData, - posZData: REGL.TextureImageData, negZData: REGL.TextureImageData - ): REGL.TextureCube; - /* Reinitializes the texture in place using the provided creation options for the six faces. */ - ( - posXOptions: REGL.Texture2DOptions, negXOptions: REGL.Texture2DOptions, - posYOptions: REGL.Texture2DOptions, negYOptions: REGL.Texture2DOptions, - posZOptions: REGL.Texture2DOptions, negZOptions: REGL.Texture2DOptions, - ): REGL.TextureCube; - /* Reinitializes the texture in place using creation `options`. */ - (options: REGL.TextureCubeOptions): REGL.TextureCube; - - /** - * Replaces the part of texture with new data. - * - * @param face index of the face to modify - * @param data 2D image data object to use for the replacement - * @param x horizontal offset of the image within the face (Default: `0`) - * @param y vertical offset of the image within the face (Default: `0`) - * @param level mipmap level of the texture to modify (Default: `0`) - */ - subimage( - face: REGL.TextureCubeFaceIndex, - data: TextureImageData, - x?: number, - y?: number, - level?: number, - ): REGL.TextureCube; - - /** Resizes the cube-map texture, setting the dimensions of each face to `radius` x `radius`. */ - resize(radius: number): REGL.TextureCube; - } - - type TextureCubeFaceIndex = - /* positive X face */ - 0 | - /* negative X face */ - 1 | - /* positive Y face */ - 2 | - /* negative Y face */ - 3 | - /* positive Z face */ - 4 | - /* negative Z face */ - 5; - - interface TextureCubeOptions extends Texture2DOptions { - /* Uses the provided texture data for the six faces. */ - faces?: [ - TextureImageData, TextureImageData, - TextureImageData, TextureImageData, - TextureImageData, TextureImageData - ]; - } - - interface Renderbuffer extends REGL.Resource { - readonly stats: { - /** Size of the renderbuffer in bytes. */ - size: number; - } - - /** Width of the renderbuffer */ - readonly width: number; - /** Height of the renderbuffer */ - readonly height: number; - /** Format of the renderbuffer. */ - readonly format: number; - - /* Reinitializes the Renderbuffer in place using dimensions: 1 x 1. */ - (): REGL.Renderbuffer; - /* Reinitializes the Renderbuffer in place using dimensions: `radius` x `radius`. */ - (radius: number): REGL.Renderbuffer; - /* Reinitializes the Renderbuffer in place using dimensions: `width` x `height`. */ - (width: number, height: number): REGL.Renderbuffer; - /* Reinitializes the Renderbuffer in place using creation `options`. */ - (options: REGL.RenderbufferOptions): REGL.Renderbuffer; - - /* Resizes the Renderbuffer. */ - resize(radius: number): REGL.Renderbuffer; - resize(width: number, height: number): REGL.Renderbuffer; - } - - interface RenderbufferOptions { - /* NB: `shape`, `radius`, and `width`/`height` are alternative (and mutually exclusive) means for setting the size of the renderbuffer. */ - /* Sets the dimensions [width, height] for the renderbuffer. */ - shape?: [number, number]; - /* Sets the dimensions `radius` x `radius` for the renderbuffer. */ - radius?: number; - /* Sets the width of the renderbuffer. Default: `gl.drawingBufferWidth` */ - width?: number; - /* Sets the height of the renderbuffer. Default: `gl.drawingBufferHeight` */ - height?: number; - /** Sets the internal format of the render buffer. Default 'rgba4' */ - format?: REGL.RenderbufferFormat; - } - - type RenderbufferFormat = - REGL.RenderbufferColorFormat | - /* `gl.DEPTH_COMPONENT16` */ - "depth" | - /* `gl.STENCIL_INDEX8` */ - "stencil" | - /* `gl.DEPTH_STENCIL` */ - "depth stencil"; - - type RenderbufferColorFormat = - /* `gl.RGBA4` */ - "rgba4" | - /* `gl.RGB565` */ - "rgb565" | - /* `gl.RGB5_A1` */ - "rgb5 a1" | - /* `gl.RGB16F`, requires EXT_color_buffer_half_float */ - "rgb16f" | - /* `gl.RGBA16F`, requires EXT_color_buffer_half_float */ - "rgba16f" | - /* `gl.RGBA32F`, requires WEBGL_color_buffer_float */ - "rgba32f" | - /* `gl.SRGB8_ALPHA8`, requires EXT_sRGB */ - "srgba"; - - type Framebuffer = REGL.Framebuffer2D | REGL.FramebufferCube; - - interface Framebuffer2D extends REGL.Resource { - /* Reinitializes the Framebuffer in place using dimensions: 1 x 1. */ - (): REGL.Framebuffer2D; - /* Reinitializes the Framebuffer in place using dimensions: `radius` x `radius`. */ - (radius: number): REGL.Framebuffer2D; - /* Reinitializes the Framebuffer in place using dimensions: `width` x `height`. */ - (width: number, height: number): REGL.Framebuffer2D; - /* Reinitializes the Framebuffer in place using creation `options`. */ - (options: REGL.FramebufferOptions): REGL.Framebuffer2D; - - /* Framebuffer binding */ - - /* Binds a framebuffer directly. This is a short cut for creating a command which sets the framebuffer. */ - use< - Context extends REGL.DefaultContext = REGL.DefaultContext, - Props extends {} = {} - >(body: REGL.CommandBodyFn): void; - - /* Resizes the Framebuffer and all its attachments. */ - resize(radius: number): REGL.Framebuffer2D; - resize(width: number, height: number): REGL.Framebuffer2D; - } - - interface FramebufferOptions { - /* NB: `shape`, `radius`, and `width`/`height` are alternative (and mutually exclusive) means for setting the size of the framebuffer. */ - /* Sets the dimensions [width, height] for the framebuffer. */ - shape?: [number, number]; - /* Sets the dimensions `radius` x `radius` for the framebuffer. */ - radius?: number; - /* Sets the width of the framebuffer. Default: `gl.drawingBufferWidth` */ - width?: number; - /* Sets the height of the framebuffer. Default: `gl.drawingBufferHeight` */ - height?: number; - - /* NB: If neither `color` nor `colors` is specified, color attachments are created automatically. */ - /* A texture or renderbuffer for the color attachment. */ - color?: REGL.Framebuffer2DAttachment; - /* An array of textures or renderbuffers for the color attachments. */ - colors?: REGL.Framebuffer2DAttachment[]; - /* Sets the format of the color buffer. Ignored if `color` is specified. Default: 'rgba' */ - colorFormat?: REGL.FramebufferTextureColorFormat | REGL.RenderbufferColorFormat; - /* Sets the type of the color buffer if it is a texture. Default: 'uint8' */ - colorType?: REGL.FramebufferColorDataType; - /* Sets the number of color buffers. Values > 1 require WEBGL_draw_buffers. Default: 1 */ - colorCount?: number; - /* If boolean, toggles the depth attachment. If a renderbuffer or texture, sets the depth attachment. Default: true */ - depth?: boolean | REGL.Framebuffer2DAttachment; - /* If boolean, toggles the stencil attachments. If a renderbuffer or texture, sets the stencil attachment. Default: true */ - stencil?: boolean | REGL.Framebuffer2DAttachment; - /* If boolean, toggles both the depth and stencil attachments. If a renderbuffer or texture, sets the combined depth/stencil attachment. Default: true */ - depthStencil?: boolean | REGL.Framebuffer2DAttachment; - /* Toggles whether depth/stencil attachments should be in texture. Requires WEBGL_depth_texture. Default: false */ - depthTexture?: boolean; - } - - type Framebuffer2DAttachment = REGL.Texture2D | REGL.Renderbuffer; - - interface FramebufferCube extends REGL.Resource { - /* Reinitializes the FramebufferCube in place using face dimensions 1 x 1. */ - (): REGL.FramebufferCube; - /* Reinitializes the FramebufferCube in place using face dimensions `radius` x `radius`. */ - (radius: number): REGL.FramebufferCube; - /* Reinitializes the FramebufferCube in place using creation `options`. */ - (options: FramebufferCubeOptions): REGL.FramebufferCube; - - /* Resizes the FramebufferCube and all its attachments. */ - resize(radius: number): REGL.FramebufferCube; - - /* Faces of the FramebufferCube */ - faces: [ - REGL.Framebuffer, - REGL.Framebuffer, - REGL.Framebuffer, - REGL.Framebuffer, - REGL.Framebuffer - ] - } - - interface FramebufferCubeOptions { - /* NB: `shape`, `radius`, and `width`/`height` are alternative (and mutually exclusive) means for setting the size of the cube. */ - /* Sets the dimensions [width, height] for each face of the cube. Width must equal height. */ - shape?: [number, number]; - /* Sets the dimensions `radius` x `radius` for each face of the cube. */ - radius?: number; - /* Sets the width dimension for each face of the cube. Must equal `height`. */ - width?: number; - /* Sets the height dimension for each face of the cube. Must equal `width`. */ - height?: number; - - /* A TextureCube for the color attachment. */ - color?: REGL.TextureCube; - /* An array of TextureCubes for the color attachments. */ - colors?: REGL.TextureCube[]; - /* Sets the format of the color buffer. */ - colorFormat?: REGL.FramebufferTextureColorFormat; - /* Sets the type of the color buffer. */ - colorType?: REGL.FramebufferColorDataType; - /* Sets the number of color buffers. Values > 1 require WEBGL_draw_buffers. Default: 1 */ - colorCount?: number; - /* If boolean, toggles the depth attachment. If texture, sets the depth attachment. Default: true */ - depth?: boolean | REGL.TextureCube; - /* If boolean, toggles the stencil attachment. If texture, sets the stencil attachment. Default: true */ - stencil?: boolean | REGL.TextureCube; - /* If boolean, toggles both the depth and stencil attachments. If texture, sets the combined depth/stencil attachment. Default: true */ - depthStencil?: boolean | REGL.TextureCube; - } - - /* `gl.RGBA` */ - type FramebufferTextureColorFormat = "rgba"; - - type FramebufferColorDataType = - /* `gl.UNSIGNED_BYTE` */ - "uint8" | - /* `ext.HALF_FLOAT_OES` (16-bit float), requires OES_texture_half_float */ - "half float" | - /* `gl.FLOAT` (32-bit float), requires OES_texture_float */ - "float"; - - interface Limits { - /** An array of bits depths for the red, green, blue and alpha channels */ - colorBits: [number, number, number, number]; - /** Bit depth of drawing buffer */ - depthBits: number; - /** Bit depth of stencil buffer */ - stencilBits: number; - /** gl.SUBPIXEL_BITS */ - subpixelBits: number; - /** A list of all supported extensions */ - extensions: string[]; - /** Maximum number of anisotropic filtering samples */ - maxAnisotropic: number; - /** Maximum number of draw buffers */ - maxDrawbuffers: number; - /** Maximum number of color attachments */ - maxColorAttachments: number; - /** gl.ALIASED_POINT_SIZE_RANGE */ - pointSizeDims: Float32Array; - /** gl.ALIASED_LINE_WIDTH_RANGE */ - lineWidthDims: Float32Array; - /** gl.MAX_VIEWPORT_DIMS */ - maxViewportDims: Int32Array; - /** gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS */ - maxCombinedTextureUnits: number; - /** gl.MAX_CUBE_MAP_TEXTURE_SIZE */ - maxCubeMapSize: number; - /** gl.MAX_RENDERBUFFER_SIZE */ - maxRenderbufferSize: number; - /** gl.MAX_TEXTURE_IMAGE_UNITS */ - maxTextureUnits: number; - /** gl.MAX_TEXTURE_SIZE */ - maxTextureSize: number; - /** gl.MAX_VERTEX_ATTRIBS */ - maxAttributes: number; - /** gl.MAX_VERTEX_UNIFORM_VECTORS */ - maxVertexUniforms: number; - /** gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS */ - maxVertexTextureUnits: number; - /** gl.MAX_VARYING_VECTORS */ - maxVaryingVectors: number; - /** gl.MAX_FRAGMENT_UNIFORM_VECTORS */ - maxFragmentUniforms: number; - /** gl.SHADING_LANGUAGE_VERSION */ - glsl: string; - /** gl.RENDERER */ - renderer: string; - /** gl.VENDOR */ - vendor: string; - /** gl.VERSION */ - version: string; - /** A list of all supported texture formats */ - textureFormats: TextureFormatType[]; - } - - interface Stats { - /** The number of array buffers currently allocated */ - bufferCount: number; - /** The number of element buffers currently allocated */ - elementsCount: number; - /** The number of framebuffers currently allocated */ - framebufferCount: number; - /** The number of shaders currently allocated */ - shaderCount: number; - /** The number of textures currently allocated */ - textureCount: number; - /** The number of cube maps currently allocated */ - cubeCount: number; - /** The number of renderbuffers currently allocated */ - renderbufferCount: number; - /** The maximum number of texture units used */ - maxTextureUnits: number; - /** Number of vertex array objects */ - vaoCount: number; - - // The following functions are only available if regl is initialized with option `profile: true` - - /** The total amount of memory allocated for textures and cube maps */ - getTotalTextureSize?: () => number; - /** The total amount of memory allocated for array buffers and element buffers */ - getTotalBufferSize?: () => number; - /** The total amount of memory allocated for renderbuffers */ - getTotalRenderbufferSize?: () => number; - /** The maximum number of uniforms in any shader */ - getMaxUniformsCount?: () => number; - /** The maximum number of attributes in any shader */ - getMaxAttributesCount?: () => number; - } - - interface CommandStats { - /** The number of times the command has been called. */ - count: number; - /** - * The cumulative CPU time spent executing the command in milliseconds. - * `cpuTime` uses `performance.now` if available. Otherwise it falls back to `Date.now`. - */ - cpuTime: number; - /** - * The cumulative GPU time spent executing the command in milliseconds. - * (requires the `EXT_disjoint_timer_query` extension). - * GPU timer queries update asynchronously. If you are not using `regl.frame()` to tick your - * application, then you should periodically call `regl.poll()` each frame to update the timer - * statistics. - */ - gpuTime: number; - } - - /** - * The following types are defined for the convenience of clients of this library. They represent - * the most likely forms in which values being passed to shaders (via uniforms and attributes) are - * defined: flat JS arrays for vectors and either flat or two-dimensional JS arrays for matrices. - */ - - type Vec2 = [number, number]; - type Vec3 = [number, number, number]; - type Vec4 = [number, number, number, number]; - - type BVec2 = [boolean, boolean]; - type BVec3 = [boolean, boolean, boolean]; - type BVec4 = [boolean, boolean, boolean, boolean]; - - type Mat2 = [ - number, number, - number, number - ] | [ - REGL.Vec2, - REGL.Vec2 - ]; - - type Mat3 = [ - number, number, number, - number, number, number, - number, number, number - ] | [ - REGL.Vec3, - REGL.Vec3, - REGL.Vec3 - ]; - - type Mat4 = [ - number, number, number, number, - number, number, number, number, - number, number, number, number, - number, number, number, number - ] | [ - REGL.Vec4, - REGL.Vec4, - REGL.Vec4, - REGL.Vec4 - ]; -} diff --git a/dist/regl.js b/dist/regl.js deleted file mode 100644 index 105828eb..00000000 --- a/dist/regl.js +++ /dev/null @@ -1,10527 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.createREGL = factory()); -}(this, (function () { 'use strict'; - -var isTypedArray = function (x) { - return ( - x instanceof Uint8Array || - x instanceof Uint16Array || - x instanceof Uint32Array || - x instanceof Int8Array || - x instanceof Int16Array || - x instanceof Int32Array || - x instanceof Float32Array || - x instanceof Float64Array || - x instanceof Uint8ClampedArray - ) -} - -var extend = function (base, opts) { - var keys = Object.keys(opts) - for (var i = 0; i < keys.length; ++i) { - base[keys[i]] = opts[keys[i]] - } - return base -} - -// Error checking and parameter validation. -// -// Statements for the form `check.someProcedure(...)` get removed by -// a browserify transform for optimized/minified bundles. -// -/* globals atob */ -var endl = '\n' - -// only used for extracting shader names. if atob not present, then errors -// will be slightly crappier -function decodeB64 (str) { - if (typeof atob !== 'undefined') { - return atob(str) - } - return 'base64:' + str -} - -function raise (message) { - var error = new Error('(regl) ' + message) - console.error(error) - throw error -} - -function check (pred, message) { - if (!pred) { - raise(message) - } -} - -function encolon (message) { - if (message) { - return ': ' + message - } - return '' -} - -function checkParameter (param, possibilities, message) { - if (!(param in possibilities)) { - raise('unknown parameter (' + param + ')' + encolon(message) + - '. possible values: ' + Object.keys(possibilities).join()) - } -} - -function checkIsTypedArray (data, message) { - if (!isTypedArray(data)) { - raise( - 'invalid parameter type' + encolon(message) + - '. must be a typed array') - } -} - -function standardTypeEh (value, type) { - switch (type) { - case 'number': return typeof value === 'number' - case 'object': return typeof value === 'object' - case 'string': return typeof value === 'string' - case 'boolean': return typeof value === 'boolean' - case 'function': return typeof value === 'function' - case 'undefined': return typeof value === 'undefined' - case 'symbol': return typeof value === 'symbol' - } -} - -function checkTypeOf (value, type, message) { - if (!standardTypeEh(value, type)) { - raise( - 'invalid parameter type' + encolon(message) + - '. expected ' + type + ', got ' + (typeof value)) - } -} - -function checkNonNegativeInt (value, message) { - if (!((value >= 0) && - ((value | 0) === value))) { - raise('invalid parameter type, (' + value + ')' + encolon(message) + - '. must be a nonnegative integer') - } -} - -function checkOneOf (value, list, message) { - if (list.indexOf(value) < 0) { - raise('invalid value' + encolon(message) + '. must be one of: ' + list) - } -} - -var constructorKeys = [ - 'gl', - 'canvas', - 'container', - 'attributes', - 'pixelRatio', - 'extensions', - 'optionalExtensions', - 'profile', - 'onDone' -] - -function checkConstructor (obj) { - Object.keys(obj).forEach(function (key) { - if (constructorKeys.indexOf(key) < 0) { - raise('invalid regl constructor argument "' + key + '". must be one of ' + constructorKeys) - } - }) -} - -function leftPad (str, n) { - str = str + '' - while (str.length < n) { - str = ' ' + str - } - return str -} - -function ShaderFile () { - this.name = 'unknown' - this.lines = [] - this.index = {} - this.hasErrors = false -} - -function ShaderLine (number, line) { - this.number = number - this.line = line - this.errors = [] -} - -function ShaderError (fileNumber, lineNumber, message) { - this.file = fileNumber - this.line = lineNumber - this.message = message -} - -function guessCommand () { - var error = new Error() - var stack = (error.stack || error).toString() - var pat = /compileProcedure.*\n\s*at.*\((.*)\)/.exec(stack) - if (pat) { - return pat[1] - } - var pat2 = /compileProcedure.*\n\s*at\s+(.*)(\n|$)/.exec(stack) - if (pat2) { - return pat2[1] - } - return 'unknown' -} - -function guessCallSite () { - var error = new Error() - var stack = (error.stack || error).toString() - var pat = /at REGLCommand.*\n\s+at.*\((.*)\)/.exec(stack) - if (pat) { - return pat[1] - } - var pat2 = /at REGLCommand.*\n\s+at\s+(.*)\n/.exec(stack) - if (pat2) { - return pat2[1] - } - return 'unknown' -} - -function parseSource (source, command) { - var lines = source.split('\n') - var lineNumber = 1 - var fileNumber = 0 - var files = { - unknown: new ShaderFile(), - 0: new ShaderFile() - } - files.unknown.name = files[0].name = command || guessCommand() - files.unknown.lines.push(new ShaderLine(0, '')) - for (var i = 0; i < lines.length; ++i) { - var line = lines[i] - var parts = /^\s*#\s*(\w+)\s+(.+)\s*$/.exec(line) - if (parts) { - switch (parts[1]) { - case 'line': - var lineNumberInfo = /(\d+)(\s+\d+)?/.exec(parts[2]) - if (lineNumberInfo) { - lineNumber = lineNumberInfo[1] | 0 - if (lineNumberInfo[2]) { - fileNumber = lineNumberInfo[2] | 0 - if (!(fileNumber in files)) { - files[fileNumber] = new ShaderFile() - } - } - } - break - case 'define': - var nameInfo = /SHADER_NAME(_B64)?\s+(.*)$/.exec(parts[2]) - if (nameInfo) { - files[fileNumber].name = (nameInfo[1] - ? decodeB64(nameInfo[2]) - : nameInfo[2]) - } - break - } - } - files[fileNumber].lines.push(new ShaderLine(lineNumber++, line)) - } - Object.keys(files).forEach(function (fileNumber) { - var file = files[fileNumber] - file.lines.forEach(function (line) { - file.index[line.number] = line - }) - }) - return files -} - -function parseErrorLog (errLog) { - var result = [] - errLog.split('\n').forEach(function (errMsg) { - if (errMsg.length < 5) { - return - } - var parts = /^ERROR:\s+(\d+):(\d+):\s*(.*)$/.exec(errMsg) - if (parts) { - result.push(new ShaderError( - parts[1] | 0, - parts[2] | 0, - parts[3].trim())) - } else if (errMsg.length > 0) { - result.push(new ShaderError('unknown', 0, errMsg)) - } - }) - return result -} - -function annotateFiles (files, errors) { - errors.forEach(function (error) { - var file = files[error.file] - if (file) { - var line = file.index[error.line] - if (line) { - line.errors.push(error) - file.hasErrors = true - return - } - } - files.unknown.hasErrors = true - files.unknown.lines[0].errors.push(error) - }) -} - -function checkShaderError (gl, shader, source, type, command) { - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - var errLog = gl.getShaderInfoLog(shader) - var typeName = type === gl.FRAGMENT_SHADER ? 'fragment' : 'vertex' - checkCommandType(source, 'string', typeName + ' shader source must be a string', command) - var files = parseSource(source, command) - var errors = parseErrorLog(errLog) - annotateFiles(files, errors) - - Object.keys(files).forEach(function (fileNumber) { - var file = files[fileNumber] - if (!file.hasErrors) { - return - } - - var strings = [''] - var styles = [''] - - function push (str, style) { - strings.push(str) - styles.push(style || '') - } - - push('file number ' + fileNumber + ': ' + file.name + '\n', 'color:red;text-decoration:underline;font-weight:bold') - - file.lines.forEach(function (line) { - if (line.errors.length > 0) { - push(leftPad(line.number, 4) + '| ', 'background-color:yellow; font-weight:bold') - push(line.line + endl, 'color:red; background-color:yellow; font-weight:bold') - - // try to guess token - var offset = 0 - line.errors.forEach(function (error) { - var message = error.message - var token = /^\s*'(.*)'\s*:\s*(.*)$/.exec(message) - if (token) { - var tokenPat = token[1] - message = token[2] - switch (tokenPat) { - case 'assign': - tokenPat = '=' - break - } - offset = Math.max(line.line.indexOf(tokenPat, offset), 0) - } else { - offset = 0 - } - - push(leftPad('| ', 6)) - push(leftPad('^^^', offset + 3) + endl, 'font-weight:bold') - push(leftPad('| ', 6)) - push(message + endl, 'font-weight:bold') - }) - push(leftPad('| ', 6) + endl) - } else { - push(leftPad(line.number, 4) + '| ') - push(line.line + endl, 'color:red') - } - }) - if (typeof document !== 'undefined' && !window.chrome) { - styles[0] = strings.join('%c') - console.log.apply(console, styles) - } else { - console.log(strings.join('')) - } - }) - - check.raise('Error compiling ' + typeName + ' shader, ' + files[0].name) - } -} - -function checkLinkError (gl, program, fragShader, vertShader, command) { - if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { - var errLog = gl.getProgramInfoLog(program) - var fragParse = parseSource(fragShader, command) - var vertParse = parseSource(vertShader, command) - - var header = 'Error linking program with vertex shader, "' + - vertParse[0].name + '", and fragment shader "' + fragParse[0].name + '"' - - if (typeof document !== 'undefined') { - console.log('%c' + header + endl + '%c' + errLog, - 'color:red;text-decoration:underline;font-weight:bold', - 'color:red') - } else { - console.log(header + endl + errLog) - } - check.raise(header) - } -} - -function saveCommandRef (object) { - object._commandRef = guessCommand() -} - -function saveDrawCommandInfo (opts, uniforms, attributes, stringStore) { - saveCommandRef(opts) - - function id (str) { - if (str) { - return stringStore.id(str) - } - return 0 - } - opts._fragId = id(opts.static.frag) - opts._vertId = id(opts.static.vert) - - function addProps (dict, set) { - Object.keys(set).forEach(function (u) { - dict[stringStore.id(u)] = true - }) - } - - var uniformSet = opts._uniformSet = {} - addProps(uniformSet, uniforms.static) - addProps(uniformSet, uniforms.dynamic) - - var attributeSet = opts._attributeSet = {} - addProps(attributeSet, attributes.static) - addProps(attributeSet, attributes.dynamic) - - opts._hasCount = ( - 'count' in opts.static || - 'count' in opts.dynamic || - 'elements' in opts.static || - 'elements' in opts.dynamic) -} - -function commandRaise (message, command) { - var callSite = guessCallSite() - raise(message + - ' in command ' + (command || guessCommand()) + - (callSite === 'unknown' ? '' : ' called from ' + callSite)) -} - -function checkCommand (pred, message, command) { - if (!pred) { - commandRaise(message, command || guessCommand()) - } -} - -function checkParameterCommand (param, possibilities, message, command) { - if (!(param in possibilities)) { - commandRaise( - 'unknown parameter (' + param + ')' + encolon(message) + - '. possible values: ' + Object.keys(possibilities).join(), - command || guessCommand()) - } -} - -function checkCommandType (value, type, message, command) { - if (!standardTypeEh(value, type)) { - commandRaise( - 'invalid parameter type' + encolon(message) + - '. expected ' + type + ', got ' + (typeof value), - command || guessCommand()) - } -} - -function checkOptional (block) { - block() -} - -function checkFramebufferFormat (attachment, texFormats, rbFormats) { - if (attachment.texture) { - checkOneOf( - attachment.texture._texture.internalformat, - texFormats, - 'unsupported texture format for attachment') - } else { - checkOneOf( - attachment.renderbuffer._renderbuffer.format, - rbFormats, - 'unsupported renderbuffer format for attachment') - } -} - -var GL_CLAMP_TO_EDGE = 0x812F - -var GL_NEAREST = 0x2600 -var GL_NEAREST_MIPMAP_NEAREST = 0x2700 -var GL_LINEAR_MIPMAP_NEAREST = 0x2701 -var GL_NEAREST_MIPMAP_LINEAR = 0x2702 -var GL_LINEAR_MIPMAP_LINEAR = 0x2703 - -var GL_BYTE = 5120 -var GL_UNSIGNED_BYTE = 5121 -var GL_SHORT = 5122 -var GL_UNSIGNED_SHORT = 5123 -var GL_INT = 5124 -var GL_UNSIGNED_INT = 5125 -var GL_FLOAT = 5126 - -var GL_UNSIGNED_SHORT_4_4_4_4 = 0x8033 -var GL_UNSIGNED_SHORT_5_5_5_1 = 0x8034 -var GL_UNSIGNED_SHORT_5_6_5 = 0x8363 -var GL_UNSIGNED_INT_24_8_WEBGL = 0x84FA - -var GL_HALF_FLOAT_OES = 0x8D61 - -var TYPE_SIZE = {} - -TYPE_SIZE[GL_BYTE] = -TYPE_SIZE[GL_UNSIGNED_BYTE] = 1 - -TYPE_SIZE[GL_SHORT] = -TYPE_SIZE[GL_UNSIGNED_SHORT] = -TYPE_SIZE[GL_HALF_FLOAT_OES] = -TYPE_SIZE[GL_UNSIGNED_SHORT_5_6_5] = -TYPE_SIZE[GL_UNSIGNED_SHORT_4_4_4_4] = -TYPE_SIZE[GL_UNSIGNED_SHORT_5_5_5_1] = 2 - -TYPE_SIZE[GL_INT] = -TYPE_SIZE[GL_UNSIGNED_INT] = -TYPE_SIZE[GL_FLOAT] = -TYPE_SIZE[GL_UNSIGNED_INT_24_8_WEBGL] = 4 - -function pixelSize (type, channels) { - if (type === GL_UNSIGNED_SHORT_5_5_5_1 || - type === GL_UNSIGNED_SHORT_4_4_4_4 || - type === GL_UNSIGNED_SHORT_5_6_5) { - return 2 - } else if (type === GL_UNSIGNED_INT_24_8_WEBGL) { - return 4 - } else { - return TYPE_SIZE[type] * channels - } -} - -function isPow2 (v) { - return !(v & (v - 1)) && (!!v) -} - -function checkTexture2D (info, mipData, limits) { - var i - var w = mipData.width - var h = mipData.height - var c = mipData.channels - - // Check texture shape - check(w > 0 && w <= limits.maxTextureSize && - h > 0 && h <= limits.maxTextureSize, - 'invalid texture shape') - - // check wrap mode - if (info.wrapS !== GL_CLAMP_TO_EDGE || info.wrapT !== GL_CLAMP_TO_EDGE) { - check(isPow2(w) && isPow2(h), - 'incompatible wrap mode for texture, both width and height must be power of 2') - } - - if (mipData.mipmask === 1) { - if (w !== 1 && h !== 1) { - check( - info.minFilter !== GL_NEAREST_MIPMAP_NEAREST && - info.minFilter !== GL_NEAREST_MIPMAP_LINEAR && - info.minFilter !== GL_LINEAR_MIPMAP_NEAREST && - info.minFilter !== GL_LINEAR_MIPMAP_LINEAR, - 'min filter requires mipmap') - } - } else { - // texture must be power of 2 - check(isPow2(w) && isPow2(h), - 'texture must be a square power of 2 to support mipmapping') - check(mipData.mipmask === (w << 1) - 1, - 'missing or incomplete mipmap data') - } - - if (mipData.type === GL_FLOAT) { - if (limits.extensions.indexOf('oes_texture_float_linear') < 0) { - check(info.minFilter === GL_NEAREST && info.magFilter === GL_NEAREST, - 'filter not supported, must enable oes_texture_float_linear') - } - check(!info.genMipmaps, - 'mipmap generation not supported with float textures') - } - - // check image complete - var mipimages = mipData.images - for (i = 0; i < 16; ++i) { - if (mipimages[i]) { - var mw = w >> i - var mh = h >> i - check(mipData.mipmask & (1 << i), 'missing mipmap data') - - var img = mipimages[i] - - check( - img.width === mw && - img.height === mh, - 'invalid shape for mip images') - - check( - img.format === mipData.format && - img.internalformat === mipData.internalformat && - img.type === mipData.type, - 'incompatible type for mip image') - - if (img.compressed) { - // TODO: check size for compressed images - } else if (img.data) { - // check(img.data.byteLength === mw * mh * - // Math.max(pixelSize(img.type, c), img.unpackAlignment), - var rowSize = Math.ceil(pixelSize(img.type, c) * mw / img.unpackAlignment) * img.unpackAlignment - check(img.data.byteLength === rowSize * mh, - 'invalid data for image, buffer size is inconsistent with image format') - } else if (img.element) { - // TODO: check element can be loaded - } else if (img.copy) { - // TODO: check compatible format and type - } - } else if (!info.genMipmaps) { - check((mipData.mipmask & (1 << i)) === 0, 'extra mipmap data') - } - } - - if (mipData.compressed) { - check(!info.genMipmaps, - 'mipmap generation for compressed images not supported') - } -} - -function checkTextureCube (texture, info, faces, limits) { - var w = texture.width - var h = texture.height - var c = texture.channels - - // Check texture shape - check( - w > 0 && w <= limits.maxTextureSize && h > 0 && h <= limits.maxTextureSize, - 'invalid texture shape') - check( - w === h, - 'cube map must be square') - check( - info.wrapS === GL_CLAMP_TO_EDGE && info.wrapT === GL_CLAMP_TO_EDGE, - 'wrap mode not supported by cube map') - - for (var i = 0; i < faces.length; ++i) { - var face = faces[i] - check( - face.width === w && face.height === h, - 'inconsistent cube map face shape') - - if (info.genMipmaps) { - check(!face.compressed, - 'can not generate mipmap for compressed textures') - check(face.mipmask === 1, - 'can not specify mipmaps and generate mipmaps') - } else { - // TODO: check mip and filter mode - } - - var mipmaps = face.images - for (var j = 0; j < 16; ++j) { - var img = mipmaps[j] - if (img) { - var mw = w >> j - var mh = h >> j - check(face.mipmask & (1 << j), 'missing mipmap data') - check( - img.width === mw && - img.height === mh, - 'invalid shape for mip images') - check( - img.format === texture.format && - img.internalformat === texture.internalformat && - img.type === texture.type, - 'incompatible type for mip image') - - if (img.compressed) { - // TODO: check size for compressed images - } else if (img.data) { - check(img.data.byteLength === mw * mh * - Math.max(pixelSize(img.type, c), img.unpackAlignment), - 'invalid data for image, buffer size is inconsistent with image format') - } else if (img.element) { - // TODO: check element can be loaded - } else if (img.copy) { - // TODO: check compatible format and type - } - } - } - } -} - -var check$1 = extend(check, { - optional: checkOptional, - raise: raise, - commandRaise: commandRaise, - command: checkCommand, - parameter: checkParameter, - commandParameter: checkParameterCommand, - constructor: checkConstructor, - type: checkTypeOf, - commandType: checkCommandType, - isTypedArray: checkIsTypedArray, - nni: checkNonNegativeInt, - oneOf: checkOneOf, - shaderError: checkShaderError, - linkError: checkLinkError, - callSite: guessCallSite, - saveCommandRef: saveCommandRef, - saveDrawInfo: saveDrawCommandInfo, - framebufferFormat: checkFramebufferFormat, - guessCommand: guessCommand, - texture2D: checkTexture2D, - textureCube: checkTextureCube -}); - -var VARIABLE_COUNTER = 0 - -var DYN_FUNC = 0 -var DYN_CONSTANT = 5 -var DYN_ARRAY = 6 - -function DynamicVariable (type, data) { - this.id = (VARIABLE_COUNTER++) - this.type = type - this.data = data -} - -function escapeStr (str) { - return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"') -} - -function splitParts (str) { - if (str.length === 0) { - return [] - } - - var firstChar = str.charAt(0) - var lastChar = str.charAt(str.length - 1) - - if (str.length > 1 && - firstChar === lastChar && - (firstChar === '"' || firstChar === "'")) { - return ['"' + escapeStr(str.substr(1, str.length - 2)) + '"'] - } - - var parts = /\[(false|true|null|\d+|'[^']*'|"[^"]*")\]/.exec(str) - if (parts) { - return ( - splitParts(str.substr(0, parts.index)) - .concat(splitParts(parts[1])) - .concat(splitParts(str.substr(parts.index + parts[0].length))) - ) - } - - var subparts = str.split('.') - if (subparts.length === 1) { - return ['"' + escapeStr(str) + '"'] - } - - var result = [] - for (var i = 0; i < subparts.length; ++i) { - result = result.concat(splitParts(subparts[i])) - } - return result -} - -function toAccessorString (str) { - return '[' + splitParts(str).join('][') + ']' -} - -function defineDynamic (type, data) { - return new DynamicVariable(type, toAccessorString(data + '')) -} - -function isDynamic (x) { - return (typeof x === 'function' && !x._reglType) || (x instanceof DynamicVariable) -} - -function unbox (x, path) { - if (typeof x === 'function') { - return new DynamicVariable(DYN_FUNC, x) - } else if (typeof x === 'number' || typeof x === 'boolean') { - return new DynamicVariable(DYN_CONSTANT, x) - } else if (Array.isArray(x)) { - return new DynamicVariable(DYN_ARRAY, x.map(function (y, i) { return unbox(y, path + '[' + i + ']') })) - } else if (x instanceof DynamicVariable) { - return x - } - check$1(false, 'invalid option type in uniform ' + path) -} - -var dynamic = { - DynamicVariable: DynamicVariable, - define: defineDynamic, - isDynamic: isDynamic, - unbox: unbox, - accessor: toAccessorString -}; - -/* globals requestAnimationFrame, cancelAnimationFrame */ -var raf = { - next: typeof requestAnimationFrame === 'function' - ? function (cb) { return requestAnimationFrame(cb) } - : function (cb) { return setTimeout(cb, 16) }, - cancel: typeof cancelAnimationFrame === 'function' - ? function (raf) { return cancelAnimationFrame(raf) } - : clearTimeout -}; - -/* globals performance */ -var clock = (typeof performance !== 'undefined' && performance.now) - ? function () { return performance.now() } - : function () { return +(new Date()) }; - -function createStringStore () { - var stringIds = { '': 0 } - var stringValues = [''] - return { - id: function (str) { - var result = stringIds[str] - if (result) { - return result - } - result = stringIds[str] = stringValues.length - stringValues.push(str) - return result - }, - - str: function (id) { - return stringValues[id] - } - } -} - -// Context and canvas creation helper functions -function createCanvas (element, onDone, pixelRatio) { - var canvas = document.createElement('canvas') - extend(canvas.style, { - border: 0, - margin: 0, - padding: 0, - top: 0, - left: 0, - width: '100%', - height: '100%' - }) - element.appendChild(canvas) - - if (element === document.body) { - canvas.style.position = 'absolute' - extend(element.style, { - margin: 0, - padding: 0 - }) - } - - function resize () { - var w = window.innerWidth - var h = window.innerHeight - if (element !== document.body) { - var bounds = canvas.getBoundingClientRect() - w = bounds.right - bounds.left - h = bounds.bottom - bounds.top - } - canvas.width = pixelRatio * w - canvas.height = pixelRatio * h - } - - var resizeObserver - if (element !== document.body && typeof ResizeObserver === 'function') { - // ignore 'ResizeObserver' is not defined - // eslint-disable-next-line - resizeObserver = new ResizeObserver(function () { - // setTimeout to avoid flicker - setTimeout(resize) - }) - resizeObserver.observe(element) - } else { - window.addEventListener('resize', resize, false) - } - - function onDestroy () { - if (resizeObserver) { - resizeObserver.disconnect() - } else { - window.removeEventListener('resize', resize) - } - element.removeChild(canvas) - } - - resize() - - return { - canvas: canvas, - onDestroy: onDestroy - } -} - -function createContext (canvas, contextAttributes) { - function get (name) { - try { - return canvas.getContext(name, contextAttributes) - } catch (e) { - return null - } - } - return ( - get('webgl') || - get('experimental-webgl') || - get('webgl-experimental') - ) -} - -function isHTMLElement (obj) { - return ( - typeof obj.nodeName === 'string' && - typeof obj.appendChild === 'function' && - typeof obj.getBoundingClientRect === 'function' - ) -} - -function isWebGLContext (obj) { - return ( - typeof obj.drawArrays === 'function' || - typeof obj.drawElements === 'function' - ) -} - -function parseExtensions (input) { - if (typeof input === 'string') { - return input.split() - } - check$1(Array.isArray(input), 'invalid extension array') - return input -} - -function getElement (desc) { - if (typeof desc === 'string') { - check$1(typeof document !== 'undefined', 'not supported outside of DOM') - return document.querySelector(desc) - } - return desc -} - -function parseArgs (args_) { - var args = args_ || {} - var element, container, canvas, gl - var contextAttributes = {} - var extensions = [] - var optionalExtensions = [] - var pixelRatio = (typeof window === 'undefined' ? 1 : window.devicePixelRatio) - var profile = false - var onDone = function (err) { - if (err) { - check$1.raise(err) - } - } - var onDestroy = function () {} - if (typeof args === 'string') { - check$1( - typeof document !== 'undefined', - 'selector queries only supported in DOM environments') - element = document.querySelector(args) - check$1(element, 'invalid query string for element') - } else if (typeof args === 'object') { - if (isHTMLElement(args)) { - element = args - } else if (isWebGLContext(args)) { - gl = args - canvas = gl.canvas - } else { - check$1.constructor(args) - if ('gl' in args) { - gl = args.gl - } else if ('canvas' in args) { - canvas = getElement(args.canvas) - } else if ('container' in args) { - container = getElement(args.container) - } - if ('attributes' in args) { - contextAttributes = args.attributes - check$1.type(contextAttributes, 'object', 'invalid context attributes') - } - if ('extensions' in args) { - extensions = parseExtensions(args.extensions) - } - if ('optionalExtensions' in args) { - optionalExtensions = parseExtensions(args.optionalExtensions) - } - if ('onDone' in args) { - check$1.type( - args.onDone, 'function', - 'invalid or missing onDone callback') - onDone = args.onDone - } - if ('profile' in args) { - profile = !!args.profile - } - if ('pixelRatio' in args) { - pixelRatio = +args.pixelRatio - check$1(pixelRatio > 0, 'invalid pixel ratio') - } - } - } else { - check$1.raise('invalid arguments to regl') - } - - if (element) { - if (element.nodeName.toLowerCase() === 'canvas') { - canvas = element - } else { - container = element - } - } - - if (!gl) { - if (!canvas) { - check$1( - typeof document !== 'undefined', - 'must manually specify webgl context outside of DOM environments') - var result = createCanvas(container || document.body, onDone, pixelRatio) - if (!result) { - return null - } - canvas = result.canvas - onDestroy = result.onDestroy - } - // workaround for chromium bug, premultiplied alpha value is platform dependent - if (contextAttributes.premultipliedAlpha === undefined) contextAttributes.premultipliedAlpha = true - gl = createContext(canvas, contextAttributes) - } - - if (!gl) { - onDestroy() - onDone('webgl not supported, try upgrading your browser or graphics drivers http://get.webgl.org') - return null - } - - return { - gl: gl, - canvas: canvas, - container: container, - extensions: extensions, - optionalExtensions: optionalExtensions, - pixelRatio: pixelRatio, - profile: profile, - onDone: onDone, - onDestroy: onDestroy - } -} - -function createExtensionCache (gl, config) { - var extensions = {} - - function tryLoadExtension (name_) { - check$1.type(name_, 'string', 'extension name must be string') - var name = name_.toLowerCase() - var ext - try { - ext = extensions[name] = gl.getExtension(name) - } catch (e) {} - return !!ext - } - - for (var i = 0; i < config.extensions.length; ++i) { - var name = config.extensions[i] - if (!tryLoadExtension(name)) { - config.onDestroy() - config.onDone('"' + name + '" extension is not supported by the current WebGL context, try upgrading your system or a different browser') - return null - } - } - - config.optionalExtensions.forEach(tryLoadExtension) - - return { - extensions: extensions, - restore: function () { - Object.keys(extensions).forEach(function (name) { - if (extensions[name] && !tryLoadExtension(name)) { - throw new Error('(regl): error restoring extension ' + name) - } - }) - } - } -} - -function loop (n, f) { - var result = Array(n) - for (var i = 0; i < n; ++i) { - result[i] = f(i) - } - return result -} - -var GL_BYTE$1 = 5120 -var GL_UNSIGNED_BYTE$2 = 5121 -var GL_SHORT$1 = 5122 -var GL_UNSIGNED_SHORT$1 = 5123 -var GL_INT$1 = 5124 -var GL_UNSIGNED_INT$1 = 5125 -var GL_FLOAT$2 = 5126 - -function nextPow16 (v) { - for (var i = 16; i <= (1 << 28); i *= 16) { - if (v <= i) { - return i - } - } - return 0 -} - -function log2 (v) { - var r, shift - r = (v > 0xFFFF) << 4 - v >>>= r - shift = (v > 0xFF) << 3 - v >>>= shift; r |= shift - shift = (v > 0xF) << 2 - v >>>= shift; r |= shift - shift = (v > 0x3) << 1 - v >>>= shift; r |= shift - return r | (v >> 1) -} - -function createPool () { - var bufferPool = loop(8, function () { - return [] - }) - - function alloc (n) { - var sz = nextPow16(n) - var bin = bufferPool[log2(sz) >> 2] - if (bin.length > 0) { - return bin.pop() - } - return new ArrayBuffer(sz) - } - - function free (buf) { - bufferPool[log2(buf.byteLength) >> 2].push(buf) - } - - function allocType (type, n) { - var result = null - switch (type) { - case GL_BYTE$1: - result = new Int8Array(alloc(n), 0, n) - break - case GL_UNSIGNED_BYTE$2: - result = new Uint8Array(alloc(n), 0, n) - break - case GL_SHORT$1: - result = new Int16Array(alloc(2 * n), 0, n) - break - case GL_UNSIGNED_SHORT$1: - result = new Uint16Array(alloc(2 * n), 0, n) - break - case GL_INT$1: - result = new Int32Array(alloc(4 * n), 0, n) - break - case GL_UNSIGNED_INT$1: - result = new Uint32Array(alloc(4 * n), 0, n) - break - case GL_FLOAT$2: - result = new Float32Array(alloc(4 * n), 0, n) - break - default: - return null - } - if (result.length !== n) { - return result.subarray(0, n) - } - return result - } - - function freeType (array) { - free(array.buffer) - } - - return { - alloc: alloc, - free: free, - allocType: allocType, - freeType: freeType - } -} - -var pool = createPool() - -// zero pool for initial zero data -pool.zero = createPool() - -var GL_SUBPIXEL_BITS = 0x0D50 -var GL_RED_BITS = 0x0D52 -var GL_GREEN_BITS = 0x0D53 -var GL_BLUE_BITS = 0x0D54 -var GL_ALPHA_BITS = 0x0D55 -var GL_DEPTH_BITS = 0x0D56 -var GL_STENCIL_BITS = 0x0D57 - -var GL_ALIASED_POINT_SIZE_RANGE = 0x846D -var GL_ALIASED_LINE_WIDTH_RANGE = 0x846E - -var GL_MAX_TEXTURE_SIZE = 0x0D33 -var GL_MAX_VIEWPORT_DIMS = 0x0D3A -var GL_MAX_VERTEX_ATTRIBS = 0x8869 -var GL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB -var GL_MAX_VARYING_VECTORS = 0x8DFC -var GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D -var GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C -var GL_MAX_TEXTURE_IMAGE_UNITS = 0x8872 -var GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD -var GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C -var GL_MAX_RENDERBUFFER_SIZE = 0x84E8 - -var GL_VENDOR = 0x1F00 -var GL_RENDERER = 0x1F01 -var GL_VERSION = 0x1F02 -var GL_SHADING_LANGUAGE_VERSION = 0x8B8C - -var GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF - -var GL_MAX_COLOR_ATTACHMENTS_WEBGL = 0x8CDF -var GL_MAX_DRAW_BUFFERS_WEBGL = 0x8824 - -var GL_TEXTURE_2D = 0x0DE1 -var GL_TEXTURE_CUBE_MAP = 0x8513 -var GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515 -var GL_TEXTURE0 = 0x84C0 -var GL_RGBA = 0x1908 -var GL_FLOAT$1 = 0x1406 -var GL_UNSIGNED_BYTE$1 = 0x1401 -var GL_FRAMEBUFFER = 0x8D40 -var GL_FRAMEBUFFER_COMPLETE = 0x8CD5 -var GL_COLOR_ATTACHMENT0 = 0x8CE0 -var GL_COLOR_BUFFER_BIT$1 = 0x4000 - -var wrapLimits = function (gl, extensions) { - var maxAnisotropic = 1 - if (extensions.ext_texture_filter_anisotropic) { - maxAnisotropic = gl.getParameter(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) - } - - var maxDrawbuffers = 1 - var maxColorAttachments = 1 - if (extensions.webgl_draw_buffers) { - maxDrawbuffers = gl.getParameter(GL_MAX_DRAW_BUFFERS_WEBGL) - maxColorAttachments = gl.getParameter(GL_MAX_COLOR_ATTACHMENTS_WEBGL) - } - - // detect if reading float textures is available (Safari doesn't support) - var readFloat = !!extensions.oes_texture_float - if (readFloat) { - var readFloatTexture = gl.createTexture() - gl.bindTexture(GL_TEXTURE_2D, readFloatTexture) - gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_FLOAT$1, null) - - var fbo = gl.createFramebuffer() - gl.bindFramebuffer(GL_FRAMEBUFFER, fbo) - gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, readFloatTexture, 0) - gl.bindTexture(GL_TEXTURE_2D, null) - - if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) !== GL_FRAMEBUFFER_COMPLETE) readFloat = false - - else { - gl.viewport(0, 0, 1, 1) - gl.clearColor(1.0, 0.0, 0.0, 1.0) - gl.clear(GL_COLOR_BUFFER_BIT$1) - var pixels = pool.allocType(GL_FLOAT$1, 4) - gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT$1, pixels) - - if (gl.getError()) readFloat = false - else { - gl.deleteFramebuffer(fbo) - gl.deleteTexture(readFloatTexture) - - readFloat = pixels[0] === 1.0 - } - - pool.freeType(pixels) - } - } - - // detect non power of two cube textures support (IE doesn't support) - var isIE = typeof navigator !== 'undefined' && (/MSIE/.test(navigator.userAgent) || /Trident\//.test(navigator.appVersion) || /Edge/.test(navigator.userAgent)) - - var npotTextureCube = true - - if (!isIE) { - var cubeTexture = gl.createTexture() - var data = pool.allocType(GL_UNSIGNED_BYTE$1, 36) - gl.activeTexture(GL_TEXTURE0) - gl.bindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture) - gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE$1, data) - pool.freeType(data) - gl.bindTexture(GL_TEXTURE_CUBE_MAP, null) - gl.deleteTexture(cubeTexture) - npotTextureCube = !gl.getError() - } - - return { - // drawing buffer bit depth - colorBits: [ - gl.getParameter(GL_RED_BITS), - gl.getParameter(GL_GREEN_BITS), - gl.getParameter(GL_BLUE_BITS), - gl.getParameter(GL_ALPHA_BITS) - ], - depthBits: gl.getParameter(GL_DEPTH_BITS), - stencilBits: gl.getParameter(GL_STENCIL_BITS), - subpixelBits: gl.getParameter(GL_SUBPIXEL_BITS), - - // supported extensions - extensions: Object.keys(extensions).filter(function (ext) { - return !!extensions[ext] - }), - - // max aniso samples - maxAnisotropic: maxAnisotropic, - - // max draw buffers - maxDrawbuffers: maxDrawbuffers, - maxColorAttachments: maxColorAttachments, - - // point and line size ranges - pointSizeDims: gl.getParameter(GL_ALIASED_POINT_SIZE_RANGE), - lineWidthDims: gl.getParameter(GL_ALIASED_LINE_WIDTH_RANGE), - maxViewportDims: gl.getParameter(GL_MAX_VIEWPORT_DIMS), - maxCombinedTextureUnits: gl.getParameter(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS), - maxCubeMapSize: gl.getParameter(GL_MAX_CUBE_MAP_TEXTURE_SIZE), - maxRenderbufferSize: gl.getParameter(GL_MAX_RENDERBUFFER_SIZE), - maxTextureUnits: gl.getParameter(GL_MAX_TEXTURE_IMAGE_UNITS), - maxTextureSize: gl.getParameter(GL_MAX_TEXTURE_SIZE), - maxAttributes: gl.getParameter(GL_MAX_VERTEX_ATTRIBS), - maxVertexUniforms: gl.getParameter(GL_MAX_VERTEX_UNIFORM_VECTORS), - maxVertexTextureUnits: gl.getParameter(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS), - maxVaryingVectors: gl.getParameter(GL_MAX_VARYING_VECTORS), - maxFragmentUniforms: gl.getParameter(GL_MAX_FRAGMENT_UNIFORM_VECTORS), - - // vendor info - glsl: gl.getParameter(GL_SHADING_LANGUAGE_VERSION), - renderer: gl.getParameter(GL_RENDERER), - vendor: gl.getParameter(GL_VENDOR), - version: gl.getParameter(GL_VERSION), - - // quirks - readFloat: readFloat, - npotTextureCube: npotTextureCube - } -} - -function isNDArrayLike (obj) { - return ( - !!obj && - typeof obj === 'object' && - Array.isArray(obj.shape) && - Array.isArray(obj.stride) && - typeof obj.offset === 'number' && - obj.shape.length === obj.stride.length && - (Array.isArray(obj.data) || - isTypedArray(obj.data))) -} - -var values = function (obj) { - return Object.keys(obj).map(function (key) { return obj[key] }) -} - -var flattenUtils = { - shape: arrayShape$1, - flatten: flattenArray -}; - -function flatten1D (array, nx, out) { - for (var i = 0; i < nx; ++i) { - out[i] = array[i] - } -} - -function flatten2D (array, nx, ny, out) { - var ptr = 0 - for (var i = 0; i < nx; ++i) { - var row = array[i] - for (var j = 0; j < ny; ++j) { - out[ptr++] = row[j] - } - } -} - -function flatten3D (array, nx, ny, nz, out, ptr_) { - var ptr = ptr_ - for (var i = 0; i < nx; ++i) { - var row = array[i] - for (var j = 0; j < ny; ++j) { - var col = row[j] - for (var k = 0; k < nz; ++k) { - out[ptr++] = col[k] - } - } - } -} - -function flattenRec (array, shape, level, out, ptr) { - var stride = 1 - for (var i = level + 1; i < shape.length; ++i) { - stride *= shape[i] - } - var n = shape[level] - if (shape.length - level === 4) { - var nx = shape[level + 1] - var ny = shape[level + 2] - var nz = shape[level + 3] - for (i = 0; i < n; ++i) { - flatten3D(array[i], nx, ny, nz, out, ptr) - ptr += stride - } - } else { - for (i = 0; i < n; ++i) { - flattenRec(array[i], shape, level + 1, out, ptr) - ptr += stride - } - } -} - -function flattenArray (array, shape, type, out_) { - var sz = 1 - if (shape.length) { - for (var i = 0; i < shape.length; ++i) { - sz *= shape[i] - } - } else { - sz = 0 - } - var out = out_ || pool.allocType(type, sz) - switch (shape.length) { - case 0: - break - case 1: - flatten1D(array, shape[0], out) - break - case 2: - flatten2D(array, shape[0], shape[1], out) - break - case 3: - flatten3D(array, shape[0], shape[1], shape[2], out, 0) - break - default: - flattenRec(array, shape, 0, out, 0) - } - return out -} - -function arrayShape$1 (array_) { - var shape = [] - for (var array = array_; array.length; array = array[0]) { - shape.push(array.length) - } - return shape -} - -var arrayTypes = { - "[object Int8Array]": 5120, - "[object Int16Array]": 5122, - "[object Int32Array]": 5124, - "[object Uint8Array]": 5121, - "[object Uint8ClampedArray]": 5121, - "[object Uint16Array]": 5123, - "[object Uint32Array]": 5125, - "[object Float32Array]": 5126, - "[object Float64Array]": 5121, - "[object ArrayBuffer]": 5121 -}; - -var int8 = 5120; -var int16 = 5122; -var int32 = 5124; -var uint8 = 5121; -var uint16 = 5123; -var uint32 = 5125; -var float = 5126; -var float32 = 5126; -var glTypes = { - int8: int8, - int16: int16, - int32: int32, - uint8: uint8, - uint16: uint16, - uint32: uint32, - float: float, - float32: float32 -}; - -var dynamic$1 = 35048; -var stream = 35040; -var usageTypes = { - dynamic: dynamic$1, - stream: stream, - "static": 35044 -}; - -var arrayFlatten = flattenUtils.flatten -var arrayShape = flattenUtils.shape - -var GL_STATIC_DRAW = 0x88E4 -var GL_STREAM_DRAW = 0x88E0 - -var GL_UNSIGNED_BYTE$3 = 5121 -var GL_FLOAT$3 = 5126 - -var DTYPES_SIZES = [] -DTYPES_SIZES[5120] = 1 // int8 -DTYPES_SIZES[5122] = 2 // int16 -DTYPES_SIZES[5124] = 4 // int32 -DTYPES_SIZES[5121] = 1 // uint8 -DTYPES_SIZES[5123] = 2 // uint16 -DTYPES_SIZES[5125] = 4 // uint32 -DTYPES_SIZES[5126] = 4 // float32 - -function typedArrayCode (data) { - return arrayTypes[Object.prototype.toString.call(data)] | 0 -} - -function copyArray (out, inp) { - for (var i = 0; i < inp.length; ++i) { - out[i] = inp[i] - } -} - -function transpose ( - result, data, shapeX, shapeY, strideX, strideY, offset) { - var ptr = 0 - for (var i = 0; i < shapeX; ++i) { - for (var j = 0; j < shapeY; ++j) { - result[ptr++] = data[strideX * i + strideY * j + offset] - } - } -} - -function wrapBufferState (gl, stats, config, destroyBuffer) { - var bufferCount = 0 - var bufferSet = {} - - function REGLBuffer (type) { - this.id = bufferCount++ - this.buffer = gl.createBuffer() - this.type = type - this.usage = GL_STATIC_DRAW - this.byteLength = 0 - this.dimension = 1 - this.dtype = GL_UNSIGNED_BYTE$3 - - this.persistentData = null - - if (config.profile) { - this.stats = { size: 0 } - } - } - - REGLBuffer.prototype.bind = function () { - gl.bindBuffer(this.type, this.buffer) - } - - REGLBuffer.prototype.destroy = function () { - destroy(this) - } - - var streamPool = [] - - function createStream (type, data) { - var buffer = streamPool.pop() - if (!buffer) { - buffer = new REGLBuffer(type) - } - buffer.bind() - initBufferFromData(buffer, data, GL_STREAM_DRAW, 0, 1, false) - return buffer - } - - function destroyStream (stream$$1) { - streamPool.push(stream$$1) - } - - function initBufferFromTypedArray (buffer, data, usage) { - buffer.byteLength = data.byteLength - gl.bufferData(buffer.type, data, usage) - } - - function initBufferFromData (buffer, data, usage, dtype, dimension, persist) { - var shape - buffer.usage = usage - if (Array.isArray(data)) { - buffer.dtype = dtype || GL_FLOAT$3 - if (data.length > 0) { - var flatData - if (Array.isArray(data[0])) { - shape = arrayShape(data) - var dim = 1 - for (var i = 1; i < shape.length; ++i) { - dim *= shape[i] - } - buffer.dimension = dim - flatData = arrayFlatten(data, shape, buffer.dtype) - initBufferFromTypedArray(buffer, flatData, usage) - if (persist) { - buffer.persistentData = flatData - } else { - pool.freeType(flatData) - } - } else if (typeof data[0] === 'number') { - buffer.dimension = dimension - var typedData = pool.allocType(buffer.dtype, data.length) - copyArray(typedData, data) - initBufferFromTypedArray(buffer, typedData, usage) - if (persist) { - buffer.persistentData = typedData - } else { - pool.freeType(typedData) - } - } else if (isTypedArray(data[0])) { - buffer.dimension = data[0].length - buffer.dtype = dtype || typedArrayCode(data[0]) || GL_FLOAT$3 - flatData = arrayFlatten( - data, - [data.length, data[0].length], - buffer.dtype) - initBufferFromTypedArray(buffer, flatData, usage) - if (persist) { - buffer.persistentData = flatData - } else { - pool.freeType(flatData) - } - } else { - check$1.raise('invalid buffer data') - } - } - } else if (isTypedArray(data)) { - buffer.dtype = dtype || typedArrayCode(data) - buffer.dimension = dimension - initBufferFromTypedArray(buffer, data, usage) - if (persist) { - buffer.persistentData = new Uint8Array(new Uint8Array(data.buffer)) - } - } else if (isNDArrayLike(data)) { - shape = data.shape - var stride = data.stride - var offset = data.offset - - var shapeX = 0 - var shapeY = 0 - var strideX = 0 - var strideY = 0 - if (shape.length === 1) { - shapeX = shape[0] - shapeY = 1 - strideX = stride[0] - strideY = 0 - } else if (shape.length === 2) { - shapeX = shape[0] - shapeY = shape[1] - strideX = stride[0] - strideY = stride[1] - } else { - check$1.raise('invalid shape') - } - - buffer.dtype = dtype || typedArrayCode(data.data) || GL_FLOAT$3 - buffer.dimension = shapeY - - var transposeData = pool.allocType(buffer.dtype, shapeX * shapeY) - transpose(transposeData, - data.data, - shapeX, shapeY, - strideX, strideY, - offset) - initBufferFromTypedArray(buffer, transposeData, usage) - if (persist) { - buffer.persistentData = transposeData - } else { - pool.freeType(transposeData) - } - } else if (data instanceof ArrayBuffer) { - buffer.dtype = GL_UNSIGNED_BYTE$3 - buffer.dimension = dimension - initBufferFromTypedArray(buffer, data, usage) - if (persist) { - buffer.persistentData = new Uint8Array(new Uint8Array(data)) - } - } else { - check$1.raise('invalid buffer data') - } - } - - function destroy (buffer) { - stats.bufferCount-- - - // remove attribute link - destroyBuffer(buffer) - - var handle = buffer.buffer - check$1(handle, 'buffer must not be deleted already') - gl.deleteBuffer(handle) - buffer.buffer = null - delete bufferSet[buffer.id] - } - - function createBuffer (options, type, deferInit, persistent) { - stats.bufferCount++ - - var buffer = new REGLBuffer(type) - bufferSet[buffer.id] = buffer - - function reglBuffer (options) { - var usage = GL_STATIC_DRAW - var data = null - var byteLength = 0 - var dtype = 0 - var dimension = 1 - if (Array.isArray(options) || - isTypedArray(options) || - isNDArrayLike(options) || - options instanceof ArrayBuffer) { - data = options - } else if (typeof options === 'number') { - byteLength = options | 0 - } else if (options) { - check$1.type( - options, 'object', - 'buffer arguments must be an object, a number or an array') - - if ('data' in options) { - check$1( - data === null || - Array.isArray(data) || - isTypedArray(data) || - isNDArrayLike(data), - 'invalid data for buffer') - data = options.data - } - - if ('usage' in options) { - check$1.parameter(options.usage, usageTypes, 'invalid buffer usage') - usage = usageTypes[options.usage] - } - - if ('type' in options) { - check$1.parameter(options.type, glTypes, 'invalid buffer type') - dtype = glTypes[options.type] - } - - if ('dimension' in options) { - check$1.type(options.dimension, 'number', 'invalid dimension') - dimension = options.dimension | 0 - } - - if ('length' in options) { - check$1.nni(byteLength, 'buffer length must be a nonnegative integer') - byteLength = options.length | 0 - } - } - - buffer.bind() - if (!data) { - // #475 - if (byteLength) gl.bufferData(buffer.type, byteLength, usage) - buffer.dtype = dtype || GL_UNSIGNED_BYTE$3 - buffer.usage = usage - buffer.dimension = dimension - buffer.byteLength = byteLength - } else { - initBufferFromData(buffer, data, usage, dtype, dimension, persistent) - } - - if (config.profile) { - buffer.stats.size = buffer.byteLength * DTYPES_SIZES[buffer.dtype] - } - - return reglBuffer - } - - function setSubData (data, offset) { - check$1(offset + data.byteLength <= buffer.byteLength, - 'invalid buffer subdata call, buffer is too small. ' + ' Can\'t write data of size ' + data.byteLength + ' starting from offset ' + offset + ' to a buffer of size ' + buffer.byteLength) - - gl.bufferSubData(buffer.type, offset, data) - } - - function subdata (data, offset_) { - var offset = (offset_ || 0) | 0 - var shape - buffer.bind() - if (isTypedArray(data) || data instanceof ArrayBuffer) { - setSubData(data, offset) - } else if (Array.isArray(data)) { - if (data.length > 0) { - if (typeof data[0] === 'number') { - var converted = pool.allocType(buffer.dtype, data.length) - copyArray(converted, data) - setSubData(converted, offset) - pool.freeType(converted) - } else if (Array.isArray(data[0]) || isTypedArray(data[0])) { - shape = arrayShape(data) - var flatData = arrayFlatten(data, shape, buffer.dtype) - setSubData(flatData, offset) - pool.freeType(flatData) - } else { - check$1.raise('invalid buffer data') - } - } - } else if (isNDArrayLike(data)) { - shape = data.shape - var stride = data.stride - - var shapeX = 0 - var shapeY = 0 - var strideX = 0 - var strideY = 0 - if (shape.length === 1) { - shapeX = shape[0] - shapeY = 1 - strideX = stride[0] - strideY = 0 - } else if (shape.length === 2) { - shapeX = shape[0] - shapeY = shape[1] - strideX = stride[0] - strideY = stride[1] - } else { - check$1.raise('invalid shape') - } - var dtype = Array.isArray(data.data) - ? buffer.dtype - : typedArrayCode(data.data) - - var transposeData = pool.allocType(dtype, shapeX * shapeY) - transpose(transposeData, - data.data, - shapeX, shapeY, - strideX, strideY, - data.offset) - setSubData(transposeData, offset) - pool.freeType(transposeData) - } else { - check$1.raise('invalid data for buffer subdata') - } - return reglBuffer - } - - if (!deferInit) { - reglBuffer(options) - } - - reglBuffer._reglType = 'buffer' - reglBuffer._buffer = buffer - reglBuffer.subdata = subdata - if (config.profile) { - reglBuffer.stats = buffer.stats - } - reglBuffer.destroy = function () { destroy(buffer) } - - return reglBuffer - } - - function restoreBuffers () { - values(bufferSet).forEach(function (buffer) { - buffer.buffer = gl.createBuffer() - gl.bindBuffer(buffer.type, buffer.buffer) - gl.bufferData( - buffer.type, buffer.persistentData || buffer.byteLength, buffer.usage) - }) - } - - if (config.profile) { - stats.getTotalBufferSize = function () { - var total = 0 - // TODO: Right now, the streams are not part of the total count. - Object.keys(bufferSet).forEach(function (key) { - total += bufferSet[key].stats.size - }) - return total - } - } - - return { - create: createBuffer, - - createStream: createStream, - destroyStream: destroyStream, - - clear: function () { - values(bufferSet).forEach(destroy) - streamPool.forEach(destroy) - }, - - getBuffer: function (wrapper) { - if (wrapper && wrapper._buffer instanceof REGLBuffer) { - return wrapper._buffer - } - return null - }, - - restore: restoreBuffers, - - _initBuffer: initBufferFromData - } -} - -var points = 0; -var point = 0; -var lines = 1; -var line = 1; -var triangles = 4; -var triangle = 4; -var primTypes = { - points: points, - point: point, - lines: lines, - line: line, - triangles: triangles, - triangle: triangle, - "line loop": 2, - "line strip": 3, - "triangle strip": 5, - "triangle fan": 6 -}; - -var GL_POINTS = 0 -var GL_LINES = 1 -var GL_TRIANGLES = 4 - -var GL_BYTE$2 = 5120 -var GL_UNSIGNED_BYTE$4 = 5121 -var GL_SHORT$2 = 5122 -var GL_UNSIGNED_SHORT$2 = 5123 -var GL_INT$2 = 5124 -var GL_UNSIGNED_INT$2 = 5125 - -var GL_ELEMENT_ARRAY_BUFFER = 34963 - -var GL_STREAM_DRAW$1 = 0x88E0 -var GL_STATIC_DRAW$1 = 0x88E4 - -function wrapElementsState (gl, extensions, bufferState, stats) { - var elementSet = {} - var elementCount = 0 - - var elementTypes = { - 'uint8': GL_UNSIGNED_BYTE$4, - 'uint16': GL_UNSIGNED_SHORT$2 - } - - if (extensions.oes_element_index_uint) { - elementTypes.uint32 = GL_UNSIGNED_INT$2 - } - - function REGLElementBuffer (buffer) { - this.id = elementCount++ - elementSet[this.id] = this - this.buffer = buffer - this.primType = GL_TRIANGLES - this.vertCount = 0 - this.type = 0 - } - - REGLElementBuffer.prototype.bind = function () { - this.buffer.bind() - } - - var bufferPool = [] - - function createElementStream (data) { - var result = bufferPool.pop() - if (!result) { - result = new REGLElementBuffer(bufferState.create( - null, - GL_ELEMENT_ARRAY_BUFFER, - true, - false)._buffer) - } - initElements(result, data, GL_STREAM_DRAW$1, -1, -1, 0, 0) - return result - } - - function destroyElementStream (elements) { - bufferPool.push(elements) - } - - function initElements ( - elements, - data, - usage, - prim, - count, - byteLength, - type) { - elements.buffer.bind() - var dtype - if (data) { - var predictedType = type - if (!type && ( - !isTypedArray(data) || - (isNDArrayLike(data) && !isTypedArray(data.data)))) { - predictedType = extensions.oes_element_index_uint - ? GL_UNSIGNED_INT$2 - : GL_UNSIGNED_SHORT$2 - } - bufferState._initBuffer( - elements.buffer, - data, - usage, - predictedType, - 3) - } else { - gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, byteLength, usage) - elements.buffer.dtype = dtype || GL_UNSIGNED_BYTE$4 - elements.buffer.usage = usage - elements.buffer.dimension = 3 - elements.buffer.byteLength = byteLength - } - - dtype = type - if (!type) { - switch (elements.buffer.dtype) { - case GL_UNSIGNED_BYTE$4: - case GL_BYTE$2: - dtype = GL_UNSIGNED_BYTE$4 - break - - case GL_UNSIGNED_SHORT$2: - case GL_SHORT$2: - dtype = GL_UNSIGNED_SHORT$2 - break - - case GL_UNSIGNED_INT$2: - case GL_INT$2: - dtype = GL_UNSIGNED_INT$2 - break - - default: - check$1.raise('unsupported type for element array') - } - elements.buffer.dtype = dtype - } - elements.type = dtype - - // Check oes_element_index_uint extension - check$1( - dtype !== GL_UNSIGNED_INT$2 || - !!extensions.oes_element_index_uint, - '32 bit element buffers not supported, enable oes_element_index_uint first') - - // try to guess default primitive type and arguments - var vertCount = count - if (vertCount < 0) { - vertCount = elements.buffer.byteLength - if (dtype === GL_UNSIGNED_SHORT$2) { - vertCount >>= 1 - } else if (dtype === GL_UNSIGNED_INT$2) { - vertCount >>= 2 - } - } - elements.vertCount = vertCount - - // try to guess primitive type from cell dimension - var primType = prim - if (prim < 0) { - primType = GL_TRIANGLES - var dimension = elements.buffer.dimension - if (dimension === 1) primType = GL_POINTS - if (dimension === 2) primType = GL_LINES - if (dimension === 3) primType = GL_TRIANGLES - } - elements.primType = primType - } - - function destroyElements (elements) { - stats.elementsCount-- - - check$1(elements.buffer !== null, 'must not double destroy elements') - delete elementSet[elements.id] - elements.buffer.destroy() - elements.buffer = null - } - - function createElements (options, persistent) { - var buffer = bufferState.create(null, GL_ELEMENT_ARRAY_BUFFER, true) - var elements = new REGLElementBuffer(buffer._buffer) - stats.elementsCount++ - - function reglElements (options) { - if (!options) { - buffer() - elements.primType = GL_TRIANGLES - elements.vertCount = 0 - elements.type = GL_UNSIGNED_BYTE$4 - } else if (typeof options === 'number') { - buffer(options) - elements.primType = GL_TRIANGLES - elements.vertCount = options | 0 - elements.type = GL_UNSIGNED_BYTE$4 - } else { - var data = null - var usage = GL_STATIC_DRAW$1 - var primType = -1 - var vertCount = -1 - var byteLength = 0 - var dtype = 0 - if (Array.isArray(options) || - isTypedArray(options) || - isNDArrayLike(options)) { - data = options - } else { - check$1.type(options, 'object', 'invalid arguments for elements') - if ('data' in options) { - data = options.data - check$1( - Array.isArray(data) || - isTypedArray(data) || - isNDArrayLike(data), - 'invalid data for element buffer') - } - if ('usage' in options) { - check$1.parameter( - options.usage, - usageTypes, - 'invalid element buffer usage') - usage = usageTypes[options.usage] - } - if ('primitive' in options) { - check$1.parameter( - options.primitive, - primTypes, - 'invalid element buffer primitive') - primType = primTypes[options.primitive] - } - if ('count' in options) { - check$1( - typeof options.count === 'number' && options.count >= 0, - 'invalid vertex count for elements') - vertCount = options.count | 0 - } - if ('type' in options) { - check$1.parameter( - options.type, - elementTypes, - 'invalid buffer type') - dtype = elementTypes[options.type] - } - if ('length' in options) { - byteLength = options.length | 0 - } else { - byteLength = vertCount - if (dtype === GL_UNSIGNED_SHORT$2 || dtype === GL_SHORT$2) { - byteLength *= 2 - } else if (dtype === GL_UNSIGNED_INT$2 || dtype === GL_INT$2) { - byteLength *= 4 - } - } - } - initElements( - elements, - data, - usage, - primType, - vertCount, - byteLength, - dtype) - } - - return reglElements - } - - reglElements(options) - - reglElements._reglType = 'elements' - reglElements._elements = elements - reglElements.subdata = function (data, offset) { - buffer.subdata(data, offset) - return reglElements - } - reglElements.destroy = function () { - destroyElements(elements) - } - - return reglElements - } - - return { - create: createElements, - createStream: createElementStream, - destroyStream: destroyElementStream, - getElements: function (elements) { - if (typeof elements === 'function' && - elements._elements instanceof REGLElementBuffer) { - return elements._elements - } - return null - }, - clear: function () { - values(elementSet).forEach(destroyElements) - } - } -} - -var FLOAT = new Float32Array(1) -var INT = new Uint32Array(FLOAT.buffer) - -var GL_UNSIGNED_SHORT$4 = 5123 - -function convertToHalfFloat (array) { - var ushorts = pool.allocType(GL_UNSIGNED_SHORT$4, array.length) - - for (var i = 0; i < array.length; ++i) { - if (isNaN(array[i])) { - ushorts[i] = 0xffff - } else if (array[i] === Infinity) { - ushorts[i] = 0x7c00 - } else if (array[i] === -Infinity) { - ushorts[i] = 0xfc00 - } else { - FLOAT[0] = array[i] - var x = INT[0] - - var sgn = (x >>> 31) << 15 - var exp = ((x << 1) >>> 24) - 127 - var frac = (x >> 13) & ((1 << 10) - 1) - - if (exp < -24) { - // round non-representable denormals to 0 - ushorts[i] = sgn - } else if (exp < -14) { - // handle denormals - var s = -14 - exp - ushorts[i] = sgn + ((frac + (1 << 10)) >> s) - } else if (exp > 15) { - // round overflow to +/- Infinity - ushorts[i] = sgn + 0x7c00 - } else { - // otherwise convert directly - ushorts[i] = sgn + ((exp + 15) << 10) + frac - } - } - } - - return ushorts -} - -function isArrayLike (s) { - return Array.isArray(s) || isTypedArray(s) -} - -var isPow2$1 = function (v) { - return !(v & (v - 1)) && (!!v) -} - -var GL_COMPRESSED_TEXTURE_FORMATS = 0x86A3 - -var GL_TEXTURE_2D$1 = 0x0DE1 -var GL_TEXTURE_CUBE_MAP$1 = 0x8513 -var GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 = 0x8515 - -var GL_RGBA$1 = 0x1908 -var GL_ALPHA = 0x1906 -var GL_RGB = 0x1907 -var GL_LUMINANCE = 0x1909 -var GL_LUMINANCE_ALPHA = 0x190A - -var GL_RGBA4 = 0x8056 -var GL_RGB5_A1 = 0x8057 -var GL_RGB565 = 0x8D62 - -var GL_UNSIGNED_SHORT_4_4_4_4$1 = 0x8033 -var GL_UNSIGNED_SHORT_5_5_5_1$1 = 0x8034 -var GL_UNSIGNED_SHORT_5_6_5$1 = 0x8363 -var GL_UNSIGNED_INT_24_8_WEBGL$1 = 0x84FA - -var GL_DEPTH_COMPONENT = 0x1902 -var GL_DEPTH_STENCIL = 0x84F9 - -var GL_SRGB_EXT = 0x8C40 -var GL_SRGB_ALPHA_EXT = 0x8C42 - -var GL_HALF_FLOAT_OES$1 = 0x8D61 - -var GL_COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0 -var GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1 -var GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2 -var GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3 - -var GL_COMPRESSED_RGB_ATC_WEBGL = 0x8C92 -var GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 0x8C93 -var GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE - -var GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00 -var GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01 -var GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02 -var GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03 - -var GL_COMPRESSED_RGB_ETC1_WEBGL = 0x8D64 - -var GL_UNSIGNED_BYTE$5 = 0x1401 -var GL_UNSIGNED_SHORT$3 = 0x1403 -var GL_UNSIGNED_INT$3 = 0x1405 -var GL_FLOAT$4 = 0x1406 - -var GL_TEXTURE_WRAP_S = 0x2802 -var GL_TEXTURE_WRAP_T = 0x2803 - -var GL_REPEAT = 0x2901 -var GL_CLAMP_TO_EDGE$1 = 0x812F -var GL_MIRRORED_REPEAT = 0x8370 - -var GL_TEXTURE_MAG_FILTER = 0x2800 -var GL_TEXTURE_MIN_FILTER = 0x2801 - -var GL_NEAREST$1 = 0x2600 -var GL_LINEAR = 0x2601 -var GL_NEAREST_MIPMAP_NEAREST$1 = 0x2700 -var GL_LINEAR_MIPMAP_NEAREST$1 = 0x2701 -var GL_NEAREST_MIPMAP_LINEAR$1 = 0x2702 -var GL_LINEAR_MIPMAP_LINEAR$1 = 0x2703 - -var GL_GENERATE_MIPMAP_HINT = 0x8192 -var GL_DONT_CARE = 0x1100 -var GL_FASTEST = 0x1101 -var GL_NICEST = 0x1102 - -var GL_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE - -var GL_UNPACK_ALIGNMENT = 0x0CF5 -var GL_UNPACK_FLIP_Y_WEBGL = 0x9240 -var GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241 -var GL_UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243 - -var GL_BROWSER_DEFAULT_WEBGL = 0x9244 - -var GL_TEXTURE0$1 = 0x84C0 - -var MIPMAP_FILTERS = [ - GL_NEAREST_MIPMAP_NEAREST$1, - GL_NEAREST_MIPMAP_LINEAR$1, - GL_LINEAR_MIPMAP_NEAREST$1, - GL_LINEAR_MIPMAP_LINEAR$1 -] - -var CHANNELS_FORMAT = [ - 0, - GL_LUMINANCE, - GL_LUMINANCE_ALPHA, - GL_RGB, - GL_RGBA$1 -] - -var FORMAT_CHANNELS = {} -FORMAT_CHANNELS[GL_LUMINANCE] = -FORMAT_CHANNELS[GL_ALPHA] = -FORMAT_CHANNELS[GL_DEPTH_COMPONENT] = 1 -FORMAT_CHANNELS[GL_DEPTH_STENCIL] = -FORMAT_CHANNELS[GL_LUMINANCE_ALPHA] = 2 -FORMAT_CHANNELS[GL_RGB] = -FORMAT_CHANNELS[GL_SRGB_EXT] = 3 -FORMAT_CHANNELS[GL_RGBA$1] = -FORMAT_CHANNELS[GL_SRGB_ALPHA_EXT] = 4 - -function objectName (str) { - return '[object ' + str + ']' -} - -var CANVAS_CLASS = objectName('HTMLCanvasElement') -var OFFSCREENCANVAS_CLASS = objectName('OffscreenCanvas') -var CONTEXT2D_CLASS = objectName('CanvasRenderingContext2D') -var BITMAP_CLASS = objectName('ImageBitmap') -var IMAGE_CLASS = objectName('HTMLImageElement') -var VIDEO_CLASS = objectName('HTMLVideoElement') - -var PIXEL_CLASSES = Object.keys(arrayTypes).concat([ - CANVAS_CLASS, - OFFSCREENCANVAS_CLASS, - CONTEXT2D_CLASS, - BITMAP_CLASS, - IMAGE_CLASS, - VIDEO_CLASS -]) - -// for every texture type, store -// the size in bytes. -var TYPE_SIZES = [] -TYPE_SIZES[GL_UNSIGNED_BYTE$5] = 1 -TYPE_SIZES[GL_FLOAT$4] = 4 -TYPE_SIZES[GL_HALF_FLOAT_OES$1] = 2 - -TYPE_SIZES[GL_UNSIGNED_SHORT$3] = 2 -TYPE_SIZES[GL_UNSIGNED_INT$3] = 4 - -var FORMAT_SIZES_SPECIAL = [] -FORMAT_SIZES_SPECIAL[GL_RGBA4] = 2 -FORMAT_SIZES_SPECIAL[GL_RGB5_A1] = 2 -FORMAT_SIZES_SPECIAL[GL_RGB565] = 2 -FORMAT_SIZES_SPECIAL[GL_DEPTH_STENCIL] = 4 - -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_S3TC_DXT1_EXT] = 0.5 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT1_EXT] = 0.5 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT3_EXT] = 1 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT5_EXT] = 1 - -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_ATC_WEBGL] = 0.5 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL] = 1 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL] = 1 - -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG] = 0.5 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG] = 0.25 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG] = 0.5 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG] = 0.25 - -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_ETC1_WEBGL] = 0.5 - -function isNumericArray (arr) { - return ( - Array.isArray(arr) && - (arr.length === 0 || - typeof arr[0] === 'number')) -} - -function isRectArray (arr) { - if (!Array.isArray(arr)) { - return false - } - var width = arr.length - if (width === 0 || !isArrayLike(arr[0])) { - return false - } - return true -} - -function classString (x) { - return Object.prototype.toString.call(x) -} - -function isCanvasElement (object) { - return classString(object) === CANVAS_CLASS -} - -function isOffscreenCanvas (object) { - return classString(object) === OFFSCREENCANVAS_CLASS -} - -function isContext2D (object) { - return classString(object) === CONTEXT2D_CLASS -} - -function isBitmap (object) { - return classString(object) === BITMAP_CLASS -} - -function isImageElement (object) { - return classString(object) === IMAGE_CLASS -} - -function isVideoElement (object) { - return classString(object) === VIDEO_CLASS -} - -function isPixelData (object) { - if (!object) { - return false - } - var className = classString(object) - if (PIXEL_CLASSES.indexOf(className) >= 0) { - return true - } - return ( - isNumericArray(object) || - isRectArray(object) || - isNDArrayLike(object)) -} - -function typedArrayCode$1 (data) { - return arrayTypes[Object.prototype.toString.call(data)] | 0 -} - -function convertData (result, data) { - var n = data.length - switch (result.type) { - case GL_UNSIGNED_BYTE$5: - case GL_UNSIGNED_SHORT$3: - case GL_UNSIGNED_INT$3: - case GL_FLOAT$4: - var converted = pool.allocType(result.type, n) - converted.set(data) - result.data = converted - break - - case GL_HALF_FLOAT_OES$1: - result.data = convertToHalfFloat(data) - break - - default: - check$1.raise('unsupported texture type, must specify a typed array') - } -} - -function preConvert (image, n) { - return pool.allocType( - image.type === GL_HALF_FLOAT_OES$1 - ? GL_FLOAT$4 - : image.type, n) -} - -function postConvert (image, data) { - if (image.type === GL_HALF_FLOAT_OES$1) { - image.data = convertToHalfFloat(data) - pool.freeType(data) - } else { - image.data = data - } -} - -function transposeData (image, array, strideX, strideY, strideC, offset) { - var w = image.width - var h = image.height - var c = image.channels - var n = w * h * c - var data = preConvert(image, n) - - var p = 0 - for (var i = 0; i < h; ++i) { - for (var j = 0; j < w; ++j) { - for (var k = 0; k < c; ++k) { - data[p++] = array[strideX * j + strideY * i + strideC * k + offset] - } - } - } - - postConvert(image, data) -} - -function getTextureSize (format, type, width, height, isMipmap, isCube) { - var s - if (typeof FORMAT_SIZES_SPECIAL[format] !== 'undefined') { - // we have a special array for dealing with weird color formats such as RGB5A1 - s = FORMAT_SIZES_SPECIAL[format] - } else { - s = FORMAT_CHANNELS[format] * TYPE_SIZES[type] - } - - if (isCube) { - s *= 6 - } - - if (isMipmap) { - // compute the total size of all the mipmaps. - var total = 0 - - var w = width - while (w >= 1) { - // we can only use mipmaps on a square image, - // so we can simply use the width and ignore the height: - total += s * w * w - w /= 2 - } - return total - } else { - return s * width * height - } -} - -function createTextureSet ( - gl, extensions, limits, reglPoll, contextState, stats, config) { - // ------------------------------------------------------- - // Initialize constants and parameter tables here - // ------------------------------------------------------- - var mipmapHint = { - "don't care": GL_DONT_CARE, - 'dont care': GL_DONT_CARE, - 'nice': GL_NICEST, - 'fast': GL_FASTEST - } - - var wrapModes = { - 'repeat': GL_REPEAT, - 'clamp': GL_CLAMP_TO_EDGE$1, - 'mirror': GL_MIRRORED_REPEAT - } - - var magFilters = { - 'nearest': GL_NEAREST$1, - 'linear': GL_LINEAR - } - - var minFilters = extend({ - 'mipmap': GL_LINEAR_MIPMAP_LINEAR$1, - 'nearest mipmap nearest': GL_NEAREST_MIPMAP_NEAREST$1, - 'linear mipmap nearest': GL_LINEAR_MIPMAP_NEAREST$1, - 'nearest mipmap linear': GL_NEAREST_MIPMAP_LINEAR$1, - 'linear mipmap linear': GL_LINEAR_MIPMAP_LINEAR$1 - }, magFilters) - - var colorSpace = { - 'none': 0, - 'browser': GL_BROWSER_DEFAULT_WEBGL - } - - var textureTypes = { - 'uint8': GL_UNSIGNED_BYTE$5, - 'rgba4': GL_UNSIGNED_SHORT_4_4_4_4$1, - 'rgb565': GL_UNSIGNED_SHORT_5_6_5$1, - 'rgb5 a1': GL_UNSIGNED_SHORT_5_5_5_1$1 - } - - var textureFormats = { - 'alpha': GL_ALPHA, - 'luminance': GL_LUMINANCE, - 'luminance alpha': GL_LUMINANCE_ALPHA, - 'rgb': GL_RGB, - 'rgba': GL_RGBA$1, - 'rgba4': GL_RGBA4, - 'rgb5 a1': GL_RGB5_A1, - 'rgb565': GL_RGB565 - } - - var compressedTextureFormats = {} - - if (extensions.ext_srgb) { - textureFormats.srgb = GL_SRGB_EXT - textureFormats.srgba = GL_SRGB_ALPHA_EXT - } - - if (extensions.oes_texture_float) { - textureTypes.float32 = textureTypes.float = GL_FLOAT$4 - } - - if (extensions.oes_texture_half_float) { - textureTypes['float16'] = textureTypes['half float'] = GL_HALF_FLOAT_OES$1 - } - - if (extensions.webgl_depth_texture) { - extend(textureFormats, { - 'depth': GL_DEPTH_COMPONENT, - 'depth stencil': GL_DEPTH_STENCIL - }) - - extend(textureTypes, { - 'uint16': GL_UNSIGNED_SHORT$3, - 'uint32': GL_UNSIGNED_INT$3, - 'depth stencil': GL_UNSIGNED_INT_24_8_WEBGL$1 - }) - } - - if (extensions.webgl_compressed_texture_s3tc) { - extend(compressedTextureFormats, { - 'rgb s3tc dxt1': GL_COMPRESSED_RGB_S3TC_DXT1_EXT, - 'rgba s3tc dxt1': GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, - 'rgba s3tc dxt3': GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, - 'rgba s3tc dxt5': GL_COMPRESSED_RGBA_S3TC_DXT5_EXT - }) - } - - if (extensions.webgl_compressed_texture_atc) { - extend(compressedTextureFormats, { - 'rgb atc': GL_COMPRESSED_RGB_ATC_WEBGL, - 'rgba atc explicit alpha': GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL, - 'rgba atc interpolated alpha': GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL - }) - } - - if (extensions.webgl_compressed_texture_pvrtc) { - extend(compressedTextureFormats, { - 'rgb pvrtc 4bppv1': GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, - 'rgb pvrtc 2bppv1': GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, - 'rgba pvrtc 4bppv1': GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, - 'rgba pvrtc 2bppv1': GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG - }) - } - - if (extensions.webgl_compressed_texture_etc1) { - compressedTextureFormats['rgb etc1'] = GL_COMPRESSED_RGB_ETC1_WEBGL - } - - // Copy over all texture formats - var supportedCompressedFormats = Array.prototype.slice.call( - gl.getParameter(GL_COMPRESSED_TEXTURE_FORMATS)) - Object.keys(compressedTextureFormats).forEach(function (name) { - var format = compressedTextureFormats[name] - if (supportedCompressedFormats.indexOf(format) >= 0) { - textureFormats[name] = format - } - }) - - var supportedFormats = Object.keys(textureFormats) - limits.textureFormats = supportedFormats - - // associate with every format string its - // corresponding GL-value. - var textureFormatsInvert = [] - Object.keys(textureFormats).forEach(function (key) { - var val = textureFormats[key] - textureFormatsInvert[val] = key - }) - - // associate with every type string its - // corresponding GL-value. - var textureTypesInvert = [] - Object.keys(textureTypes).forEach(function (key) { - var val = textureTypes[key] - textureTypesInvert[val] = key - }) - - var magFiltersInvert = [] - Object.keys(magFilters).forEach(function (key) { - var val = magFilters[key] - magFiltersInvert[val] = key - }) - - var minFiltersInvert = [] - Object.keys(minFilters).forEach(function (key) { - var val = minFilters[key] - minFiltersInvert[val] = key - }) - - var wrapModesInvert = [] - Object.keys(wrapModes).forEach(function (key) { - var val = wrapModes[key] - wrapModesInvert[val] = key - }) - - // colorFormats[] gives the format (channels) associated to an - // internalformat - var colorFormats = supportedFormats.reduce(function (color, key) { - var glenum = textureFormats[key] - if (glenum === GL_LUMINANCE || - glenum === GL_ALPHA || - glenum === GL_LUMINANCE || - glenum === GL_LUMINANCE_ALPHA || - glenum === GL_DEPTH_COMPONENT || - glenum === GL_DEPTH_STENCIL || - (extensions.ext_srgb && - (glenum === GL_SRGB_EXT || - glenum === GL_SRGB_ALPHA_EXT))) { - color[glenum] = glenum - } else if (glenum === GL_RGB5_A1 || key.indexOf('rgba') >= 0) { - color[glenum] = GL_RGBA$1 - } else { - color[glenum] = GL_RGB - } - return color - }, {}) - - function TexFlags () { - // format info - this.internalformat = GL_RGBA$1 - this.format = GL_RGBA$1 - this.type = GL_UNSIGNED_BYTE$5 - this.compressed = false - - // pixel storage - this.premultiplyAlpha = false - this.flipY = false - this.unpackAlignment = 1 - this.colorSpace = GL_BROWSER_DEFAULT_WEBGL - - // shape info - this.width = 0 - this.height = 0 - this.channels = 0 - } - - function copyFlags (result, other) { - result.internalformat = other.internalformat - result.format = other.format - result.type = other.type - result.compressed = other.compressed - - result.premultiplyAlpha = other.premultiplyAlpha - result.flipY = other.flipY - result.unpackAlignment = other.unpackAlignment - result.colorSpace = other.colorSpace - - result.width = other.width - result.height = other.height - result.channels = other.channels - } - - function parseFlags (flags, options) { - if (typeof options !== 'object' || !options) { - return - } - - if ('premultiplyAlpha' in options) { - check$1.type(options.premultiplyAlpha, 'boolean', - 'invalid premultiplyAlpha') - flags.premultiplyAlpha = options.premultiplyAlpha - } - - if ('flipY' in options) { - check$1.type(options.flipY, 'boolean', - 'invalid texture flip') - flags.flipY = options.flipY - } - - if ('alignment' in options) { - check$1.oneOf(options.alignment, [1, 2, 4, 8], - 'invalid texture unpack alignment') - flags.unpackAlignment = options.alignment - } - - if ('colorSpace' in options) { - check$1.parameter(options.colorSpace, colorSpace, - 'invalid colorSpace') - flags.colorSpace = colorSpace[options.colorSpace] - } - - if ('type' in options) { - var type = options.type - check$1(extensions.oes_texture_float || - !(type === 'float' || type === 'float32'), - 'you must enable the OES_texture_float extension in order to use floating point textures.') - check$1(extensions.oes_texture_half_float || - !(type === 'half float' || type === 'float16'), - 'you must enable the OES_texture_half_float extension in order to use 16-bit floating point textures.') - check$1(extensions.webgl_depth_texture || - !(type === 'uint16' || type === 'uint32' || type === 'depth stencil'), - 'you must enable the WEBGL_depth_texture extension in order to use depth/stencil textures.') - check$1.parameter(type, textureTypes, - 'invalid texture type') - flags.type = textureTypes[type] - } - - var w = flags.width - var h = flags.height - var c = flags.channels - var hasChannels = false - if ('shape' in options) { - check$1(Array.isArray(options.shape) && options.shape.length >= 2, - 'shape must be an array') - w = options.shape[0] - h = options.shape[1] - if (options.shape.length === 3) { - c = options.shape[2] - check$1(c > 0 && c <= 4, 'invalid number of channels') - hasChannels = true - } - check$1(w >= 0 && w <= limits.maxTextureSize, 'invalid width') - check$1(h >= 0 && h <= limits.maxTextureSize, 'invalid height') - } else { - if ('radius' in options) { - w = h = options.radius - check$1(w >= 0 && w <= limits.maxTextureSize, 'invalid radius') - } - if ('width' in options) { - w = options.width - check$1(w >= 0 && w <= limits.maxTextureSize, 'invalid width') - } - if ('height' in options) { - h = options.height - check$1(h >= 0 && h <= limits.maxTextureSize, 'invalid height') - } - if ('channels' in options) { - c = options.channels - check$1(c > 0 && c <= 4, 'invalid number of channels') - hasChannels = true - } - } - flags.width = w | 0 - flags.height = h | 0 - flags.channels = c | 0 - - var hasFormat = false - if ('format' in options) { - var formatStr = options.format - check$1(extensions.webgl_depth_texture || - !(formatStr === 'depth' || formatStr === 'depth stencil'), - 'you must enable the WEBGL_depth_texture extension in order to use depth/stencil textures.') - check$1.parameter(formatStr, textureFormats, - 'invalid texture format') - var internalformat = flags.internalformat = textureFormats[formatStr] - flags.format = colorFormats[internalformat] - if (formatStr in textureTypes) { - if (!('type' in options)) { - flags.type = textureTypes[formatStr] - } - } - if (formatStr in compressedTextureFormats) { - flags.compressed = true - } - hasFormat = true - } - - // Reconcile channels and format - if (!hasChannels && hasFormat) { - flags.channels = FORMAT_CHANNELS[flags.format] - } else if (hasChannels && !hasFormat) { - if (flags.channels !== CHANNELS_FORMAT[flags.format]) { - flags.format = flags.internalformat = CHANNELS_FORMAT[flags.channels] - } - } else if (hasFormat && hasChannels) { - check$1( - flags.channels === FORMAT_CHANNELS[flags.format], - 'number of channels inconsistent with specified format') - } - } - - function setFlags (flags) { - gl.pixelStorei(GL_UNPACK_FLIP_Y_WEBGL, flags.flipY) - gl.pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL, flags.premultiplyAlpha) - gl.pixelStorei(GL_UNPACK_COLORSPACE_CONVERSION_WEBGL, flags.colorSpace) - gl.pixelStorei(GL_UNPACK_ALIGNMENT, flags.unpackAlignment) - } - - // ------------------------------------------------------- - // Tex image data - // ------------------------------------------------------- - function TexImage () { - TexFlags.call(this) - - this.xOffset = 0 - this.yOffset = 0 - - // data - this.data = null - this.needsFree = false - - // html element - this.element = null - - // copyTexImage info - this.needsCopy = false - } - - function parseImage (image, options) { - var data = null - if (isPixelData(options)) { - data = options - } else if (options) { - check$1.type(options, 'object', 'invalid pixel data type') - parseFlags(image, options) - if ('x' in options) { - image.xOffset = options.x | 0 - } - if ('y' in options) { - image.yOffset = options.y | 0 - } - if (isPixelData(options.data)) { - data = options.data - } - } - - check$1( - !image.compressed || - data instanceof Uint8Array, - 'compressed texture data must be stored in a uint8array') - - if (options.copy) { - check$1(!data, 'can not specify copy and data field for the same texture') - var viewW = contextState.viewportWidth - var viewH = contextState.viewportHeight - image.width = image.width || (viewW - image.xOffset) - image.height = image.height || (viewH - image.yOffset) - image.needsCopy = true - check$1(image.xOffset >= 0 && image.xOffset < viewW && - image.yOffset >= 0 && image.yOffset < viewH && - image.width > 0 && image.width <= viewW && - image.height > 0 && image.height <= viewH, - 'copy texture read out of bounds') - } else if (!data) { - image.width = image.width || 1 - image.height = image.height || 1 - image.channels = image.channels || 4 - } else if (isTypedArray(data)) { - image.channels = image.channels || 4 - image.data = data - if (!('type' in options) && image.type === GL_UNSIGNED_BYTE$5) { - image.type = typedArrayCode$1(data) - } - } else if (isNumericArray(data)) { - image.channels = image.channels || 4 - convertData(image, data) - image.alignment = 1 - image.needsFree = true - } else if (isNDArrayLike(data)) { - var array = data.data - if (!Array.isArray(array) && image.type === GL_UNSIGNED_BYTE$5) { - image.type = typedArrayCode$1(array) - } - var shape = data.shape - var stride = data.stride - var shapeX, shapeY, shapeC, strideX, strideY, strideC - if (shape.length === 3) { - shapeC = shape[2] - strideC = stride[2] - } else { - check$1(shape.length === 2, 'invalid ndarray pixel data, must be 2 or 3D') - shapeC = 1 - strideC = 1 - } - shapeX = shape[0] - shapeY = shape[1] - strideX = stride[0] - strideY = stride[1] - image.alignment = 1 - image.width = shapeX - image.height = shapeY - image.channels = shapeC - image.format = image.internalformat = CHANNELS_FORMAT[shapeC] - image.needsFree = true - transposeData(image, array, strideX, strideY, strideC, data.offset) - } else if (isCanvasElement(data) || isOffscreenCanvas(data) || isContext2D(data)) { - if (isCanvasElement(data) || isOffscreenCanvas(data)) { - image.element = data - } else { - image.element = data.canvas - } - image.width = image.element.width - image.height = image.element.height - image.channels = 4 - } else if (isBitmap(data)) { - image.element = data - image.width = data.width - image.height = data.height - image.channels = 4 - } else if (isImageElement(data)) { - image.element = data - image.width = data.naturalWidth - image.height = data.naturalHeight - image.channels = 4 - } else if (isVideoElement(data)) { - image.element = data - image.width = data.videoWidth - image.height = data.videoHeight - image.channels = 4 - } else if (isRectArray(data)) { - var w = image.width || data[0].length - var h = image.height || data.length - var c = image.channels - if (isArrayLike(data[0][0])) { - c = c || data[0][0].length - } else { - c = c || 1 - } - var arrayShape = flattenUtils.shape(data) - var n = 1 - for (var dd = 0; dd < arrayShape.length; ++dd) { - n *= arrayShape[dd] - } - var allocData = preConvert(image, n) - flattenUtils.flatten(data, arrayShape, '', allocData) - postConvert(image, allocData) - image.alignment = 1 - image.width = w - image.height = h - image.channels = c - image.format = image.internalformat = CHANNELS_FORMAT[c] - image.needsFree = true - } - - if (image.type === GL_FLOAT$4) { - check$1(limits.extensions.indexOf('oes_texture_float') >= 0, - 'oes_texture_float extension not enabled') - } else if (image.type === GL_HALF_FLOAT_OES$1) { - check$1(limits.extensions.indexOf('oes_texture_half_float') >= 0, - 'oes_texture_half_float extension not enabled') - } - - // do compressed texture validation here. - } - - function setImage (info, target, miplevel) { - var element = info.element - var data = info.data - var internalformat = info.internalformat - var format = info.format - var type = info.type - var width = info.width - var height = info.height - - setFlags(info) - - if (element) { - gl.texImage2D(target, miplevel, format, format, type, element) - } else if (info.compressed) { - gl.compressedTexImage2D(target, miplevel, internalformat, width, height, 0, data) - } else if (info.needsCopy) { - reglPoll() - gl.copyTexImage2D( - target, miplevel, format, info.xOffset, info.yOffset, width, height, 0) - } else { - gl.texImage2D(target, miplevel, format, width, height, 0, format, type, data || null) - } - } - - function setSubImage (info, target, x, y, miplevel) { - var element = info.element - var data = info.data - var internalformat = info.internalformat - var format = info.format - var type = info.type - var width = info.width - var height = info.height - - setFlags(info) - - if (element) { - gl.texSubImage2D( - target, miplevel, x, y, format, type, element) - } else if (info.compressed) { - gl.compressedTexSubImage2D( - target, miplevel, x, y, internalformat, width, height, data) - } else if (info.needsCopy) { - reglPoll() - gl.copyTexSubImage2D( - target, miplevel, x, y, info.xOffset, info.yOffset, width, height) - } else { - gl.texSubImage2D( - target, miplevel, x, y, width, height, format, type, data) - } - } - - // texImage pool - var imagePool = [] - - function allocImage () { - return imagePool.pop() || new TexImage() - } - - function freeImage (image) { - if (image.needsFree) { - pool.freeType(image.data) - } - TexImage.call(image) - imagePool.push(image) - } - - // ------------------------------------------------------- - // Mip map - // ------------------------------------------------------- - function MipMap () { - TexFlags.call(this) - - this.genMipmaps = false - this.mipmapHint = GL_DONT_CARE - this.mipmask = 0 - this.images = Array(16) - } - - function parseMipMapFromShape (mipmap, width, height) { - var img = mipmap.images[0] = allocImage() - mipmap.mipmask = 1 - img.width = mipmap.width = width - img.height = mipmap.height = height - img.channels = mipmap.channels = 4 - } - - function parseMipMapFromObject (mipmap, options) { - var imgData = null - if (isPixelData(options)) { - imgData = mipmap.images[0] = allocImage() - copyFlags(imgData, mipmap) - parseImage(imgData, options) - mipmap.mipmask = 1 - } else { - parseFlags(mipmap, options) - if (Array.isArray(options.mipmap)) { - var mipData = options.mipmap - for (var i = 0; i < mipData.length; ++i) { - imgData = mipmap.images[i] = allocImage() - copyFlags(imgData, mipmap) - imgData.width >>= i - imgData.height >>= i - parseImage(imgData, mipData[i]) - mipmap.mipmask |= (1 << i) - } - } else { - imgData = mipmap.images[0] = allocImage() - copyFlags(imgData, mipmap) - parseImage(imgData, options) - mipmap.mipmask = 1 - } - } - copyFlags(mipmap, mipmap.images[0]) - - // For textures of the compressed format WEBGL_compressed_texture_s3tc - // we must have that - // - // "When level equals zero width and height must be a multiple of 4. - // When level is greater than 0 width and height must be 0, 1, 2 or a multiple of 4. " - // - // but we do not yet support having multiple mipmap levels for compressed textures, - // so we only test for level zero. - - if ( - mipmap.compressed && - ( - mipmap.internalformat === GL_COMPRESSED_RGB_S3TC_DXT1_EXT || - mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || - mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT3_EXT || - mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT5_EXT - ) - ) { - check$1(mipmap.width % 4 === 0 && mipmap.height % 4 === 0, - 'for compressed texture formats, mipmap level 0 must have width and height that are a multiple of 4') - } - } - - function setMipMap (mipmap, target) { - var images = mipmap.images - for (var i = 0; i < images.length; ++i) { - if (!images[i]) { - return - } - setImage(images[i], target, i) - } - } - - var mipPool = [] - - function allocMipMap () { - var result = mipPool.pop() || new MipMap() - TexFlags.call(result) - result.mipmask = 0 - for (var i = 0; i < 16; ++i) { - result.images[i] = null - } - return result - } - - function freeMipMap (mipmap) { - var images = mipmap.images - for (var i = 0; i < images.length; ++i) { - if (images[i]) { - freeImage(images[i]) - } - images[i] = null - } - mipPool.push(mipmap) - } - - // ------------------------------------------------------- - // Tex info - // ------------------------------------------------------- - function TexInfo () { - this.minFilter = GL_NEAREST$1 - this.magFilter = GL_NEAREST$1 - - this.wrapS = GL_CLAMP_TO_EDGE$1 - this.wrapT = GL_CLAMP_TO_EDGE$1 - - this.anisotropic = 1 - - this.genMipmaps = false - this.mipmapHint = GL_DONT_CARE - } - - function parseTexInfo (info, options) { - if ('min' in options) { - var minFilter = options.min - check$1.parameter(minFilter, minFilters) - info.minFilter = minFilters[minFilter] - if (MIPMAP_FILTERS.indexOf(info.minFilter) >= 0 && !('faces' in options)) { - info.genMipmaps = true - } - } - - if ('mag' in options) { - var magFilter = options.mag - check$1.parameter(magFilter, magFilters) - info.magFilter = magFilters[magFilter] - } - - var wrapS = info.wrapS - var wrapT = info.wrapT - if ('wrap' in options) { - var wrap = options.wrap - if (typeof wrap === 'string') { - check$1.parameter(wrap, wrapModes) - wrapS = wrapT = wrapModes[wrap] - } else if (Array.isArray(wrap)) { - check$1.parameter(wrap[0], wrapModes) - check$1.parameter(wrap[1], wrapModes) - wrapS = wrapModes[wrap[0]] - wrapT = wrapModes[wrap[1]] - } - } else { - if ('wrapS' in options) { - var optWrapS = options.wrapS - check$1.parameter(optWrapS, wrapModes) - wrapS = wrapModes[optWrapS] - } - if ('wrapT' in options) { - var optWrapT = options.wrapT - check$1.parameter(optWrapT, wrapModes) - wrapT = wrapModes[optWrapT] - } - } - info.wrapS = wrapS - info.wrapT = wrapT - - if ('anisotropic' in options) { - var anisotropic = options.anisotropic - check$1(typeof anisotropic === 'number' && - anisotropic >= 1 && anisotropic <= limits.maxAnisotropic, - 'aniso samples must be between 1 and ') - info.anisotropic = options.anisotropic - } - - if ('mipmap' in options) { - var hasMipMap = false - switch (typeof options.mipmap) { - case 'string': - check$1.parameter(options.mipmap, mipmapHint, - 'invalid mipmap hint') - info.mipmapHint = mipmapHint[options.mipmap] - info.genMipmaps = true - hasMipMap = true - break - - case 'boolean': - hasMipMap = info.genMipmaps = options.mipmap - break - - case 'object': - check$1(Array.isArray(options.mipmap), 'invalid mipmap type') - info.genMipmaps = false - hasMipMap = true - break - - default: - check$1.raise('invalid mipmap type') - } - if (hasMipMap && !('min' in options)) { - info.minFilter = GL_NEAREST_MIPMAP_NEAREST$1 - } - } - } - - function setTexInfo (info, target) { - gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, info.minFilter) - gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, info.magFilter) - gl.texParameteri(target, GL_TEXTURE_WRAP_S, info.wrapS) - gl.texParameteri(target, GL_TEXTURE_WRAP_T, info.wrapT) - if (extensions.ext_texture_filter_anisotropic) { - gl.texParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, info.anisotropic) - } - if (info.genMipmaps) { - gl.hint(GL_GENERATE_MIPMAP_HINT, info.mipmapHint) - gl.generateMipmap(target) - } - } - - // ------------------------------------------------------- - // Full texture object - // ------------------------------------------------------- - var textureCount = 0 - var textureSet = {} - var numTexUnits = limits.maxTextureUnits - var textureUnits = Array(numTexUnits).map(function () { - return null - }) - - function REGLTexture (target) { - TexFlags.call(this) - this.mipmask = 0 - this.internalformat = GL_RGBA$1 - - this.id = textureCount++ - - this.refCount = 1 - - this.target = target - this.texture = gl.createTexture() - - this.unit = -1 - this.bindCount = 0 - - this.texInfo = new TexInfo() - - if (config.profile) { - this.stats = { size: 0 } - } - } - - function tempBind (texture) { - gl.activeTexture(GL_TEXTURE0$1) - gl.bindTexture(texture.target, texture.texture) - } - - function tempRestore () { - var prev = textureUnits[0] - if (prev) { - gl.bindTexture(prev.target, prev.texture) - } else { - gl.bindTexture(GL_TEXTURE_2D$1, null) - } - } - - function destroy (texture) { - var handle = texture.texture - check$1(handle, 'must not double destroy texture') - var unit = texture.unit - var target = texture.target - if (unit >= 0) { - gl.activeTexture(GL_TEXTURE0$1 + unit) - gl.bindTexture(target, null) - textureUnits[unit] = null - } - gl.deleteTexture(handle) - texture.texture = null - texture.params = null - texture.pixels = null - texture.refCount = 0 - delete textureSet[texture.id] - stats.textureCount-- - } - - extend(REGLTexture.prototype, { - bind: function () { - var texture = this - texture.bindCount += 1 - var unit = texture.unit - if (unit < 0) { - for (var i = 0; i < numTexUnits; ++i) { - var other = textureUnits[i] - if (other) { - if (other.bindCount > 0) { - continue - } - other.unit = -1 - } - textureUnits[i] = texture - unit = i - break - } - if (unit >= numTexUnits) { - check$1.raise('insufficient number of texture units') - } - if (config.profile && stats.maxTextureUnits < (unit + 1)) { - stats.maxTextureUnits = unit + 1 // +1, since the units are zero-based - } - texture.unit = unit - gl.activeTexture(GL_TEXTURE0$1 + unit) - gl.bindTexture(texture.target, texture.texture) - } - return unit - }, - - unbind: function () { - this.bindCount -= 1 - }, - - decRef: function () { - if (--this.refCount <= 0) { - destroy(this) - } - } - }) - - function createTexture2D (a, b) { - var texture = new REGLTexture(GL_TEXTURE_2D$1) - textureSet[texture.id] = texture - stats.textureCount++ - - function reglTexture2D (a, b) { - var texInfo = texture.texInfo - TexInfo.call(texInfo) - var mipData = allocMipMap() - - if (typeof a === 'number') { - if (typeof b === 'number') { - parseMipMapFromShape(mipData, a | 0, b | 0) - } else { - parseMipMapFromShape(mipData, a | 0, a | 0) - } - } else if (a) { - check$1.type(a, 'object', 'invalid arguments to regl.texture') - parseTexInfo(texInfo, a) - parseMipMapFromObject(mipData, a) - } else { - // empty textures get assigned a default shape of 1x1 - parseMipMapFromShape(mipData, 1, 1) - } - - if (texInfo.genMipmaps) { - mipData.mipmask = (mipData.width << 1) - 1 - } - texture.mipmask = mipData.mipmask - - copyFlags(texture, mipData) - - check$1.texture2D(texInfo, mipData, limits) - texture.internalformat = mipData.internalformat - - reglTexture2D.width = mipData.width - reglTexture2D.height = mipData.height - - tempBind(texture) - setMipMap(mipData, GL_TEXTURE_2D$1) - setTexInfo(texInfo, GL_TEXTURE_2D$1) - tempRestore() - - freeMipMap(mipData) - - if (config.profile) { - texture.stats.size = getTextureSize( - texture.internalformat, - texture.type, - mipData.width, - mipData.height, - texInfo.genMipmaps, - false) - } - reglTexture2D.format = textureFormatsInvert[texture.internalformat] - reglTexture2D.type = textureTypesInvert[texture.type] - - reglTexture2D.mag = magFiltersInvert[texInfo.magFilter] - reglTexture2D.min = minFiltersInvert[texInfo.minFilter] - - reglTexture2D.wrapS = wrapModesInvert[texInfo.wrapS] - reglTexture2D.wrapT = wrapModesInvert[texInfo.wrapT] - - return reglTexture2D - } - - function subimage (image, x_, y_, level_) { - check$1(!!image, 'must specify image data') - - var x = x_ | 0 - var y = y_ | 0 - var level = level_ | 0 - - var imageData = allocImage() - copyFlags(imageData, texture) - imageData.width = 0 - imageData.height = 0 - parseImage(imageData, image) - imageData.width = imageData.width || ((texture.width >> level) - x) - imageData.height = imageData.height || ((texture.height >> level) - y) - - check$1( - texture.type === imageData.type && - texture.format === imageData.format && - texture.internalformat === imageData.internalformat, - 'incompatible format for texture.subimage') - check$1( - x >= 0 && y >= 0 && - x + imageData.width <= texture.width && - y + imageData.height <= texture.height, - 'texture.subimage write out of bounds') - check$1( - texture.mipmask & (1 << level), - 'missing mipmap data') - check$1( - imageData.data || imageData.element || imageData.needsCopy, - 'missing image data') - - tempBind(texture) - setSubImage(imageData, GL_TEXTURE_2D$1, x, y, level) - tempRestore() - - freeImage(imageData) - - return reglTexture2D - } - - function resize (w_, h_) { - var w = w_ | 0 - var h = (h_ | 0) || w - if (w === texture.width && h === texture.height) { - return reglTexture2D - } - - reglTexture2D.width = texture.width = w - reglTexture2D.height = texture.height = h - - tempBind(texture) - - for (var i = 0; texture.mipmask >> i; ++i) { - var _w = w >> i - var _h = h >> i - if (!_w || !_h) break - gl.texImage2D( - GL_TEXTURE_2D$1, - i, - texture.format, - _w, - _h, - 0, - texture.format, - texture.type, - null) - } - tempRestore() - - // also, recompute the texture size. - if (config.profile) { - texture.stats.size = getTextureSize( - texture.internalformat, - texture.type, - w, - h, - false, - false) - } - - return reglTexture2D - } - - reglTexture2D(a, b) - - reglTexture2D.subimage = subimage - reglTexture2D.resize = resize - reglTexture2D._reglType = 'texture2d' - reglTexture2D._texture = texture - if (config.profile) { - reglTexture2D.stats = texture.stats - } - reglTexture2D.destroy = function () { - texture.decRef() - } - - return reglTexture2D - } - - function createTextureCube (a0, a1, a2, a3, a4, a5) { - var texture = new REGLTexture(GL_TEXTURE_CUBE_MAP$1) - textureSet[texture.id] = texture - stats.cubeCount++ - - var faces = new Array(6) - - function reglTextureCube (a0, a1, a2, a3, a4, a5) { - var i - var texInfo = texture.texInfo - TexInfo.call(texInfo) - for (i = 0; i < 6; ++i) { - faces[i] = allocMipMap() - } - - if (typeof a0 === 'number' || !a0) { - var s = (a0 | 0) || 1 - for (i = 0; i < 6; ++i) { - parseMipMapFromShape(faces[i], s, s) - } - } else if (typeof a0 === 'object') { - if (a1) { - parseMipMapFromObject(faces[0], a0) - parseMipMapFromObject(faces[1], a1) - parseMipMapFromObject(faces[2], a2) - parseMipMapFromObject(faces[3], a3) - parseMipMapFromObject(faces[4], a4) - parseMipMapFromObject(faces[5], a5) - } else { - parseTexInfo(texInfo, a0) - parseFlags(texture, a0) - if ('faces' in a0) { - var faceInput = a0.faces - check$1(Array.isArray(faceInput) && faceInput.length === 6, - 'cube faces must be a length 6 array') - for (i = 0; i < 6; ++i) { - check$1(typeof faceInput[i] === 'object' && !!faceInput[i], - 'invalid input for cube map face') - copyFlags(faces[i], texture) - parseMipMapFromObject(faces[i], faceInput[i]) - } - } else { - for (i = 0; i < 6; ++i) { - parseMipMapFromObject(faces[i], a0) - } - } - } - } else { - check$1.raise('invalid arguments to cube map') - } - - copyFlags(texture, faces[0]) - check$1.optional(function () { - if (!limits.npotTextureCube) { - check$1(isPow2$1(texture.width) && isPow2$1(texture.height), 'your browser does not support non power or two texture dimensions') - } - }) - - if (texInfo.genMipmaps) { - texture.mipmask = (faces[0].width << 1) - 1 - } else { - texture.mipmask = faces[0].mipmask - } - - check$1.textureCube(texture, texInfo, faces, limits) - texture.internalformat = faces[0].internalformat - - reglTextureCube.width = faces[0].width - reglTextureCube.height = faces[0].height - - tempBind(texture) - for (i = 0; i < 6; ++i) { - setMipMap(faces[i], GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + i) - } - setTexInfo(texInfo, GL_TEXTURE_CUBE_MAP$1) - tempRestore() - - if (config.profile) { - texture.stats.size = getTextureSize( - texture.internalformat, - texture.type, - reglTextureCube.width, - reglTextureCube.height, - texInfo.genMipmaps, - true) - } - - reglTextureCube.format = textureFormatsInvert[texture.internalformat] - reglTextureCube.type = textureTypesInvert[texture.type] - - reglTextureCube.mag = magFiltersInvert[texInfo.magFilter] - reglTextureCube.min = minFiltersInvert[texInfo.minFilter] - - reglTextureCube.wrapS = wrapModesInvert[texInfo.wrapS] - reglTextureCube.wrapT = wrapModesInvert[texInfo.wrapT] - - for (i = 0; i < 6; ++i) { - freeMipMap(faces[i]) - } - - return reglTextureCube - } - - function subimage (face, image, x_, y_, level_) { - check$1(!!image, 'must specify image data') - check$1(typeof face === 'number' && face === (face | 0) && - face >= 0 && face < 6, 'invalid face') - - var x = x_ | 0 - var y = y_ | 0 - var level = level_ | 0 - - var imageData = allocImage() - copyFlags(imageData, texture) - imageData.width = 0 - imageData.height = 0 - parseImage(imageData, image) - imageData.width = imageData.width || ((texture.width >> level) - x) - imageData.height = imageData.height || ((texture.height >> level) - y) - - check$1( - texture.type === imageData.type && - texture.format === imageData.format && - texture.internalformat === imageData.internalformat, - 'incompatible format for texture.subimage') - check$1( - x >= 0 && y >= 0 && - x + imageData.width <= texture.width && - y + imageData.height <= texture.height, - 'texture.subimage write out of bounds') - check$1( - texture.mipmask & (1 << level), - 'missing mipmap data') - check$1( - imageData.data || imageData.element || imageData.needsCopy, - 'missing image data') - - tempBind(texture) - setSubImage(imageData, GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + face, x, y, level) - tempRestore() - - freeImage(imageData) - - return reglTextureCube - } - - function resize (radius_) { - var radius = radius_ | 0 - if (radius === texture.width) { - return - } - - reglTextureCube.width = texture.width = radius - reglTextureCube.height = texture.height = radius - - tempBind(texture) - for (var i = 0; i < 6; ++i) { - for (var j = 0; texture.mipmask >> j; ++j) { - gl.texImage2D( - GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + i, - j, - texture.format, - radius >> j, - radius >> j, - 0, - texture.format, - texture.type, - null) - } - } - tempRestore() - - if (config.profile) { - texture.stats.size = getTextureSize( - texture.internalformat, - texture.type, - reglTextureCube.width, - reglTextureCube.height, - false, - true) - } - - return reglTextureCube - } - - reglTextureCube(a0, a1, a2, a3, a4, a5) - - reglTextureCube.subimage = subimage - reglTextureCube.resize = resize - reglTextureCube._reglType = 'textureCube' - reglTextureCube._texture = texture - if (config.profile) { - reglTextureCube.stats = texture.stats - } - reglTextureCube.destroy = function () { - texture.decRef() - } - - return reglTextureCube - } - - // Called when regl is destroyed - function destroyTextures () { - for (var i = 0; i < numTexUnits; ++i) { - gl.activeTexture(GL_TEXTURE0$1 + i) - gl.bindTexture(GL_TEXTURE_2D$1, null) - textureUnits[i] = null - } - values(textureSet).forEach(destroy) - - stats.cubeCount = 0 - stats.textureCount = 0 - } - - if (config.profile) { - stats.getTotalTextureSize = function () { - var total = 0 - Object.keys(textureSet).forEach(function (key) { - total += textureSet[key].stats.size - }) - return total - } - } - - function restoreTextures () { - for (var i = 0; i < numTexUnits; ++i) { - var tex = textureUnits[i] - if (tex) { - tex.bindCount = 0 - tex.unit = -1 - textureUnits[i] = null - } - } - - values(textureSet).forEach(function (texture) { - texture.texture = gl.createTexture() - gl.bindTexture(texture.target, texture.texture) - for (var i = 0; i < 32; ++i) { - if ((texture.mipmask & (1 << i)) === 0) { - continue - } - if (texture.target === GL_TEXTURE_2D$1) { - gl.texImage2D(GL_TEXTURE_2D$1, - i, - texture.internalformat, - texture.width >> i, - texture.height >> i, - 0, - texture.internalformat, - texture.type, - null) - } else { - for (var j = 0; j < 6; ++j) { - gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + j, - i, - texture.internalformat, - texture.width >> i, - texture.height >> i, - 0, - texture.internalformat, - texture.type, - null) - } - } - } - setTexInfo(texture.texInfo, texture.target) - }) - } - - function refreshTextures () { - for (var i = 0; i < numTexUnits; ++i) { - var tex = textureUnits[i] - if (tex) { - tex.bindCount = 0 - tex.unit = -1 - textureUnits[i] = null - } - gl.activeTexture(GL_TEXTURE0$1 + i) - gl.bindTexture(GL_TEXTURE_2D$1, null) - gl.bindTexture(GL_TEXTURE_CUBE_MAP$1, null) - } - } - - return { - create2D: createTexture2D, - createCube: createTextureCube, - clear: destroyTextures, - getTexture: function (wrapper) { - return null - }, - restore: restoreTextures, - refresh: refreshTextures - } -} - -var GL_RENDERBUFFER = 0x8D41 - -var GL_RGBA4$1 = 0x8056 -var GL_RGB5_A1$1 = 0x8057 -var GL_RGB565$1 = 0x8D62 -var GL_DEPTH_COMPONENT16 = 0x81A5 -var GL_STENCIL_INDEX8 = 0x8D48 -var GL_DEPTH_STENCIL$1 = 0x84F9 - -var GL_SRGB8_ALPHA8_EXT = 0x8C43 - -var GL_RGBA32F_EXT = 0x8814 - -var GL_RGBA16F_EXT = 0x881A -var GL_RGB16F_EXT = 0x881B - -var FORMAT_SIZES = [] - -FORMAT_SIZES[GL_RGBA4$1] = 2 -FORMAT_SIZES[GL_RGB5_A1$1] = 2 -FORMAT_SIZES[GL_RGB565$1] = 2 - -FORMAT_SIZES[GL_DEPTH_COMPONENT16] = 2 -FORMAT_SIZES[GL_STENCIL_INDEX8] = 1 -FORMAT_SIZES[GL_DEPTH_STENCIL$1] = 4 - -FORMAT_SIZES[GL_SRGB8_ALPHA8_EXT] = 4 -FORMAT_SIZES[GL_RGBA32F_EXT] = 16 -FORMAT_SIZES[GL_RGBA16F_EXT] = 8 -FORMAT_SIZES[GL_RGB16F_EXT] = 6 - -function getRenderbufferSize (format, width, height) { - return FORMAT_SIZES[format] * width * height -} - -var wrapRenderbuffers = function (gl, extensions, limits, stats, config) { - var formatTypes = { - 'rgba4': GL_RGBA4$1, - 'rgb565': GL_RGB565$1, - 'rgb5 a1': GL_RGB5_A1$1, - 'depth': GL_DEPTH_COMPONENT16, - 'stencil': GL_STENCIL_INDEX8, - 'depth stencil': GL_DEPTH_STENCIL$1 - } - - if (extensions.ext_srgb) { - formatTypes['srgba'] = GL_SRGB8_ALPHA8_EXT - } - - if (extensions.ext_color_buffer_half_float) { - formatTypes['rgba16f'] = GL_RGBA16F_EXT - formatTypes['rgb16f'] = GL_RGB16F_EXT - } - - if (extensions.webgl_color_buffer_float) { - formatTypes['rgba32f'] = GL_RGBA32F_EXT - } - - var formatTypesInvert = [] - Object.keys(formatTypes).forEach(function (key) { - var val = formatTypes[key] - formatTypesInvert[val] = key - }) - - var renderbufferCount = 0 - var renderbufferSet = {} - - function REGLRenderbuffer (renderbuffer) { - this.id = renderbufferCount++ - this.refCount = 1 - - this.renderbuffer = renderbuffer - - this.format = GL_RGBA4$1 - this.width = 0 - this.height = 0 - - if (config.profile) { - this.stats = { size: 0 } - } - } - - REGLRenderbuffer.prototype.decRef = function () { - if (--this.refCount <= 0) { - destroy(this) - } - } - - function destroy (rb) { - var handle = rb.renderbuffer - check$1(handle, 'must not double destroy renderbuffer') - gl.bindRenderbuffer(GL_RENDERBUFFER, null) - gl.deleteRenderbuffer(handle) - rb.renderbuffer = null - rb.refCount = 0 - delete renderbufferSet[rb.id] - stats.renderbufferCount-- - } - - function createRenderbuffer (a, b) { - var renderbuffer = new REGLRenderbuffer(gl.createRenderbuffer()) - renderbufferSet[renderbuffer.id] = renderbuffer - stats.renderbufferCount++ - - function reglRenderbuffer (a, b) { - var w = 0 - var h = 0 - var format = GL_RGBA4$1 - - if (typeof a === 'object' && a) { - var options = a - if ('shape' in options) { - var shape = options.shape - check$1(Array.isArray(shape) && shape.length >= 2, - 'invalid renderbuffer shape') - w = shape[0] | 0 - h = shape[1] | 0 - } else { - if ('radius' in options) { - w = h = options.radius | 0 - } - if ('width' in options) { - w = options.width | 0 - } - if ('height' in options) { - h = options.height | 0 - } - } - if ('format' in options) { - check$1.parameter(options.format, formatTypes, - 'invalid renderbuffer format') - format = formatTypes[options.format] - } - } else if (typeof a === 'number') { - w = a | 0 - if (typeof b === 'number') { - h = b | 0 - } else { - h = w - } - } else if (!a) { - w = h = 1 - } else { - check$1.raise('invalid arguments to renderbuffer constructor') - } - - // check shape - check$1( - w > 0 && h > 0 && - w <= limits.maxRenderbufferSize && h <= limits.maxRenderbufferSize, - 'invalid renderbuffer size') - - if (w === renderbuffer.width && - h === renderbuffer.height && - format === renderbuffer.format) { - return - } - - reglRenderbuffer.width = renderbuffer.width = w - reglRenderbuffer.height = renderbuffer.height = h - renderbuffer.format = format - - gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer.renderbuffer) - gl.renderbufferStorage(GL_RENDERBUFFER, format, w, h) - - check$1( - gl.getError() === 0, - 'invalid render buffer format') - - if (config.profile) { - renderbuffer.stats.size = getRenderbufferSize(renderbuffer.format, renderbuffer.width, renderbuffer.height) - } - reglRenderbuffer.format = formatTypesInvert[renderbuffer.format] - - return reglRenderbuffer - } - - function resize (w_, h_) { - var w = w_ | 0 - var h = (h_ | 0) || w - - if (w === renderbuffer.width && h === renderbuffer.height) { - return reglRenderbuffer - } - - // check shape - check$1( - w > 0 && h > 0 && - w <= limits.maxRenderbufferSize && h <= limits.maxRenderbufferSize, - 'invalid renderbuffer size') - - reglRenderbuffer.width = renderbuffer.width = w - reglRenderbuffer.height = renderbuffer.height = h - - gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer.renderbuffer) - gl.renderbufferStorage(GL_RENDERBUFFER, renderbuffer.format, w, h) - - check$1( - gl.getError() === 0, - 'invalid render buffer format') - - // also, recompute size. - if (config.profile) { - renderbuffer.stats.size = getRenderbufferSize( - renderbuffer.format, renderbuffer.width, renderbuffer.height) - } - - return reglRenderbuffer - } - - reglRenderbuffer(a, b) - - reglRenderbuffer.resize = resize - reglRenderbuffer._reglType = 'renderbuffer' - reglRenderbuffer._renderbuffer = renderbuffer - if (config.profile) { - reglRenderbuffer.stats = renderbuffer.stats - } - reglRenderbuffer.destroy = function () { - renderbuffer.decRef() - } - - return reglRenderbuffer - } - - if (config.profile) { - stats.getTotalRenderbufferSize = function () { - var total = 0 - Object.keys(renderbufferSet).forEach(function (key) { - total += renderbufferSet[key].stats.size - }) - return total - } - } - - function restoreRenderbuffers () { - values(renderbufferSet).forEach(function (rb) { - rb.renderbuffer = gl.createRenderbuffer() - gl.bindRenderbuffer(GL_RENDERBUFFER, rb.renderbuffer) - gl.renderbufferStorage(GL_RENDERBUFFER, rb.format, rb.width, rb.height) - }) - gl.bindRenderbuffer(GL_RENDERBUFFER, null) - } - - return { - create: createRenderbuffer, - clear: function () { - values(renderbufferSet).forEach(destroy) - }, - restore: restoreRenderbuffers - } -} - -// We store these constants so that the minifier can inline them -var GL_FRAMEBUFFER$1 = 0x8D40 -var GL_RENDERBUFFER$1 = 0x8D41 - -var GL_TEXTURE_2D$2 = 0x0DE1 -var GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 = 0x8515 - -var GL_COLOR_ATTACHMENT0$1 = 0x8CE0 -var GL_DEPTH_ATTACHMENT = 0x8D00 -var GL_STENCIL_ATTACHMENT = 0x8D20 -var GL_DEPTH_STENCIL_ATTACHMENT = 0x821A - -var GL_FRAMEBUFFER_COMPLETE$1 = 0x8CD5 -var GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6 -var GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7 -var GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9 -var GL_FRAMEBUFFER_UNSUPPORTED = 0x8CDD - -var GL_HALF_FLOAT_OES$2 = 0x8D61 -var GL_UNSIGNED_BYTE$6 = 0x1401 -var GL_FLOAT$5 = 0x1406 - -var GL_RGB$1 = 0x1907 -var GL_RGBA$2 = 0x1908 - -var GL_DEPTH_COMPONENT$1 = 0x1902 - -var colorTextureFormatEnums = [ - GL_RGB$1, - GL_RGBA$2 -] - -// for every texture format, store -// the number of channels -var textureFormatChannels = [] -textureFormatChannels[GL_RGBA$2] = 4 -textureFormatChannels[GL_RGB$1] = 3 - -// for every texture type, store -// the size in bytes. -var textureTypeSizes = [] -textureTypeSizes[GL_UNSIGNED_BYTE$6] = 1 -textureTypeSizes[GL_FLOAT$5] = 4 -textureTypeSizes[GL_HALF_FLOAT_OES$2] = 2 - -var GL_RGBA4$2 = 0x8056 -var GL_RGB5_A1$2 = 0x8057 -var GL_RGB565$2 = 0x8D62 -var GL_DEPTH_COMPONENT16$1 = 0x81A5 -var GL_STENCIL_INDEX8$1 = 0x8D48 -var GL_DEPTH_STENCIL$2 = 0x84F9 - -var GL_SRGB8_ALPHA8_EXT$1 = 0x8C43 - -var GL_RGBA32F_EXT$1 = 0x8814 - -var GL_RGBA16F_EXT$1 = 0x881A -var GL_RGB16F_EXT$1 = 0x881B - -var colorRenderbufferFormatEnums = [ - GL_RGBA4$2, - GL_RGB5_A1$2, - GL_RGB565$2, - GL_SRGB8_ALPHA8_EXT$1, - GL_RGBA16F_EXT$1, - GL_RGB16F_EXT$1, - GL_RGBA32F_EXT$1 -] - -var statusCode = {} -statusCode[GL_FRAMEBUFFER_COMPLETE$1] = 'complete' -statusCode[GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT] = 'incomplete attachment' -statusCode[GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS] = 'incomplete dimensions' -statusCode[GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT] = 'incomplete, missing attachment' -statusCode[GL_FRAMEBUFFER_UNSUPPORTED] = 'unsupported' - -function wrapFBOState ( - gl, - extensions, - limits, - textureState, - renderbufferState, - stats) { - var framebufferState = { - cur: null, - next: null, - dirty: false, - setFBO: null - } - - var colorTextureFormats = ['rgba'] - var colorRenderbufferFormats = ['rgba4', 'rgb565', 'rgb5 a1'] - - if (extensions.ext_srgb) { - colorRenderbufferFormats.push('srgba') - } - - if (extensions.ext_color_buffer_half_float) { - colorRenderbufferFormats.push('rgba16f', 'rgb16f') - } - - if (extensions.webgl_color_buffer_float) { - colorRenderbufferFormats.push('rgba32f') - } - - var colorTypes = ['uint8'] - if (extensions.oes_texture_half_float) { - colorTypes.push('half float', 'float16') - } - if (extensions.oes_texture_float) { - colorTypes.push('float', 'float32') - } - - function FramebufferAttachment (target, texture, renderbuffer) { - this.target = target - this.texture = texture - this.renderbuffer = renderbuffer - - var w = 0 - var h = 0 - if (texture) { - w = texture.width - h = texture.height - } else if (renderbuffer) { - w = renderbuffer.width - h = renderbuffer.height - } - this.width = w - this.height = h - } - - function decRef (attachment) { - if (attachment) { - if (attachment.texture) { - attachment.texture._texture.decRef() - } - if (attachment.renderbuffer) { - attachment.renderbuffer._renderbuffer.decRef() - } - } - } - - function incRefAndCheckShape (attachment, width, height) { - if (!attachment) { - return - } - if (attachment.texture) { - var texture = attachment.texture._texture - var tw = Math.max(1, texture.width) - var th = Math.max(1, texture.height) - check$1(tw === width && th === height, - 'inconsistent width/height for supplied texture') - texture.refCount += 1 - } else { - var renderbuffer = attachment.renderbuffer._renderbuffer - check$1( - renderbuffer.width === width && renderbuffer.height === height, - 'inconsistent width/height for renderbuffer') - renderbuffer.refCount += 1 - } - } - - function attach (location, attachment) { - if (attachment) { - if (attachment.texture) { - gl.framebufferTexture2D( - GL_FRAMEBUFFER$1, - location, - attachment.target, - attachment.texture._texture.texture, - 0) - } else { - gl.framebufferRenderbuffer( - GL_FRAMEBUFFER$1, - location, - GL_RENDERBUFFER$1, - attachment.renderbuffer._renderbuffer.renderbuffer) - } - } - } - - function parseAttachment (attachment) { - var target = GL_TEXTURE_2D$2 - var texture = null - var renderbuffer = null - - var data = attachment - if (typeof attachment === 'object') { - data = attachment.data - if ('target' in attachment) { - target = attachment.target | 0 - } - } - - check$1.type(data, 'function', 'invalid attachment data') - - var type = data._reglType - if (type === 'texture2d') { - texture = data - check$1(target === GL_TEXTURE_2D$2) - } else if (type === 'textureCube') { - texture = data - check$1( - target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 && - target < GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 + 6, - 'invalid cube map target') - } else if (type === 'renderbuffer') { - renderbuffer = data - target = GL_RENDERBUFFER$1 - } else { - check$1.raise('invalid regl object for attachment') - } - - return new FramebufferAttachment(target, texture, renderbuffer) - } - - function allocAttachment ( - width, - height, - isTexture, - format, - type) { - if (isTexture) { - var texture = textureState.create2D({ - width: width, - height: height, - format: format, - type: type - }) - texture._texture.refCount = 0 - return new FramebufferAttachment(GL_TEXTURE_2D$2, texture, null) - } else { - var rb = renderbufferState.create({ - width: width, - height: height, - format: format - }) - rb._renderbuffer.refCount = 0 - return new FramebufferAttachment(GL_RENDERBUFFER$1, null, rb) - } - } - - function unwrapAttachment (attachment) { - return attachment && (attachment.texture || attachment.renderbuffer) - } - - function resizeAttachment (attachment, w, h) { - if (attachment) { - if (attachment.texture) { - attachment.texture.resize(w, h) - } else if (attachment.renderbuffer) { - attachment.renderbuffer.resize(w, h) - } - attachment.width = w - attachment.height = h - } - } - - var framebufferCount = 0 - var framebufferSet = {} - - function REGLFramebuffer () { - this.id = framebufferCount++ - framebufferSet[this.id] = this - - this.framebuffer = gl.createFramebuffer() - this.width = 0 - this.height = 0 - - this.colorAttachments = [] - this.depthAttachment = null - this.stencilAttachment = null - this.depthStencilAttachment = null - } - - function decFBORefs (framebuffer) { - framebuffer.colorAttachments.forEach(decRef) - decRef(framebuffer.depthAttachment) - decRef(framebuffer.stencilAttachment) - decRef(framebuffer.depthStencilAttachment) - } - - function destroy (framebuffer) { - var handle = framebuffer.framebuffer - check$1(handle, 'must not double destroy framebuffer') - gl.deleteFramebuffer(handle) - framebuffer.framebuffer = null - stats.framebufferCount-- - delete framebufferSet[framebuffer.id] - } - - function updateFramebuffer (framebuffer) { - var i - - gl.bindFramebuffer(GL_FRAMEBUFFER$1, framebuffer.framebuffer) - var colorAttachments = framebuffer.colorAttachments - for (i = 0; i < colorAttachments.length; ++i) { - attach(GL_COLOR_ATTACHMENT0$1 + i, colorAttachments[i]) - } - for (i = colorAttachments.length; i < limits.maxColorAttachments; ++i) { - gl.framebufferTexture2D( - GL_FRAMEBUFFER$1, - GL_COLOR_ATTACHMENT0$1 + i, - GL_TEXTURE_2D$2, - null, - 0) - } - - gl.framebufferTexture2D( - GL_FRAMEBUFFER$1, - GL_DEPTH_STENCIL_ATTACHMENT, - GL_TEXTURE_2D$2, - null, - 0) - gl.framebufferTexture2D( - GL_FRAMEBUFFER$1, - GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D$2, - null, - 0) - gl.framebufferTexture2D( - GL_FRAMEBUFFER$1, - GL_STENCIL_ATTACHMENT, - GL_TEXTURE_2D$2, - null, - 0) - - attach(GL_DEPTH_ATTACHMENT, framebuffer.depthAttachment) - attach(GL_STENCIL_ATTACHMENT, framebuffer.stencilAttachment) - attach(GL_DEPTH_STENCIL_ATTACHMENT, framebuffer.depthStencilAttachment) - - // Check status code - var status = gl.checkFramebufferStatus(GL_FRAMEBUFFER$1) - if (!gl.isContextLost() && status !== GL_FRAMEBUFFER_COMPLETE$1) { - check$1.raise('framebuffer configuration not supported, status = ' + - statusCode[status]) - } - - gl.bindFramebuffer(GL_FRAMEBUFFER$1, framebufferState.next ? framebufferState.next.framebuffer : null) - framebufferState.cur = framebufferState.next - - // FIXME: Clear error code here. This is a work around for a bug in - // headless-gl - gl.getError() - } - - function createFBO (a0, a1) { - var framebuffer = new REGLFramebuffer() - stats.framebufferCount++ - - function reglFramebuffer (a, b) { - var i - - check$1(framebufferState.next !== framebuffer, - 'can not update framebuffer which is currently in use') - - var width = 0 - var height = 0 - - var needsDepth = true - var needsStencil = true - - var colorBuffer = null - var colorTexture = true - var colorFormat = 'rgba' - var colorType = 'uint8' - var colorCount = 1 - - var depthBuffer = null - var stencilBuffer = null - var depthStencilBuffer = null - var depthStencilTexture = false - - if (typeof a === 'number') { - width = a | 0 - height = (b | 0) || width - } else if (!a) { - width = height = 1 - } else { - check$1.type(a, 'object', 'invalid arguments for framebuffer') - var options = a - - if ('shape' in options) { - var shape = options.shape - check$1(Array.isArray(shape) && shape.length >= 2, - 'invalid shape for framebuffer') - width = shape[0] - height = shape[1] - } else { - if ('radius' in options) { - width = height = options.radius - } - if ('width' in options) { - width = options.width - } - if ('height' in options) { - height = options.height - } - } - - if ('color' in options || - 'colors' in options) { - colorBuffer = - options.color || - options.colors - if (Array.isArray(colorBuffer)) { - check$1( - colorBuffer.length === 1 || extensions.webgl_draw_buffers, - 'multiple render targets not supported') - } - } - - if (!colorBuffer) { - if ('colorCount' in options) { - colorCount = options.colorCount | 0 - check$1(colorCount > 0, 'invalid color buffer count') - } - - if ('colorTexture' in options) { - colorTexture = !!options.colorTexture - colorFormat = 'rgba4' - } - - if ('colorType' in options) { - colorType = options.colorType - if (!colorTexture) { - if (colorType === 'half float' || colorType === 'float16') { - check$1(extensions.ext_color_buffer_half_float, - 'you must enable EXT_color_buffer_half_float to use 16-bit render buffers') - colorFormat = 'rgba16f' - } else if (colorType === 'float' || colorType === 'float32') { - check$1(extensions.webgl_color_buffer_float, - 'you must enable WEBGL_color_buffer_float in order to use 32-bit floating point renderbuffers') - colorFormat = 'rgba32f' - } - } else { - check$1(extensions.oes_texture_float || - !(colorType === 'float' || colorType === 'float32'), - 'you must enable OES_texture_float in order to use floating point framebuffer objects') - check$1(extensions.oes_texture_half_float || - !(colorType === 'half float' || colorType === 'float16'), - 'you must enable OES_texture_half_float in order to use 16-bit floating point framebuffer objects') - } - check$1.oneOf(colorType, colorTypes, 'invalid color type') - } - - if ('colorFormat' in options) { - colorFormat = options.colorFormat - if (colorTextureFormats.indexOf(colorFormat) >= 0) { - colorTexture = true - } else if (colorRenderbufferFormats.indexOf(colorFormat) >= 0) { - colorTexture = false - } else { - check$1.optional(function () { - if (colorTexture) { - check$1.oneOf( - options.colorFormat, colorTextureFormats, - 'invalid color format for texture') - } else { - check$1.oneOf( - options.colorFormat, colorRenderbufferFormats, - 'invalid color format for renderbuffer') - } - }) - } - } - } - - if ('depthTexture' in options || 'depthStencilTexture' in options) { - depthStencilTexture = !!(options.depthTexture || - options.depthStencilTexture) - check$1(!depthStencilTexture || extensions.webgl_depth_texture, - 'webgl_depth_texture extension not supported') - } - - if ('depth' in options) { - if (typeof options.depth === 'boolean') { - needsDepth = options.depth - } else { - depthBuffer = options.depth - needsStencil = false - } - } - - if ('stencil' in options) { - if (typeof options.stencil === 'boolean') { - needsStencil = options.stencil - } else { - stencilBuffer = options.stencil - needsDepth = false - } - } - - if ('depthStencil' in options) { - if (typeof options.depthStencil === 'boolean') { - needsDepth = needsStencil = options.depthStencil - } else { - depthStencilBuffer = options.depthStencil - needsDepth = false - needsStencil = false - } - } - } - - // parse attachments - var colorAttachments = null - var depthAttachment = null - var stencilAttachment = null - var depthStencilAttachment = null - - // Set up color attachments - if (Array.isArray(colorBuffer)) { - colorAttachments = colorBuffer.map(parseAttachment) - } else if (colorBuffer) { - colorAttachments = [parseAttachment(colorBuffer)] - } else { - colorAttachments = new Array(colorCount) - for (i = 0; i < colorCount; ++i) { - colorAttachments[i] = allocAttachment( - width, - height, - colorTexture, - colorFormat, - colorType) - } - } - - check$1(extensions.webgl_draw_buffers || colorAttachments.length <= 1, - 'you must enable the WEBGL_draw_buffers extension in order to use multiple color buffers.') - check$1(colorAttachments.length <= limits.maxColorAttachments, - 'too many color attachments, not supported') - - width = width || colorAttachments[0].width - height = height || colorAttachments[0].height - - if (depthBuffer) { - depthAttachment = parseAttachment(depthBuffer) - } else if (needsDepth && !needsStencil) { - depthAttachment = allocAttachment( - width, - height, - depthStencilTexture, - 'depth', - 'uint32') - } - - if (stencilBuffer) { - stencilAttachment = parseAttachment(stencilBuffer) - } else if (needsStencil && !needsDepth) { - stencilAttachment = allocAttachment( - width, - height, - false, - 'stencil', - 'uint8') - } - - if (depthStencilBuffer) { - depthStencilAttachment = parseAttachment(depthStencilBuffer) - } else if (!depthBuffer && !stencilBuffer && needsStencil && needsDepth) { - depthStencilAttachment = allocAttachment( - width, - height, - depthStencilTexture, - 'depth stencil', - 'depth stencil') - } - - check$1( - (!!depthBuffer) + (!!stencilBuffer) + (!!depthStencilBuffer) <= 1, - 'invalid framebuffer configuration, can specify exactly one depth/stencil attachment') - - var commonColorAttachmentSize = null - - for (i = 0; i < colorAttachments.length; ++i) { - incRefAndCheckShape(colorAttachments[i], width, height) - check$1(!colorAttachments[i] || - (colorAttachments[i].texture && - colorTextureFormatEnums.indexOf(colorAttachments[i].texture._texture.format) >= 0) || - (colorAttachments[i].renderbuffer && - colorRenderbufferFormatEnums.indexOf(colorAttachments[i].renderbuffer._renderbuffer.format) >= 0), - 'framebuffer color attachment ' + i + ' is invalid') - - if (colorAttachments[i] && colorAttachments[i].texture) { - var colorAttachmentSize = - textureFormatChannels[colorAttachments[i].texture._texture.format] * - textureTypeSizes[colorAttachments[i].texture._texture.type] - - if (commonColorAttachmentSize === null) { - commonColorAttachmentSize = colorAttachmentSize - } else { - // We need to make sure that all color attachments have the same number of bitplanes - // (that is, the same numer of bits per pixel) - // This is required by the GLES2.0 standard. See the beginning of Chapter 4 in that document. - check$1(commonColorAttachmentSize === colorAttachmentSize, - 'all color attachments much have the same number of bits per pixel.') - } - } - } - incRefAndCheckShape(depthAttachment, width, height) - check$1(!depthAttachment || - (depthAttachment.texture && - depthAttachment.texture._texture.format === GL_DEPTH_COMPONENT$1) || - (depthAttachment.renderbuffer && - depthAttachment.renderbuffer._renderbuffer.format === GL_DEPTH_COMPONENT16$1), - 'invalid depth attachment for framebuffer object') - incRefAndCheckShape(stencilAttachment, width, height) - check$1(!stencilAttachment || - (stencilAttachment.renderbuffer && - stencilAttachment.renderbuffer._renderbuffer.format === GL_STENCIL_INDEX8$1), - 'invalid stencil attachment for framebuffer object') - incRefAndCheckShape(depthStencilAttachment, width, height) - check$1(!depthStencilAttachment || - (depthStencilAttachment.texture && - depthStencilAttachment.texture._texture.format === GL_DEPTH_STENCIL$2) || - (depthStencilAttachment.renderbuffer && - depthStencilAttachment.renderbuffer._renderbuffer.format === GL_DEPTH_STENCIL$2), - 'invalid depth-stencil attachment for framebuffer object') - - // decrement references - decFBORefs(framebuffer) - - framebuffer.width = width - framebuffer.height = height - - framebuffer.colorAttachments = colorAttachments - framebuffer.depthAttachment = depthAttachment - framebuffer.stencilAttachment = stencilAttachment - framebuffer.depthStencilAttachment = depthStencilAttachment - - reglFramebuffer.color = colorAttachments.map(unwrapAttachment) - reglFramebuffer.depth = unwrapAttachment(depthAttachment) - reglFramebuffer.stencil = unwrapAttachment(stencilAttachment) - reglFramebuffer.depthStencil = unwrapAttachment(depthStencilAttachment) - - reglFramebuffer.width = framebuffer.width - reglFramebuffer.height = framebuffer.height - - updateFramebuffer(framebuffer) - - return reglFramebuffer - } - - function resize (w_, h_) { - check$1(framebufferState.next !== framebuffer, - 'can not resize a framebuffer which is currently in use') - - var w = Math.max(w_ | 0, 1) - var h = Math.max((h_ | 0) || w, 1) - if (w === framebuffer.width && h === framebuffer.height) { - return reglFramebuffer - } - - // resize all buffers - var colorAttachments = framebuffer.colorAttachments - for (var i = 0; i < colorAttachments.length; ++i) { - resizeAttachment(colorAttachments[i], w, h) - } - resizeAttachment(framebuffer.depthAttachment, w, h) - resizeAttachment(framebuffer.stencilAttachment, w, h) - resizeAttachment(framebuffer.depthStencilAttachment, w, h) - - framebuffer.width = reglFramebuffer.width = w - framebuffer.height = reglFramebuffer.height = h - - updateFramebuffer(framebuffer) - - return reglFramebuffer - } - - reglFramebuffer(a0, a1) - - return extend(reglFramebuffer, { - resize: resize, - _reglType: 'framebuffer', - _framebuffer: framebuffer, - destroy: function () { - destroy(framebuffer) - decFBORefs(framebuffer) - }, - use: function (block) { - framebufferState.setFBO({ - framebuffer: reglFramebuffer - }, block) - } - }) - } - - function createCubeFBO (options) { - var faces = Array(6) - - function reglFramebufferCube (a) { - var i - - check$1(faces.indexOf(framebufferState.next) < 0, - 'can not update framebuffer which is currently in use') - - var params = { - color: null - } - - var radius = 0 - - var colorBuffer = null - var colorFormat = 'rgba' - var colorType = 'uint8' - var colorCount = 1 - - if (typeof a === 'number') { - radius = a | 0 - } else if (!a) { - radius = 1 - } else { - check$1.type(a, 'object', 'invalid arguments for framebuffer') - var options = a - - if ('shape' in options) { - var shape = options.shape - check$1( - Array.isArray(shape) && shape.length >= 2, - 'invalid shape for framebuffer') - check$1( - shape[0] === shape[1], - 'cube framebuffer must be square') - radius = shape[0] - } else { - if ('radius' in options) { - radius = options.radius | 0 - } - if ('width' in options) { - radius = options.width | 0 - if ('height' in options) { - check$1(options.height === radius, 'must be square') - } - } else if ('height' in options) { - radius = options.height | 0 - } - } - - if ('color' in options || - 'colors' in options) { - colorBuffer = - options.color || - options.colors - if (Array.isArray(colorBuffer)) { - check$1( - colorBuffer.length === 1 || extensions.webgl_draw_buffers, - 'multiple render targets not supported') - } - } - - if (!colorBuffer) { - if ('colorCount' in options) { - colorCount = options.colorCount | 0 - check$1(colorCount > 0, 'invalid color buffer count') - } - - if ('colorType' in options) { - check$1.oneOf( - options.colorType, colorTypes, - 'invalid color type') - colorType = options.colorType - } - - if ('colorFormat' in options) { - colorFormat = options.colorFormat - check$1.oneOf( - options.colorFormat, colorTextureFormats, - 'invalid color format for texture') - } - } - - if ('depth' in options) { - params.depth = options.depth - } - - if ('stencil' in options) { - params.stencil = options.stencil - } - - if ('depthStencil' in options) { - params.depthStencil = options.depthStencil - } - } - - var colorCubes - if (colorBuffer) { - if (Array.isArray(colorBuffer)) { - colorCubes = [] - for (i = 0; i < colorBuffer.length; ++i) { - colorCubes[i] = colorBuffer[i] - } - } else { - colorCubes = [ colorBuffer ] - } - } else { - colorCubes = Array(colorCount) - var cubeMapParams = { - radius: radius, - format: colorFormat, - type: colorType - } - for (i = 0; i < colorCount; ++i) { - colorCubes[i] = textureState.createCube(cubeMapParams) - } - } - - // Check color cubes - params.color = Array(colorCubes.length) - for (i = 0; i < colorCubes.length; ++i) { - var cube = colorCubes[i] - check$1( - typeof cube === 'function' && cube._reglType === 'textureCube', - 'invalid cube map') - radius = radius || cube.width - check$1( - cube.width === radius && cube.height === radius, - 'invalid cube map shape') - params.color[i] = { - target: GL_TEXTURE_CUBE_MAP_POSITIVE_X$2, - data: colorCubes[i] - } - } - - for (i = 0; i < 6; ++i) { - for (var j = 0; j < colorCubes.length; ++j) { - params.color[j].target = GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 + i - } - // reuse depth-stencil attachments across all cube maps - if (i > 0) { - params.depth = faces[0].depth - params.stencil = faces[0].stencil - params.depthStencil = faces[0].depthStencil - } - if (faces[i]) { - (faces[i])(params) - } else { - faces[i] = createFBO(params) - } - } - - return extend(reglFramebufferCube, { - width: radius, - height: radius, - color: colorCubes - }) - } - - function resize (radius_) { - var i - var radius = radius_ | 0 - check$1(radius > 0 && radius <= limits.maxCubeMapSize, - 'invalid radius for cube fbo') - - if (radius === reglFramebufferCube.width) { - return reglFramebufferCube - } - - var colors = reglFramebufferCube.color - for (i = 0; i < colors.length; ++i) { - colors[i].resize(radius) - } - - for (i = 0; i < 6; ++i) { - faces[i].resize(radius) - } - - reglFramebufferCube.width = reglFramebufferCube.height = radius - - return reglFramebufferCube - } - - reglFramebufferCube(options) - - return extend(reglFramebufferCube, { - faces: faces, - resize: resize, - _reglType: 'framebufferCube', - destroy: function () { - faces.forEach(function (f) { - f.destroy() - }) - } - }) - } - - function restoreFramebuffers () { - framebufferState.cur = null - framebufferState.next = null - framebufferState.dirty = true - values(framebufferSet).forEach(function (fb) { - fb.framebuffer = gl.createFramebuffer() - updateFramebuffer(fb) - }) - } - - return extend(framebufferState, { - getFramebuffer: function (object) { - if (typeof object === 'function' && object._reglType === 'framebuffer') { - var fbo = object._framebuffer - if (fbo instanceof REGLFramebuffer) { - return fbo - } - } - return null - }, - create: createFBO, - createCube: createCubeFBO, - clear: function () { - values(framebufferSet).forEach(destroy) - }, - restore: restoreFramebuffers - }) -} - -var GL_FLOAT$6 = 5126 -var GL_ARRAY_BUFFER$1 = 34962 -var GL_ELEMENT_ARRAY_BUFFER$1 = 34963 - -var VAO_OPTIONS = [ - 'attributes', - 'elements', - 'offset', - 'count', - 'primitive', - 'instances' -] - -function AttributeRecord () { - this.state = 0 - - this.x = 0.0 - this.y = 0.0 - this.z = 0.0 - this.w = 0.0 - - this.buffer = null - this.size = 0 - this.normalized = false - this.type = GL_FLOAT$6 - this.offset = 0 - this.stride = 0 - this.divisor = 0 -} - -function wrapAttributeState ( - gl, - extensions, - limits, - stats, - bufferState, - elementState, - drawState) { - var NUM_ATTRIBUTES = limits.maxAttributes - var attributeBindings = new Array(NUM_ATTRIBUTES) - for (var i = 0; i < NUM_ATTRIBUTES; ++i) { - attributeBindings[i] = new AttributeRecord() - } - var vaoCount = 0 - var vaoSet = {} - - var state = { - Record: AttributeRecord, - scope: {}, - state: attributeBindings, - currentVAO: null, - targetVAO: null, - restore: extVAO() ? restoreVAO : function () {}, - createVAO: createVAO, - getVAO: getVAO, - destroyBuffer: destroyBuffer, - setVAO: extVAO() ? setVAOEXT : setVAOEmulated, - clear: extVAO() ? destroyVAOEXT : function () {} - } - - function destroyBuffer (buffer) { - for (var i = 0; i < attributeBindings.length; ++i) { - var record = attributeBindings[i] - if (record.buffer === buffer) { - gl.disableVertexAttribArray(i) - record.buffer = null - } - } - } - - function extVAO () { - return extensions.oes_vertex_array_object - } - - function extInstanced () { - return extensions.angle_instanced_arrays - } - - function getVAO (vao) { - if (typeof vao === 'function' && vao._vao) { - return vao._vao - } - return null - } - - function setVAOEXT (vao) { - if (vao === state.currentVAO) { - return - } - var ext = extVAO() - if (vao) { - ext.bindVertexArrayOES(vao.vao) - } else { - ext.bindVertexArrayOES(null) - } - state.currentVAO = vao - } - - function setVAOEmulated (vao) { - if (vao === state.currentVAO) { - return - } - if (vao) { - vao.bindAttrs() - } else { - var exti = extInstanced() - for (var i = 0; i < attributeBindings.length; ++i) { - var binding = attributeBindings[i] - if (binding.buffer) { - gl.enableVertexAttribArray(i) - binding.buffer.bind() - gl.vertexAttribPointer(i, binding.size, binding.type, binding.normalized, binding.stride, binding.offfset) - if (exti && binding.divisor) { - exti.vertexAttribDivisorANGLE(i, binding.divisor) - } - } else { - gl.disableVertexAttribArray(i) - gl.vertexAttrib4f(i, binding.x, binding.y, binding.z, binding.w) - } - } - if (drawState.elements) { - gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER$1, drawState.elements.buffer.buffer) - } else { - gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER$1, null) - } - } - state.currentVAO = vao - } - - function destroyVAOEXT () { - values(vaoSet).forEach(function (vao) { - vao.destroy() - }) - } - - function REGLVAO () { - this.id = ++vaoCount - this.attributes = [] - this.elements = null - this.ownsElements = false - this.count = 0 - this.offset = 0 - this.instances = -1 - this.primitive = 4 - var extension = extVAO() - if (extension) { - this.vao = extension.createVertexArrayOES() - } else { - this.vao = null - } - vaoSet[this.id] = this - this.buffers = [] - } - - REGLVAO.prototype.bindAttrs = function () { - var exti = extInstanced() - var attributes = this.attributes - for (var i = 0; i < attributes.length; ++i) { - var attr = attributes[i] - if (attr.buffer) { - gl.enableVertexAttribArray(i) - gl.bindBuffer(GL_ARRAY_BUFFER$1, attr.buffer.buffer) - gl.vertexAttribPointer(i, attr.size, attr.type, attr.normalized, attr.stride, attr.offset) - if (exti && attr.divisor) { - exti.vertexAttribDivisorANGLE(i, attr.divisor) - } - } else { - gl.disableVertexAttribArray(i) - gl.vertexAttrib4f(i, attr.x, attr.y, attr.z, attr.w) - } - } - for (var j = attributes.length; j < NUM_ATTRIBUTES; ++j) { - gl.disableVertexAttribArray(j) - } - var elements = elementState.getElements(this.elements) - if (elements) { - gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER$1, elements.buffer.buffer) - } else { - gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER$1, null) - } - } - - REGLVAO.prototype.refresh = function () { - var ext = extVAO() - if (ext) { - ext.bindVertexArrayOES(this.vao) - this.bindAttrs() - state.currentVAO = null - ext.bindVertexArrayOES(null) - } - } - - REGLVAO.prototype.destroy = function () { - if (this.vao) { - var extension = extVAO() - if (this === state.currentVAO) { - state.currentVAO = null - extension.bindVertexArrayOES(null) - } - extension.deleteVertexArrayOES(this.vao) - this.vao = null - } - if (this.ownsElements) { - this.elements.destroy() - this.elements = null - this.ownsElements = false - } - if (vaoSet[this.id]) { - delete vaoSet[this.id] - stats.vaoCount -= 1 - } - } - - function restoreVAO () { - var ext = extVAO() - if (ext) { - values(vaoSet).forEach(function (vao) { - vao.refresh() - }) - } - } - - function createVAO (_attr) { - var vao = new REGLVAO() - stats.vaoCount += 1 - - function updateVAO (options) { - var attributes - if (Array.isArray(options)) { - attributes = options - if (vao.elements && vao.ownsElements) { - vao.elements.destroy() - } - vao.elements = null - vao.ownsElements = false - vao.offset = 0 - vao.count = 0 - vao.instances = -1 - vao.primitive = 4 - } else { - check$1(typeof options === 'object', 'invalid arguments for create vao') - check$1('attributes' in options, 'must specify attributes for vao') - if (options.elements) { - var elements = options.elements - if (vao.ownsElements) { - if (typeof elements === 'function' && elements._reglType === 'elements') { - vao.elements.destroy() - vao.ownsElements = false - } else { - vao.elements(elements) - vao.ownsElements = false - } - } else if (elementState.getElements(options.elements)) { - vao.elements = options.elements - vao.ownsElements = false - } else { - vao.elements = elementState.create(options.elements) - vao.ownsElements = true - } - } else { - vao.elements = null - vao.ownsElements = false - } - attributes = options.attributes - - // set default vao - vao.offset = 0 - vao.count = -1 - vao.instances = -1 - vao.primitive = 4 - - // copy element properties - if (vao.elements) { - vao.count = vao.elements._elements.vertCount - vao.primitive = vao.elements._elements.primType - } - - if ('offset' in options) { - vao.offset = options.offset | 0 - } - if ('count' in options) { - vao.count = options.count | 0 - } - if ('instances' in options) { - vao.instances = options.instances | 0 - } - if ('primitive' in options) { - check$1(options.primitive in primTypes, 'bad primitive type: ' + options.primitive) - vao.primitive = primTypes[options.primitive] - } - - check$1.optional(() => { - var keys = Object.keys(options) - for (var i = 0; i < keys.length; ++i) { - check$1(VAO_OPTIONS.indexOf(keys[i]) >= 0, 'invalid option for vao: "' + keys[i] + '" valid options are ' + VAO_OPTIONS) - } - }) - check$1(Array.isArray(attributes), 'attributes must be an array') - } - - check$1(attributes.length < NUM_ATTRIBUTES, 'too many attributes') - check$1(attributes.length > 0, 'must specify at least one attribute') - - var bufUpdated = {} - var nattributes = vao.attributes - nattributes.length = attributes.length - for (var i = 0; i < attributes.length; ++i) { - var spec = attributes[i] - var rec = nattributes[i] = new AttributeRecord() - var data = spec.data || spec - if (Array.isArray(data) || isTypedArray(data) || isNDArrayLike(data)) { - var buf - if (vao.buffers[i]) { - buf = vao.buffers[i] - if (isTypedArray(data) && buf._buffer.byteLength >= data.byteLength) { - buf.subdata(data) - } else { - buf.destroy() - vao.buffers[i] = null - } - } - if (!vao.buffers[i]) { - buf = vao.buffers[i] = bufferState.create(spec, GL_ARRAY_BUFFER$1, false, true) - } - rec.buffer = bufferState.getBuffer(buf) - rec.size = rec.buffer.dimension | 0 - rec.normalized = false - rec.type = rec.buffer.dtype - rec.offset = 0 - rec.stride = 0 - rec.divisor = 0 - rec.state = 1 - bufUpdated[i] = 1 - } else if (bufferState.getBuffer(spec)) { - rec.buffer = bufferState.getBuffer(spec) - rec.size = rec.buffer.dimension | 0 - rec.normalized = false - rec.type = rec.buffer.dtype - rec.offset = 0 - rec.stride = 0 - rec.divisor = 0 - rec.state = 1 - } else if (bufferState.getBuffer(spec.buffer)) { - rec.buffer = bufferState.getBuffer(spec.buffer) - rec.size = ((+spec.size) || rec.buffer.dimension) | 0 - rec.normalized = !!spec.normalized || false - if ('type' in spec) { - check$1.parameter(spec.type, glTypes, 'invalid buffer type') - rec.type = glTypes[spec.type] - } else { - rec.type = rec.buffer.dtype - } - rec.offset = (spec.offset || 0) | 0 - rec.stride = (spec.stride || 0) | 0 - rec.divisor = (spec.divisor || 0) | 0 - rec.state = 1 - - check$1(rec.size >= 1 && rec.size <= 4, 'size must be between 1 and 4') - check$1(rec.offset >= 0, 'invalid offset') - check$1(rec.stride >= 0 && rec.stride <= 255, 'stride must be between 0 and 255') - check$1(rec.divisor >= 0, 'divisor must be positive') - check$1(!rec.divisor || !!extensions.angle_instanced_arrays, 'ANGLE_instanced_arrays must be enabled to use divisor') - } else if ('x' in spec) { - check$1(i > 0, 'first attribute must not be a constant') - rec.x = +spec.x || 0 - rec.y = +spec.y || 0 - rec.z = +spec.z || 0 - rec.w = +spec.w || 0 - rec.state = 2 - } else { - check$1(false, 'invalid attribute spec for location ' + i) - } - } - - // retire unused buffers - for (var j = 0; j < vao.buffers.length; ++j) { - if (!bufUpdated[j] && vao.buffers[j]) { - vao.buffers[j].destroy() - vao.buffers[j] = null - } - } - - vao.refresh() - return updateVAO - } - - updateVAO.destroy = function () { - for (var j = 0; j < vao.buffers.length; ++j) { - if (vao.buffers[j]) { - vao.buffers[j].destroy() - } - } - vao.buffers.length = 0 - - if (vao.ownsElements) { - vao.elements.destroy() - vao.elements = null - vao.ownsElements = false - } - - vao.destroy() - } - - updateVAO._vao = vao - updateVAO._reglType = 'vao' - - return updateVAO(_attr) - } - - return state -} - -var GL_FRAGMENT_SHADER = 35632 -var GL_VERTEX_SHADER = 35633 - -var GL_ACTIVE_UNIFORMS = 0x8B86 -var GL_ACTIVE_ATTRIBUTES = 0x8B89 - -function wrapShaderState (gl, stringStore, stats, config) { - // =================================================== - // glsl compilation and linking - // =================================================== - var fragShaders = {} - var vertShaders = {} - - function ActiveInfo (name, id, location, info) { - this.name = name - this.id = id - this.location = location - this.info = info - } - - function insertActiveInfo (list, info) { - for (var i = 0; i < list.length; ++i) { - if (list[i].id === info.id) { - list[i].location = info.location - return - } - } - list.push(info) - } - - function getShader (type, id, command) { - var cache = type === GL_FRAGMENT_SHADER ? fragShaders : vertShaders - var shader = cache[id] - - if (!shader) { - var source = stringStore.str(id) - shader = gl.createShader(type) - gl.shaderSource(shader, source) - gl.compileShader(shader) - check$1.shaderError(gl, shader, source, type, command) - cache[id] = shader - } - - return shader - } - - // =================================================== - // program linking - // =================================================== - var programCache = {} - var programList = [] - - var PROGRAM_COUNTER = 0 - - function REGLProgram (fragId, vertId) { - this.id = PROGRAM_COUNTER++ - this.fragId = fragId - this.vertId = vertId - this.program = null - this.uniforms = [] - this.attributes = [] - this.refCount = 1 - - if (config.profile) { - this.stats = { - uniformsCount: 0, - attributesCount: 0 - } - } - } - - function linkProgram (desc, command, attributeLocations) { - var i, info - - // ------------------------------- - // compile & link - // ------------------------------- - var fragShader = getShader(GL_FRAGMENT_SHADER, desc.fragId) - var vertShader = getShader(GL_VERTEX_SHADER, desc.vertId) - - var program = desc.program = gl.createProgram() - gl.attachShader(program, fragShader) - gl.attachShader(program, vertShader) - if (attributeLocations) { - for (i = 0; i < attributeLocations.length; ++i) { - var binding = attributeLocations[i] - gl.bindAttribLocation(program, binding[0], binding[1]) - } - } - - gl.linkProgram(program) - check$1.linkError( - gl, - program, - stringStore.str(desc.fragId), - stringStore.str(desc.vertId), - command) - - // ------------------------------- - // grab uniforms - // ------------------------------- - var numUniforms = gl.getProgramParameter(program, GL_ACTIVE_UNIFORMS) - if (config.profile) { - desc.stats.uniformsCount = numUniforms - } - var uniforms = desc.uniforms - for (i = 0; i < numUniforms; ++i) { - info = gl.getActiveUniform(program, i) - if (info) { - if (info.size > 1) { - for (var j = 0; j < info.size; ++j) { - var name = info.name.replace('[0]', '[' + j + ']') - insertActiveInfo(uniforms, new ActiveInfo( - name, - stringStore.id(name), - gl.getUniformLocation(program, name), - info)) - } - } - var uniName = info.name - if (info.size > 1) { - uniName = uniName.replace('[0]', '') - } - insertActiveInfo(uniforms, new ActiveInfo( - uniName, - stringStore.id(uniName), - gl.getUniformLocation(program, uniName), - info)) - } - } - - // ------------------------------- - // grab attributes - // ------------------------------- - var numAttributes = gl.getProgramParameter(program, GL_ACTIVE_ATTRIBUTES) - if (config.profile) { - desc.stats.attributesCount = numAttributes - } - - var attributes = desc.attributes - for (i = 0; i < numAttributes; ++i) { - info = gl.getActiveAttrib(program, i) - if (info) { - insertActiveInfo(attributes, new ActiveInfo( - info.name, - stringStore.id(info.name), - gl.getAttribLocation(program, info.name), - info)) - } - } - } - - if (config.profile) { - stats.getMaxUniformsCount = function () { - var m = 0 - programList.forEach(function (desc) { - if (desc.stats.uniformsCount > m) { - m = desc.stats.uniformsCount - } - }) - return m - } - - stats.getMaxAttributesCount = function () { - var m = 0 - programList.forEach(function (desc) { - if (desc.stats.attributesCount > m) { - m = desc.stats.attributesCount - } - }) - return m - } - } - - function restoreShaders () { - fragShaders = {} - vertShaders = {} - for (var i = 0; i < programList.length; ++i) { - linkProgram(programList[i], null, programList[i].attributes.map(function (info) { - return [info.location, info.name] - })) - } - } - - return { - clear: function () { - var deleteShader = gl.deleteShader.bind(gl) - values(fragShaders).forEach(deleteShader) - fragShaders = {} - values(vertShaders).forEach(deleteShader) - vertShaders = {} - - programList.forEach(function (desc) { - gl.deleteProgram(desc.program) - }) - programList.length = 0 - programCache = {} - - stats.shaderCount = 0 - }, - - program: function (vertId, fragId, command, attribLocations) { - check$1.command(vertId >= 0, 'missing vertex shader', command) - check$1.command(fragId >= 0, 'missing fragment shader', command) - - var cache = programCache[fragId] - if (!cache) { - cache = programCache[fragId] = {} - } - var prevProgram = cache[vertId] - if (prevProgram) { - prevProgram.refCount++ - if (!attribLocations) { - return prevProgram - } - } - var program = new REGLProgram(fragId, vertId) - stats.shaderCount++ - linkProgram(program, command, attribLocations) - if (!prevProgram) { - cache[vertId] = program - } - programList.push(program) - return extend(program, { - destroy: function () { - program.refCount-- - if (program.refCount <= 0) { - gl.deleteProgram(program.program) - var idx = programList.indexOf(program) - programList.splice(idx, 1) - stats.shaderCount-- - } - // no program is linked to this vert anymore - if (cache[program.vertId].refCount <= 0) { - gl.deleteShader(vertShaders[program.vertId]) - delete vertShaders[program.vertId] - delete programCache[program.fragId][program.vertId] - } - // no program is linked to this frag anymore - if (!Object.keys(programCache[program.fragId]).length) { - gl.deleteShader(fragShaders[program.fragId]) - delete fragShaders[program.fragId] - delete programCache[program.fragId] - } - } - }) - }, - - restore: restoreShaders, - - shader: getShader, - - frag: -1, - vert: -1 - } -} - -var GL_RGBA$3 = 6408 -var GL_UNSIGNED_BYTE$7 = 5121 -var GL_PACK_ALIGNMENT = 0x0D05 -var GL_FLOAT$7 = 0x1406 // 5126 - -function wrapReadPixels ( - gl, - framebufferState, - reglPoll, - context, - glAttributes, - extensions, - limits) { - function readPixelsImpl (input) { - var type - if (framebufferState.next === null) { - check$1( - glAttributes.preserveDrawingBuffer, - 'you must create a webgl context with "preserveDrawingBuffer":true in order to read pixels from the drawing buffer') - type = GL_UNSIGNED_BYTE$7 - } else { - check$1( - framebufferState.next.colorAttachments[0].texture !== null, - 'You cannot read from a renderbuffer') - type = framebufferState.next.colorAttachments[0].texture._texture.type - - check$1.optional(function () { - if (extensions.oes_texture_float) { - check$1( - type === GL_UNSIGNED_BYTE$7 || type === GL_FLOAT$7, - 'Reading from a framebuffer is only allowed for the types \'uint8\' and \'float\'') - - if (type === GL_FLOAT$7) { - check$1(limits.readFloat, 'Reading \'float\' values is not permitted in your browser. For a fallback, please see: https://www.npmjs.com/package/glsl-read-float') - } - } else { - check$1( - type === GL_UNSIGNED_BYTE$7, - 'Reading from a framebuffer is only allowed for the type \'uint8\'') - } - }) - } - - var x = 0 - var y = 0 - var width = context.framebufferWidth - var height = context.framebufferHeight - var data = null - - if (isTypedArray(input)) { - data = input - } else if (input) { - check$1.type(input, 'object', 'invalid arguments to regl.read()') - x = input.x | 0 - y = input.y | 0 - check$1( - x >= 0 && x < context.framebufferWidth, - 'invalid x offset for regl.read') - check$1( - y >= 0 && y < context.framebufferHeight, - 'invalid y offset for regl.read') - width = (input.width || (context.framebufferWidth - x)) | 0 - height = (input.height || (context.framebufferHeight - y)) | 0 - data = input.data || null - } - - // sanity check input.data - if (data) { - if (type === GL_UNSIGNED_BYTE$7) { - check$1( - data instanceof Uint8Array, - 'buffer must be \'Uint8Array\' when reading from a framebuffer of type \'uint8\'') - } else if (type === GL_FLOAT$7) { - check$1( - data instanceof Float32Array, - 'buffer must be \'Float32Array\' when reading from a framebuffer of type \'float\'') - } - } - - check$1( - width > 0 && width + x <= context.framebufferWidth, - 'invalid width for read pixels') - check$1( - height > 0 && height + y <= context.framebufferHeight, - 'invalid height for read pixels') - - // Update WebGL state - reglPoll() - - // Compute size - var size = width * height * 4 - - // Allocate data - if (!data) { - if (type === GL_UNSIGNED_BYTE$7) { - data = new Uint8Array(size) - } else if (type === GL_FLOAT$7) { - data = data || new Float32Array(size) - } - } - - // Type check - check$1.isTypedArray(data, 'data buffer for regl.read() must be a typedarray') - check$1(data.byteLength >= size, 'data buffer for regl.read() too small') - - // Run read pixels - gl.pixelStorei(GL_PACK_ALIGNMENT, 4) - gl.readPixels(x, y, width, height, GL_RGBA$3, - type, - data) - - return data - } - - function readPixelsFBO (options) { - var result - framebufferState.setFBO({ - framebuffer: options.framebuffer - }, function () { - result = readPixelsImpl(options) - }) - return result - } - - function readPixels (options) { - if (!options || !('framebuffer' in options)) { - return readPixelsImpl(options) - } else { - return readPixelsFBO(options) - } - } - - return readPixels -} - -function slice (x) { - return Array.prototype.slice.call(x) -} - -function join (x) { - return slice(x).join('') -} - -function createEnvironment () { - // Unique variable id counter - var varCounter = 0 - - // Linked values are passed from this scope into the generated code block - // Calling link() passes a value into the generated scope and returns - // the variable name which it is bound to - var linkedNames = [] - var linkedValues = [] - function link (value) { - for (var i = 0; i < linkedValues.length; ++i) { - if (linkedValues[i] === value) { - return linkedNames[i] - } - } - - var name = 'g' + (varCounter++) - linkedNames.push(name) - linkedValues.push(value) - return name - } - - // create a code block - function block () { - var code = [] - function push () { - code.push.apply(code, slice(arguments)) - } - - var vars = [] - function def () { - var name = 'v' + (varCounter++) - vars.push(name) - - if (arguments.length > 0) { - code.push(name, '=') - code.push.apply(code, slice(arguments)) - code.push(';') - } - - return name - } - - return extend(push, { - def: def, - toString: function () { - return join([ - (vars.length > 0 ? 'var ' + vars.join(',') + ';' : ''), - join(code) - ]) - } - }) - } - - function scope () { - var entry = block() - var exit = block() - - var entryToString = entry.toString - var exitToString = exit.toString - - function save (object, prop) { - exit(object, prop, '=', entry.def(object, prop), ';') - } - - return extend(function () { - entry.apply(entry, slice(arguments)) - }, { - def: entry.def, - entry: entry, - exit: exit, - save: save, - set: function (object, prop, value) { - save(object, prop) - entry(object, prop, '=', value, ';') - }, - toString: function () { - return entryToString() + exitToString() - } - }) - } - - function conditional () { - var pred = join(arguments) - var thenBlock = scope() - var elseBlock = scope() - - var thenToString = thenBlock.toString - var elseToString = elseBlock.toString - - return extend(thenBlock, { - then: function () { - thenBlock.apply(thenBlock, slice(arguments)) - return this - }, - else: function () { - elseBlock.apply(elseBlock, slice(arguments)) - return this - }, - toString: function () { - var elseClause = elseToString() - if (elseClause) { - elseClause = 'else{' + elseClause + '}' - } - return join([ - 'if(', pred, '){', - thenToString(), - '}', elseClause - ]) - } - }) - } - - // procedure list - var globalBlock = block() - var procedures = {} - function proc (name, count) { - var args = [] - function arg () { - var name = 'a' + args.length - args.push(name) - return name - } - - count = count || 0 - for (var i = 0; i < count; ++i) { - arg() - } - - var body = scope() - var bodyToString = body.toString - - var result = procedures[name] = extend(body, { - arg: arg, - toString: function () { - return join([ - 'function(', args.join(), '){', - bodyToString(), - '}' - ]) - } - }) - - return result - } - - function compile () { - var code = ['"use strict";', - globalBlock, - 'return {'] - Object.keys(procedures).forEach(function (name) { - code.push('"', name, '":', procedures[name].toString(), ',') - }) - code.push('}') - var src = join(code) - .replace(/;/g, ';\n') - .replace(/}/g, '}\n') - .replace(/{/g, '{\n') - var proc = Function.apply(null, linkedNames.concat(src)) - return proc.apply(null, linkedValues) - } - - return { - global: globalBlock, - link: link, - block: block, - proc: proc, - scope: scope, - cond: conditional, - compile: compile - } -} - -// "cute" names for vector components -var CUTE_COMPONENTS = 'xyzw'.split('') - -var GL_UNSIGNED_BYTE$8 = 5121 - -var ATTRIB_STATE_POINTER = 1 -var ATTRIB_STATE_CONSTANT = 2 - -var DYN_FUNC$1 = 0 -var DYN_PROP$1 = 1 -var DYN_CONTEXT$1 = 2 -var DYN_STATE$1 = 3 -var DYN_THUNK = 4 -var DYN_CONSTANT$1 = 5 -var DYN_ARRAY$1 = 6 - -var S_DITHER = 'dither' -var S_BLEND_ENABLE = 'blend.enable' -var S_BLEND_COLOR = 'blend.color' -var S_BLEND_EQUATION = 'blend.equation' -var S_BLEND_FUNC = 'blend.func' -var S_DEPTH_ENABLE = 'depth.enable' -var S_DEPTH_FUNC = 'depth.func' -var S_DEPTH_RANGE = 'depth.range' -var S_DEPTH_MASK = 'depth.mask' -var S_COLOR_MASK = 'colorMask' -var S_CULL_ENABLE = 'cull.enable' -var S_CULL_FACE = 'cull.face' -var S_FRONT_FACE = 'frontFace' -var S_LINE_WIDTH = 'lineWidth' -var S_POLYGON_OFFSET_ENABLE = 'polygonOffset.enable' -var S_POLYGON_OFFSET_OFFSET = 'polygonOffset.offset' -var S_SAMPLE_ALPHA = 'sample.alpha' -var S_SAMPLE_ENABLE = 'sample.enable' -var S_SAMPLE_COVERAGE = 'sample.coverage' -var S_STENCIL_ENABLE = 'stencil.enable' -var S_STENCIL_MASK = 'stencil.mask' -var S_STENCIL_FUNC = 'stencil.func' -var S_STENCIL_OPFRONT = 'stencil.opFront' -var S_STENCIL_OPBACK = 'stencil.opBack' -var S_SCISSOR_ENABLE = 'scissor.enable' -var S_SCISSOR_BOX = 'scissor.box' -var S_VIEWPORT = 'viewport' - -var S_PROFILE = 'profile' - -var S_FRAMEBUFFER = 'framebuffer' -var S_VERT = 'vert' -var S_FRAG = 'frag' -var S_ELEMENTS = 'elements' -var S_PRIMITIVE = 'primitive' -var S_COUNT = 'count' -var S_OFFSET = 'offset' -var S_INSTANCES = 'instances' -var S_VAO = 'vao' - -var SUFFIX_WIDTH = 'Width' -var SUFFIX_HEIGHT = 'Height' - -var S_FRAMEBUFFER_WIDTH = S_FRAMEBUFFER + SUFFIX_WIDTH -var S_FRAMEBUFFER_HEIGHT = S_FRAMEBUFFER + SUFFIX_HEIGHT -var S_VIEWPORT_WIDTH = S_VIEWPORT + SUFFIX_WIDTH -var S_VIEWPORT_HEIGHT = S_VIEWPORT + SUFFIX_HEIGHT -var S_DRAWINGBUFFER = 'drawingBuffer' -var S_DRAWINGBUFFER_WIDTH = S_DRAWINGBUFFER + SUFFIX_WIDTH -var S_DRAWINGBUFFER_HEIGHT = S_DRAWINGBUFFER + SUFFIX_HEIGHT - -var NESTED_OPTIONS = [ - S_BLEND_FUNC, - S_BLEND_EQUATION, - S_STENCIL_FUNC, - S_STENCIL_OPFRONT, - S_STENCIL_OPBACK, - S_SAMPLE_COVERAGE, - S_VIEWPORT, - S_SCISSOR_BOX, - S_POLYGON_OFFSET_OFFSET -] - -var GL_ARRAY_BUFFER$2 = 34962 -var GL_ELEMENT_ARRAY_BUFFER$2 = 34963 - -var GL_FRAGMENT_SHADER$1 = 35632 -var GL_VERTEX_SHADER$1 = 35633 - -var GL_TEXTURE_2D$3 = 0x0DE1 -var GL_TEXTURE_CUBE_MAP$2 = 0x8513 - -var GL_CULL_FACE = 0x0B44 -var GL_BLEND = 0x0BE2 -var GL_DITHER = 0x0BD0 -var GL_STENCIL_TEST = 0x0B90 -var GL_DEPTH_TEST = 0x0B71 -var GL_SCISSOR_TEST = 0x0C11 -var GL_POLYGON_OFFSET_FILL = 0x8037 -var GL_SAMPLE_ALPHA_TO_COVERAGE = 0x809E -var GL_SAMPLE_COVERAGE = 0x80A0 - -var GL_FLOAT$8 = 5126 -var GL_FLOAT_VEC2 = 35664 -var GL_FLOAT_VEC3 = 35665 -var GL_FLOAT_VEC4 = 35666 -var GL_INT$3 = 5124 -var GL_INT_VEC2 = 35667 -var GL_INT_VEC3 = 35668 -var GL_INT_VEC4 = 35669 -var GL_BOOL = 35670 -var GL_BOOL_VEC2 = 35671 -var GL_BOOL_VEC3 = 35672 -var GL_BOOL_VEC4 = 35673 -var GL_FLOAT_MAT2 = 35674 -var GL_FLOAT_MAT3 = 35675 -var GL_FLOAT_MAT4 = 35676 -var GL_SAMPLER_2D = 35678 -var GL_SAMPLER_CUBE = 35680 - -var GL_TRIANGLES$1 = 4 - -var GL_FRONT = 1028 -var GL_BACK = 1029 -var GL_CW = 0x0900 -var GL_CCW = 0x0901 -var GL_MIN_EXT = 0x8007 -var GL_MAX_EXT = 0x8008 -var GL_ALWAYS = 519 -var GL_KEEP = 7680 -var GL_ZERO = 0 -var GL_ONE = 1 -var GL_FUNC_ADD = 0x8006 -var GL_LESS = 513 - -var GL_FRAMEBUFFER$2 = 0x8D40 -var GL_COLOR_ATTACHMENT0$2 = 0x8CE0 - -var blendFuncs = { - '0': 0, - '1': 1, - 'zero': 0, - 'one': 1, - 'src color': 768, - 'one minus src color': 769, - 'src alpha': 770, - 'one minus src alpha': 771, - 'dst color': 774, - 'one minus dst color': 775, - 'dst alpha': 772, - 'one minus dst alpha': 773, - 'constant color': 32769, - 'one minus constant color': 32770, - 'constant alpha': 32771, - 'one minus constant alpha': 32772, - 'src alpha saturate': 776 -} - -// There are invalid values for srcRGB and dstRGB. See: -// https://www.khronos.org/registry/webgl/specs/1.0/#6.13 -// https://github.com/KhronosGroup/WebGL/blob/0d3201f5f7ec3c0060bc1f04077461541f1987b9/conformance-suites/1.0.3/conformance/misc/webgl-specific.html#L56 -var invalidBlendCombinations = [ - 'constant color, constant alpha', - 'one minus constant color, constant alpha', - 'constant color, one minus constant alpha', - 'one minus constant color, one minus constant alpha', - 'constant alpha, constant color', - 'constant alpha, one minus constant color', - 'one minus constant alpha, constant color', - 'one minus constant alpha, one minus constant color' -] - -var compareFuncs = { - 'never': 512, - 'less': 513, - '<': 513, - 'equal': 514, - '=': 514, - '==': 514, - '===': 514, - 'lequal': 515, - '<=': 515, - 'greater': 516, - '>': 516, - 'notequal': 517, - '!=': 517, - '!==': 517, - 'gequal': 518, - '>=': 518, - 'always': 519 -} - -var stencilOps = { - '0': 0, - 'zero': 0, - 'keep': 7680, - 'replace': 7681, - 'increment': 7682, - 'decrement': 7683, - 'increment wrap': 34055, - 'decrement wrap': 34056, - 'invert': 5386 -} - -var shaderType = { - 'frag': GL_FRAGMENT_SHADER$1, - 'vert': GL_VERTEX_SHADER$1 -} - -var orientationType = { - 'cw': GL_CW, - 'ccw': GL_CCW -} - -function isBufferArgs (x) { - return Array.isArray(x) || - isTypedArray(x) || - isNDArrayLike(x) -} - -// Make sure viewport is processed first -function sortState (state) { - return state.sort(function (a, b) { - if (a === S_VIEWPORT) { - return -1 - } else if (b === S_VIEWPORT) { - return 1 - } - return (a < b) ? -1 : 1 - }) -} - -function Declaration (thisDep, contextDep, propDep, append) { - this.thisDep = thisDep - this.contextDep = contextDep - this.propDep = propDep - this.append = append -} - -function isStatic (decl) { - return decl && !(decl.thisDep || decl.contextDep || decl.propDep) -} - -function createStaticDecl (append) { - return new Declaration(false, false, false, append) -} - -function createDynamicDecl (dyn, append) { - var type = dyn.type - if (type === DYN_FUNC$1) { - var numArgs = dyn.data.length - return new Declaration( - true, - numArgs >= 1, - numArgs >= 2, - append) - } else if (type === DYN_THUNK) { - var data = dyn.data - return new Declaration( - data.thisDep, - data.contextDep, - data.propDep, - append) - } else if (type === DYN_CONSTANT$1) { - return new Declaration( - false, - false, - false, - append) - } else if (type === DYN_ARRAY$1) { - var thisDep = false - var contextDep = false - var propDep = false - for (var i = 0; i < dyn.data.length; ++i) { - var subDyn = dyn.data[i] - if (subDyn.type === DYN_PROP$1) { - propDep = true - } else if (subDyn.type === DYN_CONTEXT$1) { - contextDep = true - } else if (subDyn.type === DYN_STATE$1) { - thisDep = true - } else if (subDyn.type === DYN_FUNC$1) { - thisDep = true - var subArgs = subDyn.data - if (subArgs >= 1) { - contextDep = true - } - if (subArgs >= 2) { - propDep = true - } - } else if (subDyn.type === DYN_THUNK) { - thisDep = thisDep || subDyn.data.thisDep - contextDep = contextDep || subDyn.data.contextDep - propDep = propDep || subDyn.data.propDep - } - } - return new Declaration( - thisDep, - contextDep, - propDep, - append) - } else { - return new Declaration( - type === DYN_STATE$1, - type === DYN_CONTEXT$1, - type === DYN_PROP$1, - append) - } -} - -var SCOPE_DECL = new Declaration(false, false, false, function () {}) - -function reglCore ( - gl, - stringStore, - extensions, - limits, - bufferState, - elementState, - textureState, - framebufferState, - uniformState, - attributeState, - shaderState, - drawState, - contextState, - timer, - config) { - var AttributeRecord = attributeState.Record - - var blendEquations = { - 'add': 32774, - 'subtract': 32778, - 'reverse subtract': 32779 - } - if (extensions.ext_blend_minmax) { - blendEquations.min = GL_MIN_EXT - blendEquations.max = GL_MAX_EXT - } - - var extInstancing = extensions.angle_instanced_arrays - var extDrawBuffers = extensions.webgl_draw_buffers - var extVertexArrays = extensions.oes_vertex_array_object - - // =================================================== - // =================================================== - // WEBGL STATE - // =================================================== - // =================================================== - var currentState = { - dirty: true, - profile: config.profile - } - var nextState = {} - var GL_STATE_NAMES = [] - var GL_FLAGS = {} - var GL_VARIABLES = {} - - function propName (name) { - return name.replace('.', '_') - } - - function stateFlag (sname, cap, init) { - var name = propName(sname) - GL_STATE_NAMES.push(sname) - nextState[name] = currentState[name] = !!init - GL_FLAGS[name] = cap - } - - function stateVariable (sname, func, init) { - var name = propName(sname) - GL_STATE_NAMES.push(sname) - if (Array.isArray(init)) { - currentState[name] = init.slice() - nextState[name] = init.slice() - } else { - currentState[name] = nextState[name] = init - } - GL_VARIABLES[name] = func - } - - // Dithering - stateFlag(S_DITHER, GL_DITHER) - - // Blending - stateFlag(S_BLEND_ENABLE, GL_BLEND) - stateVariable(S_BLEND_COLOR, 'blendColor', [0, 0, 0, 0]) - stateVariable(S_BLEND_EQUATION, 'blendEquationSeparate', - [GL_FUNC_ADD, GL_FUNC_ADD]) - stateVariable(S_BLEND_FUNC, 'blendFuncSeparate', - [GL_ONE, GL_ZERO, GL_ONE, GL_ZERO]) - - // Depth - stateFlag(S_DEPTH_ENABLE, GL_DEPTH_TEST, true) - stateVariable(S_DEPTH_FUNC, 'depthFunc', GL_LESS) - stateVariable(S_DEPTH_RANGE, 'depthRange', [0, 1]) - stateVariable(S_DEPTH_MASK, 'depthMask', true) - - // Color mask - stateVariable(S_COLOR_MASK, S_COLOR_MASK, [true, true, true, true]) - - // Face culling - stateFlag(S_CULL_ENABLE, GL_CULL_FACE) - stateVariable(S_CULL_FACE, 'cullFace', GL_BACK) - - // Front face orientation - stateVariable(S_FRONT_FACE, S_FRONT_FACE, GL_CCW) - - // Line width - stateVariable(S_LINE_WIDTH, S_LINE_WIDTH, 1) - - // Polygon offset - stateFlag(S_POLYGON_OFFSET_ENABLE, GL_POLYGON_OFFSET_FILL) - stateVariable(S_POLYGON_OFFSET_OFFSET, 'polygonOffset', [0, 0]) - - // Sample coverage - stateFlag(S_SAMPLE_ALPHA, GL_SAMPLE_ALPHA_TO_COVERAGE) - stateFlag(S_SAMPLE_ENABLE, GL_SAMPLE_COVERAGE) - stateVariable(S_SAMPLE_COVERAGE, 'sampleCoverage', [1, false]) - - // Stencil - stateFlag(S_STENCIL_ENABLE, GL_STENCIL_TEST) - stateVariable(S_STENCIL_MASK, 'stencilMask', -1) - stateVariable(S_STENCIL_FUNC, 'stencilFunc', [GL_ALWAYS, 0, -1]) - stateVariable(S_STENCIL_OPFRONT, 'stencilOpSeparate', - [GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP]) - stateVariable(S_STENCIL_OPBACK, 'stencilOpSeparate', - [GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP]) - - // Scissor - stateFlag(S_SCISSOR_ENABLE, GL_SCISSOR_TEST) - stateVariable(S_SCISSOR_BOX, 'scissor', - [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight]) - - // Viewport - stateVariable(S_VIEWPORT, S_VIEWPORT, - [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight]) - - // =================================================== - // =================================================== - // ENVIRONMENT - // =================================================== - // =================================================== - var sharedState = { - gl: gl, - context: contextState, - strings: stringStore, - next: nextState, - current: currentState, - draw: drawState, - elements: elementState, - buffer: bufferState, - shader: shaderState, - attributes: attributeState.state, - vao: attributeState, - uniforms: uniformState, - framebuffer: framebufferState, - extensions: extensions, - - timer: timer, - isBufferArgs: isBufferArgs - } - - var sharedConstants = { - primTypes: primTypes, - compareFuncs: compareFuncs, - blendFuncs: blendFuncs, - blendEquations: blendEquations, - stencilOps: stencilOps, - glTypes: glTypes, - orientationType: orientationType - } - - check$1.optional(function () { - sharedState.isArrayLike = isArrayLike - }) - - if (extDrawBuffers) { - sharedConstants.backBuffer = [GL_BACK] - sharedConstants.drawBuffer = loop(limits.maxDrawbuffers, function (i) { - if (i === 0) { - return [0] - } - return loop(i, function (j) { - return GL_COLOR_ATTACHMENT0$2 + j - }) - }) - } - - var drawCallCounter = 0 - function createREGLEnvironment () { - var env = createEnvironment() - var link = env.link - var global = env.global - env.id = drawCallCounter++ - - env.batchId = '0' - - // link shared state - var SHARED = link(sharedState) - var shared = env.shared = { - props: 'a0' - } - Object.keys(sharedState).forEach(function (prop) { - shared[prop] = global.def(SHARED, '.', prop) - }) - - // Inject runtime assertion stuff for debug builds - check$1.optional(function () { - env.CHECK = link(check$1) - env.commandStr = check$1.guessCommand() - env.command = link(env.commandStr) - env.assert = function (block, pred, message) { - block( - 'if(!(', pred, '))', - this.CHECK, '.commandRaise(', link(message), ',', this.command, ');') - } - - sharedConstants.invalidBlendCombinations = invalidBlendCombinations - }) - - // Copy GL state variables over - var nextVars = env.next = {} - var currentVars = env.current = {} - Object.keys(GL_VARIABLES).forEach(function (variable) { - if (Array.isArray(currentState[variable])) { - nextVars[variable] = global.def(shared.next, '.', variable) - currentVars[variable] = global.def(shared.current, '.', variable) - } - }) - - // Initialize shared constants - var constants = env.constants = {} - Object.keys(sharedConstants).forEach(function (name) { - constants[name] = global.def(JSON.stringify(sharedConstants[name])) - }) - - // Helper function for calling a block - env.invoke = function (block, x) { - switch (x.type) { - case DYN_FUNC$1: - var argList = [ - 'this', - shared.context, - shared.props, - env.batchId - ] - return block.def( - link(x.data), '.call(', - argList.slice(0, Math.max(x.data.length + 1, 4)), - ')') - case DYN_PROP$1: - return block.def(shared.props, x.data) - case DYN_CONTEXT$1: - return block.def(shared.context, x.data) - case DYN_STATE$1: - return block.def('this', x.data) - case DYN_THUNK: - x.data.append(env, block) - return x.data.ref - case DYN_CONSTANT$1: - return x.data.toString() - case DYN_ARRAY$1: - return x.data.map(function (y) { - return env.invoke(block, y) - }) - } - } - - env.attribCache = {} - - var scopeAttribs = {} - env.scopeAttrib = function (name) { - var id = stringStore.id(name) - if (id in scopeAttribs) { - return scopeAttribs[id] - } - var binding = attributeState.scope[id] - if (!binding) { - binding = attributeState.scope[id] = new AttributeRecord() - } - var result = scopeAttribs[id] = link(binding) - return result - } - - return env - } - - // =================================================== - // =================================================== - // PARSING - // =================================================== - // =================================================== - function parseProfile (options) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - var profileEnable - if (S_PROFILE in staticOptions) { - var value = !!staticOptions[S_PROFILE] - profileEnable = createStaticDecl(function (env, scope) { - return value - }) - profileEnable.enable = value - } else if (S_PROFILE in dynamicOptions) { - var dyn = dynamicOptions[S_PROFILE] - profileEnable = createDynamicDecl(dyn, function (env, scope) { - return env.invoke(scope, dyn) - }) - } - - return profileEnable - } - - function parseFramebuffer (options, env) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - if (S_FRAMEBUFFER in staticOptions) { - var framebuffer = staticOptions[S_FRAMEBUFFER] - if (framebuffer) { - framebuffer = framebufferState.getFramebuffer(framebuffer) - check$1.command(framebuffer, 'invalid framebuffer object') - return createStaticDecl(function (env, block) { - var FRAMEBUFFER = env.link(framebuffer) - var shared = env.shared - block.set( - shared.framebuffer, - '.next', - FRAMEBUFFER) - var CONTEXT = shared.context - block.set( - CONTEXT, - '.' + S_FRAMEBUFFER_WIDTH, - FRAMEBUFFER + '.width') - block.set( - CONTEXT, - '.' + S_FRAMEBUFFER_HEIGHT, - FRAMEBUFFER + '.height') - return FRAMEBUFFER - }) - } else { - return createStaticDecl(function (env, scope) { - var shared = env.shared - scope.set( - shared.framebuffer, - '.next', - 'null') - var CONTEXT = shared.context - scope.set( - CONTEXT, - '.' + S_FRAMEBUFFER_WIDTH, - CONTEXT + '.' + S_DRAWINGBUFFER_WIDTH) - scope.set( - CONTEXT, - '.' + S_FRAMEBUFFER_HEIGHT, - CONTEXT + '.' + S_DRAWINGBUFFER_HEIGHT) - return 'null' - }) - } - } else if (S_FRAMEBUFFER in dynamicOptions) { - var dyn = dynamicOptions[S_FRAMEBUFFER] - return createDynamicDecl(dyn, function (env, scope) { - var FRAMEBUFFER_FUNC = env.invoke(scope, dyn) - var shared = env.shared - var FRAMEBUFFER_STATE = shared.framebuffer - var FRAMEBUFFER = scope.def( - FRAMEBUFFER_STATE, '.getFramebuffer(', FRAMEBUFFER_FUNC, ')') - - check$1.optional(function () { - env.assert(scope, - '!' + FRAMEBUFFER_FUNC + '||' + FRAMEBUFFER, - 'invalid framebuffer object') - }) - - scope.set( - FRAMEBUFFER_STATE, - '.next', - FRAMEBUFFER) - var CONTEXT = shared.context - scope.set( - CONTEXT, - '.' + S_FRAMEBUFFER_WIDTH, - FRAMEBUFFER + '?' + FRAMEBUFFER + '.width:' + - CONTEXT + '.' + S_DRAWINGBUFFER_WIDTH) - scope.set( - CONTEXT, - '.' + S_FRAMEBUFFER_HEIGHT, - FRAMEBUFFER + - '?' + FRAMEBUFFER + '.height:' + - CONTEXT + '.' + S_DRAWINGBUFFER_HEIGHT) - return FRAMEBUFFER - }) - } else { - return null - } - } - - function parseViewportScissor (options, framebuffer, env) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - function parseBox (param) { - if (param in staticOptions) { - var box = staticOptions[param] - check$1.commandType(box, 'object', 'invalid ' + param, env.commandStr) - - var isStatic = true - var x = box.x | 0 - var y = box.y | 0 - var w, h - if ('width' in box) { - w = box.width | 0 - check$1.command(w >= 0, 'invalid ' + param, env.commandStr) - } else { - isStatic = false - } - if ('height' in box) { - h = box.height | 0 - check$1.command(h >= 0, 'invalid ' + param, env.commandStr) - } else { - isStatic = false - } - - return new Declaration( - !isStatic && framebuffer && framebuffer.thisDep, - !isStatic && framebuffer && framebuffer.contextDep, - !isStatic && framebuffer && framebuffer.propDep, - function (env, scope) { - var CONTEXT = env.shared.context - var BOX_W = w - if (!('width' in box)) { - BOX_W = scope.def(CONTEXT, '.', S_FRAMEBUFFER_WIDTH, '-', x) - } - var BOX_H = h - if (!('height' in box)) { - BOX_H = scope.def(CONTEXT, '.', S_FRAMEBUFFER_HEIGHT, '-', y) - } - return [x, y, BOX_W, BOX_H] - }) - } else if (param in dynamicOptions) { - var dynBox = dynamicOptions[param] - var result = createDynamicDecl(dynBox, function (env, scope) { - var BOX = env.invoke(scope, dynBox) - - check$1.optional(function () { - env.assert(scope, - BOX + '&&typeof ' + BOX + '==="object"', - 'invalid ' + param) - }) - - var CONTEXT = env.shared.context - var BOX_X = scope.def(BOX, '.x|0') - var BOX_Y = scope.def(BOX, '.y|0') - var BOX_W = scope.def( - '"width" in ', BOX, '?', BOX, '.width|0:', - '(', CONTEXT, '.', S_FRAMEBUFFER_WIDTH, '-', BOX_X, ')') - var BOX_H = scope.def( - '"height" in ', BOX, '?', BOX, '.height|0:', - '(', CONTEXT, '.', S_FRAMEBUFFER_HEIGHT, '-', BOX_Y, ')') - - check$1.optional(function () { - env.assert(scope, - BOX_W + '>=0&&' + - BOX_H + '>=0', - 'invalid ' + param) - }) - - return [BOX_X, BOX_Y, BOX_W, BOX_H] - }) - if (framebuffer) { - result.thisDep = result.thisDep || framebuffer.thisDep - result.contextDep = result.contextDep || framebuffer.contextDep - result.propDep = result.propDep || framebuffer.propDep - } - return result - } else if (framebuffer) { - return new Declaration( - framebuffer.thisDep, - framebuffer.contextDep, - framebuffer.propDep, - function (env, scope) { - var CONTEXT = env.shared.context - return [ - 0, 0, - scope.def(CONTEXT, '.', S_FRAMEBUFFER_WIDTH), - scope.def(CONTEXT, '.', S_FRAMEBUFFER_HEIGHT)] - }) - } else { - return null - } - } - - var viewport = parseBox(S_VIEWPORT) - - if (viewport) { - var prevViewport = viewport - viewport = new Declaration( - viewport.thisDep, - viewport.contextDep, - viewport.propDep, - function (env, scope) { - var VIEWPORT = prevViewport.append(env, scope) - var CONTEXT = env.shared.context - scope.set( - CONTEXT, - '.' + S_VIEWPORT_WIDTH, - VIEWPORT[2]) - scope.set( - CONTEXT, - '.' + S_VIEWPORT_HEIGHT, - VIEWPORT[3]) - return VIEWPORT - }) - } - - return { - viewport: viewport, - scissor_box: parseBox(S_SCISSOR_BOX) - } - } - - function parseAttribLocations (options, attributes) { - var staticOptions = options.static - var staticProgram = - typeof staticOptions[S_FRAG] === 'string' && - typeof staticOptions[S_VERT] === 'string' - if (staticProgram) { - if (Object.keys(attributes.dynamic).length > 0) { - return null - } - var staticAttributes = attributes.static - var sAttributes = Object.keys(staticAttributes) - if (sAttributes.length > 0 && typeof staticAttributes[sAttributes[0]] === 'number') { - var bindings = [] - for (var i = 0; i < sAttributes.length; ++i) { - check$1(typeof staticAttributes[sAttributes[i]] === 'number', 'must specify all vertex attribute locations when using vaos') - bindings.push([staticAttributes[sAttributes[i]] | 0, sAttributes[i]]) - } - return bindings - } - } - return null - } - - function parseProgram (options, env, attribLocations) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - function parseShader (name) { - if (name in staticOptions) { - var id = stringStore.id(staticOptions[name]) - check$1.optional(function () { - shaderState.shader(shaderType[name], id, check$1.guessCommand()) - }) - var result = createStaticDecl(function () { - return id - }) - result.id = id - return result - } else if (name in dynamicOptions) { - var dyn = dynamicOptions[name] - return createDynamicDecl(dyn, function (env, scope) { - var str = env.invoke(scope, dyn) - var id = scope.def(env.shared.strings, '.id(', str, ')') - check$1.optional(function () { - scope( - env.shared.shader, '.shader(', - shaderType[name], ',', - id, ',', - env.command, ');') - }) - return id - }) - } - return null - } - - var frag = parseShader(S_FRAG) - var vert = parseShader(S_VERT) - - var program = null - var progVar - if (isStatic(frag) && isStatic(vert)) { - program = shaderState.program(vert.id, frag.id, null, attribLocations) - progVar = createStaticDecl(function (env, scope) { - return env.link(program) - }) - } else { - progVar = new Declaration( - (frag && frag.thisDep) || (vert && vert.thisDep), - (frag && frag.contextDep) || (vert && vert.contextDep), - (frag && frag.propDep) || (vert && vert.propDep), - function (env, scope) { - var SHADER_STATE = env.shared.shader - var fragId - if (frag) { - fragId = frag.append(env, scope) - } else { - fragId = scope.def(SHADER_STATE, '.', S_FRAG) - } - var vertId - if (vert) { - vertId = vert.append(env, scope) - } else { - vertId = scope.def(SHADER_STATE, '.', S_VERT) - } - var progDef = SHADER_STATE + '.program(' + vertId + ',' + fragId - check$1.optional(function () { - progDef += ',' + env.command - }) - return scope.def(progDef + ')') - }) - } - - return { - frag: frag, - vert: vert, - progVar: progVar, - program: program - } - } - - function parseDraw (options, env) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - // TODO: should use VAO to get default values for offset properties - // should move vao parse into here and out of the old stuff - - var staticDraw = {} - var vaoActive = false - - function parseVAO () { - if (S_VAO in staticOptions) { - var vao = staticOptions[S_VAO] - if (vao !== null && attributeState.getVAO(vao) === null) { - vao = attributeState.createVAO(vao) - } - - vaoActive = true - staticDraw.vao = vao - - return createStaticDecl(function (env) { - var vaoRef = attributeState.getVAO(vao) - if (vaoRef) { - return env.link(vaoRef) - } else { - return 'null' - } - }) - } else if (S_VAO in dynamicOptions) { - vaoActive = true - var dyn = dynamicOptions[S_VAO] - return createDynamicDecl(dyn, function (env, scope) { - var vaoRef = env.invoke(scope, dyn) - return scope.def(env.shared.vao + '.getVAO(' + vaoRef + ')') - }) - } - return null - } - - var vao = parseVAO() - - var elementsActive = false - - function parseElements () { - if (S_ELEMENTS in staticOptions) { - var elements = staticOptions[S_ELEMENTS] - staticDraw.elements = elements - if (isBufferArgs(elements)) { - var e = staticDraw.elements = elementState.create(elements, true) - elements = elementState.getElements(e) - elementsActive = true - } else if (elements) { - elements = elementState.getElements(elements) - elementsActive = true - check$1.command(elements, 'invalid elements', env.commandStr) - } - - var result = createStaticDecl(function (env, scope) { - if (elements) { - var result = env.link(elements) - env.ELEMENTS = result - return result - } - env.ELEMENTS = null - return null - }) - result.value = elements - return result - } else if (S_ELEMENTS in dynamicOptions) { - elementsActive = true - - var dyn = dynamicOptions[S_ELEMENTS] - return createDynamicDecl(dyn, function (env, scope) { - var shared = env.shared - - var IS_BUFFER_ARGS = shared.isBufferArgs - var ELEMENT_STATE = shared.elements - - var elementDefn = env.invoke(scope, dyn) - var elements = scope.def('null') - var elementStream = scope.def(IS_BUFFER_ARGS, '(', elementDefn, ')') - - var ifte = env.cond(elementStream) - .then(elements, '=', ELEMENT_STATE, '.createStream(', elementDefn, ');') - .else(elements, '=', ELEMENT_STATE, '.getElements(', elementDefn, ');') - - check$1.optional(function () { - env.assert(ifte.else, - '!' + elementDefn + '||' + elements, - 'invalid elements') - }) - - scope.entry(ifte) - scope.exit( - env.cond(elementStream) - .then(ELEMENT_STATE, '.destroyStream(', elements, ');')) - - env.ELEMENTS = elements - - return elements - }) - } else if (vaoActive) { - return new Declaration( - vao.thisDep, - vao.contextDep, - vao.propDep, - function (env, scope) { - return scope.def(env.shared.vao + '.currentVAO?' + env.shared.elements + '.getElements(' + env.shared.vao + '.currentVAO.elements):null') - }) - } - return null - } - - var elements = parseElements() - - function parsePrimitive () { - if (S_PRIMITIVE in staticOptions) { - var primitive = staticOptions[S_PRIMITIVE] - staticDraw.primitive = primitive - check$1.commandParameter(primitive, primTypes, 'invalid primitve', env.commandStr) - return createStaticDecl(function (env, scope) { - return primTypes[primitive] - }) - } else if (S_PRIMITIVE in dynamicOptions) { - var dynPrimitive = dynamicOptions[S_PRIMITIVE] - return createDynamicDecl(dynPrimitive, function (env, scope) { - var PRIM_TYPES = env.constants.primTypes - var prim = env.invoke(scope, dynPrimitive) - check$1.optional(function () { - env.assert(scope, - prim + ' in ' + PRIM_TYPES, - 'invalid primitive, must be one of ' + Object.keys(primTypes)) - }) - return scope.def(PRIM_TYPES, '[', prim, ']') - }) - } else if (elementsActive) { - if (isStatic(elements)) { - if (elements.value) { - return createStaticDecl(function (env, scope) { - return scope.def(env.ELEMENTS, '.primType') - }) - } else { - return createStaticDecl(function () { - return GL_TRIANGLES$1 - }) - } - } else { - return new Declaration( - elements.thisDep, - elements.contextDep, - elements.propDep, - function (env, scope) { - var elements = env.ELEMENTS - return scope.def(elements, '?', elements, '.primType:', GL_TRIANGLES$1) - }) - } - } else if (vaoActive) { - return new Declaration( - vao.thisDep, - vao.contextDep, - vao.propDep, - function (env, scope) { - return scope.def(env.shared.vao + '.currentVAO?' + env.shared.vao + '.currentVAO.primitive:' + GL_TRIANGLES$1) - }) - } - return null - } - - function parseParam (param, isOffset) { - if (param in staticOptions) { - var value = staticOptions[param] | 0 - if (isOffset) { - staticDraw.offset = value - } else { - staticDraw.instances = value - } - check$1.command(!isOffset || value >= 0, 'invalid ' + param, env.commandStr) - return createStaticDecl(function (env, scope) { - if (isOffset) { - env.OFFSET = value - } - return value - }) - } else if (param in dynamicOptions) { - var dynValue = dynamicOptions[param] - return createDynamicDecl(dynValue, function (env, scope) { - var result = env.invoke(scope, dynValue) - if (isOffset) { - env.OFFSET = result - check$1.optional(function () { - env.assert(scope, - result + '>=0', - 'invalid ' + param) - }) - } - return result - }) - } else if (isOffset) { - if (elementsActive) { - return createStaticDecl(function (env, scope) { - env.OFFSET = 0 - return 0 - }) - } else if (vaoActive) { - return new Declaration( - vao.thisDep, - vao.contextDep, - vao.propDep, - function (env, scope) { - return scope.def(env.shared.vao + '.currentVAO?' + env.shared.vao + '.currentVAO.offset:0') - }) - } - } else if (vaoActive) { - return new Declaration( - vao.thisDep, - vao.contextDep, - vao.propDep, - function (env, scope) { - return scope.def(env.shared.vao + '.currentVAO?' + env.shared.vao + '.currentVAO.instances:-1') - }) - } - return null - } - - var OFFSET = parseParam(S_OFFSET, true) - - function parseVertCount () { - if (S_COUNT in staticOptions) { - var count = staticOptions[S_COUNT] | 0 - staticDraw.count = count - check$1.command( - typeof count === 'number' && count >= 0, 'invalid vertex count', env.commandStr) - return createStaticDecl(function () { - return count - }) - } else if (S_COUNT in dynamicOptions) { - var dynCount = dynamicOptions[S_COUNT] - return createDynamicDecl(dynCount, function (env, scope) { - var result = env.invoke(scope, dynCount) - check$1.optional(function () { - env.assert(scope, - 'typeof ' + result + '==="number"&&' + - result + '>=0&&' + - result + '===(' + result + '|0)', - 'invalid vertex count') - }) - return result - }) - } else if (elementsActive) { - if (isStatic(elements)) { - if (elements) { - if (OFFSET) { - return new Declaration( - OFFSET.thisDep, - OFFSET.contextDep, - OFFSET.propDep, - function (env, scope) { - var result = scope.def( - env.ELEMENTS, '.vertCount-', env.OFFSET) - - check$1.optional(function () { - env.assert(scope, - result + '>=0', - 'invalid vertex offset/element buffer too small') - }) - - return result - }) - } else { - return createStaticDecl(function (env, scope) { - return scope.def(env.ELEMENTS, '.vertCount') - }) - } - } else { - var result = createStaticDecl(function () { - return -1 - }) - check$1.optional(function () { - result.MISSING = true - }) - return result - } - } else { - var variable = new Declaration( - elements.thisDep || OFFSET.thisDep, - elements.contextDep || OFFSET.contextDep, - elements.propDep || OFFSET.propDep, - function (env, scope) { - var elements = env.ELEMENTS - if (env.OFFSET) { - return scope.def(elements, '?', elements, '.vertCount-', - env.OFFSET, ':-1') - } - return scope.def(elements, '?', elements, '.vertCount:-1') - }) - check$1.optional(function () { - variable.DYNAMIC = true - }) - return variable - } - } else if (vaoActive) { - var countVariable = new Declaration( - vao.thisDep, - vao.contextDep, - vao.propDep, - function (env, scope) { - return scope.def(env.shared.vao, '.currentVAO?', env.shared.vao, '.currentVAO.count:-1') - }) - return countVariable - } - return null - } - - var primitive = parsePrimitive() - var count = parseVertCount() - var instances = parseParam(S_INSTANCES, false) - - return { - elements: elements, - primitive: primitive, - count: count, - instances: instances, - offset: OFFSET, - vao: vao, - - vaoActive: vaoActive, - elementsActive: elementsActive, - - // static draw props - static: staticDraw - } - } - - function parseGLState (options, env) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - var STATE = {} - - GL_STATE_NAMES.forEach(function (prop) { - var param = propName(prop) - - function parseParam (parseStatic, parseDynamic) { - if (prop in staticOptions) { - var value = parseStatic(staticOptions[prop]) - STATE[param] = createStaticDecl(function () { - return value - }) - } else if (prop in dynamicOptions) { - var dyn = dynamicOptions[prop] - STATE[param] = createDynamicDecl(dyn, function (env, scope) { - return parseDynamic(env, scope, env.invoke(scope, dyn)) - }) - } - } - - switch (prop) { - case S_CULL_ENABLE: - case S_BLEND_ENABLE: - case S_DITHER: - case S_STENCIL_ENABLE: - case S_DEPTH_ENABLE: - case S_SCISSOR_ENABLE: - case S_POLYGON_OFFSET_ENABLE: - case S_SAMPLE_ALPHA: - case S_SAMPLE_ENABLE: - case S_DEPTH_MASK: - return parseParam( - function (value) { - check$1.commandType(value, 'boolean', prop, env.commandStr) - return value - }, - function (env, scope, value) { - check$1.optional(function () { - env.assert(scope, - 'typeof ' + value + '==="boolean"', - 'invalid flag ' + prop, env.commandStr) - }) - return value - }) - - case S_DEPTH_FUNC: - return parseParam( - function (value) { - check$1.commandParameter(value, compareFuncs, 'invalid ' + prop, env.commandStr) - return compareFuncs[value] - }, - function (env, scope, value) { - var COMPARE_FUNCS = env.constants.compareFuncs - check$1.optional(function () { - env.assert(scope, - value + ' in ' + COMPARE_FUNCS, - 'invalid ' + prop + ', must be one of ' + Object.keys(compareFuncs)) - }) - return scope.def(COMPARE_FUNCS, '[', value, ']') - }) - - case S_DEPTH_RANGE: - return parseParam( - function (value) { - check$1.command( - isArrayLike(value) && - value.length === 2 && - typeof value[0] === 'number' && - typeof value[1] === 'number' && - value[0] <= value[1], - 'depth range is 2d array', - env.commandStr) - return value - }, - function (env, scope, value) { - check$1.optional(function () { - env.assert(scope, - env.shared.isArrayLike + '(' + value + ')&&' + - value + '.length===2&&' + - 'typeof ' + value + '[0]==="number"&&' + - 'typeof ' + value + '[1]==="number"&&' + - value + '[0]<=' + value + '[1]', - 'depth range must be a 2d array') - }) - - var Z_NEAR = scope.def('+', value, '[0]') - var Z_FAR = scope.def('+', value, '[1]') - return [Z_NEAR, Z_FAR] - }) - - case S_BLEND_FUNC: - return parseParam( - function (value) { - check$1.commandType(value, 'object', 'blend.func', env.commandStr) - var srcRGB = ('srcRGB' in value ? value.srcRGB : value.src) - var srcAlpha = ('srcAlpha' in value ? value.srcAlpha : value.src) - var dstRGB = ('dstRGB' in value ? value.dstRGB : value.dst) - var dstAlpha = ('dstAlpha' in value ? value.dstAlpha : value.dst) - check$1.commandParameter(srcRGB, blendFuncs, param + '.srcRGB', env.commandStr) - check$1.commandParameter(srcAlpha, blendFuncs, param + '.srcAlpha', env.commandStr) - check$1.commandParameter(dstRGB, blendFuncs, param + '.dstRGB', env.commandStr) - check$1.commandParameter(dstAlpha, blendFuncs, param + '.dstAlpha', env.commandStr) - - check$1.command( - (invalidBlendCombinations.indexOf(srcRGB + ', ' + dstRGB) === -1), - 'unallowed blending combination (srcRGB, dstRGB) = (' + srcRGB + ', ' + dstRGB + ')', env.commandStr) - - return [ - blendFuncs[srcRGB], - blendFuncs[dstRGB], - blendFuncs[srcAlpha], - blendFuncs[dstAlpha] - ] - }, - function (env, scope, value) { - var BLEND_FUNCS = env.constants.blendFuncs - - check$1.optional(function () { - env.assert(scope, - value + '&&typeof ' + value + '==="object"', - 'invalid blend func, must be an object') - }) - - function read (prefix, suffix) { - var func = scope.def( - '"', prefix, suffix, '" in ', value, - '?', value, '.', prefix, suffix, - ':', value, '.', prefix) - - check$1.optional(function () { - env.assert(scope, - func + ' in ' + BLEND_FUNCS, - 'invalid ' + prop + '.' + prefix + suffix + ', must be one of ' + Object.keys(blendFuncs)) - }) - - return func - } - - var srcRGB = read('src', 'RGB') - var dstRGB = read('dst', 'RGB') - - check$1.optional(function () { - var INVALID_BLEND_COMBINATIONS = env.constants.invalidBlendCombinations - - env.assert(scope, - INVALID_BLEND_COMBINATIONS + - '.indexOf(' + srcRGB + '+", "+' + dstRGB + ') === -1 ', - 'unallowed blending combination for (srcRGB, dstRGB)' - ) - }) - - var SRC_RGB = scope.def(BLEND_FUNCS, '[', srcRGB, ']') - var SRC_ALPHA = scope.def(BLEND_FUNCS, '[', read('src', 'Alpha'), ']') - var DST_RGB = scope.def(BLEND_FUNCS, '[', dstRGB, ']') - var DST_ALPHA = scope.def(BLEND_FUNCS, '[', read('dst', 'Alpha'), ']') - - return [SRC_RGB, DST_RGB, SRC_ALPHA, DST_ALPHA] - }) - - case S_BLEND_EQUATION: - return parseParam( - function (value) { - if (typeof value === 'string') { - check$1.commandParameter(value, blendEquations, 'invalid ' + prop, env.commandStr) - return [ - blendEquations[value], - blendEquations[value] - ] - } else if (typeof value === 'object') { - check$1.commandParameter( - value.rgb, blendEquations, prop + '.rgb', env.commandStr) - check$1.commandParameter( - value.alpha, blendEquations, prop + '.alpha', env.commandStr) - return [ - blendEquations[value.rgb], - blendEquations[value.alpha] - ] - } else { - check$1.commandRaise('invalid blend.equation', env.commandStr) - } - }, - function (env, scope, value) { - var BLEND_EQUATIONS = env.constants.blendEquations - - var RGB = scope.def() - var ALPHA = scope.def() - - var ifte = env.cond('typeof ', value, '==="string"') - - check$1.optional(function () { - function checkProp (block, name, value) { - env.assert(block, - value + ' in ' + BLEND_EQUATIONS, - 'invalid ' + name + ', must be one of ' + Object.keys(blendEquations)) - } - checkProp(ifte.then, prop, value) - - env.assert(ifte.else, - value + '&&typeof ' + value + '==="object"', - 'invalid ' + prop) - checkProp(ifte.else, prop + '.rgb', value + '.rgb') - checkProp(ifte.else, prop + '.alpha', value + '.alpha') - }) - - ifte.then( - RGB, '=', ALPHA, '=', BLEND_EQUATIONS, '[', value, '];') - ifte.else( - RGB, '=', BLEND_EQUATIONS, '[', value, '.rgb];', - ALPHA, '=', BLEND_EQUATIONS, '[', value, '.alpha];') - - scope(ifte) - - return [RGB, ALPHA] - }) - - case S_BLEND_COLOR: - return parseParam( - function (value) { - check$1.command( - isArrayLike(value) && - value.length === 4, - 'blend.color must be a 4d array', env.commandStr) - return loop(4, function (i) { - return +value[i] - }) - }, - function (env, scope, value) { - check$1.optional(function () { - env.assert(scope, - env.shared.isArrayLike + '(' + value + ')&&' + - value + '.length===4', - 'blend.color must be a 4d array') - }) - return loop(4, function (i) { - return scope.def('+', value, '[', i, ']') - }) - }) - - case S_STENCIL_MASK: - return parseParam( - function (value) { - check$1.commandType(value, 'number', param, env.commandStr) - return value | 0 - }, - function (env, scope, value) { - check$1.optional(function () { - env.assert(scope, - 'typeof ' + value + '==="number"', - 'invalid stencil.mask') - }) - return scope.def(value, '|0') - }) - - case S_STENCIL_FUNC: - return parseParam( - function (value) { - check$1.commandType(value, 'object', param, env.commandStr) - var cmp = value.cmp || 'keep' - var ref = value.ref || 0 - var mask = 'mask' in value ? value.mask : -1 - check$1.commandParameter(cmp, compareFuncs, prop + '.cmp', env.commandStr) - check$1.commandType(ref, 'number', prop + '.ref', env.commandStr) - check$1.commandType(mask, 'number', prop + '.mask', env.commandStr) - return [ - compareFuncs[cmp], - ref, - mask - ] - }, - function (env, scope, value) { - var COMPARE_FUNCS = env.constants.compareFuncs - check$1.optional(function () { - function assert () { - env.assert(scope, - Array.prototype.join.call(arguments, ''), - 'invalid stencil.func') - } - assert(value + '&&typeof ', value, '==="object"') - assert('!("cmp" in ', value, ')||(', - value, '.cmp in ', COMPARE_FUNCS, ')') - }) - var cmp = scope.def( - '"cmp" in ', value, - '?', COMPARE_FUNCS, '[', value, '.cmp]', - ':', GL_KEEP) - var ref = scope.def(value, '.ref|0') - var mask = scope.def( - '"mask" in ', value, - '?', value, '.mask|0:-1') - return [cmp, ref, mask] - }) - - case S_STENCIL_OPFRONT: - case S_STENCIL_OPBACK: - return parseParam( - function (value) { - check$1.commandType(value, 'object', param, env.commandStr) - var fail = value.fail || 'keep' - var zfail = value.zfail || 'keep' - var zpass = value.zpass || 'keep' - check$1.commandParameter(fail, stencilOps, prop + '.fail', env.commandStr) - check$1.commandParameter(zfail, stencilOps, prop + '.zfail', env.commandStr) - check$1.commandParameter(zpass, stencilOps, prop + '.zpass', env.commandStr) - return [ - prop === S_STENCIL_OPBACK ? GL_BACK : GL_FRONT, - stencilOps[fail], - stencilOps[zfail], - stencilOps[zpass] - ] - }, - function (env, scope, value) { - var STENCIL_OPS = env.constants.stencilOps - - check$1.optional(function () { - env.assert(scope, - value + '&&typeof ' + value + '==="object"', - 'invalid ' + prop) - }) - - function read (name) { - check$1.optional(function () { - env.assert(scope, - '!("' + name + '" in ' + value + ')||' + - '(' + value + '.' + name + ' in ' + STENCIL_OPS + ')', - 'invalid ' + prop + '.' + name + ', must be one of ' + Object.keys(stencilOps)) - }) - - return scope.def( - '"', name, '" in ', value, - '?', STENCIL_OPS, '[', value, '.', name, ']:', - GL_KEEP) - } - - return [ - prop === S_STENCIL_OPBACK ? GL_BACK : GL_FRONT, - read('fail'), - read('zfail'), - read('zpass') - ] - }) - - case S_POLYGON_OFFSET_OFFSET: - return parseParam( - function (value) { - check$1.commandType(value, 'object', param, env.commandStr) - var factor = value.factor | 0 - var units = value.units | 0 - check$1.commandType(factor, 'number', param + '.factor', env.commandStr) - check$1.commandType(units, 'number', param + '.units', env.commandStr) - return [factor, units] - }, - function (env, scope, value) { - check$1.optional(function () { - env.assert(scope, - value + '&&typeof ' + value + '==="object"', - 'invalid ' + prop) - }) - - var FACTOR = scope.def(value, '.factor|0') - var UNITS = scope.def(value, '.units|0') - - return [FACTOR, UNITS] - }) - - case S_CULL_FACE: - return parseParam( - function (value) { - var face = 0 - if (value === 'front') { - face = GL_FRONT - } else if (value === 'back') { - face = GL_BACK - } - check$1.command(!!face, param, env.commandStr) - return face - }, - function (env, scope, value) { - check$1.optional(function () { - env.assert(scope, - value + '==="front"||' + - value + '==="back"', - 'invalid cull.face') - }) - return scope.def(value, '==="front"?', GL_FRONT, ':', GL_BACK) - }) - - case S_LINE_WIDTH: - return parseParam( - function (value) { - check$1.command( - typeof value === 'number' && - value >= limits.lineWidthDims[0] && - value <= limits.lineWidthDims[1], - 'invalid line width, must be a positive number between ' + - limits.lineWidthDims[0] + ' and ' + limits.lineWidthDims[1], env.commandStr) - return value - }, - function (env, scope, value) { - check$1.optional(function () { - env.assert(scope, - 'typeof ' + value + '==="number"&&' + - value + '>=' + limits.lineWidthDims[0] + '&&' + - value + '<=' + limits.lineWidthDims[1], - 'invalid line width') - }) - - return value - }) - - case S_FRONT_FACE: - return parseParam( - function (value) { - check$1.commandParameter(value, orientationType, param, env.commandStr) - return orientationType[value] - }, - function (env, scope, value) { - check$1.optional(function () { - env.assert(scope, - value + '==="cw"||' + - value + '==="ccw"', - 'invalid frontFace, must be one of cw,ccw') - }) - return scope.def(value + '==="cw"?' + GL_CW + ':' + GL_CCW) - }) - - case S_COLOR_MASK: - return parseParam( - function (value) { - check$1.command( - isArrayLike(value) && value.length === 4, - 'color.mask must be length 4 array', env.commandStr) - return value.map(function (v) { return !!v }) - }, - function (env, scope, value) { - check$1.optional(function () { - env.assert(scope, - env.shared.isArrayLike + '(' + value + ')&&' + - value + '.length===4', - 'invalid color.mask') - }) - return loop(4, function (i) { - return '!!' + value + '[' + i + ']' - }) - }) - - case S_SAMPLE_COVERAGE: - return parseParam( - function (value) { - check$1.command(typeof value === 'object' && value, param, env.commandStr) - var sampleValue = 'value' in value ? value.value : 1 - var sampleInvert = !!value.invert - check$1.command( - typeof sampleValue === 'number' && - sampleValue >= 0 && sampleValue <= 1, - 'sample.coverage.value must be a number between 0 and 1', env.commandStr) - return [sampleValue, sampleInvert] - }, - function (env, scope, value) { - check$1.optional(function () { - env.assert(scope, - value + '&&typeof ' + value + '==="object"', - 'invalid sample.coverage') - }) - var VALUE = scope.def( - '"value" in ', value, '?+', value, '.value:1') - var INVERT = scope.def('!!', value, '.invert') - return [VALUE, INVERT] - }) - } - }) - - return STATE - } - - function parseUniforms (uniforms, env) { - var staticUniforms = uniforms.static - var dynamicUniforms = uniforms.dynamic - - var UNIFORMS = {} - - Object.keys(staticUniforms).forEach(function (name) { - var value = staticUniforms[name] - var result - if (typeof value === 'number' || - typeof value === 'boolean') { - result = createStaticDecl(function () { - return value - }) - } else if (typeof value === 'function') { - var reglType = value._reglType - if (reglType === 'texture2d' || - reglType === 'textureCube') { - result = createStaticDecl(function (env) { - return env.link(value) - }) - } else if (reglType === 'framebuffer' || - reglType === 'framebufferCube') { - check$1.command(value.color.length > 0, - 'missing color attachment for framebuffer sent to uniform "' + name + '"', env.commandStr) - result = createStaticDecl(function (env) { - return env.link(value.color[0]) - }) - } else { - check$1.commandRaise('invalid data for uniform "' + name + '"', env.commandStr) - } - } else if (isArrayLike(value)) { - result = createStaticDecl(function (env) { - var ITEM = env.global.def('[', - loop(value.length, function (i) { - check$1.command( - typeof value[i] === 'number' || - typeof value[i] === 'boolean', - 'invalid uniform ' + name, env.commandStr) - return value[i] - }), ']') - return ITEM - }) - } else { - check$1.commandRaise('invalid or missing data for uniform "' + name + '"', env.commandStr) - } - result.value = value - UNIFORMS[name] = result - }) - - Object.keys(dynamicUniforms).forEach(function (key) { - var dyn = dynamicUniforms[key] - UNIFORMS[key] = createDynamicDecl(dyn, function (env, scope) { - return env.invoke(scope, dyn) - }) - }) - - return UNIFORMS - } - - function parseAttributes (attributes, env) { - var staticAttributes = attributes.static - var dynamicAttributes = attributes.dynamic - - var attributeDefs = {} - - Object.keys(staticAttributes).forEach(function (attribute) { - var value = staticAttributes[attribute] - var id = stringStore.id(attribute) - - var record = new AttributeRecord() - if (isBufferArgs(value)) { - record.state = ATTRIB_STATE_POINTER - record.buffer = bufferState.getBuffer( - bufferState.create(value, GL_ARRAY_BUFFER$2, false, true)) - record.type = 0 - } else { - var buffer = bufferState.getBuffer(value) - if (buffer) { - record.state = ATTRIB_STATE_POINTER - record.buffer = buffer - record.type = 0 - } else { - check$1.command(typeof value === 'object' && value, - 'invalid data for attribute ' + attribute, env.commandStr) - if ('constant' in value) { - var constant = value.constant - record.buffer = 'null' - record.state = ATTRIB_STATE_CONSTANT - if (typeof constant === 'number') { - record.x = constant - } else { - check$1.command( - isArrayLike(constant) && - constant.length > 0 && - constant.length <= 4, - 'invalid constant for attribute ' + attribute, env.commandStr) - CUTE_COMPONENTS.forEach(function (c, i) { - if (i < constant.length) { - record[c] = constant[i] - } - }) - } - } else { - if (isBufferArgs(value.buffer)) { - buffer = bufferState.getBuffer( - bufferState.create(value.buffer, GL_ARRAY_BUFFER$2, false, true)) - } else { - buffer = bufferState.getBuffer(value.buffer) - } - check$1.command(!!buffer, 'missing buffer for attribute "' + attribute + '"', env.commandStr) - - var offset = value.offset | 0 - check$1.command(offset >= 0, - 'invalid offset for attribute "' + attribute + '"', env.commandStr) - - var stride = value.stride | 0 - check$1.command(stride >= 0 && stride < 256, - 'invalid stride for attribute "' + attribute + '", must be integer betweeen [0, 255]', env.commandStr) - - var size = value.size | 0 - check$1.command(!('size' in value) || (size > 0 && size <= 4), - 'invalid size for attribute "' + attribute + '", must be 1,2,3,4', env.commandStr) - - var normalized = !!value.normalized - - var type = 0 - if ('type' in value) { - check$1.commandParameter( - value.type, glTypes, - 'invalid type for attribute ' + attribute, env.commandStr) - type = glTypes[value.type] - } - - var divisor = value.divisor | 0 - check$1.optional(function () { - if ('divisor' in value) { - check$1.command(divisor === 0 || extInstancing, - 'cannot specify divisor for attribute "' + attribute + '", instancing not supported', env.commandStr) - check$1.command(divisor >= 0, - 'invalid divisor for attribute "' + attribute + '"', env.commandStr) - } - - var command = env.commandStr - - var VALID_KEYS = [ - 'buffer', - 'offset', - 'divisor', - 'normalized', - 'type', - 'size', - 'stride' - ] - - Object.keys(value).forEach(function (prop) { - check$1.command( - VALID_KEYS.indexOf(prop) >= 0, - 'unknown parameter "' + prop + '" for attribute pointer "' + attribute + '" (valid parameters are ' + VALID_KEYS + ')', - command) - }) - }) - - record.buffer = buffer - record.state = ATTRIB_STATE_POINTER - record.size = size - record.normalized = normalized - record.type = type || buffer.dtype - record.offset = offset - record.stride = stride - record.divisor = divisor - } - } - } - - attributeDefs[attribute] = createStaticDecl(function (env, scope) { - var cache = env.attribCache - if (id in cache) { - return cache[id] - } - var result = { - isStream: false - } - Object.keys(record).forEach(function (key) { - result[key] = record[key] - }) - if (record.buffer) { - result.buffer = env.link(record.buffer) - result.type = result.type || (result.buffer + '.dtype') - } - cache[id] = result - return result - }) - }) - - Object.keys(dynamicAttributes).forEach(function (attribute) { - var dyn = dynamicAttributes[attribute] - - function appendAttributeCode (env, block) { - var VALUE = env.invoke(block, dyn) - - var shared = env.shared - var constants = env.constants - - var IS_BUFFER_ARGS = shared.isBufferArgs - var BUFFER_STATE = shared.buffer - - // Perform validation on attribute - check$1.optional(function () { - env.assert(block, - VALUE + '&&(typeof ' + VALUE + '==="object"||typeof ' + - VALUE + '==="function")&&(' + - IS_BUFFER_ARGS + '(' + VALUE + ')||' + - BUFFER_STATE + '.getBuffer(' + VALUE + ')||' + - BUFFER_STATE + '.getBuffer(' + VALUE + '.buffer)||' + - IS_BUFFER_ARGS + '(' + VALUE + '.buffer)||' + - '("constant" in ' + VALUE + - '&&(typeof ' + VALUE + '.constant==="number"||' + - shared.isArrayLike + '(' + VALUE + '.constant))))', - 'invalid dynamic attribute "' + attribute + '"') - }) - - // allocate names for result - var result = { - isStream: block.def(false) - } - var defaultRecord = new AttributeRecord() - defaultRecord.state = ATTRIB_STATE_POINTER - Object.keys(defaultRecord).forEach(function (key) { - result[key] = block.def('' + defaultRecord[key]) - }) - - var BUFFER = result.buffer - var TYPE = result.type - block( - 'if(', IS_BUFFER_ARGS, '(', VALUE, ')){', - result.isStream, '=true;', - BUFFER, '=', BUFFER_STATE, '.createStream(', GL_ARRAY_BUFFER$2, ',', VALUE, ');', - TYPE, '=', BUFFER, '.dtype;', - '}else{', - BUFFER, '=', BUFFER_STATE, '.getBuffer(', VALUE, ');', - 'if(', BUFFER, '){', - TYPE, '=', BUFFER, '.dtype;', - '}else if("constant" in ', VALUE, '){', - result.state, '=', ATTRIB_STATE_CONSTANT, ';', - 'if(typeof ' + VALUE + '.constant === "number"){', - result[CUTE_COMPONENTS[0]], '=', VALUE, '.constant;', - CUTE_COMPONENTS.slice(1).map(function (n) { - return result[n] - }).join('='), '=0;', - '}else{', - CUTE_COMPONENTS.map(function (name, i) { - return ( - result[name] + '=' + VALUE + '.constant.length>' + i + - '?' + VALUE + '.constant[' + i + ']:0;' - ) - }).join(''), - '}}else{', - 'if(', IS_BUFFER_ARGS, '(', VALUE, '.buffer)){', - BUFFER, '=', BUFFER_STATE, '.createStream(', GL_ARRAY_BUFFER$2, ',', VALUE, '.buffer);', - '}else{', - BUFFER, '=', BUFFER_STATE, '.getBuffer(', VALUE, '.buffer);', - '}', - TYPE, '="type" in ', VALUE, '?', - constants.glTypes, '[', VALUE, '.type]:', BUFFER, '.dtype;', - result.normalized, '=!!', VALUE, '.normalized;') - function emitReadRecord (name) { - block(result[name], '=', VALUE, '.', name, '|0;') - } - emitReadRecord('size') - emitReadRecord('offset') - emitReadRecord('stride') - emitReadRecord('divisor') - - block('}}') - - block.exit( - 'if(', result.isStream, '){', - BUFFER_STATE, '.destroyStream(', BUFFER, ');', - '}') - - return result - } - - attributeDefs[attribute] = createDynamicDecl(dyn, appendAttributeCode) - }) - - return attributeDefs - } - - function parseContext (context) { - var staticContext = context.static - var dynamicContext = context.dynamic - var result = {} - - Object.keys(staticContext).forEach(function (name) { - var value = staticContext[name] - result[name] = createStaticDecl(function (env, scope) { - if (typeof value === 'number' || typeof value === 'boolean') { - return '' + value - } else { - return env.link(value) - } - }) - }) - - Object.keys(dynamicContext).forEach(function (name) { - var dyn = dynamicContext[name] - result[name] = createDynamicDecl(dyn, function (env, scope) { - return env.invoke(scope, dyn) - }) - }) - - return result - } - - function parseArguments (options, attributes, uniforms, context, env) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - check$1.optional(function () { - var KEY_NAMES = [ - S_FRAMEBUFFER, - S_VERT, - S_FRAG, - S_ELEMENTS, - S_PRIMITIVE, - S_OFFSET, - S_COUNT, - S_INSTANCES, - S_PROFILE, - S_VAO - ].concat(GL_STATE_NAMES) - - function checkKeys (dict) { - Object.keys(dict).forEach(function (key) { - check$1.command( - KEY_NAMES.indexOf(key) >= 0, - 'unknown parameter "' + key + '"', - env.commandStr) - }) - } - - checkKeys(staticOptions) - checkKeys(dynamicOptions) - }) - - var attribLocations = parseAttribLocations(options, attributes) - - var framebuffer = parseFramebuffer(options, env) - var viewportAndScissor = parseViewportScissor(options, framebuffer, env) - var draw = parseDraw(options, env) - var state = parseGLState(options, env) - var shader = parseProgram(options, env, attribLocations) - - function copyBox (name) { - var defn = viewportAndScissor[name] - if (defn) { - state[name] = defn - } - } - copyBox(S_VIEWPORT) - copyBox(propName(S_SCISSOR_BOX)) - - var dirty = Object.keys(state).length > 0 - - var result = { - framebuffer: framebuffer, - draw: draw, - shader: shader, - state: state, - dirty: dirty, - scopeVAO: null, - drawVAO: null, - useVAO: false, - attributes: {} - } - - result.profile = parseProfile(options, env) - result.uniforms = parseUniforms(uniforms, env) - result.drawVAO = result.scopeVAO = draw.vao - // special case: check if we can statically allocate a vertex array object for this program - if (!result.drawVAO && - shader.program && - !attribLocations && - extensions.angle_instanced_arrays && - draw.static.elements) { - var useVAO = true - var staticBindings = shader.program.attributes.map(function (attr) { - var binding = attributes.static[attr] - useVAO = useVAO && !!binding - return binding - }) - if (useVAO && staticBindings.length > 0) { - var vao = attributeState.getVAO(attributeState.createVAO({ - attributes: staticBindings, - elements: draw.static.elements - })) - result.drawVAO = new Declaration(null, null, null, function (env, scope) { - return env.link(vao) - }) - result.useVAO = true - } - } - if (attribLocations) { - result.useVAO = true - } else { - result.attributes = parseAttributes(attributes, env) - } - result.context = parseContext(context, env) - return result - } - - // =================================================== - // =================================================== - // COMMON UPDATE FUNCTIONS - // =================================================== - // =================================================== - function emitContext (env, scope, context) { - var shared = env.shared - var CONTEXT = shared.context - - var contextEnter = env.scope() - - Object.keys(context).forEach(function (name) { - scope.save(CONTEXT, '.' + name) - var defn = context[name] - var value = defn.append(env, scope) - if (Array.isArray(value)) { - contextEnter(CONTEXT, '.', name, '=[', value.join(), '];') - } else { - contextEnter(CONTEXT, '.', name, '=', value, ';') - } - }) - - scope(contextEnter) - } - - // =================================================== - // =================================================== - // COMMON DRAWING FUNCTIONS - // =================================================== - // =================================================== - function emitPollFramebuffer (env, scope, framebuffer, skipCheck) { - var shared = env.shared - - var GL = shared.gl - var FRAMEBUFFER_STATE = shared.framebuffer - var EXT_DRAW_BUFFERS - if (extDrawBuffers) { - EXT_DRAW_BUFFERS = scope.def(shared.extensions, '.webgl_draw_buffers') - } - - var constants = env.constants - - var DRAW_BUFFERS = constants.drawBuffer - var BACK_BUFFER = constants.backBuffer - - var NEXT - if (framebuffer) { - NEXT = framebuffer.append(env, scope) - } else { - NEXT = scope.def(FRAMEBUFFER_STATE, '.next') - } - - if (!skipCheck) { - scope('if(', NEXT, '!==', FRAMEBUFFER_STATE, '.cur){') - } - scope( - 'if(', NEXT, '){', - GL, '.bindFramebuffer(', GL_FRAMEBUFFER$2, ',', NEXT, '.framebuffer);') - if (extDrawBuffers) { - scope(EXT_DRAW_BUFFERS, '.drawBuffersWEBGL(', - DRAW_BUFFERS, '[', NEXT, '.colorAttachments.length]);') - } - scope('}else{', - GL, '.bindFramebuffer(', GL_FRAMEBUFFER$2, ',null);') - if (extDrawBuffers) { - scope(EXT_DRAW_BUFFERS, '.drawBuffersWEBGL(', BACK_BUFFER, ');') - } - scope( - '}', - FRAMEBUFFER_STATE, '.cur=', NEXT, ';') - if (!skipCheck) { - scope('}') - } - } - - function emitPollState (env, scope, args) { - var shared = env.shared - - var GL = shared.gl - - var CURRENT_VARS = env.current - var NEXT_VARS = env.next - var CURRENT_STATE = shared.current - var NEXT_STATE = shared.next - - var block = env.cond(CURRENT_STATE, '.dirty') - - GL_STATE_NAMES.forEach(function (prop) { - var param = propName(prop) - if (param in args.state) { - return - } - - var NEXT, CURRENT - if (param in NEXT_VARS) { - NEXT = NEXT_VARS[param] - CURRENT = CURRENT_VARS[param] - var parts = loop(currentState[param].length, function (i) { - return block.def(NEXT, '[', i, ']') - }) - block(env.cond(parts.map(function (p, i) { - return p + '!==' + CURRENT + '[' + i + ']' - }).join('||')) - .then( - GL, '.', GL_VARIABLES[param], '(', parts, ');', - parts.map(function (p, i) { - return CURRENT + '[' + i + ']=' + p - }).join(';'), ';')) - } else { - NEXT = block.def(NEXT_STATE, '.', param) - var ifte = env.cond(NEXT, '!==', CURRENT_STATE, '.', param) - block(ifte) - if (param in GL_FLAGS) { - ifte( - env.cond(NEXT) - .then(GL, '.enable(', GL_FLAGS[param], ');') - .else(GL, '.disable(', GL_FLAGS[param], ');'), - CURRENT_STATE, '.', param, '=', NEXT, ';') - } else { - ifte( - GL, '.', GL_VARIABLES[param], '(', NEXT, ');', - CURRENT_STATE, '.', param, '=', NEXT, ';') - } - } - }) - if (Object.keys(args.state).length === 0) { - block(CURRENT_STATE, '.dirty=false;') - } - scope(block) - } - - function emitSetOptions (env, scope, options, filter) { - var shared = env.shared - var CURRENT_VARS = env.current - var CURRENT_STATE = shared.current - var GL = shared.gl - sortState(Object.keys(options)).forEach(function (param) { - var defn = options[param] - if (filter && !filter(defn)) { - return - } - var variable = defn.append(env, scope) - if (GL_FLAGS[param]) { - var flag = GL_FLAGS[param] - if (isStatic(defn)) { - if (variable) { - scope(GL, '.enable(', flag, ');') - } else { - scope(GL, '.disable(', flag, ');') - } - } else { - scope(env.cond(variable) - .then(GL, '.enable(', flag, ');') - .else(GL, '.disable(', flag, ');')) - } - scope(CURRENT_STATE, '.', param, '=', variable, ';') - } else if (isArrayLike(variable)) { - var CURRENT = CURRENT_VARS[param] - scope( - GL, '.', GL_VARIABLES[param], '(', variable, ');', - variable.map(function (v, i) { - return CURRENT + '[' + i + ']=' + v - }).join(';'), ';') - } else { - scope( - GL, '.', GL_VARIABLES[param], '(', variable, ');', - CURRENT_STATE, '.', param, '=', variable, ';') - } - }) - } - - function injectExtensions (env, scope) { - if (extInstancing) { - env.instancing = scope.def( - env.shared.extensions, '.angle_instanced_arrays') - } - } - - function emitProfile (env, scope, args, useScope, incrementCounter) { - var shared = env.shared - var STATS = env.stats - var CURRENT_STATE = shared.current - var TIMER = shared.timer - var profileArg = args.profile - - function perfCounter () { - if (typeof performance === 'undefined') { - return 'Date.now()' - } else { - return 'performance.now()' - } - } - - var CPU_START, QUERY_COUNTER - function emitProfileStart (block) { - CPU_START = scope.def() - block(CPU_START, '=', perfCounter(), ';') - if (typeof incrementCounter === 'string') { - block(STATS, '.count+=', incrementCounter, ';') - } else { - block(STATS, '.count++;') - } - if (timer) { - if (useScope) { - QUERY_COUNTER = scope.def() - block(QUERY_COUNTER, '=', TIMER, '.getNumPendingQueries();') - } else { - block(TIMER, '.beginQuery(', STATS, ');') - } - } - } - - function emitProfileEnd (block) { - block(STATS, '.cpuTime+=', perfCounter(), '-', CPU_START, ';') - if (timer) { - if (useScope) { - block(TIMER, '.pushScopeStats(', - QUERY_COUNTER, ',', - TIMER, '.getNumPendingQueries(),', - STATS, ');') - } else { - block(TIMER, '.endQuery();') - } - } - } - - function scopeProfile (value) { - var prev = scope.def(CURRENT_STATE, '.profile') - scope(CURRENT_STATE, '.profile=', value, ';') - scope.exit(CURRENT_STATE, '.profile=', prev, ';') - } - - var USE_PROFILE - if (profileArg) { - if (isStatic(profileArg)) { - if (profileArg.enable) { - emitProfileStart(scope) - emitProfileEnd(scope.exit) - scopeProfile('true') - } else { - scopeProfile('false') - } - return - } - USE_PROFILE = profileArg.append(env, scope) - scopeProfile(USE_PROFILE) - } else { - USE_PROFILE = scope.def(CURRENT_STATE, '.profile') - } - - var start = env.block() - emitProfileStart(start) - scope('if(', USE_PROFILE, '){', start, '}') - var end = env.block() - emitProfileEnd(end) - scope.exit('if(', USE_PROFILE, '){', end, '}') - } - - function emitAttributes (env, scope, args, attributes, filter) { - var shared = env.shared - - function typeLength (x) { - switch (x) { - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - case GL_BOOL_VEC2: - return 2 - case GL_FLOAT_VEC3: - case GL_INT_VEC3: - case GL_BOOL_VEC3: - return 3 - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - case GL_BOOL_VEC4: - return 4 - default: - return 1 - } - } - - function emitBindAttribute (ATTRIBUTE, size, record) { - var GL = shared.gl - - var LOCATION = scope.def(ATTRIBUTE, '.location') - var BINDING = scope.def(shared.attributes, '[', LOCATION, ']') - - var STATE = record.state - var BUFFER = record.buffer - var CONST_COMPONENTS = [ - record.x, - record.y, - record.z, - record.w - ] - - var COMMON_KEYS = [ - 'buffer', - 'normalized', - 'offset', - 'stride' - ] - - function emitBuffer () { - scope( - 'if(!', BINDING, '.buffer){', - GL, '.enableVertexAttribArray(', LOCATION, ');}') - - var TYPE = record.type - var SIZE - if (!record.size) { - SIZE = size - } else { - SIZE = scope.def(record.size, '||', size) - } - - scope('if(', - BINDING, '.type!==', TYPE, '||', - BINDING, '.size!==', SIZE, '||', - COMMON_KEYS.map(function (key) { - return BINDING + '.' + key + '!==' + record[key] - }).join('||'), - '){', - GL, '.bindBuffer(', GL_ARRAY_BUFFER$2, ',', BUFFER, '.buffer);', - GL, '.vertexAttribPointer(', [ - LOCATION, - SIZE, - TYPE, - record.normalized, - record.stride, - record.offset - ], ');', - BINDING, '.type=', TYPE, ';', - BINDING, '.size=', SIZE, ';', - COMMON_KEYS.map(function (key) { - return BINDING + '.' + key + '=' + record[key] + ';' - }).join(''), - '}') - - if (extInstancing) { - var DIVISOR = record.divisor - scope( - 'if(', BINDING, '.divisor!==', DIVISOR, '){', - env.instancing, '.vertexAttribDivisorANGLE(', [LOCATION, DIVISOR], ');', - BINDING, '.divisor=', DIVISOR, ';}') - } - } - - function emitConstant () { - scope( - 'if(', BINDING, '.buffer){', - GL, '.disableVertexAttribArray(', LOCATION, ');', - BINDING, '.buffer=null;', - '}if(', CUTE_COMPONENTS.map(function (c, i) { - return BINDING + '.' + c + '!==' + CONST_COMPONENTS[i] - }).join('||'), '){', - GL, '.vertexAttrib4f(', LOCATION, ',', CONST_COMPONENTS, ');', - CUTE_COMPONENTS.map(function (c, i) { - return BINDING + '.' + c + '=' + CONST_COMPONENTS[i] + ';' - }).join(''), - '}') - } - - if (STATE === ATTRIB_STATE_POINTER) { - emitBuffer() - } else if (STATE === ATTRIB_STATE_CONSTANT) { - emitConstant() - } else { - scope('if(', STATE, '===', ATTRIB_STATE_POINTER, '){') - emitBuffer() - scope('}else{') - emitConstant() - scope('}') - } - } - - attributes.forEach(function (attribute) { - var name = attribute.name - var arg = args.attributes[name] - var record - if (arg) { - if (!filter(arg)) { - return - } - record = arg.append(env, scope) - } else { - if (!filter(SCOPE_DECL)) { - return - } - var scopeAttrib = env.scopeAttrib(name) - check$1.optional(function () { - env.assert(scope, - scopeAttrib + '.state', - 'missing attribute ' + name) - }) - record = {} - Object.keys(new AttributeRecord()).forEach(function (key) { - record[key] = scope.def(scopeAttrib, '.', key) - }) - } - emitBindAttribute( - env.link(attribute), typeLength(attribute.info.type), record) - }) - } - - function emitUniforms (env, scope, args, uniforms, filter, isBatchInnerLoop) { - var shared = env.shared - var GL = shared.gl - - var definedArrUniforms = {} - var infix - for (var i = 0; i < uniforms.length; ++i) { - var uniform = uniforms[i] - var name = uniform.name - var type = uniform.info.type - var size = uniform.info.size - var arg = args.uniforms[name] - if (size > 1) { - // either foo[n] or foos, avoid define both - if (!arg) { - continue - } - var arrUniformName = name.replace('[0]', '') - if (definedArrUniforms[arrUniformName]) { - continue - } - definedArrUniforms[arrUniformName] = 1 - } - var UNIFORM = env.link(uniform) - var LOCATION = UNIFORM + '.location' - - var VALUE - if (arg) { - if (!filter(arg)) { - continue - } - if (isStatic(arg)) { - var value = arg.value - check$1.command( - value !== null && typeof value !== 'undefined', - 'missing uniform "' + name + '"', env.commandStr) - if (type === GL_SAMPLER_2D || type === GL_SAMPLER_CUBE) { - check$1.command( - typeof value === 'function' && - ((type === GL_SAMPLER_2D && - (value._reglType === 'texture2d' || - value._reglType === 'framebuffer')) || - (type === GL_SAMPLER_CUBE && - (value._reglType === 'textureCube' || - value._reglType === 'framebufferCube'))), - 'invalid texture for uniform ' + name, env.commandStr) - var TEX_VALUE = env.link(value._texture || value.color[0]._texture) - scope(GL, '.uniform1i(', LOCATION, ',', TEX_VALUE + '.bind());') - scope.exit(TEX_VALUE, '.unbind();') - } else if ( - type === GL_FLOAT_MAT2 || - type === GL_FLOAT_MAT3 || - type === GL_FLOAT_MAT4) { - check$1.optional(function () { - check$1.command(isArrayLike(value), - 'invalid matrix for uniform ' + name, env.commandStr) - check$1.command( - (type === GL_FLOAT_MAT2 && value.length === 4) || - (type === GL_FLOAT_MAT3 && value.length === 9) || - (type === GL_FLOAT_MAT4 && value.length === 16), - 'invalid length for matrix uniform ' + name, env.commandStr) - }) - var MAT_VALUE = env.global.def('new Float32Array([' + - Array.prototype.slice.call(value) + '])') - var dim = 2 - if (type === GL_FLOAT_MAT3) { - dim = 3 - } else if (type === GL_FLOAT_MAT4) { - dim = 4 - } - scope( - GL, '.uniformMatrix', dim, 'fv(', - LOCATION, ',false,', MAT_VALUE, ');') - } else { - switch (type) { - case GL_FLOAT$8: - if (size === 1) { - check$1.commandType(value, 'number', 'uniform ' + name, env.commandStr) - } else { - check$1.command( - isArrayLike(value) && (value.length === size), - 'uniform ' + name, env.commandStr) - } - infix = '1f' - break - case GL_FLOAT_VEC2: - check$1.command( - isArrayLike(value) && (value.length && value.length % 2 === 0 && value.length <= size * 2), - 'uniform ' + name, env.commandStr) - infix = '2f' - break - case GL_FLOAT_VEC3: - check$1.command( - isArrayLike(value) && (value.length && value.length % 3 === 0 && value.length <= size * 3), - 'uniform ' + name, env.commandStr) - infix = '3f' - break - case GL_FLOAT_VEC4: - check$1.command( - isArrayLike(value) && (value.length && value.length % 4 === 0 && value.length <= size * 4), - 'uniform ' + name, env.commandStr) - infix = '4f' - break - case GL_BOOL: - if (size === 1) { - check$1.commandType(value, 'boolean', 'uniform ' + name, env.commandStr) - } else { - check$1.command( - isArrayLike(value) && (value.length === size), - 'uniform ' + name, env.commandStr) - } - infix = '1i' - break - case GL_INT$3: - if (size === 1) { - check$1.commandType(value, 'number', 'uniform ' + name, env.commandStr) - } else { - check$1.command( - isArrayLike(value) && (value.length === size), - 'uniform ' + name, env.commandStr) - } - infix = '1i' - break - case GL_BOOL_VEC2: - check$1.command( - isArrayLike(value) && (value.length && value.length % 2 === 0 && value.length <= size * 2), - 'uniform ' + name, env.commandStr) - infix = '2i' - break - case GL_INT_VEC2: - check$1.command( - isArrayLike(value) && (value.length && value.length % 2 === 0 && value.length <= size * 2), - 'uniform ' + name, env.commandStr) - infix = '2i' - break - case GL_BOOL_VEC3: - check$1.command( - isArrayLike(value) && (value.length && value.length % 3 === 0 && value.length <= size * 3), - 'uniform ' + name, env.commandStr) - infix = '3i' - break - case GL_INT_VEC3: - check$1.command( - isArrayLike(value) && (value.length && value.length % 3 === 0 && value.length <= size * 3), - 'uniform ' + name, env.commandStr) - infix = '3i' - break - case GL_BOOL_VEC4: - check$1.command( - isArrayLike(value) && (value.length && value.length % 4 === 0 && value.length <= size * 4), - 'uniform ' + name, env.commandStr) - infix = '4i' - break - case GL_INT_VEC4: - check$1.command( - isArrayLike(value) && (value.length && value.length % 4 === 0 && value.length <= size * 4), - 'uniform ' + name, env.commandStr) - infix = '4i' - break - } - if (size > 1) { - infix += 'v' - value = env.global.def('[' + - Array.prototype.slice.call(value) + ']') - } else { - value = isArrayLike(value) ? Array.prototype.slice.call(value) : value - } - scope(GL, '.uniform', infix, '(', LOCATION, ',', - value, - ');') - } - continue - } else { - VALUE = arg.append(env, scope) - } - } else { - if (!filter(SCOPE_DECL)) { - continue - } - VALUE = scope.def(shared.uniforms, '[', stringStore.id(name), ']') - } - - if (type === GL_SAMPLER_2D) { - check$1(!Array.isArray(VALUE), 'must specify a scalar prop for textures') - scope( - 'if(', VALUE, '&&', VALUE, '._reglType==="framebuffer"){', - VALUE, '=', VALUE, '.color[0];', - '}') - } else if (type === GL_SAMPLER_CUBE) { - check$1(!Array.isArray(VALUE), 'must specify a scalar prop for cube maps') - scope( - 'if(', VALUE, '&&', VALUE, '._reglType==="framebufferCube"){', - VALUE, '=', VALUE, '.color[0];', - '}') - } - - // perform type validation - check$1.optional(function () { - function emitCheck (pred, message) { - env.assert(scope, pred, - 'bad data or missing for uniform "' + name + '". ' + message) - } - - function checkType (type, size) { - if (size === 1) { - check$1(!Array.isArray(VALUE), 'must not specify an array type for uniform') - } - emitCheck( - 'Array.isArray(' + VALUE + ') && typeof ' + VALUE + '[0]===" ' + type + '"' + - ' || typeof ' + VALUE + '==="' + type + '"', - 'invalid type, expected ' + type) - } - - function checkVector (n, type, size) { - if (Array.isArray(VALUE)) { - check$1(VALUE.length && VALUE.length % n === 0 && VALUE.length <= n * size, 'must have length of ' + (size === 1 ? '' : 'n * ') + n) - } else { - emitCheck( - shared.isArrayLike + '(' + VALUE + ')&&' + VALUE + '.length && ' + VALUE + '.length % ' + n + ' === 0' + - ' && ' + VALUE + '.length<=' + n * size, - 'invalid vector, should have length of ' + (size === 1 ? '' : 'n * ') + n, env.commandStr) - } - } - - function checkTexture (target) { - check$1(!Array.isArray(VALUE), 'must not specify a value type') - emitCheck( - 'typeof ' + VALUE + '==="function"&&' + - VALUE + '._reglType==="texture' + - (target === GL_TEXTURE_2D$3 ? '2d' : 'Cube') + '"', - 'invalid texture type', env.commandStr) - } - - switch (type) { - case GL_INT$3: - checkType('number', size) - break - case GL_INT_VEC2: - checkVector(2, 'number', size) - break - case GL_INT_VEC3: - checkVector(3, 'number', size) - break - case GL_INT_VEC4: - checkVector(4, 'number', size) - break - case GL_FLOAT$8: - checkType('number', size) - break - case GL_FLOAT_VEC2: - checkVector(2, 'number', size) - break - case GL_FLOAT_VEC3: - checkVector(3, 'number', size) - break - case GL_FLOAT_VEC4: - checkVector(4, 'number', size) - break - case GL_BOOL: - checkType('boolean', size) - break - case GL_BOOL_VEC2: - checkVector(2, 'boolean', size) - break - case GL_BOOL_VEC3: - checkVector(3, 'boolean', size) - break - case GL_BOOL_VEC4: - checkVector(4, 'boolean', size) - break - case GL_FLOAT_MAT2: - checkVector(4, 'number', size) - break - case GL_FLOAT_MAT3: - checkVector(9, 'number', size) - break - case GL_FLOAT_MAT4: - checkVector(16, 'number', size) - break - case GL_SAMPLER_2D: - checkTexture(GL_TEXTURE_2D$3) - break - case GL_SAMPLER_CUBE: - checkTexture(GL_TEXTURE_CUBE_MAP$2) - break - } - }) - - var unroll = 1 - switch (type) { - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - var TEX = scope.def(VALUE, '._texture') - scope(GL, '.uniform1i(', LOCATION, ',', TEX, '.bind());') - scope.exit(TEX, '.unbind();') - continue - - case GL_INT$3: - case GL_BOOL: - infix = '1i' - break - - case GL_INT_VEC2: - case GL_BOOL_VEC2: - infix = '2i' - unroll = 2 - break - - case GL_INT_VEC3: - case GL_BOOL_VEC3: - infix = '3i' - unroll = 3 - break - - case GL_INT_VEC4: - case GL_BOOL_VEC4: - infix = '4i' - unroll = 4 - break - - case GL_FLOAT$8: - infix = '1f' - break - - case GL_FLOAT_VEC2: - infix = '2f' - unroll = 2 - break - - case GL_FLOAT_VEC3: - infix = '3f' - unroll = 3 - break - - case GL_FLOAT_VEC4: - infix = '4f' - unroll = 4 - break - - case GL_FLOAT_MAT2: - infix = 'Matrix2fv' - break - - case GL_FLOAT_MAT3: - infix = 'Matrix3fv' - break - - case GL_FLOAT_MAT4: - infix = 'Matrix4fv' - break - } - - if (infix.indexOf('Matrix') === -1 && size > 1) { - infix += 'v' - unroll = 1 - } - - if (infix.charAt(0) === 'M') { - scope(GL, '.uniform', infix, '(', LOCATION, ',') - var matSize = Math.pow(type - GL_FLOAT_MAT2 + 2, 2) - var STORAGE = env.global.def('new Float32Array(', matSize, ')') - if (Array.isArray(VALUE)) { - scope( - 'false,(', - loop(matSize, function (i) { - return STORAGE + '[' + i + ']=' + VALUE[i] - }), ',', STORAGE, ')') - } else { - scope( - 'false,(Array.isArray(', VALUE, ')||', VALUE, ' instanceof Float32Array)?', VALUE, ':(', - loop(matSize, function (i) { - return STORAGE + '[' + i + ']=' + VALUE + '[' + i + ']' - }), ',', STORAGE, ')') - } - scope(');') - } else if (unroll > 1) { - var prev = [] - var cur = [] - for (var j = 0; j < unroll; ++j) { - if (Array.isArray(VALUE)) { - cur.push(VALUE[j]) - } else { - cur.push(scope.def(VALUE + '[' + j + ']')) - } - if (isBatchInnerLoop) { - prev.push(scope.def()) - } - } - if (isBatchInnerLoop) { - scope('if(!', env.batchId, '||', prev.map(function (p, i) { - return p + '!==' + cur[i] - }).join('||'), '){', prev.map(function (p, i) { - return p + '=' + cur[i] + ';' - }).join('')) - } - scope(GL, '.uniform', infix, '(', LOCATION, ',', cur.join(','), ');') - if (isBatchInnerLoop) { - scope('}') - } - } else { - check$1(!Array.isArray(VALUE), 'uniform value must not be an array') - if (isBatchInnerLoop) { - var prevS = scope.def() - scope('if(!', env.batchId, '||', prevS, '!==', VALUE, '){', - prevS, '=', VALUE, ';') - } - scope(GL, '.uniform', infix, '(', LOCATION, ',', VALUE, ');') - if (isBatchInnerLoop) { - scope('}') - } - } - } - } - - function emitDraw (env, outer, inner, args) { - var shared = env.shared - var GL = shared.gl - var DRAW_STATE = shared.draw - - var drawOptions = args.draw - - function emitElements () { - var defn = drawOptions.elements - var ELEMENTS - var scope = outer - if (defn) { - if ((defn.contextDep && args.contextDynamic) || defn.propDep) { - scope = inner - } - ELEMENTS = defn.append(env, scope) - if (drawOptions.elementsActive) { - scope( - 'if(' + ELEMENTS + ')' + - GL + '.bindBuffer(' + GL_ELEMENT_ARRAY_BUFFER$2 + ',' + ELEMENTS + '.buffer.buffer);') - } - } else { - ELEMENTS = scope.def() - scope( - ELEMENTS, '=', DRAW_STATE, '.', S_ELEMENTS, ';', - 'if(', ELEMENTS, '){', - GL, '.bindBuffer(', GL_ELEMENT_ARRAY_BUFFER$2, ',', ELEMENTS, '.buffer.buffer);}', - 'else if(', shared.vao, '.currentVAO){', - ELEMENTS, '=', env.shared.elements + '.getElements(' + shared.vao, '.currentVAO.elements);', - (!extVertexArrays ? 'if(' + ELEMENTS + ')' + GL + '.bindBuffer(' + GL_ELEMENT_ARRAY_BUFFER$2 + ',' + ELEMENTS + '.buffer.buffer);' : ''), - '}') - } - return ELEMENTS - } - - function emitCount () { - var defn = drawOptions.count - var COUNT - var scope = outer - if (defn) { - if ((defn.contextDep && args.contextDynamic) || defn.propDep) { - scope = inner - } - COUNT = defn.append(env, scope) - check$1.optional(function () { - if (defn.MISSING) { - env.assert(outer, 'false', 'missing vertex count') - } - if (defn.DYNAMIC) { - env.assert(scope, COUNT + '>=0', 'missing vertex count') - } - }) - } else { - COUNT = scope.def(DRAW_STATE, '.', S_COUNT) - check$1.optional(function () { - env.assert(scope, COUNT + '>=0', 'missing vertex count') - }) - } - return COUNT - } - - var ELEMENTS = emitElements() - function emitValue (name) { - var defn = drawOptions[name] - if (defn) { - if ((defn.contextDep && args.contextDynamic) || defn.propDep) { - return defn.append(env, inner) - } else { - return defn.append(env, outer) - } - } else { - return outer.def(DRAW_STATE, '.', name) - } - } - - var PRIMITIVE = emitValue(S_PRIMITIVE) - var OFFSET = emitValue(S_OFFSET) - - var COUNT = emitCount() - if (typeof COUNT === 'number') { - if (COUNT === 0) { - return - } - } else { - inner('if(', COUNT, '){') - inner.exit('}') - } - - var INSTANCES, EXT_INSTANCING - if (extInstancing) { - INSTANCES = emitValue(S_INSTANCES) - EXT_INSTANCING = env.instancing - } - - var ELEMENT_TYPE = ELEMENTS + '.type' - - var elementsStatic = drawOptions.elements && isStatic(drawOptions.elements) && !drawOptions.vaoActive - - function emitInstancing () { - function drawElements () { - inner(EXT_INSTANCING, '.drawElementsInstancedANGLE(', [ - PRIMITIVE, - COUNT, - ELEMENT_TYPE, - OFFSET + '<<((' + ELEMENT_TYPE + '-' + GL_UNSIGNED_BYTE$8 + ')>>1)', - INSTANCES - ], ');') - } - - function drawArrays () { - inner(EXT_INSTANCING, '.drawArraysInstancedANGLE(', - [PRIMITIVE, OFFSET, COUNT, INSTANCES], ');') - } - - if (ELEMENTS && ELEMENTS !== 'null') { - if (!elementsStatic) { - inner('if(', ELEMENTS, '){') - drawElements() - inner('}else{') - drawArrays() - inner('}') - } else { - drawElements() - } - } else { - drawArrays() - } - } - - function emitRegular () { - function drawElements () { - inner(GL + '.drawElements(' + [ - PRIMITIVE, - COUNT, - ELEMENT_TYPE, - OFFSET + '<<((' + ELEMENT_TYPE + '-' + GL_UNSIGNED_BYTE$8 + ')>>1)' - ] + ');') - } - - function drawArrays () { - inner(GL + '.drawArrays(' + [PRIMITIVE, OFFSET, COUNT] + ');') - } - - if (ELEMENTS && ELEMENTS !== 'null') { - if (!elementsStatic) { - inner('if(', ELEMENTS, '){') - drawElements() - inner('}else{') - drawArrays() - inner('}') - } else { - drawElements() - } - } else { - drawArrays() - } - } - - if (extInstancing && (typeof INSTANCES !== 'number' || INSTANCES >= 0)) { - if (typeof INSTANCES === 'string') { - inner('if(', INSTANCES, '>0){') - emitInstancing() - inner('}else if(', INSTANCES, '<0){') - emitRegular() - inner('}') - } else { - emitInstancing() - } - } else { - emitRegular() - } - } - - function createBody (emitBody, parentEnv, args, program, count) { - var env = createREGLEnvironment() - var scope = env.proc('body', count) - check$1.optional(function () { - env.commandStr = parentEnv.commandStr - env.command = env.link(parentEnv.commandStr) - }) - if (extInstancing) { - env.instancing = scope.def( - env.shared.extensions, '.angle_instanced_arrays') - } - emitBody(env, scope, args, program) - return env.compile().body - } - - // =================================================== - // =================================================== - // DRAW PROC - // =================================================== - // =================================================== - function emitDrawBody (env, draw, args, program) { - injectExtensions(env, draw) - if (args.useVAO) { - if (args.drawVAO) { - draw(env.shared.vao, '.setVAO(', args.drawVAO.append(env, draw), ');') - } else { - draw(env.shared.vao, '.setVAO(', env.shared.vao, '.targetVAO);') - } - } else { - draw(env.shared.vao, '.setVAO(null);') - emitAttributes(env, draw, args, program.attributes, function () { - return true - }) - } - emitUniforms(env, draw, args, program.uniforms, function () { - return true - }, false) - emitDraw(env, draw, draw, args) - } - - function emitDrawProc (env, args) { - var draw = env.proc('draw', 1) - - injectExtensions(env, draw) - - emitContext(env, draw, args.context) - emitPollFramebuffer(env, draw, args.framebuffer) - - emitPollState(env, draw, args) - emitSetOptions(env, draw, args.state) - - emitProfile(env, draw, args, false, true) - - var program = args.shader.progVar.append(env, draw) - draw(env.shared.gl, '.useProgram(', program, '.program);') - - if (args.shader.program) { - emitDrawBody(env, draw, args, args.shader.program) - } else { - draw(env.shared.vao, '.setVAO(null);') - var drawCache = env.global.def('{}') - var PROG_ID = draw.def(program, '.id') - var CACHED_PROC = draw.def(drawCache, '[', PROG_ID, ']') - draw( - env.cond(CACHED_PROC) - .then(CACHED_PROC, '.call(this,a0);') - .else( - CACHED_PROC, '=', drawCache, '[', PROG_ID, ']=', - env.link(function (program) { - return createBody(emitDrawBody, env, args, program, 1) - }), '(', program, ');', - CACHED_PROC, '.call(this,a0);')) - } - - if (Object.keys(args.state).length > 0) { - draw(env.shared.current, '.dirty=true;') - } - if (env.shared.vao) { - draw(env.shared.vao, '.setVAO(null);') - } - } - - // =================================================== - // =================================================== - // BATCH PROC - // =================================================== - // =================================================== - - function emitBatchDynamicShaderBody (env, scope, args, program) { - env.batchId = 'a1' - - injectExtensions(env, scope) - - function all () { - return true - } - - emitAttributes(env, scope, args, program.attributes, all) - emitUniforms(env, scope, args, program.uniforms, all, false) - emitDraw(env, scope, scope, args) - } - - function emitBatchBody (env, scope, args, program) { - injectExtensions(env, scope) - - var contextDynamic = args.contextDep - - var BATCH_ID = scope.def() - var PROP_LIST = 'a0' - var NUM_PROPS = 'a1' - var PROPS = scope.def() - env.shared.props = PROPS - env.batchId = BATCH_ID - - var outer = env.scope() - var inner = env.scope() - - scope( - outer.entry, - 'for(', BATCH_ID, '=0;', BATCH_ID, '<', NUM_PROPS, ';++', BATCH_ID, '){', - PROPS, '=', PROP_LIST, '[', BATCH_ID, '];', - inner, - '}', - outer.exit) - - function isInnerDefn (defn) { - return ((defn.contextDep && contextDynamic) || defn.propDep) - } - - function isOuterDefn (defn) { - return !isInnerDefn(defn) - } - - if (args.needsContext) { - emitContext(env, inner, args.context) - } - if (args.needsFramebuffer) { - emitPollFramebuffer(env, inner, args.framebuffer) - } - emitSetOptions(env, inner, args.state, isInnerDefn) - - if (args.profile && isInnerDefn(args.profile)) { - emitProfile(env, inner, args, false, true) - } - - if (!program) { - var progCache = env.global.def('{}') - var PROGRAM = args.shader.progVar.append(env, inner) - var PROG_ID = inner.def(PROGRAM, '.id') - var CACHED_PROC = inner.def(progCache, '[', PROG_ID, ']') - inner( - env.shared.gl, '.useProgram(', PROGRAM, '.program);', - 'if(!', CACHED_PROC, '){', - CACHED_PROC, '=', progCache, '[', PROG_ID, ']=', - env.link(function (program) { - return createBody( - emitBatchDynamicShaderBody, env, args, program, 2) - }), '(', PROGRAM, ');}', - CACHED_PROC, '.call(this,a0[', BATCH_ID, '],', BATCH_ID, ');') - } else { - if (args.useVAO) { - if (args.drawVAO) { - if (isInnerDefn(args.drawVAO)) { - // vao is a prop - inner(env.shared.vao, '.setVAO(', args.drawVAO.append(env, inner), ');') - } else { - // vao is invariant - outer(env.shared.vao, '.setVAO(', args.drawVAO.append(env, outer), ');') - } - } else { - // scoped vao binding - outer(env.shared.vao, '.setVAO(', env.shared.vao, '.targetVAO);') - } - } else { - outer(env.shared.vao, '.setVAO(null);') - emitAttributes(env, outer, args, program.attributes, isOuterDefn) - emitAttributes(env, inner, args, program.attributes, isInnerDefn) - } - emitUniforms(env, outer, args, program.uniforms, isOuterDefn, false) - emitUniforms(env, inner, args, program.uniforms, isInnerDefn, true) - emitDraw(env, outer, inner, args) - } - } - - function emitBatchProc (env, args) { - var batch = env.proc('batch', 2) - env.batchId = '0' - - injectExtensions(env, batch) - - // Check if any context variables depend on props - var contextDynamic = false - var needsContext = true - Object.keys(args.context).forEach(function (name) { - contextDynamic = contextDynamic || args.context[name].propDep - }) - if (!contextDynamic) { - emitContext(env, batch, args.context) - needsContext = false - } - - // framebuffer state affects framebufferWidth/height context vars - var framebuffer = args.framebuffer - var needsFramebuffer = false - if (framebuffer) { - if (framebuffer.propDep) { - contextDynamic = needsFramebuffer = true - } else if (framebuffer.contextDep && contextDynamic) { - needsFramebuffer = true - } - if (!needsFramebuffer) { - emitPollFramebuffer(env, batch, framebuffer) - } - } else { - emitPollFramebuffer(env, batch, null) - } - - // viewport is weird because it can affect context vars - if (args.state.viewport && args.state.viewport.propDep) { - contextDynamic = true - } - - function isInnerDefn (defn) { - return (defn.contextDep && contextDynamic) || defn.propDep - } - - // set webgl options - emitPollState(env, batch, args) - emitSetOptions(env, batch, args.state, function (defn) { - return !isInnerDefn(defn) - }) - - if (!args.profile || !isInnerDefn(args.profile)) { - emitProfile(env, batch, args, false, 'a1') - } - - // Save these values to args so that the batch body routine can use them - args.contextDep = contextDynamic - args.needsContext = needsContext - args.needsFramebuffer = needsFramebuffer - - // determine if shader is dynamic - var progDefn = args.shader.progVar - if ((progDefn.contextDep && contextDynamic) || progDefn.propDep) { - emitBatchBody( - env, - batch, - args, - null) - } else { - var PROGRAM = progDefn.append(env, batch) - batch(env.shared.gl, '.useProgram(', PROGRAM, '.program);') - if (args.shader.program) { - emitBatchBody( - env, - batch, - args, - args.shader.program) - } else { - batch(env.shared.vao, '.setVAO(null);') - var batchCache = env.global.def('{}') - var PROG_ID = batch.def(PROGRAM, '.id') - var CACHED_PROC = batch.def(batchCache, '[', PROG_ID, ']') - batch( - env.cond(CACHED_PROC) - .then(CACHED_PROC, '.call(this,a0,a1);') - .else( - CACHED_PROC, '=', batchCache, '[', PROG_ID, ']=', - env.link(function (program) { - return createBody(emitBatchBody, env, args, program, 2) - }), '(', PROGRAM, ');', - CACHED_PROC, '.call(this,a0,a1);')) - } - } - - if (Object.keys(args.state).length > 0) { - batch(env.shared.current, '.dirty=true;') - } - - if (env.shared.vao) { - batch(env.shared.vao, '.setVAO(null);') - } - } - - // =================================================== - // =================================================== - // SCOPE COMMAND - // =================================================== - // =================================================== - function emitScopeProc (env, args) { - var scope = env.proc('scope', 3) - env.batchId = 'a2' - - var shared = env.shared - var CURRENT_STATE = shared.current - - emitContext(env, scope, args.context) - - if (args.framebuffer) { - args.framebuffer.append(env, scope) - } - - sortState(Object.keys(args.state)).forEach(function (name) { - var defn = args.state[name] - var value = defn.append(env, scope) - if (isArrayLike(value)) { - value.forEach(function (v, i) { - scope.set(env.next[name], '[' + i + ']', v) - }) - } else { - scope.set(shared.next, '.' + name, value) - } - }) - - emitProfile(env, scope, args, true, true) - - ;[S_ELEMENTS, S_OFFSET, S_COUNT, S_INSTANCES, S_PRIMITIVE].forEach( - function (opt) { - var variable = args.draw[opt] - if (!variable) { - return - } - scope.set(shared.draw, '.' + opt, '' + variable.append(env, scope)) - }) - - Object.keys(args.uniforms).forEach(function (opt) { - var value = args.uniforms[opt].append(env, scope) - if (Array.isArray(value)) { - value = '[' + value.join() + ']' - } - scope.set( - shared.uniforms, - '[' + stringStore.id(opt) + ']', - value) - }) - - Object.keys(args.attributes).forEach(function (name) { - var record = args.attributes[name].append(env, scope) - var scopeAttrib = env.scopeAttrib(name) - Object.keys(new AttributeRecord()).forEach(function (prop) { - scope.set(scopeAttrib, '.' + prop, record[prop]) - }) - }) - - if (args.scopeVAO) { - scope.set(shared.vao, '.targetVAO', args.scopeVAO.append(env, scope)) - } - - function saveShader (name) { - var shader = args.shader[name] - if (shader) { - scope.set(shared.shader, '.' + name, shader.append(env, scope)) - } - } - saveShader(S_VERT) - saveShader(S_FRAG) - - if (Object.keys(args.state).length > 0) { - scope(CURRENT_STATE, '.dirty=true;') - scope.exit(CURRENT_STATE, '.dirty=true;') - } - - scope('a1(', env.shared.context, ',a0,', env.batchId, ');') - } - - function isDynamicObject (object) { - if (typeof object !== 'object' || isArrayLike(object)) { - return - } - var props = Object.keys(object) - for (var i = 0; i < props.length; ++i) { - if (dynamic.isDynamic(object[props[i]])) { - return true - } - } - return false - } - - function splatObject (env, options, name) { - var object = options.static[name] - if (!object || !isDynamicObject(object)) { - return - } - - var globals = env.global - var keys = Object.keys(object) - var thisDep = false - var contextDep = false - var propDep = false - var objectRef = env.global.def('{}') - keys.forEach(function (key) { - var value = object[key] - if (dynamic.isDynamic(value)) { - if (typeof value === 'function') { - value = object[key] = dynamic.unbox(value) - } - var deps = createDynamicDecl(value, null) - thisDep = thisDep || deps.thisDep - propDep = propDep || deps.propDep - contextDep = contextDep || deps.contextDep - } else { - globals(objectRef, '.', key, '=') - switch (typeof value) { - case 'number': - globals(value) - break - case 'string': - globals('"', value, '"') - break - case 'object': - if (Array.isArray(value)) { - globals('[', value.join(), ']') - } - break - default: - globals(env.link(value)) - break - } - globals(';') - } - }) - - function appendBlock (env, block) { - keys.forEach(function (key) { - var value = object[key] - if (!dynamic.isDynamic(value)) { - return - } - var ref = env.invoke(block, value) - block(objectRef, '.', key, '=', ref, ';') - }) - } - - options.dynamic[name] = new dynamic.DynamicVariable(DYN_THUNK, { - thisDep: thisDep, - contextDep: contextDep, - propDep: propDep, - ref: objectRef, - append: appendBlock - }) - delete options.static[name] - } - - // =========================================================================== - // =========================================================================== - // MAIN DRAW COMMAND - // =========================================================================== - // =========================================================================== - function compileCommand (options, attributes, uniforms, context, stats) { - var env = createREGLEnvironment() - - // link stats, so that we can easily access it in the program. - env.stats = env.link(stats) - - // splat options and attributes to allow for dynamic nested properties - Object.keys(attributes.static).forEach(function (key) { - splatObject(env, attributes, key) - }) - NESTED_OPTIONS.forEach(function (name) { - splatObject(env, options, name) - }) - - var args = parseArguments(options, attributes, uniforms, context, env) - - emitDrawProc(env, args) - emitScopeProc(env, args) - emitBatchProc(env, args) - - return extend(env.compile(), { - destroy: function () { - args.shader.program.destroy() - } - }) - } - - // =========================================================================== - // =========================================================================== - // POLL / REFRESH - // =========================================================================== - // =========================================================================== - return { - next: nextState, - current: currentState, - procs: (function () { - var env = createREGLEnvironment() - var poll = env.proc('poll') - var refresh = env.proc('refresh') - var common = env.block() - poll(common) - refresh(common) - - var shared = env.shared - var GL = shared.gl - var NEXT_STATE = shared.next - var CURRENT_STATE = shared.current - - common(CURRENT_STATE, '.dirty=false;') - - emitPollFramebuffer(env, poll) - emitPollFramebuffer(env, refresh, null, true) - - // Refresh updates all attribute state changes - var INSTANCING - if (extInstancing) { - INSTANCING = env.link(extInstancing) - } - - // update vertex array bindings - if (extensions.oes_vertex_array_object) { - refresh(env.link(extensions.oes_vertex_array_object), '.bindVertexArrayOES(null);') - } - for (var i = 0; i < limits.maxAttributes; ++i) { - var BINDING = refresh.def(shared.attributes, '[', i, ']') - var ifte = env.cond(BINDING, '.buffer') - ifte.then( - GL, '.enableVertexAttribArray(', i, ');', - GL, '.bindBuffer(', - GL_ARRAY_BUFFER$2, ',', - BINDING, '.buffer.buffer);', - GL, '.vertexAttribPointer(', - i, ',', - BINDING, '.size,', - BINDING, '.type,', - BINDING, '.normalized,', - BINDING, '.stride,', - BINDING, '.offset);' - ).else( - GL, '.disableVertexAttribArray(', i, ');', - GL, '.vertexAttrib4f(', - i, ',', - BINDING, '.x,', - BINDING, '.y,', - BINDING, '.z,', - BINDING, '.w);', - BINDING, '.buffer=null;') - refresh(ifte) - if (extInstancing) { - refresh( - INSTANCING, '.vertexAttribDivisorANGLE(', - i, ',', - BINDING, '.divisor);') - } - } - refresh( - env.shared.vao, '.currentVAO=null;', - env.shared.vao, '.setVAO(', env.shared.vao, '.targetVAO);') - - Object.keys(GL_FLAGS).forEach(function (flag) { - var cap = GL_FLAGS[flag] - var NEXT = common.def(NEXT_STATE, '.', flag) - var block = env.block() - block('if(', NEXT, '){', - GL, '.enable(', cap, ')}else{', - GL, '.disable(', cap, ')}', - CURRENT_STATE, '.', flag, '=', NEXT, ';') - refresh(block) - poll( - 'if(', NEXT, '!==', CURRENT_STATE, '.', flag, '){', - block, - '}') - }) - - Object.keys(GL_VARIABLES).forEach(function (name) { - var func = GL_VARIABLES[name] - var init = currentState[name] - var NEXT, CURRENT - var block = env.block() - block(GL, '.', func, '(') - if (isArrayLike(init)) { - var n = init.length - NEXT = env.global.def(NEXT_STATE, '.', name) - CURRENT = env.global.def(CURRENT_STATE, '.', name) - block( - loop(n, function (i) { - return NEXT + '[' + i + ']' - }), ');', - loop(n, function (i) { - return CURRENT + '[' + i + ']=' + NEXT + '[' + i + '];' - }).join('')) - poll( - 'if(', loop(n, function (i) { - return NEXT + '[' + i + ']!==' + CURRENT + '[' + i + ']' - }).join('||'), '){', - block, - '}') - } else { - NEXT = common.def(NEXT_STATE, '.', name) - CURRENT = common.def(CURRENT_STATE, '.', name) - block( - NEXT, ');', - CURRENT_STATE, '.', name, '=', NEXT, ';') - poll( - 'if(', NEXT, '!==', CURRENT, '){', - block, - '}') - } - refresh(block) - }) - - return env.compile() - })(), - compile: compileCommand - } -} - -function stats () { - return { - vaoCount: 0, - bufferCount: 0, - elementsCount: 0, - framebufferCount: 0, - shaderCount: 0, - textureCount: 0, - cubeCount: 0, - renderbufferCount: 0, - maxTextureUnits: 0 - } -} - -var GL_QUERY_RESULT_EXT = 0x8866 -var GL_QUERY_RESULT_AVAILABLE_EXT = 0x8867 -var GL_TIME_ELAPSED_EXT = 0x88BF - -var createTimer = function (gl, extensions) { - if (!extensions.ext_disjoint_timer_query) { - return null - } - - // QUERY POOL BEGIN - var queryPool = [] - function allocQuery () { - return queryPool.pop() || extensions.ext_disjoint_timer_query.createQueryEXT() - } - function freeQuery (query) { - queryPool.push(query) - } - // QUERY POOL END - - var pendingQueries = [] - function beginQuery (stats) { - var query = allocQuery() - extensions.ext_disjoint_timer_query.beginQueryEXT(GL_TIME_ELAPSED_EXT, query) - pendingQueries.push(query) - pushScopeStats(pendingQueries.length - 1, pendingQueries.length, stats) - } - - function endQuery () { - extensions.ext_disjoint_timer_query.endQueryEXT(GL_TIME_ELAPSED_EXT) - } - - // - // Pending stats pool. - // - function PendingStats () { - this.startQueryIndex = -1 - this.endQueryIndex = -1 - this.sum = 0 - this.stats = null - } - var pendingStatsPool = [] - function allocPendingStats () { - return pendingStatsPool.pop() || new PendingStats() - } - function freePendingStats (pendingStats) { - pendingStatsPool.push(pendingStats) - } - // Pending stats pool end - - var pendingStats = [] - function pushScopeStats (start, end, stats) { - var ps = allocPendingStats() - ps.startQueryIndex = start - ps.endQueryIndex = end - ps.sum = 0 - ps.stats = stats - pendingStats.push(ps) - } - - // we should call this at the beginning of the frame, - // in order to update gpuTime - var timeSum = [] - var queryPtr = [] - function update () { - var ptr, i - - var n = pendingQueries.length - if (n === 0) { - return - } - - // Reserve space - queryPtr.length = Math.max(queryPtr.length, n + 1) - timeSum.length = Math.max(timeSum.length, n + 1) - timeSum[0] = 0 - queryPtr[0] = 0 - - // Update all pending timer queries - var queryTime = 0 - ptr = 0 - for (i = 0; i < pendingQueries.length; ++i) { - var query = pendingQueries[i] - if (extensions.ext_disjoint_timer_query.getQueryObjectEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT)) { - queryTime += extensions.ext_disjoint_timer_query.getQueryObjectEXT(query, GL_QUERY_RESULT_EXT) - freeQuery(query) - } else { - pendingQueries[ptr++] = query - } - timeSum[i + 1] = queryTime - queryPtr[i + 1] = ptr - } - pendingQueries.length = ptr - - // Update all pending stat queries - ptr = 0 - for (i = 0; i < pendingStats.length; ++i) { - var stats = pendingStats[i] - var start = stats.startQueryIndex - var end = stats.endQueryIndex - stats.sum += timeSum[end] - timeSum[start] - var startPtr = queryPtr[start] - var endPtr = queryPtr[end] - if (endPtr === startPtr) { - stats.stats.gpuTime += stats.sum / 1e6 - freePendingStats(stats) - } else { - stats.startQueryIndex = startPtr - stats.endQueryIndex = endPtr - pendingStats[ptr++] = stats - } - } - pendingStats.length = ptr - } - - return { - beginQuery: beginQuery, - endQuery: endQuery, - pushScopeStats: pushScopeStats, - update: update, - getNumPendingQueries: function () { - return pendingQueries.length - }, - clear: function () { - queryPool.push.apply(queryPool, pendingQueries) - for (var i = 0; i < queryPool.length; i++) { - extensions.ext_disjoint_timer_query.deleteQueryEXT(queryPool[i]) - } - pendingQueries.length = 0 - queryPool.length = 0 - }, - restore: function () { - pendingQueries.length = 0 - queryPool.length = 0 - } - } -} - -var GL_COLOR_BUFFER_BIT = 16384 -var GL_DEPTH_BUFFER_BIT = 256 -var GL_STENCIL_BUFFER_BIT = 1024 - -var GL_ARRAY_BUFFER = 34962 - -var CONTEXT_LOST_EVENT = 'webglcontextlost' -var CONTEXT_RESTORED_EVENT = 'webglcontextrestored' - -var DYN_PROP = 1 -var DYN_CONTEXT = 2 -var DYN_STATE = 3 - -function find (haystack, needle) { - for (var i = 0; i < haystack.length; ++i) { - if (haystack[i] === needle) { - return i - } - } - return -1 -} - -function wrapREGL (args) { - var config = parseArgs(args) - if (!config) { - return null - } - - var gl = config.gl - var glAttributes = gl.getContextAttributes() - var contextLost = gl.isContextLost() - - var extensionState = createExtensionCache(gl, config) - if (!extensionState) { - return null - } - - var stringStore = createStringStore() - var stats$$1 = stats() - var extensions = extensionState.extensions - var timer = createTimer(gl, extensions) - - var START_TIME = clock() - var WIDTH = gl.drawingBufferWidth - var HEIGHT = gl.drawingBufferHeight - - var contextState = { - tick: 0, - time: 0, - viewportWidth: WIDTH, - viewportHeight: HEIGHT, - framebufferWidth: WIDTH, - framebufferHeight: HEIGHT, - drawingBufferWidth: WIDTH, - drawingBufferHeight: HEIGHT, - pixelRatio: config.pixelRatio - } - var uniformState = {} - var drawState = { - elements: null, - primitive: 4, // GL_TRIANGLES - count: -1, - offset: 0, - instances: -1 - } - - var limits = wrapLimits(gl, extensions) - var bufferState = wrapBufferState( - gl, - stats$$1, - config, - destroyBuffer) - var elementState = wrapElementsState(gl, extensions, bufferState, stats$$1) - var attributeState = wrapAttributeState( - gl, - extensions, - limits, - stats$$1, - bufferState, - elementState, - drawState) - function destroyBuffer (buffer) { - return attributeState.destroyBuffer(buffer) - } - var shaderState = wrapShaderState(gl, stringStore, stats$$1, config) - var textureState = createTextureSet( - gl, - extensions, - limits, - function () { core.procs.poll() }, - contextState, - stats$$1, - config) - var renderbufferState = wrapRenderbuffers(gl, extensions, limits, stats$$1, config) - var framebufferState = wrapFBOState( - gl, - extensions, - limits, - textureState, - renderbufferState, - stats$$1) - var core = reglCore( - gl, - stringStore, - extensions, - limits, - bufferState, - elementState, - textureState, - framebufferState, - uniformState, - attributeState, - shaderState, - drawState, - contextState, - timer, - config) - var readPixels = wrapReadPixels( - gl, - framebufferState, - core.procs.poll, - contextState, - glAttributes, extensions, limits) - - var nextState = core.next - var canvas = gl.canvas - - var rafCallbacks = [] - var lossCallbacks = [] - var restoreCallbacks = [] - var destroyCallbacks = [config.onDestroy] - - var activeRAF = null - function handleRAF () { - if (rafCallbacks.length === 0) { - if (timer) { - timer.update() - } - activeRAF = null - return - } - - // schedule next animation frame - activeRAF = raf.next(handleRAF) - - // poll for changes - poll() - - // fire a callback for all pending rafs - for (var i = rafCallbacks.length - 1; i >= 0; --i) { - var cb = rafCallbacks[i] - if (cb) { - cb(contextState, null, 0) - } - } - - // flush all pending webgl calls - gl.flush() - - // poll GPU timers *after* gl.flush so we don't delay command dispatch - if (timer) { - timer.update() - } - } - - function startRAF () { - if (!activeRAF && rafCallbacks.length > 0) { - activeRAF = raf.next(handleRAF) - } - } - - function stopRAF () { - if (activeRAF) { - raf.cancel(handleRAF) - activeRAF = null - } - } - - function handleContextLoss (event) { - event.preventDefault() - - // set context lost flag - contextLost = true - - // pause request animation frame - stopRAF() - - // lose context - lossCallbacks.forEach(function (cb) { - cb() - }) - } - - function handleContextRestored (event) { - // clear error code - gl.getError() - - // clear context lost flag - contextLost = false - - // refresh state - extensionState.restore() - shaderState.restore() - bufferState.restore() - textureState.restore() - renderbufferState.restore() - framebufferState.restore() - attributeState.restore() - if (timer) { - timer.restore() - } - - // refresh state - core.procs.refresh() - - // restart RAF - startRAF() - - // restore context - restoreCallbacks.forEach(function (cb) { - cb() - }) - } - - if (canvas) { - canvas.addEventListener(CONTEXT_LOST_EVENT, handleContextLoss, false) - canvas.addEventListener(CONTEXT_RESTORED_EVENT, handleContextRestored, false) - } - - function destroy () { - rafCallbacks.length = 0 - stopRAF() - - if (canvas) { - canvas.removeEventListener(CONTEXT_LOST_EVENT, handleContextLoss) - canvas.removeEventListener(CONTEXT_RESTORED_EVENT, handleContextRestored) - } - - shaderState.clear() - framebufferState.clear() - renderbufferState.clear() - attributeState.clear() - textureState.clear() - elementState.clear() - bufferState.clear() - - if (timer) { - timer.clear() - } - - destroyCallbacks.forEach(function (cb) { - cb() - }) - } - - function compileProcedure (options) { - check$1(!!options, 'invalid args to regl({...})') - check$1.type(options, 'object', 'invalid args to regl({...})') - - function flattenNestedOptions (options) { - var result = extend({}, options) - delete result.uniforms - delete result.attributes - delete result.context - delete result.vao - - if ('stencil' in result && result.stencil.op) { - result.stencil.opBack = result.stencil.opFront = result.stencil.op - delete result.stencil.op - } - - function merge (name) { - if (name in result) { - var child = result[name] - delete result[name] - Object.keys(child).forEach(function (prop) { - result[name + '.' + prop] = child[prop] - }) - } - } - merge('blend') - merge('depth') - merge('cull') - merge('stencil') - merge('polygonOffset') - merge('scissor') - merge('sample') - - if ('vao' in options) { - result.vao = options.vao - } - - return result - } - - function separateDynamic (object, useArrays) { - var staticItems = {} - var dynamicItems = {} - Object.keys(object).forEach(function (option) { - var value = object[option] - if (dynamic.isDynamic(value)) { - dynamicItems[option] = dynamic.unbox(value, option) - return - } else if (useArrays && Array.isArray(value)) { - for (var i = 0; i < value.length; ++i) { - if (dynamic.isDynamic(value[i])) { - dynamicItems[option] = dynamic.unbox(value, option) - return - } - } - } - staticItems[option] = value - }) - return { - dynamic: dynamicItems, - static: staticItems - } - } - - // Treat context variables separate from other dynamic variables - var context = separateDynamic(options.context || {}, true) - var uniforms = separateDynamic(options.uniforms || {}, true) - var attributes = separateDynamic(options.attributes || {}, false) - var opts = separateDynamic(flattenNestedOptions(options), false) - - var stats$$1 = { - gpuTime: 0.0, - cpuTime: 0.0, - count: 0 - } - - var compiled = core.compile(opts, attributes, uniforms, context, stats$$1) - - var draw = compiled.draw - var batch = compiled.batch - var scope = compiled.scope - - // FIXME: we should modify code generation for batch commands so this - // isn't necessary - var EMPTY_ARRAY = [] - function reserve (count) { - while (EMPTY_ARRAY.length < count) { - EMPTY_ARRAY.push(null) - } - return EMPTY_ARRAY - } - - function REGLCommand (args, body) { - var i - if (contextLost) { - check$1.raise('context lost') - } - if (typeof args === 'function') { - return scope.call(this, null, args, 0) - } else if (typeof body === 'function') { - if (typeof args === 'number') { - for (i = 0; i < args; ++i) { - scope.call(this, null, body, i) - } - } else if (Array.isArray(args)) { - for (i = 0; i < args.length; ++i) { - scope.call(this, args[i], body, i) - } - } else { - return scope.call(this, args, body, 0) - } - } else if (typeof args === 'number') { - if (args > 0) { - return batch.call(this, reserve(args | 0), args | 0) - } - } else if (Array.isArray(args)) { - if (args.length) { - return batch.call(this, args, args.length) - } - } else { - return draw.call(this, args) - } - } - - return extend(REGLCommand, { - stats: stats$$1, - destroy: function () { - compiled.destroy() - } - }) - } - - var setFBO = framebufferState.setFBO = compileProcedure({ - framebuffer: dynamic.define.call(null, DYN_PROP, 'framebuffer') - }) - - function clearImpl (_, options) { - var clearFlags = 0 - core.procs.poll() - - var c = options.color - if (c) { - gl.clearColor(+c[0] || 0, +c[1] || 0, +c[2] || 0, +c[3] || 0) - clearFlags |= GL_COLOR_BUFFER_BIT - } - if ('depth' in options) { - gl.clearDepth(+options.depth) - clearFlags |= GL_DEPTH_BUFFER_BIT - } - if ('stencil' in options) { - gl.clearStencil(options.stencil | 0) - clearFlags |= GL_STENCIL_BUFFER_BIT - } - - check$1(!!clearFlags, 'called regl.clear with no buffer specified') - gl.clear(clearFlags) - } - - function clear (options) { - check$1( - typeof options === 'object' && options, - 'regl.clear() takes an object as input') - if ('framebuffer' in options) { - if (options.framebuffer && - options.framebuffer_reglType === 'framebufferCube') { - for (var i = 0; i < 6; ++i) { - setFBO(extend({ - framebuffer: options.framebuffer.faces[i] - }, options), clearImpl) - } - } else { - setFBO(options, clearImpl) - } - } else { - clearImpl(null, options) - } - } - - function frame (cb) { - check$1.type(cb, 'function', 'regl.frame() callback must be a function') - rafCallbacks.push(cb) - - function cancel () { - // FIXME: should we check something other than equals cb here? - // what if a user calls frame twice with the same callback... - // - var i = find(rafCallbacks, cb) - check$1(i >= 0, 'cannot cancel a frame twice') - function pendingCancel () { - var index = find(rafCallbacks, pendingCancel) - rafCallbacks[index] = rafCallbacks[rafCallbacks.length - 1] - rafCallbacks.length -= 1 - if (rafCallbacks.length <= 0) { - stopRAF() - } - } - rafCallbacks[i] = pendingCancel - } - - startRAF() - - return { - cancel: cancel - } - } - - // poll viewport - function pollViewport () { - var viewport = nextState.viewport - var scissorBox = nextState.scissor_box - viewport[0] = viewport[1] = scissorBox[0] = scissorBox[1] = 0 - contextState.viewportWidth = - contextState.framebufferWidth = - contextState.drawingBufferWidth = - viewport[2] = - scissorBox[2] = gl.drawingBufferWidth - contextState.viewportHeight = - contextState.framebufferHeight = - contextState.drawingBufferHeight = - viewport[3] = - scissorBox[3] = gl.drawingBufferHeight - } - - function poll () { - contextState.tick += 1 - contextState.time = now() - pollViewport() - core.procs.poll() - } - - function refresh () { - textureState.refresh() - pollViewport() - core.procs.refresh() - if (timer) { - timer.update() - } - } - - function now () { - return (clock() - START_TIME) / 1000.0 - } - - refresh() - - function addListener (event, callback) { - check$1.type(callback, 'function', 'listener callback must be a function') - - var callbacks - switch (event) { - case 'frame': - return frame(callback) - case 'lost': - callbacks = lossCallbacks - break - case 'restore': - callbacks = restoreCallbacks - break - case 'destroy': - callbacks = destroyCallbacks - break - default: - check$1.raise('invalid event, must be one of frame,lost,restore,destroy') - } - - callbacks.push(callback) - return { - cancel: function () { - for (var i = 0; i < callbacks.length; ++i) { - if (callbacks[i] === callback) { - callbacks[i] = callbacks[callbacks.length - 1] - callbacks.pop() - return - } - } - } - } - } - - var regl = extend(compileProcedure, { - // Clear current FBO - clear: clear, - - // Short cuts for dynamic variables - prop: dynamic.define.bind(null, DYN_PROP), - context: dynamic.define.bind(null, DYN_CONTEXT), - this: dynamic.define.bind(null, DYN_STATE), - - // executes an empty draw command - draw: compileProcedure({}), - - // Resources - buffer: function (options) { - return bufferState.create(options, GL_ARRAY_BUFFER, false, false) - }, - elements: function (options) { - return elementState.create(options, false) - }, - texture: textureState.create2D, - cube: textureState.createCube, - renderbuffer: renderbufferState.create, - framebuffer: framebufferState.create, - framebufferCube: framebufferState.createCube, - vao: attributeState.createVAO, - - // Expose context attributes - attributes: glAttributes, - - // Frame rendering - frame: frame, - on: addListener, - - // System limits - limits: limits, - hasExtension: function (name) { - return limits.extensions.indexOf(name.toLowerCase()) >= 0 - }, - - // Read pixels - read: readPixels, - - // Destroy regl and all associated resources - destroy: destroy, - - // Direct GL state manipulation - _gl: gl, - _refresh: refresh, - - poll: function () { - poll() - if (timer) { - timer.update() - } - }, - - // Current time - now: now, - - // regl Statistics Information - stats: stats$$1 - }) - - config.onDone(null, regl) - - return regl -} - -return wrapREGL; - -}))); -//# sourceMappingURL=regl.js.map diff --git a/dist/regl.js.map b/dist/regl.js.map deleted file mode 100644 index 19989870..00000000 --- a/dist/regl.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":null,"sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/dist/regl.min.js b/dist/regl.min.js deleted file mode 100644 index 8b682601..00000000 --- a/dist/regl.min.js +++ /dev/null @@ -1,171 +0,0 @@ -(function(Z,ka){"object"===typeof exports&&"undefined"!==typeof module?module.exports=ka():"function"===typeof define&&define.amd?define(ka):Z.createREGL=ka()})(this,function(){function Z(a,b){this.id=Db++;this.type=a;this.data=b}function ka(a){if(0===a.length)return[];var b=a.charAt(0),c=a.charAt(a.length-1);if(1>>=b;c=(255>>=c;b|=c;c=(15>>=c;b|=c;c=(3>>c>>1}function hb(){function a(a){a:{for(var b=16;268435456>=b;b*=16)if(a<=b){a=b;break a}a=0}b=c[gb(a)>>2];return 0>2].push(a)}var c=R(8,function(){return[]});return{alloc:a,free:b,allocType:function(b,c){var d=null;switch(b){case 5120:d=new Int8Array(a(c),0,c);break;case 5121:d=new Uint8Array(a(c),0,c);break;case 5122:d=new Int16Array(a(2*c),0,c);break;case 5123:d=new Uint16Array(a(2*c),0,c);break;case 5124:d=new Int32Array(a(4*c),0,c);break;case 5125:d=new Uint32Array(a(4*c),0,c);break;case 5126:d=new Float32Array(a(4*c),0,c);break;default:return null}return d.length!== -c?d.subarray(0,c):d},freeType:function(a){b(a.buffer)}}}function la(a){return!!a&&"object"===typeof a&&Array.isArray(a.shape)&&Array.isArray(a.stride)&&"number"===typeof a.offset&&a.shape.length===a.stride.length&&(Array.isArray(a.data)||O(a.data))}function ib(a,b,c,e,f,d){for(var q=0;qe&&(e=d.buffer.byteLength,5123===k?e>>=1:5125===k&&(e>>=2));d.vertCount=e;e=g;0>g&&(e=4,g=d.buffer.dimension,1===g&&(e=0),2===g&&(e=1),3===g&&(e=4));d.primType=e}function q(a){e.elementsCount--;delete n[a.id];a.buffer.destroy();a.buffer=null}var n={},v=0,k={uint8:5121,uint16:5123};b.oes_element_index_uint&&(k.uint32=5125);f.prototype.bind=function(){this.buffer.bind()};var u=[];return{create:function(a, -b){function l(a){if(a)if("number"===typeof a)g(a),h.primType=4,h.vertCount=a|0,h.type=5121;else{var b=null,c=35044,e=-1,f=-1,m=0,n=0;if(Array.isArray(a)||O(a)||la(a))b=a;else if("data"in a&&(b=a.data),"usage"in a&&(c=nb[a.usage]),"primitive"in a&&(e=Ka[a.primitive]),"count"in a&&(f=a.count|0),"type"in a&&(n=k[a.type]),"length"in a)m=a.length|0;else if(m=f,5123===n||5122===n)m*=2;else if(5125===n||5124===n)m*=4;d(h,b,c,e,f,m,n)}else g(),h.primType=4,h.vertCount=0,h.type=5121;return l}var g=c.create(null, -34963,!0),h=new f(g._buffer);e.elementsCount++;l(a);l._reglType="elements";l._elements=h;l.subdata=function(a,b){g.subdata(a,b);return l};l.destroy=function(){q(h)};return l},createStream:function(a){var b=u.pop();b||(b=new f(c.create(null,34963,!0,!1)._buffer));d(b,a,35040,-1,-1,0,0);return b},destroyStream:function(a){u.push(a)},getElements:function(a){return"function"===typeof a&&a._elements instanceof f?a._elements:null},clear:function(){I(n).forEach(q)}}}function ob(a){for(var b=G.allocType(5123, -a.length),c=0;c>>31<<15,d=(e<<1>>>24)-127,e=e>>13&1023;b[c]=-24>d?f:-14>d?f+(e+1024>>-14-d):15>=e,c.height>>=e,x(c,d[e]),a.mipmask|=1<b;++b)a.images[b]=null;return a}function ya(a){for(var b=a.images,c=0;cb){for(var c=0;c=--this.refCount&&F(this)}});q.profile&&(d.getTotalTextureSize=function(){var a=0;Object.keys(ea).forEach(function(b){a+=ea[b].stats.size});return a});return{create2D:function(b,c){function e(a,b){var c=f.texInfo;w.call(c);var d=ma();"number"===typeof a?"number"===typeof b?p(d,a|0,b|0):p(d,a|0,a|0):a?(H(c,a),P(d,a)):p(d,1,1);c.genMipmaps&&(d.mipmask=(d.width<<1)-1);f.mipmask=d.mipmask;v(f, -d);f.internalformat=d.internalformat;e.width=d.width;e.height=d.height;T(f);t(d,3553);M(c,3553);wa();ya(d);q.profile&&(f.stats.size=La(f.internalformat,f.type,d.width,d.height,c.genMipmaps,!1));e.format=ca[f.internalformat];e.type=K[f.type];e.mag=Fa[c.magFilter];e.min=pa[c.minFilter];e.wrapS=qa[c.wrapS];e.wrapT=qa[c.wrapT];return e}var f=new y(3553);ea[f.id]=f;d.textureCount++;e(b,c);e.subimage=function(a,b,c,d){b|=0;c|=0;d|=0;var y=g();v(y,f);y.width=0;y.height=0;x(y,a);y.width=y.width||(f.width>> -d)-b;y.height=y.height||(f.height>>d)-c;T(f);l(y,3553,b,c,d);wa();h(y);return e};e.resize=function(b,c){var d=b|0,g=c|0||d;if(d===f.width&&g===f.height)return e;e.width=f.width=d;e.height=f.height=g;T(f);for(var y=0;f.mipmask>>y;++y){var h=d>>y,z=g>>y;if(!h||!z)break;a.texImage2D(3553,y,f.format,h,z,0,f.format,f.type,null)}wa();q.profile&&(f.stats.size=La(f.internalformat,f.type,d,g,!1,!1));return e};e._reglType="texture2d";e._texture=f;q.profile&&(e.stats=f.stats);e.destroy=function(){f.decRef()}; -return e},createCube:function(b,c,e,f,n,r){function m(a,b,c,d,e,f){var g,da=A.texInfo;w.call(da);for(g=0;6>g;++g)F[g]=ma();if("number"===typeof a||!a)for(a=a|0||1,g=0;6>g;++g)p(F[g],a,a);else if("object"===typeof a)if(b)P(F[0],a),P(F[1],b),P(F[2],c),P(F[3],d),P(F[4],e),P(F[5],f);else if(H(da,a),k(A,a),"faces"in a)for(a=a.faces,g=0;6>g;++g)v(F[g],A),P(F[g],a[g]);else for(g=0;6>g;++g)P(F[g],a);v(A,F[0]);A.mipmask=da.genMipmaps?(F[0].width<<1)-1:F[0].mipmask;A.internalformat=F[0].internalformat;m.width= -F[0].width;m.height=F[0].height;T(A);for(g=0;6>g;++g)t(F[g],34069+g);M(da,34067);wa();q.profile&&(A.stats.size=La(A.internalformat,A.type,m.width,m.height,da.genMipmaps,!0));m.format=ca[A.internalformat];m.type=K[A.type];m.mag=Fa[da.magFilter];m.min=pa[da.minFilter];m.wrapS=qa[da.wrapS];m.wrapT=qa[da.wrapT];for(g=0;6>g;++g)ya(F[g]);return m}var A=new y(34067);ea[A.id]=A;d.cubeCount++;var F=Array(6);m(b,c,e,f,n,r);m.subimage=function(a,b,c,d,e){c|=0;d|=0;e|=0;var f=g();v(f,A);f.width=0;f.height=0; -x(f,b);f.width=f.width||(A.width>>e)-c;f.height=f.height||(A.height>>e)-d;T(A);l(f,34069+a,c,d,e);wa();h(f);return m};m.resize=function(b){b|=0;if(b!==A.width){m.width=A.width=b;m.height=A.height=b;T(A);for(var c=0;6>c;++c)for(var d=0;A.mipmask>>d;++d)a.texImage2D(34069+c,d,A.format,b>>d,b>>d,0,A.format,A.type,null);wa();q.profile&&(A.stats.size=La(A.internalformat,A.type,m.width,m.height,!1,!0));return m}};m._reglType="textureCube";m._texture=A;q.profile&&(m.stats=A.stats);m.destroy=function(){A.decRef()}; -return m},clear:function(){for(var b=0;bc;++c)if(0!==(b.mipmask&1<>c,b.height>>c,0,b.internalformat, -b.type,null);else for(var d=0;6>d;++d)a.texImage2D(34069+d,c,b.internalformat,b.width>>c,b.height>>c,0,b.internalformat,b.type,null);M(b.texInfo,b.target)})},refresh:function(){for(var b=0;bd;++d){for(p= -0;pa;++a)c[a].resize(d);b.width=b.height=d;return b},_reglType:"framebufferCube",destroy:function(){c.forEach(function(a){a.destroy()})}})},clear:function(){I(M).forEach(r)}, -restore:function(){t.cur=null;t.next=null;t.dirty=!0;I(M).forEach(function(b){b.framebuffer=a.createFramebuffer();p(b)})}})}function $a(){this.w=this.z=this.y=this.x=this.state=0;this.buffer=null;this.size=0;this.normalized=!1;this.type=5126;this.divisor=this.stride=this.offset=0}function Sb(a,b,c,e,f,d,q){function n(a){if(a!==r.currentVAO){var c=b.oes_vertex_array_object;a?c.bindVertexArrayOES(a.vao):c.bindVertexArrayOES(null);r.currentVAO=a}}function v(c){if(c!==r.currentVAO){if(c)c.bindAttrs(); -else{for(var d=b.angle_instanced_arrays,e=0;e=m.byteLength?l.subdata(m): -(l.destroy(),c.buffers[h]=null));c.buffers[h]||(l=c.buffers[h]=f.create(p,34962,!1,!0));k.buffer=f.getBuffer(l);k.size=k.buffer.dimension|0;k.normalized=!1;k.type=k.buffer.dtype;k.offset=0;k.stride=0;k.divisor=0;k.state=1;a[h]=1}else f.getBuffer(p)?(k.buffer=f.getBuffer(p),k.size=k.buffer.dimension|0,k.normalized=!1,k.type=k.buffer.dtype,k.offset=0,k.stride=0,k.divisor=0,k.state=1):f.getBuffer(p.buffer)?(k.buffer=f.getBuffer(p.buffer),k.size=(+p.size||k.buffer.dimension)|0,k.normalized=!!p.normalized|| -!1,k.type="type"in p?Ja[p.type]:k.buffer.dtype,k.offset=(p.offset||0)|0,k.stride=(p.stride||0)|0,k.divisor=(p.divisor||0)|0,k.state=1):"x"in p&&(k.x=+p.x||0,k.y=+p.y||0,k.z=+p.z||0,k.w=+p.w||0,k.state=2)}for(l=0;la&&(a=b.stats.uniformsCount)});return a},c.getMaxAttributesCount=function(){var a=0;x.forEach(function(b){b.stats.attributesCount>a&&(a=b.stats.attributesCount)});return a});return{clear:function(){var b=a.deleteShader.bind(a);I(k).forEach(b);k={};I(u).forEach(b); -u={};x.forEach(function(b){a.deleteProgram(b.program)});x.length=0;m={};c.shaderCount=0},program:function(b,d,e,f){var l=m[d];l||(l=m[d]={});var q=l[b];if(q&&(q.refCount++,!f))return q;var w=new n(d,b);c.shaderCount++;v(w,e,f);q||(l[b]=w);x.push(w);return L(w,{destroy:function(){w.refCount--;if(0>=w.refCount){a.deleteProgram(w.program);var b=x.indexOf(w);x.splice(b,1);c.shaderCount--}0>=l[w.vertId].refCount&&(a.deleteShader(u[w.vertId]),delete u[w.vertId],delete m[w.fragId][w.vertId]);Object.keys(m[w.fragId]).length|| -(a.deleteShader(k[w.fragId]),delete k[w.fragId],delete m[w.fragId])}})},restore:function(){k={};u={};for(var a=0;a"+b+"?"+e+".constant["+b+"]:0;"}).join(""),"}}else{","if(",g,"(",e,".buffer)){",k,"=",f,".createStream(",34962,",",e,".buffer);","}else{",k,"=",f,".getBuffer(",e,".buffer);","}",m,'="type" in ',e,"?",z.glTypes,"[",e,".type]:",k,".dtype;",B.normalized,"=!!", -e,".normalized;");d("size");d("offset");d("stride");d("divisor");c("}}");c.exit("if(",B.isStream,"){",f,".destroyStream(",k,");","}");return B})});return g}function F(a){var b=a["static"],c=a.dynamic,d={};Object.keys(b).forEach(function(a){var c=b[a];d[a]=w(function(a,b){return"number"===typeof c||"boolean"===typeof c?""+c:a.link(c)})});Object.keys(c).forEach(function(a){var b=c[a];d[a]=K(b,function(a,c){return a.invoke(c,b)})});return d}function A(a,b,d,e,f){function g(a){var b=p[a];b&&(ja[a]=b)} -var m=O(a,b),l=G(a,f),p=C(a,l,f),X=M(a,f),ja=y(a,f),q=H(a,f,m);g("viewport");g(h("scissor.box"));var n=0>1)",u],");")}function b(){c(t,".drawArraysInstancedANGLE(",[n,q,r,u],");")}p&&"null"!==p?v?a():(c("if(",p,"){"),a(),c("}else{"),b(),c("}")):b()}function g(){function a(){c(l+".drawElements("+[n,r,x,q+"<<(("+x+"-5121)>>1)"]+");")}function b(){c(l+".drawArrays("+[n,q,r]+");")}p&&"null"!==p?v?a():(c("if(",p,"){"),a(),c("}else{"),b(),c("}")):b()}var h=a.shared,l=h.gl,k=h.draw,m=d.draw, -p=function(){var e=m.elements,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f);m.elementsActive&&f("if("+e+")"+l+".bindBuffer(34963,"+e+".buffer.buffer);")}else e=f.def(),f(e,"=",k,".","elements",";","if(",e,"){",l,".bindBuffer(",34963,",",e,".buffer.buffer);}","else if(",h.vao,".currentVAO){",e,"=",a.shared.elements+".getElements("+h.vao,".currentVAO.elements);",na?"":"if("+e+")"+l+".bindBuffer(34963,"+e+".buffer.buffer);","}");return e}(),n=e("primitive"),q=e("offset"), -r=function(){var e=m.count,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f)}else e=f.def(k,".","count");return e}();if("number"===typeof r){if(0===r)return}else c("if(",r,"){"),c.exit("}");var u,t;W&&(u=e("instances"),t=a.instancing);var x=p+".type",v=m.elements&&xa(m.elements)&&!m.vaoActive;W&&("number"!==typeof u||0<=u)?"string"===typeof u?(c("if(",u,">0){"),f(),c("}else if(",u,"<0){"),g(),c("}")):f():g()}function ca(a,b,c,d,e){b=P();e=b.proc("body",e);W&&(b.instancing= -e.def(b.shared.extensions,".angle_instanced_arrays"));a(b,e,c,d);return b.compile().body}function Z(a,b,c,d){N(a,b);c.useVAO?c.drawVAO?b(a.shared.vao,".setVAO(",c.drawVAO.append(a,b),");"):b(a.shared.vao,".setVAO(",a.shared.vao,".targetVAO);"):(b(a.shared.vao,".setVAO(null);"),ga(a,b,c,d.attributes,function(){return!0}));Q(a,b,c,d.uniforms,function(){return!0},!1);U(a,b,b,c)}function Fa(a,b){var c=a.proc("draw",1);N(a,c);ia(a,c,b.context);S(a,c,b.framebuffer);Aa(a,c,b);I(a,c,b.state);E(a,c,b,!1,!0); -var d=b.shader.progVar.append(a,c);c(a.shared.gl,".useProgram(",d,".program);");if(b.shader.program)Z(a,c,b,b.shader.program);else{c(a.shared.vao,".setVAO(null);");var e=a.global.def("{}"),f=c.def(d,".id"),g=c.def(e,"[",f,"]");c(a.cond(g).then(g,".call(this,a0);")["else"](g,"=",e,"[",f,"]=",a.link(function(c){return ca(Z,a,b,c,1)}),"(",d,");",g,".call(this,a0);"))}0=--this.refCount&&q(this)};f.profile&&(e.getTotalRenderbufferSize=function(){var a=0;Object.keys(u).forEach(function(b){a+=u[b].stats.size});return a});return{create:function(b, -c){function l(b,c){var d=0,e=0,k=32854;"object"===typeof b&&b?("shape"in b?(e=b.shape,d=e[0]|0,e=e[1]|0):("radius"in b&&(d=e=b.radius|0),"width"in b&&(d=b.width|0),"height"in b&&(e=b.height|0)),"format"in b&&(k=n[b.format])):"number"===typeof b?(d=b|0,e="number"===typeof c?c|0:d):b||(d=e=1);if(d!==g.width||e!==g.height||k!==g.format)return l.width=g.width=d,l.height=g.height=e,g.format=k,a.bindRenderbuffer(36161,g.renderbuffer),a.renderbufferStorage(36161,k,d,e),f.profile&&(g.stats.size=Q[g.format]* -g.width*g.height),l.format=v[g.format],l}var g=new d(a.createRenderbuffer());u[g.id]=g;e.renderbufferCount++;l(b,c);l.resize=function(b,c){var d=b|0,e=c|0||d;if(d===g.width&&e===g.height)return l;l.width=g.width=d;l.height=g.height=e;a.bindRenderbuffer(36161,g.renderbuffer);a.renderbufferStorage(36161,g.format,d,e);f.profile&&(g.stats.size=Q[g.format]*g.width*g.height);return l};l._reglType="renderbuffer";l._renderbuffer=g;f.profile&&(l.stats=g.stats);l.destroy=function(){g.decRef()};return l},clear:function(){I(u).forEach(q)}, -restore:function(){I(u).forEach(function(b){b.renderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,b.renderbuffer);a.renderbufferStorage(36161,b.format,b.width,b.height)});a.bindRenderbuffer(36161,null)}}},Za=[];Za[6408]=4;Za[6407]=3;var Ra=[];Ra[5121]=1;Ra[5126]=4;Ra[36193]=2;var Da=["x","y","z","w"],Xb="blend.func blend.equation stencil.func stencil.opFront stencil.opBack sample.coverage viewport scissor.box polygonOffset.offset".split(" "),Ga={0:0,1:1,zero:0,one:1,"src color":768,"one minus src color":769, -"src alpha":770,"one minus src alpha":771,"dst color":774,"one minus dst color":775,"dst alpha":772,"one minus dst alpha":773,"constant color":32769,"one minus constant color":32770,"constant alpha":32771,"one minus constant alpha":32772,"src alpha saturate":776},ab={never:512,less:513,"<":513,equal:514,"=":514,"==":514,"===":514,lequal:515,"<=":515,greater:516,">":516,notequal:517,"!=":517,"!==":517,gequal:518,">=":518,always:519},Ta={0:0,zero:0,keep:7680,replace:7681,increment:7682,decrement:7683, -"increment wrap":34055,"decrement wrap":34056,invert:5386},zb={cw:2304,ccw:2305},Ab=new J(!1,!1,!1,function(){}),$b=function(a,b){function c(){this.endQueryIndex=this.startQueryIndex=-1;this.sum=0;this.stats=null}function e(a,b,d){var e=q.pop()||new c;e.startQueryIndex=a;e.endQueryIndex=b;e.sum=0;e.stats=d;n.push(e)}if(!b.ext_disjoint_timer_query)return null;var f=[],d=[],q=[],n=[],v=[],k=[];return{beginQuery:function(a){var c=f.pop()||b.ext_disjoint_timer_query.createQueryEXT();b.ext_disjoint_timer_query.beginQueryEXT(35007, -c);d.push(c);e(d.length-1,d.length,a)},endQuery:function(){b.ext_disjoint_timer_query.endQueryEXT(35007)},pushScopeStats:e,update:function(){var a,c;a=d.length;if(0!==a){k.length=Math.max(k.length,a+1);v.length=Math.max(v.length,a+1);v[0]=0;var e=k[0]=0;for(c=a=0;c=E.length&&e()}var c=Bb(E,a);E[c]=b}}}function k(){var a=Q.viewport,b=Q.scissor_box;a[0]=a[1]=b[0]=b[1]=0;H.viewportWidth=H.framebufferWidth=H.drawingBufferWidth=a[2]=b[2]=l.drawingBufferWidth;H.viewportHeight=H.framebufferHeight=H.drawingBufferHeight=a[3]=b[3]=l.drawingBufferHeight}function u(){H.tick+=1;H.time=x();k();I.procs.poll()}function m(){A.refresh();k();I.procs.refresh();t&&t.update()}function x(){return(Cb()- -G)/1E3}a=Hb(a);if(!a)return null;var l=a.gl,g=l.getContextAttributes();l.isContextLost();var h=Ib(l,a);if(!h)return null;var r=Eb(),p={vaoCount:0,bufferCount:0,elementsCount:0,framebufferCount:0,shaderCount:0,textureCount:0,cubeCount:0,renderbufferCount:0,maxTextureUnits:0},w=h.extensions,t=$b(l,w),G=Cb(),C=l.drawingBufferWidth,J=l.drawingBufferHeight,H={tick:0,time:0,viewportWidth:C,viewportHeight:J,framebufferWidth:C,framebufferHeight:J,drawingBufferWidth:C,drawingBufferHeight:J,pixelRatio:a.pixelRatio}, -C={elements:null,primitive:4,count:-1,offset:0,instances:-1},M=Yb(l,w),y=Jb(l,p,a,function(a){return K.destroyBuffer(a)}),T=Kb(l,w,y,p),K=Sb(l,w,M,p,y,T,C),F=Tb(l,r,p,a),A=Nb(l,w,M,function(){I.procs.poll()},H,p,a),O=Zb(l,w,M,p,a),S=Rb(l,w,M,A,O,p),I=Wb(l,r,w,M,y,T,A,S,{},K,F,C,H,t,a),r=Ub(l,S,I.procs.poll,H,g,w,M),Q=I.next,N=l.canvas,E=[],R=[],U=[],Z=[a.onDestroy],ca=null;N&&(N.addEventListener("webglcontextlost",f,!1),N.addEventListener("webglcontextrestored",d,!1));var aa=S.setFBO=q({framebuffer:Y.define.call(null, -1,"framebuffer")});m();g=L(q,{clear:function(a){if("framebuffer"in a)if(a.framebuffer&&"framebufferCube"===a.framebuffer_reglType)for(var b=0;6>b;++b)aa(L({framebuffer:a.framebuffer.faces[b]},a),n);else aa(a,n);else n(null,a)},prop:Y.define.bind(null,1),context:Y.define.bind(null,2),"this":Y.define.bind(null,3),draw:q({}),buffer:function(a){return y.create(a,34962,!1,!1)},elements:function(a){return T.create(a,!1)},texture:A.create2D,cube:A.createCube,renderbuffer:O.create,framebuffer:S.create,framebufferCube:S.createCube, -vao:K.createVAO,attributes:g,frame:v,on:function(a,b){var c;switch(a){case "frame":return v(b);case "lost":c=R;break;case "restore":c=U;break;case "destroy":c=Z}c.push(b);return{cancel:function(){for(var a=0;a 1 && - firstChar === lastChar && - (firstChar === '"' || firstChar === "'")) { - return ['"' + escapeStr(str.substr(1, str.length - 2)) + '"'] - } - - var parts = /\[(false|true|null|\d+|'[^']*'|"[^"]*")\]/.exec(str) - if (parts) { - return ( - splitParts(str.substr(0, parts.index)) - .concat(splitParts(parts[1])) - .concat(splitParts(str.substr(parts.index + parts[0].length))) - ) - } - - var subparts = str.split('.') - if (subparts.length === 1) { - return ['"' + escapeStr(str) + '"'] - } - - var result = [] - for (var i = 0; i < subparts.length; ++i) { - result = result.concat(splitParts(subparts[i])) - } - return result -} - -function toAccessorString (str) { - return '[' + splitParts(str).join('][') + ']' -} - -function defineDynamic (type, data) { - return new DynamicVariable(type, toAccessorString(data + '')) -} - -function isDynamic (x) { - return (typeof x === 'function' && !x._reglType) || (x instanceof DynamicVariable) -} - -function unbox (x, path) { - if (typeof x === 'function') { - return new DynamicVariable(DYN_FUNC, x) - } else if (typeof x === 'number' || typeof x === 'boolean') { - return new DynamicVariable(DYN_CONSTANT, x) - } else if (Array.isArray(x)) { - return new DynamicVariable(DYN_ARRAY, x.map(function (y, i) { return unbox(y, path + '[' + i + ']') })) - } else if (x instanceof DynamicVariable) { - return x - } - -} - -var dynamic = { - DynamicVariable: DynamicVariable, - define: defineDynamic, - isDynamic: isDynamic, - unbox: unbox, - accessor: toAccessorString -}; - -/* globals requestAnimationFrame, cancelAnimationFrame */ -var raf = { - next: typeof requestAnimationFrame === 'function' - ? function (cb) { return requestAnimationFrame(cb) } - : function (cb) { return setTimeout(cb, 16) }, - cancel: typeof cancelAnimationFrame === 'function' - ? function (raf) { return cancelAnimationFrame(raf) } - : clearTimeout -}; - -/* globals performance */ -var clock = (typeof performance !== 'undefined' && performance.now) - ? function () { return performance.now() } - : function () { return +(new Date()) }; - -function createStringStore () { - var stringIds = { '': 0 } - var stringValues = [''] - return { - id: function (str) { - var result = stringIds[str] - if (result) { - return result - } - result = stringIds[str] = stringValues.length - stringValues.push(str) - return result - }, - - str: function (id) { - return stringValues[id] - } - } -} - -// Context and canvas creation helper functions - -function createCanvas (element, onDone, pixelRatio) { - var canvas = document.createElement('canvas') - extend(canvas.style, { - border: 0, - margin: 0, - padding: 0, - top: 0, - left: 0, - width: '100%', - height: '100%' - }) - element.appendChild(canvas) - - if (element === document.body) { - canvas.style.position = 'absolute' - extend(element.style, { - margin: 0, - padding: 0 - }) - } - - function resize () { - var w = window.innerWidth - var h = window.innerHeight - if (element !== document.body) { - var bounds = canvas.getBoundingClientRect() - w = bounds.right - bounds.left - h = bounds.bottom - bounds.top - } - canvas.width = pixelRatio * w - canvas.height = pixelRatio * h - } - - var resizeObserver - if (element !== document.body && typeof ResizeObserver === 'function') { - // ignore 'ResizeObserver' is not defined - // eslint-disable-next-line - resizeObserver = new ResizeObserver(function () { - // setTimeout to avoid flicker - setTimeout(resize) - }) - resizeObserver.observe(element) - } else { - window.addEventListener('resize', resize, false) - } - - function onDestroy () { - if (resizeObserver) { - resizeObserver.disconnect() - } else { - window.removeEventListener('resize', resize) - } - element.removeChild(canvas) - } - - resize() - - return { - canvas: canvas, - onDestroy: onDestroy - } -} - -function createContext (canvas, contextAttributes) { - function get (name) { - try { - return canvas.getContext(name, contextAttributes) - } catch (e) { - return null - } - } - return ( - get('webgl') || - get('experimental-webgl') || - get('webgl-experimental') - ) -} - -function isHTMLElement (obj) { - return ( - typeof obj.nodeName === 'string' && - typeof obj.appendChild === 'function' && - typeof obj.getBoundingClientRect === 'function' - ) -} - -function isWebGLContext (obj) { - return ( - typeof obj.drawArrays === 'function' || - typeof obj.drawElements === 'function' - ) -} - -function parseExtensions (input) { - if (typeof input === 'string') { - return input.split() - } - - return input -} - -function getElement (desc) { - if (typeof desc === 'string') { - - return document.querySelector(desc) - } - return desc -} - -function parseArgs (args_) { - var args = args_ || {} - var element, container, canvas, gl - var contextAttributes = {} - var extensions = [] - var optionalExtensions = [] - var pixelRatio = (typeof window === 'undefined' ? 1 : window.devicePixelRatio) - var profile = false - var onDone = function (err) { - if (err) { - - } - } - var onDestroy = function () {} - if (typeof args === 'string') { - - element = document.querySelector(args) - - } else if (typeof args === 'object') { - if (isHTMLElement(args)) { - element = args - } else if (isWebGLContext(args)) { - gl = args - canvas = gl.canvas - } else { - - if ('gl' in args) { - gl = args.gl - } else if ('canvas' in args) { - canvas = getElement(args.canvas) - } else if ('container' in args) { - container = getElement(args.container) - } - if ('attributes' in args) { - contextAttributes = args.attributes - - } - if ('extensions' in args) { - extensions = parseExtensions(args.extensions) - } - if ('optionalExtensions' in args) { - optionalExtensions = parseExtensions(args.optionalExtensions) - } - if ('onDone' in args) { - - onDone = args.onDone - } - if ('profile' in args) { - profile = !!args.profile - } - if ('pixelRatio' in args) { - pixelRatio = +args.pixelRatio - - } - } - } else { - - } - - if (element) { - if (element.nodeName.toLowerCase() === 'canvas') { - canvas = element - } else { - container = element - } - } - - if (!gl) { - if (!canvas) { - - var result = createCanvas(container || document.body, onDone, pixelRatio) - if (!result) { - return null - } - canvas = result.canvas - onDestroy = result.onDestroy - } - // workaround for chromium bug, premultiplied alpha value is platform dependent - if (contextAttributes.premultipliedAlpha === undefined) contextAttributes.premultipliedAlpha = true - gl = createContext(canvas, contextAttributes) - } - - if (!gl) { - onDestroy() - onDone('webgl not supported, try upgrading your browser or graphics drivers http://get.webgl.org') - return null - } - - return { - gl: gl, - canvas: canvas, - container: container, - extensions: extensions, - optionalExtensions: optionalExtensions, - pixelRatio: pixelRatio, - profile: profile, - onDone: onDone, - onDestroy: onDestroy - } -} - -function createExtensionCache (gl, config) { - var extensions = {} - - function tryLoadExtension (name_) { - - var name = name_.toLowerCase() - var ext - try { - ext = extensions[name] = gl.getExtension(name) - } catch (e) {} - return !!ext - } - - for (var i = 0; i < config.extensions.length; ++i) { - var name = config.extensions[i] - if (!tryLoadExtension(name)) { - config.onDestroy() - config.onDone('"' + name + '" extension is not supported by the current WebGL context, try upgrading your system or a different browser') - return null - } - } - - config.optionalExtensions.forEach(tryLoadExtension) - - return { - extensions: extensions, - restore: function () { - Object.keys(extensions).forEach(function (name) { - if (extensions[name] && !tryLoadExtension(name)) { - throw new Error('(regl): error restoring extension ' + name) - } - }) - } - } -} - -function loop (n, f) { - var result = Array(n) - for (var i = 0; i < n; ++i) { - result[i] = f(i) - } - return result -} - -var GL_BYTE = 5120 -var GL_UNSIGNED_BYTE$1 = 5121 -var GL_SHORT = 5122 -var GL_UNSIGNED_SHORT = 5123 -var GL_INT = 5124 -var GL_UNSIGNED_INT = 5125 -var GL_FLOAT$1 = 5126 - -function nextPow16 (v) { - for (var i = 16; i <= (1 << 28); i *= 16) { - if (v <= i) { - return i - } - } - return 0 -} - -function log2 (v) { - var r, shift - r = (v > 0xFFFF) << 4 - v >>>= r - shift = (v > 0xFF) << 3 - v >>>= shift; r |= shift - shift = (v > 0xF) << 2 - v >>>= shift; r |= shift - shift = (v > 0x3) << 1 - v >>>= shift; r |= shift - return r | (v >> 1) -} - -function createPool () { - var bufferPool = loop(8, function () { - return [] - }) - - function alloc (n) { - var sz = nextPow16(n) - var bin = bufferPool[log2(sz) >> 2] - if (bin.length > 0) { - return bin.pop() - } - return new ArrayBuffer(sz) - } - - function free (buf) { - bufferPool[log2(buf.byteLength) >> 2].push(buf) - } - - function allocType (type, n) { - var result = null - switch (type) { - case GL_BYTE: - result = new Int8Array(alloc(n), 0, n) - break - case GL_UNSIGNED_BYTE$1: - result = new Uint8Array(alloc(n), 0, n) - break - case GL_SHORT: - result = new Int16Array(alloc(2 * n), 0, n) - break - case GL_UNSIGNED_SHORT: - result = new Uint16Array(alloc(2 * n), 0, n) - break - case GL_INT: - result = new Int32Array(alloc(4 * n), 0, n) - break - case GL_UNSIGNED_INT: - result = new Uint32Array(alloc(4 * n), 0, n) - break - case GL_FLOAT$1: - result = new Float32Array(alloc(4 * n), 0, n) - break - default: - return null - } - if (result.length !== n) { - return result.subarray(0, n) - } - return result - } - - function freeType (array) { - free(array.buffer) - } - - return { - alloc: alloc, - free: free, - allocType: allocType, - freeType: freeType - } -} - -var pool = createPool() - -// zero pool for initial zero data -pool.zero = createPool() - -var GL_SUBPIXEL_BITS = 0x0D50 -var GL_RED_BITS = 0x0D52 -var GL_GREEN_BITS = 0x0D53 -var GL_BLUE_BITS = 0x0D54 -var GL_ALPHA_BITS = 0x0D55 -var GL_DEPTH_BITS = 0x0D56 -var GL_STENCIL_BITS = 0x0D57 - -var GL_ALIASED_POINT_SIZE_RANGE = 0x846D -var GL_ALIASED_LINE_WIDTH_RANGE = 0x846E - -var GL_MAX_TEXTURE_SIZE = 0x0D33 -var GL_MAX_VIEWPORT_DIMS = 0x0D3A -var GL_MAX_VERTEX_ATTRIBS = 0x8869 -var GL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB -var GL_MAX_VARYING_VECTORS = 0x8DFC -var GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D -var GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C -var GL_MAX_TEXTURE_IMAGE_UNITS = 0x8872 -var GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD -var GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C -var GL_MAX_RENDERBUFFER_SIZE = 0x84E8 - -var GL_VENDOR = 0x1F00 -var GL_RENDERER = 0x1F01 -var GL_VERSION = 0x1F02 -var GL_SHADING_LANGUAGE_VERSION = 0x8B8C - -var GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF - -var GL_MAX_COLOR_ATTACHMENTS_WEBGL = 0x8CDF -var GL_MAX_DRAW_BUFFERS_WEBGL = 0x8824 - -var GL_TEXTURE_2D = 0x0DE1 -var GL_TEXTURE_CUBE_MAP = 0x8513 -var GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515 -var GL_TEXTURE0 = 0x84C0 -var GL_RGBA = 0x1908 -var GL_FLOAT = 0x1406 -var GL_UNSIGNED_BYTE = 0x1401 -var GL_FRAMEBUFFER = 0x8D40 -var GL_FRAMEBUFFER_COMPLETE = 0x8CD5 -var GL_COLOR_ATTACHMENT0 = 0x8CE0 -var GL_COLOR_BUFFER_BIT$1 = 0x4000 - -var wrapLimits = function (gl, extensions) { - var maxAnisotropic = 1 - if (extensions.ext_texture_filter_anisotropic) { - maxAnisotropic = gl.getParameter(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) - } - - var maxDrawbuffers = 1 - var maxColorAttachments = 1 - if (extensions.webgl_draw_buffers) { - maxDrawbuffers = gl.getParameter(GL_MAX_DRAW_BUFFERS_WEBGL) - maxColorAttachments = gl.getParameter(GL_MAX_COLOR_ATTACHMENTS_WEBGL) - } - - // detect if reading float textures is available (Safari doesn't support) - var readFloat = !!extensions.oes_texture_float - if (readFloat) { - var readFloatTexture = gl.createTexture() - gl.bindTexture(GL_TEXTURE_2D, readFloatTexture) - gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_FLOAT, null) - - var fbo = gl.createFramebuffer() - gl.bindFramebuffer(GL_FRAMEBUFFER, fbo) - gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, readFloatTexture, 0) - gl.bindTexture(GL_TEXTURE_2D, null) - - if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) !== GL_FRAMEBUFFER_COMPLETE) readFloat = false - - else { - gl.viewport(0, 0, 1, 1) - gl.clearColor(1.0, 0.0, 0.0, 1.0) - gl.clear(GL_COLOR_BUFFER_BIT$1) - var pixels = pool.allocType(GL_FLOAT, 4) - gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, pixels) - - if (gl.getError()) readFloat = false - else { - gl.deleteFramebuffer(fbo) - gl.deleteTexture(readFloatTexture) - - readFloat = pixels[0] === 1.0 - } - - pool.freeType(pixels) - } - } - - // detect non power of two cube textures support (IE doesn't support) - var isIE = typeof navigator !== 'undefined' && (/MSIE/.test(navigator.userAgent) || /Trident\//.test(navigator.appVersion) || /Edge/.test(navigator.userAgent)) - - var npotTextureCube = true - - if (!isIE) { - var cubeTexture = gl.createTexture() - var data = pool.allocType(GL_UNSIGNED_BYTE, 36) - gl.activeTexture(GL_TEXTURE0) - gl.bindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture) - gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, data) - pool.freeType(data) - gl.bindTexture(GL_TEXTURE_CUBE_MAP, null) - gl.deleteTexture(cubeTexture) - npotTextureCube = !gl.getError() - } - - return { - // drawing buffer bit depth - colorBits: [ - gl.getParameter(GL_RED_BITS), - gl.getParameter(GL_GREEN_BITS), - gl.getParameter(GL_BLUE_BITS), - gl.getParameter(GL_ALPHA_BITS) - ], - depthBits: gl.getParameter(GL_DEPTH_BITS), - stencilBits: gl.getParameter(GL_STENCIL_BITS), - subpixelBits: gl.getParameter(GL_SUBPIXEL_BITS), - - // supported extensions - extensions: Object.keys(extensions).filter(function (ext) { - return !!extensions[ext] - }), - - // max aniso samples - maxAnisotropic: maxAnisotropic, - - // max draw buffers - maxDrawbuffers: maxDrawbuffers, - maxColorAttachments: maxColorAttachments, - - // point and line size ranges - pointSizeDims: gl.getParameter(GL_ALIASED_POINT_SIZE_RANGE), - lineWidthDims: gl.getParameter(GL_ALIASED_LINE_WIDTH_RANGE), - maxViewportDims: gl.getParameter(GL_MAX_VIEWPORT_DIMS), - maxCombinedTextureUnits: gl.getParameter(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS), - maxCubeMapSize: gl.getParameter(GL_MAX_CUBE_MAP_TEXTURE_SIZE), - maxRenderbufferSize: gl.getParameter(GL_MAX_RENDERBUFFER_SIZE), - maxTextureUnits: gl.getParameter(GL_MAX_TEXTURE_IMAGE_UNITS), - maxTextureSize: gl.getParameter(GL_MAX_TEXTURE_SIZE), - maxAttributes: gl.getParameter(GL_MAX_VERTEX_ATTRIBS), - maxVertexUniforms: gl.getParameter(GL_MAX_VERTEX_UNIFORM_VECTORS), - maxVertexTextureUnits: gl.getParameter(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS), - maxVaryingVectors: gl.getParameter(GL_MAX_VARYING_VECTORS), - maxFragmentUniforms: gl.getParameter(GL_MAX_FRAGMENT_UNIFORM_VECTORS), - - // vendor info - glsl: gl.getParameter(GL_SHADING_LANGUAGE_VERSION), - renderer: gl.getParameter(GL_RENDERER), - vendor: gl.getParameter(GL_VENDOR), - version: gl.getParameter(GL_VERSION), - - // quirks - readFloat: readFloat, - npotTextureCube: npotTextureCube - } -} - -var isTypedArray = function (x) { - return ( - x instanceof Uint8Array || - x instanceof Uint16Array || - x instanceof Uint32Array || - x instanceof Int8Array || - x instanceof Int16Array || - x instanceof Int32Array || - x instanceof Float32Array || - x instanceof Float64Array || - x instanceof Uint8ClampedArray - ) -} - -function isNDArrayLike (obj) { - return ( - !!obj && - typeof obj === 'object' && - Array.isArray(obj.shape) && - Array.isArray(obj.stride) && - typeof obj.offset === 'number' && - obj.shape.length === obj.stride.length && - (Array.isArray(obj.data) || - isTypedArray(obj.data))) -} - -var values = function (obj) { - return Object.keys(obj).map(function (key) { return obj[key] }) -} - -var flattenUtils = { - shape: arrayShape$1, - flatten: flattenArray -}; - -function flatten1D (array, nx, out) { - for (var i = 0; i < nx; ++i) { - out[i] = array[i] - } -} - -function flatten2D (array, nx, ny, out) { - var ptr = 0 - for (var i = 0; i < nx; ++i) { - var row = array[i] - for (var j = 0; j < ny; ++j) { - out[ptr++] = row[j] - } - } -} - -function flatten3D (array, nx, ny, nz, out, ptr_) { - var ptr = ptr_ - for (var i = 0; i < nx; ++i) { - var row = array[i] - for (var j = 0; j < ny; ++j) { - var col = row[j] - for (var k = 0; k < nz; ++k) { - out[ptr++] = col[k] - } - } - } -} - -function flattenRec (array, shape, level, out, ptr) { - var stride = 1 - for (var i = level + 1; i < shape.length; ++i) { - stride *= shape[i] - } - var n = shape[level] - if (shape.length - level === 4) { - var nx = shape[level + 1] - var ny = shape[level + 2] - var nz = shape[level + 3] - for (i = 0; i < n; ++i) { - flatten3D(array[i], nx, ny, nz, out, ptr) - ptr += stride - } - } else { - for (i = 0; i < n; ++i) { - flattenRec(array[i], shape, level + 1, out, ptr) - ptr += stride - } - } -} - -function flattenArray (array, shape, type, out_) { - var sz = 1 - if (shape.length) { - for (var i = 0; i < shape.length; ++i) { - sz *= shape[i] - } - } else { - sz = 0 - } - var out = out_ || pool.allocType(type, sz) - switch (shape.length) { - case 0: - break - case 1: - flatten1D(array, shape[0], out) - break - case 2: - flatten2D(array, shape[0], shape[1], out) - break - case 3: - flatten3D(array, shape[0], shape[1], shape[2], out, 0) - break - default: - flattenRec(array, shape, 0, out, 0) - } - return out -} - -function arrayShape$1 (array_) { - var shape = [] - for (var array = array_; array.length; array = array[0]) { - shape.push(array.length) - } - return shape -} - -var arrayTypes = { - "[object Int8Array]": 5120, - "[object Int16Array]": 5122, - "[object Int32Array]": 5124, - "[object Uint8Array]": 5121, - "[object Uint8ClampedArray]": 5121, - "[object Uint16Array]": 5123, - "[object Uint32Array]": 5125, - "[object Float32Array]": 5126, - "[object Float64Array]": 5121, - "[object ArrayBuffer]": 5121 -}; - -var int8 = 5120; -var int16 = 5122; -var int32 = 5124; -var uint8 = 5121; -var uint16 = 5123; -var uint32 = 5125; -var float = 5126; -var float32 = 5126; -var glTypes = { - int8: int8, - int16: int16, - int32: int32, - uint8: uint8, - uint16: uint16, - uint32: uint32, - float: float, - float32: float32 -}; - -var dynamic$1 = 35048; -var stream = 35040; -var usageTypes = { - dynamic: dynamic$1, - stream: stream, - "static": 35044 -}; - -var arrayFlatten = flattenUtils.flatten -var arrayShape = flattenUtils.shape - -var GL_STATIC_DRAW = 0x88E4 -var GL_STREAM_DRAW = 0x88E0 - -var GL_UNSIGNED_BYTE$2 = 5121 -var GL_FLOAT$2 = 5126 - -var DTYPES_SIZES = [] -DTYPES_SIZES[5120] = 1 // int8 -DTYPES_SIZES[5122] = 2 // int16 -DTYPES_SIZES[5124] = 4 // int32 -DTYPES_SIZES[5121] = 1 // uint8 -DTYPES_SIZES[5123] = 2 // uint16 -DTYPES_SIZES[5125] = 4 // uint32 -DTYPES_SIZES[5126] = 4 // float32 - -function typedArrayCode (data) { - return arrayTypes[Object.prototype.toString.call(data)] | 0 -} - -function copyArray (out, inp) { - for (var i = 0; i < inp.length; ++i) { - out[i] = inp[i] - } -} - -function transpose ( - result, data, shapeX, shapeY, strideX, strideY, offset) { - var ptr = 0 - for (var i = 0; i < shapeX; ++i) { - for (var j = 0; j < shapeY; ++j) { - result[ptr++] = data[strideX * i + strideY * j + offset] - } - } -} - -function wrapBufferState (gl, stats, config, destroyBuffer) { - var bufferCount = 0 - var bufferSet = {} - - function REGLBuffer (type) { - this.id = bufferCount++ - this.buffer = gl.createBuffer() - this.type = type - this.usage = GL_STATIC_DRAW - this.byteLength = 0 - this.dimension = 1 - this.dtype = GL_UNSIGNED_BYTE$2 - - this.persistentData = null - - if (config.profile) { - this.stats = { size: 0 } - } - } - - REGLBuffer.prototype.bind = function () { - gl.bindBuffer(this.type, this.buffer) - } - - REGLBuffer.prototype.destroy = function () { - destroy(this) - } - - var streamPool = [] - - function createStream (type, data) { - var buffer = streamPool.pop() - if (!buffer) { - buffer = new REGLBuffer(type) - } - buffer.bind() - initBufferFromData(buffer, data, GL_STREAM_DRAW, 0, 1, false) - return buffer - } - - function destroyStream (stream$$1) { - streamPool.push(stream$$1) - } - - function initBufferFromTypedArray (buffer, data, usage) { - buffer.byteLength = data.byteLength - gl.bufferData(buffer.type, data, usage) - } - - function initBufferFromData (buffer, data, usage, dtype, dimension, persist) { - var shape - buffer.usage = usage - if (Array.isArray(data)) { - buffer.dtype = dtype || GL_FLOAT$2 - if (data.length > 0) { - var flatData - if (Array.isArray(data[0])) { - shape = arrayShape(data) - var dim = 1 - for (var i = 1; i < shape.length; ++i) { - dim *= shape[i] - } - buffer.dimension = dim - flatData = arrayFlatten(data, shape, buffer.dtype) - initBufferFromTypedArray(buffer, flatData, usage) - if (persist) { - buffer.persistentData = flatData - } else { - pool.freeType(flatData) - } - } else if (typeof data[0] === 'number') { - buffer.dimension = dimension - var typedData = pool.allocType(buffer.dtype, data.length) - copyArray(typedData, data) - initBufferFromTypedArray(buffer, typedData, usage) - if (persist) { - buffer.persistentData = typedData - } else { - pool.freeType(typedData) - } - } else if (isTypedArray(data[0])) { - buffer.dimension = data[0].length - buffer.dtype = dtype || typedArrayCode(data[0]) || GL_FLOAT$2 - flatData = arrayFlatten( - data, - [data.length, data[0].length], - buffer.dtype) - initBufferFromTypedArray(buffer, flatData, usage) - if (persist) { - buffer.persistentData = flatData - } else { - pool.freeType(flatData) - } - } else { - - } - } - } else if (isTypedArray(data)) { - buffer.dtype = dtype || typedArrayCode(data) - buffer.dimension = dimension - initBufferFromTypedArray(buffer, data, usage) - if (persist) { - buffer.persistentData = new Uint8Array(new Uint8Array(data.buffer)) - } - } else if (isNDArrayLike(data)) { - shape = data.shape - var stride = data.stride - var offset = data.offset - - var shapeX = 0 - var shapeY = 0 - var strideX = 0 - var strideY = 0 - if (shape.length === 1) { - shapeX = shape[0] - shapeY = 1 - strideX = stride[0] - strideY = 0 - } else if (shape.length === 2) { - shapeX = shape[0] - shapeY = shape[1] - strideX = stride[0] - strideY = stride[1] - } else { - - } - - buffer.dtype = dtype || typedArrayCode(data.data) || GL_FLOAT$2 - buffer.dimension = shapeY - - var transposeData = pool.allocType(buffer.dtype, shapeX * shapeY) - transpose(transposeData, - data.data, - shapeX, shapeY, - strideX, strideY, - offset) - initBufferFromTypedArray(buffer, transposeData, usage) - if (persist) { - buffer.persistentData = transposeData - } else { - pool.freeType(transposeData) - } - } else if (data instanceof ArrayBuffer) { - buffer.dtype = GL_UNSIGNED_BYTE$2 - buffer.dimension = dimension - initBufferFromTypedArray(buffer, data, usage) - if (persist) { - buffer.persistentData = new Uint8Array(new Uint8Array(data)) - } - } else { - - } - } - - function destroy (buffer) { - stats.bufferCount-- - - // remove attribute link - destroyBuffer(buffer) - - var handle = buffer.buffer - - gl.deleteBuffer(handle) - buffer.buffer = null - delete bufferSet[buffer.id] - } - - function createBuffer (options, type, deferInit, persistent) { - stats.bufferCount++ - - var buffer = new REGLBuffer(type) - bufferSet[buffer.id] = buffer - - function reglBuffer (options) { - var usage = GL_STATIC_DRAW - var data = null - var byteLength = 0 - var dtype = 0 - var dimension = 1 - if (Array.isArray(options) || - isTypedArray(options) || - isNDArrayLike(options) || - options instanceof ArrayBuffer) { - data = options - } else if (typeof options === 'number') { - byteLength = options | 0 - } else if (options) { - - - if ('data' in options) { - - data = options.data - } - - if ('usage' in options) { - - usage = usageTypes[options.usage] - } - - if ('type' in options) { - - dtype = glTypes[options.type] - } - - if ('dimension' in options) { - - dimension = options.dimension | 0 - } - - if ('length' in options) { - - byteLength = options.length | 0 - } - } - - buffer.bind() - if (!data) { - // #475 - if (byteLength) gl.bufferData(buffer.type, byteLength, usage) - buffer.dtype = dtype || GL_UNSIGNED_BYTE$2 - buffer.usage = usage - buffer.dimension = dimension - buffer.byteLength = byteLength - } else { - initBufferFromData(buffer, data, usage, dtype, dimension, persistent) - } - - if (config.profile) { - buffer.stats.size = buffer.byteLength * DTYPES_SIZES[buffer.dtype] - } - - return reglBuffer - } - - function setSubData (data, offset) { - - - gl.bufferSubData(buffer.type, offset, data) - } - - function subdata (data, offset_) { - var offset = (offset_ || 0) | 0 - var shape - buffer.bind() - if (isTypedArray(data) || data instanceof ArrayBuffer) { - setSubData(data, offset) - } else if (Array.isArray(data)) { - if (data.length > 0) { - if (typeof data[0] === 'number') { - var converted = pool.allocType(buffer.dtype, data.length) - copyArray(converted, data) - setSubData(converted, offset) - pool.freeType(converted) - } else if (Array.isArray(data[0]) || isTypedArray(data[0])) { - shape = arrayShape(data) - var flatData = arrayFlatten(data, shape, buffer.dtype) - setSubData(flatData, offset) - pool.freeType(flatData) - } else { - - } - } - } else if (isNDArrayLike(data)) { - shape = data.shape - var stride = data.stride - - var shapeX = 0 - var shapeY = 0 - var strideX = 0 - var strideY = 0 - if (shape.length === 1) { - shapeX = shape[0] - shapeY = 1 - strideX = stride[0] - strideY = 0 - } else if (shape.length === 2) { - shapeX = shape[0] - shapeY = shape[1] - strideX = stride[0] - strideY = stride[1] - } else { - - } - var dtype = Array.isArray(data.data) - ? buffer.dtype - : typedArrayCode(data.data) - - var transposeData = pool.allocType(dtype, shapeX * shapeY) - transpose(transposeData, - data.data, - shapeX, shapeY, - strideX, strideY, - data.offset) - setSubData(transposeData, offset) - pool.freeType(transposeData) - } else { - - } - return reglBuffer - } - - if (!deferInit) { - reglBuffer(options) - } - - reglBuffer._reglType = 'buffer' - reglBuffer._buffer = buffer - reglBuffer.subdata = subdata - if (config.profile) { - reglBuffer.stats = buffer.stats - } - reglBuffer.destroy = function () { destroy(buffer) } - - return reglBuffer - } - - function restoreBuffers () { - values(bufferSet).forEach(function (buffer) { - buffer.buffer = gl.createBuffer() - gl.bindBuffer(buffer.type, buffer.buffer) - gl.bufferData( - buffer.type, buffer.persistentData || buffer.byteLength, buffer.usage) - }) - } - - if (config.profile) { - stats.getTotalBufferSize = function () { - var total = 0 - // TODO: Right now, the streams are not part of the total count. - Object.keys(bufferSet).forEach(function (key) { - total += bufferSet[key].stats.size - }) - return total - } - } - - return { - create: createBuffer, - - createStream: createStream, - destroyStream: destroyStream, - - clear: function () { - values(bufferSet).forEach(destroy) - streamPool.forEach(destroy) - }, - - getBuffer: function (wrapper) { - if (wrapper && wrapper._buffer instanceof REGLBuffer) { - return wrapper._buffer - } - return null - }, - - restore: restoreBuffers, - - _initBuffer: initBufferFromData - } -} - -var points = 0; -var point = 0; -var lines = 1; -var line = 1; -var triangles = 4; -var triangle = 4; -var primTypes = { - points: points, - point: point, - lines: lines, - line: line, - triangles: triangles, - triangle: triangle, - "line loop": 2, - "line strip": 3, - "triangle strip": 5, - "triangle fan": 6 -}; - -var GL_POINTS = 0 -var GL_LINES = 1 -var GL_TRIANGLES = 4 - -var GL_BYTE$1 = 5120 -var GL_UNSIGNED_BYTE$3 = 5121 -var GL_SHORT$1 = 5122 -var GL_UNSIGNED_SHORT$1 = 5123 -var GL_INT$1 = 5124 -var GL_UNSIGNED_INT$1 = 5125 - -var GL_ELEMENT_ARRAY_BUFFER = 34963 - -var GL_STREAM_DRAW$1 = 0x88E0 -var GL_STATIC_DRAW$1 = 0x88E4 - -function wrapElementsState (gl, extensions, bufferState, stats) { - var elementSet = {} - var elementCount = 0 - - var elementTypes = { - 'uint8': GL_UNSIGNED_BYTE$3, - 'uint16': GL_UNSIGNED_SHORT$1 - } - - if (extensions.oes_element_index_uint) { - elementTypes.uint32 = GL_UNSIGNED_INT$1 - } - - function REGLElementBuffer (buffer) { - this.id = elementCount++ - elementSet[this.id] = this - this.buffer = buffer - this.primType = GL_TRIANGLES - this.vertCount = 0 - this.type = 0 - } - - REGLElementBuffer.prototype.bind = function () { - this.buffer.bind() - } - - var bufferPool = [] - - function createElementStream (data) { - var result = bufferPool.pop() - if (!result) { - result = new REGLElementBuffer(bufferState.create( - null, - GL_ELEMENT_ARRAY_BUFFER, - true, - false)._buffer) - } - initElements(result, data, GL_STREAM_DRAW$1, -1, -1, 0, 0) - return result - } - - function destroyElementStream (elements) { - bufferPool.push(elements) - } - - function initElements ( - elements, - data, - usage, - prim, - count, - byteLength, - type) { - elements.buffer.bind() - var dtype - if (data) { - var predictedType = type - if (!type && ( - !isTypedArray(data) || - (isNDArrayLike(data) && !isTypedArray(data.data)))) { - predictedType = extensions.oes_element_index_uint - ? GL_UNSIGNED_INT$1 - : GL_UNSIGNED_SHORT$1 - } - bufferState._initBuffer( - elements.buffer, - data, - usage, - predictedType, - 3) - } else { - gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, byteLength, usage) - elements.buffer.dtype = dtype || GL_UNSIGNED_BYTE$3 - elements.buffer.usage = usage - elements.buffer.dimension = 3 - elements.buffer.byteLength = byteLength - } - - dtype = type - if (!type) { - switch (elements.buffer.dtype) { - case GL_UNSIGNED_BYTE$3: - case GL_BYTE$1: - dtype = GL_UNSIGNED_BYTE$3 - break - - case GL_UNSIGNED_SHORT$1: - case GL_SHORT$1: - dtype = GL_UNSIGNED_SHORT$1 - break - - case GL_UNSIGNED_INT$1: - case GL_INT$1: - dtype = GL_UNSIGNED_INT$1 - break - - default: - - } - elements.buffer.dtype = dtype - } - elements.type = dtype - - // Check oes_element_index_uint extension - - - // try to guess default primitive type and arguments - var vertCount = count - if (vertCount < 0) { - vertCount = elements.buffer.byteLength - if (dtype === GL_UNSIGNED_SHORT$1) { - vertCount >>= 1 - } else if (dtype === GL_UNSIGNED_INT$1) { - vertCount >>= 2 - } - } - elements.vertCount = vertCount - - // try to guess primitive type from cell dimension - var primType = prim - if (prim < 0) { - primType = GL_TRIANGLES - var dimension = elements.buffer.dimension - if (dimension === 1) primType = GL_POINTS - if (dimension === 2) primType = GL_LINES - if (dimension === 3) primType = GL_TRIANGLES - } - elements.primType = primType - } - - function destroyElements (elements) { - stats.elementsCount-- - - - delete elementSet[elements.id] - elements.buffer.destroy() - elements.buffer = null - } - - function createElements (options, persistent) { - var buffer = bufferState.create(null, GL_ELEMENT_ARRAY_BUFFER, true) - var elements = new REGLElementBuffer(buffer._buffer) - stats.elementsCount++ - - function reglElements (options) { - if (!options) { - buffer() - elements.primType = GL_TRIANGLES - elements.vertCount = 0 - elements.type = GL_UNSIGNED_BYTE$3 - } else if (typeof options === 'number') { - buffer(options) - elements.primType = GL_TRIANGLES - elements.vertCount = options | 0 - elements.type = GL_UNSIGNED_BYTE$3 - } else { - var data = null - var usage = GL_STATIC_DRAW$1 - var primType = -1 - var vertCount = -1 - var byteLength = 0 - var dtype = 0 - if (Array.isArray(options) || - isTypedArray(options) || - isNDArrayLike(options)) { - data = options - } else { - - if ('data' in options) { - data = options.data - - } - if ('usage' in options) { - - usage = usageTypes[options.usage] - } - if ('primitive' in options) { - - primType = primTypes[options.primitive] - } - if ('count' in options) { - - vertCount = options.count | 0 - } - if ('type' in options) { - - dtype = elementTypes[options.type] - } - if ('length' in options) { - byteLength = options.length | 0 - } else { - byteLength = vertCount - if (dtype === GL_UNSIGNED_SHORT$1 || dtype === GL_SHORT$1) { - byteLength *= 2 - } else if (dtype === GL_UNSIGNED_INT$1 || dtype === GL_INT$1) { - byteLength *= 4 - } - } - } - initElements( - elements, - data, - usage, - primType, - vertCount, - byteLength, - dtype) - } - - return reglElements - } - - reglElements(options) - - reglElements._reglType = 'elements' - reglElements._elements = elements - reglElements.subdata = function (data, offset) { - buffer.subdata(data, offset) - return reglElements - } - reglElements.destroy = function () { - destroyElements(elements) - } - - return reglElements - } - - return { - create: createElements, - createStream: createElementStream, - destroyStream: destroyElementStream, - getElements: function (elements) { - if (typeof elements === 'function' && - elements._elements instanceof REGLElementBuffer) { - return elements._elements - } - return null - }, - clear: function () { - values(elementSet).forEach(destroyElements) - } - } -} - -var FLOAT = new Float32Array(1) -var INT = new Uint32Array(FLOAT.buffer) - -var GL_UNSIGNED_SHORT$3 = 5123 - -function convertToHalfFloat (array) { - var ushorts = pool.allocType(GL_UNSIGNED_SHORT$3, array.length) - - for (var i = 0; i < array.length; ++i) { - if (isNaN(array[i])) { - ushorts[i] = 0xffff - } else if (array[i] === Infinity) { - ushorts[i] = 0x7c00 - } else if (array[i] === -Infinity) { - ushorts[i] = 0xfc00 - } else { - FLOAT[0] = array[i] - var x = INT[0] - - var sgn = (x >>> 31) << 15 - var exp = ((x << 1) >>> 24) - 127 - var frac = (x >> 13) & ((1 << 10) - 1) - - if (exp < -24) { - // round non-representable denormals to 0 - ushorts[i] = sgn - } else if (exp < -14) { - // handle denormals - var s = -14 - exp - ushorts[i] = sgn + ((frac + (1 << 10)) >> s) - } else if (exp > 15) { - // round overflow to +/- Infinity - ushorts[i] = sgn + 0x7c00 - } else { - // otherwise convert directly - ushorts[i] = sgn + ((exp + 15) << 10) + frac - } - } - } - - return ushorts -} - -function isArrayLike (s) { - return Array.isArray(s) || isTypedArray(s) -} - -var GL_COMPRESSED_TEXTURE_FORMATS = 0x86A3 - -var GL_TEXTURE_2D$1 = 0x0DE1 -var GL_TEXTURE_CUBE_MAP$1 = 0x8513 -var GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 = 0x8515 - -var GL_RGBA$1 = 0x1908 -var GL_ALPHA = 0x1906 -var GL_RGB = 0x1907 -var GL_LUMINANCE = 0x1909 -var GL_LUMINANCE_ALPHA = 0x190A - -var GL_RGBA4 = 0x8056 -var GL_RGB5_A1 = 0x8057 -var GL_RGB565 = 0x8D62 - -var GL_UNSIGNED_SHORT_4_4_4_4 = 0x8033 -var GL_UNSIGNED_SHORT_5_5_5_1 = 0x8034 -var GL_UNSIGNED_SHORT_5_6_5 = 0x8363 -var GL_UNSIGNED_INT_24_8_WEBGL = 0x84FA - -var GL_DEPTH_COMPONENT = 0x1902 -var GL_DEPTH_STENCIL = 0x84F9 - -var GL_SRGB_EXT = 0x8C40 -var GL_SRGB_ALPHA_EXT = 0x8C42 - -var GL_HALF_FLOAT_OES = 0x8D61 - -var GL_COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0 -var GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1 -var GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2 -var GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3 - -var GL_COMPRESSED_RGB_ATC_WEBGL = 0x8C92 -var GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 0x8C93 -var GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE - -var GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00 -var GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01 -var GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02 -var GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03 - -var GL_COMPRESSED_RGB_ETC1_WEBGL = 0x8D64 - -var GL_UNSIGNED_BYTE$4 = 0x1401 -var GL_UNSIGNED_SHORT$2 = 0x1403 -var GL_UNSIGNED_INT$2 = 0x1405 -var GL_FLOAT$3 = 0x1406 - -var GL_TEXTURE_WRAP_S = 0x2802 -var GL_TEXTURE_WRAP_T = 0x2803 - -var GL_REPEAT = 0x2901 -var GL_CLAMP_TO_EDGE = 0x812F -var GL_MIRRORED_REPEAT = 0x8370 - -var GL_TEXTURE_MAG_FILTER = 0x2800 -var GL_TEXTURE_MIN_FILTER = 0x2801 - -var GL_NEAREST = 0x2600 -var GL_LINEAR = 0x2601 -var GL_NEAREST_MIPMAP_NEAREST = 0x2700 -var GL_LINEAR_MIPMAP_NEAREST = 0x2701 -var GL_NEAREST_MIPMAP_LINEAR = 0x2702 -var GL_LINEAR_MIPMAP_LINEAR = 0x2703 - -var GL_GENERATE_MIPMAP_HINT = 0x8192 -var GL_DONT_CARE = 0x1100 -var GL_FASTEST = 0x1101 -var GL_NICEST = 0x1102 - -var GL_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE - -var GL_UNPACK_ALIGNMENT = 0x0CF5 -var GL_UNPACK_FLIP_Y_WEBGL = 0x9240 -var GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241 -var GL_UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243 - -var GL_BROWSER_DEFAULT_WEBGL = 0x9244 - -var GL_TEXTURE0$1 = 0x84C0 - -var MIPMAP_FILTERS = [ - GL_NEAREST_MIPMAP_NEAREST, - GL_NEAREST_MIPMAP_LINEAR, - GL_LINEAR_MIPMAP_NEAREST, - GL_LINEAR_MIPMAP_LINEAR -] - -var CHANNELS_FORMAT = [ - 0, - GL_LUMINANCE, - GL_LUMINANCE_ALPHA, - GL_RGB, - GL_RGBA$1 -] - -var FORMAT_CHANNELS = {} -FORMAT_CHANNELS[GL_LUMINANCE] = -FORMAT_CHANNELS[GL_ALPHA] = -FORMAT_CHANNELS[GL_DEPTH_COMPONENT] = 1 -FORMAT_CHANNELS[GL_DEPTH_STENCIL] = -FORMAT_CHANNELS[GL_LUMINANCE_ALPHA] = 2 -FORMAT_CHANNELS[GL_RGB] = -FORMAT_CHANNELS[GL_SRGB_EXT] = 3 -FORMAT_CHANNELS[GL_RGBA$1] = -FORMAT_CHANNELS[GL_SRGB_ALPHA_EXT] = 4 - -function objectName (str) { - return '[object ' + str + ']' -} - -var CANVAS_CLASS = objectName('HTMLCanvasElement') -var OFFSCREENCANVAS_CLASS = objectName('OffscreenCanvas') -var CONTEXT2D_CLASS = objectName('CanvasRenderingContext2D') -var BITMAP_CLASS = objectName('ImageBitmap') -var IMAGE_CLASS = objectName('HTMLImageElement') -var VIDEO_CLASS = objectName('HTMLVideoElement') - -var PIXEL_CLASSES = Object.keys(arrayTypes).concat([ - CANVAS_CLASS, - OFFSCREENCANVAS_CLASS, - CONTEXT2D_CLASS, - BITMAP_CLASS, - IMAGE_CLASS, - VIDEO_CLASS -]) - -// for every texture type, store -// the size in bytes. -var TYPE_SIZES = [] -TYPE_SIZES[GL_UNSIGNED_BYTE$4] = 1 -TYPE_SIZES[GL_FLOAT$3] = 4 -TYPE_SIZES[GL_HALF_FLOAT_OES] = 2 - -TYPE_SIZES[GL_UNSIGNED_SHORT$2] = 2 -TYPE_SIZES[GL_UNSIGNED_INT$2] = 4 - -var FORMAT_SIZES_SPECIAL = [] -FORMAT_SIZES_SPECIAL[GL_RGBA4] = 2 -FORMAT_SIZES_SPECIAL[GL_RGB5_A1] = 2 -FORMAT_SIZES_SPECIAL[GL_RGB565] = 2 -FORMAT_SIZES_SPECIAL[GL_DEPTH_STENCIL] = 4 - -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_S3TC_DXT1_EXT] = 0.5 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT1_EXT] = 0.5 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT3_EXT] = 1 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT5_EXT] = 1 - -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_ATC_WEBGL] = 0.5 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL] = 1 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL] = 1 - -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG] = 0.5 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG] = 0.25 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG] = 0.5 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG] = 0.25 - -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_ETC1_WEBGL] = 0.5 - -function isNumericArray (arr) { - return ( - Array.isArray(arr) && - (arr.length === 0 || - typeof arr[0] === 'number')) -} - -function isRectArray (arr) { - if (!Array.isArray(arr)) { - return false - } - var width = arr.length - if (width === 0 || !isArrayLike(arr[0])) { - return false - } - return true -} - -function classString (x) { - return Object.prototype.toString.call(x) -} - -function isCanvasElement (object) { - return classString(object) === CANVAS_CLASS -} - -function isOffscreenCanvas (object) { - return classString(object) === OFFSCREENCANVAS_CLASS -} - -function isContext2D (object) { - return classString(object) === CONTEXT2D_CLASS -} - -function isBitmap (object) { - return classString(object) === BITMAP_CLASS -} - -function isImageElement (object) { - return classString(object) === IMAGE_CLASS -} - -function isVideoElement (object) { - return classString(object) === VIDEO_CLASS -} - -function isPixelData (object) { - if (!object) { - return false - } - var className = classString(object) - if (PIXEL_CLASSES.indexOf(className) >= 0) { - return true - } - return ( - isNumericArray(object) || - isRectArray(object) || - isNDArrayLike(object)) -} - -function typedArrayCode$1 (data) { - return arrayTypes[Object.prototype.toString.call(data)] | 0 -} - -function convertData (result, data) { - var n = data.length - switch (result.type) { - case GL_UNSIGNED_BYTE$4: - case GL_UNSIGNED_SHORT$2: - case GL_UNSIGNED_INT$2: - case GL_FLOAT$3: - var converted = pool.allocType(result.type, n) - converted.set(data) - result.data = converted - break - - case GL_HALF_FLOAT_OES: - result.data = convertToHalfFloat(data) - break - - default: - - } -} - -function preConvert (image, n) { - return pool.allocType( - image.type === GL_HALF_FLOAT_OES - ? GL_FLOAT$3 - : image.type, n) -} - -function postConvert (image, data) { - if (image.type === GL_HALF_FLOAT_OES) { - image.data = convertToHalfFloat(data) - pool.freeType(data) - } else { - image.data = data - } -} - -function transposeData (image, array, strideX, strideY, strideC, offset) { - var w = image.width - var h = image.height - var c = image.channels - var n = w * h * c - var data = preConvert(image, n) - - var p = 0 - for (var i = 0; i < h; ++i) { - for (var j = 0; j < w; ++j) { - for (var k = 0; k < c; ++k) { - data[p++] = array[strideX * j + strideY * i + strideC * k + offset] - } - } - } - - postConvert(image, data) -} - -function getTextureSize (format, type, width, height, isMipmap, isCube) { - var s - if (typeof FORMAT_SIZES_SPECIAL[format] !== 'undefined') { - // we have a special array for dealing with weird color formats such as RGB5A1 - s = FORMAT_SIZES_SPECIAL[format] - } else { - s = FORMAT_CHANNELS[format] * TYPE_SIZES[type] - } - - if (isCube) { - s *= 6 - } - - if (isMipmap) { - // compute the total size of all the mipmaps. - var total = 0 - - var w = width - while (w >= 1) { - // we can only use mipmaps on a square image, - // so we can simply use the width and ignore the height: - total += s * w * w - w /= 2 - } - return total - } else { - return s * width * height - } -} - -function createTextureSet ( - gl, extensions, limits, reglPoll, contextState, stats, config) { - // ------------------------------------------------------- - // Initialize constants and parameter tables here - // ------------------------------------------------------- - var mipmapHint = { - "don't care": GL_DONT_CARE, - 'dont care': GL_DONT_CARE, - 'nice': GL_NICEST, - 'fast': GL_FASTEST - } - - var wrapModes = { - 'repeat': GL_REPEAT, - 'clamp': GL_CLAMP_TO_EDGE, - 'mirror': GL_MIRRORED_REPEAT - } - - var magFilters = { - 'nearest': GL_NEAREST, - 'linear': GL_LINEAR - } - - var minFilters = extend({ - 'mipmap': GL_LINEAR_MIPMAP_LINEAR, - 'nearest mipmap nearest': GL_NEAREST_MIPMAP_NEAREST, - 'linear mipmap nearest': GL_LINEAR_MIPMAP_NEAREST, - 'nearest mipmap linear': GL_NEAREST_MIPMAP_LINEAR, - 'linear mipmap linear': GL_LINEAR_MIPMAP_LINEAR - }, magFilters) - - var colorSpace = { - 'none': 0, - 'browser': GL_BROWSER_DEFAULT_WEBGL - } - - var textureTypes = { - 'uint8': GL_UNSIGNED_BYTE$4, - 'rgba4': GL_UNSIGNED_SHORT_4_4_4_4, - 'rgb565': GL_UNSIGNED_SHORT_5_6_5, - 'rgb5 a1': GL_UNSIGNED_SHORT_5_5_5_1 - } - - var textureFormats = { - 'alpha': GL_ALPHA, - 'luminance': GL_LUMINANCE, - 'luminance alpha': GL_LUMINANCE_ALPHA, - 'rgb': GL_RGB, - 'rgba': GL_RGBA$1, - 'rgba4': GL_RGBA4, - 'rgb5 a1': GL_RGB5_A1, - 'rgb565': GL_RGB565 - } - - var compressedTextureFormats = {} - - if (extensions.ext_srgb) { - textureFormats.srgb = GL_SRGB_EXT - textureFormats.srgba = GL_SRGB_ALPHA_EXT - } - - if (extensions.oes_texture_float) { - textureTypes.float32 = textureTypes.float = GL_FLOAT$3 - } - - if (extensions.oes_texture_half_float) { - textureTypes['float16'] = textureTypes['half float'] = GL_HALF_FLOAT_OES - } - - if (extensions.webgl_depth_texture) { - extend(textureFormats, { - 'depth': GL_DEPTH_COMPONENT, - 'depth stencil': GL_DEPTH_STENCIL - }) - - extend(textureTypes, { - 'uint16': GL_UNSIGNED_SHORT$2, - 'uint32': GL_UNSIGNED_INT$2, - 'depth stencil': GL_UNSIGNED_INT_24_8_WEBGL - }) - } - - if (extensions.webgl_compressed_texture_s3tc) { - extend(compressedTextureFormats, { - 'rgb s3tc dxt1': GL_COMPRESSED_RGB_S3TC_DXT1_EXT, - 'rgba s3tc dxt1': GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, - 'rgba s3tc dxt3': GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, - 'rgba s3tc dxt5': GL_COMPRESSED_RGBA_S3TC_DXT5_EXT - }) - } - - if (extensions.webgl_compressed_texture_atc) { - extend(compressedTextureFormats, { - 'rgb atc': GL_COMPRESSED_RGB_ATC_WEBGL, - 'rgba atc explicit alpha': GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL, - 'rgba atc interpolated alpha': GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL - }) - } - - if (extensions.webgl_compressed_texture_pvrtc) { - extend(compressedTextureFormats, { - 'rgb pvrtc 4bppv1': GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, - 'rgb pvrtc 2bppv1': GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, - 'rgba pvrtc 4bppv1': GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, - 'rgba pvrtc 2bppv1': GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG - }) - } - - if (extensions.webgl_compressed_texture_etc1) { - compressedTextureFormats['rgb etc1'] = GL_COMPRESSED_RGB_ETC1_WEBGL - } - - // Copy over all texture formats - var supportedCompressedFormats = Array.prototype.slice.call( - gl.getParameter(GL_COMPRESSED_TEXTURE_FORMATS)) - Object.keys(compressedTextureFormats).forEach(function (name) { - var format = compressedTextureFormats[name] - if (supportedCompressedFormats.indexOf(format) >= 0) { - textureFormats[name] = format - } - }) - - var supportedFormats = Object.keys(textureFormats) - limits.textureFormats = supportedFormats - - // associate with every format string its - // corresponding GL-value. - var textureFormatsInvert = [] - Object.keys(textureFormats).forEach(function (key) { - var val = textureFormats[key] - textureFormatsInvert[val] = key - }) - - // associate with every type string its - // corresponding GL-value. - var textureTypesInvert = [] - Object.keys(textureTypes).forEach(function (key) { - var val = textureTypes[key] - textureTypesInvert[val] = key - }) - - var magFiltersInvert = [] - Object.keys(magFilters).forEach(function (key) { - var val = magFilters[key] - magFiltersInvert[val] = key - }) - - var minFiltersInvert = [] - Object.keys(minFilters).forEach(function (key) { - var val = minFilters[key] - minFiltersInvert[val] = key - }) - - var wrapModesInvert = [] - Object.keys(wrapModes).forEach(function (key) { - var val = wrapModes[key] - wrapModesInvert[val] = key - }) - - // colorFormats[] gives the format (channels) associated to an - // internalformat - var colorFormats = supportedFormats.reduce(function (color, key) { - var glenum = textureFormats[key] - if (glenum === GL_LUMINANCE || - glenum === GL_ALPHA || - glenum === GL_LUMINANCE || - glenum === GL_LUMINANCE_ALPHA || - glenum === GL_DEPTH_COMPONENT || - glenum === GL_DEPTH_STENCIL || - (extensions.ext_srgb && - (glenum === GL_SRGB_EXT || - glenum === GL_SRGB_ALPHA_EXT))) { - color[glenum] = glenum - } else if (glenum === GL_RGB5_A1 || key.indexOf('rgba') >= 0) { - color[glenum] = GL_RGBA$1 - } else { - color[glenum] = GL_RGB - } - return color - }, {}) - - function TexFlags () { - // format info - this.internalformat = GL_RGBA$1 - this.format = GL_RGBA$1 - this.type = GL_UNSIGNED_BYTE$4 - this.compressed = false - - // pixel storage - this.premultiplyAlpha = false - this.flipY = false - this.unpackAlignment = 1 - this.colorSpace = GL_BROWSER_DEFAULT_WEBGL - - // shape info - this.width = 0 - this.height = 0 - this.channels = 0 - } - - function copyFlags (result, other) { - result.internalformat = other.internalformat - result.format = other.format - result.type = other.type - result.compressed = other.compressed - - result.premultiplyAlpha = other.premultiplyAlpha - result.flipY = other.flipY - result.unpackAlignment = other.unpackAlignment - result.colorSpace = other.colorSpace - - result.width = other.width - result.height = other.height - result.channels = other.channels - } - - function parseFlags (flags, options) { - if (typeof options !== 'object' || !options) { - return - } - - if ('premultiplyAlpha' in options) { - - flags.premultiplyAlpha = options.premultiplyAlpha - } - - if ('flipY' in options) { - - flags.flipY = options.flipY - } - - if ('alignment' in options) { - - flags.unpackAlignment = options.alignment - } - - if ('colorSpace' in options) { - - flags.colorSpace = colorSpace[options.colorSpace] - } - - if ('type' in options) { - var type = options.type - - - - - flags.type = textureTypes[type] - } - - var w = flags.width - var h = flags.height - var c = flags.channels - var hasChannels = false - if ('shape' in options) { - - w = options.shape[0] - h = options.shape[1] - if (options.shape.length === 3) { - c = options.shape[2] - - hasChannels = true - } - - - } else { - if ('radius' in options) { - w = h = options.radius - - } - if ('width' in options) { - w = options.width - - } - if ('height' in options) { - h = options.height - - } - if ('channels' in options) { - c = options.channels - - hasChannels = true - } - } - flags.width = w | 0 - flags.height = h | 0 - flags.channels = c | 0 - - var hasFormat = false - if ('format' in options) { - var formatStr = options.format - - - var internalformat = flags.internalformat = textureFormats[formatStr] - flags.format = colorFormats[internalformat] - if (formatStr in textureTypes) { - if (!('type' in options)) { - flags.type = textureTypes[formatStr] - } - } - if (formatStr in compressedTextureFormats) { - flags.compressed = true - } - hasFormat = true - } - - // Reconcile channels and format - if (!hasChannels && hasFormat) { - flags.channels = FORMAT_CHANNELS[flags.format] - } else if (hasChannels && !hasFormat) { - if (flags.channels !== CHANNELS_FORMAT[flags.format]) { - flags.format = flags.internalformat = CHANNELS_FORMAT[flags.channels] - } - } else if (hasFormat && hasChannels) { - - } - } - - function setFlags (flags) { - gl.pixelStorei(GL_UNPACK_FLIP_Y_WEBGL, flags.flipY) - gl.pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL, flags.premultiplyAlpha) - gl.pixelStorei(GL_UNPACK_COLORSPACE_CONVERSION_WEBGL, flags.colorSpace) - gl.pixelStorei(GL_UNPACK_ALIGNMENT, flags.unpackAlignment) - } - - // ------------------------------------------------------- - // Tex image data - // ------------------------------------------------------- - function TexImage () { - TexFlags.call(this) - - this.xOffset = 0 - this.yOffset = 0 - - // data - this.data = null - this.needsFree = false - - // html element - this.element = null - - // copyTexImage info - this.needsCopy = false - } - - function parseImage (image, options) { - var data = null - if (isPixelData(options)) { - data = options - } else if (options) { - - parseFlags(image, options) - if ('x' in options) { - image.xOffset = options.x | 0 - } - if ('y' in options) { - image.yOffset = options.y | 0 - } - if (isPixelData(options.data)) { - data = options.data - } - } - - - - if (options.copy) { - - var viewW = contextState.viewportWidth - var viewH = contextState.viewportHeight - image.width = image.width || (viewW - image.xOffset) - image.height = image.height || (viewH - image.yOffset) - image.needsCopy = true - - } else if (!data) { - image.width = image.width || 1 - image.height = image.height || 1 - image.channels = image.channels || 4 - } else if (isTypedArray(data)) { - image.channels = image.channels || 4 - image.data = data - if (!('type' in options) && image.type === GL_UNSIGNED_BYTE$4) { - image.type = typedArrayCode$1(data) - } - } else if (isNumericArray(data)) { - image.channels = image.channels || 4 - convertData(image, data) - image.alignment = 1 - image.needsFree = true - } else if (isNDArrayLike(data)) { - var array = data.data - if (!Array.isArray(array) && image.type === GL_UNSIGNED_BYTE$4) { - image.type = typedArrayCode$1(array) - } - var shape = data.shape - var stride = data.stride - var shapeX, shapeY, shapeC, strideX, strideY, strideC - if (shape.length === 3) { - shapeC = shape[2] - strideC = stride[2] - } else { - - shapeC = 1 - strideC = 1 - } - shapeX = shape[0] - shapeY = shape[1] - strideX = stride[0] - strideY = stride[1] - image.alignment = 1 - image.width = shapeX - image.height = shapeY - image.channels = shapeC - image.format = image.internalformat = CHANNELS_FORMAT[shapeC] - image.needsFree = true - transposeData(image, array, strideX, strideY, strideC, data.offset) - } else if (isCanvasElement(data) || isOffscreenCanvas(data) || isContext2D(data)) { - if (isCanvasElement(data) || isOffscreenCanvas(data)) { - image.element = data - } else { - image.element = data.canvas - } - image.width = image.element.width - image.height = image.element.height - image.channels = 4 - } else if (isBitmap(data)) { - image.element = data - image.width = data.width - image.height = data.height - image.channels = 4 - } else if (isImageElement(data)) { - image.element = data - image.width = data.naturalWidth - image.height = data.naturalHeight - image.channels = 4 - } else if (isVideoElement(data)) { - image.element = data - image.width = data.videoWidth - image.height = data.videoHeight - image.channels = 4 - } else if (isRectArray(data)) { - var w = image.width || data[0].length - var h = image.height || data.length - var c = image.channels - if (isArrayLike(data[0][0])) { - c = c || data[0][0].length - } else { - c = c || 1 - } - var arrayShape = flattenUtils.shape(data) - var n = 1 - for (var dd = 0; dd < arrayShape.length; ++dd) { - n *= arrayShape[dd] - } - var allocData = preConvert(image, n) - flattenUtils.flatten(data, arrayShape, '', allocData) - postConvert(image, allocData) - image.alignment = 1 - image.width = w - image.height = h - image.channels = c - image.format = image.internalformat = CHANNELS_FORMAT[c] - image.needsFree = true - } - - if (image.type === GL_FLOAT$3) { - - } else if (image.type === GL_HALF_FLOAT_OES) { - - } - - // do compressed texture validation here. - } - - function setImage (info, target, miplevel) { - var element = info.element - var data = info.data - var internalformat = info.internalformat - var format = info.format - var type = info.type - var width = info.width - var height = info.height - - setFlags(info) - - if (element) { - gl.texImage2D(target, miplevel, format, format, type, element) - } else if (info.compressed) { - gl.compressedTexImage2D(target, miplevel, internalformat, width, height, 0, data) - } else if (info.needsCopy) { - reglPoll() - gl.copyTexImage2D( - target, miplevel, format, info.xOffset, info.yOffset, width, height, 0) - } else { - gl.texImage2D(target, miplevel, format, width, height, 0, format, type, data || null) - } - } - - function setSubImage (info, target, x, y, miplevel) { - var element = info.element - var data = info.data - var internalformat = info.internalformat - var format = info.format - var type = info.type - var width = info.width - var height = info.height - - setFlags(info) - - if (element) { - gl.texSubImage2D( - target, miplevel, x, y, format, type, element) - } else if (info.compressed) { - gl.compressedTexSubImage2D( - target, miplevel, x, y, internalformat, width, height, data) - } else if (info.needsCopy) { - reglPoll() - gl.copyTexSubImage2D( - target, miplevel, x, y, info.xOffset, info.yOffset, width, height) - } else { - gl.texSubImage2D( - target, miplevel, x, y, width, height, format, type, data) - } - } - - // texImage pool - var imagePool = [] - - function allocImage () { - return imagePool.pop() || new TexImage() - } - - function freeImage (image) { - if (image.needsFree) { - pool.freeType(image.data) - } - TexImage.call(image) - imagePool.push(image) - } - - // ------------------------------------------------------- - // Mip map - // ------------------------------------------------------- - function MipMap () { - TexFlags.call(this) - - this.genMipmaps = false - this.mipmapHint = GL_DONT_CARE - this.mipmask = 0 - this.images = Array(16) - } - - function parseMipMapFromShape (mipmap, width, height) { - var img = mipmap.images[0] = allocImage() - mipmap.mipmask = 1 - img.width = mipmap.width = width - img.height = mipmap.height = height - img.channels = mipmap.channels = 4 - } - - function parseMipMapFromObject (mipmap, options) { - var imgData = null - if (isPixelData(options)) { - imgData = mipmap.images[0] = allocImage() - copyFlags(imgData, mipmap) - parseImage(imgData, options) - mipmap.mipmask = 1 - } else { - parseFlags(mipmap, options) - if (Array.isArray(options.mipmap)) { - var mipData = options.mipmap - for (var i = 0; i < mipData.length; ++i) { - imgData = mipmap.images[i] = allocImage() - copyFlags(imgData, mipmap) - imgData.width >>= i - imgData.height >>= i - parseImage(imgData, mipData[i]) - mipmap.mipmask |= (1 << i) - } - } else { - imgData = mipmap.images[0] = allocImage() - copyFlags(imgData, mipmap) - parseImage(imgData, options) - mipmap.mipmask = 1 - } - } - copyFlags(mipmap, mipmap.images[0]) - - // For textures of the compressed format WEBGL_compressed_texture_s3tc - // we must have that - // - // "When level equals zero width and height must be a multiple of 4. - // When level is greater than 0 width and height must be 0, 1, 2 or a multiple of 4. " - // - // but we do not yet support having multiple mipmap levels for compressed textures, - // so we only test for level zero. - - if ( - mipmap.compressed && - ( - mipmap.internalformat === GL_COMPRESSED_RGB_S3TC_DXT1_EXT || - mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || - mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT3_EXT || - mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT5_EXT - ) - ) { - - } - } - - function setMipMap (mipmap, target) { - var images = mipmap.images - for (var i = 0; i < images.length; ++i) { - if (!images[i]) { - return - } - setImage(images[i], target, i) - } - } - - var mipPool = [] - - function allocMipMap () { - var result = mipPool.pop() || new MipMap() - TexFlags.call(result) - result.mipmask = 0 - for (var i = 0; i < 16; ++i) { - result.images[i] = null - } - return result - } - - function freeMipMap (mipmap) { - var images = mipmap.images - for (var i = 0; i < images.length; ++i) { - if (images[i]) { - freeImage(images[i]) - } - images[i] = null - } - mipPool.push(mipmap) - } - - // ------------------------------------------------------- - // Tex info - // ------------------------------------------------------- - function TexInfo () { - this.minFilter = GL_NEAREST - this.magFilter = GL_NEAREST - - this.wrapS = GL_CLAMP_TO_EDGE - this.wrapT = GL_CLAMP_TO_EDGE - - this.anisotropic = 1 - - this.genMipmaps = false - this.mipmapHint = GL_DONT_CARE - } - - function parseTexInfo (info, options) { - if ('min' in options) { - var minFilter = options.min - - info.minFilter = minFilters[minFilter] - if (MIPMAP_FILTERS.indexOf(info.minFilter) >= 0 && !('faces' in options)) { - info.genMipmaps = true - } - } - - if ('mag' in options) { - var magFilter = options.mag - - info.magFilter = magFilters[magFilter] - } - - var wrapS = info.wrapS - var wrapT = info.wrapT - if ('wrap' in options) { - var wrap = options.wrap - if (typeof wrap === 'string') { - - wrapS = wrapT = wrapModes[wrap] - } else if (Array.isArray(wrap)) { - - - wrapS = wrapModes[wrap[0]] - wrapT = wrapModes[wrap[1]] - } - } else { - if ('wrapS' in options) { - var optWrapS = options.wrapS - - wrapS = wrapModes[optWrapS] - } - if ('wrapT' in options) { - var optWrapT = options.wrapT - - wrapT = wrapModes[optWrapT] - } - } - info.wrapS = wrapS - info.wrapT = wrapT - - if ('anisotropic' in options) { - var anisotropic = options.anisotropic - - info.anisotropic = options.anisotropic - } - - if ('mipmap' in options) { - var hasMipMap = false - switch (typeof options.mipmap) { - case 'string': - - info.mipmapHint = mipmapHint[options.mipmap] - info.genMipmaps = true - hasMipMap = true - break - - case 'boolean': - hasMipMap = info.genMipmaps = options.mipmap - break - - case 'object': - - info.genMipmaps = false - hasMipMap = true - break - - default: - - } - if (hasMipMap && !('min' in options)) { - info.minFilter = GL_NEAREST_MIPMAP_NEAREST - } - } - } - - function setTexInfo (info, target) { - gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, info.minFilter) - gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, info.magFilter) - gl.texParameteri(target, GL_TEXTURE_WRAP_S, info.wrapS) - gl.texParameteri(target, GL_TEXTURE_WRAP_T, info.wrapT) - if (extensions.ext_texture_filter_anisotropic) { - gl.texParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, info.anisotropic) - } - if (info.genMipmaps) { - gl.hint(GL_GENERATE_MIPMAP_HINT, info.mipmapHint) - gl.generateMipmap(target) - } - } - - // ------------------------------------------------------- - // Full texture object - // ------------------------------------------------------- - var textureCount = 0 - var textureSet = {} - var numTexUnits = limits.maxTextureUnits - var textureUnits = Array(numTexUnits).map(function () { - return null - }) - - function REGLTexture (target) { - TexFlags.call(this) - this.mipmask = 0 - this.internalformat = GL_RGBA$1 - - this.id = textureCount++ - - this.refCount = 1 - - this.target = target - this.texture = gl.createTexture() - - this.unit = -1 - this.bindCount = 0 - - this.texInfo = new TexInfo() - - if (config.profile) { - this.stats = { size: 0 } - } - } - - function tempBind (texture) { - gl.activeTexture(GL_TEXTURE0$1) - gl.bindTexture(texture.target, texture.texture) - } - - function tempRestore () { - var prev = textureUnits[0] - if (prev) { - gl.bindTexture(prev.target, prev.texture) - } else { - gl.bindTexture(GL_TEXTURE_2D$1, null) - } - } - - function destroy (texture) { - var handle = texture.texture - - var unit = texture.unit - var target = texture.target - if (unit >= 0) { - gl.activeTexture(GL_TEXTURE0$1 + unit) - gl.bindTexture(target, null) - textureUnits[unit] = null - } - gl.deleteTexture(handle) - texture.texture = null - texture.params = null - texture.pixels = null - texture.refCount = 0 - delete textureSet[texture.id] - stats.textureCount-- - } - - extend(REGLTexture.prototype, { - bind: function () { - var texture = this - texture.bindCount += 1 - var unit = texture.unit - if (unit < 0) { - for (var i = 0; i < numTexUnits; ++i) { - var other = textureUnits[i] - if (other) { - if (other.bindCount > 0) { - continue - } - other.unit = -1 - } - textureUnits[i] = texture - unit = i - break - } - if (unit >= numTexUnits) { - - } - if (config.profile && stats.maxTextureUnits < (unit + 1)) { - stats.maxTextureUnits = unit + 1 // +1, since the units are zero-based - } - texture.unit = unit - gl.activeTexture(GL_TEXTURE0$1 + unit) - gl.bindTexture(texture.target, texture.texture) - } - return unit - }, - - unbind: function () { - this.bindCount -= 1 - }, - - decRef: function () { - if (--this.refCount <= 0) { - destroy(this) - } - } - }) - - function createTexture2D (a, b) { - var texture = new REGLTexture(GL_TEXTURE_2D$1) - textureSet[texture.id] = texture - stats.textureCount++ - - function reglTexture2D (a, b) { - var texInfo = texture.texInfo - TexInfo.call(texInfo) - var mipData = allocMipMap() - - if (typeof a === 'number') { - if (typeof b === 'number') { - parseMipMapFromShape(mipData, a | 0, b | 0) - } else { - parseMipMapFromShape(mipData, a | 0, a | 0) - } - } else if (a) { - - parseTexInfo(texInfo, a) - parseMipMapFromObject(mipData, a) - } else { - // empty textures get assigned a default shape of 1x1 - parseMipMapFromShape(mipData, 1, 1) - } - - if (texInfo.genMipmaps) { - mipData.mipmask = (mipData.width << 1) - 1 - } - texture.mipmask = mipData.mipmask - - copyFlags(texture, mipData) - - - texture.internalformat = mipData.internalformat - - reglTexture2D.width = mipData.width - reglTexture2D.height = mipData.height - - tempBind(texture) - setMipMap(mipData, GL_TEXTURE_2D$1) - setTexInfo(texInfo, GL_TEXTURE_2D$1) - tempRestore() - - freeMipMap(mipData) - - if (config.profile) { - texture.stats.size = getTextureSize( - texture.internalformat, - texture.type, - mipData.width, - mipData.height, - texInfo.genMipmaps, - false) - } - reglTexture2D.format = textureFormatsInvert[texture.internalformat] - reglTexture2D.type = textureTypesInvert[texture.type] - - reglTexture2D.mag = magFiltersInvert[texInfo.magFilter] - reglTexture2D.min = minFiltersInvert[texInfo.minFilter] - - reglTexture2D.wrapS = wrapModesInvert[texInfo.wrapS] - reglTexture2D.wrapT = wrapModesInvert[texInfo.wrapT] - - return reglTexture2D - } - - function subimage (image, x_, y_, level_) { - - - var x = x_ | 0 - var y = y_ | 0 - var level = level_ | 0 - - var imageData = allocImage() - copyFlags(imageData, texture) - imageData.width = 0 - imageData.height = 0 - parseImage(imageData, image) - imageData.width = imageData.width || ((texture.width >> level) - x) - imageData.height = imageData.height || ((texture.height >> level) - y) - - - - - - - tempBind(texture) - setSubImage(imageData, GL_TEXTURE_2D$1, x, y, level) - tempRestore() - - freeImage(imageData) - - return reglTexture2D - } - - function resize (w_, h_) { - var w = w_ | 0 - var h = (h_ | 0) || w - if (w === texture.width && h === texture.height) { - return reglTexture2D - } - - reglTexture2D.width = texture.width = w - reglTexture2D.height = texture.height = h - - tempBind(texture) - - for (var i = 0; texture.mipmask >> i; ++i) { - var _w = w >> i - var _h = h >> i - if (!_w || !_h) break - gl.texImage2D( - GL_TEXTURE_2D$1, - i, - texture.format, - _w, - _h, - 0, - texture.format, - texture.type, - null) - } - tempRestore() - - // also, recompute the texture size. - if (config.profile) { - texture.stats.size = getTextureSize( - texture.internalformat, - texture.type, - w, - h, - false, - false) - } - - return reglTexture2D - } - - reglTexture2D(a, b) - - reglTexture2D.subimage = subimage - reglTexture2D.resize = resize - reglTexture2D._reglType = 'texture2d' - reglTexture2D._texture = texture - if (config.profile) { - reglTexture2D.stats = texture.stats - } - reglTexture2D.destroy = function () { - texture.decRef() - } - - return reglTexture2D - } - - function createTextureCube (a0, a1, a2, a3, a4, a5) { - var texture = new REGLTexture(GL_TEXTURE_CUBE_MAP$1) - textureSet[texture.id] = texture - stats.cubeCount++ - - var faces = new Array(6) - - function reglTextureCube (a0, a1, a2, a3, a4, a5) { - var i - var texInfo = texture.texInfo - TexInfo.call(texInfo) - for (i = 0; i < 6; ++i) { - faces[i] = allocMipMap() - } - - if (typeof a0 === 'number' || !a0) { - var s = (a0 | 0) || 1 - for (i = 0; i < 6; ++i) { - parseMipMapFromShape(faces[i], s, s) - } - } else if (typeof a0 === 'object') { - if (a1) { - parseMipMapFromObject(faces[0], a0) - parseMipMapFromObject(faces[1], a1) - parseMipMapFromObject(faces[2], a2) - parseMipMapFromObject(faces[3], a3) - parseMipMapFromObject(faces[4], a4) - parseMipMapFromObject(faces[5], a5) - } else { - parseTexInfo(texInfo, a0) - parseFlags(texture, a0) - if ('faces' in a0) { - var faceInput = a0.faces - - for (i = 0; i < 6; ++i) { - - copyFlags(faces[i], texture) - parseMipMapFromObject(faces[i], faceInput[i]) - } - } else { - for (i = 0; i < 6; ++i) { - parseMipMapFromObject(faces[i], a0) - } - } - } - } else { - - } - - copyFlags(texture, faces[0]) - - - if (texInfo.genMipmaps) { - texture.mipmask = (faces[0].width << 1) - 1 - } else { - texture.mipmask = faces[0].mipmask - } - - - texture.internalformat = faces[0].internalformat - - reglTextureCube.width = faces[0].width - reglTextureCube.height = faces[0].height - - tempBind(texture) - for (i = 0; i < 6; ++i) { - setMipMap(faces[i], GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + i) - } - setTexInfo(texInfo, GL_TEXTURE_CUBE_MAP$1) - tempRestore() - - if (config.profile) { - texture.stats.size = getTextureSize( - texture.internalformat, - texture.type, - reglTextureCube.width, - reglTextureCube.height, - texInfo.genMipmaps, - true) - } - - reglTextureCube.format = textureFormatsInvert[texture.internalformat] - reglTextureCube.type = textureTypesInvert[texture.type] - - reglTextureCube.mag = magFiltersInvert[texInfo.magFilter] - reglTextureCube.min = minFiltersInvert[texInfo.minFilter] - - reglTextureCube.wrapS = wrapModesInvert[texInfo.wrapS] - reglTextureCube.wrapT = wrapModesInvert[texInfo.wrapT] - - for (i = 0; i < 6; ++i) { - freeMipMap(faces[i]) - } - - return reglTextureCube - } - - function subimage (face, image, x_, y_, level_) { - - - - var x = x_ | 0 - var y = y_ | 0 - var level = level_ | 0 - - var imageData = allocImage() - copyFlags(imageData, texture) - imageData.width = 0 - imageData.height = 0 - parseImage(imageData, image) - imageData.width = imageData.width || ((texture.width >> level) - x) - imageData.height = imageData.height || ((texture.height >> level) - y) - - - - - - - tempBind(texture) - setSubImage(imageData, GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + face, x, y, level) - tempRestore() - - freeImage(imageData) - - return reglTextureCube - } - - function resize (radius_) { - var radius = radius_ | 0 - if (radius === texture.width) { - return - } - - reglTextureCube.width = texture.width = radius - reglTextureCube.height = texture.height = radius - - tempBind(texture) - for (var i = 0; i < 6; ++i) { - for (var j = 0; texture.mipmask >> j; ++j) { - gl.texImage2D( - GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + i, - j, - texture.format, - radius >> j, - radius >> j, - 0, - texture.format, - texture.type, - null) - } - } - tempRestore() - - if (config.profile) { - texture.stats.size = getTextureSize( - texture.internalformat, - texture.type, - reglTextureCube.width, - reglTextureCube.height, - false, - true) - } - - return reglTextureCube - } - - reglTextureCube(a0, a1, a2, a3, a4, a5) - - reglTextureCube.subimage = subimage - reglTextureCube.resize = resize - reglTextureCube._reglType = 'textureCube' - reglTextureCube._texture = texture - if (config.profile) { - reglTextureCube.stats = texture.stats - } - reglTextureCube.destroy = function () { - texture.decRef() - } - - return reglTextureCube - } - - // Called when regl is destroyed - function destroyTextures () { - for (var i = 0; i < numTexUnits; ++i) { - gl.activeTexture(GL_TEXTURE0$1 + i) - gl.bindTexture(GL_TEXTURE_2D$1, null) - textureUnits[i] = null - } - values(textureSet).forEach(destroy) - - stats.cubeCount = 0 - stats.textureCount = 0 - } - - if (config.profile) { - stats.getTotalTextureSize = function () { - var total = 0 - Object.keys(textureSet).forEach(function (key) { - total += textureSet[key].stats.size - }) - return total - } - } - - function restoreTextures () { - for (var i = 0; i < numTexUnits; ++i) { - var tex = textureUnits[i] - if (tex) { - tex.bindCount = 0 - tex.unit = -1 - textureUnits[i] = null - } - } - - values(textureSet).forEach(function (texture) { - texture.texture = gl.createTexture() - gl.bindTexture(texture.target, texture.texture) - for (var i = 0; i < 32; ++i) { - if ((texture.mipmask & (1 << i)) === 0) { - continue - } - if (texture.target === GL_TEXTURE_2D$1) { - gl.texImage2D(GL_TEXTURE_2D$1, - i, - texture.internalformat, - texture.width >> i, - texture.height >> i, - 0, - texture.internalformat, - texture.type, - null) - } else { - for (var j = 0; j < 6; ++j) { - gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + j, - i, - texture.internalformat, - texture.width >> i, - texture.height >> i, - 0, - texture.internalformat, - texture.type, - null) - } - } - } - setTexInfo(texture.texInfo, texture.target) - }) - } - - function refreshTextures () { - for (var i = 0; i < numTexUnits; ++i) { - var tex = textureUnits[i] - if (tex) { - tex.bindCount = 0 - tex.unit = -1 - textureUnits[i] = null - } - gl.activeTexture(GL_TEXTURE0$1 + i) - gl.bindTexture(GL_TEXTURE_2D$1, null) - gl.bindTexture(GL_TEXTURE_CUBE_MAP$1, null) - } - } - - return { - create2D: createTexture2D, - createCube: createTextureCube, - clear: destroyTextures, - getTexture: function (wrapper) { - return null - }, - restore: restoreTextures, - refresh: refreshTextures - } -} - -var GL_RENDERBUFFER = 0x8D41 - -var GL_RGBA4$1 = 0x8056 -var GL_RGB5_A1$1 = 0x8057 -var GL_RGB565$1 = 0x8D62 -var GL_DEPTH_COMPONENT16 = 0x81A5 -var GL_STENCIL_INDEX8 = 0x8D48 -var GL_DEPTH_STENCIL$1 = 0x84F9 - -var GL_SRGB8_ALPHA8_EXT = 0x8C43 - -var GL_RGBA32F_EXT = 0x8814 - -var GL_RGBA16F_EXT = 0x881A -var GL_RGB16F_EXT = 0x881B - -var FORMAT_SIZES = [] - -FORMAT_SIZES[GL_RGBA4$1] = 2 -FORMAT_SIZES[GL_RGB5_A1$1] = 2 -FORMAT_SIZES[GL_RGB565$1] = 2 - -FORMAT_SIZES[GL_DEPTH_COMPONENT16] = 2 -FORMAT_SIZES[GL_STENCIL_INDEX8] = 1 -FORMAT_SIZES[GL_DEPTH_STENCIL$1] = 4 - -FORMAT_SIZES[GL_SRGB8_ALPHA8_EXT] = 4 -FORMAT_SIZES[GL_RGBA32F_EXT] = 16 -FORMAT_SIZES[GL_RGBA16F_EXT] = 8 -FORMAT_SIZES[GL_RGB16F_EXT] = 6 - -function getRenderbufferSize (format, width, height) { - return FORMAT_SIZES[format] * width * height -} - -var wrapRenderbuffers = function (gl, extensions, limits, stats, config) { - var formatTypes = { - 'rgba4': GL_RGBA4$1, - 'rgb565': GL_RGB565$1, - 'rgb5 a1': GL_RGB5_A1$1, - 'depth': GL_DEPTH_COMPONENT16, - 'stencil': GL_STENCIL_INDEX8, - 'depth stencil': GL_DEPTH_STENCIL$1 - } - - if (extensions.ext_srgb) { - formatTypes['srgba'] = GL_SRGB8_ALPHA8_EXT - } - - if (extensions.ext_color_buffer_half_float) { - formatTypes['rgba16f'] = GL_RGBA16F_EXT - formatTypes['rgb16f'] = GL_RGB16F_EXT - } - - if (extensions.webgl_color_buffer_float) { - formatTypes['rgba32f'] = GL_RGBA32F_EXT - } - - var formatTypesInvert = [] - Object.keys(formatTypes).forEach(function (key) { - var val = formatTypes[key] - formatTypesInvert[val] = key - }) - - var renderbufferCount = 0 - var renderbufferSet = {} - - function REGLRenderbuffer (renderbuffer) { - this.id = renderbufferCount++ - this.refCount = 1 - - this.renderbuffer = renderbuffer - - this.format = GL_RGBA4$1 - this.width = 0 - this.height = 0 - - if (config.profile) { - this.stats = { size: 0 } - } - } - - REGLRenderbuffer.prototype.decRef = function () { - if (--this.refCount <= 0) { - destroy(this) - } - } - - function destroy (rb) { - var handle = rb.renderbuffer - - gl.bindRenderbuffer(GL_RENDERBUFFER, null) - gl.deleteRenderbuffer(handle) - rb.renderbuffer = null - rb.refCount = 0 - delete renderbufferSet[rb.id] - stats.renderbufferCount-- - } - - function createRenderbuffer (a, b) { - var renderbuffer = new REGLRenderbuffer(gl.createRenderbuffer()) - renderbufferSet[renderbuffer.id] = renderbuffer - stats.renderbufferCount++ - - function reglRenderbuffer (a, b) { - var w = 0 - var h = 0 - var format = GL_RGBA4$1 - - if (typeof a === 'object' && a) { - var options = a - if ('shape' in options) { - var shape = options.shape - - w = shape[0] | 0 - h = shape[1] | 0 - } else { - if ('radius' in options) { - w = h = options.radius | 0 - } - if ('width' in options) { - w = options.width | 0 - } - if ('height' in options) { - h = options.height | 0 - } - } - if ('format' in options) { - - format = formatTypes[options.format] - } - } else if (typeof a === 'number') { - w = a | 0 - if (typeof b === 'number') { - h = b | 0 - } else { - h = w - } - } else if (!a) { - w = h = 1 - } else { - - } - - // check shape - - - if (w === renderbuffer.width && - h === renderbuffer.height && - format === renderbuffer.format) { - return - } - - reglRenderbuffer.width = renderbuffer.width = w - reglRenderbuffer.height = renderbuffer.height = h - renderbuffer.format = format - - gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer.renderbuffer) - gl.renderbufferStorage(GL_RENDERBUFFER, format, w, h) - - - - if (config.profile) { - renderbuffer.stats.size = getRenderbufferSize(renderbuffer.format, renderbuffer.width, renderbuffer.height) - } - reglRenderbuffer.format = formatTypesInvert[renderbuffer.format] - - return reglRenderbuffer - } - - function resize (w_, h_) { - var w = w_ | 0 - var h = (h_ | 0) || w - - if (w === renderbuffer.width && h === renderbuffer.height) { - return reglRenderbuffer - } - - // check shape - - - reglRenderbuffer.width = renderbuffer.width = w - reglRenderbuffer.height = renderbuffer.height = h - - gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer.renderbuffer) - gl.renderbufferStorage(GL_RENDERBUFFER, renderbuffer.format, w, h) - - - - // also, recompute size. - if (config.profile) { - renderbuffer.stats.size = getRenderbufferSize( - renderbuffer.format, renderbuffer.width, renderbuffer.height) - } - - return reglRenderbuffer - } - - reglRenderbuffer(a, b) - - reglRenderbuffer.resize = resize - reglRenderbuffer._reglType = 'renderbuffer' - reglRenderbuffer._renderbuffer = renderbuffer - if (config.profile) { - reglRenderbuffer.stats = renderbuffer.stats - } - reglRenderbuffer.destroy = function () { - renderbuffer.decRef() - } - - return reglRenderbuffer - } - - if (config.profile) { - stats.getTotalRenderbufferSize = function () { - var total = 0 - Object.keys(renderbufferSet).forEach(function (key) { - total += renderbufferSet[key].stats.size - }) - return total - } - } - - function restoreRenderbuffers () { - values(renderbufferSet).forEach(function (rb) { - rb.renderbuffer = gl.createRenderbuffer() - gl.bindRenderbuffer(GL_RENDERBUFFER, rb.renderbuffer) - gl.renderbufferStorage(GL_RENDERBUFFER, rb.format, rb.width, rb.height) - }) - gl.bindRenderbuffer(GL_RENDERBUFFER, null) - } - - return { - create: createRenderbuffer, - clear: function () { - values(renderbufferSet).forEach(destroy) - }, - restore: restoreRenderbuffers - } -} - -// We store these constants so that the minifier can inline them -var GL_FRAMEBUFFER$1 = 0x8D40 -var GL_RENDERBUFFER$1 = 0x8D41 - -var GL_TEXTURE_2D$2 = 0x0DE1 -var GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 = 0x8515 - -var GL_COLOR_ATTACHMENT0$1 = 0x8CE0 -var GL_DEPTH_ATTACHMENT = 0x8D00 -var GL_STENCIL_ATTACHMENT = 0x8D20 -var GL_DEPTH_STENCIL_ATTACHMENT = 0x821A - -var GL_FRAMEBUFFER_COMPLETE$1 = 0x8CD5 -var GL_HALF_FLOAT_OES$1 = 0x8D61 -var GL_UNSIGNED_BYTE$5 = 0x1401 -var GL_FLOAT$4 = 0x1406 - -var GL_RGB$1 = 0x1907 -var GL_RGBA$2 = 0x1908 - -// for every texture format, store -// the number of channels -var textureFormatChannels = [] -textureFormatChannels[GL_RGBA$2] = 4 -textureFormatChannels[GL_RGB$1] = 3 - -// for every texture type, store -// the size in bytes. -var textureTypeSizes = [] -textureTypeSizes[GL_UNSIGNED_BYTE$5] = 1 -textureTypeSizes[GL_FLOAT$4] = 4 -textureTypeSizes[GL_HALF_FLOAT_OES$1] = 2 - -function wrapFBOState ( - gl, - extensions, - limits, - textureState, - renderbufferState, - stats) { - var framebufferState = { - cur: null, - next: null, - dirty: false, - setFBO: null - } - - var colorTextureFormats = ['rgba'] - var colorRenderbufferFormats = ['rgba4', 'rgb565', 'rgb5 a1'] - - if (extensions.ext_srgb) { - colorRenderbufferFormats.push('srgba') - } - - if (extensions.ext_color_buffer_half_float) { - colorRenderbufferFormats.push('rgba16f', 'rgb16f') - } - - if (extensions.webgl_color_buffer_float) { - colorRenderbufferFormats.push('rgba32f') - } - - var colorTypes = ['uint8'] - if (extensions.oes_texture_half_float) { - colorTypes.push('half float', 'float16') - } - if (extensions.oes_texture_float) { - colorTypes.push('float', 'float32') - } - - function FramebufferAttachment (target, texture, renderbuffer) { - this.target = target - this.texture = texture - this.renderbuffer = renderbuffer - - var w = 0 - var h = 0 - if (texture) { - w = texture.width - h = texture.height - } else if (renderbuffer) { - w = renderbuffer.width - h = renderbuffer.height - } - this.width = w - this.height = h - } - - function decRef (attachment) { - if (attachment) { - if (attachment.texture) { - attachment.texture._texture.decRef() - } - if (attachment.renderbuffer) { - attachment.renderbuffer._renderbuffer.decRef() - } - } - } - - function incRefAndCheckShape (attachment, width, height) { - if (!attachment) { - return - } - if (attachment.texture) { - var texture = attachment.texture._texture - var tw = Math.max(1, texture.width) - var th = Math.max(1, texture.height) - - texture.refCount += 1 - } else { - var renderbuffer = attachment.renderbuffer._renderbuffer - - renderbuffer.refCount += 1 - } - } - - function attach (location, attachment) { - if (attachment) { - if (attachment.texture) { - gl.framebufferTexture2D( - GL_FRAMEBUFFER$1, - location, - attachment.target, - attachment.texture._texture.texture, - 0) - } else { - gl.framebufferRenderbuffer( - GL_FRAMEBUFFER$1, - location, - GL_RENDERBUFFER$1, - attachment.renderbuffer._renderbuffer.renderbuffer) - } - } - } - - function parseAttachment (attachment) { - var target = GL_TEXTURE_2D$2 - var texture = null - var renderbuffer = null - - var data = attachment - if (typeof attachment === 'object') { - data = attachment.data - if ('target' in attachment) { - target = attachment.target | 0 - } - } - - - - var type = data._reglType - if (type === 'texture2d') { - texture = data - - } else if (type === 'textureCube') { - texture = data - - } else if (type === 'renderbuffer') { - renderbuffer = data - target = GL_RENDERBUFFER$1 - } else { - - } - - return new FramebufferAttachment(target, texture, renderbuffer) - } - - function allocAttachment ( - width, - height, - isTexture, - format, - type) { - if (isTexture) { - var texture = textureState.create2D({ - width: width, - height: height, - format: format, - type: type - }) - texture._texture.refCount = 0 - return new FramebufferAttachment(GL_TEXTURE_2D$2, texture, null) - } else { - var rb = renderbufferState.create({ - width: width, - height: height, - format: format - }) - rb._renderbuffer.refCount = 0 - return new FramebufferAttachment(GL_RENDERBUFFER$1, null, rb) - } - } - - function unwrapAttachment (attachment) { - return attachment && (attachment.texture || attachment.renderbuffer) - } - - function resizeAttachment (attachment, w, h) { - if (attachment) { - if (attachment.texture) { - attachment.texture.resize(w, h) - } else if (attachment.renderbuffer) { - attachment.renderbuffer.resize(w, h) - } - attachment.width = w - attachment.height = h - } - } - - var framebufferCount = 0 - var framebufferSet = {} - - function REGLFramebuffer () { - this.id = framebufferCount++ - framebufferSet[this.id] = this - - this.framebuffer = gl.createFramebuffer() - this.width = 0 - this.height = 0 - - this.colorAttachments = [] - this.depthAttachment = null - this.stencilAttachment = null - this.depthStencilAttachment = null - } - - function decFBORefs (framebuffer) { - framebuffer.colorAttachments.forEach(decRef) - decRef(framebuffer.depthAttachment) - decRef(framebuffer.stencilAttachment) - decRef(framebuffer.depthStencilAttachment) - } - - function destroy (framebuffer) { - var handle = framebuffer.framebuffer - - gl.deleteFramebuffer(handle) - framebuffer.framebuffer = null - stats.framebufferCount-- - delete framebufferSet[framebuffer.id] - } - - function updateFramebuffer (framebuffer) { - var i - - gl.bindFramebuffer(GL_FRAMEBUFFER$1, framebuffer.framebuffer) - var colorAttachments = framebuffer.colorAttachments - for (i = 0; i < colorAttachments.length; ++i) { - attach(GL_COLOR_ATTACHMENT0$1 + i, colorAttachments[i]) - } - for (i = colorAttachments.length; i < limits.maxColorAttachments; ++i) { - gl.framebufferTexture2D( - GL_FRAMEBUFFER$1, - GL_COLOR_ATTACHMENT0$1 + i, - GL_TEXTURE_2D$2, - null, - 0) - } - - gl.framebufferTexture2D( - GL_FRAMEBUFFER$1, - GL_DEPTH_STENCIL_ATTACHMENT, - GL_TEXTURE_2D$2, - null, - 0) - gl.framebufferTexture2D( - GL_FRAMEBUFFER$1, - GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D$2, - null, - 0) - gl.framebufferTexture2D( - GL_FRAMEBUFFER$1, - GL_STENCIL_ATTACHMENT, - GL_TEXTURE_2D$2, - null, - 0) - - attach(GL_DEPTH_ATTACHMENT, framebuffer.depthAttachment) - attach(GL_STENCIL_ATTACHMENT, framebuffer.stencilAttachment) - attach(GL_DEPTH_STENCIL_ATTACHMENT, framebuffer.depthStencilAttachment) - - // Check status code - var status = gl.checkFramebufferStatus(GL_FRAMEBUFFER$1) - if (!gl.isContextLost() && status !== GL_FRAMEBUFFER_COMPLETE$1) { - - } - - gl.bindFramebuffer(GL_FRAMEBUFFER$1, framebufferState.next ? framebufferState.next.framebuffer : null) - framebufferState.cur = framebufferState.next - - // FIXME: Clear error code here. This is a work around for a bug in - // headless-gl - gl.getError() - } - - function createFBO (a0, a1) { - var framebuffer = new REGLFramebuffer() - stats.framebufferCount++ - - function reglFramebuffer (a, b) { - var i - - - - var width = 0 - var height = 0 - - var needsDepth = true - var needsStencil = true - - var colorBuffer = null - var colorTexture = true - var colorFormat = 'rgba' - var colorType = 'uint8' - var colorCount = 1 - - var depthBuffer = null - var stencilBuffer = null - var depthStencilBuffer = null - var depthStencilTexture = false - - if (typeof a === 'number') { - width = a | 0 - height = (b | 0) || width - } else if (!a) { - width = height = 1 - } else { - - var options = a - - if ('shape' in options) { - var shape = options.shape - - width = shape[0] - height = shape[1] - } else { - if ('radius' in options) { - width = height = options.radius - } - if ('width' in options) { - width = options.width - } - if ('height' in options) { - height = options.height - } - } - - if ('color' in options || - 'colors' in options) { - colorBuffer = - options.color || - options.colors - if (Array.isArray(colorBuffer)) { - - } - } - - if (!colorBuffer) { - if ('colorCount' in options) { - colorCount = options.colorCount | 0 - - } - - if ('colorTexture' in options) { - colorTexture = !!options.colorTexture - colorFormat = 'rgba4' - } - - if ('colorType' in options) { - colorType = options.colorType - if (!colorTexture) { - if (colorType === 'half float' || colorType === 'float16') { - - colorFormat = 'rgba16f' - } else if (colorType === 'float' || colorType === 'float32') { - - colorFormat = 'rgba32f' - } - } else { - - - } - - } - - if ('colorFormat' in options) { - colorFormat = options.colorFormat - if (colorTextureFormats.indexOf(colorFormat) >= 0) { - colorTexture = true - } else if (colorRenderbufferFormats.indexOf(colorFormat) >= 0) { - colorTexture = false - } else { - - } - } - } - - if ('depthTexture' in options || 'depthStencilTexture' in options) { - depthStencilTexture = !!(options.depthTexture || - options.depthStencilTexture) - - } - - if ('depth' in options) { - if (typeof options.depth === 'boolean') { - needsDepth = options.depth - } else { - depthBuffer = options.depth - needsStencil = false - } - } - - if ('stencil' in options) { - if (typeof options.stencil === 'boolean') { - needsStencil = options.stencil - } else { - stencilBuffer = options.stencil - needsDepth = false - } - } - - if ('depthStencil' in options) { - if (typeof options.depthStencil === 'boolean') { - needsDepth = needsStencil = options.depthStencil - } else { - depthStencilBuffer = options.depthStencil - needsDepth = false - needsStencil = false - } - } - } - - // parse attachments - var colorAttachments = null - var depthAttachment = null - var stencilAttachment = null - var depthStencilAttachment = null - - // Set up color attachments - if (Array.isArray(colorBuffer)) { - colorAttachments = colorBuffer.map(parseAttachment) - } else if (colorBuffer) { - colorAttachments = [parseAttachment(colorBuffer)] - } else { - colorAttachments = new Array(colorCount) - for (i = 0; i < colorCount; ++i) { - colorAttachments[i] = allocAttachment( - width, - height, - colorTexture, - colorFormat, - colorType) - } - } - - - - - width = width || colorAttachments[0].width - height = height || colorAttachments[0].height - - if (depthBuffer) { - depthAttachment = parseAttachment(depthBuffer) - } else if (needsDepth && !needsStencil) { - depthAttachment = allocAttachment( - width, - height, - depthStencilTexture, - 'depth', - 'uint32') - } - - if (stencilBuffer) { - stencilAttachment = parseAttachment(stencilBuffer) - } else if (needsStencil && !needsDepth) { - stencilAttachment = allocAttachment( - width, - height, - false, - 'stencil', - 'uint8') - } - - if (depthStencilBuffer) { - depthStencilAttachment = parseAttachment(depthStencilBuffer) - } else if (!depthBuffer && !stencilBuffer && needsStencil && needsDepth) { - depthStencilAttachment = allocAttachment( - width, - height, - depthStencilTexture, - 'depth stencil', - 'depth stencil') - } - - - - var commonColorAttachmentSize = null - - for (i = 0; i < colorAttachments.length; ++i) { - incRefAndCheckShape(colorAttachments[i], width, height) - - - if (colorAttachments[i] && colorAttachments[i].texture) { - var colorAttachmentSize = - textureFormatChannels[colorAttachments[i].texture._texture.format] * - textureTypeSizes[colorAttachments[i].texture._texture.type] - - if (commonColorAttachmentSize === null) { - commonColorAttachmentSize = colorAttachmentSize - } else { - // We need to make sure that all color attachments have the same number of bitplanes - // (that is, the same numer of bits per pixel) - // This is required by the GLES2.0 standard. See the beginning of Chapter 4 in that document. - - } - } - } - incRefAndCheckShape(depthAttachment, width, height) - - incRefAndCheckShape(stencilAttachment, width, height) - - incRefAndCheckShape(depthStencilAttachment, width, height) - - - // decrement references - decFBORefs(framebuffer) - - framebuffer.width = width - framebuffer.height = height - - framebuffer.colorAttachments = colorAttachments - framebuffer.depthAttachment = depthAttachment - framebuffer.stencilAttachment = stencilAttachment - framebuffer.depthStencilAttachment = depthStencilAttachment - - reglFramebuffer.color = colorAttachments.map(unwrapAttachment) - reglFramebuffer.depth = unwrapAttachment(depthAttachment) - reglFramebuffer.stencil = unwrapAttachment(stencilAttachment) - reglFramebuffer.depthStencil = unwrapAttachment(depthStencilAttachment) - - reglFramebuffer.width = framebuffer.width - reglFramebuffer.height = framebuffer.height - - updateFramebuffer(framebuffer) - - return reglFramebuffer - } - - function resize (w_, h_) { - - - var w = Math.max(w_ | 0, 1) - var h = Math.max((h_ | 0) || w, 1) - if (w === framebuffer.width && h === framebuffer.height) { - return reglFramebuffer - } - - // resize all buffers - var colorAttachments = framebuffer.colorAttachments - for (var i = 0; i < colorAttachments.length; ++i) { - resizeAttachment(colorAttachments[i], w, h) - } - resizeAttachment(framebuffer.depthAttachment, w, h) - resizeAttachment(framebuffer.stencilAttachment, w, h) - resizeAttachment(framebuffer.depthStencilAttachment, w, h) - - framebuffer.width = reglFramebuffer.width = w - framebuffer.height = reglFramebuffer.height = h - - updateFramebuffer(framebuffer) - - return reglFramebuffer - } - - reglFramebuffer(a0, a1) - - return extend(reglFramebuffer, { - resize: resize, - _reglType: 'framebuffer', - _framebuffer: framebuffer, - destroy: function () { - destroy(framebuffer) - decFBORefs(framebuffer) - }, - use: function (block) { - framebufferState.setFBO({ - framebuffer: reglFramebuffer - }, block) - } - }) - } - - function createCubeFBO (options) { - var faces = Array(6) - - function reglFramebufferCube (a) { - var i - - - - var params = { - color: null - } - - var radius = 0 - - var colorBuffer = null - var colorFormat = 'rgba' - var colorType = 'uint8' - var colorCount = 1 - - if (typeof a === 'number') { - radius = a | 0 - } else if (!a) { - radius = 1 - } else { - - var options = a - - if ('shape' in options) { - var shape = options.shape - - - radius = shape[0] - } else { - if ('radius' in options) { - radius = options.radius | 0 - } - if ('width' in options) { - radius = options.width | 0 - if ('height' in options) { - - } - } else if ('height' in options) { - radius = options.height | 0 - } - } - - if ('color' in options || - 'colors' in options) { - colorBuffer = - options.color || - options.colors - if (Array.isArray(colorBuffer)) { - - } - } - - if (!colorBuffer) { - if ('colorCount' in options) { - colorCount = options.colorCount | 0 - - } - - if ('colorType' in options) { - - colorType = options.colorType - } - - if ('colorFormat' in options) { - colorFormat = options.colorFormat - - } - } - - if ('depth' in options) { - params.depth = options.depth - } - - if ('stencil' in options) { - params.stencil = options.stencil - } - - if ('depthStencil' in options) { - params.depthStencil = options.depthStencil - } - } - - var colorCubes - if (colorBuffer) { - if (Array.isArray(colorBuffer)) { - colorCubes = [] - for (i = 0; i < colorBuffer.length; ++i) { - colorCubes[i] = colorBuffer[i] - } - } else { - colorCubes = [ colorBuffer ] - } - } else { - colorCubes = Array(colorCount) - var cubeMapParams = { - radius: radius, - format: colorFormat, - type: colorType - } - for (i = 0; i < colorCount; ++i) { - colorCubes[i] = textureState.createCube(cubeMapParams) - } - } - - // Check color cubes - params.color = Array(colorCubes.length) - for (i = 0; i < colorCubes.length; ++i) { - var cube = colorCubes[i] - - radius = radius || cube.width - - params.color[i] = { - target: GL_TEXTURE_CUBE_MAP_POSITIVE_X$2, - data: colorCubes[i] - } - } - - for (i = 0; i < 6; ++i) { - for (var j = 0; j < colorCubes.length; ++j) { - params.color[j].target = GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 + i - } - // reuse depth-stencil attachments across all cube maps - if (i > 0) { - params.depth = faces[0].depth - params.stencil = faces[0].stencil - params.depthStencil = faces[0].depthStencil - } - if (faces[i]) { - (faces[i])(params) - } else { - faces[i] = createFBO(params) - } - } - - return extend(reglFramebufferCube, { - width: radius, - height: radius, - color: colorCubes - }) - } - - function resize (radius_) { - var i - var radius = radius_ | 0 - - - if (radius === reglFramebufferCube.width) { - return reglFramebufferCube - } - - var colors = reglFramebufferCube.color - for (i = 0; i < colors.length; ++i) { - colors[i].resize(radius) - } - - for (i = 0; i < 6; ++i) { - faces[i].resize(radius) - } - - reglFramebufferCube.width = reglFramebufferCube.height = radius - - return reglFramebufferCube - } - - reglFramebufferCube(options) - - return extend(reglFramebufferCube, { - faces: faces, - resize: resize, - _reglType: 'framebufferCube', - destroy: function () { - faces.forEach(function (f) { - f.destroy() - }) - } - }) - } - - function restoreFramebuffers () { - framebufferState.cur = null - framebufferState.next = null - framebufferState.dirty = true - values(framebufferSet).forEach(function (fb) { - fb.framebuffer = gl.createFramebuffer() - updateFramebuffer(fb) - }) - } - - return extend(framebufferState, { - getFramebuffer: function (object) { - if (typeof object === 'function' && object._reglType === 'framebuffer') { - var fbo = object._framebuffer - if (fbo instanceof REGLFramebuffer) { - return fbo - } - } - return null - }, - create: createFBO, - createCube: createCubeFBO, - clear: function () { - values(framebufferSet).forEach(destroy) - }, - restore: restoreFramebuffers - }) -} - -var GL_FLOAT$5 = 5126 -var GL_ARRAY_BUFFER$1 = 34962 -var GL_ELEMENT_ARRAY_BUFFER$1 = 34963 - -function AttributeRecord () { - this.state = 0 - - this.x = 0.0 - this.y = 0.0 - this.z = 0.0 - this.w = 0.0 - - this.buffer = null - this.size = 0 - this.normalized = false - this.type = GL_FLOAT$5 - this.offset = 0 - this.stride = 0 - this.divisor = 0 -} - -function wrapAttributeState ( - gl, - extensions, - limits, - stats, - bufferState, - elementState, - drawState) { - var NUM_ATTRIBUTES = limits.maxAttributes - var attributeBindings = new Array(NUM_ATTRIBUTES) - for (var i = 0; i < NUM_ATTRIBUTES; ++i) { - attributeBindings[i] = new AttributeRecord() - } - var vaoCount = 0 - var vaoSet = {} - - var state = { - Record: AttributeRecord, - scope: {}, - state: attributeBindings, - currentVAO: null, - targetVAO: null, - restore: extVAO() ? restoreVAO : function () {}, - createVAO: createVAO, - getVAO: getVAO, - destroyBuffer: destroyBuffer, - setVAO: extVAO() ? setVAOEXT : setVAOEmulated, - clear: extVAO() ? destroyVAOEXT : function () {} - } - - function destroyBuffer (buffer) { - for (var i = 0; i < attributeBindings.length; ++i) { - var record = attributeBindings[i] - if (record.buffer === buffer) { - gl.disableVertexAttribArray(i) - record.buffer = null - } - } - } - - function extVAO () { - return extensions.oes_vertex_array_object - } - - function extInstanced () { - return extensions.angle_instanced_arrays - } - - function getVAO (vao) { - if (typeof vao === 'function' && vao._vao) { - return vao._vao - } - return null - } - - function setVAOEXT (vao) { - if (vao === state.currentVAO) { - return - } - var ext = extVAO() - if (vao) { - ext.bindVertexArrayOES(vao.vao) - } else { - ext.bindVertexArrayOES(null) - } - state.currentVAO = vao - } - - function setVAOEmulated (vao) { - if (vao === state.currentVAO) { - return - } - if (vao) { - vao.bindAttrs() - } else { - var exti = extInstanced() - for (var i = 0; i < attributeBindings.length; ++i) { - var binding = attributeBindings[i] - if (binding.buffer) { - gl.enableVertexAttribArray(i) - binding.buffer.bind() - gl.vertexAttribPointer(i, binding.size, binding.type, binding.normalized, binding.stride, binding.offfset) - if (exti && binding.divisor) { - exti.vertexAttribDivisorANGLE(i, binding.divisor) - } - } else { - gl.disableVertexAttribArray(i) - gl.vertexAttrib4f(i, binding.x, binding.y, binding.z, binding.w) - } - } - if (drawState.elements) { - gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER$1, drawState.elements.buffer.buffer) - } else { - gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER$1, null) - } - } - state.currentVAO = vao - } - - function destroyVAOEXT () { - values(vaoSet).forEach(function (vao) { - vao.destroy() - }) - } - - function REGLVAO () { - this.id = ++vaoCount - this.attributes = [] - this.elements = null - this.ownsElements = false - this.count = 0 - this.offset = 0 - this.instances = -1 - this.primitive = 4 - var extension = extVAO() - if (extension) { - this.vao = extension.createVertexArrayOES() - } else { - this.vao = null - } - vaoSet[this.id] = this - this.buffers = [] - } - - REGLVAO.prototype.bindAttrs = function () { - var exti = extInstanced() - var attributes = this.attributes - for (var i = 0; i < attributes.length; ++i) { - var attr = attributes[i] - if (attr.buffer) { - gl.enableVertexAttribArray(i) - gl.bindBuffer(GL_ARRAY_BUFFER$1, attr.buffer.buffer) - gl.vertexAttribPointer(i, attr.size, attr.type, attr.normalized, attr.stride, attr.offset) - if (exti && attr.divisor) { - exti.vertexAttribDivisorANGLE(i, attr.divisor) - } - } else { - gl.disableVertexAttribArray(i) - gl.vertexAttrib4f(i, attr.x, attr.y, attr.z, attr.w) - } - } - for (var j = attributes.length; j < NUM_ATTRIBUTES; ++j) { - gl.disableVertexAttribArray(j) - } - var elements = elementState.getElements(this.elements) - if (elements) { - gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER$1, elements.buffer.buffer) - } else { - gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER$1, null) - } - } - - REGLVAO.prototype.refresh = function () { - var ext = extVAO() - if (ext) { - ext.bindVertexArrayOES(this.vao) - this.bindAttrs() - state.currentVAO = null - ext.bindVertexArrayOES(null) - } - } - - REGLVAO.prototype.destroy = function () { - if (this.vao) { - var extension = extVAO() - if (this === state.currentVAO) { - state.currentVAO = null - extension.bindVertexArrayOES(null) - } - extension.deleteVertexArrayOES(this.vao) - this.vao = null - } - if (this.ownsElements) { - this.elements.destroy() - this.elements = null - this.ownsElements = false - } - if (vaoSet[this.id]) { - delete vaoSet[this.id] - stats.vaoCount -= 1 - } - } - - function restoreVAO () { - var ext = extVAO() - if (ext) { - values(vaoSet).forEach(function (vao) { - vao.refresh() - }) - } - } - - function createVAO (_attr) { - var vao = new REGLVAO() - stats.vaoCount += 1 - - function updateVAO (options) { - var attributes - if (Array.isArray(options)) { - attributes = options - if (vao.elements && vao.ownsElements) { - vao.elements.destroy() - } - vao.elements = null - vao.ownsElements = false - vao.offset = 0 - vao.count = 0 - vao.instances = -1 - vao.primitive = 4 - } else { - - - if (options.elements) { - var elements = options.elements - if (vao.ownsElements) { - if (typeof elements === 'function' && elements._reglType === 'elements') { - vao.elements.destroy() - vao.ownsElements = false - } else { - vao.elements(elements) - vao.ownsElements = false - } - } else if (elementState.getElements(options.elements)) { - vao.elements = options.elements - vao.ownsElements = false - } else { - vao.elements = elementState.create(options.elements) - vao.ownsElements = true - } - } else { - vao.elements = null - vao.ownsElements = false - } - attributes = options.attributes - - // set default vao - vao.offset = 0 - vao.count = -1 - vao.instances = -1 - vao.primitive = 4 - - // copy element properties - if (vao.elements) { - vao.count = vao.elements._elements.vertCount - vao.primitive = vao.elements._elements.primType - } - - if ('offset' in options) { - vao.offset = options.offset | 0 - } - if ('count' in options) { - vao.count = options.count | 0 - } - if ('instances' in options) { - vao.instances = options.instances | 0 - } - if ('primitive' in options) { - - vao.primitive = primTypes[options.primitive] - } - - - - } - - - - - var bufUpdated = {} - var nattributes = vao.attributes - nattributes.length = attributes.length - for (var i = 0; i < attributes.length; ++i) { - var spec = attributes[i] - var rec = nattributes[i] = new AttributeRecord() - var data = spec.data || spec - if (Array.isArray(data) || isTypedArray(data) || isNDArrayLike(data)) { - var buf - if (vao.buffers[i]) { - buf = vao.buffers[i] - if (isTypedArray(data) && buf._buffer.byteLength >= data.byteLength) { - buf.subdata(data) - } else { - buf.destroy() - vao.buffers[i] = null - } - } - if (!vao.buffers[i]) { - buf = vao.buffers[i] = bufferState.create(spec, GL_ARRAY_BUFFER$1, false, true) - } - rec.buffer = bufferState.getBuffer(buf) - rec.size = rec.buffer.dimension | 0 - rec.normalized = false - rec.type = rec.buffer.dtype - rec.offset = 0 - rec.stride = 0 - rec.divisor = 0 - rec.state = 1 - bufUpdated[i] = 1 - } else if (bufferState.getBuffer(spec)) { - rec.buffer = bufferState.getBuffer(spec) - rec.size = rec.buffer.dimension | 0 - rec.normalized = false - rec.type = rec.buffer.dtype - rec.offset = 0 - rec.stride = 0 - rec.divisor = 0 - rec.state = 1 - } else if (bufferState.getBuffer(spec.buffer)) { - rec.buffer = bufferState.getBuffer(spec.buffer) - rec.size = ((+spec.size) || rec.buffer.dimension) | 0 - rec.normalized = !!spec.normalized || false - if ('type' in spec) { - - rec.type = glTypes[spec.type] - } else { - rec.type = rec.buffer.dtype - } - rec.offset = (spec.offset || 0) | 0 - rec.stride = (spec.stride || 0) | 0 - rec.divisor = (spec.divisor || 0) | 0 - rec.state = 1 - - - - - - - } else if ('x' in spec) { - - rec.x = +spec.x || 0 - rec.y = +spec.y || 0 - rec.z = +spec.z || 0 - rec.w = +spec.w || 0 - rec.state = 2 - } else { - - } - } - - // retire unused buffers - for (var j = 0; j < vao.buffers.length; ++j) { - if (!bufUpdated[j] && vao.buffers[j]) { - vao.buffers[j].destroy() - vao.buffers[j] = null - } - } - - vao.refresh() - return updateVAO - } - - updateVAO.destroy = function () { - for (var j = 0; j < vao.buffers.length; ++j) { - if (vao.buffers[j]) { - vao.buffers[j].destroy() - } - } - vao.buffers.length = 0 - - if (vao.ownsElements) { - vao.elements.destroy() - vao.elements = null - vao.ownsElements = false - } - - vao.destroy() - } - - updateVAO._vao = vao - updateVAO._reglType = 'vao' - - return updateVAO(_attr) - } - - return state -} - -var GL_FRAGMENT_SHADER = 35632 -var GL_VERTEX_SHADER = 35633 - -var GL_ACTIVE_UNIFORMS = 0x8B86 -var GL_ACTIVE_ATTRIBUTES = 0x8B89 - -function wrapShaderState (gl, stringStore, stats, config) { - // =================================================== - // glsl compilation and linking - // =================================================== - var fragShaders = {} - var vertShaders = {} - - function ActiveInfo (name, id, location, info) { - this.name = name - this.id = id - this.location = location - this.info = info - } - - function insertActiveInfo (list, info) { - for (var i = 0; i < list.length; ++i) { - if (list[i].id === info.id) { - list[i].location = info.location - return - } - } - list.push(info) - } - - function getShader (type, id, command) { - var cache = type === GL_FRAGMENT_SHADER ? fragShaders : vertShaders - var shader = cache[id] - - if (!shader) { - var source = stringStore.str(id) - shader = gl.createShader(type) - gl.shaderSource(shader, source) - gl.compileShader(shader) - - cache[id] = shader - } - - return shader - } - - // =================================================== - // program linking - // =================================================== - var programCache = {} - var programList = [] - - var PROGRAM_COUNTER = 0 - - function REGLProgram (fragId, vertId) { - this.id = PROGRAM_COUNTER++ - this.fragId = fragId - this.vertId = vertId - this.program = null - this.uniforms = [] - this.attributes = [] - this.refCount = 1 - - if (config.profile) { - this.stats = { - uniformsCount: 0, - attributesCount: 0 - } - } - } - - function linkProgram (desc, command, attributeLocations) { - var i, info - - // ------------------------------- - // compile & link - // ------------------------------- - var fragShader = getShader(GL_FRAGMENT_SHADER, desc.fragId) - var vertShader = getShader(GL_VERTEX_SHADER, desc.vertId) - - var program = desc.program = gl.createProgram() - gl.attachShader(program, fragShader) - gl.attachShader(program, vertShader) - if (attributeLocations) { - for (i = 0; i < attributeLocations.length; ++i) { - var binding = attributeLocations[i] - gl.bindAttribLocation(program, binding[0], binding[1]) - } - } - - gl.linkProgram(program) - - - // ------------------------------- - // grab uniforms - // ------------------------------- - var numUniforms = gl.getProgramParameter(program, GL_ACTIVE_UNIFORMS) - if (config.profile) { - desc.stats.uniformsCount = numUniforms - } - var uniforms = desc.uniforms - for (i = 0; i < numUniforms; ++i) { - info = gl.getActiveUniform(program, i) - if (info) { - if (info.size > 1) { - for (var j = 0; j < info.size; ++j) { - var name = info.name.replace('[0]', '[' + j + ']') - insertActiveInfo(uniforms, new ActiveInfo( - name, - stringStore.id(name), - gl.getUniformLocation(program, name), - info)) - } - } - var uniName = info.name - if (info.size > 1) { - uniName = uniName.replace('[0]', '') - } - insertActiveInfo(uniforms, new ActiveInfo( - uniName, - stringStore.id(uniName), - gl.getUniformLocation(program, uniName), - info)) - } - } - - // ------------------------------- - // grab attributes - // ------------------------------- - var numAttributes = gl.getProgramParameter(program, GL_ACTIVE_ATTRIBUTES) - if (config.profile) { - desc.stats.attributesCount = numAttributes - } - - var attributes = desc.attributes - for (i = 0; i < numAttributes; ++i) { - info = gl.getActiveAttrib(program, i) - if (info) { - insertActiveInfo(attributes, new ActiveInfo( - info.name, - stringStore.id(info.name), - gl.getAttribLocation(program, info.name), - info)) - } - } - } - - if (config.profile) { - stats.getMaxUniformsCount = function () { - var m = 0 - programList.forEach(function (desc) { - if (desc.stats.uniformsCount > m) { - m = desc.stats.uniformsCount - } - }) - return m - } - - stats.getMaxAttributesCount = function () { - var m = 0 - programList.forEach(function (desc) { - if (desc.stats.attributesCount > m) { - m = desc.stats.attributesCount - } - }) - return m - } - } - - function restoreShaders () { - fragShaders = {} - vertShaders = {} - for (var i = 0; i < programList.length; ++i) { - linkProgram(programList[i], null, programList[i].attributes.map(function (info) { - return [info.location, info.name] - })) - } - } - - return { - clear: function () { - var deleteShader = gl.deleteShader.bind(gl) - values(fragShaders).forEach(deleteShader) - fragShaders = {} - values(vertShaders).forEach(deleteShader) - vertShaders = {} - - programList.forEach(function (desc) { - gl.deleteProgram(desc.program) - }) - programList.length = 0 - programCache = {} - - stats.shaderCount = 0 - }, - - program: function (vertId, fragId, command, attribLocations) { - - - - var cache = programCache[fragId] - if (!cache) { - cache = programCache[fragId] = {} - } - var prevProgram = cache[vertId] - if (prevProgram) { - prevProgram.refCount++ - if (!attribLocations) { - return prevProgram - } - } - var program = new REGLProgram(fragId, vertId) - stats.shaderCount++ - linkProgram(program, command, attribLocations) - if (!prevProgram) { - cache[vertId] = program - } - programList.push(program) - return extend(program, { - destroy: function () { - program.refCount-- - if (program.refCount <= 0) { - gl.deleteProgram(program.program) - var idx = programList.indexOf(program) - programList.splice(idx, 1) - stats.shaderCount-- - } - // no program is linked to this vert anymore - if (cache[program.vertId].refCount <= 0) { - gl.deleteShader(vertShaders[program.vertId]) - delete vertShaders[program.vertId] - delete programCache[program.fragId][program.vertId] - } - // no program is linked to this frag anymore - if (!Object.keys(programCache[program.fragId]).length) { - gl.deleteShader(fragShaders[program.fragId]) - delete fragShaders[program.fragId] - delete programCache[program.fragId] - } - } - }) - }, - - restore: restoreShaders, - - shader: getShader, - - frag: -1, - vert: -1 - } -} - -var GL_RGBA$3 = 6408 -var GL_UNSIGNED_BYTE$6 = 5121 -var GL_PACK_ALIGNMENT = 0x0D05 -var GL_FLOAT$6 = 0x1406 // 5126 - -function wrapReadPixels ( - gl, - framebufferState, - reglPoll, - context, - glAttributes, - extensions, - limits) { - function readPixelsImpl (input) { - var type - if (framebufferState.next === null) { - - type = GL_UNSIGNED_BYTE$6 - } else { - - type = framebufferState.next.colorAttachments[0].texture._texture.type - - - } - - var x = 0 - var y = 0 - var width = context.framebufferWidth - var height = context.framebufferHeight - var data = null - - if (isTypedArray(input)) { - data = input - } else if (input) { - - x = input.x | 0 - y = input.y | 0 - - - width = (input.width || (context.framebufferWidth - x)) | 0 - height = (input.height || (context.framebufferHeight - y)) | 0 - data = input.data || null - } - - // sanity check input.data - if (data) { - if (type === GL_UNSIGNED_BYTE$6) { - - } else if (type === GL_FLOAT$6) { - - } - } - - - - - // Update WebGL state - reglPoll() - - // Compute size - var size = width * height * 4 - - // Allocate data - if (!data) { - if (type === GL_UNSIGNED_BYTE$6) { - data = new Uint8Array(size) - } else if (type === GL_FLOAT$6) { - data = data || new Float32Array(size) - } - } - - // Type check - - - - // Run read pixels - gl.pixelStorei(GL_PACK_ALIGNMENT, 4) - gl.readPixels(x, y, width, height, GL_RGBA$3, - type, - data) - - return data - } - - function readPixelsFBO (options) { - var result - framebufferState.setFBO({ - framebuffer: options.framebuffer - }, function () { - result = readPixelsImpl(options) - }) - return result - } - - function readPixels (options) { - if (!options || !('framebuffer' in options)) { - return readPixelsImpl(options) - } else { - return readPixelsFBO(options) - } - } - - return readPixels -} - -function slice (x) { - return Array.prototype.slice.call(x) -} - -function join (x) { - return slice(x).join('') -} - -function createEnvironment () { - // Unique variable id counter - var varCounter = 0 - - // Linked values are passed from this scope into the generated code block - // Calling link() passes a value into the generated scope and returns - // the variable name which it is bound to - var linkedNames = [] - var linkedValues = [] - function link (value) { - for (var i = 0; i < linkedValues.length; ++i) { - if (linkedValues[i] === value) { - return linkedNames[i] - } - } - - var name = 'g' + (varCounter++) - linkedNames.push(name) - linkedValues.push(value) - return name - } - - // create a code block - function block () { - var code = [] - function push () { - code.push.apply(code, slice(arguments)) - } - - var vars = [] - function def () { - var name = 'v' + (varCounter++) - vars.push(name) - - if (arguments.length > 0) { - code.push(name, '=') - code.push.apply(code, slice(arguments)) - code.push(';') - } - - return name - } - - return extend(push, { - def: def, - toString: function () { - return join([ - (vars.length > 0 ? 'var ' + vars.join(',') + ';' : ''), - join(code) - ]) - } - }) - } - - function scope () { - var entry = block() - var exit = block() - - var entryToString = entry.toString - var exitToString = exit.toString - - function save (object, prop) { - exit(object, prop, '=', entry.def(object, prop), ';') - } - - return extend(function () { - entry.apply(entry, slice(arguments)) - }, { - def: entry.def, - entry: entry, - exit: exit, - save: save, - set: function (object, prop, value) { - save(object, prop) - entry(object, prop, '=', value, ';') - }, - toString: function () { - return entryToString() + exitToString() - } - }) - } - - function conditional () { - var pred = join(arguments) - var thenBlock = scope() - var elseBlock = scope() - - var thenToString = thenBlock.toString - var elseToString = elseBlock.toString - - return extend(thenBlock, { - then: function () { - thenBlock.apply(thenBlock, slice(arguments)) - return this - }, - else: function () { - elseBlock.apply(elseBlock, slice(arguments)) - return this - }, - toString: function () { - var elseClause = elseToString() - if (elseClause) { - elseClause = 'else{' + elseClause + '}' - } - return join([ - 'if(', pred, '){', - thenToString(), - '}', elseClause - ]) - } - }) - } - - // procedure list - var globalBlock = block() - var procedures = {} - function proc (name, count) { - var args = [] - function arg () { - var name = 'a' + args.length - args.push(name) - return name - } - - count = count || 0 - for (var i = 0; i < count; ++i) { - arg() - } - - var body = scope() - var bodyToString = body.toString - - var result = procedures[name] = extend(body, { - arg: arg, - toString: function () { - return join([ - 'function(', args.join(), '){', - bodyToString(), - '}' - ]) - } - }) - - return result - } - - function compile () { - var code = ['"use strict";', - globalBlock, - 'return {'] - Object.keys(procedures).forEach(function (name) { - code.push('"', name, '":', procedures[name].toString(), ',') - }) - code.push('}') - var src = join(code) - .replace(/;/g, ';\n') - .replace(/}/g, '}\n') - .replace(/{/g, '{\n') - var proc = Function.apply(null, linkedNames.concat(src)) - return proc.apply(null, linkedValues) - } - - return { - global: globalBlock, - link: link, - block: block, - proc: proc, - scope: scope, - cond: conditional, - compile: compile - } -} - -// "cute" names for vector components -var CUTE_COMPONENTS = 'xyzw'.split('') - -var GL_UNSIGNED_BYTE$7 = 5121 - -var ATTRIB_STATE_POINTER = 1 -var ATTRIB_STATE_CONSTANT = 2 - -var DYN_FUNC$1 = 0 -var DYN_PROP$1 = 1 -var DYN_CONTEXT$1 = 2 -var DYN_STATE$1 = 3 -var DYN_THUNK = 4 -var DYN_CONSTANT$1 = 5 -var DYN_ARRAY$1 = 6 - -var S_DITHER = 'dither' -var S_BLEND_ENABLE = 'blend.enable' -var S_BLEND_COLOR = 'blend.color' -var S_BLEND_EQUATION = 'blend.equation' -var S_BLEND_FUNC = 'blend.func' -var S_DEPTH_ENABLE = 'depth.enable' -var S_DEPTH_FUNC = 'depth.func' -var S_DEPTH_RANGE = 'depth.range' -var S_DEPTH_MASK = 'depth.mask' -var S_COLOR_MASK = 'colorMask' -var S_CULL_ENABLE = 'cull.enable' -var S_CULL_FACE = 'cull.face' -var S_FRONT_FACE = 'frontFace' -var S_LINE_WIDTH = 'lineWidth' -var S_POLYGON_OFFSET_ENABLE = 'polygonOffset.enable' -var S_POLYGON_OFFSET_OFFSET = 'polygonOffset.offset' -var S_SAMPLE_ALPHA = 'sample.alpha' -var S_SAMPLE_ENABLE = 'sample.enable' -var S_SAMPLE_COVERAGE = 'sample.coverage' -var S_STENCIL_ENABLE = 'stencil.enable' -var S_STENCIL_MASK = 'stencil.mask' -var S_STENCIL_FUNC = 'stencil.func' -var S_STENCIL_OPFRONT = 'stencil.opFront' -var S_STENCIL_OPBACK = 'stencil.opBack' -var S_SCISSOR_ENABLE = 'scissor.enable' -var S_SCISSOR_BOX = 'scissor.box' -var S_VIEWPORT = 'viewport' - -var S_PROFILE = 'profile' - -var S_FRAMEBUFFER = 'framebuffer' -var S_VERT = 'vert' -var S_FRAG = 'frag' -var S_ELEMENTS = 'elements' -var S_PRIMITIVE = 'primitive' -var S_COUNT = 'count' -var S_OFFSET = 'offset' -var S_INSTANCES = 'instances' -var S_VAO = 'vao' - -var SUFFIX_WIDTH = 'Width' -var SUFFIX_HEIGHT = 'Height' - -var S_FRAMEBUFFER_WIDTH = S_FRAMEBUFFER + SUFFIX_WIDTH -var S_FRAMEBUFFER_HEIGHT = S_FRAMEBUFFER + SUFFIX_HEIGHT -var S_VIEWPORT_WIDTH = S_VIEWPORT + SUFFIX_WIDTH -var S_VIEWPORT_HEIGHT = S_VIEWPORT + SUFFIX_HEIGHT -var S_DRAWINGBUFFER = 'drawingBuffer' -var S_DRAWINGBUFFER_WIDTH = S_DRAWINGBUFFER + SUFFIX_WIDTH -var S_DRAWINGBUFFER_HEIGHT = S_DRAWINGBUFFER + SUFFIX_HEIGHT - -var NESTED_OPTIONS = [ - S_BLEND_FUNC, - S_BLEND_EQUATION, - S_STENCIL_FUNC, - S_STENCIL_OPFRONT, - S_STENCIL_OPBACK, - S_SAMPLE_COVERAGE, - S_VIEWPORT, - S_SCISSOR_BOX, - S_POLYGON_OFFSET_OFFSET -] - -var GL_ARRAY_BUFFER$2 = 34962 -var GL_ELEMENT_ARRAY_BUFFER$2 = 34963 - -var GL_CULL_FACE = 0x0B44 -var GL_BLEND = 0x0BE2 -var GL_DITHER = 0x0BD0 -var GL_STENCIL_TEST = 0x0B90 -var GL_DEPTH_TEST = 0x0B71 -var GL_SCISSOR_TEST = 0x0C11 -var GL_POLYGON_OFFSET_FILL = 0x8037 -var GL_SAMPLE_ALPHA_TO_COVERAGE = 0x809E -var GL_SAMPLE_COVERAGE = 0x80A0 - -var GL_FLOAT$7 = 5126 -var GL_FLOAT_VEC2 = 35664 -var GL_FLOAT_VEC3 = 35665 -var GL_FLOAT_VEC4 = 35666 -var GL_INT$2 = 5124 -var GL_INT_VEC2 = 35667 -var GL_INT_VEC3 = 35668 -var GL_INT_VEC4 = 35669 -var GL_BOOL = 35670 -var GL_BOOL_VEC2 = 35671 -var GL_BOOL_VEC3 = 35672 -var GL_BOOL_VEC4 = 35673 -var GL_FLOAT_MAT2 = 35674 -var GL_FLOAT_MAT3 = 35675 -var GL_FLOAT_MAT4 = 35676 -var GL_SAMPLER_2D = 35678 -var GL_SAMPLER_CUBE = 35680 - -var GL_TRIANGLES$1 = 4 - -var GL_FRONT = 1028 -var GL_BACK = 1029 -var GL_CW = 0x0900 -var GL_CCW = 0x0901 -var GL_MIN_EXT = 0x8007 -var GL_MAX_EXT = 0x8008 -var GL_ALWAYS = 519 -var GL_KEEP = 7680 -var GL_ZERO = 0 -var GL_ONE = 1 -var GL_FUNC_ADD = 0x8006 -var GL_LESS = 513 - -var GL_FRAMEBUFFER$2 = 0x8D40 -var GL_COLOR_ATTACHMENT0$2 = 0x8CE0 - -var blendFuncs = { - '0': 0, - '1': 1, - 'zero': 0, - 'one': 1, - 'src color': 768, - 'one minus src color': 769, - 'src alpha': 770, - 'one minus src alpha': 771, - 'dst color': 774, - 'one minus dst color': 775, - 'dst alpha': 772, - 'one minus dst alpha': 773, - 'constant color': 32769, - 'one minus constant color': 32770, - 'constant alpha': 32771, - 'one minus constant alpha': 32772, - 'src alpha saturate': 776 -} - -var compareFuncs = { - 'never': 512, - 'less': 513, - '<': 513, - 'equal': 514, - '=': 514, - '==': 514, - '===': 514, - 'lequal': 515, - '<=': 515, - 'greater': 516, - '>': 516, - 'notequal': 517, - '!=': 517, - '!==': 517, - 'gequal': 518, - '>=': 518, - 'always': 519 -} - -var stencilOps = { - '0': 0, - 'zero': 0, - 'keep': 7680, - 'replace': 7681, - 'increment': 7682, - 'decrement': 7683, - 'increment wrap': 34055, - 'decrement wrap': 34056, - 'invert': 5386 -} - -var orientationType = { - 'cw': GL_CW, - 'ccw': GL_CCW -} - -function isBufferArgs (x) { - return Array.isArray(x) || - isTypedArray(x) || - isNDArrayLike(x) -} - -// Make sure viewport is processed first -function sortState (state) { - return state.sort(function (a, b) { - if (a === S_VIEWPORT) { - return -1 - } else if (b === S_VIEWPORT) { - return 1 - } - return (a < b) ? -1 : 1 - }) -} - -function Declaration (thisDep, contextDep, propDep, append) { - this.thisDep = thisDep - this.contextDep = contextDep - this.propDep = propDep - this.append = append -} - -function isStatic (decl) { - return decl && !(decl.thisDep || decl.contextDep || decl.propDep) -} - -function createStaticDecl (append) { - return new Declaration(false, false, false, append) -} - -function createDynamicDecl (dyn, append) { - var type = dyn.type - if (type === DYN_FUNC$1) { - var numArgs = dyn.data.length - return new Declaration( - true, - numArgs >= 1, - numArgs >= 2, - append) - } else if (type === DYN_THUNK) { - var data = dyn.data - return new Declaration( - data.thisDep, - data.contextDep, - data.propDep, - append) - } else if (type === DYN_CONSTANT$1) { - return new Declaration( - false, - false, - false, - append) - } else if (type === DYN_ARRAY$1) { - var thisDep = false - var contextDep = false - var propDep = false - for (var i = 0; i < dyn.data.length; ++i) { - var subDyn = dyn.data[i] - if (subDyn.type === DYN_PROP$1) { - propDep = true - } else if (subDyn.type === DYN_CONTEXT$1) { - contextDep = true - } else if (subDyn.type === DYN_STATE$1) { - thisDep = true - } else if (subDyn.type === DYN_FUNC$1) { - thisDep = true - var subArgs = subDyn.data - if (subArgs >= 1) { - contextDep = true - } - if (subArgs >= 2) { - propDep = true - } - } else if (subDyn.type === DYN_THUNK) { - thisDep = thisDep || subDyn.data.thisDep - contextDep = contextDep || subDyn.data.contextDep - propDep = propDep || subDyn.data.propDep - } - } - return new Declaration( - thisDep, - contextDep, - propDep, - append) - } else { - return new Declaration( - type === DYN_STATE$1, - type === DYN_CONTEXT$1, - type === DYN_PROP$1, - append) - } -} - -var SCOPE_DECL = new Declaration(false, false, false, function () {}) - -function reglCore ( - gl, - stringStore, - extensions, - limits, - bufferState, - elementState, - textureState, - framebufferState, - uniformState, - attributeState, - shaderState, - drawState, - contextState, - timer, - config) { - var AttributeRecord = attributeState.Record - - var blendEquations = { - 'add': 32774, - 'subtract': 32778, - 'reverse subtract': 32779 - } - if (extensions.ext_blend_minmax) { - blendEquations.min = GL_MIN_EXT - blendEquations.max = GL_MAX_EXT - } - - var extInstancing = extensions.angle_instanced_arrays - var extDrawBuffers = extensions.webgl_draw_buffers - var extVertexArrays = extensions.oes_vertex_array_object - - // =================================================== - // =================================================== - // WEBGL STATE - // =================================================== - // =================================================== - var currentState = { - dirty: true, - profile: config.profile - } - var nextState = {} - var GL_STATE_NAMES = [] - var GL_FLAGS = {} - var GL_VARIABLES = {} - - function propName (name) { - return name.replace('.', '_') - } - - function stateFlag (sname, cap, init) { - var name = propName(sname) - GL_STATE_NAMES.push(sname) - nextState[name] = currentState[name] = !!init - GL_FLAGS[name] = cap - } - - function stateVariable (sname, func, init) { - var name = propName(sname) - GL_STATE_NAMES.push(sname) - if (Array.isArray(init)) { - currentState[name] = init.slice() - nextState[name] = init.slice() - } else { - currentState[name] = nextState[name] = init - } - GL_VARIABLES[name] = func - } - - // Dithering - stateFlag(S_DITHER, GL_DITHER) - - // Blending - stateFlag(S_BLEND_ENABLE, GL_BLEND) - stateVariable(S_BLEND_COLOR, 'blendColor', [0, 0, 0, 0]) - stateVariable(S_BLEND_EQUATION, 'blendEquationSeparate', - [GL_FUNC_ADD, GL_FUNC_ADD]) - stateVariable(S_BLEND_FUNC, 'blendFuncSeparate', - [GL_ONE, GL_ZERO, GL_ONE, GL_ZERO]) - - // Depth - stateFlag(S_DEPTH_ENABLE, GL_DEPTH_TEST, true) - stateVariable(S_DEPTH_FUNC, 'depthFunc', GL_LESS) - stateVariable(S_DEPTH_RANGE, 'depthRange', [0, 1]) - stateVariable(S_DEPTH_MASK, 'depthMask', true) - - // Color mask - stateVariable(S_COLOR_MASK, S_COLOR_MASK, [true, true, true, true]) - - // Face culling - stateFlag(S_CULL_ENABLE, GL_CULL_FACE) - stateVariable(S_CULL_FACE, 'cullFace', GL_BACK) - - // Front face orientation - stateVariable(S_FRONT_FACE, S_FRONT_FACE, GL_CCW) - - // Line width - stateVariable(S_LINE_WIDTH, S_LINE_WIDTH, 1) - - // Polygon offset - stateFlag(S_POLYGON_OFFSET_ENABLE, GL_POLYGON_OFFSET_FILL) - stateVariable(S_POLYGON_OFFSET_OFFSET, 'polygonOffset', [0, 0]) - - // Sample coverage - stateFlag(S_SAMPLE_ALPHA, GL_SAMPLE_ALPHA_TO_COVERAGE) - stateFlag(S_SAMPLE_ENABLE, GL_SAMPLE_COVERAGE) - stateVariable(S_SAMPLE_COVERAGE, 'sampleCoverage', [1, false]) - - // Stencil - stateFlag(S_STENCIL_ENABLE, GL_STENCIL_TEST) - stateVariable(S_STENCIL_MASK, 'stencilMask', -1) - stateVariable(S_STENCIL_FUNC, 'stencilFunc', [GL_ALWAYS, 0, -1]) - stateVariable(S_STENCIL_OPFRONT, 'stencilOpSeparate', - [GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP]) - stateVariable(S_STENCIL_OPBACK, 'stencilOpSeparate', - [GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP]) - - // Scissor - stateFlag(S_SCISSOR_ENABLE, GL_SCISSOR_TEST) - stateVariable(S_SCISSOR_BOX, 'scissor', - [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight]) - - // Viewport - stateVariable(S_VIEWPORT, S_VIEWPORT, - [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight]) - - // =================================================== - // =================================================== - // ENVIRONMENT - // =================================================== - // =================================================== - var sharedState = { - gl: gl, - context: contextState, - strings: stringStore, - next: nextState, - current: currentState, - draw: drawState, - elements: elementState, - buffer: bufferState, - shader: shaderState, - attributes: attributeState.state, - vao: attributeState, - uniforms: uniformState, - framebuffer: framebufferState, - extensions: extensions, - - timer: timer, - isBufferArgs: isBufferArgs - } - - var sharedConstants = { - primTypes: primTypes, - compareFuncs: compareFuncs, - blendFuncs: blendFuncs, - blendEquations: blendEquations, - stencilOps: stencilOps, - glTypes: glTypes, - orientationType: orientationType - } - - - - if (extDrawBuffers) { - sharedConstants.backBuffer = [GL_BACK] - sharedConstants.drawBuffer = loop(limits.maxDrawbuffers, function (i) { - if (i === 0) { - return [0] - } - return loop(i, function (j) { - return GL_COLOR_ATTACHMENT0$2 + j - }) - }) - } - - var drawCallCounter = 0 - function createREGLEnvironment () { - var env = createEnvironment() - var link = env.link - var global = env.global - env.id = drawCallCounter++ - - env.batchId = '0' - - // link shared state - var SHARED = link(sharedState) - var shared = env.shared = { - props: 'a0' - } - Object.keys(sharedState).forEach(function (prop) { - shared[prop] = global.def(SHARED, '.', prop) - }) - - // Inject runtime assertion stuff for debug builds - - - // Copy GL state variables over - var nextVars = env.next = {} - var currentVars = env.current = {} - Object.keys(GL_VARIABLES).forEach(function (variable) { - if (Array.isArray(currentState[variable])) { - nextVars[variable] = global.def(shared.next, '.', variable) - currentVars[variable] = global.def(shared.current, '.', variable) - } - }) - - // Initialize shared constants - var constants = env.constants = {} - Object.keys(sharedConstants).forEach(function (name) { - constants[name] = global.def(JSON.stringify(sharedConstants[name])) - }) - - // Helper function for calling a block - env.invoke = function (block, x) { - switch (x.type) { - case DYN_FUNC$1: - var argList = [ - 'this', - shared.context, - shared.props, - env.batchId - ] - return block.def( - link(x.data), '.call(', - argList.slice(0, Math.max(x.data.length + 1, 4)), - ')') - case DYN_PROP$1: - return block.def(shared.props, x.data) - case DYN_CONTEXT$1: - return block.def(shared.context, x.data) - case DYN_STATE$1: - return block.def('this', x.data) - case DYN_THUNK: - x.data.append(env, block) - return x.data.ref - case DYN_CONSTANT$1: - return x.data.toString() - case DYN_ARRAY$1: - return x.data.map(function (y) { - return env.invoke(block, y) - }) - } - } - - env.attribCache = {} - - var scopeAttribs = {} - env.scopeAttrib = function (name) { - var id = stringStore.id(name) - if (id in scopeAttribs) { - return scopeAttribs[id] - } - var binding = attributeState.scope[id] - if (!binding) { - binding = attributeState.scope[id] = new AttributeRecord() - } - var result = scopeAttribs[id] = link(binding) - return result - } - - return env - } - - // =================================================== - // =================================================== - // PARSING - // =================================================== - // =================================================== - function parseProfile (options) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - var profileEnable - if (S_PROFILE in staticOptions) { - var value = !!staticOptions[S_PROFILE] - profileEnable = createStaticDecl(function (env, scope) { - return value - }) - profileEnable.enable = value - } else if (S_PROFILE in dynamicOptions) { - var dyn = dynamicOptions[S_PROFILE] - profileEnable = createDynamicDecl(dyn, function (env, scope) { - return env.invoke(scope, dyn) - }) - } - - return profileEnable - } - - function parseFramebuffer (options, env) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - if (S_FRAMEBUFFER in staticOptions) { - var framebuffer = staticOptions[S_FRAMEBUFFER] - if (framebuffer) { - framebuffer = framebufferState.getFramebuffer(framebuffer) - - return createStaticDecl(function (env, block) { - var FRAMEBUFFER = env.link(framebuffer) - var shared = env.shared - block.set( - shared.framebuffer, - '.next', - FRAMEBUFFER) - var CONTEXT = shared.context - block.set( - CONTEXT, - '.' + S_FRAMEBUFFER_WIDTH, - FRAMEBUFFER + '.width') - block.set( - CONTEXT, - '.' + S_FRAMEBUFFER_HEIGHT, - FRAMEBUFFER + '.height') - return FRAMEBUFFER - }) - } else { - return createStaticDecl(function (env, scope) { - var shared = env.shared - scope.set( - shared.framebuffer, - '.next', - 'null') - var CONTEXT = shared.context - scope.set( - CONTEXT, - '.' + S_FRAMEBUFFER_WIDTH, - CONTEXT + '.' + S_DRAWINGBUFFER_WIDTH) - scope.set( - CONTEXT, - '.' + S_FRAMEBUFFER_HEIGHT, - CONTEXT + '.' + S_DRAWINGBUFFER_HEIGHT) - return 'null' - }) - } - } else if (S_FRAMEBUFFER in dynamicOptions) { - var dyn = dynamicOptions[S_FRAMEBUFFER] - return createDynamicDecl(dyn, function (env, scope) { - var FRAMEBUFFER_FUNC = env.invoke(scope, dyn) - var shared = env.shared - var FRAMEBUFFER_STATE = shared.framebuffer - var FRAMEBUFFER = scope.def( - FRAMEBUFFER_STATE, '.getFramebuffer(', FRAMEBUFFER_FUNC, ')') - - - - scope.set( - FRAMEBUFFER_STATE, - '.next', - FRAMEBUFFER) - var CONTEXT = shared.context - scope.set( - CONTEXT, - '.' + S_FRAMEBUFFER_WIDTH, - FRAMEBUFFER + '?' + FRAMEBUFFER + '.width:' + - CONTEXT + '.' + S_DRAWINGBUFFER_WIDTH) - scope.set( - CONTEXT, - '.' + S_FRAMEBUFFER_HEIGHT, - FRAMEBUFFER + - '?' + FRAMEBUFFER + '.height:' + - CONTEXT + '.' + S_DRAWINGBUFFER_HEIGHT) - return FRAMEBUFFER - }) - } else { - return null - } - } - - function parseViewportScissor (options, framebuffer, env) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - function parseBox (param) { - if (param in staticOptions) { - var box = staticOptions[param] - - - var isStatic = true - var x = box.x | 0 - var y = box.y | 0 - var w, h - if ('width' in box) { - w = box.width | 0 - - } else { - isStatic = false - } - if ('height' in box) { - h = box.height | 0 - - } else { - isStatic = false - } - - return new Declaration( - !isStatic && framebuffer && framebuffer.thisDep, - !isStatic && framebuffer && framebuffer.contextDep, - !isStatic && framebuffer && framebuffer.propDep, - function (env, scope) { - var CONTEXT = env.shared.context - var BOX_W = w - if (!('width' in box)) { - BOX_W = scope.def(CONTEXT, '.', S_FRAMEBUFFER_WIDTH, '-', x) - } - var BOX_H = h - if (!('height' in box)) { - BOX_H = scope.def(CONTEXT, '.', S_FRAMEBUFFER_HEIGHT, '-', y) - } - return [x, y, BOX_W, BOX_H] - }) - } else if (param in dynamicOptions) { - var dynBox = dynamicOptions[param] - var result = createDynamicDecl(dynBox, function (env, scope) { - var BOX = env.invoke(scope, dynBox) - - - - var CONTEXT = env.shared.context - var BOX_X = scope.def(BOX, '.x|0') - var BOX_Y = scope.def(BOX, '.y|0') - var BOX_W = scope.def( - '"width" in ', BOX, '?', BOX, '.width|0:', - '(', CONTEXT, '.', S_FRAMEBUFFER_WIDTH, '-', BOX_X, ')') - var BOX_H = scope.def( - '"height" in ', BOX, '?', BOX, '.height|0:', - '(', CONTEXT, '.', S_FRAMEBUFFER_HEIGHT, '-', BOX_Y, ')') - - - - return [BOX_X, BOX_Y, BOX_W, BOX_H] - }) - if (framebuffer) { - result.thisDep = result.thisDep || framebuffer.thisDep - result.contextDep = result.contextDep || framebuffer.contextDep - result.propDep = result.propDep || framebuffer.propDep - } - return result - } else if (framebuffer) { - return new Declaration( - framebuffer.thisDep, - framebuffer.contextDep, - framebuffer.propDep, - function (env, scope) { - var CONTEXT = env.shared.context - return [ - 0, 0, - scope.def(CONTEXT, '.', S_FRAMEBUFFER_WIDTH), - scope.def(CONTEXT, '.', S_FRAMEBUFFER_HEIGHT)] - }) - } else { - return null - } - } - - var viewport = parseBox(S_VIEWPORT) - - if (viewport) { - var prevViewport = viewport - viewport = new Declaration( - viewport.thisDep, - viewport.contextDep, - viewport.propDep, - function (env, scope) { - var VIEWPORT = prevViewport.append(env, scope) - var CONTEXT = env.shared.context - scope.set( - CONTEXT, - '.' + S_VIEWPORT_WIDTH, - VIEWPORT[2]) - scope.set( - CONTEXT, - '.' + S_VIEWPORT_HEIGHT, - VIEWPORT[3]) - return VIEWPORT - }) - } - - return { - viewport: viewport, - scissor_box: parseBox(S_SCISSOR_BOX) - } - } - - function parseAttribLocations (options, attributes) { - var staticOptions = options.static - var staticProgram = - typeof staticOptions[S_FRAG] === 'string' && - typeof staticOptions[S_VERT] === 'string' - if (staticProgram) { - if (Object.keys(attributes.dynamic).length > 0) { - return null - } - var staticAttributes = attributes.static - var sAttributes = Object.keys(staticAttributes) - if (sAttributes.length > 0 && typeof staticAttributes[sAttributes[0]] === 'number') { - var bindings = [] - for (var i = 0; i < sAttributes.length; ++i) { - - bindings.push([staticAttributes[sAttributes[i]] | 0, sAttributes[i]]) - } - return bindings - } - } - return null - } - - function parseProgram (options, env, attribLocations) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - function parseShader (name) { - if (name in staticOptions) { - var id = stringStore.id(staticOptions[name]) - - var result = createStaticDecl(function () { - return id - }) - result.id = id - return result - } else if (name in dynamicOptions) { - var dyn = dynamicOptions[name] - return createDynamicDecl(dyn, function (env, scope) { - var str = env.invoke(scope, dyn) - var id = scope.def(env.shared.strings, '.id(', str, ')') - - return id - }) - } - return null - } - - var frag = parseShader(S_FRAG) - var vert = parseShader(S_VERT) - - var program = null - var progVar - if (isStatic(frag) && isStatic(vert)) { - program = shaderState.program(vert.id, frag.id, null, attribLocations) - progVar = createStaticDecl(function (env, scope) { - return env.link(program) - }) - } else { - progVar = new Declaration( - (frag && frag.thisDep) || (vert && vert.thisDep), - (frag && frag.contextDep) || (vert && vert.contextDep), - (frag && frag.propDep) || (vert && vert.propDep), - function (env, scope) { - var SHADER_STATE = env.shared.shader - var fragId - if (frag) { - fragId = frag.append(env, scope) - } else { - fragId = scope.def(SHADER_STATE, '.', S_FRAG) - } - var vertId - if (vert) { - vertId = vert.append(env, scope) - } else { - vertId = scope.def(SHADER_STATE, '.', S_VERT) - } - var progDef = SHADER_STATE + '.program(' + vertId + ',' + fragId - - return scope.def(progDef + ')') - }) - } - - return { - frag: frag, - vert: vert, - progVar: progVar, - program: program - } - } - - function parseDraw (options, env) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - // TODO: should use VAO to get default values for offset properties - // should move vao parse into here and out of the old stuff - - var staticDraw = {} - var vaoActive = false - - function parseVAO () { - if (S_VAO in staticOptions) { - var vao = staticOptions[S_VAO] - if (vao !== null && attributeState.getVAO(vao) === null) { - vao = attributeState.createVAO(vao) - } - - vaoActive = true - staticDraw.vao = vao - - return createStaticDecl(function (env) { - var vaoRef = attributeState.getVAO(vao) - if (vaoRef) { - return env.link(vaoRef) - } else { - return 'null' - } - }) - } else if (S_VAO in dynamicOptions) { - vaoActive = true - var dyn = dynamicOptions[S_VAO] - return createDynamicDecl(dyn, function (env, scope) { - var vaoRef = env.invoke(scope, dyn) - return scope.def(env.shared.vao + '.getVAO(' + vaoRef + ')') - }) - } - return null - } - - var vao = parseVAO() - - var elementsActive = false - - function parseElements () { - if (S_ELEMENTS in staticOptions) { - var elements = staticOptions[S_ELEMENTS] - staticDraw.elements = elements - if (isBufferArgs(elements)) { - var e = staticDraw.elements = elementState.create(elements, true) - elements = elementState.getElements(e) - elementsActive = true - } else if (elements) { - elements = elementState.getElements(elements) - elementsActive = true - - } - - var result = createStaticDecl(function (env, scope) { - if (elements) { - var result = env.link(elements) - env.ELEMENTS = result - return result - } - env.ELEMENTS = null - return null - }) - result.value = elements - return result - } else if (S_ELEMENTS in dynamicOptions) { - elementsActive = true - - var dyn = dynamicOptions[S_ELEMENTS] - return createDynamicDecl(dyn, function (env, scope) { - var shared = env.shared - - var IS_BUFFER_ARGS = shared.isBufferArgs - var ELEMENT_STATE = shared.elements - - var elementDefn = env.invoke(scope, dyn) - var elements = scope.def('null') - var elementStream = scope.def(IS_BUFFER_ARGS, '(', elementDefn, ')') - - var ifte = env.cond(elementStream) - .then(elements, '=', ELEMENT_STATE, '.createStream(', elementDefn, ');') - .else(elements, '=', ELEMENT_STATE, '.getElements(', elementDefn, ');') - - - - scope.entry(ifte) - scope.exit( - env.cond(elementStream) - .then(ELEMENT_STATE, '.destroyStream(', elements, ');')) - - env.ELEMENTS = elements - - return elements - }) - } else if (vaoActive) { - return new Declaration( - vao.thisDep, - vao.contextDep, - vao.propDep, - function (env, scope) { - return scope.def(env.shared.vao + '.currentVAO?' + env.shared.elements + '.getElements(' + env.shared.vao + '.currentVAO.elements):null') - }) - } - return null - } - - var elements = parseElements() - - function parsePrimitive () { - if (S_PRIMITIVE in staticOptions) { - var primitive = staticOptions[S_PRIMITIVE] - staticDraw.primitive = primitive - - return createStaticDecl(function (env, scope) { - return primTypes[primitive] - }) - } else if (S_PRIMITIVE in dynamicOptions) { - var dynPrimitive = dynamicOptions[S_PRIMITIVE] - return createDynamicDecl(dynPrimitive, function (env, scope) { - var PRIM_TYPES = env.constants.primTypes - var prim = env.invoke(scope, dynPrimitive) - - return scope.def(PRIM_TYPES, '[', prim, ']') - }) - } else if (elementsActive) { - if (isStatic(elements)) { - if (elements.value) { - return createStaticDecl(function (env, scope) { - return scope.def(env.ELEMENTS, '.primType') - }) - } else { - return createStaticDecl(function () { - return GL_TRIANGLES$1 - }) - } - } else { - return new Declaration( - elements.thisDep, - elements.contextDep, - elements.propDep, - function (env, scope) { - var elements = env.ELEMENTS - return scope.def(elements, '?', elements, '.primType:', GL_TRIANGLES$1) - }) - } - } else if (vaoActive) { - return new Declaration( - vao.thisDep, - vao.contextDep, - vao.propDep, - function (env, scope) { - return scope.def(env.shared.vao + '.currentVAO?' + env.shared.vao + '.currentVAO.primitive:' + GL_TRIANGLES$1) - }) - } - return null - } - - function parseParam (param, isOffset) { - if (param in staticOptions) { - var value = staticOptions[param] | 0 - if (isOffset) { - staticDraw.offset = value - } else { - staticDraw.instances = value - } - - return createStaticDecl(function (env, scope) { - if (isOffset) { - env.OFFSET = value - } - return value - }) - } else if (param in dynamicOptions) { - var dynValue = dynamicOptions[param] - return createDynamicDecl(dynValue, function (env, scope) { - var result = env.invoke(scope, dynValue) - if (isOffset) { - env.OFFSET = result - - } - return result - }) - } else if (isOffset) { - if (elementsActive) { - return createStaticDecl(function (env, scope) { - env.OFFSET = 0 - return 0 - }) - } else if (vaoActive) { - return new Declaration( - vao.thisDep, - vao.contextDep, - vao.propDep, - function (env, scope) { - return scope.def(env.shared.vao + '.currentVAO?' + env.shared.vao + '.currentVAO.offset:0') - }) - } - } else if (vaoActive) { - return new Declaration( - vao.thisDep, - vao.contextDep, - vao.propDep, - function (env, scope) { - return scope.def(env.shared.vao + '.currentVAO?' + env.shared.vao + '.currentVAO.instances:-1') - }) - } - return null - } - - var OFFSET = parseParam(S_OFFSET, true) - - function parseVertCount () { - if (S_COUNT in staticOptions) { - var count = staticOptions[S_COUNT] | 0 - staticDraw.count = count - - return createStaticDecl(function () { - return count - }) - } else if (S_COUNT in dynamicOptions) { - var dynCount = dynamicOptions[S_COUNT] - return createDynamicDecl(dynCount, function (env, scope) { - var result = env.invoke(scope, dynCount) - - return result - }) - } else if (elementsActive) { - if (isStatic(elements)) { - if (elements) { - if (OFFSET) { - return new Declaration( - OFFSET.thisDep, - OFFSET.contextDep, - OFFSET.propDep, - function (env, scope) { - var result = scope.def( - env.ELEMENTS, '.vertCount-', env.OFFSET) - - - - return result - }) - } else { - return createStaticDecl(function (env, scope) { - return scope.def(env.ELEMENTS, '.vertCount') - }) - } - } else { - var result = createStaticDecl(function () { - return -1 - }) - - return result - } - } else { - var variable = new Declaration( - elements.thisDep || OFFSET.thisDep, - elements.contextDep || OFFSET.contextDep, - elements.propDep || OFFSET.propDep, - function (env, scope) { - var elements = env.ELEMENTS - if (env.OFFSET) { - return scope.def(elements, '?', elements, '.vertCount-', - env.OFFSET, ':-1') - } - return scope.def(elements, '?', elements, '.vertCount:-1') - }) - - return variable - } - } else if (vaoActive) { - var countVariable = new Declaration( - vao.thisDep, - vao.contextDep, - vao.propDep, - function (env, scope) { - return scope.def(env.shared.vao, '.currentVAO?', env.shared.vao, '.currentVAO.count:-1') - }) - return countVariable - } - return null - } - - var primitive = parsePrimitive() - var count = parseVertCount() - var instances = parseParam(S_INSTANCES, false) - - return { - elements: elements, - primitive: primitive, - count: count, - instances: instances, - offset: OFFSET, - vao: vao, - - vaoActive: vaoActive, - elementsActive: elementsActive, - - // static draw props - static: staticDraw - } - } - - function parseGLState (options, env) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - var STATE = {} - - GL_STATE_NAMES.forEach(function (prop) { - var param = propName(prop) - - function parseParam (parseStatic, parseDynamic) { - if (prop in staticOptions) { - var value = parseStatic(staticOptions[prop]) - STATE[param] = createStaticDecl(function () { - return value - }) - } else if (prop in dynamicOptions) { - var dyn = dynamicOptions[prop] - STATE[param] = createDynamicDecl(dyn, function (env, scope) { - return parseDynamic(env, scope, env.invoke(scope, dyn)) - }) - } - } - - switch (prop) { - case S_CULL_ENABLE: - case S_BLEND_ENABLE: - case S_DITHER: - case S_STENCIL_ENABLE: - case S_DEPTH_ENABLE: - case S_SCISSOR_ENABLE: - case S_POLYGON_OFFSET_ENABLE: - case S_SAMPLE_ALPHA: - case S_SAMPLE_ENABLE: - case S_DEPTH_MASK: - return parseParam( - function (value) { - - return value - }, - function (env, scope, value) { - - return value - }) - - case S_DEPTH_FUNC: - return parseParam( - function (value) { - - return compareFuncs[value] - }, - function (env, scope, value) { - var COMPARE_FUNCS = env.constants.compareFuncs - - return scope.def(COMPARE_FUNCS, '[', value, ']') - }) - - case S_DEPTH_RANGE: - return parseParam( - function (value) { - - return value - }, - function (env, scope, value) { - - - var Z_NEAR = scope.def('+', value, '[0]') - var Z_FAR = scope.def('+', value, '[1]') - return [Z_NEAR, Z_FAR] - }) - - case S_BLEND_FUNC: - return parseParam( - function (value) { - - var srcRGB = ('srcRGB' in value ? value.srcRGB : value.src) - var srcAlpha = ('srcAlpha' in value ? value.srcAlpha : value.src) - var dstRGB = ('dstRGB' in value ? value.dstRGB : value.dst) - var dstAlpha = ('dstAlpha' in value ? value.dstAlpha : value.dst) - - - - - - - - return [ - blendFuncs[srcRGB], - blendFuncs[dstRGB], - blendFuncs[srcAlpha], - blendFuncs[dstAlpha] - ] - }, - function (env, scope, value) { - var BLEND_FUNCS = env.constants.blendFuncs - - - - function read (prefix, suffix) { - var func = scope.def( - '"', prefix, suffix, '" in ', value, - '?', value, '.', prefix, suffix, - ':', value, '.', prefix) - - - - return func - } - - var srcRGB = read('src', 'RGB') - var dstRGB = read('dst', 'RGB') - - - - var SRC_RGB = scope.def(BLEND_FUNCS, '[', srcRGB, ']') - var SRC_ALPHA = scope.def(BLEND_FUNCS, '[', read('src', 'Alpha'), ']') - var DST_RGB = scope.def(BLEND_FUNCS, '[', dstRGB, ']') - var DST_ALPHA = scope.def(BLEND_FUNCS, '[', read('dst', 'Alpha'), ']') - - return [SRC_RGB, DST_RGB, SRC_ALPHA, DST_ALPHA] - }) - - case S_BLEND_EQUATION: - return parseParam( - function (value) { - if (typeof value === 'string') { - - return [ - blendEquations[value], - blendEquations[value] - ] - } else if (typeof value === 'object') { - - - return [ - blendEquations[value.rgb], - blendEquations[value.alpha] - ] - } else { - - } - }, - function (env, scope, value) { - var BLEND_EQUATIONS = env.constants.blendEquations - - var RGB = scope.def() - var ALPHA = scope.def() - - var ifte = env.cond('typeof ', value, '==="string"') - - - - ifte.then( - RGB, '=', ALPHA, '=', BLEND_EQUATIONS, '[', value, '];') - ifte.else( - RGB, '=', BLEND_EQUATIONS, '[', value, '.rgb];', - ALPHA, '=', BLEND_EQUATIONS, '[', value, '.alpha];') - - scope(ifte) - - return [RGB, ALPHA] - }) - - case S_BLEND_COLOR: - return parseParam( - function (value) { - - return loop(4, function (i) { - return +value[i] - }) - }, - function (env, scope, value) { - - return loop(4, function (i) { - return scope.def('+', value, '[', i, ']') - }) - }) - - case S_STENCIL_MASK: - return parseParam( - function (value) { - - return value | 0 - }, - function (env, scope, value) { - - return scope.def(value, '|0') - }) - - case S_STENCIL_FUNC: - return parseParam( - function (value) { - - var cmp = value.cmp || 'keep' - var ref = value.ref || 0 - var mask = 'mask' in value ? value.mask : -1 - - - - return [ - compareFuncs[cmp], - ref, - mask - ] - }, - function (env, scope, value) { - var COMPARE_FUNCS = env.constants.compareFuncs - - var cmp = scope.def( - '"cmp" in ', value, - '?', COMPARE_FUNCS, '[', value, '.cmp]', - ':', GL_KEEP) - var ref = scope.def(value, '.ref|0') - var mask = scope.def( - '"mask" in ', value, - '?', value, '.mask|0:-1') - return [cmp, ref, mask] - }) - - case S_STENCIL_OPFRONT: - case S_STENCIL_OPBACK: - return parseParam( - function (value) { - - var fail = value.fail || 'keep' - var zfail = value.zfail || 'keep' - var zpass = value.zpass || 'keep' - - - - return [ - prop === S_STENCIL_OPBACK ? GL_BACK : GL_FRONT, - stencilOps[fail], - stencilOps[zfail], - stencilOps[zpass] - ] - }, - function (env, scope, value) { - var STENCIL_OPS = env.constants.stencilOps - - - - function read (name) { - - - return scope.def( - '"', name, '" in ', value, - '?', STENCIL_OPS, '[', value, '.', name, ']:', - GL_KEEP) - } - - return [ - prop === S_STENCIL_OPBACK ? GL_BACK : GL_FRONT, - read('fail'), - read('zfail'), - read('zpass') - ] - }) - - case S_POLYGON_OFFSET_OFFSET: - return parseParam( - function (value) { - - var factor = value.factor | 0 - var units = value.units | 0 - - - return [factor, units] - }, - function (env, scope, value) { - - - var FACTOR = scope.def(value, '.factor|0') - var UNITS = scope.def(value, '.units|0') - - return [FACTOR, UNITS] - }) - - case S_CULL_FACE: - return parseParam( - function (value) { - var face = 0 - if (value === 'front') { - face = GL_FRONT - } else if (value === 'back') { - face = GL_BACK - } - - return face - }, - function (env, scope, value) { - - return scope.def(value, '==="front"?', GL_FRONT, ':', GL_BACK) - }) - - case S_LINE_WIDTH: - return parseParam( - function (value) { - - return value - }, - function (env, scope, value) { - - - return value - }) - - case S_FRONT_FACE: - return parseParam( - function (value) { - - return orientationType[value] - }, - function (env, scope, value) { - - return scope.def(value + '==="cw"?' + GL_CW + ':' + GL_CCW) - }) - - case S_COLOR_MASK: - return parseParam( - function (value) { - - return value.map(function (v) { return !!v }) - }, - function (env, scope, value) { - - return loop(4, function (i) { - return '!!' + value + '[' + i + ']' - }) - }) - - case S_SAMPLE_COVERAGE: - return parseParam( - function (value) { - - var sampleValue = 'value' in value ? value.value : 1 - var sampleInvert = !!value.invert - - return [sampleValue, sampleInvert] - }, - function (env, scope, value) { - - var VALUE = scope.def( - '"value" in ', value, '?+', value, '.value:1') - var INVERT = scope.def('!!', value, '.invert') - return [VALUE, INVERT] - }) - } - }) - - return STATE - } - - function parseUniforms (uniforms, env) { - var staticUniforms = uniforms.static - var dynamicUniforms = uniforms.dynamic - - var UNIFORMS = {} - - Object.keys(staticUniforms).forEach(function (name) { - var value = staticUniforms[name] - var result - if (typeof value === 'number' || - typeof value === 'boolean') { - result = createStaticDecl(function () { - return value - }) - } else if (typeof value === 'function') { - var reglType = value._reglType - if (reglType === 'texture2d' || - reglType === 'textureCube') { - result = createStaticDecl(function (env) { - return env.link(value) - }) - } else if (reglType === 'framebuffer' || - reglType === 'framebufferCube') { - - result = createStaticDecl(function (env) { - return env.link(value.color[0]) - }) - } else { - - } - } else if (isArrayLike(value)) { - result = createStaticDecl(function (env) { - var ITEM = env.global.def('[', - loop(value.length, function (i) { - - return value[i] - }), ']') - return ITEM - }) - } else { - - } - result.value = value - UNIFORMS[name] = result - }) - - Object.keys(dynamicUniforms).forEach(function (key) { - var dyn = dynamicUniforms[key] - UNIFORMS[key] = createDynamicDecl(dyn, function (env, scope) { - return env.invoke(scope, dyn) - }) - }) - - return UNIFORMS - } - - function parseAttributes (attributes, env) { - var staticAttributes = attributes.static - var dynamicAttributes = attributes.dynamic - - var attributeDefs = {} - - Object.keys(staticAttributes).forEach(function (attribute) { - var value = staticAttributes[attribute] - var id = stringStore.id(attribute) - - var record = new AttributeRecord() - if (isBufferArgs(value)) { - record.state = ATTRIB_STATE_POINTER - record.buffer = bufferState.getBuffer( - bufferState.create(value, GL_ARRAY_BUFFER$2, false, true)) - record.type = 0 - } else { - var buffer = bufferState.getBuffer(value) - if (buffer) { - record.state = ATTRIB_STATE_POINTER - record.buffer = buffer - record.type = 0 - } else { - - if ('constant' in value) { - var constant = value.constant - record.buffer = 'null' - record.state = ATTRIB_STATE_CONSTANT - if (typeof constant === 'number') { - record.x = constant - } else { - - CUTE_COMPONENTS.forEach(function (c, i) { - if (i < constant.length) { - record[c] = constant[i] - } - }) - } - } else { - if (isBufferArgs(value.buffer)) { - buffer = bufferState.getBuffer( - bufferState.create(value.buffer, GL_ARRAY_BUFFER$2, false, true)) - } else { - buffer = bufferState.getBuffer(value.buffer) - } - - - var offset = value.offset | 0 - - - var stride = value.stride | 0 - - - var size = value.size | 0 - - - var normalized = !!value.normalized - - var type = 0 - if ('type' in value) { - - type = glTypes[value.type] - } - - var divisor = value.divisor | 0 - - - record.buffer = buffer - record.state = ATTRIB_STATE_POINTER - record.size = size - record.normalized = normalized - record.type = type || buffer.dtype - record.offset = offset - record.stride = stride - record.divisor = divisor - } - } - } - - attributeDefs[attribute] = createStaticDecl(function (env, scope) { - var cache = env.attribCache - if (id in cache) { - return cache[id] - } - var result = { - isStream: false - } - Object.keys(record).forEach(function (key) { - result[key] = record[key] - }) - if (record.buffer) { - result.buffer = env.link(record.buffer) - result.type = result.type || (result.buffer + '.dtype') - } - cache[id] = result - return result - }) - }) - - Object.keys(dynamicAttributes).forEach(function (attribute) { - var dyn = dynamicAttributes[attribute] - - function appendAttributeCode (env, block) { - var VALUE = env.invoke(block, dyn) - - var shared = env.shared - var constants = env.constants - - var IS_BUFFER_ARGS = shared.isBufferArgs - var BUFFER_STATE = shared.buffer - - // Perform validation on attribute - - - // allocate names for result - var result = { - isStream: block.def(false) - } - var defaultRecord = new AttributeRecord() - defaultRecord.state = ATTRIB_STATE_POINTER - Object.keys(defaultRecord).forEach(function (key) { - result[key] = block.def('' + defaultRecord[key]) - }) - - var BUFFER = result.buffer - var TYPE = result.type - block( - 'if(', IS_BUFFER_ARGS, '(', VALUE, ')){', - result.isStream, '=true;', - BUFFER, '=', BUFFER_STATE, '.createStream(', GL_ARRAY_BUFFER$2, ',', VALUE, ');', - TYPE, '=', BUFFER, '.dtype;', - '}else{', - BUFFER, '=', BUFFER_STATE, '.getBuffer(', VALUE, ');', - 'if(', BUFFER, '){', - TYPE, '=', BUFFER, '.dtype;', - '}else if("constant" in ', VALUE, '){', - result.state, '=', ATTRIB_STATE_CONSTANT, ';', - 'if(typeof ' + VALUE + '.constant === "number"){', - result[CUTE_COMPONENTS[0]], '=', VALUE, '.constant;', - CUTE_COMPONENTS.slice(1).map(function (n) { - return result[n] - }).join('='), '=0;', - '}else{', - CUTE_COMPONENTS.map(function (name, i) { - return ( - result[name] + '=' + VALUE + '.constant.length>' + i + - '?' + VALUE + '.constant[' + i + ']:0;' - ) - }).join(''), - '}}else{', - 'if(', IS_BUFFER_ARGS, '(', VALUE, '.buffer)){', - BUFFER, '=', BUFFER_STATE, '.createStream(', GL_ARRAY_BUFFER$2, ',', VALUE, '.buffer);', - '}else{', - BUFFER, '=', BUFFER_STATE, '.getBuffer(', VALUE, '.buffer);', - '}', - TYPE, '="type" in ', VALUE, '?', - constants.glTypes, '[', VALUE, '.type]:', BUFFER, '.dtype;', - result.normalized, '=!!', VALUE, '.normalized;') - function emitReadRecord (name) { - block(result[name], '=', VALUE, '.', name, '|0;') - } - emitReadRecord('size') - emitReadRecord('offset') - emitReadRecord('stride') - emitReadRecord('divisor') - - block('}}') - - block.exit( - 'if(', result.isStream, '){', - BUFFER_STATE, '.destroyStream(', BUFFER, ');', - '}') - - return result - } - - attributeDefs[attribute] = createDynamicDecl(dyn, appendAttributeCode) - }) - - return attributeDefs - } - - function parseContext (context) { - var staticContext = context.static - var dynamicContext = context.dynamic - var result = {} - - Object.keys(staticContext).forEach(function (name) { - var value = staticContext[name] - result[name] = createStaticDecl(function (env, scope) { - if (typeof value === 'number' || typeof value === 'boolean') { - return '' + value - } else { - return env.link(value) - } - }) - }) - - Object.keys(dynamicContext).forEach(function (name) { - var dyn = dynamicContext[name] - result[name] = createDynamicDecl(dyn, function (env, scope) { - return env.invoke(scope, dyn) - }) - }) - - return result - } - - function parseArguments (options, attributes, uniforms, context, env) { - var staticOptions = options.static - var dynamicOptions = options.dynamic - - - - var attribLocations = parseAttribLocations(options, attributes) - - var framebuffer = parseFramebuffer(options, env) - var viewportAndScissor = parseViewportScissor(options, framebuffer, env) - var draw = parseDraw(options, env) - var state = parseGLState(options, env) - var shader = parseProgram(options, env, attribLocations) - - function copyBox (name) { - var defn = viewportAndScissor[name] - if (defn) { - state[name] = defn - } - } - copyBox(S_VIEWPORT) - copyBox(propName(S_SCISSOR_BOX)) - - var dirty = Object.keys(state).length > 0 - - var result = { - framebuffer: framebuffer, - draw: draw, - shader: shader, - state: state, - dirty: dirty, - scopeVAO: null, - drawVAO: null, - useVAO: false, - attributes: {} - } - - result.profile = parseProfile(options, env) - result.uniforms = parseUniforms(uniforms, env) - result.drawVAO = result.scopeVAO = draw.vao - // special case: check if we can statically allocate a vertex array object for this program - if (!result.drawVAO && - shader.program && - !attribLocations && - extensions.angle_instanced_arrays && - draw.static.elements) { - var useVAO = true - var staticBindings = shader.program.attributes.map(function (attr) { - var binding = attributes.static[attr] - useVAO = useVAO && !!binding - return binding - }) - if (useVAO && staticBindings.length > 0) { - var vao = attributeState.getVAO(attributeState.createVAO({ - attributes: staticBindings, - elements: draw.static.elements - })) - result.drawVAO = new Declaration(null, null, null, function (env, scope) { - return env.link(vao) - }) - result.useVAO = true - } - } - if (attribLocations) { - result.useVAO = true - } else { - result.attributes = parseAttributes(attributes, env) - } - result.context = parseContext(context, env) - return result - } - - // =================================================== - // =================================================== - // COMMON UPDATE FUNCTIONS - // =================================================== - // =================================================== - function emitContext (env, scope, context) { - var shared = env.shared - var CONTEXT = shared.context - - var contextEnter = env.scope() - - Object.keys(context).forEach(function (name) { - scope.save(CONTEXT, '.' + name) - var defn = context[name] - var value = defn.append(env, scope) - if (Array.isArray(value)) { - contextEnter(CONTEXT, '.', name, '=[', value.join(), '];') - } else { - contextEnter(CONTEXT, '.', name, '=', value, ';') - } - }) - - scope(contextEnter) - } - - // =================================================== - // =================================================== - // COMMON DRAWING FUNCTIONS - // =================================================== - // =================================================== - function emitPollFramebuffer (env, scope, framebuffer, skipCheck) { - var shared = env.shared - - var GL = shared.gl - var FRAMEBUFFER_STATE = shared.framebuffer - var EXT_DRAW_BUFFERS - if (extDrawBuffers) { - EXT_DRAW_BUFFERS = scope.def(shared.extensions, '.webgl_draw_buffers') - } - - var constants = env.constants - - var DRAW_BUFFERS = constants.drawBuffer - var BACK_BUFFER = constants.backBuffer - - var NEXT - if (framebuffer) { - NEXT = framebuffer.append(env, scope) - } else { - NEXT = scope.def(FRAMEBUFFER_STATE, '.next') - } - - if (!skipCheck) { - scope('if(', NEXT, '!==', FRAMEBUFFER_STATE, '.cur){') - } - scope( - 'if(', NEXT, '){', - GL, '.bindFramebuffer(', GL_FRAMEBUFFER$2, ',', NEXT, '.framebuffer);') - if (extDrawBuffers) { - scope(EXT_DRAW_BUFFERS, '.drawBuffersWEBGL(', - DRAW_BUFFERS, '[', NEXT, '.colorAttachments.length]);') - } - scope('}else{', - GL, '.bindFramebuffer(', GL_FRAMEBUFFER$2, ',null);') - if (extDrawBuffers) { - scope(EXT_DRAW_BUFFERS, '.drawBuffersWEBGL(', BACK_BUFFER, ');') - } - scope( - '}', - FRAMEBUFFER_STATE, '.cur=', NEXT, ';') - if (!skipCheck) { - scope('}') - } - } - - function emitPollState (env, scope, args) { - var shared = env.shared - - var GL = shared.gl - - var CURRENT_VARS = env.current - var NEXT_VARS = env.next - var CURRENT_STATE = shared.current - var NEXT_STATE = shared.next - - var block = env.cond(CURRENT_STATE, '.dirty') - - GL_STATE_NAMES.forEach(function (prop) { - var param = propName(prop) - if (param in args.state) { - return - } - - var NEXT, CURRENT - if (param in NEXT_VARS) { - NEXT = NEXT_VARS[param] - CURRENT = CURRENT_VARS[param] - var parts = loop(currentState[param].length, function (i) { - return block.def(NEXT, '[', i, ']') - }) - block(env.cond(parts.map(function (p, i) { - return p + '!==' + CURRENT + '[' + i + ']' - }).join('||')) - .then( - GL, '.', GL_VARIABLES[param], '(', parts, ');', - parts.map(function (p, i) { - return CURRENT + '[' + i + ']=' + p - }).join(';'), ';')) - } else { - NEXT = block.def(NEXT_STATE, '.', param) - var ifte = env.cond(NEXT, '!==', CURRENT_STATE, '.', param) - block(ifte) - if (param in GL_FLAGS) { - ifte( - env.cond(NEXT) - .then(GL, '.enable(', GL_FLAGS[param], ');') - .else(GL, '.disable(', GL_FLAGS[param], ');'), - CURRENT_STATE, '.', param, '=', NEXT, ';') - } else { - ifte( - GL, '.', GL_VARIABLES[param], '(', NEXT, ');', - CURRENT_STATE, '.', param, '=', NEXT, ';') - } - } - }) - if (Object.keys(args.state).length === 0) { - block(CURRENT_STATE, '.dirty=false;') - } - scope(block) - } - - function emitSetOptions (env, scope, options, filter) { - var shared = env.shared - var CURRENT_VARS = env.current - var CURRENT_STATE = shared.current - var GL = shared.gl - sortState(Object.keys(options)).forEach(function (param) { - var defn = options[param] - if (filter && !filter(defn)) { - return - } - var variable = defn.append(env, scope) - if (GL_FLAGS[param]) { - var flag = GL_FLAGS[param] - if (isStatic(defn)) { - if (variable) { - scope(GL, '.enable(', flag, ');') - } else { - scope(GL, '.disable(', flag, ');') - } - } else { - scope(env.cond(variable) - .then(GL, '.enable(', flag, ');') - .else(GL, '.disable(', flag, ');')) - } - scope(CURRENT_STATE, '.', param, '=', variable, ';') - } else if (isArrayLike(variable)) { - var CURRENT = CURRENT_VARS[param] - scope( - GL, '.', GL_VARIABLES[param], '(', variable, ');', - variable.map(function (v, i) { - return CURRENT + '[' + i + ']=' + v - }).join(';'), ';') - } else { - scope( - GL, '.', GL_VARIABLES[param], '(', variable, ');', - CURRENT_STATE, '.', param, '=', variable, ';') - } - }) - } - - function injectExtensions (env, scope) { - if (extInstancing) { - env.instancing = scope.def( - env.shared.extensions, '.angle_instanced_arrays') - } - } - - function emitProfile (env, scope, args, useScope, incrementCounter) { - var shared = env.shared - var STATS = env.stats - var CURRENT_STATE = shared.current - var TIMER = shared.timer - var profileArg = args.profile - - function perfCounter () { - if (typeof performance === 'undefined') { - return 'Date.now()' - } else { - return 'performance.now()' - } - } - - var CPU_START, QUERY_COUNTER - function emitProfileStart (block) { - CPU_START = scope.def() - block(CPU_START, '=', perfCounter(), ';') - if (typeof incrementCounter === 'string') { - block(STATS, '.count+=', incrementCounter, ';') - } else { - block(STATS, '.count++;') - } - if (timer) { - if (useScope) { - QUERY_COUNTER = scope.def() - block(QUERY_COUNTER, '=', TIMER, '.getNumPendingQueries();') - } else { - block(TIMER, '.beginQuery(', STATS, ');') - } - } - } - - function emitProfileEnd (block) { - block(STATS, '.cpuTime+=', perfCounter(), '-', CPU_START, ';') - if (timer) { - if (useScope) { - block(TIMER, '.pushScopeStats(', - QUERY_COUNTER, ',', - TIMER, '.getNumPendingQueries(),', - STATS, ');') - } else { - block(TIMER, '.endQuery();') - } - } - } - - function scopeProfile (value) { - var prev = scope.def(CURRENT_STATE, '.profile') - scope(CURRENT_STATE, '.profile=', value, ';') - scope.exit(CURRENT_STATE, '.profile=', prev, ';') - } - - var USE_PROFILE - if (profileArg) { - if (isStatic(profileArg)) { - if (profileArg.enable) { - emitProfileStart(scope) - emitProfileEnd(scope.exit) - scopeProfile('true') - } else { - scopeProfile('false') - } - return - } - USE_PROFILE = profileArg.append(env, scope) - scopeProfile(USE_PROFILE) - } else { - USE_PROFILE = scope.def(CURRENT_STATE, '.profile') - } - - var start = env.block() - emitProfileStart(start) - scope('if(', USE_PROFILE, '){', start, '}') - var end = env.block() - emitProfileEnd(end) - scope.exit('if(', USE_PROFILE, '){', end, '}') - } - - function emitAttributes (env, scope, args, attributes, filter) { - var shared = env.shared - - function typeLength (x) { - switch (x) { - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - case GL_BOOL_VEC2: - return 2 - case GL_FLOAT_VEC3: - case GL_INT_VEC3: - case GL_BOOL_VEC3: - return 3 - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - case GL_BOOL_VEC4: - return 4 - default: - return 1 - } - } - - function emitBindAttribute (ATTRIBUTE, size, record) { - var GL = shared.gl - - var LOCATION = scope.def(ATTRIBUTE, '.location') - var BINDING = scope.def(shared.attributes, '[', LOCATION, ']') - - var STATE = record.state - var BUFFER = record.buffer - var CONST_COMPONENTS = [ - record.x, - record.y, - record.z, - record.w - ] - - var COMMON_KEYS = [ - 'buffer', - 'normalized', - 'offset', - 'stride' - ] - - function emitBuffer () { - scope( - 'if(!', BINDING, '.buffer){', - GL, '.enableVertexAttribArray(', LOCATION, ');}') - - var TYPE = record.type - var SIZE - if (!record.size) { - SIZE = size - } else { - SIZE = scope.def(record.size, '||', size) - } - - scope('if(', - BINDING, '.type!==', TYPE, '||', - BINDING, '.size!==', SIZE, '||', - COMMON_KEYS.map(function (key) { - return BINDING + '.' + key + '!==' + record[key] - }).join('||'), - '){', - GL, '.bindBuffer(', GL_ARRAY_BUFFER$2, ',', BUFFER, '.buffer);', - GL, '.vertexAttribPointer(', [ - LOCATION, - SIZE, - TYPE, - record.normalized, - record.stride, - record.offset - ], ');', - BINDING, '.type=', TYPE, ';', - BINDING, '.size=', SIZE, ';', - COMMON_KEYS.map(function (key) { - return BINDING + '.' + key + '=' + record[key] + ';' - }).join(''), - '}') - - if (extInstancing) { - var DIVISOR = record.divisor - scope( - 'if(', BINDING, '.divisor!==', DIVISOR, '){', - env.instancing, '.vertexAttribDivisorANGLE(', [LOCATION, DIVISOR], ');', - BINDING, '.divisor=', DIVISOR, ';}') - } - } - - function emitConstant () { - scope( - 'if(', BINDING, '.buffer){', - GL, '.disableVertexAttribArray(', LOCATION, ');', - BINDING, '.buffer=null;', - '}if(', CUTE_COMPONENTS.map(function (c, i) { - return BINDING + '.' + c + '!==' + CONST_COMPONENTS[i] - }).join('||'), '){', - GL, '.vertexAttrib4f(', LOCATION, ',', CONST_COMPONENTS, ');', - CUTE_COMPONENTS.map(function (c, i) { - return BINDING + '.' + c + '=' + CONST_COMPONENTS[i] + ';' - }).join(''), - '}') - } - - if (STATE === ATTRIB_STATE_POINTER) { - emitBuffer() - } else if (STATE === ATTRIB_STATE_CONSTANT) { - emitConstant() - } else { - scope('if(', STATE, '===', ATTRIB_STATE_POINTER, '){') - emitBuffer() - scope('}else{') - emitConstant() - scope('}') - } - } - - attributes.forEach(function (attribute) { - var name = attribute.name - var arg = args.attributes[name] - var record - if (arg) { - if (!filter(arg)) { - return - } - record = arg.append(env, scope) - } else { - if (!filter(SCOPE_DECL)) { - return - } - var scopeAttrib = env.scopeAttrib(name) - - record = {} - Object.keys(new AttributeRecord()).forEach(function (key) { - record[key] = scope.def(scopeAttrib, '.', key) - }) - } - emitBindAttribute( - env.link(attribute), typeLength(attribute.info.type), record) - }) - } - - function emitUniforms (env, scope, args, uniforms, filter, isBatchInnerLoop) { - var shared = env.shared - var GL = shared.gl - - var definedArrUniforms = {} - var infix - for (var i = 0; i < uniforms.length; ++i) { - var uniform = uniforms[i] - var name = uniform.name - var type = uniform.info.type - var size = uniform.info.size - var arg = args.uniforms[name] - if (size > 1) { - // either foo[n] or foos, avoid define both - if (!arg) { - continue - } - var arrUniformName = name.replace('[0]', '') - if (definedArrUniforms[arrUniformName]) { - continue - } - definedArrUniforms[arrUniformName] = 1 - } - var UNIFORM = env.link(uniform) - var LOCATION = UNIFORM + '.location' - - var VALUE - if (arg) { - if (!filter(arg)) { - continue - } - if (isStatic(arg)) { - var value = arg.value - - if (type === GL_SAMPLER_2D || type === GL_SAMPLER_CUBE) { - - var TEX_VALUE = env.link(value._texture || value.color[0]._texture) - scope(GL, '.uniform1i(', LOCATION, ',', TEX_VALUE + '.bind());') - scope.exit(TEX_VALUE, '.unbind();') - } else if ( - type === GL_FLOAT_MAT2 || - type === GL_FLOAT_MAT3 || - type === GL_FLOAT_MAT4) { - - var MAT_VALUE = env.global.def('new Float32Array([' + - Array.prototype.slice.call(value) + '])') - var dim = 2 - if (type === GL_FLOAT_MAT3) { - dim = 3 - } else if (type === GL_FLOAT_MAT4) { - dim = 4 - } - scope( - GL, '.uniformMatrix', dim, 'fv(', - LOCATION, ',false,', MAT_VALUE, ');') - } else { - switch (type) { - case GL_FLOAT$7: - if (size === 1) { - - } else { - - } - infix = '1f' - break - case GL_FLOAT_VEC2: - - infix = '2f' - break - case GL_FLOAT_VEC3: - - infix = '3f' - break - case GL_FLOAT_VEC4: - - infix = '4f' - break - case GL_BOOL: - if (size === 1) { - - } else { - - } - infix = '1i' - break - case GL_INT$2: - if (size === 1) { - - } else { - - } - infix = '1i' - break - case GL_BOOL_VEC2: - - infix = '2i' - break - case GL_INT_VEC2: - - infix = '2i' - break - case GL_BOOL_VEC3: - - infix = '3i' - break - case GL_INT_VEC3: - - infix = '3i' - break - case GL_BOOL_VEC4: - - infix = '4i' - break - case GL_INT_VEC4: - - infix = '4i' - break - } - if (size > 1) { - infix += 'v' - value = env.global.def('[' + - Array.prototype.slice.call(value) + ']') - } else { - value = isArrayLike(value) ? Array.prototype.slice.call(value) : value - } - scope(GL, '.uniform', infix, '(', LOCATION, ',', - value, - ');') - } - continue - } else { - VALUE = arg.append(env, scope) - } - } else { - if (!filter(SCOPE_DECL)) { - continue - } - VALUE = scope.def(shared.uniforms, '[', stringStore.id(name), ']') - } - - if (type === GL_SAMPLER_2D) { - - scope( - 'if(', VALUE, '&&', VALUE, '._reglType==="framebuffer"){', - VALUE, '=', VALUE, '.color[0];', - '}') - } else if (type === GL_SAMPLER_CUBE) { - - scope( - 'if(', VALUE, '&&', VALUE, '._reglType==="framebufferCube"){', - VALUE, '=', VALUE, '.color[0];', - '}') - } - - // perform type validation - - - var unroll = 1 - switch (type) { - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - var TEX = scope.def(VALUE, '._texture') - scope(GL, '.uniform1i(', LOCATION, ',', TEX, '.bind());') - scope.exit(TEX, '.unbind();') - continue - - case GL_INT$2: - case GL_BOOL: - infix = '1i' - break - - case GL_INT_VEC2: - case GL_BOOL_VEC2: - infix = '2i' - unroll = 2 - break - - case GL_INT_VEC3: - case GL_BOOL_VEC3: - infix = '3i' - unroll = 3 - break - - case GL_INT_VEC4: - case GL_BOOL_VEC4: - infix = '4i' - unroll = 4 - break - - case GL_FLOAT$7: - infix = '1f' - break - - case GL_FLOAT_VEC2: - infix = '2f' - unroll = 2 - break - - case GL_FLOAT_VEC3: - infix = '3f' - unroll = 3 - break - - case GL_FLOAT_VEC4: - infix = '4f' - unroll = 4 - break - - case GL_FLOAT_MAT2: - infix = 'Matrix2fv' - break - - case GL_FLOAT_MAT3: - infix = 'Matrix3fv' - break - - case GL_FLOAT_MAT4: - infix = 'Matrix4fv' - break - } - - if (infix.indexOf('Matrix') === -1 && size > 1) { - infix += 'v' - unroll = 1 - } - - if (infix.charAt(0) === 'M') { - scope(GL, '.uniform', infix, '(', LOCATION, ',') - var matSize = Math.pow(type - GL_FLOAT_MAT2 + 2, 2) - var STORAGE = env.global.def('new Float32Array(', matSize, ')') - if (Array.isArray(VALUE)) { - scope( - 'false,(', - loop(matSize, function (i) { - return STORAGE + '[' + i + ']=' + VALUE[i] - }), ',', STORAGE, ')') - } else { - scope( - 'false,(Array.isArray(', VALUE, ')||', VALUE, ' instanceof Float32Array)?', VALUE, ':(', - loop(matSize, function (i) { - return STORAGE + '[' + i + ']=' + VALUE + '[' + i + ']' - }), ',', STORAGE, ')') - } - scope(');') - } else if (unroll > 1) { - var prev = [] - var cur = [] - for (var j = 0; j < unroll; ++j) { - if (Array.isArray(VALUE)) { - cur.push(VALUE[j]) - } else { - cur.push(scope.def(VALUE + '[' + j + ']')) - } - if (isBatchInnerLoop) { - prev.push(scope.def()) - } - } - if (isBatchInnerLoop) { - scope('if(!', env.batchId, '||', prev.map(function (p, i) { - return p + '!==' + cur[i] - }).join('||'), '){', prev.map(function (p, i) { - return p + '=' + cur[i] + ';' - }).join('')) - } - scope(GL, '.uniform', infix, '(', LOCATION, ',', cur.join(','), ');') - if (isBatchInnerLoop) { - scope('}') - } - } else { - - if (isBatchInnerLoop) { - var prevS = scope.def() - scope('if(!', env.batchId, '||', prevS, '!==', VALUE, '){', - prevS, '=', VALUE, ';') - } - scope(GL, '.uniform', infix, '(', LOCATION, ',', VALUE, ');') - if (isBatchInnerLoop) { - scope('}') - } - } - } - } - - function emitDraw (env, outer, inner, args) { - var shared = env.shared - var GL = shared.gl - var DRAW_STATE = shared.draw - - var drawOptions = args.draw - - function emitElements () { - var defn = drawOptions.elements - var ELEMENTS - var scope = outer - if (defn) { - if ((defn.contextDep && args.contextDynamic) || defn.propDep) { - scope = inner - } - ELEMENTS = defn.append(env, scope) - if (drawOptions.elementsActive) { - scope( - 'if(' + ELEMENTS + ')' + - GL + '.bindBuffer(' + GL_ELEMENT_ARRAY_BUFFER$2 + ',' + ELEMENTS + '.buffer.buffer);') - } - } else { - ELEMENTS = scope.def() - scope( - ELEMENTS, '=', DRAW_STATE, '.', S_ELEMENTS, ';', - 'if(', ELEMENTS, '){', - GL, '.bindBuffer(', GL_ELEMENT_ARRAY_BUFFER$2, ',', ELEMENTS, '.buffer.buffer);}', - 'else if(', shared.vao, '.currentVAO){', - ELEMENTS, '=', env.shared.elements + '.getElements(' + shared.vao, '.currentVAO.elements);', - (!extVertexArrays ? 'if(' + ELEMENTS + ')' + GL + '.bindBuffer(' + GL_ELEMENT_ARRAY_BUFFER$2 + ',' + ELEMENTS + '.buffer.buffer);' : ''), - '}') - } - return ELEMENTS - } - - function emitCount () { - var defn = drawOptions.count - var COUNT - var scope = outer - if (defn) { - if ((defn.contextDep && args.contextDynamic) || defn.propDep) { - scope = inner - } - COUNT = defn.append(env, scope) - - } else { - COUNT = scope.def(DRAW_STATE, '.', S_COUNT) - - } - return COUNT - } - - var ELEMENTS = emitElements() - function emitValue (name) { - var defn = drawOptions[name] - if (defn) { - if ((defn.contextDep && args.contextDynamic) || defn.propDep) { - return defn.append(env, inner) - } else { - return defn.append(env, outer) - } - } else { - return outer.def(DRAW_STATE, '.', name) - } - } - - var PRIMITIVE = emitValue(S_PRIMITIVE) - var OFFSET = emitValue(S_OFFSET) - - var COUNT = emitCount() - if (typeof COUNT === 'number') { - if (COUNT === 0) { - return - } - } else { - inner('if(', COUNT, '){') - inner.exit('}') - } - - var INSTANCES, EXT_INSTANCING - if (extInstancing) { - INSTANCES = emitValue(S_INSTANCES) - EXT_INSTANCING = env.instancing - } - - var ELEMENT_TYPE = ELEMENTS + '.type' - - var elementsStatic = drawOptions.elements && isStatic(drawOptions.elements) && !drawOptions.vaoActive - - function emitInstancing () { - function drawElements () { - inner(EXT_INSTANCING, '.drawElementsInstancedANGLE(', [ - PRIMITIVE, - COUNT, - ELEMENT_TYPE, - OFFSET + '<<((' + ELEMENT_TYPE + '-' + GL_UNSIGNED_BYTE$7 + ')>>1)', - INSTANCES - ], ');') - } - - function drawArrays () { - inner(EXT_INSTANCING, '.drawArraysInstancedANGLE(', - [PRIMITIVE, OFFSET, COUNT, INSTANCES], ');') - } - - if (ELEMENTS && ELEMENTS !== 'null') { - if (!elementsStatic) { - inner('if(', ELEMENTS, '){') - drawElements() - inner('}else{') - drawArrays() - inner('}') - } else { - drawElements() - } - } else { - drawArrays() - } - } - - function emitRegular () { - function drawElements () { - inner(GL + '.drawElements(' + [ - PRIMITIVE, - COUNT, - ELEMENT_TYPE, - OFFSET + '<<((' + ELEMENT_TYPE + '-' + GL_UNSIGNED_BYTE$7 + ')>>1)' - ] + ');') - } - - function drawArrays () { - inner(GL + '.drawArrays(' + [PRIMITIVE, OFFSET, COUNT] + ');') - } - - if (ELEMENTS && ELEMENTS !== 'null') { - if (!elementsStatic) { - inner('if(', ELEMENTS, '){') - drawElements() - inner('}else{') - drawArrays() - inner('}') - } else { - drawElements() - } - } else { - drawArrays() - } - } - - if (extInstancing && (typeof INSTANCES !== 'number' || INSTANCES >= 0)) { - if (typeof INSTANCES === 'string') { - inner('if(', INSTANCES, '>0){') - emitInstancing() - inner('}else if(', INSTANCES, '<0){') - emitRegular() - inner('}') - } else { - emitInstancing() - } - } else { - emitRegular() - } - } - - function createBody (emitBody, parentEnv, args, program, count) { - var env = createREGLEnvironment() - var scope = env.proc('body', count) - - if (extInstancing) { - env.instancing = scope.def( - env.shared.extensions, '.angle_instanced_arrays') - } - emitBody(env, scope, args, program) - return env.compile().body - } - - // =================================================== - // =================================================== - // DRAW PROC - // =================================================== - // =================================================== - function emitDrawBody (env, draw, args, program) { - injectExtensions(env, draw) - if (args.useVAO) { - if (args.drawVAO) { - draw(env.shared.vao, '.setVAO(', args.drawVAO.append(env, draw), ');') - } else { - draw(env.shared.vao, '.setVAO(', env.shared.vao, '.targetVAO);') - } - } else { - draw(env.shared.vao, '.setVAO(null);') - emitAttributes(env, draw, args, program.attributes, function () { - return true - }) - } - emitUniforms(env, draw, args, program.uniforms, function () { - return true - }, false) - emitDraw(env, draw, draw, args) - } - - function emitDrawProc (env, args) { - var draw = env.proc('draw', 1) - - injectExtensions(env, draw) - - emitContext(env, draw, args.context) - emitPollFramebuffer(env, draw, args.framebuffer) - - emitPollState(env, draw, args) - emitSetOptions(env, draw, args.state) - - emitProfile(env, draw, args, false, true) - - var program = args.shader.progVar.append(env, draw) - draw(env.shared.gl, '.useProgram(', program, '.program);') - - if (args.shader.program) { - emitDrawBody(env, draw, args, args.shader.program) - } else { - draw(env.shared.vao, '.setVAO(null);') - var drawCache = env.global.def('{}') - var PROG_ID = draw.def(program, '.id') - var CACHED_PROC = draw.def(drawCache, '[', PROG_ID, ']') - draw( - env.cond(CACHED_PROC) - .then(CACHED_PROC, '.call(this,a0);') - .else( - CACHED_PROC, '=', drawCache, '[', PROG_ID, ']=', - env.link(function (program) { - return createBody(emitDrawBody, env, args, program, 1) - }), '(', program, ');', - CACHED_PROC, '.call(this,a0);')) - } - - if (Object.keys(args.state).length > 0) { - draw(env.shared.current, '.dirty=true;') - } - if (env.shared.vao) { - draw(env.shared.vao, '.setVAO(null);') - } - } - - // =================================================== - // =================================================== - // BATCH PROC - // =================================================== - // =================================================== - - function emitBatchDynamicShaderBody (env, scope, args, program) { - env.batchId = 'a1' - - injectExtensions(env, scope) - - function all () { - return true - } - - emitAttributes(env, scope, args, program.attributes, all) - emitUniforms(env, scope, args, program.uniforms, all, false) - emitDraw(env, scope, scope, args) - } - - function emitBatchBody (env, scope, args, program) { - injectExtensions(env, scope) - - var contextDynamic = args.contextDep - - var BATCH_ID = scope.def() - var PROP_LIST = 'a0' - var NUM_PROPS = 'a1' - var PROPS = scope.def() - env.shared.props = PROPS - env.batchId = BATCH_ID - - var outer = env.scope() - var inner = env.scope() - - scope( - outer.entry, - 'for(', BATCH_ID, '=0;', BATCH_ID, '<', NUM_PROPS, ';++', BATCH_ID, '){', - PROPS, '=', PROP_LIST, '[', BATCH_ID, '];', - inner, - '}', - outer.exit) - - function isInnerDefn (defn) { - return ((defn.contextDep && contextDynamic) || defn.propDep) - } - - function isOuterDefn (defn) { - return !isInnerDefn(defn) - } - - if (args.needsContext) { - emitContext(env, inner, args.context) - } - if (args.needsFramebuffer) { - emitPollFramebuffer(env, inner, args.framebuffer) - } - emitSetOptions(env, inner, args.state, isInnerDefn) - - if (args.profile && isInnerDefn(args.profile)) { - emitProfile(env, inner, args, false, true) - } - - if (!program) { - var progCache = env.global.def('{}') - var PROGRAM = args.shader.progVar.append(env, inner) - var PROG_ID = inner.def(PROGRAM, '.id') - var CACHED_PROC = inner.def(progCache, '[', PROG_ID, ']') - inner( - env.shared.gl, '.useProgram(', PROGRAM, '.program);', - 'if(!', CACHED_PROC, '){', - CACHED_PROC, '=', progCache, '[', PROG_ID, ']=', - env.link(function (program) { - return createBody( - emitBatchDynamicShaderBody, env, args, program, 2) - }), '(', PROGRAM, ');}', - CACHED_PROC, '.call(this,a0[', BATCH_ID, '],', BATCH_ID, ');') - } else { - if (args.useVAO) { - if (args.drawVAO) { - if (isInnerDefn(args.drawVAO)) { - // vao is a prop - inner(env.shared.vao, '.setVAO(', args.drawVAO.append(env, inner), ');') - } else { - // vao is invariant - outer(env.shared.vao, '.setVAO(', args.drawVAO.append(env, outer), ');') - } - } else { - // scoped vao binding - outer(env.shared.vao, '.setVAO(', env.shared.vao, '.targetVAO);') - } - } else { - outer(env.shared.vao, '.setVAO(null);') - emitAttributes(env, outer, args, program.attributes, isOuterDefn) - emitAttributes(env, inner, args, program.attributes, isInnerDefn) - } - emitUniforms(env, outer, args, program.uniforms, isOuterDefn, false) - emitUniforms(env, inner, args, program.uniforms, isInnerDefn, true) - emitDraw(env, outer, inner, args) - } - } - - function emitBatchProc (env, args) { - var batch = env.proc('batch', 2) - env.batchId = '0' - - injectExtensions(env, batch) - - // Check if any context variables depend on props - var contextDynamic = false - var needsContext = true - Object.keys(args.context).forEach(function (name) { - contextDynamic = contextDynamic || args.context[name].propDep - }) - if (!contextDynamic) { - emitContext(env, batch, args.context) - needsContext = false - } - - // framebuffer state affects framebufferWidth/height context vars - var framebuffer = args.framebuffer - var needsFramebuffer = false - if (framebuffer) { - if (framebuffer.propDep) { - contextDynamic = needsFramebuffer = true - } else if (framebuffer.contextDep && contextDynamic) { - needsFramebuffer = true - } - if (!needsFramebuffer) { - emitPollFramebuffer(env, batch, framebuffer) - } - } else { - emitPollFramebuffer(env, batch, null) - } - - // viewport is weird because it can affect context vars - if (args.state.viewport && args.state.viewport.propDep) { - contextDynamic = true - } - - function isInnerDefn (defn) { - return (defn.contextDep && contextDynamic) || defn.propDep - } - - // set webgl options - emitPollState(env, batch, args) - emitSetOptions(env, batch, args.state, function (defn) { - return !isInnerDefn(defn) - }) - - if (!args.profile || !isInnerDefn(args.profile)) { - emitProfile(env, batch, args, false, 'a1') - } - - // Save these values to args so that the batch body routine can use them - args.contextDep = contextDynamic - args.needsContext = needsContext - args.needsFramebuffer = needsFramebuffer - - // determine if shader is dynamic - var progDefn = args.shader.progVar - if ((progDefn.contextDep && contextDynamic) || progDefn.propDep) { - emitBatchBody( - env, - batch, - args, - null) - } else { - var PROGRAM = progDefn.append(env, batch) - batch(env.shared.gl, '.useProgram(', PROGRAM, '.program);') - if (args.shader.program) { - emitBatchBody( - env, - batch, - args, - args.shader.program) - } else { - batch(env.shared.vao, '.setVAO(null);') - var batchCache = env.global.def('{}') - var PROG_ID = batch.def(PROGRAM, '.id') - var CACHED_PROC = batch.def(batchCache, '[', PROG_ID, ']') - batch( - env.cond(CACHED_PROC) - .then(CACHED_PROC, '.call(this,a0,a1);') - .else( - CACHED_PROC, '=', batchCache, '[', PROG_ID, ']=', - env.link(function (program) { - return createBody(emitBatchBody, env, args, program, 2) - }), '(', PROGRAM, ');', - CACHED_PROC, '.call(this,a0,a1);')) - } - } - - if (Object.keys(args.state).length > 0) { - batch(env.shared.current, '.dirty=true;') - } - - if (env.shared.vao) { - batch(env.shared.vao, '.setVAO(null);') - } - } - - // =================================================== - // =================================================== - // SCOPE COMMAND - // =================================================== - // =================================================== - function emitScopeProc (env, args) { - var scope = env.proc('scope', 3) - env.batchId = 'a2' - - var shared = env.shared - var CURRENT_STATE = shared.current - - emitContext(env, scope, args.context) - - if (args.framebuffer) { - args.framebuffer.append(env, scope) - } - - sortState(Object.keys(args.state)).forEach(function (name) { - var defn = args.state[name] - var value = defn.append(env, scope) - if (isArrayLike(value)) { - value.forEach(function (v, i) { - scope.set(env.next[name], '[' + i + ']', v) - }) - } else { - scope.set(shared.next, '.' + name, value) - } - }) - - emitProfile(env, scope, args, true, true) - - ;[S_ELEMENTS, S_OFFSET, S_COUNT, S_INSTANCES, S_PRIMITIVE].forEach( - function (opt) { - var variable = args.draw[opt] - if (!variable) { - return - } - scope.set(shared.draw, '.' + opt, '' + variable.append(env, scope)) - }) - - Object.keys(args.uniforms).forEach(function (opt) { - var value = args.uniforms[opt].append(env, scope) - if (Array.isArray(value)) { - value = '[' + value.join() + ']' - } - scope.set( - shared.uniforms, - '[' + stringStore.id(opt) + ']', - value) - }) - - Object.keys(args.attributes).forEach(function (name) { - var record = args.attributes[name].append(env, scope) - var scopeAttrib = env.scopeAttrib(name) - Object.keys(new AttributeRecord()).forEach(function (prop) { - scope.set(scopeAttrib, '.' + prop, record[prop]) - }) - }) - - if (args.scopeVAO) { - scope.set(shared.vao, '.targetVAO', args.scopeVAO.append(env, scope)) - } - - function saveShader (name) { - var shader = args.shader[name] - if (shader) { - scope.set(shared.shader, '.' + name, shader.append(env, scope)) - } - } - saveShader(S_VERT) - saveShader(S_FRAG) - - if (Object.keys(args.state).length > 0) { - scope(CURRENT_STATE, '.dirty=true;') - scope.exit(CURRENT_STATE, '.dirty=true;') - } - - scope('a1(', env.shared.context, ',a0,', env.batchId, ');') - } - - function isDynamicObject (object) { - if (typeof object !== 'object' || isArrayLike(object)) { - return - } - var props = Object.keys(object) - for (var i = 0; i < props.length; ++i) { - if (dynamic.isDynamic(object[props[i]])) { - return true - } - } - return false - } - - function splatObject (env, options, name) { - var object = options.static[name] - if (!object || !isDynamicObject(object)) { - return - } - - var globals = env.global - var keys = Object.keys(object) - var thisDep = false - var contextDep = false - var propDep = false - var objectRef = env.global.def('{}') - keys.forEach(function (key) { - var value = object[key] - if (dynamic.isDynamic(value)) { - if (typeof value === 'function') { - value = object[key] = dynamic.unbox(value) - } - var deps = createDynamicDecl(value, null) - thisDep = thisDep || deps.thisDep - propDep = propDep || deps.propDep - contextDep = contextDep || deps.contextDep - } else { - globals(objectRef, '.', key, '=') - switch (typeof value) { - case 'number': - globals(value) - break - case 'string': - globals('"', value, '"') - break - case 'object': - if (Array.isArray(value)) { - globals('[', value.join(), ']') - } - break - default: - globals(env.link(value)) - break - } - globals(';') - } - }) - - function appendBlock (env, block) { - keys.forEach(function (key) { - var value = object[key] - if (!dynamic.isDynamic(value)) { - return - } - var ref = env.invoke(block, value) - block(objectRef, '.', key, '=', ref, ';') - }) - } - - options.dynamic[name] = new dynamic.DynamicVariable(DYN_THUNK, { - thisDep: thisDep, - contextDep: contextDep, - propDep: propDep, - ref: objectRef, - append: appendBlock - }) - delete options.static[name] - } - - // =========================================================================== - // =========================================================================== - // MAIN DRAW COMMAND - // =========================================================================== - // =========================================================================== - function compileCommand (options, attributes, uniforms, context, stats) { - var env = createREGLEnvironment() - - // link stats, so that we can easily access it in the program. - env.stats = env.link(stats) - - // splat options and attributes to allow for dynamic nested properties - Object.keys(attributes.static).forEach(function (key) { - splatObject(env, attributes, key) - }) - NESTED_OPTIONS.forEach(function (name) { - splatObject(env, options, name) - }) - - var args = parseArguments(options, attributes, uniforms, context, env) - - emitDrawProc(env, args) - emitScopeProc(env, args) - emitBatchProc(env, args) - - return extend(env.compile(), { - destroy: function () { - args.shader.program.destroy() - } - }) - } - - // =========================================================================== - // =========================================================================== - // POLL / REFRESH - // =========================================================================== - // =========================================================================== - return { - next: nextState, - current: currentState, - procs: (function () { - var env = createREGLEnvironment() - var poll = env.proc('poll') - var refresh = env.proc('refresh') - var common = env.block() - poll(common) - refresh(common) - - var shared = env.shared - var GL = shared.gl - var NEXT_STATE = shared.next - var CURRENT_STATE = shared.current - - common(CURRENT_STATE, '.dirty=false;') - - emitPollFramebuffer(env, poll) - emitPollFramebuffer(env, refresh, null, true) - - // Refresh updates all attribute state changes - var INSTANCING - if (extInstancing) { - INSTANCING = env.link(extInstancing) - } - - // update vertex array bindings - if (extensions.oes_vertex_array_object) { - refresh(env.link(extensions.oes_vertex_array_object), '.bindVertexArrayOES(null);') - } - for (var i = 0; i < limits.maxAttributes; ++i) { - var BINDING = refresh.def(shared.attributes, '[', i, ']') - var ifte = env.cond(BINDING, '.buffer') - ifte.then( - GL, '.enableVertexAttribArray(', i, ');', - GL, '.bindBuffer(', - GL_ARRAY_BUFFER$2, ',', - BINDING, '.buffer.buffer);', - GL, '.vertexAttribPointer(', - i, ',', - BINDING, '.size,', - BINDING, '.type,', - BINDING, '.normalized,', - BINDING, '.stride,', - BINDING, '.offset);' - ).else( - GL, '.disableVertexAttribArray(', i, ');', - GL, '.vertexAttrib4f(', - i, ',', - BINDING, '.x,', - BINDING, '.y,', - BINDING, '.z,', - BINDING, '.w);', - BINDING, '.buffer=null;') - refresh(ifte) - if (extInstancing) { - refresh( - INSTANCING, '.vertexAttribDivisorANGLE(', - i, ',', - BINDING, '.divisor);') - } - } - refresh( - env.shared.vao, '.currentVAO=null;', - env.shared.vao, '.setVAO(', env.shared.vao, '.targetVAO);') - - Object.keys(GL_FLAGS).forEach(function (flag) { - var cap = GL_FLAGS[flag] - var NEXT = common.def(NEXT_STATE, '.', flag) - var block = env.block() - block('if(', NEXT, '){', - GL, '.enable(', cap, ')}else{', - GL, '.disable(', cap, ')}', - CURRENT_STATE, '.', flag, '=', NEXT, ';') - refresh(block) - poll( - 'if(', NEXT, '!==', CURRENT_STATE, '.', flag, '){', - block, - '}') - }) - - Object.keys(GL_VARIABLES).forEach(function (name) { - var func = GL_VARIABLES[name] - var init = currentState[name] - var NEXT, CURRENT - var block = env.block() - block(GL, '.', func, '(') - if (isArrayLike(init)) { - var n = init.length - NEXT = env.global.def(NEXT_STATE, '.', name) - CURRENT = env.global.def(CURRENT_STATE, '.', name) - block( - loop(n, function (i) { - return NEXT + '[' + i + ']' - }), ');', - loop(n, function (i) { - return CURRENT + '[' + i + ']=' + NEXT + '[' + i + '];' - }).join('')) - poll( - 'if(', loop(n, function (i) { - return NEXT + '[' + i + ']!==' + CURRENT + '[' + i + ']' - }).join('||'), '){', - block, - '}') - } else { - NEXT = common.def(NEXT_STATE, '.', name) - CURRENT = common.def(CURRENT_STATE, '.', name) - block( - NEXT, ');', - CURRENT_STATE, '.', name, '=', NEXT, ';') - poll( - 'if(', NEXT, '!==', CURRENT, '){', - block, - '}') - } - refresh(block) - }) - - return env.compile() - })(), - compile: compileCommand - } -} - -function stats () { - return { - vaoCount: 0, - bufferCount: 0, - elementsCount: 0, - framebufferCount: 0, - shaderCount: 0, - textureCount: 0, - cubeCount: 0, - renderbufferCount: 0, - maxTextureUnits: 0 - } -} - -var GL_QUERY_RESULT_EXT = 0x8866 -var GL_QUERY_RESULT_AVAILABLE_EXT = 0x8867 -var GL_TIME_ELAPSED_EXT = 0x88BF - -var createTimer = function (gl, extensions) { - if (!extensions.ext_disjoint_timer_query) { - return null - } - - // QUERY POOL BEGIN - var queryPool = [] - function allocQuery () { - return queryPool.pop() || extensions.ext_disjoint_timer_query.createQueryEXT() - } - function freeQuery (query) { - queryPool.push(query) - } - // QUERY POOL END - - var pendingQueries = [] - function beginQuery (stats) { - var query = allocQuery() - extensions.ext_disjoint_timer_query.beginQueryEXT(GL_TIME_ELAPSED_EXT, query) - pendingQueries.push(query) - pushScopeStats(pendingQueries.length - 1, pendingQueries.length, stats) - } - - function endQuery () { - extensions.ext_disjoint_timer_query.endQueryEXT(GL_TIME_ELAPSED_EXT) - } - - // - // Pending stats pool. - // - function PendingStats () { - this.startQueryIndex = -1 - this.endQueryIndex = -1 - this.sum = 0 - this.stats = null - } - var pendingStatsPool = [] - function allocPendingStats () { - return pendingStatsPool.pop() || new PendingStats() - } - function freePendingStats (pendingStats) { - pendingStatsPool.push(pendingStats) - } - // Pending stats pool end - - var pendingStats = [] - function pushScopeStats (start, end, stats) { - var ps = allocPendingStats() - ps.startQueryIndex = start - ps.endQueryIndex = end - ps.sum = 0 - ps.stats = stats - pendingStats.push(ps) - } - - // we should call this at the beginning of the frame, - // in order to update gpuTime - var timeSum = [] - var queryPtr = [] - function update () { - var ptr, i - - var n = pendingQueries.length - if (n === 0) { - return - } - - // Reserve space - queryPtr.length = Math.max(queryPtr.length, n + 1) - timeSum.length = Math.max(timeSum.length, n + 1) - timeSum[0] = 0 - queryPtr[0] = 0 - - // Update all pending timer queries - var queryTime = 0 - ptr = 0 - for (i = 0; i < pendingQueries.length; ++i) { - var query = pendingQueries[i] - if (extensions.ext_disjoint_timer_query.getQueryObjectEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT)) { - queryTime += extensions.ext_disjoint_timer_query.getQueryObjectEXT(query, GL_QUERY_RESULT_EXT) - freeQuery(query) - } else { - pendingQueries[ptr++] = query - } - timeSum[i + 1] = queryTime - queryPtr[i + 1] = ptr - } - pendingQueries.length = ptr - - // Update all pending stat queries - ptr = 0 - for (i = 0; i < pendingStats.length; ++i) { - var stats = pendingStats[i] - var start = stats.startQueryIndex - var end = stats.endQueryIndex - stats.sum += timeSum[end] - timeSum[start] - var startPtr = queryPtr[start] - var endPtr = queryPtr[end] - if (endPtr === startPtr) { - stats.stats.gpuTime += stats.sum / 1e6 - freePendingStats(stats) - } else { - stats.startQueryIndex = startPtr - stats.endQueryIndex = endPtr - pendingStats[ptr++] = stats - } - } - pendingStats.length = ptr - } - - return { - beginQuery: beginQuery, - endQuery: endQuery, - pushScopeStats: pushScopeStats, - update: update, - getNumPendingQueries: function () { - return pendingQueries.length - }, - clear: function () { - queryPool.push.apply(queryPool, pendingQueries) - for (var i = 0; i < queryPool.length; i++) { - extensions.ext_disjoint_timer_query.deleteQueryEXT(queryPool[i]) - } - pendingQueries.length = 0 - queryPool.length = 0 - }, - restore: function () { - pendingQueries.length = 0 - queryPool.length = 0 - } - } -} - -var GL_COLOR_BUFFER_BIT = 16384 -var GL_DEPTH_BUFFER_BIT = 256 -var GL_STENCIL_BUFFER_BIT = 1024 - -var GL_ARRAY_BUFFER = 34962 - -var CONTEXT_LOST_EVENT = 'webglcontextlost' -var CONTEXT_RESTORED_EVENT = 'webglcontextrestored' - -var DYN_PROP = 1 -var DYN_CONTEXT = 2 -var DYN_STATE = 3 - -function find (haystack, needle) { - for (var i = 0; i < haystack.length; ++i) { - if (haystack[i] === needle) { - return i - } - } - return -1 -} - -function wrapREGL (args) { - var config = parseArgs(args) - if (!config) { - return null - } - - var gl = config.gl - var glAttributes = gl.getContextAttributes() - var contextLost = gl.isContextLost() - - var extensionState = createExtensionCache(gl, config) - if (!extensionState) { - return null - } - - var stringStore = createStringStore() - var stats$$1 = stats() - var extensions = extensionState.extensions - var timer = createTimer(gl, extensions) - - var START_TIME = clock() - var WIDTH = gl.drawingBufferWidth - var HEIGHT = gl.drawingBufferHeight - - var contextState = { - tick: 0, - time: 0, - viewportWidth: WIDTH, - viewportHeight: HEIGHT, - framebufferWidth: WIDTH, - framebufferHeight: HEIGHT, - drawingBufferWidth: WIDTH, - drawingBufferHeight: HEIGHT, - pixelRatio: config.pixelRatio - } - var uniformState = {} - var drawState = { - elements: null, - primitive: 4, // GL_TRIANGLES - count: -1, - offset: 0, - instances: -1 - } - - var limits = wrapLimits(gl, extensions) - var bufferState = wrapBufferState( - gl, - stats$$1, - config, - destroyBuffer) - var elementState = wrapElementsState(gl, extensions, bufferState, stats$$1) - var attributeState = wrapAttributeState( - gl, - extensions, - limits, - stats$$1, - bufferState, - elementState, - drawState) - function destroyBuffer (buffer) { - return attributeState.destroyBuffer(buffer) - } - var shaderState = wrapShaderState(gl, stringStore, stats$$1, config) - var textureState = createTextureSet( - gl, - extensions, - limits, - function () { core.procs.poll() }, - contextState, - stats$$1, - config) - var renderbufferState = wrapRenderbuffers(gl, extensions, limits, stats$$1, config) - var framebufferState = wrapFBOState( - gl, - extensions, - limits, - textureState, - renderbufferState, - stats$$1) - var core = reglCore( - gl, - stringStore, - extensions, - limits, - bufferState, - elementState, - textureState, - framebufferState, - uniformState, - attributeState, - shaderState, - drawState, - contextState, - timer, - config) - var readPixels = wrapReadPixels( - gl, - framebufferState, - core.procs.poll, - contextState, - glAttributes, extensions, limits) - - var nextState = core.next - var canvas = gl.canvas - - var rafCallbacks = [] - var lossCallbacks = [] - var restoreCallbacks = [] - var destroyCallbacks = [config.onDestroy] - - var activeRAF = null - function handleRAF () { - if (rafCallbacks.length === 0) { - if (timer) { - timer.update() - } - activeRAF = null - return - } - - // schedule next animation frame - activeRAF = raf.next(handleRAF) - - // poll for changes - poll() - - // fire a callback for all pending rafs - for (var i = rafCallbacks.length - 1; i >= 0; --i) { - var cb = rafCallbacks[i] - if (cb) { - cb(contextState, null, 0) - } - } - - // flush all pending webgl calls - gl.flush() - - // poll GPU timers *after* gl.flush so we don't delay command dispatch - if (timer) { - timer.update() - } - } - - function startRAF () { - if (!activeRAF && rafCallbacks.length > 0) { - activeRAF = raf.next(handleRAF) - } - } - - function stopRAF () { - if (activeRAF) { - raf.cancel(handleRAF) - activeRAF = null - } - } - - function handleContextLoss (event) { - event.preventDefault() - - // set context lost flag - contextLost = true - - // pause request animation frame - stopRAF() - - // lose context - lossCallbacks.forEach(function (cb) { - cb() - }) - } - - function handleContextRestored (event) { - // clear error code - gl.getError() - - // clear context lost flag - contextLost = false - - // refresh state - extensionState.restore() - shaderState.restore() - bufferState.restore() - textureState.restore() - renderbufferState.restore() - framebufferState.restore() - attributeState.restore() - if (timer) { - timer.restore() - } - - // refresh state - core.procs.refresh() - - // restart RAF - startRAF() - - // restore context - restoreCallbacks.forEach(function (cb) { - cb() - }) - } - - if (canvas) { - canvas.addEventListener(CONTEXT_LOST_EVENT, handleContextLoss, false) - canvas.addEventListener(CONTEXT_RESTORED_EVENT, handleContextRestored, false) - } - - function destroy () { - rafCallbacks.length = 0 - stopRAF() - - if (canvas) { - canvas.removeEventListener(CONTEXT_LOST_EVENT, handleContextLoss) - canvas.removeEventListener(CONTEXT_RESTORED_EVENT, handleContextRestored) - } - - shaderState.clear() - framebufferState.clear() - renderbufferState.clear() - attributeState.clear() - textureState.clear() - elementState.clear() - bufferState.clear() - - if (timer) { - timer.clear() - } - - destroyCallbacks.forEach(function (cb) { - cb() - }) - } - - function compileProcedure (options) { - - - - function flattenNestedOptions (options) { - var result = extend({}, options) - delete result.uniforms - delete result.attributes - delete result.context - delete result.vao - - if ('stencil' in result && result.stencil.op) { - result.stencil.opBack = result.stencil.opFront = result.stencil.op - delete result.stencil.op - } - - function merge (name) { - if (name in result) { - var child = result[name] - delete result[name] - Object.keys(child).forEach(function (prop) { - result[name + '.' + prop] = child[prop] - }) - } - } - merge('blend') - merge('depth') - merge('cull') - merge('stencil') - merge('polygonOffset') - merge('scissor') - merge('sample') - - if ('vao' in options) { - result.vao = options.vao - } - - return result - } - - function separateDynamic (object, useArrays) { - var staticItems = {} - var dynamicItems = {} - Object.keys(object).forEach(function (option) { - var value = object[option] - if (dynamic.isDynamic(value)) { - dynamicItems[option] = dynamic.unbox(value, option) - return - } else if (useArrays && Array.isArray(value)) { - for (var i = 0; i < value.length; ++i) { - if (dynamic.isDynamic(value[i])) { - dynamicItems[option] = dynamic.unbox(value, option) - return - } - } - } - staticItems[option] = value - }) - return { - dynamic: dynamicItems, - static: staticItems - } - } - - // Treat context variables separate from other dynamic variables - var context = separateDynamic(options.context || {}, true) - var uniforms = separateDynamic(options.uniforms || {}, true) - var attributes = separateDynamic(options.attributes || {}, false) - var opts = separateDynamic(flattenNestedOptions(options), false) - - var stats$$1 = { - gpuTime: 0.0, - cpuTime: 0.0, - count: 0 - } - - var compiled = core.compile(opts, attributes, uniforms, context, stats$$1) - - var draw = compiled.draw - var batch = compiled.batch - var scope = compiled.scope - - // FIXME: we should modify code generation for batch commands so this - // isn't necessary - var EMPTY_ARRAY = [] - function reserve (count) { - while (EMPTY_ARRAY.length < count) { - EMPTY_ARRAY.push(null) - } - return EMPTY_ARRAY - } - - function REGLCommand (args, body) { - var i - if (contextLost) { - - } - if (typeof args === 'function') { - return scope.call(this, null, args, 0) - } else if (typeof body === 'function') { - if (typeof args === 'number') { - for (i = 0; i < args; ++i) { - scope.call(this, null, body, i) - } - } else if (Array.isArray(args)) { - for (i = 0; i < args.length; ++i) { - scope.call(this, args[i], body, i) - } - } else { - return scope.call(this, args, body, 0) - } - } else if (typeof args === 'number') { - if (args > 0) { - return batch.call(this, reserve(args | 0), args | 0) - } - } else if (Array.isArray(args)) { - if (args.length) { - return batch.call(this, args, args.length) - } - } else { - return draw.call(this, args) - } - } - - return extend(REGLCommand, { - stats: stats$$1, - destroy: function () { - compiled.destroy() - } - }) - } - - var setFBO = framebufferState.setFBO = compileProcedure({ - framebuffer: dynamic.define.call(null, DYN_PROP, 'framebuffer') - }) - - function clearImpl (_, options) { - var clearFlags = 0 - core.procs.poll() - - var c = options.color - if (c) { - gl.clearColor(+c[0] || 0, +c[1] || 0, +c[2] || 0, +c[3] || 0) - clearFlags |= GL_COLOR_BUFFER_BIT - } - if ('depth' in options) { - gl.clearDepth(+options.depth) - clearFlags |= GL_DEPTH_BUFFER_BIT - } - if ('stencil' in options) { - gl.clearStencil(options.stencil | 0) - clearFlags |= GL_STENCIL_BUFFER_BIT - } - - - gl.clear(clearFlags) - } - - function clear (options) { - - if ('framebuffer' in options) { - if (options.framebuffer && - options.framebuffer_reglType === 'framebufferCube') { - for (var i = 0; i < 6; ++i) { - setFBO(extend({ - framebuffer: options.framebuffer.faces[i] - }, options), clearImpl) - } - } else { - setFBO(options, clearImpl) - } - } else { - clearImpl(null, options) - } - } - - function frame (cb) { - - rafCallbacks.push(cb) - - function cancel () { - // FIXME: should we check something other than equals cb here? - // what if a user calls frame twice with the same callback... - // - var i = find(rafCallbacks, cb) - - function pendingCancel () { - var index = find(rafCallbacks, pendingCancel) - rafCallbacks[index] = rafCallbacks[rafCallbacks.length - 1] - rafCallbacks.length -= 1 - if (rafCallbacks.length <= 0) { - stopRAF() - } - } - rafCallbacks[i] = pendingCancel - } - - startRAF() - - return { - cancel: cancel - } - } - - // poll viewport - function pollViewport () { - var viewport = nextState.viewport - var scissorBox = nextState.scissor_box - viewport[0] = viewport[1] = scissorBox[0] = scissorBox[1] = 0 - contextState.viewportWidth = - contextState.framebufferWidth = - contextState.drawingBufferWidth = - viewport[2] = - scissorBox[2] = gl.drawingBufferWidth - contextState.viewportHeight = - contextState.framebufferHeight = - contextState.drawingBufferHeight = - viewport[3] = - scissorBox[3] = gl.drawingBufferHeight - } - - function poll () { - contextState.tick += 1 - contextState.time = now() - pollViewport() - core.procs.poll() - } - - function refresh () { - textureState.refresh() - pollViewport() - core.procs.refresh() - if (timer) { - timer.update() - } - } - - function now () { - return (clock() - START_TIME) / 1000.0 - } - - refresh() - - function addListener (event, callback) { - - - var callbacks - switch (event) { - case 'frame': - return frame(callback) - case 'lost': - callbacks = lossCallbacks - break - case 'restore': - callbacks = restoreCallbacks - break - case 'destroy': - callbacks = destroyCallbacks - break - default: - - } - - callbacks.push(callback) - return { - cancel: function () { - for (var i = 0; i < callbacks.length; ++i) { - if (callbacks[i] === callback) { - callbacks[i] = callbacks[callbacks.length - 1] - callbacks.pop() - return - } - } - } - } - } - - var regl = extend(compileProcedure, { - // Clear current FBO - clear: clear, - - // Short cuts for dynamic variables - prop: dynamic.define.bind(null, DYN_PROP), - context: dynamic.define.bind(null, DYN_CONTEXT), - this: dynamic.define.bind(null, DYN_STATE), - - // executes an empty draw command - draw: compileProcedure({}), - - // Resources - buffer: function (options) { - return bufferState.create(options, GL_ARRAY_BUFFER, false, false) - }, - elements: function (options) { - return elementState.create(options, false) - }, - texture: textureState.create2D, - cube: textureState.createCube, - renderbuffer: renderbufferState.create, - framebuffer: framebufferState.create, - framebufferCube: framebufferState.createCube, - vao: attributeState.createVAO, - - // Expose context attributes - attributes: glAttributes, - - // Frame rendering - frame: frame, - on: addListener, - - // System limits - limits: limits, - hasExtension: function (name) { - return limits.extensions.indexOf(name.toLowerCase()) >= 0 - }, - - // Read pixels - read: readPixels, - - // Destroy regl and all associated resources - destroy: destroy, - - // Direct GL state manipulation - _gl: gl, - _refresh: refresh, - - poll: function () { - poll() - if (timer) { - timer.update() - } - }, - - // Current time - now: now, - - // regl Statistics Information - stats: stats$$1 - }) - - config.onDone(null, regl) - - return regl -} - -return wrapREGL; - -}))); diff --git a/package.json b/package.json index 33950557..430c4c8e 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "bench-node": "node bench/bench-node.js", "bench-graph": "node bench/bench-graph.js", "bench-history": "node bench/bench-history", - "build": "npm run build-script && npm run build-min && npm run build-typescript", + "build": "mkdirp build && npm run build-script && npm run build-min && npm run build-typescript", "build-script": "rollup -c rollup/config.js", "build-min": "rollup -c rollup/config.unchecked.js && node bin/minify.js dist/regl.unchecked.js dist/regl.min.js", "build-bench": "rollup -c rollup/config.bench.js",