# webgl-utils

This luma.gl sub-module contains a number of completely generic WebGL helper functions that luma.gl relies on. They are independent of the luma.gl API and of each other, and could possibly be of generic interest for other webgl programs or frameworks that don't want to use luma.gl itself.

Since all luma.gl code is MIT licensed you are of course welcome to copy these into your projects should you find them helpful.


## Canvas Management

The canvas manages the default drawing buffer including the size of the default drawing buffer, so the canvas typically needs to be updated when the window resizes

## getPageLoadPromise

Returns a promise that resolves when the page's HTML has loaded (meaning that any canvas specified in the HTML can now be queried by id).

### createCanvas

Programatically creates a canvas element with a certain size and id, and inserts it into the documents body once the page is loaded (see `getPageLoadPromise`).

### resizeDrawingBuffer

Resizes the drawing buffer if the size of the canvas has changed. Intended to be called on every frame. By default, takes devicePixelRatio into account.

### createContext

Gives a controlled interface to create a WebGL1 or WebGL2 context from a canvas.

### trackContextCreation

If you need access to the WebGL context created by another application or framework, this spy allows you to intercept context creation requests.


## State Management

### trackContextState

Initialize WebGL state caching on a context. After calling this function, context state will be cached. State caching speeds up parameter access and enables `pushContextState` and `popContextState` to efficiently save and restore global WebGL context state.

`trackContextState(gl, {enable = true, copyState} = {})`

* `gl` (WebGLRenderingContext) - gl context
* `enable` (Boolean) - whether cache is being used
* `copyState` whether the state cache is initialized to WebGL defaults (fast) or read from the context (slow)

Remarks:
* `trackContextState` can be called multiple times to enable/disable state cache.
* `copyState`-`false` is fast, and yields correct results for newly created, unmodified contexts. If you are tracking a context created by an external framework, it is likely safest to use `copyState`=`true` to ensure the cache corresponds to the context state.


### pushContextState

Saves the current state of the context by "pushing" it onto an internal stack, enabling it to be restored later.

`pushContextState(gl)`

* `gl` (WebGLRenderingContext) - gl context
Returns: nothing

Remarks:
* Can be called multiple times, enabling "nested" usage.
* Each invocation of `pushContextState` is expected to be matched by a call to `popContextState` at a later time.


### popContextState

Restores the state of the context at the time of the latest call to `pushContextState`.

`popContextState(gl)`

* `gl` (WebGLRenderingContext) - gl context
Returns: nothing

Remarks;
* Any changes made to the context state after the last call to `pushContextState` are undone and "discarded".
* It is an error to call `popContextState` without first doing a matching call to `pushContextState`.


## Polyfills

Handles instanced rendering, vertex arrays, draw buffers, timer queries, etc, etc.


### polyfillContext

Registers WebGL2 API polyfills for functions that are available both in WebGL2 and as WebGL1 extensions.

`polyfillContext(gl)`
* `gl` (WebGLRenderingContext) - gl context
Returns: the polyfilled context (`gl`).

Remarks:
* Polyfills can be mock functions when the functionality is not provided by the current WebGL context. Capability checks will normally still be required by the application in this case, however once the capability is confirmed, the application can use the WebGL2 API regardless of the actual implementation.


### polyfillGetParameter

A polyfill for the `getParameter` function, allowing WebGL2 and extension constants to be queried regardless of what capabilities the platforms support. Intended to let applications be written in a more portable way.

Remarks:
* `polyfillGetParameter` is used by ("installed" by) `polyfillContext`.


## GLSL Error Parser

### formatGLSLError

A formatter for parsing errors and warnings from the GLSL compiler. see `parseGLSLError`.

* `errLog` (String) - error log (from `gl.getShaderInfoLog`)
* `src` (String) - original shader source code
* `shaderType` (Number) - shader type (GL constant)
Return (String) - Formatted string, has the error marked inline with src.

### parseGLSLError

A parse for GLSL compiler error logs. Note that the format of the error logs generated by the GLSL compiler is defined the WebGL spec, so it is possible to portably parse these logs.

This function formats each GLSL shader compiler error or warning and generates text showing the source code around the error with marks pointing out where the issue was encountered.

* `errLog` (String) - error log (from `gl.getShaderInfoLog`)
* `src` (String) - original shader source code
* `shaderType` (Number) - shader type (GL constant)
Return (object) - with `shaderName`, `errors` and `warnings` fields (all strings).


## WebGL Constants

### GL (namespace)

All WebGL2 and extension constants exported as a single namespace `GL`. Allows constants to be referenced without tracking which version of WebGL or what extensions are available.


### getKeyValue

Resolves a WebGL enumeration `name` (returns itself if already a number)

`getKeyValue(gl, name)`
* `gl` (WebGLRenderingContext) - gl context
* `name` (String)


### getKeyValue

Returns a key that matches the number.

`getKey(gl, value)`
* `gl` (WebGLRenderingContext) - gl context
