UNPKG

cione-comp-lib

Version:

`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`

262 lines (261 loc) 8.38 kB
import vendor from "../core/vendor.mjs"; import Base from "../core/Base.mjs"; var SHADER_STATE_TO_ENABLE = 1; var SHADER_STATE_KEEP_ENABLE = 2; var SHADER_STATE_PENDING = 3; var enabledAttributeList = {}; function addLineNumbers(string) { var chunks = string.split("\n"); for (var i = 0, il = chunks.length; i < il; i++) { chunks[i] = i + 1 + ": " + chunks[i]; } return chunks.join("\n"); } function checkShaderErrorMsg(_gl, shader, shaderString) { if (!_gl.getShaderParameter(shader, _gl.COMPILE_STATUS)) { return [_gl.getShaderInfoLog(shader), addLineNumbers(shaderString)].join("\n"); } } var tmpFloat32Array16 = new vendor.Float32Array(16); var GLProgram = Base.extend({ uniformSemantics: {}, attributes: {} }, function() { this._locations = {}; this._textureSlot = 0; this._program = null; }, { bind: function(renderer) { this._textureSlot = 0; renderer.gl.useProgram(this._program); }, hasUniform: function(symbol) { var location = this._locations[symbol]; return location !== null && location !== void 0; }, useTextureSlot: function(renderer, texture, slot) { if (texture) { renderer.gl.activeTexture(renderer.gl.TEXTURE0 + slot); if (texture.isRenderable()) { texture.bind(renderer); } else { texture.unbind(renderer); } } }, currentTextureSlot: function() { return this._textureSlot; }, resetTextureSlot: function(slot) { this._textureSlot = slot || 0; }, takeCurrentTextureSlot: function(renderer, texture) { var textureSlot = this._textureSlot; this.useTextureSlot(renderer, texture, textureSlot); this._textureSlot++; return textureSlot; }, setUniform: function(_gl, type, symbol, value) { var locationMap = this._locations; var location = locationMap[symbol]; if (location === null || location === void 0) { return false; } switch (type) { case "m4": if (!(value instanceof Float32Array)) { for (var i = 0; i < value.length; i++) { tmpFloat32Array16[i] = value[i]; } value = tmpFloat32Array16; } _gl.uniformMatrix4fv(location, false, value); break; case "2i": _gl.uniform2i(location, value[0], value[1]); break; case "2f": _gl.uniform2f(location, value[0], value[1]); break; case "3i": _gl.uniform3i(location, value[0], value[1], value[2]); break; case "3f": _gl.uniform3f(location, value[0], value[1], value[2]); break; case "4i": _gl.uniform4i(location, value[0], value[1], value[2], value[3]); break; case "4f": _gl.uniform4f(location, value[0], value[1], value[2], value[3]); break; case "1i": _gl.uniform1i(location, value); break; case "1f": _gl.uniform1f(location, value); break; case "1fv": _gl.uniform1fv(location, value); break; case "1iv": _gl.uniform1iv(location, value); break; case "2iv": _gl.uniform2iv(location, value); break; case "2fv": _gl.uniform2fv(location, value); break; case "3iv": _gl.uniform3iv(location, value); break; case "3fv": _gl.uniform3fv(location, value); break; case "4iv": _gl.uniform4iv(location, value); break; case "4fv": _gl.uniform4fv(location, value); break; case "m2": case "m2v": _gl.uniformMatrix2fv(location, false, value); break; case "m3": case "m3v": _gl.uniformMatrix3fv(location, false, value); break; case "m4v": if (Array.isArray(value) && Array.isArray(value[0])) { var array = new vendor.Float32Array(value.length * 16); var cursor = 0; for (var i = 0; i < value.length; i++) { var item = value[i]; for (var j = 0; j < 16; j++) { array[cursor++] = item[j]; } } _gl.uniformMatrix4fv(location, false, array); } else { _gl.uniformMatrix4fv(location, false, value); } break; } return true; }, setUniformOfSemantic: function(_gl, semantic, val) { var semanticInfo = this.uniformSemantics[semantic]; if (semanticInfo) { return this.setUniform(_gl, semanticInfo.type, semanticInfo.symbol, val); } return false; }, enableAttributes: function(renderer, attribList, vao) { var _gl = renderer.gl; var program = this._program; var locationMap = this._locations; var enabledAttributeListInContext; if (vao) { enabledAttributeListInContext = vao.__enabledAttributeList; } else { enabledAttributeListInContext = enabledAttributeList[renderer.__uid__]; } if (!enabledAttributeListInContext) { if (vao) { enabledAttributeListInContext = vao.__enabledAttributeList = []; } else { enabledAttributeListInContext = enabledAttributeList[renderer.__uid__] = []; } } var locationList = []; for (var i = 0; i < attribList.length; i++) { var symbol = attribList[i]; if (!this.attributes[symbol]) { locationList[i] = -1; continue; } var location = locationMap[symbol]; if (location == null) { location = _gl.getAttribLocation(program, symbol); if (location === -1) { locationList[i] = -1; continue; } locationMap[symbol] = location; } locationList[i] = location; if (!enabledAttributeListInContext[location]) { enabledAttributeListInContext[location] = SHADER_STATE_TO_ENABLE; } else { enabledAttributeListInContext[location] = SHADER_STATE_KEEP_ENABLE; } } for (var i = 0; i < enabledAttributeListInContext.length; i++) { switch (enabledAttributeListInContext[i]) { case SHADER_STATE_TO_ENABLE: _gl.enableVertexAttribArray(i); enabledAttributeListInContext[i] = SHADER_STATE_PENDING; break; case SHADER_STATE_KEEP_ENABLE: enabledAttributeListInContext[i] = SHADER_STATE_PENDING; break; case SHADER_STATE_PENDING: _gl.disableVertexAttribArray(i); enabledAttributeListInContext[i] = 0; break; } } return locationList; }, getAttribLocation: function(_gl, symbol) { var locationMap = this._locations; var location = locationMap[symbol]; if (location == null) { location = _gl.getAttribLocation(this._program, symbol); locationMap[symbol] = location; } return location; }, buildProgram: function(_gl, shader, vertexShaderCode, fragmentShaderCode) { var vertexShader = _gl.createShader(_gl.VERTEX_SHADER); var program = _gl.createProgram(); _gl.shaderSource(vertexShader, vertexShaderCode); _gl.compileShader(vertexShader); var fragmentShader = _gl.createShader(_gl.FRAGMENT_SHADER); _gl.shaderSource(fragmentShader, fragmentShaderCode); _gl.compileShader(fragmentShader); var msg = checkShaderErrorMsg(_gl, vertexShader, vertexShaderCode); if (msg) { return msg; } msg = checkShaderErrorMsg(_gl, fragmentShader, fragmentShaderCode); if (msg) { return msg; } _gl.attachShader(program, vertexShader); _gl.attachShader(program, fragmentShader); if (shader.attributeSemantics["POSITION"]) { _gl.bindAttribLocation(program, 0, shader.attributeSemantics["POSITION"].symbol); } else { var keys = Object.keys(this.attributes); _gl.bindAttribLocation(program, 0, keys[0]); } _gl.linkProgram(program); _gl.deleteShader(vertexShader); _gl.deleteShader(fragmentShader); this._program = program; this.vertexCode = vertexShaderCode; this.fragmentCode = fragmentShaderCode; if (!_gl.getProgramParameter(program, _gl.LINK_STATUS)) { return "Could not link program\n" + _gl.getProgramInfoLog(program); } for (var i = 0; i < shader.uniforms.length; i++) { var uniformSymbol = shader.uniforms[i]; this._locations[uniformSymbol] = _gl.getUniformLocation(program, uniformSymbol); } } }); var GLProgram$1 = GLProgram; export { GLProgram$1 as default };