StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics
https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
5.6 KiB
181 lines
5.6 KiB
'use strict'
|
|
|
|
const isBrowser = require('is-browser')
|
|
const isPlainObject = require('is-plain-obj')
|
|
const getProgram = require('./program')
|
|
const WeakMap = require('weak-map')
|
|
|
|
let texturesCache = setTexture.cache = new WeakMap()
|
|
let texturesIdx = new WeakMap()
|
|
|
|
|
|
module.exports = setTexture
|
|
|
|
|
|
function setTexture (gl, name, options) {
|
|
if (!gl) throw Error('WebGL context is not provided')
|
|
|
|
let program
|
|
if (gl instanceof WebGLProgram) {
|
|
program = gl
|
|
gl = program.gl
|
|
}
|
|
else {
|
|
program = getProgram(gl)
|
|
}
|
|
|
|
if (!program) throw Error('Context has no active program')
|
|
|
|
// object with textures passed
|
|
if (name && typeof name != 'string') {
|
|
let result = {}
|
|
let textures = name
|
|
|
|
for (let name in textures) {
|
|
result[name] = setTexture(gl, name, textures[name], program)
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
let textures = texturesCache.has(gl) ? texturesCache.get(gl) : texturesCache.set(gl, {}).get(gl)
|
|
|
|
// return all textures if no name provided
|
|
if (!name) return textures
|
|
|
|
let texture = textures[name]
|
|
|
|
// autoinit texture(s)
|
|
if (!texture) {
|
|
let count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS)
|
|
|
|
for (let i=0; i < count; ++i) {
|
|
let info = gl.getActiveUniform(program, i)
|
|
if (!info) continue
|
|
if (info.type === gl.SAMPLER_2D || info.type === gl.SAMPLER_CUBE) {
|
|
if (!textures[info.name]) {
|
|
textures[info.name] = {name: info.name}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!textures[name]) textures[name] = {name: name, data: null}
|
|
|
|
texture = textures[name]
|
|
}
|
|
|
|
// detect location
|
|
if (texture.locations == null) {
|
|
texture.locations = new WeakMap()
|
|
}
|
|
if (!texture.locations.has(program)) {
|
|
texture.locations.set(program, gl.getUniformLocation(program, name))
|
|
}
|
|
|
|
// if no options passed - just return known texture info
|
|
if (options == null) {
|
|
return texture
|
|
}
|
|
|
|
if (!isPlainObject(options)) options = {data: options}
|
|
|
|
|
|
if (texture.index == null || options.index != null) {
|
|
let textureCount = texturesIdx.get(program) || 0
|
|
texture.index = options.index != null ? options.index : textureCount++
|
|
textureCount = Math.max(textureCount, texture.index)
|
|
texturesIdx.set(program, textureCount)
|
|
gl.uniform1i(texture.locations.get(program), texture.index)
|
|
}
|
|
|
|
if (!texture.texture) {
|
|
texture.texture = gl.createTexture()
|
|
}
|
|
|
|
gl.activeTexture(gl.TEXTURE0 + texture.index)
|
|
gl.bindTexture(gl.TEXTURE_2D, texture.texture)
|
|
|
|
if (options.wrap || options.wrapS || !texture.wrapS) {
|
|
texture.wrapS = options.wrap && options.wrap[0] || options.wrapS || options.wrap || texture.wrapS || gl.CLAMP_TO_EDGE
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texture.wrapS)
|
|
}
|
|
|
|
if (options.wrap || options.wrapT || !texture.wrapT) {
|
|
texture.wrapT = options.wrap && options.wrap[1] || options.wrapT || options.wrap || texture.wrapT || gl.CLAMP_TO_EDGE
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texture.wrapT)
|
|
}
|
|
|
|
if (options.filter || options.minFilter || !texture.minFilter) {
|
|
texture.minFilter = options.minFilter || options.filter || texture.minFilter || gl.NEAREST
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.minFilter)
|
|
}
|
|
|
|
if (options.filter || options.magFilter || !texture.magFilter) {
|
|
texture.magFilter = options.magFilter || options.filter || texture.magFilter || gl.NEAREST
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.magFilter)
|
|
}
|
|
|
|
if (!texture.type || options.type) {
|
|
texture.type = options.type || texture.type || gl.UNSIGNED_BYTE
|
|
}
|
|
|
|
if (!texture.format || options.format) {
|
|
texture.format = options.format || texture.format || gl.RGBA
|
|
}
|
|
|
|
|
|
let data = options.data || null
|
|
let image
|
|
if (isBrowser) {
|
|
// url for image
|
|
if (typeof data === 'string') {
|
|
if (data === (texture.data && texture.data._src) || data === (texture.data && texture.data.src)) {
|
|
return texture
|
|
}
|
|
image = new Image
|
|
image.src = data
|
|
image._src = data
|
|
}
|
|
else if ('Image' in self && data instanceof Image && !data.complete) {
|
|
image = data
|
|
}
|
|
|
|
if (image) {
|
|
if (image.complete && image === texture.data || (texture.data && image.src === texture.data.src)) {
|
|
return texture
|
|
}
|
|
image.addEventListener('load', () => {
|
|
setTexture(gl, name, image, program)
|
|
})
|
|
data = null
|
|
}
|
|
}
|
|
|
|
if (texture.level == null) texture.level = 0
|
|
|
|
// handle raw data case
|
|
if (data == null || Array.isArray(data) || ArrayBuffer.isView(data)) {
|
|
if (options && options.shape) {
|
|
if (texture.width == null) texture.width = options.shape[0]
|
|
if (texture.height == null) texture.height = options.shape[1]
|
|
}
|
|
else {
|
|
let len = data && data.length || 1
|
|
if (options.width != null) texture.width = options.width
|
|
else if (texture.width == null) texture.width = data && data.width || (texture.format === gl.ALPHA ? len : Math.max(len / 4, 1))
|
|
if (options.height != null) texture.height = options.height
|
|
else if (texture.height == null) texture.height = (data && data.height) || 1
|
|
}
|
|
texture.data = data == null ? null : texture.type === gl.FLOAT ? new Float32Array(data) : texture.type === gl.UNSIGNED_SHORT ? new Uint16Array(data) : new Uint8Array(data)
|
|
|
|
// TODO: use texSubImage2D here, it is possible
|
|
gl.texImage2D(gl.TEXTURE_2D, texture.level, texture.format, texture.width, texture.height, 0, texture.format, texture.type, texture.data)
|
|
} else {
|
|
texture.width = data && data.width || 1
|
|
texture.height = data && data.height || 1
|
|
texture.data = data
|
|
gl.texImage2D(gl.TEXTURE_2D, texture.level, texture.format, texture.format, texture.type, texture.data)
|
|
}
|
|
|
|
return texture;
|
|
}
|
|
|