Socket
Socket
Sign inDemoInstall

regl

Package Overview
Dependencies
0
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.2.0 to 0.3.0

lib/framebuffer.js

126

API.md

@@ -917,3 +917,2 @@ # REGL API

---------------------------------------

@@ -1109,4 +1108,4 @@ ### Types

| `poll` | If set, then each frame check if this texture needs to be reuploaded | Depends on the element type |
| `data` | Image data for the texture |
| `crossOrigin` | Cross origin resource sharing URL |
| `data` | Image data for the texture | `null` |
| `crossOrigin` | Cross origin resource sharing URL | `null` |

@@ -1168,6 +1167,6 @@ * `shape` can be used as an array shortcut for `[width, height, channels]` of image

| `'rgba arc interpolated alpha'` | `ext.COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL` | 4 | `'uint8'` | ✓ | [WEBGL_compressed_texture_atc](https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_atc/) |
| 'rgb pvrtc 4bppv1' | `ext.COMPRESSED_RGB_PVRTC_4BPPV1_IMG` | 3 | `'uint8'` | ✓ | [WEBGL_compressed_texture_pvrtc](https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/) |
| 'rgb pvrtc 2bppv1' | `ext.COMPRESSED_RGB_PVRTC_2BPPV1_IMG` | 3 | `'uint8'` | ✓ | [WEBGL_compressed_texture_pvrtc](https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/) |
| 'rgba pvrtc 4bppv1' | `ext.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG` | 4 | `'uint8'` | ✓ | [WEBGL_compressed_texture_pvrtc](https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/) |
| 'rgba pvrtc 2bppv1' | `ext.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG` | 4 | `'uint8'` | ✓ | [WEBGL_compressed_texture_pvrtc](https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/) |
| `'rgb pvrtc 4bppv1'` | `ext.COMPRESSED_RGB_PVRTC_4BPPV1_IMG` | 3 | `'uint8'` | ✓ | [WEBGL_compressed_texture_pvrtc](https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/) |
| `'rgb pvrtc 2bppv1'` | `ext.COMPRESSED_RGB_PVRTC_2BPPV1_IMG` | 3 | `'uint8'` | ✓ | [WEBGL_compressed_texture_pvrtc](https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/) |
| `'rgba pvrtc 4bppv1'` | `ext.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG` | 4 | `'uint8'` | ✓ | [WEBGL_compressed_texture_pvrtc](https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/) |
| `'rgba pvrtc 2bppv1'` | `ext.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG` | 4 | `'uint8'` | ✓ | [WEBGL_compressed_texture_pvrtc](https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/) |
| `'rgb etc1'` | `ext.COMPRESSED_RGB_ETC1_WEBGL` | 3 | `'uint8'` | ✓ | [WEBGL_compressed_texture_etc1](https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/) |

@@ -1223,9 +1222,89 @@

