mirror of
https://github.com/pyalot/webgl-heatmap.git
synced 2025-12-08 20:13:00 +00:00
modified to work on android
This commit is contained in:
parent
bb59d4110c
commit
8874855b42
@ -16,8 +16,6 @@
|
|||||||
document.body.appendChild(heatmap.canvas);
|
document.body.appendChild(heatmap.canvas);
|
||||||
|
|
||||||
var paintAtCoord = function(x, y){
|
var paintAtCoord = function(x, y){
|
||||||
//heatmap.addPoint(x, y, 100, 10/255);
|
|
||||||
|
|
||||||
var count = 0;
|
var count = 0;
|
||||||
while(count < 200){
|
while(count < 200){
|
||||||
var xoff = Math.random()*2-1;
|
var xoff = Math.random()*2-1;
|
||||||
@ -30,7 +28,7 @@
|
|||||||
xoff/=ls; yoff/=ls;
|
xoff/=ls; yoff/=ls;
|
||||||
xoff*=1-l; yoff*=1-l;
|
xoff*=1-l; yoff*=1-l;
|
||||||
count += 1;
|
count += 1;
|
||||||
heatmap.addPoint(x+xoff*50, y+yoff*50, 20, 1/300);
|
heatmap.addPoint(x+xoff*50, y+yoff*50, 30, 2/300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,459 @@
|
|||||||
|
nukeVendorPrefix = ->
|
||||||
|
if window.WebGLRenderingContext?
|
||||||
|
vendors = ['WEBKIT', 'MOZ', 'MS', 'O']
|
||||||
|
vendorRe = /^WEBKIT_(.*)|MOZ_(.*)|MS_(.*)|O_(.*)/
|
||||||
|
|
||||||
|
getExtension = WebGLRenderingContext.prototype.getExtension
|
||||||
|
WebGLRenderingContext.prototype.getExtension = (name) ->
|
||||||
|
match = name.match vendorRe
|
||||||
|
if match != null
|
||||||
|
name = match[1]
|
||||||
|
|
||||||
|
extobj = getExtension.call @, name
|
||||||
|
if extobj == null
|
||||||
|
for vendor in vendors
|
||||||
|
extobj = getExtension.call @, vendor + '_' + name
|
||||||
|
if extobj != null
|
||||||
|
return extobj
|
||||||
|
return null
|
||||||
|
else
|
||||||
|
return extobj
|
||||||
|
|
||||||
|
getSupportedExtensions = WebGLRenderingContext.prototype.getSupportedExtensions
|
||||||
|
WebGLRenderingContext.prototype.getSupportedExtensions = ->
|
||||||
|
supported = getSupportedExtensions.call @
|
||||||
|
result = []
|
||||||
|
|
||||||
|
for extension in supported
|
||||||
|
match = extension.match vendorRe
|
||||||
|
if match != null
|
||||||
|
extension = match[1]
|
||||||
|
|
||||||
|
if extension not in result
|
||||||
|
result.push extension
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
textureFloatShims = ->
|
||||||
|
createSourceCanvas = ->
|
||||||
|
canvas = document.createElement 'canvas'
|
||||||
|
canvas.width = 2
|
||||||
|
canvas.height = 2
|
||||||
|
ctx = canvas.getContext '2d'
|
||||||
|
imageData = ctx.getImageData(0, 0, 2, 2)
|
||||||
|
imageData.data.set(new Uint8ClampedArray([
|
||||||
|
0,0,0,0,
|
||||||
|
255,255,255,255,
|
||||||
|
0,0,0,0,
|
||||||
|
255,255,255,255,
|
||||||
|
]))
|
||||||
|
ctx.putImageData(imageData, 0, 0)
|
||||||
|
return canvas
|
||||||
|
|
||||||
|
createSourceCanvas()
|
||||||
|
|
||||||
|
checkFloatLinear = (gl, sourceType) ->
|
||||||
|
## drawing program ##
|
||||||
|
program = gl.createProgram()
|
||||||
|
vertexShader = gl.createShader(gl.VERTEX_SHADER)
|
||||||
|
gl.attachShader(program, vertexShader)
|
||||||
|
gl.shaderSource(vertexShader, '''
|
||||||
|
attribute vec2 position;
|
||||||
|
void main(){
|
||||||
|
gl_Position = vec4(position, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
''')
|
||||||
|
|
||||||
|
gl.compileShader(vertexShader)
|
||||||
|
if not gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)
|
||||||
|
throw gl.getShaderInfoLog(vertexShader)
|
||||||
|
|
||||||
|
fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
|
||||||
|
gl.attachShader(program, fragmentShader)
|
||||||
|
gl.shaderSource(fragmentShader, '''
|
||||||
|
uniform sampler2D source;
|
||||||
|
void main(){
|
||||||
|
gl_FragColor = texture2D(source, vec2(1.0, 1.0));
|
||||||
|
}
|
||||||
|
''')
|
||||||
|
gl.compileShader(fragmentShader)
|
||||||
|
if not gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)
|
||||||
|
throw gl.getShaderInfoLog(fragmentShader)
|
||||||
|
|
||||||
|
gl.linkProgram(program)
|
||||||
|
if not gl.getProgramParameter(program, gl.LINK_STATUS)
|
||||||
|
throw gl.getProgramInfoLog(program)
|
||||||
|
|
||||||
|
gl.useProgram(program)
|
||||||
|
|
||||||
|
cleanup = ->
|
||||||
|
gl.deleteShader(fragmentShader)
|
||||||
|
gl.deleteShader(vertexShader)
|
||||||
|
gl.deleteProgram(program)
|
||||||
|
gl.deleteBuffer(buffer)
|
||||||
|
gl.deleteTexture(source)
|
||||||
|
gl.deleteTexture(target)
|
||||||
|
gl.deleteFramebuffer(framebuffer)
|
||||||
|
|
||||||
|
gl.bindBuffer(gl.ARRAY_BUFFER, null)
|
||||||
|
gl.useProgram(null)
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, null)
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null)
|
||||||
|
|
||||||
|
## target FBO ##
|
||||||
|
target = gl.createTexture()
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, target)
|
||||||
|
gl.texImage2D(
|
||||||
|
gl.TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
2, 2,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
gl.UNSIGNED_BYTE,
|
||||||
|
null,
|
||||||
|
)
|
||||||
|
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
|
||||||
|
|
||||||
|
framebuffer = gl.createFramebuffer()
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)
|
||||||
|
gl.framebufferTexture2D(
|
||||||
|
gl.FRAMEBUFFER,
|
||||||
|
gl.COLOR_ATTACHMENT0,
|
||||||
|
gl.TEXTURE_2D,
|
||||||
|
target,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
|
||||||
|
## source texture ##
|
||||||
|
sourceCanvas = createSourceCanvas()
|
||||||
|
source = gl.createTexture()
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, source)
|
||||||
|
gl.texImage2D(
|
||||||
|
gl.TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
gl.RGBA,
|
||||||
|
sourceType,
|
||||||
|
sourceCanvas,
|
||||||
|
)
|
||||||
|
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
|
||||||
|
|
||||||
|
## create VBO ##
|
||||||
|
vertices = new Float32Array([
|
||||||
|
1, 1,
|
||||||
|
-1, 1,
|
||||||
|
-1, -1,
|
||||||
|
|
||||||
|
1, 1,
|
||||||
|
-1, -1,
|
||||||
|
1, -1,
|
||||||
|
])
|
||||||
|
buffer = gl.createBuffer()
|
||||||
|
gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
|
||||||
|
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)
|
||||||
|
positionLoc = gl.getAttribLocation(program, 'position')
|
||||||
|
sourceLoc = gl.getUniformLocation(program, 'source')
|
||||||
|
gl.enableVertexAttribArray(positionLoc)
|
||||||
|
gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0)
|
||||||
|
gl.uniform1i(sourceLoc, 0)
|
||||||
|
gl.drawArrays(gl.TRIANGLES, 0, 6)
|
||||||
|
|
||||||
|
readBuffer = new Uint8Array(4*4)
|
||||||
|
gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, readBuffer)
|
||||||
|
|
||||||
|
result = Math.abs(readBuffer[0] - 127) < 10
|
||||||
|
|
||||||
|
cleanup()
|
||||||
|
return result
|
||||||
|
|
||||||
|
checkTexture = (gl, targetType) ->
|
||||||
|
target = gl.createTexture()
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, target)
|
||||||
|
gl.texImage2D(
|
||||||
|
gl.TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
2, 2,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
targetType,
|
||||||
|
null,
|
||||||
|
)
|
||||||
|
|
||||||
|
if gl.getError() == 0
|
||||||
|
gl.deleteTexture(target)
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
gl.deleteTexture(target)
|
||||||
|
return false
|
||||||
|
|
||||||
|
checkColorBuffer = (gl, targetType) ->
|
||||||
|
target = gl.createTexture()
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, target)
|
||||||
|
gl.texImage2D(
|
||||||
|
gl.TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
2, 2,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
targetType,
|
||||||
|
null,
|
||||||
|
)
|
||||||
|
|
||||||
|
framebuffer = gl.createFramebuffer()
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)
|
||||||
|
gl.framebufferTexture2D(
|
||||||
|
gl.FRAMEBUFFER,
|
||||||
|
gl.COLOR_ATTACHMENT0,
|
||||||
|
gl.TEXTURE_2D,
|
||||||
|
target,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
|
||||||
|
check = gl.checkFramebufferStatus(gl.FRAMEBUFFER)
|
||||||
|
|
||||||
|
gl.deleteTexture(target)
|
||||||
|
gl.deleteFramebuffer(framebuffer)
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, null)
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null)
|
||||||
|
|
||||||
|
if check == gl.FRAMEBUFFER_COMPLETE
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
|
||||||
|
shimExtensions = []
|
||||||
|
shimLookup = {}
|
||||||
|
unshimExtensions = []
|
||||||
|
|
||||||
|
checkSupport = ->
|
||||||
|
canvas = document.createElement 'canvas'
|
||||||
|
gl = null
|
||||||
|
try
|
||||||
|
gl = canvas.getContext 'experimental-webgl'
|
||||||
|
if(gl == null)
|
||||||
|
gl = canvas.getContext 'webgl'
|
||||||
|
|
||||||
|
if gl?
|
||||||
|
singleFloatExt = gl.getExtension 'OES_texture_float'
|
||||||
|
if singleFloatExt == null
|
||||||
|
if checkTexture gl, gl.FLOAT
|
||||||
|
singleFloatTexturing = true
|
||||||
|
shimExtensions.push 'OES_texture_float'
|
||||||
|
shimLookup.OES_texture_float = {shim:true}
|
||||||
|
else
|
||||||
|
singleFloatTexturing = false
|
||||||
|
unshimExtensions.push 'OES_texture_float'
|
||||||
|
else
|
||||||
|
if checkTexture gl, gl.FLOAT
|
||||||
|
singleFloatTexturing = true
|
||||||
|
shimExtensions.push 'OES_texture_float'
|
||||||
|
else
|
||||||
|
singleFloatTexturing = false
|
||||||
|
unshimExtensions.push 'OES_texture_float'
|
||||||
|
|
||||||
|
if singleFloatTexturing
|
||||||
|
extobj = gl.getExtension 'WEBGL_color_buffer_float'
|
||||||
|
if extobj == null
|
||||||
|
if checkColorBuffer gl, gl.FLOAT
|
||||||
|
shimExtensions.push 'WEBGL_color_buffer_float'
|
||||||
|
shimLookup.WEBGL_color_buffer_float = {
|
||||||
|
shim: true
|
||||||
|
RGBA32F_EXT: 0x8814
|
||||||
|
RGB32F_EXT: 0x8815
|
||||||
|
FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: 0x8211
|
||||||
|
UNSIGNED_NORMALIZED_EXT: 0x8C17
|
||||||
|
}
|
||||||
|
else
|
||||||
|
unshimExtensions.push 'WEBGL_color_buffer_float'
|
||||||
|
else
|
||||||
|
if checkColorBuffer gl, gl.FLOAT
|
||||||
|
shimExtensions.push 'WEBGL_color_buffer_float'
|
||||||
|
else
|
||||||
|
unshimExtensions.push 'WEBGL_color_buffer_float'
|
||||||
|
|
||||||
|
extobj = gl.getExtension 'OES_texture_float_linear'
|
||||||
|
if extobj == null
|
||||||
|
if checkFloatLinear gl, gl.FLOAT
|
||||||
|
shimExtensions.push 'OES_texture_float_linear'
|
||||||
|
shimLookup.OES_texture_float_linear = {shim:true}
|
||||||
|
else
|
||||||
|
unshimExtensions.push 'OES_texture_float_linear'
|
||||||
|
else
|
||||||
|
if checkFloatLinear gl, gl.FLOAT
|
||||||
|
shimExtensions.push 'OES_texture_float_linear'
|
||||||
|
else
|
||||||
|
unshimExtensions.push 'OES_texture_float_linear'
|
||||||
|
|
||||||
|
halfFloatExt = gl.getExtension 'OES_texture_half_float'
|
||||||
|
if halfFloatExt == null
|
||||||
|
if checkTexture(gl, 0x8D61)
|
||||||
|
halfFloatTexturing = true
|
||||||
|
shimExtensions.push 'OES_texture_half_float'
|
||||||
|
halfFloatExt = shimLookup.OES_texture_half_float = {
|
||||||
|
HALF_FLOAT_OES: 0x8D61
|
||||||
|
shim:true
|
||||||
|
}
|
||||||
|
else
|
||||||
|
halfFloatTexturing = false
|
||||||
|
unshimExtensions.push 'OES_texture_half_float'
|
||||||
|
else
|
||||||
|
if checkTexture(gl, halfFloatExt.HALF_FLOAT_OES)
|
||||||
|
halfFloatTexturing = true
|
||||||
|
shimExtensions.push 'OES_texture_half_float'
|
||||||
|
else
|
||||||
|
halfFloatTexturing = false
|
||||||
|
unshimExtensions.push 'OES_texture_half_float'
|
||||||
|
|
||||||
|
if halfFloatTexturing
|
||||||
|
extobj = gl.getExtension 'EXT_color_buffer_half_float'
|
||||||
|
if extobj == null
|
||||||
|
if checkColorBuffer gl, halfFloatExt.HALF_FLOAT_OES
|
||||||
|
shimExtensions.push 'EXT_color_buffer_half_float'
|
||||||
|
shimLookup.EXT_color_buffer_half_float = {
|
||||||
|
shim: true
|
||||||
|
RGBA16F_EXT: 0x881A
|
||||||
|
RGB16F_EXT: 0x881B
|
||||||
|
FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: 0x8211
|
||||||
|
UNSIGNED_NORMALIZED_EXT: 0x8C17
|
||||||
|
}
|
||||||
|
else
|
||||||
|
unshimExtensions.push 'EXT_color_buffer_half_float'
|
||||||
|
else
|
||||||
|
if checkColorBuffer gl, halfFloatExt.HALF_FLOAT_OES
|
||||||
|
shimExtensions.push 'EXT_color_buffer_half_float'
|
||||||
|
else
|
||||||
|
unshimExtensions.push 'EXT_color_buffer_half_float'
|
||||||
|
|
||||||
|
extobj = gl.getExtension 'OES_texture_half_float_linear'
|
||||||
|
if extobj == null
|
||||||
|
if checkFloatLinear gl, halfFloatExt.HALF_FLOAT_OES
|
||||||
|
shimExtensions.push 'OES_texture_half_float_linear'
|
||||||
|
shimLookup.OES_texture_half_float_linear = {shim:true}
|
||||||
|
else
|
||||||
|
unshimExtensions.push 'OES_texture_half_float_linear'
|
||||||
|
else
|
||||||
|
if checkFloatLinear gl, halfFloatExt.HALF_FLOAT_OES
|
||||||
|
shimExtensions.push 'OES_texture_half_float_linear'
|
||||||
|
else
|
||||||
|
unshimExtensions.push 'OES_texture_half_float_linear'
|
||||||
|
|
||||||
|
if window.WebGLRenderingContext?
|
||||||
|
checkSupport()
|
||||||
|
|
||||||
|
unshimLookup = {}
|
||||||
|
for name in unshimExtensions
|
||||||
|
unshimLookup[name] = true
|
||||||
|
|
||||||
|
getExtension = WebGLRenderingContext.prototype.getExtension
|
||||||
|
WebGLRenderingContext.prototype.getExtension = (name) ->
|
||||||
|
extobj = shimLookup[name]
|
||||||
|
if extobj == undefined
|
||||||
|
if unshimLookup[name]
|
||||||
|
return null
|
||||||
|
else
|
||||||
|
return getExtension.call @, name
|
||||||
|
else
|
||||||
|
return extobj
|
||||||
|
|
||||||
|
getSupportedExtensions = WebGLRenderingContext.prototype.getSupportedExtensions
|
||||||
|
WebGLRenderingContext.prototype.getSupportedExtensions = ->
|
||||||
|
supported = getSupportedExtensions.call(@)
|
||||||
|
result = []
|
||||||
|
|
||||||
|
for extension in supported
|
||||||
|
if unshimLookup[extension] == undefined
|
||||||
|
result.push(extension)
|
||||||
|
|
||||||
|
for extension in shimExtensions
|
||||||
|
if extension not in result
|
||||||
|
result.push extension
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
WebGLRenderingContext.prototype.getFloatExtension = (spec) ->
|
||||||
|
spec.prefer ?= ['half']
|
||||||
|
spec.require ?= []
|
||||||
|
spec.throws ?= true
|
||||||
|
|
||||||
|
singleTexture = @getExtension 'OES_texture_float'
|
||||||
|
halfTexture = @getExtension 'OES_texture_half_float'
|
||||||
|
singleFramebuffer = @getExtension 'WEBGL_color_buffer_float'
|
||||||
|
halfFramebuffer = @getExtension 'EXT_color_buffer_half_float'
|
||||||
|
singleLinear = @getExtension 'OES_texture_float_linear'
|
||||||
|
halfLinear = @getExtension 'OES_texture_half_float_linear'
|
||||||
|
|
||||||
|
single = {
|
||||||
|
texture: singleTexture != null
|
||||||
|
filterable: singleLinear != null
|
||||||
|
renderable: singleFramebuffer != null
|
||||||
|
score: 0
|
||||||
|
precision: 'single'
|
||||||
|
half: false
|
||||||
|
single: true
|
||||||
|
type: @FLOAT
|
||||||
|
}
|
||||||
|
|
||||||
|
half = {
|
||||||
|
texture: halfTexture != null
|
||||||
|
filterable: halfLinear != null
|
||||||
|
renderable: halfFramebuffer != null
|
||||||
|
score: 0
|
||||||
|
precision: 'half'
|
||||||
|
half: true
|
||||||
|
single: false
|
||||||
|
type: halfTexture?.HALF_FLOAT_OES ? null
|
||||||
|
}
|
||||||
|
|
||||||
|
candidates = []
|
||||||
|
if single.texture
|
||||||
|
candidates.push(single)
|
||||||
|
if half.texture
|
||||||
|
candidates.push(half)
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for candidate in candidates
|
||||||
|
use = true
|
||||||
|
for name in spec.require
|
||||||
|
if candidate[name] == false
|
||||||
|
use = false
|
||||||
|
if use
|
||||||
|
result.push candidate
|
||||||
|
|
||||||
|
for candidate in result
|
||||||
|
for preference, i in spec.prefer
|
||||||
|
importance = Math.pow 2, spec.prefer.length - i - 1
|
||||||
|
if candidate[preference]
|
||||||
|
candidate.score += importance
|
||||||
|
|
||||||
|
result.sort (a, b) ->
|
||||||
|
if a.score == b.score then 0
|
||||||
|
else if a.score < b.score then 1
|
||||||
|
else if a.score > b.score then -1
|
||||||
|
|
||||||
|
if result.length == 0
|
||||||
|
if throws
|
||||||
|
throw 'No floating point texture support that is ' + spec.require.join(', ')
|
||||||
|
else
|
||||||
|
return null
|
||||||
|
else
|
||||||
|
result = result[0]
|
||||||
|
return {
|
||||||
|
filterable: result.filterable
|
||||||
|
renderable: result.renderable
|
||||||
|
type: result.type
|
||||||
|
precision: result.precision
|
||||||
|
}
|
||||||
|
|
||||||
|
nukeVendorPrefix()
|
||||||
|
textureFloatShims()
|
||||||
|
|
||||||
class Shader
|
class Shader
|
||||||
constructor: (@gl, {vertex, fragment}) ->
|
constructor: (@gl, {vertex, fragment}) ->
|
||||||
@program = @gl.createProgram()
|
@program = @gl.createProgram()
|
||||||
@ -106,8 +562,12 @@ class Framebuffer
|
|||||||
|
|
||||||
class Texture
|
class Texture
|
||||||
constructor: (@gl, params={}) ->
|
constructor: (@gl, params={}) ->
|
||||||
@channels = @gl[(params.channels ? 'rgb').toUpperCase()]
|
@channels = @gl[(params.channels ? 'rgba').toUpperCase()]
|
||||||
@type = @gl[(params.type ? 'unsigned_byte').toUpperCase()]
|
|
||||||
|
if typeof(params.type) == 'number'
|
||||||
|
@type = params.type
|
||||||
|
else
|
||||||
|
@type = @gl[(params.type ? 'unsigned_byte').toUpperCase()]
|
||||||
|
|
||||||
switch @channels
|
switch @channels
|
||||||
when @gl.RGBA then @chancount = 4
|
when @gl.RGBA then @chancount = 4
|
||||||
@ -163,11 +623,9 @@ class Texture
|
|||||||
|
|
||||||
class Node
|
class Node
|
||||||
constructor: (@gl, @width, @height) ->
|
constructor: (@gl, @width, @height) ->
|
||||||
@texture = new Texture(@gl, type:'float').bind(0).setSize(@width, @height).nearest().clampToEdge()
|
floatExt = @gl.getFloatExtension require: ['renderable']
|
||||||
try
|
@texture = new Texture(@gl, type:floatExt.type).bind(0).setSize(@width, @height).nearest().clampToEdge()
|
||||||
@fbo = new Framebuffer(@gl).bind().color(@texture).unbind()
|
@fbo = new Framebuffer(@gl).bind().color(@texture).unbind()
|
||||||
catch error
|
|
||||||
throw 'Floating point render target not supported'
|
|
||||||
|
|
||||||
use: -> @fbo.bind()
|
use: -> @fbo.bind()
|
||||||
bind: (unit) -> @texture.bind(unit)
|
bind: (unit) -> @texture.bind(unit)
|
||||||
@ -395,9 +853,6 @@ class WebGLHeatmap
|
|||||||
@gl = WebGLDebugUtils.makeDebugContext @gl, (err, funcName, args) ->
|
@gl = WebGLDebugUtils.makeDebugContext @gl, (err, funcName, args) ->
|
||||||
throw WebGLDebugUtils.glEnumToString(err) + " was caused by call to: " + funcName
|
throw WebGLDebugUtils.glEnumToString(err) + " was caused by call to: " + funcName
|
||||||
|
|
||||||
if not @gl.getExtension('OES_texture_float')
|
|
||||||
throw 'No floating point texture support'
|
|
||||||
|
|
||||||
@gl.enableVertexAttribArray 0
|
@gl.enableVertexAttribArray 0
|
||||||
@gl.blendFunc @gl.ONE, @gl.ONE
|
@gl.blendFunc @gl.ONE, @gl.ONE
|
||||||
|
|
||||||
|
|||||||
464
webgl-heatmap.js
464
webgl-heatmap.js
@ -1,6 +1,445 @@
|
|||||||
// Generated by CoffeeScript 1.3.3
|
// Generated by CoffeeScript 1.3.3
|
||||||
(function() {
|
(function() {
|
||||||
var Framebuffer, Heights, Node, Shader, Texture, WebGLHeatmap, fragmentShaderBlit, vertexShaderBlit;
|
var Framebuffer, Heights, Node, Shader, Texture, WebGLHeatmap, fragmentShaderBlit, nukeVendorPrefix, textureFloatShims, vertexShaderBlit,
|
||||||
|
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||||
|
|
||||||
|
nukeVendorPrefix = function() {
|
||||||
|
var getExtension, getSupportedExtensions, vendorRe, vendors;
|
||||||
|
if (window.WebGLRenderingContext != null) {
|
||||||
|
vendors = ['WEBKIT', 'MOZ', 'MS', 'O'];
|
||||||
|
vendorRe = /^WEBKIT_(.*)|MOZ_(.*)|MS_(.*)|O_(.*)/;
|
||||||
|
getExtension = WebGLRenderingContext.prototype.getExtension;
|
||||||
|
WebGLRenderingContext.prototype.getExtension = function(name) {
|
||||||
|
var extobj, match, vendor, _i, _len;
|
||||||
|
match = name.match(vendorRe);
|
||||||
|
if (match !== null) {
|
||||||
|
name = match[1];
|
||||||
|
}
|
||||||
|
extobj = getExtension.call(this, name);
|
||||||
|
if (extobj === null) {
|
||||||
|
for (_i = 0, _len = vendors.length; _i < _len; _i++) {
|
||||||
|
vendor = vendors[_i];
|
||||||
|
extobj = getExtension.call(this, vendor + '_' + name);
|
||||||
|
if (extobj !== null) {
|
||||||
|
return extobj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return extobj;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
getSupportedExtensions = WebGLRenderingContext.prototype.getSupportedExtensions;
|
||||||
|
return WebGLRenderingContext.prototype.getSupportedExtensions = function() {
|
||||||
|
var extension, match, result, supported, _i, _len;
|
||||||
|
supported = getSupportedExtensions.call(this);
|
||||||
|
result = [];
|
||||||
|
for (_i = 0, _len = supported.length; _i < _len; _i++) {
|
||||||
|
extension = supported[_i];
|
||||||
|
match = extension.match(vendorRe);
|
||||||
|
if (match !== null) {
|
||||||
|
extension = match[1];
|
||||||
|
}
|
||||||
|
if (__indexOf.call(result, extension) < 0) {
|
||||||
|
result.push(extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
textureFloatShims = function() {
|
||||||
|
var checkColorBuffer, checkFloatLinear, checkSupport, checkTexture, createSourceCanvas, getExtension, getSupportedExtensions, name, shimExtensions, shimLookup, unshimExtensions, unshimLookup, _i, _len;
|
||||||
|
createSourceCanvas = function() {
|
||||||
|
var canvas, ctx, imageData;
|
||||||
|
canvas = document.createElement('canvas');
|
||||||
|
canvas.width = 2;
|
||||||
|
canvas.height = 2;
|
||||||
|
ctx = canvas.getContext('2d');
|
||||||
|
imageData = ctx.getImageData(0, 0, 2, 2);
|
||||||
|
imageData.data.set(new Uint8ClampedArray([0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255]));
|
||||||
|
ctx.putImageData(imageData, 0, 0);
|
||||||
|
return canvas;
|
||||||
|
};
|
||||||
|
createSourceCanvas();
|
||||||
|
checkFloatLinear = function(gl, sourceType) {
|
||||||
|
var buffer, cleanup, fragmentShader, framebuffer, positionLoc, program, readBuffer, result, source, sourceCanvas, sourceLoc, target, vertexShader, vertices;
|
||||||
|
program = gl.createProgram();
|
||||||
|
vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
||||||
|
gl.attachShader(program, vertexShader);
|
||||||
|
gl.shaderSource(vertexShader, 'attribute vec2 position;\nvoid main(){\n gl_Position = vec4(position, 0.0, 1.0);\n}');
|
||||||
|
gl.compileShader(vertexShader);
|
||||||
|
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
|
||||||
|
throw gl.getShaderInfoLog(vertexShader);
|
||||||
|
}
|
||||||
|
fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
||||||
|
gl.attachShader(program, fragmentShader);
|
||||||
|
gl.shaderSource(fragmentShader, 'uniform sampler2D source;\nvoid main(){\n gl_FragColor = texture2D(source, vec2(1.0, 1.0));\n}');
|
||||||
|
gl.compileShader(fragmentShader);
|
||||||
|
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
|
||||||
|
throw gl.getShaderInfoLog(fragmentShader);
|
||||||
|
}
|
||||||
|
gl.linkProgram(program);
|
||||||
|
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
||||||
|
throw gl.getProgramInfoLog(program);
|
||||||
|
}
|
||||||
|
gl.useProgram(program);
|
||||||
|
cleanup = function() {
|
||||||
|
gl.deleteShader(fragmentShader);
|
||||||
|
gl.deleteShader(vertexShader);
|
||||||
|
gl.deleteProgram(program);
|
||||||
|
gl.deleteBuffer(buffer);
|
||||||
|
gl.deleteTexture(source);
|
||||||
|
gl.deleteTexture(target);
|
||||||
|
gl.deleteFramebuffer(framebuffer);
|
||||||
|
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||||
|
gl.useProgram(null);
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||||
|
return gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||||
|
};
|
||||||
|
target = gl.createTexture();
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, target);
|
||||||
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||||
|
framebuffer = gl.createFramebuffer();
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||||
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target, 0);
|
||||||
|
sourceCanvas = createSourceCanvas();
|
||||||
|
source = gl.createTexture();
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, source);
|
||||||
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, sourceType, sourceCanvas);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||||
|
vertices = new Float32Array([1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1]);
|
||||||
|
buffer = gl.createBuffer();
|
||||||
|
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||||
|
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
||||||
|
positionLoc = gl.getAttribLocation(program, 'position');
|
||||||
|
sourceLoc = gl.getUniformLocation(program, 'source');
|
||||||
|
gl.enableVertexAttribArray(positionLoc);
|
||||||
|
gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
|
||||||
|
gl.uniform1i(sourceLoc, 0);
|
||||||
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||||
|
readBuffer = new Uint8Array(4 * 4);
|
||||||
|
gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, readBuffer);
|
||||||
|
result = Math.abs(readBuffer[0] - 127) < 10;
|
||||||
|
cleanup();
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
checkTexture = function(gl, targetType) {
|
||||||
|
var target;
|
||||||
|
target = gl.createTexture();
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, target);
|
||||||
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, targetType, null);
|
||||||
|
if (gl.getError() === 0) {
|
||||||
|
gl.deleteTexture(target);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
gl.deleteTexture(target);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
checkColorBuffer = function(gl, targetType) {
|
||||||
|
var check, framebuffer, target;
|
||||||
|
target = gl.createTexture();
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, target);
|
||||||
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, targetType, null);
|
||||||
|
framebuffer = gl.createFramebuffer();
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||||
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target, 0);
|
||||||
|
check = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
||||||
|
gl.deleteTexture(target);
|
||||||
|
gl.deleteFramebuffer(framebuffer);
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||||
|
if (check === gl.FRAMEBUFFER_COMPLETE) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
shimExtensions = [];
|
||||||
|
shimLookup = {};
|
||||||
|
unshimExtensions = [];
|
||||||
|
checkSupport = function() {
|
||||||
|
var canvas, extobj, gl, halfFloatExt, halfFloatTexturing, singleFloatExt, singleFloatTexturing;
|
||||||
|
canvas = document.createElement('canvas');
|
||||||
|
gl = null;
|
||||||
|
try {
|
||||||
|
gl = canvas.getContext('experimental-webgl');
|
||||||
|
if (gl === null) {
|
||||||
|
gl = canvas.getContext('webgl');
|
||||||
|
}
|
||||||
|
} catch (_error) {}
|
||||||
|
if (gl != null) {
|
||||||
|
singleFloatExt = gl.getExtension('OES_texture_float');
|
||||||
|
if (singleFloatExt === null) {
|
||||||
|
if (checkTexture(gl, gl.FLOAT)) {
|
||||||
|
singleFloatTexturing = true;
|
||||||
|
shimExtensions.push('OES_texture_float');
|
||||||
|
shimLookup.OES_texture_float = {
|
||||||
|
shim: true
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
singleFloatTexturing = false;
|
||||||
|
unshimExtensions.push('OES_texture_float');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (checkTexture(gl, gl.FLOAT)) {
|
||||||
|
singleFloatTexturing = true;
|
||||||
|
shimExtensions.push('OES_texture_float');
|
||||||
|
} else {
|
||||||
|
singleFloatTexturing = false;
|
||||||
|
unshimExtensions.push('OES_texture_float');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (singleFloatTexturing) {
|
||||||
|
extobj = gl.getExtension('WEBGL_color_buffer_float');
|
||||||
|
if (extobj === null) {
|
||||||
|
if (checkColorBuffer(gl, gl.FLOAT)) {
|
||||||
|
shimExtensions.push('WEBGL_color_buffer_float');
|
||||||
|
shimLookup.WEBGL_color_buffer_float = {
|
||||||
|
shim: true,
|
||||||
|
RGBA32F_EXT: 0x8814,
|
||||||
|
RGB32F_EXT: 0x8815,
|
||||||
|
FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: 0x8211,
|
||||||
|
UNSIGNED_NORMALIZED_EXT: 0x8C17
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
unshimExtensions.push('WEBGL_color_buffer_float');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (checkColorBuffer(gl, gl.FLOAT)) {
|
||||||
|
shimExtensions.push('WEBGL_color_buffer_float');
|
||||||
|
} else {
|
||||||
|
unshimExtensions.push('WEBGL_color_buffer_float');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extobj = gl.getExtension('OES_texture_float_linear');
|
||||||
|
if (extobj === null) {
|
||||||
|
if (checkFloatLinear(gl, gl.FLOAT)) {
|
||||||
|
shimExtensions.push('OES_texture_float_linear');
|
||||||
|
shimLookup.OES_texture_float_linear = {
|
||||||
|
shim: true
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
unshimExtensions.push('OES_texture_float_linear');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (checkFloatLinear(gl, gl.FLOAT)) {
|
||||||
|
shimExtensions.push('OES_texture_float_linear');
|
||||||
|
} else {
|
||||||
|
unshimExtensions.push('OES_texture_float_linear');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
halfFloatExt = gl.getExtension('OES_texture_half_float');
|
||||||
|
if (halfFloatExt === null) {
|
||||||
|
if (checkTexture(gl, 0x8D61)) {
|
||||||
|
halfFloatTexturing = true;
|
||||||
|
shimExtensions.push('OES_texture_half_float');
|
||||||
|
halfFloatExt = shimLookup.OES_texture_half_float = {
|
||||||
|
HALF_FLOAT_OES: 0x8D61,
|
||||||
|
shim: true
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
halfFloatTexturing = false;
|
||||||
|
unshimExtensions.push('OES_texture_half_float');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (checkTexture(gl, halfFloatExt.HALF_FLOAT_OES)) {
|
||||||
|
halfFloatTexturing = true;
|
||||||
|
shimExtensions.push('OES_texture_half_float');
|
||||||
|
} else {
|
||||||
|
halfFloatTexturing = false;
|
||||||
|
unshimExtensions.push('OES_texture_half_float');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (halfFloatTexturing) {
|
||||||
|
extobj = gl.getExtension('EXT_color_buffer_half_float');
|
||||||
|
if (extobj === null) {
|
||||||
|
if (checkColorBuffer(gl, halfFloatExt.HALF_FLOAT_OES)) {
|
||||||
|
shimExtensions.push('EXT_color_buffer_half_float');
|
||||||
|
shimLookup.EXT_color_buffer_half_float = {
|
||||||
|
shim: true,
|
||||||
|
RGBA16F_EXT: 0x881A,
|
||||||
|
RGB16F_EXT: 0x881B,
|
||||||
|
FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: 0x8211,
|
||||||
|
UNSIGNED_NORMALIZED_EXT: 0x8C17
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
unshimExtensions.push('EXT_color_buffer_half_float');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (checkColorBuffer(gl, halfFloatExt.HALF_FLOAT_OES)) {
|
||||||
|
shimExtensions.push('EXT_color_buffer_half_float');
|
||||||
|
} else {
|
||||||
|
unshimExtensions.push('EXT_color_buffer_half_float');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extobj = gl.getExtension('OES_texture_half_float_linear');
|
||||||
|
if (extobj === null) {
|
||||||
|
if (checkFloatLinear(gl, halfFloatExt.HALF_FLOAT_OES)) {
|
||||||
|
shimExtensions.push('OES_texture_half_float_linear');
|
||||||
|
return shimLookup.OES_texture_half_float_linear = {
|
||||||
|
shim: true
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return unshimExtensions.push('OES_texture_half_float_linear');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (checkFloatLinear(gl, halfFloatExt.HALF_FLOAT_OES)) {
|
||||||
|
return shimExtensions.push('OES_texture_half_float_linear');
|
||||||
|
} else {
|
||||||
|
return unshimExtensions.push('OES_texture_half_float_linear');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (window.WebGLRenderingContext != null) {
|
||||||
|
checkSupport();
|
||||||
|
unshimLookup = {};
|
||||||
|
for (_i = 0, _len = unshimExtensions.length; _i < _len; _i++) {
|
||||||
|
name = unshimExtensions[_i];
|
||||||
|
unshimLookup[name] = true;
|
||||||
|
}
|
||||||
|
getExtension = WebGLRenderingContext.prototype.getExtension;
|
||||||
|
WebGLRenderingContext.prototype.getExtension = function(name) {
|
||||||
|
var extobj;
|
||||||
|
extobj = shimLookup[name];
|
||||||
|
if (extobj === void 0) {
|
||||||
|
if (unshimLookup[name]) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return getExtension.call(this, name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return extobj;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
getSupportedExtensions = WebGLRenderingContext.prototype.getSupportedExtensions;
|
||||||
|
WebGLRenderingContext.prototype.getSupportedExtensions = function() {
|
||||||
|
var extension, result, supported, _j, _k, _len1, _len2;
|
||||||
|
supported = getSupportedExtensions.call(this);
|
||||||
|
result = [];
|
||||||
|
for (_j = 0, _len1 = supported.length; _j < _len1; _j++) {
|
||||||
|
extension = supported[_j];
|
||||||
|
if (unshimLookup[extension] === void 0) {
|
||||||
|
result.push(extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (_k = 0, _len2 = shimExtensions.length; _k < _len2; _k++) {
|
||||||
|
extension = shimExtensions[_k];
|
||||||
|
if (__indexOf.call(result, extension) < 0) {
|
||||||
|
result.push(extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
return WebGLRenderingContext.prototype.getFloatExtension = function(spec) {
|
||||||
|
var candidate, candidates, half, halfFramebuffer, halfLinear, halfTexture, i, importance, preference, result, single, singleFramebuffer, singleLinear, singleTexture, use, _j, _k, _l, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
|
||||||
|
if ((_ref = spec.prefer) == null) {
|
||||||
|
spec.prefer = ['half'];
|
||||||
|
}
|
||||||
|
if ((_ref1 = spec.require) == null) {
|
||||||
|
spec.require = [];
|
||||||
|
}
|
||||||
|
if ((_ref2 = spec.throws) == null) {
|
||||||
|
spec.throws = true;
|
||||||
|
}
|
||||||
|
singleTexture = this.getExtension('OES_texture_float');
|
||||||
|
halfTexture = this.getExtension('OES_texture_half_float');
|
||||||
|
singleFramebuffer = this.getExtension('WEBGL_color_buffer_float');
|
||||||
|
halfFramebuffer = this.getExtension('EXT_color_buffer_half_float');
|
||||||
|
singleLinear = this.getExtension('OES_texture_float_linear');
|
||||||
|
halfLinear = this.getExtension('OES_texture_half_float_linear');
|
||||||
|
single = {
|
||||||
|
texture: singleTexture !== null,
|
||||||
|
filterable: singleLinear !== null,
|
||||||
|
renderable: singleFramebuffer !== null,
|
||||||
|
score: 0,
|
||||||
|
precision: 'single',
|
||||||
|
half: false,
|
||||||
|
single: true,
|
||||||
|
type: this.FLOAT
|
||||||
|
};
|
||||||
|
half = {
|
||||||
|
texture: halfTexture !== null,
|
||||||
|
filterable: halfLinear !== null,
|
||||||
|
renderable: halfFramebuffer !== null,
|
||||||
|
score: 0,
|
||||||
|
precision: 'half',
|
||||||
|
half: true,
|
||||||
|
single: false,
|
||||||
|
type: (_ref3 = halfTexture != null ? halfTexture.HALF_FLOAT_OES : void 0) != null ? _ref3 : null
|
||||||
|
};
|
||||||
|
candidates = [];
|
||||||
|
if (single.texture) {
|
||||||
|
candidates.push(single);
|
||||||
|
}
|
||||||
|
if (half.texture) {
|
||||||
|
candidates.push(half);
|
||||||
|
}
|
||||||
|
result = [];
|
||||||
|
for (_j = 0, _len1 = candidates.length; _j < _len1; _j++) {
|
||||||
|
candidate = candidates[_j];
|
||||||
|
use = true;
|
||||||
|
_ref4 = spec.require;
|
||||||
|
for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
|
||||||
|
name = _ref4[_k];
|
||||||
|
if (candidate[name] === false) {
|
||||||
|
use = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (use) {
|
||||||
|
result.push(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (_l = 0, _len3 = result.length; _l < _len3; _l++) {
|
||||||
|
candidate = result[_l];
|
||||||
|
_ref5 = spec.prefer;
|
||||||
|
for (i = _m = 0, _len4 = _ref5.length; _m < _len4; i = ++_m) {
|
||||||
|
preference = _ref5[i];
|
||||||
|
importance = Math.pow(2, spec.prefer.length - i - 1);
|
||||||
|
if (candidate[preference]) {
|
||||||
|
candidate.score += importance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.sort(function(a, b) {
|
||||||
|
if (a.score === b.score) {
|
||||||
|
return 0;
|
||||||
|
} else if (a.score < b.score) {
|
||||||
|
return 1;
|
||||||
|
} else if (a.score > b.score) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (result.length === 0) {
|
||||||
|
if (throws) {
|
||||||
|
throw 'No floating point texture support that is ' + spec.require.join(', ');
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = result[0];
|
||||||
|
return {
|
||||||
|
filterable: result.filterable,
|
||||||
|
renderable: result.renderable,
|
||||||
|
type: result.type,
|
||||||
|
precision: result.precision
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
nukeVendorPrefix();
|
||||||
|
|
||||||
|
textureFloatShims();
|
||||||
|
|
||||||
Shader = (function() {
|
Shader = (function() {
|
||||||
|
|
||||||
@ -166,8 +605,12 @@
|
|||||||
if (params == null) {
|
if (params == null) {
|
||||||
params = {};
|
params = {};
|
||||||
}
|
}
|
||||||
this.channels = this.gl[((_ref = params.channels) != null ? _ref : 'rgb').toUpperCase()];
|
this.channels = this.gl[((_ref = params.channels) != null ? _ref : 'rgba').toUpperCase()];
|
||||||
this.type = this.gl[((_ref1 = params.type) != null ? _ref1 : 'unsigned_byte').toUpperCase()];
|
if (typeof params.type === 'number') {
|
||||||
|
this.type = params.type;
|
||||||
|
} else {
|
||||||
|
this.type = this.gl[((_ref1 = params.type) != null ? _ref1 : 'unsigned_byte').toUpperCase()];
|
||||||
|
}
|
||||||
switch (this.channels) {
|
switch (this.channels) {
|
||||||
case this.gl.RGBA:
|
case this.gl.RGBA:
|
||||||
this.chancount = 4;
|
this.chancount = 4;
|
||||||
@ -246,17 +689,17 @@
|
|||||||
Node = (function() {
|
Node = (function() {
|
||||||
|
|
||||||
function Node(gl, width, height) {
|
function Node(gl, width, height) {
|
||||||
|
var floatExt;
|
||||||
this.gl = gl;
|
this.gl = gl;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
|
floatExt = this.gl.getFloatExtension({
|
||||||
|
require: ['renderable']
|
||||||
|
});
|
||||||
this.texture = new Texture(this.gl, {
|
this.texture = new Texture(this.gl, {
|
||||||
type: 'float'
|
type: floatExt.type
|
||||||
}).bind(0).setSize(this.width, this.height).nearest().clampToEdge();
|
}).bind(0).setSize(this.width, this.height).nearest().clampToEdge();
|
||||||
try {
|
this.fbo = new Framebuffer(this.gl).bind().color(this.texture).unbind();
|
||||||
this.fbo = new Framebuffer(this.gl).bind().color(this.texture).unbind();
|
|
||||||
} catch (error) {
|
|
||||||
throw 'Floating point render target not supported';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Node.prototype.use = function() {
|
Node.prototype.use = function() {
|
||||||
@ -467,9 +910,6 @@
|
|||||||
throw WebGLDebugUtils.glEnumToString(err) + " was caused by call to: " + funcName;
|
throw WebGLDebugUtils.glEnumToString(err) + " was caused by call to: " + funcName;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!this.gl.getExtension('OES_texture_float')) {
|
|
||||||
throw 'No floating point texture support';
|
|
||||||
}
|
|
||||||
this.gl.enableVertexAttribArray(0);
|
this.gl.enableVertexAttribArray(0);
|
||||||
this.gl.blendFunc(this.gl.ONE, this.gl.ONE);
|
this.gl.blendFunc(this.gl.ONE, this.gl.ONE);
|
||||||
if (gradientTexture) {
|
if (gradientTexture) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user