package.lib.renderbuffer.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of regl Show documentation
Show all versions of regl Show documentation
regl is a fast functional WebGL framework.
The newest version!
var check = require('./util/check')
var values = require('./util/values')
var GL_RENDERBUFFER = 0x8D41
var GL_RGBA4 = 0x8056
var GL_RGB5_A1 = 0x8057
var GL_RGB565 = 0x8D62
var GL_DEPTH_COMPONENT16 = 0x81A5
var GL_STENCIL_INDEX8 = 0x8D48
var GL_DEPTH_STENCIL = 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] = 2
FORMAT_SIZES[GL_RGB5_A1] = 2
FORMAT_SIZES[GL_RGB565] = 2
FORMAT_SIZES[GL_DEPTH_COMPONENT16] = 2
FORMAT_SIZES[GL_STENCIL_INDEX8] = 1
FORMAT_SIZES[GL_DEPTH_STENCIL] = 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
}
module.exports = function (gl, extensions, limits, stats, config) {
var formatTypes = {
'rgba4': GL_RGBA4,
'rgb565': GL_RGB565,
'rgb5 a1': GL_RGB5_A1,
'depth': GL_DEPTH_COMPONENT16,
'stencil': GL_STENCIL_INDEX8,
'depth stencil': GL_DEPTH_STENCIL
}
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
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(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
if (typeof a === 'object' && a) {
var options = a
if ('shape' in options) {
var shape = options.shape
check(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.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.raise('invalid arguments to renderbuffer constructor')
}
// check shape
check(
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(
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(
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(
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
}
}