**NOT YET IMPLEMENTED**
Example,
```javascript
var rb = regl.renderbuffer({
width: 16,
height: 16,
format: 'rgba4'
})
```
| Property | Interpretation | Default |
|----------|----------------|---------|
| `'format'` | Sets the internal format of the render buffer | `'rgba4'` |
| `'width'` | Sets the width of the render buffer in pixels | `1` |
| `'height'` | Sets the height of the render buffer in pixels | `1` |
| Format | Description |
|--------|-------------|
| `'rgba4'` | `gl.RGBA4` |
| `'rgb565'` | `gl.RGB565` |
| `'rgb5 a1'` | `gl.RGB5_A1` |
| `'depth'` | `gl.DEPTH_COMPONENT16` |
| `'stencil'` | `gl.STENCIL_INDEX8` |
| `'srgba'` | `ext.SRGB8_ALPHA8_EXT`, only if [EXT_sRGB](https://www.khronos.org/registry/webgl/extensions/EXT_sRGB/) supported |
**Relevant WebGL APIs**
* [`gl.createRenderbuffer`](https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCreateRenderbuffer.xml)
* [`gl.deleteRenderbuffer`](https://www.khronos.org/opengles/sdk/docs/man/xhtml/glDeleteRenderbuffer.xml)
* [`gl.renderbufferStorage`](https://www.khronos.org/opengles/sdk/docs/man/xhtml/glRenderbufferStorage.xml)
* [`gl.bindRenderbuffer`](https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindRenderbuffer.xml)
---------------------------------------
#### Frame buffers
Example,
**NOT YET IMPLEMENTED**
```javascript
var fbo = regl.framebuffer({
width: 256,
height: 256,
depth: true,
stencil: true
})
```
| Property | Description | Default |
|----------|-------------|---------|
| `width` | Sets the width of the framebuffer | `gl.drawingBufferWidth` |
| `height` | Sets the height of the framebuffer | `gl.drawingBufferHeight` |
| `format` | Sets the format of the color buffer | `'rgba'` |
| `type` | Sets the type of the color buffer if it is a texture | `'uint8'` |
| `colorCount` | Sets the number of color buffers | `1` |
| `depth` | Toggles whether or not a depth buffer is included | `true` |
| `stencil` | Toggles whether or not to use a stencil buffer | `false` |
| `depthTexture` | Toggles whether depth/stencil attachments should be in texture | `false` |
| `colorBuffers` | List of color buffers | |
| `depthBuffer` | | |
| `stencilBuffer` | | |
| `depthStencilBuffer` | | |
| Color format | Description | Attachment |
|--------------|-------------|------------|
| `'alpha'` | `gl.ALPHA` | Texture |
| `'luminance'` | `gl.LUMINANCE` | Texture |
| `'luminance alpha'` | `gl.LUMINANCE_ALPHA` | Texture |
| `'rgb'` | `gl.RGB` | Texture |
| `'rgba'` | `gl.RGBA` | Texture |
| `'rgba4'` | `gl.RGBA4` | Renderbuffer |
| `'rgb565'` | `gl.RGB565` | Renderbuffer |
| `'rgb5 a1'` | `gl.RGB5_A1` | Renderbuffer |
| Color type | Description |
|------------|-------------|
| `'best'` | Highest available precision |
| `'uint8'` | `gl.UNSIGNED_BYTE` |
| `'half float'` | 16 bit float |
| `'float'` | 32 bit float` |
**Relevant WebGL APIs**
* [`gl.createFramebuffer`](https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCreateFramebuffer.xml)
* [`gl.deleteFramebuffer`](https://www.khronos.org/opengles/sdk/docs/man/xhtml/glDeleteFramebuffer.xml)
* [`gl.framebufferRenderbuffer`](https://www.khronos.org/opengles/sdk/docs/man/xhtml/glFramebufferRenderbuffer.xml)
* [`gl.framebufferTexture2D`](https://www.khronos.org/opengles/sdk/docs/man/xhtml/glFramebufferTexture2D.xml)
* [`gl.bindFramebuffer`](https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindFramebuffer.xml)
---------------------------------------

@@ -1321,15 +1400,18 @@ ## Other features

| `extensions` | A list of all supported extensions |
| `pointSizeRange` | `gl.ALIASED_POINT_SIZE_RANGE` |
| `lineWidthRange` | `gl.ALIASED_LINE_WIDTH_RANGE` |
| `viewport` | `gl.MAX_VIEWPORT_DIMS` |
| `combinedTextureUnits` | `gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS` |
| `cubeMapSize` | `gl.MAX_CUBE_MAP_TEXTURE_SIZE` |
| `renderbufferSize` | `gl.MAX_RENDERBUFFER_SIZE` |
| `texUnits` | `gl.MAX_TEXTURE_IMAGE_UNITS` |
| `textureSize` | `gl.MAX_TEXTURE_SIZE` |
| `attributes` | `gl.MAX_VERTEX_ATTRIBS` |
| `vertexUniforms` | `gl.MAX_VERTEX_UNIFORM_VECTORS` |
| `vertexTextureUnits` | `gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS` |
| `varyingVectors` | `gl.MAX_VARYING_VECTORS` |
| `fragmentUniforms` | `gl.MAX_FRAGMENT_UNIFORM_VECTORS` |
| `maxAnisotropic` | Maximum number of anisotropic filtering samples |
| `maxDrawbuffers` | Maximum number of draw buffers |
| `maxColorAttachments` | Maximum number of color attachments |
| `pointSizeDims` | `gl.ALIASED_POINT_SIZE_RANGE` |
| `lineWidthDims` | `gl.ALIASED_LINE_WIDTH_RANGE` |
| `maxViewportDims` | `gl.MAX_VIEWPORT_DIMS` |
| `maxCombinedTextureUnits` | `gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS` |
| `maxCubeMapSize` | `gl.MAX_CUBE_MAP_TEXTURE_SIZE` |
| `maxRenderbufferSize` | `gl.MAX_RENDERBUFFER_SIZE` |
| `maxTextureUnits` | `gl.MAX_TEXTURE_IMAGE_UNITS` |
| `maxTextureSize` | `gl.MAX_TEXTURE_SIZE` |
| `maxAttributes` | `gl.MAX_VERTEX_ATTRIBS` |
| `maxVertexUniforms` | `gl.MAX_VERTEX_UNIFORM_VECTORS` |
| `maxVertexTextureUnits` | `gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS` |
| `maxVaryingVectors` | `gl.MAX_VARYING_VECTORS` |
| `maxFragmentUniforms` | `gl.MAX_FRAGMENT_UNIFORM_VECTORS` |
| `glsl` | `gl.SHADING_LANGUAGE_VERSION` |

@@ -1336,0 +1418,0 @@ | `renderer` | `gl.RENDERER` |

# Release notes
## Next
* added renderbuffers (via regl.renderbuffer)
* added framebuffer objects (via regl.framebuffer)
* regl.buffer and regl.elements can now take ndarray-like inputs
* Switch to using Google closure compiler for minified builds
## 0.2.0

@@ -4,0 +11,0 @@

6

lib/attribute.js

@@ -61,8 +61,6 @@ var glTypes = require('./constants/dtypes.json')

module.exports = function wrapAttributeState (gl, extensionState, bufferState) {
var extensions = extensionState.extensions
module.exports = function wrapAttributeState (gl, extensions, limits, bufferState) {
var attributeState = {}
var NUM_ATTRIBUTES = gl.getParameter(gl.MAX_VERTEX_ATTRIBS)
var NUM_ATTRIBUTES = limits.maxAttributes
var attributeBindings = new Array(NUM_ATTRIBUTES)

@@ -69,0 +67,0 @@ for (var i = 0; i < NUM_ATTRIBUTES; ++i) {

// Array and element buffer creation
var check = require('./check')
var isTypedArray = require('./is-typed-array')
var isNDArrayLike = require('./is-ndarray')
var arrayTypes = require('./constants/arraytypes.json')
var bufferTypes = require('./constants/dtypes.json')
var values = require('./values')
var GL_STATIC_DRAW = 35044
var GL_BYTE = 5120
var GL_UNSIGNED_BYTE = 5121
var GL_STATIC_DRAW = 35044
var GL_SHORT = 5122
var GL_UNSIGNED_SHORT = 5123
var GL_INT = 5124
var GL_UNSIGNED_INT = 5125
var GL_FLOAT = 5126

@@ -16,4 +25,28 @@

function flatten (data, dimension) {
var result = new Float32Array(data.length * dimension)
function typedArrayCode (data) {
return arrayTypes[Object.prototype.toString.call(data)] | 0
}
function makeTypedArray (dtype, args) {
switch (dtype) {
case GL_UNSIGNED_BYTE:
return new Uint8Array(args)
case GL_UNSIGNED_SHORT:
return new Uint16Array(args)
case GL_UNSIGNED_INT:
return new Uint32Array(args)
case GL_BYTE:
return new Int8Array(args)
case GL_SHORT:
return new Int16Array(args)
case GL_INT:
return new Int32Array(args)
case GL_FLOAT:
return new Float32Array(args)
default:
return null
}
}
function flatten (result, data, dimension) {
var ptr = 0

@@ -26,2 +59,11 @@ for (var i = 0; i < data.length; ++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]
}
}
return result

@@ -45,9 +87,35 @@ }

Object.assign(REGLBuffer.prototype, {
bind: function () {
gl.bindBuffer(this.type, this.buffer)
},
REGLBuffer.prototype.bind = function () {
gl.bindBuffer(this.type, this.buffer)
}
update: function (options) {
if (Array.isArray(options) || isTypedArray(options)) {
function refresh (buffer) {
if (!gl.isBuffer(buffer.buffer)) {
buffer.buffer = gl.createBuffer()
}
buffer.bind()
gl.bufferData(buffer.type, buffer.data || buffer.byteLength, buffer.usage)
}
function destroy (buffer) {
var handle = buffer.buffer
check(handle, 'buffer must not be deleted already')
if (gl.isBuffer(handle)) {
gl.deleteBuffer(handle)
}
buffer.buffer = null
delete bufferSet[buffer.id]
}
function createBuffer (options, type, deferInit) {
var handle = gl.createBuffer()
var buffer = new REGLBuffer(handle, type)
bufferSet[buffer.id] = buffer
function reglBuffer (input) {
var options = input || {}
if (Array.isArray(options) ||
isTypedArray(options) ||
isNDArrayLike(options)) {
options = {

@@ -70,68 +138,87 @@ data: options

var usage = options.usage
check.parameter(usage, usageTypes, 'buffer usage')
this.usage = usageTypes[options.usage]
check.parameter(usage, usageTypes, 'invalid buffer usage')
buffer.usage = usageTypes[options.usage]
} else {
buffer.usage = GL_STATIC_DRAW
}
var dtype = 0
if ('type' in options) {
check.parameter(options.type, bufferTypes, 'invalid buffer type')
dtype = bufferTypes[options.type]
}
var dimension = (options.dimension | 0) || 1
var byteLength = 0
var data = null
if ('data' in options) {
var data = options.data
data = options.data
if (data === null) {
this.byteLength = options.length | 0
this.dtype = GL_UNSIGNED_BYTE
byteLength = options.length | 0
} else {
if (Array.isArray(data)) {
if (isNDArrayLike(data)) {
var 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.raise('invalid shape')
}
dtype = dtype || typedArrayCode(data) || GL_FLOAT
dimension = shapeY
data = transpose(
makeTypedArray(dtype, shapeX * shapeY),
data.data,
shapeX, shapeY,
strideX, strideY,
offset)
} else if (Array.isArray(data)) {
if (data.length > 0 && Array.isArray(data[0])) {
dimension = data[0].length
data = flatten(data, dimension)
this.dtype = GL_FLOAT
dtype = dtype || GL_FLOAT
var result = makeTypedArray(dtype, data.length * dimension)
data = flatten(result, data, dimension)
data = result
} else {
data = new Float32Array(data)
this.dtype = GL_FLOAT
dtype = dtype || GL_FLOAT
data = makeTypedArray(dtype, data)
}
} else {
check.isTypedArray(data, 'invalid data type buffer data')
this.dtype = arrayTypes[Object.prototype.toString.call(data)]
dtype = dtype || typedArrayCode(data)
}
this.dimension = dimension
this.byteLength = data.byteLength
byteLength = data.byteLength
}
this.data = data
} else if ('length' in options) {
var byteLength = options.length
byteLength = options.length | 0
check.nni(byteLength, 'buffer length must be a nonnegative integer')
this.data = null
this.byteLength = options.length | 0
this.dtype = GL_UNSIGNED_BYTE
}
this.bind()
gl.bufferData(this.type, this.data || this.byteLength, this.usage)
},
buffer.data = data
buffer.dtype = dtype || GL_UNSIGNED_BYTE
buffer.byteLength = byteLength
buffer.dimension = dimension
refresh: function () {
if (!gl.isBuffer(this.buffer)) {
this.buffer = gl.createBuffer()
}
this.update({})
},
refresh(buffer)
destroy: function () {
check(this.buffer, 'buffer must not be deleted already')
gl.deleteBuffer(this.buffer)
this.buffer = null
delete bufferSet[this.id]
return reglBuffer
}
})
function createBuffer (options, type) {
options = options || {}
var handle = gl.createBuffer()
var buffer = new REGLBuffer(handle, type)
buffer.update(options)
bufferSet[buffer.id] = buffer
function reglBuffer (options) {
buffer.update(options || {})
return reglBuffer
if (!deferInit) {
reglBuffer(options)
}

@@ -141,3 +228,3 @@

reglBuffer._buffer = buffer
reglBuffer.destroy = function () { buffer.destroy() }
reglBuffer.destroy = function () { destroy(buffer) }

@@ -151,11 +238,7 @@ return reglBuffer

clear: function () {
Object.keys(bufferSet).forEach(function (bufferId) {
bufferSet[bufferId].destroy()
})
values(bufferSet).forEach(destroy)
},
refresh: function () {
Object.keys(bufferSet).forEach(function (bufferId) {
bufferSet[bufferId].refresh()
})
values(bufferSet).forEach(refresh)
},

@@ -162,0 +245,0 @@

@@ -24,32 +24,36 @@ // Error checking and parameter validation

function checkParameter (param, possibilities, message) {
check(param in possibilities,
'unknown parameter (' + param + ')' + encolon(message) +
'. possible values: ' + Object.keys(possibilities).join())
if (!(param in possibilities)) {
raise('unknown parameter (' + param + ')' + encolon(message) +
'. possible values: ' + Object.keys(possibilities).join())
}
}
function checkIsTypedArray (data, message) {
check(
isTypedArray(data),
'invalid parameter type' + encolon(message) +
'. must be a typed array')
if (!isTypedArray(data)) {
raise(
'invalid parameter type' + encolon(message) +
'. must be a typed array')
}
}
function checkTypeOf (value, type, message) {
check(typeof value === type,
'invalid parameter type' + encolon(message) +
'. expected ' + type + ', got ' + (typeof value))
if (typeof value !== type) {
raise(
'invalid parameter type' + encolon(message) +
'. expected ' + type + ', got ' + (typeof value))
}
}
function checkNonNegativeInt (value, message) {
check(
(value >= 0) &&
((value | 0) === value),
'invalid parameter type, (' + value + ')' + encolon(message) +
'. must be a nonnegative integer')
if (!((value >= 0) &&
((value | 0) === value))) {
raise('invalid parameter type, (' + value + ')' + encolon(message) +
'. must be a nonnegative integer')
}
}
function checkOneOf (value, list, message) {
check(
list.indexOf(value) >= 0,
'invalid value' + encolon(message) + '. must be one of: ' + list)
if (list.indexOf(value) < 0) {
raise('invalid value' + encolon(message) + '. must be one of: ' + list)
}
}

@@ -56,0 +60,0 @@

@@ -173,9 +173,23 @@ var check = require('./check')

// Need to process framebuffer first in options list
function optionPriority (a, b) {
if (a === 'framebuffer') {
return -1
}
if (a < b) {
return -1
} else if (a > b) {
return 1
}
return 0
}
module.exports = function reglCompiler (
gl,
extensionState,
extensions,
limits,
bufferState,
elementState,
textureState,
fboState,
framebufferState,
glState,

@@ -186,4 +200,4 @@ uniformState,

drawState,
frameState) {
var extensions = extensionState.extensions
frameState,
reglPoll) {
var contextState = glState.contextState

@@ -339,2 +353,3 @@

var FRAME_STATE = link(frameState)
var FRAMEBUFFER_STATE = link(framebufferState)
var DRAW_STATE = {

@@ -346,2 +361,3 @@ count: link(drawState.count),

}
var CONTEXT_STATE = {}
var ELEMENTS = link(elementState.elements)

@@ -361,2 +377,11 @@ var CUR_COUNT = def(stackTop(DRAW_STATE.count))

function linkContext (x) {
var result = CONTEXT_STATE[x]
if (result) {
return result
}
result = CONTEXT_STATE[x] = link(contextState[x])
return result
}
// -------------------------------

@@ -445,3 +470,3 @@ // batch/argument vars

'if(', CUR_ELEMENTS, '){',
GL, '.bindBuffer(', GL_ELEMENT_ARRAY_BUFFER, ',', CUR_ELEMENTS, '.buffer._buffer.buffer);',
GL, '.bindBuffer(', GL_ELEMENT_ARRAY_BUFFER, ',', CUR_ELEMENTS, '.buffer.buffer);',
'}else{',

@@ -462,3 +487,3 @@ GL, '.bindBuffer(', GL_ELEMENT_ARRAY_BUFFER, ',null);',

// -------------------------------
Object.keys(options).forEach(function (option) {
Object.keys(options).sort(optionPriority).forEach(function (option) {
var VALUE = dyn(options[option])

@@ -474,2 +499,14 @@

switch (option) {
case 'framebuffer':
var VIEWPORT_STATE = linkContext('viewport')
var SCISSOR_STATE = linkContext('scissor.box')
batch(
'if(', FRAMEBUFFER_STATE, '.push(',
VALUE, '&&', VALUE, '._framebuffer)){',
FRAMEBUFFER_STATE, '.poll();',
VIEWPORT_STATE, '.setDirty();',
SCISSOR_STATE, '.setDirty();',
'}')
break
// Caps

@@ -608,19 +645,9 @@ case 'cull.enable':

case 'scissor.box':
var SCISSOR_X = batch.def(VALUE + '.x||0')
var SCISSOR_Y = batch.def(VALUE + '.y||0')
batch(GL, '.scissor(',
SCISSOR_X, ',',
SCISSOR_Y, ',',
'"w" in ', VALUE, '?', VALUE, '.w:', GL, '.drawingBufferWidth-', SCISSOR_X, ',',
'"h" in ', VALUE, '?', VALUE, '.h:', GL, '.drawingBufferHeight-', SCISSOR_Y, ');')
break
case 'viewport':
var VIEWPORT_X = batch.def(VALUE + '.x||0')
var VIEWPORT_Y = batch.def(VALUE + '.y||0')
batch(GL, '.viewport(',
VIEWPORT_X, ',',
VIEWPORT_Y, ',',
'"w" in ', VALUE, '?', VALUE, '.w:', GL, '.drawingBufferWidth-', VIEWPORT_X, ',',
'"h" in ', VALUE, '?', VALUE, '.h:', GL, '.drawingBufferHeight-', VIEWPORT_Y, ');')
var BOX_STATE = linkContext(option)
batch(BOX_STATE, '.push(',
VALUE, '.x||0,',
VALUE, '.y||0,',
VALUE, '.w||-1,',
VALUE, '.h||-1);')
break

@@ -639,2 +666,13 @@

// update viewport/scissor box state and restore framebuffer
if ('viewport' in options || 'framebuffer' in options) {
batch(linkContext('viewport'), '.poll();')
}
if ('scissor.box' in options || 'framebuffer' in options) {
batch(linkContext('scissor.box'), '.poll();')
}
if ('framebuffer' in options) {
batch(FRAMEBUFFER_STATE, '.pop();')
}
// -------------------------------

@@ -725,3 +763,3 @@ // set dynamic uniforms

GL_ELEMENT_ARRAY_BUFFER, ',',
CUR_ELEMENTS, '.buffer._buffer.buffer);')
CUR_ELEMENTS, '.buffer.buffer);')
}

@@ -804,6 +842,7 @@ if (instancing) {

// -------------------------------
var GL_POLL = link(glState.poll)
var GL_POLL = link(reglPoll)
var FRAG_SHADER_STATE = link(shaderState.fragShaders)
var VERT_SHADER_STATE = link(shaderState.vertShaders)
var PROGRAM_STATE = link(shaderState.programs)
var FRAMEBUFFER_STATE = link(framebufferState)
var DRAW_STATE = {

@@ -847,3 +886,3 @@ count: link(drawState.count),

var hasShader = false
Object.keys(staticOptions).forEach(function (param) {
Object.keys(staticOptions).sort(optionPriority).forEach(function (param) {
var value = staticOptions[param]

@@ -863,2 +902,18 @@ switch (param) {

case 'framebuffer':
var fbo = framebufferState.getFramebuffer(value)
check(value === null || fbo, 'invalid framebuffer object')
var VIEWPORT_STATE = linkContext('viewport')
var SCISSOR_STATE = linkContext('scissor.box')
entry('if(', FRAMEBUFFER_STATE, '.push(', link(
value && value._framebuffer), ')){',
VIEWPORT_STATE, '.setDirty();',
SCISSOR_STATE, '.setDirty();',
'}')
exit('if(', FRAMEBUFFER_STATE, '.pop()){',
VIEWPORT_STATE, '.setDirty();',
SCISSOR_STATE, '.setDirty();',
'}')
break
// Update draw state

@@ -1070,3 +1125,9 @@ case 'count':

case 'lineWidth':
check(value > 0 && typeof value === 'number', param)
var lineWidthDims = limits.lineWidthDims
check(
typeof value === 'number' &&
value >= lineWidthDims[0] &&
value <= lineWidthDims[1],
'invalid line width, must positive number between ' +
lineWidthDims[0] + ' and ' + lineWidthDims[1])
handleStaticOption(param, value)

@@ -1280,3 +1341,3 @@ break

// -------------------------------
Object.keys(dynamicOptions).forEach(function (param) {
Object.keys(dynamicOptions).sort(optionPriority).forEach(function (param) {
// Link in dynamic variable

@@ -1286,2 +1347,18 @@ var variable = dyn(dynamicOptions[param])

switch (param) {
case 'framebuffer':
var VIEWPORT_STATE = linkContext('viewport')
var SCISSOR_STATE = linkContext('scissor.box')
dynamicEntry('if(',
FRAMEBUFFER_STATE, '.push(',
variable, '&&', variable, '._framebuffer)){',
VIEWPORT_STATE, '.setDirty();',
SCISSOR_STATE, '.setDirty();',
'}')
dynamicExit('if(',
FRAMEBUFFER_STATE, '.pop()){',
VIEWPORT_STATE, '.setDirty();',
SCISSOR_STATE, '.setDirty();',
'}')
break
case 'cull.enable':

@@ -1288,0 +1365,0 @@ case 'blend.enable':

var check = require('./check')
var isTypedArray = require('./is-typed-array')
var isNDArrayLike = require('./is-ndarray')
var primTypes = require('./constants/primitives.json')

@@ -9,4 +10,7 @@

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

@@ -16,5 +20,3 @@

module.exports = function wrapElementsState (gl, extensionState, bufferState) {
var extensions = extensionState.extensions
module.exports = function wrapElementsState (gl, extensions, bufferState) {
var elements = [ null ]

@@ -29,123 +31,132 @@

function parseOptions (elements, options) {
var result = {
type: 'elements'
}
var ext32bit = extensions.oes_element_index_uint
elements.primType = GL_TRIANGLES
elements.vertCount = 0
elements.type = 0
REGLElementBuffer.prototype.bind = function () {
this.buffer.bind()
}
var data = null
function createElements (options) {
var elements = new REGLElementBuffer()
var buffer = bufferState.create(null, GL_ELEMENT_ARRAY_BUFFER, true)
elements.buffer = buffer._buffer
// Check option type
if (!options) {
return result
}
if (typeof options === 'number') {
result.length = options
} else {
check.type(options, 'object', 'argument to element buffer must be object')
data = options.data || options
}
function reglElements (input) {
var options = input
var ext32bit = extensions.oes_element_index_uint
if (Array.isArray(data)) {
if (options.length === 0) {
data = null
} else if (Array.isArray(data[0])) {
var dim = data[0].length
if (dim === 1) elements.primType = GL_POINTS
if (dim === 2) elements.primType = GL_LINES
if (dim === 3) elements.primType = GL_TRIANGLES
var i
var count = 0
for (i = 0; i < data.length; ++i) {
count += data[i].length
}
var flattened = ext32bit
? new Uint32Array(count)
: new Uint16Array(count)
var ptr = 0
for (i = 0; i < data.length; ++i) {
var x = data[i]
for (var j = 0; j < x.length; ++j) {
flattened[ptr++] = x[j]
// Upload data to vertex buffer
if (!options) {
buffer()
} else if (typeof options === 'number') {
buffer(options)
} else {
var data = null
var usage = 'static'
var byteLength = 0
if (
Array.isArray(options) ||
isTypedArray(options) ||
isNDArrayLike(options)) {
data = options
} else {
check.type(options, 'object', 'invalid arguments for elements')
if ('data' in options) {
data = options.data
}
if ('usage' in options) {
usage = options.usage
}
if ('length' in options) {
byteLength = options.length
}
}
data = flattened
} else if (ext32bit) {
data = new Uint32Array(data)
} else {
data = new Uint16Array(data)
if (Array.isArray(data) ||
(isNDArrayLike(data) && data.dtype === 'array') ||
'type' in options) {
buffer({
type: options.type ||
(ext32bit
? 'uint32'
: 'uint16'),
usage: usage,
data: data,
length: byteLength
})
} else {
buffer({
usage: usage,
data: data,
length: byteLength
})
}
if (Array.isArray(data) || isTypedArray(data)) {
buffer.dimension = 3
}
}
}
if (isTypedArray(data)) {
if ((data instanceof Uint8Array) ||
(data instanceof Uint8ClampedArray)) {
elements.type = GL_UNSIGNED_BYTE
} else if (data instanceof Uint16Array) {
elements.type = GL_UNSIGNED_SHORT
} else if (data instanceof Uint32Array) {
check(ext32bit, '32-bit element buffers not supported')
elements.type = GL_UNSIGNED_INT
} else {
check.raise('invalid typed array for element buffer')
}
elements.vertCount = data.length
result.data = data
} else {
check(!data, 'invalid element buffer data type')
}
// try to guess default primitive type and arguments
var vertCount = elements.buffer.byteLength
var type = 0
switch (elements.buffer.dtype) {
case GL_UNSIGNED_BYTE:
case GL_BYTE:
type = GL_UNSIGNED_BYTE
break
if (typeof options === 'object') {
if ('primitive' in options) {
var primitive = options.primitive
check.param(primitive, primTypes)
elements.primType = primTypes[primitive]
}
case GL_UNSIGNED_SHORT:
case GL_SHORT:
type = GL_UNSIGNED_SHORT
vertCount >>= 1
break
if ('usage' in options) {
result.usage = options.usage
}
case GL_UNSIGNED_INT:
case GL_INT:
check(ext32bit, '32 bit element buffers not supported')
type = GL_UNSIGNED_INT
vertCount >>= 2
break
if ('count' in options) {
elements.vertCount = options.vertCount | 0
default:
check.raise('invalid element buffer type')
}
}
return result
}
// try to guess primitive type from cell dimension
var 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
Object.assign(REGLElementBuffer.prototype, {
bind: function () {
gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, this.buffer._buffer.buffer)
},
// if manual override present, use that
if (typeof options === 'object') {
if ('primitive' in options) {
var primitive = options.primitive
check.parameter(primitive, primTypes)
primType = primTypes[primitive]
}
destroy: function () {
if (this.buffer) {
this.buffer.destroy()
this.buffer = null
if ('count' in options) {
vertCount = options.vertCount | 0
}
}
}
})
function createElements (options) {
var elements = new REGLElementBuffer()
// update properties for element buffer
elements.primType = primType
elements.vertCount = vertCount
elements.type = type
// Create buffer
elements.buffer = bufferState.create(
parseOptions(elements, options),
GL_ELEMENT_ARRAY_BUFFER)
function updateElements (options) {
elements.buffer(parseOptions(elements, options))
return updateElements
return reglElements
}
updateElements._reglType = 'elements'
updateElements._elements = elements
updateElements.destroy = function () { elements.destroy() }
reglElements(options)
return updateElements
Object.assign(reglElements, {
_reglType: 'elements',
_elements: elements,
destroy: function () {
check(elements.buffer !== null, 'must not double destroy elements')
buffer.destroy()
elements.buffer = null
}
})
return reglElements
}

@@ -152,0 +163,0 @@

@@ -31,5 +31,6 @@ var GL_SUBPIXEL_BITS = 0x0D50

module.exports = function (gl, extensionState) {
var extensions = extensionState.extensions
var GL_MAX_COLOR_ATTACHMENTS_WEBGL = 0x8CDF
var GL_MAX_DRAW_BUFFERS_WEBGL = 0x8824
module.exports = function (gl, extensions) {
var maxAnisotropic = 1

@@ -40,2 +41,9 @@ if (extensions.ext_texture_filter_anisotropic) {

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)
}
return {

@@ -61,16 +69,20 @@ // drawing buffer bit depth

// max draw buffers
maxDrawbuffers: maxDrawbuffers,
maxColorAttachments: maxColorAttachments,
// point and line size ranges
pointSize: gl.getParameter(GL_ALIASED_POINT_SIZE_RANGE),
lineWidth: gl.getParameter(GL_ALIASED_LINE_WIDTH_RANGE),
viewport: gl.getParameter(GL_MAX_VIEWPORT_DIMS),
combinedTextureUnits: gl.getParameter(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS),
cubeMapSize: gl.getParameter(GL_MAX_CUBE_MAP_TEXTURE_SIZE),
renderbufferSize: gl.getParameter(GL_MAX_RENDERBUFFER_SIZE),
textureUnits: gl.getParameter(GL_MAX_TEXTURE_IMAGE_UNITS),
textureSize: gl.getParameter(GL_MAX_TEXTURE_SIZE),
attributes: gl.getParameter(GL_MAX_VERTEX_ATTRIBS),
vertexUniforms: gl.getParameter(GL_MAX_VERTEX_UNIFORM_VECTORS),
vertexTextureUnits: gl.getParameter(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS),
varyingVectors: gl.getParameter(GL_MAX_VARYING_VECTORS),
fragmentUniforms: gl.getParameter(GL_MAX_FRAGMENT_UNIFORM_VECTORS),
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),

@@ -77,0 +89,0 @@ // vendor info

@@ -8,3 +8,3 @@ var check = require('./check')

module.exports = function wrapReadPixels (gl, glState) {
module.exports = function wrapReadPixels (gl, reglPoll, viewportState) {
function readPixels (input) {

@@ -26,6 +26,5 @@ var options = input || {}

// Update WebGL state
glState.poll()
reglPoll()
// Read viewport state
var viewportState = glState.viewport
var x = options.x || 0

@@ -32,0 +31,0 @@ var y = options.y || 0

@@ -17,3 +17,2 @@ var check = require('./check')

gl,
extensions,
attributeState,

@@ -20,0 +19,0 @@ uniformState,

@@ -6,2 +6,3 @@ // A stack for managing the state of a scalar/vector parameter

var stack = init.slice()
var current = init.slice()
var dirty = true

@@ -34,2 +35,5 @@

}
for (var i = 0; i < n; ++i) {
current[i] = stack[ptr + i]
}
dirty = false

@@ -41,11 +45,16 @@ }

push: function () {
dirty = false
for (var i = 0; i < n; ++i) {
stack.push(arguments[i])
var x = arguments[i]
dirty = dirty || (x !== current[i])
stack.push(x)
}
dirty = true
},
pop: function () {
dirty = false
for (var i = 0; i < n; ++i) {
dirty = dirty || (stack[stack.length - n + i] !== current[i])
}
stack.length -= n
dirty = true
},

@@ -52,0 +61,0 @@

@@ -24,3 +24,3 @@ var createStack = require('./stack')

module.exports = function wrapContextState (gl, shaderState) {
module.exports = function wrapContextState (gl, framebufferState, viewportState) {
function capStack (cap, dflt) {

@@ -38,7 +38,2 @@ var result = createStack([!!dflt], function (flag) {

var viewportState = {
width: 0,
height: 0
}
// Caps, flags and other random WebGL context state

@@ -134,8 +129,17 @@ var contextState = {

var w_ = w
var fbo = framebufferState.top()
if (w < 0) {
w_ = gl.drawingBufferWidth - x
if (fbo) {
w_ = fbo.width - x
} else {
w_ = gl.drawingBufferWidth - x
}
}
var h_ = h
if (h < 0) {
h_ = gl.drawingBufferHeight - y
if (fbo) {
h_ = fbo.height - y
} else {
h_ = gl.drawingBufferHeight - y
}
}

@@ -148,8 +152,17 @@ gl.scissor(x, y, w_, h_)

var w_ = w
var fbo = framebufferState.top()
if (w < 0) {
w_ = gl.drawingBufferWidth - x
if (fbo) {
w_ = fbo.width - x
} else {
w_ = gl.drawingBufferWidth - x
}
}
var h_ = h
if (h < 0) {
h_ = gl.drawingBufferHeight - y
if (fbo) {
h_ = fbo.height - y
} else {
h_ = gl.drawingBufferHeight - y
}
}

@@ -156,0 +169,0 @@ gl.viewport(x, y, w_, h_)

var check = require('./check')
var values = require('./values')
var isTypedArray = require('./is-typed-array')
var isNDArrayLike = require('./is-ndarray')
var loadTexture = require('./load-texture')

@@ -108,13 +110,2 @@ var convertToHalfFloat = require('./to-half-float')

function isNDArrayLike (obj) {
return (
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)))
}
function isRectArray (arr) {

@@ -191,5 +182,3 @@ if (!Array.isArray(arr)) {

module.exports = function createTextureSet (gl, extensionState, limits, reglPoll, viewport) {
var extensions = extensionState.extensions
module.exports = function createTextureSet (gl, extensions, limits, reglPoll, viewportState) {
var mipmapHint = {

@@ -515,4 +504,2 @@ "don't care": GL_DONT_CARE,

data = loadTexture(data, this.crossOrigin)
} else {
check(!data || isPixelData(data), 'invalid pixel data')
}

@@ -629,4 +616,4 @@

this.y = this.y | 0
this.width = (this.width || viewport.width) | 0
this.height = (this.height || viewport.height) | 0
this.width = (this.width || viewportState.width) | 0
this.height = (this.height || viewportState.height) | 0
this.setDefaultFormat()

@@ -862,6 +849,2 @@ }

Object.assign(TexParams.prototype, {
clear: function () {
TexParams.call(this, this.target)
},
parse: function (options) {

@@ -1098,3 +1081,3 @@ if (typeof options !== 'object' || !options) {

var pollSet = []
var numTexUnits = limits.textureUnits
var numTexUnits = limits.maxTextureUnits
var textureUnits = Array(numTexUnits).map(function () {

@@ -1104,6 +1087,8 @@ return null

function REGLTexture (target, texture) {
function REGLTexture (target) {
this.id = textureCount++
this.refCount = 1
this.target = target
this.texture = texture
this.texture = null

@@ -1123,250 +1108,269 @@ this.pollId = -1

Object.assign(REGLTexture.prototype, {
function update (texture, options) {
var i
clearListeners(texture)
bind: function () {
this.bindCount += 1
var unit = this.unit
if (unit < 0) {
// FIXME: should we use an LRU to allocate textures here?
for (var i = 0; i < numTexUnits; ++i) {
var other = textureUnits[i]
if (!other || other.bindCount <= 0) {
if (other) {
other.unit = -1
}
textureUnits[i] = this
unit = i
break
}
}
if (unit >= numTexUnits) {
check.raise('insufficient number of texture units')
}
this.unit = unit
gl.activeTexture(GL_TEXTURE0 + unit)
gl.bindTexture(this.target, this.texture)
activeTexture = unit
}
return unit
},
// Clear parameters and pixel data
var params = texture.params
TexParams.call(params, texture.target)
var pixels = texture.pixels
pixels.length = 0
unbind: function () {
this.bindCount -= 1
},
// parse parameters
params.parse(options)
refresh: function () {
// Lazy bind
var target = this.target
var unit = this.unit
if (unit >= 0) {
gl.activeTexture(GL_TEXTURE0 + unit)
activeTexture = unit
// parse pixel data
function parseMip (target, data) {
var mipmap = data.mipmap
var pixmap
if (Array.isArray(mipmap)) {
for (var i = 0; i < mipmap.length; ++i) {
pixmap = new PixelInfo(target)
pixmap.parseFlags(options)
pixmap.parseFlags(data)
pixmap.parse(mipmap[i], i)
pixels.push(pixmap)
}
} else {
gl.bindTexture(target, this.texture)
pixmap = new PixelInfo(target)
pixmap.parseFlags(options)
pixmap.parse(data, 0)
pixels.push(pixmap)
}
// Upload
var pixels = this.pixels
var params = this.params
for (var i = 0; i < pixels.length; ++i) {
pixels[i].upload(params)
}
params.upload()
// Lazy unbind
if (unit < 0) {
var active = textureUnits[activeTexture]
if (active) {
// restore binding state
gl.bindTexture(active.target, active.texture)
} else {
// otherwise become new active
this.unit = activeTexture
textureUnits[activeTexture] = this
}
if (texture.target === GL_TEXTURE_2D) {
parseMip(GL_TEXTURE_2D, options)
} else {
var faces = options.faces || options
if (Array.isArray(faces)) {
check(faces.length === 6,
'invalid number of faces in cube map')
for (i = 0; i < 6; ++i) {
parseMip(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, faces[i])
}
} else if (typeof faces === 'string') {
// TODO Read dds
} else {
// Initialize to all empty textures
for (i = 0; i < 6; ++i) {
parseMip(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, {})
}
}
},
}
update: function (options) {
var i
// do a second pass to reconcile defaults
checkTextureComplete(params, pixels)
this.clearListeners()
if (params.needsListeners) {
hookListeners(texture)
}
// Clear parameters and pixel data
var params = this.params
var pixels = this.pixels
params.clear()
pixels.length = 0
if (params.needsPoll) {
texture.pollId = pollSet.length
pollSet.push(texture)
}
// parse parameters
params.parse(options)
refresh(texture)
}
// parse pixel data
function parseMip (target, data) {
var mipmap = data.mipmap
var pixmap
if (Array.isArray(mipmap)) {
for (var i = 0; i < mipmap.length; ++i) {
pixmap = new PixelInfo(target)
pixmap.parseFlags(options)
pixmap.parseFlags(data)
pixmap.parse(mipmap[i], i)
pixels.push(pixmap)
}
} else {
pixmap = new PixelInfo(target)
pixmap.parseFlags(options)
pixmap.parse(data, 0)
pixels.push(pixmap)
}
}
if (this.target === GL_TEXTURE_2D) {
parseMip(GL_TEXTURE_2D, options)
} else {
var faces = options.faces || options
if (Array.isArray(faces)) {
check(faces.length === 6,
'invalid number of faces in cube map')
for (i = 0; i < 6; ++i) {
parseMip(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, faces[i])
}
} else if (typeof faces === 'string') {
// TODO Read dds
} else {
// Initialize to all empty textures
for (i = 0; i < 6; ++i) {
parseMip(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, {})
}
}
}
function refresh (texture) {
if (!gl.isTexture(texture.texture)) {
texture.texture = gl.createTexture()
}
// do a second pass to reconcile defaults
checkTextureComplete(params, pixels)
// Lazy bind
var target = texture.target
var unit = texture.unit
if (unit >= 0) {
gl.activeTexture(GL_TEXTURE0 + unit)
activeTexture = unit
} else {
gl.bindTexture(target, texture.texture)
}
if (params.needsListeners) {
this.hookListeners()
}
// Upload
var pixels = texture.pixels
var params = texture.params
for (var i = 0; i < pixels.length; ++i) {
pixels[i].upload(params)
}
params.upload()
if (params.needsPoll) {
this.pollId = pollSet.length
pollSet.push(this)
// Lazy unbind
if (unit < 0) {
var active = textureUnits[activeTexture]
if (active) {
// restore binding state
gl.bindTexture(active.target, active.texture)
} else {
// otherwise become new active
texture.unit = activeTexture
textureUnits[activeTexture] = texture
}
}
}
this.refresh()
},
function hookListeners (texture) {
var params = texture.params
var pixels = texture.pixels
hookListeners: function () {
var params = this.params
var pixels = this.pixels
var texture = this
// Appends all the texture data from the buffer to the current
function appendDDS (target, miplevel, buffer) {
var dds = parseDDS(buffer)
// Appends all the texture data from the buffer to the current
function appendDDS (target, miplevel, buffer) {
var dds = parseDDS(buffer)
check(dds.format in colorFormats, 'unsupported dds texture format')
check(dds.format in colorFormats, 'unsupported dds texture format')
if (dds.cube) {
check(texture.target === GL_TEXTURE_CUBE_MAP)
if (dds.cube) {
check(texture.target === GL_TEXTURE_CUBE_MAP)
// TODO handle cube map DDS
check.raise('cube map DDS not yet implemented')
} else {
check(texture.target === GL_TEXTURE_2D)
}
// TODO handle cube map
} else {
check(texture.target === GL_TEXTURE_2D)
}
if (miplevel) {
check(dds.pixels.length === 1, 'number of mip levels inconsistent')
}
if (miplevel) {
check(dds.pixels.length === 1, 'number of mip levels inconsistent')
}
dds.pixels.forEach(function (pixmap) {
var info = new PixelInfo(dds.cube ? pixmap.target : target)
dds.pixels.forEach(function (pixmap) {
var info = new PixelInfo(dds.cube ? pixmap.target : target)
info.channels = dds.channels
info.compressed = dds.compressed
info.type = dds.type
info.internalformat = dds.format
info.format = colorFormats[dds.format]
info.channels = dds.channels
info.compressed = dds.compressed
info.type = dds.type
info.internalformat = dds.format
info.format = colorFormats[dds.format]
info.width = pixmap.width
info.height = pixmap.height
info.miplevel = pixmap.miplevel || miplevel
info.data = pixmap.data
info.width = pixmap.width
info.height = pixmap.height
info.miplevel = pixmap.miplevel || miplevel
info.data = pixmap.data
pixels.push(info)
})
}
pixels.push(info)
})
function onData () {
// Update size of any newly loaded pixels
for (var i = 0; i < pixels.length; ++i) {
var pixelData = pixels[i]
var image = pixelData.image
var video = pixelData.video
var xhr = pixelData.xhr
if (image && image.complete) {
pixelData.width = image.naturalWidth
pixelData.height = image.naturalHeight
} else if (video && video.readyState > 2) {
pixelData.width = video.width
pixelData.height = video.height
} else if (xhr && xhr.readyState === 4) {
pixels[i] = pixels[pixels.length - 1]
pixels.pop()
xhr.removeEventListener('readystatechange', refresh)
appendDDS(pixelData.target, pixelData.miplevel, xhr.response)
}
}
checkTextureComplete(params, pixels)
refresh(texture)
}
function refresh () {
// Update size of any newly loaded pixels
for (var i = 0; i < pixels.length; ++i) {
var pixelData = pixels[i]
var image = pixelData.image
var video = pixelData.video
var xhr = pixelData.xhr
if (image && image.complete) {
pixelData.width = image.naturalWidth
pixelData.height = image.naturalHeight
} else if (video && video.readyState > 2) {
pixelData.width = video.width
pixelData.height = video.height
} else if (xhr && xhr.readyState === 4) {
pixels[i] = pixels[pixels.length - 1]
pixels.pop()
xhr.removeEventListener('readystatechange', refresh)
appendDDS(pixelData.target, pixelData.miplevel, xhr.response)
}
}
checkTextureComplete(params, pixels)
texture.refresh()
pixels.forEach(function (pixelData) {
if (pixelData.image && !pixelData.image.complete) {
pixelData.image.addEventListener('load', onData)
} else if (pixelData.video && pixelData.readyState < 1) {
pixelData.video.addEventListener('progress', onData)
} else if (pixelData.xhr) {
pixelData.xhr.addEventListener('readystatechange', onData)
}
})
texture.cancelPending = function detachListeners () {
pixels.forEach(function (pixelData) {
if (pixelData.image && !pixelData.image.complete) {
pixelData.image.addEventListener('load', refresh)
} else if (pixelData.video && pixelData.readyState < 1) {
pixelData.video.addEventListener('progress', refresh)
if (pixelData.image) {
pixelData.image.removeEventListener('load', onData)
} else if (pixelData.video) {
pixelData.video.removeEventListener('progress', onData)
} else if (pixelData.xhr) {
pixelData.xhr.addEventListener('readystatechange', refresh)
pixelData.xhr.removeEventListener('readystatechange', onData)
pixelData.xhr.abort()
}
})
}
}
this.cancelPending = function detachListeners () {
pixels.forEach(function (pixelData) {
if (pixelData.image) {
pixelData.image.removeEventListener('load', refresh)
} else if (pixelData.video) {
pixelData.video.removeEventListener('progress', refresh)
function clearListeners (texture) {
var cancelPending = texture.cancelPending
if (cancelPending) {
cancelPending()
texture.cancelPending = null
}
var id = texture.pollId
if (id >= 0) {
var other = pollSet[id] = pollSet[pollSet.length - 1]
other.id = id
pollSet.pop()
texture.pollId = -1
}
}
function destroy (texture) {
var handle = texture.texture
check(handle, 'must not double destroy texture')
var unit = texture.unit
var target = texture.target
if (unit >= 0) {
gl.activeTexture(GL_TEXTURE0 + unit)
activeTexture = unit
gl.bindTexture(target, null)
textureUnits[unit] = null
}
clearListeners(texture)
if (gl.isTexture(handle)) {
gl.deleteTexture(handle)
}
texture.texture = null
texture.params = null
texture.pixels = null
texture.refCount = 0
delete textureSet[texture.id]
}
Object.assign(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.raise('insufficient number of texture units')
}
texture.unit = unit
gl.activeTexture(GL_TEXTURE0 + unit)
gl.bindTexture(texture.target, texture.texture)
activeTexture = unit
}
return unit
},
clearListeners: function () {
if (this.cancelPending) {
this.cancelPending()
this.cancelPending = null
}
var id = this.pollId
if (id >= 0) {
var other = pollSet[id] = pollSet[pollSet.length - 1]
other.id = id
pollSet.pop()
this.pollId = -1
}
unbind: function () {
this.bindCount -= 1
},
destroy: function () {
check(this.texture, 'must not double free texture')
if (this.unit >= 0) {
gl.activeTexture(GL_TEXTURE0 + this.unit)
activeTexture = this.unit
gl.bindTexture(this.target, null)
textureUnits[this.unit] = null
decRef: function () {
if (--this.refCount === 0) {
destroy(this)
}
this.clearListeners()
gl.deleteTexture(this.texture)
this.texture = null
this.params = null
this.pixels = null
delete textureSet[this.id]
}

@@ -1376,3 +1380,3 @@ })

function createTexture (options, target) {
var texture = new REGLTexture(target, gl.createTexture())
var texture = new REGLTexture(target)
textureSet[texture.id] = texture

@@ -1385,3 +1389,6 @@

}
texture.update(options)
update(texture, options)
reglTexture.width = texture.params.width
reglTexture.height = texture.params.height
return reglTexture
}

@@ -1395,3 +1402,3 @@

destroy: function () {
texture.destroy()
texture.decRef()
}

@@ -1405,5 +1412,3 @@ })

function refreshTextures () {
Object.keys(textureSet).forEach(function (texId) {
textureSet[texId].refresh()
})
values(textureSet).forEach(refresh)
for (var i = 0; i < numTexUnits; ++i) {

@@ -1425,5 +1430,3 @@ textureUnits[i] = null

activeTexture = 0
Object.keys(textureSet).forEach(function (texId) {
textureSet[texId].destroy()
})
values(textureSet).forEach(destroy)
}

@@ -1433,5 +1436,3 @@

function pollTextures () {
for (var i = 0; i < pollSet.length; ++i) {
pollSet[i].refresh()
}
pollSet.forEach(refresh)
}

@@ -1438,0 +1439,0 @@

{
"name": "regl",
"version": "0.2.0",
"version": "0.3.0",
"description": "WebGL",

@@ -17,7 +17,8 @@ "main": "regl.js",

"canvas-fit": "^1.5.0",
"canvas-orbit-camera": "^1.0.2",
"coverify": "^1.4.1",
"derequire": "^2.0.3",
"faucet": "0.0.1",
"gl": "^3.0.3",
"gl-mat4": "^1.1.4",
"google-closure-compiler": "^20160315.2.0",
"hsv2rgb": "^1.1.0",

@@ -41,4 +42,4 @@ "indexhtmlify": "^1.2.1",

"build": "npm run build-script && npm run build-min && npm run build-bench && npm run build-gallery",
"build-script": "browserify regl.js -s regl | derequire > dist/regl.js",
"build-min": "uglifyjs < dist/regl.js > dist/regl.min.js",
"build-script": "browserify regl.js --standalone reglInit > dist/regl.js",
"build-min": "node bin/build-min.js",
"build-bench": "browserify bench/index.js | indexhtmlify > www/bench.html",

@@ -45,0 +46,0 @@ "build-gallery": "node bin/build-gallery.js"

@@ -8,3 +8,4 @@ var check = require('./lib/check')

var wrapTextures = require('./lib/texture')
var wrapFBOs = require('./lib/fbo')
var wrapRenderbuffers = require('./lib/renderbuffer')
var wrapFramebuffers = require('./lib/framebuffer')
var wrapUniforms = require('./lib/uniform')

@@ -38,10 +39,30 @@ var wrapAttributes = require('./lib/attribute')

var extensionState = wrapExtensions(gl)
var limits = wrapLimits(gl, extensionState)
var extensions = extensionState.extensions
var viewportState = {
width: gl.drawingBufferWidth,
height: gl.drawingBufferHeight
}
var limits = wrapLimits(
gl,
extensions)
var bufferState = wrapBuffers(gl)
var elementState = wrapElements(gl, extensionState, bufferState)
var elementState = wrapElements(
gl,
extensions,
bufferState)
var uniformState = wrapUniforms()
var attributeState = wrapAttributes(gl, extensionState, bufferState)
var attributeState = wrapAttributes(
gl,
extensions,
limits,
bufferState)
var shaderState = wrapShaders(
gl,
extensionState,
attributeState,

@@ -52,11 +73,27 @@ uniformState,

})
var drawState = wrapDraw(gl, extensionState, bufferState)
var glState = wrapContext(gl, shaderState)
var drawState = wrapDraw(
gl,
extensions,
bufferState)
var textureState = wrapTextures(
gl,
extensionState,
extensions,
limits,
poll,
glState.viewport)
var fboState = wrapFBOs(gl, extensionState, textureState)
viewportState)
var renderbufferState = wrapRenderbuffers(
gl,
extensions,
limits)
var framebufferState = wrapFramebuffers(
gl,
extensions,
limits,
textureState,
renderbufferState)
var frameState = {

@@ -72,11 +109,18 @@ count: 0,

}
var readPixels = wrapRead(gl, glState)
var glState = wrapContext(
gl,
framebufferState,
viewportState)
var readPixels = wrapRead(gl, poll, viewportState)
var compiler = createCompiler(
gl,
extensionState,
extensions,
limits,
bufferState,
elementState,
textureState,
fboState,
framebufferState,
glState,

@@ -87,3 +131,4 @@ uniformState,

drawState,
frameState)
frameState,
poll)

@@ -145,3 +190,4 @@ var canvas = gl.canvas

textureState.refresh()
fboState.refresh()
renderbufferState.refresh()
framebufferState.refresh()
shaderState.refresh()

@@ -170,3 +216,4 @@ glState.refresh()

shaderState.clear()
fboState.clear()
framebufferState.clear()
renderbufferState.clear()
textureState.clear()

@@ -269,2 +316,3 @@ bufferState.clear()

function poll () {
framebufferState.poll()
glState.poll()

@@ -278,3 +326,3 @@ }

// Update context state
glState.poll()
poll()

@@ -286,3 +334,2 @@ var c = options.color

}
if ('depth' in options) {

@@ -292,3 +339,2 @@ gl.clearDepth(+options.depth)

}
if ('stencil' in options) {

@@ -331,6 +377,9 @@ gl.clearStencil(options.stencil | 0)

// Dynamic variable binding
// Short cut for prop binding
prop: dynamic.define,
// Object constructors
// executes an empty draw command
draw: compileProcedure({}),
// Resources
elements: function (options) {

@@ -354,3 +403,11 @@ return elementState.create(options)

},
// fbo: create(fboState),
renderbuffer: function (options) {
return renderbufferState.create(options)
},
framebuffer: function (options) {
return framebufferState.create(options)
},
framebufferCube: function (options) {
check.raise('framebuffer cube not yet implemented')
},

@@ -357,0 +414,0 @@ // Frame rendering

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc