securityos/node_modules/regl/lib/read.js

138 lines
3.8 KiB
JavaScript

var check = require('./util/check')
var isTypedArray = require('./util/is-typed-array')
var GL_RGBA = 6408
var GL_UNSIGNED_BYTE = 5121
var GL_PACK_ALIGNMENT = 0x0D05
var GL_FLOAT = 0x1406 // 5126
module.exports = function wrapReadPixels (
gl,
framebufferState,
reglPoll,
context,
glAttributes,
extensions,
limits) {
function readPixelsImpl (input) {
var type
if (framebufferState.next === null) {
check(
glAttributes.preserveDrawingBuffer,
'you must create a webgl context with "preserveDrawingBuffer":true in order to read pixels from the drawing buffer')
type = GL_UNSIGNED_BYTE
} else {
check(
framebufferState.next.colorAttachments[0].texture !== null,
'You cannot read from a renderbuffer')
type = framebufferState.next.colorAttachments[0].texture._texture.type
check.optional(function () {
if (extensions.oes_texture_float) {
check(
type === GL_UNSIGNED_BYTE || type === GL_FLOAT,
'Reading from a framebuffer is only allowed for the types \'uint8\' and \'float\'')
if (type === GL_FLOAT) {
check(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(
type === GL_UNSIGNED_BYTE,
'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.type(input, 'object', 'invalid arguments to regl.read()')
x = input.x | 0
y = input.y | 0
check(
x >= 0 && x < context.framebufferWidth,
'invalid x offset for regl.read')
check(
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) {
check(
data instanceof Uint8Array,
'buffer must be \'Uint8Array\' when reading from a framebuffer of type \'uint8\'')
} else if (type === GL_FLOAT) {
check(
data instanceof Float32Array,
'buffer must be \'Float32Array\' when reading from a framebuffer of type \'float\'')
}
}
check(
width > 0 && width + x <= context.framebufferWidth,
'invalid width for read pixels')
check(
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) {
data = new Uint8Array(size)
} else if (type === GL_FLOAT) {
data = data || new Float32Array(size)
}
}
// Type check
check.isTypedArray(data, 'data buffer for regl.read() must be a typedarray')
check(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,
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
}