UNPKG

@rtn263net/cloudhub-rts-electron-sdk

Version:

cloudhub-rts-electron-sdk

662 lines (661 loc) 25.3 kB
"use strict"; (function (root, factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else { var lib = factory.call(root); Object.keys(lib).forEach(function (key) { root[key] = lib[key]; }); } }(this, function () { var topWindow = this; function error(msg) { if (topWindow.console) { if (topWindow.console.error) { topWindow.console.error(msg); } else if (topWindow.console.log) { topWindow.console.log(msg); } } } function isInIFrame(w) { w = w || topWindow; return w !== w.top; } function makeFailHTML(msg) { return '' + '<table style="background-color: #8CE; width: 100%; height: 100%;"><tr>' + '<td align="center">' + '<div style="display: table-cell; vertical-align: middle;">' + '<div style="">' + msg + '</div>' + '</div>' + '</td></tr></table>'; } var GET_A_WEBGL_BROWSER = '' + 'This page requires a browser that supports WebGL.<br/>' + '<a href="http://get.webgl.org">Click here to upgrade your browser.</a>'; var OTHER_PROBLEM = '' + "It doesn't appear your computer can support WebGL.<br/>" + '<a href="http://get.webgl.org/troubleshooting/">Click here for more information.</a>'; function create3DContext(canvas, opt_attribs) { var names = ["webgl", "experimental-webgl"]; var context = null; for (var ii = 0; ii < names.length; ++ii) { try { context = canvas.getContext(names[ii], opt_attribs); } catch (e) { } if (context) { break; } } return context; } function setupWebGL(canvas, opt_attribs) { function showLink(str) { var container = canvas.parentNode; if (container) { container.innerHTML = makeFailHTML(str); } } if (!topWindow.WebGLRenderingContext) { showLink(GET_A_WEBGL_BROWSER); return null; } var context = create3DContext(canvas, opt_attribs); if (!context) { showLink(OTHER_PROBLEM); } return context; } function updateCSSIfInIFrame() { if (isInIFrame()) { document.body.className = "iframe"; } } function getWebGLContext(canvas, opt_attribs, opt_options) { var options = opt_options || {}; if (isInIFrame()) { updateCSSIfInIFrame(); if (!options.dontResize && options.resize !== false) { var width = canvas.clientWidth; var height = canvas.clientHeight; canvas.width = width; canvas.height = height; } } else if (!options.noTitle && options.title !== false) { var title = document.title; var h1 = document.createElement("h1"); h1.innerText = title; document.body.insertBefore(h1, document.body.children[0]); } var gl = setupWebGL(canvas, opt_attribs); return gl; } function loadShader(gl, shaderSource, shaderType, opt_errorCallback) { var errFn = opt_errorCallback || error; var shader = gl.createShader(shaderType); gl.shaderSource(shader, shaderSource); gl.compileShader(shader); var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); if (!compiled) { var lastError = gl.getShaderInfoLog(shader); errFn("*** Error compiling shader '" + shader + "':" + lastError); gl.deleteShader(shader); return null; } return shader; } function createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback) { var errFn = opt_errorCallback || error; var program = gl.createProgram(); shaders.forEach(function (shader) { gl.attachShader(program, shader); }); if (opt_attribs) { obj_attrib.forEach(function (attrib, ndx) { gl.bindAttribLocation(program, opt_locations ? opt_locations[ndx] : ndx, attrib); }); } gl.linkProgram(program); var linked = gl.getProgramParameter(program, gl.LINK_STATUS); if (!linked) { var lastError = gl.getProgramInfoLog(program); errFn("Error in program linking:" + lastError); gl.deleteProgram(program); return null; } return program; } function createShaderFromScript(gl, scriptId, opt_shaderType, opt_errorCallback) { var shaderSource = ""; var shaderType; var shaderScript = document.getElementById(scriptId); if (!shaderScript) { throw ("*** Error: unknown script element" + scriptId); } shaderSource = shaderScript.text; if (!opt_shaderType) { if (shaderScript.type === "x-shader/x-vertex") { shaderType = gl.VERTEX_SHADER; } else if (shaderScript.type === "x-shader/x-fragment") { shaderType = gl.FRAGMENT_SHADER; } else if (shaderType !== gl.VERTEX_SHADER && shaderType !== gl.FRAGMENT_SHADER) { throw ("*** Error: unknown shader type"); } } return loadShader(gl, shaderSource, opt_shaderType ? opt_shaderType : shaderType, opt_errorCallback); } var defaultShaderType = [ "VERTEX_SHADER", "FRAGMENT_SHADER", ]; function createProgramFromScripts(gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) { var shaders = []; for (var ii = 0; ii < shaderScriptIds.length; ++ii) { shaders.push(createShaderFromScript(gl, shaderScriptIds[ii], gl[defaultShaderType[ii]], opt_errorCallback)); } return createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback); } function createProgramFromSources(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { var shaders = []; for (var ii = 0; ii < shaderSources.length; ++ii) { shaders.push(loadShader(gl, shaderSources[ii], gl[defaultShaderType[ii]], opt_errorCallback)); } return createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback); } function getBindPointForSamplerType(gl, type) { if (type === gl.SAMPLER_2D) return gl.TEXTURE_2D; if (type === gl.SAMPLER_CUBE) return gl.TEXTURE_CUBE_MAP; } function createUniformSetters(gl, program) { var textureUnit = 0; function createUniformSetter(program, uniformInfo) { var location = gl.getUniformLocation(program, uniformInfo.name); var type = uniformInfo.type; var isArray = (uniformInfo.size > 1 && uniformInfo.name.substr(-3) === "[0]"); if (type === gl.FLOAT && isArray) { return function (v) { gl.uniform1fv(location, v); }; } if (type === gl.FLOAT) { return function (v) { gl.uniform1f(location, v); }; } if (type === gl.FLOAT_VEC2) { return function (v) { gl.uniform2fv(location, v); }; } if (type === gl.FLOAT_VEC3) { return function (v) { gl.uniform3fv(location, v); }; } if (type === gl.FLOAT_VEC4) { return function (v) { gl.uniform4fv(location, v); }; } if (type === gl.INT && isArray) { return function (v) { gl.uniform1iv(location, v); }; } if (type === gl.INT) { return function (v) { gl.uniform1i(location, v); }; } if (type === gl.INT_VEC2) { return function (v) { gl.uniform2iv(location, v); }; } if (type === gl.INT_VEC3) { return function (v) { gl.uniform3iv(location, v); }; } if (type === gl.INT_VEC4) { return function (v) { gl.uniform4iv(location, v); }; } if (type === gl.BOOL) { return function (v) { gl.uniform1iv(location, v); }; } if (type === gl.BOOL_VEC2) { return function (v) { gl.uniform2iv(location, v); }; } if (type === gl.BOOL_VEC3) { return function (v) { gl.uniform3iv(location, v); }; } if (type === gl.BOOL_VEC4) { return function (v) { gl.uniform4iv(location, v); }; } if (type === gl.FLOAT_MAT2) { return function (v) { gl.uniformMatrix2fv(location, false, v); }; } if (type === gl.FLOAT_MAT3) { return function (v) { gl.uniformMatrix3fv(location, false, v); }; } if (type === gl.FLOAT_MAT4) { return function (v) { gl.uniformMatrix4fv(location, false, v); }; } if ((type === gl.SAMPLER_2D || type === gl.SAMPLER_CUBE) && isArray) { var units = []; for (var ii = 0; ii < info.size; ++ii) { units.push(textureUnit++); } return function (bindPoint, units) { return function (textures) { gl.uniform1iv(location, units); textures.forEach(function (texture, index) { gl.activeTexture(gl.TEXTURE0 + units[index]); gl.bindTexture(bindPoint, texture); }); }; }(getBindPointForSamplerType(gl, type), units); } if (type === gl.SAMPLER_2D || type === gl.SAMPLER_CUBE) { return function (bindPoint, unit) { return function (texture) { gl.uniform1i(location, unit); gl.activeTexture(gl.TEXTURE0 + unit); gl.bindTexture(bindPoint, texture); }; }(getBindPointForSamplerType(gl, type), textureUnit++); } throw ("unknown type: 0x" + type.toString(16)); } var uniformSetters = {}; var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); for (var ii = 0; ii < numUniforms; ++ii) { var uniformInfo = gl.getActiveUniform(program, ii); if (!uniformInfo) { break; } var name = uniformInfo.name; if (name.substr(-3) === "[0]") { name = name.substr(0, name.length - 3); } var setter = createUniformSetter(program, uniformInfo); uniformSetters[name] = setter; } return uniformSetters; } function setUniforms(setters, values) { Object.keys(values).forEach(function (name) { var setter = setters[name]; if (setter) { setter(values[name]); } }); } function createAttributeSetters(gl, program) { var attribSetters = {}; function createAttribSetter(index) { return function (b) { gl.bindBuffer(gl.ARRAY_BUFFER, b.buffer); gl.enableVertexAttribArray(index); gl.vertexAttribPointer(index, b.numComponents || b.size, b.type || gl.FLOAT, b.normalize || false, b.stride || 0, b.offset || 0); }; } var numAttribs = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); for (var ii = 0; ii < numAttribs; ++ii) { var attribInfo = gl.getActiveAttrib(program, ii); if (!attribInfo) { break; } var index = gl.getAttribLocation(program, attribInfo.name); attribSetters[attribInfo.name] = createAttribSetter(index); } return attribSetters; } function setAttributes(setters, buffers) { Object.keys(buffers).forEach(function (name) { var setter = setters[name]; if (setter) { setter(buffers[name]); } }); } function createProgramInfo(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { shaderSources = shaderSources.map(function (source) { var script = document.getElementById(source); return script ? script.text : source; }); var program = createProgramFromSources(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback); if (!program) { return null; } var uniformSetters = createUniformSetters(gl, program); var attribSetters = createAttributeSetters(gl, program); return { program: program, uniformSetters: uniformSetters, attribSetters: attribSetters, }; } function setBuffersAndAttributes(gl, setters, buffers) { setAttributes(setters, buffers.attribs); if (buffers.indices) { gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.indices); } } var browserPrefixes = [ "", "MOZ_", "OP_", "WEBKIT_", ]; function getExtensionWithKnownPrefixes(gl, name) { for (var ii = 0; ii < browserPrefixes.length; ++ii) { var prefixedName = browserPrefixes[ii] + name; var ext = gl.getExtension(prefixedName); if (ext) { return ext; } } } function resizeCanvasToDisplaySize(canvas, multiplier) { multiplier = multiplier || 1; var width = canvas.clientWidth * multiplier; var height = canvas.clientHeight * multiplier; if (canvas.width !== width || canvas.height !== height) { canvas.width = width; canvas.height = height; return true; } return false; } function getIFrameForWindow(window) { if (!isInIFrame(window)) { return; } var iframes = window.parent.document.getElementsByTagName("iframe"); for (var ii = 0; ii < iframes.length; ++ii) { var iframe = iframes[ii]; if (iframe.contentDocument === window.document) { return iframe; } } } function isFrameVisible(window) { try { var iframe = getIFrameForWindow(window); if (!iframe) { return true; } var bounds = iframe.getBoundingClientRect(); var isVisible = bounds.top < window.parent.innerHeight && bounds.bottom >= 0 && bounds.left < window.parent.innerWidth && bounds.right >= 0; return isVisible && isFrameVisible(window.parent); } catch (e) { return true; } } function isOnScreen(element) { var isVisible = true; if (element) { var bounds = element.getBoundingClientRect(); isVisible = bounds.top < topWindow.innerHeight && bounds.bottom >= 0; } return isVisible && isFrameVisible(topWindow); } function augmentTypedArray(typedArray, numComponents) { var cursor = 0; typedArray.push = function () { for (var ii = 0; ii < arguments.length; ++ii) { var value = arguments[ii]; if (value instanceof Array || (value.buffer && value.buffer instanceof ArrayBuffer)) { for (var jj = 0; jj < value.length; ++jj) { typedArray[cursor++] = value[jj]; } } else { typedArray[cursor++] = value; } } }; typedArray.reset = function (opt_index) { cursor = opt_index || 0; }; typedArray.numComponents = numComponents; Object.defineProperty(typedArray, 'numElements', { get: function () { return this.length / this.numComponents | 0; }, }); return typedArray; } function createAugmentedTypedArray(numComponents, numElements, opt_type) { var Type = opt_type || Float32Array; return augmentTypedArray(new Type(numComponents * numElements), numComponents); } function createBufferFromTypedArray(gl, array, type, drawType) { type = type || gl.ARRAY_BUFFER; var buffer = gl.createBuffer(); gl.bindBuffer(type, buffer); gl.bufferData(type, array, drawType || gl.STATIC_DRAW); return buffer; } function allButIndices(name) { return name !== "indices"; } function createMapping(obj) { var mapping = {}; Object.keys(obj).filter(allButIndices).forEach(function (key) { mapping["a_" + key] = key; }); return mapping; } function getGLTypeForTypedArray(gl, typedArray) { if (typedArray instanceof Int8Array) { return gl.BYTE; } if (typedArray instanceof Uint8Array) { return gl.UNSIGNED_BYTE; } if (typedArray instanceof Int16Array) { return gl.SHORT; } if (typedArray instanceof Uint16Array) { return gl.UNSIGNED_SHORT; } if (typedArray instanceof Int32Array) { return gl.INT; } if (typedArray instanceof Uint32Array) { return gl.UNSIGNED_INT; } if (typedArray instanceof Float32Array) { return gl.FLOAT; } throw "unsupported typed array type"; } function getNormalizationForTypedArray(typedArray) { if (typedArray instanceof Int8Array) { return true; } if (typedArray instanceof Uint8Array) { return true; } return false; } function isArrayBuffer(a) { return a.buffer && a.buffer instanceof ArrayBuffer; } function guessNumComponentsFromName(name, length) { var numComponents; if (name.indexOf("coord") >= 0) { numComponents = 2; } else if (name.indexOf("color") >= 0) { numComponents = 4; } else { numComponents = 3; } if (length % numComponents > 0) { throw "can not guess numComponents. You should specify it."; } return numComponents; } function makeTypedArray(array, name) { if (isArrayBuffer(array)) { return array; } if (Array.isArray(array)) { array = { data: array, }; } if (!array.numComponents) { array.numComponents = guessNumComponentsFromName(name, array.length); } var type = array.type; if (!type) { if (name === "indices") { type = Uint16Array; } } var typedArray = createAugmentedTypedArray(array.numComponents, array.data.length / array.numComponents | 0, type); typedArray.push(array.data); return typedArray; } function createAttribsFromArrays(gl, arrays, opt_mapping) { var mapping = opt_mapping || createMapping(arrays); var attribs = {}; Object.keys(mapping).forEach(function (attribName) { var bufferName = mapping[attribName]; var array = makeTypedArray(arrays[bufferName], bufferName); attribs[attribName] = { buffer: createBufferFromTypedArray(gl, array), numComponents: array.numComponents || guessNumComponentsFromName(bufferName), type: getGLTypeForTypedArray(gl, array), normalize: getNormalizationForTypedArray(array), }; }); return attribs; } function getNumElementsFromNonIndexedArrays(arrays) { var key = Object.keys(arrays)[0]; var array = arrays[key]; if (isArrayBuffer(array)) { return array.numElements; } else { return array.data.length / array.numComponents; } } function createBufferInfoFromArrays(gl, arrays, opt_mapping) { var bufferInfo = { attribs: createAttribsFromArrays(gl, arrays, opt_mapping), }; var indices = arrays.indices; if (indices) { indices = makeTypedArray(indices, "indices"); bufferInfo.indices = createBufferFromTypedArray(gl, indices, gl.ELEMENT_ARRAY_BUFFER); bufferInfo.numElements = indices.length; } else { bufferInfo.numElements = getNumElementsFromNonIndexedArrays(arrays); } return bufferInfo; } function createBuffersFromArrays(gl, arrays) { var buffers = {}; Object.keys(arrays).forEach(function (key) { var type = key === "indices" ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER; var array = makeTypedArray(arrays[key], name); buffers[key] = createBufferFromTypedArray(gl, array, type); }); if (arrays.indices) { buffers.numElements = arrays.indices.length; } else if (arrays.position) { buffers.numElements = arrays.position.length / 3; } return buffers; } function drawBufferInfo(gl, type, bufferInfo, count, offset) { var indices = bufferInfo.indices; var numElements = count === undefined ? bufferInfo.numElements : count; offset = offset === undefined ? offset : 0; if (indices) { gl.drawElements(type, numElements, gl.UNSIGNED_SHORT, offset); } else { gl.drawArrays(type, offset, numElements); } } function drawObjectList(gl, objectsToDraw) { var lastUsedProgramInfo = null; var lastUsedBufferInfo = null; objectsToDraw.forEach(function (object) { var programInfo = object.programInfo; var bufferInfo = object.bufferInfo; var bindBuffers = false; if (programInfo !== lastUsedProgramInfo) { lastUsedProgramInfo = programInfo; gl.useProgram(programInfo.program); bindBuffers = true; } if (bindBuffers || bufferInfo !== lastUsedBufferInfo) { lastUsedBufferInfo = bufferInfo; setBuffersAndAttributes(gl, programInfo.attribSetters, bufferInfo); } setUniforms(programInfo.uniformSetters, object.uniforms); drawBufferInfo(gl, gl.TRIANGLES, bufferInfo); }); } return { createAugmentedTypedArray: createAugmentedTypedArray, createAttribsFromArrays: createAttribsFromArrays, createBuffersFromArrays: createBuffersFromArrays, createBufferInfoFromArrays: createBufferInfoFromArrays, createAttributeSetters: createAttributeSetters, createProgram: createProgram, createProgramFromScripts: createProgramFromScripts, createProgramFromSources: createProgramFromSources, createProgramInfo: createProgramInfo, createUniformSetters: createUniformSetters, drawBufferInfo: drawBufferInfo, drawObjectList: drawObjectList, getWebGLContext: getWebGLContext, updateCSSIfInIFrame: updateCSSIfInIFrame, getExtensionWithKnownPrefixes: getExtensionWithKnownPrefixes, resizeCanvasToDisplaySize: resizeCanvasToDisplaySize, setAttributes: setAttributes, setBuffersAndAttributes: setBuffersAndAttributes, setUniforms: setUniforms, setupWebGL: setupWebGL, }; }));