cables_dev/cables/src/core/cgl/cgl_mesh.js
- import { Logger } from "cables-shared-client";
- import { Uniform } from "./cgl_shader_uniform.js";
- import { CONSTANTS } from "./constants.js";
-
- const MESH = {};
- MESH.lastMesh = null;
-
- /**
- * webgl renderable 3d object
- * @class
- * @namespace external:CGL
- * @hideconstructor
- * @param {Context} _cgl cgl
- * @param {Geometry} __geom geometry
- * @param {Number} _options glPrimitive
- * @example
- * const cgl=this._cgl
- * const mesh=new CGL.Mesh(cgl, geometry);
- *
- * function render()
- * {
- * mesh.render(cgl.getShader());
- * }
- */
- const Mesh = function (_cgl, __geom, _options)
- {
- this._cgl = _cgl;
-
- let options = _options || {};
- if (CABLES.UTILS.isNumeric(options))options = { "glPrimitive": _options }; // old constructor fallback...
- this._log = new Logger("cgl_mesh");
- this._bufVertexAttrib = null;
- this._bufVerticesIndizes = this._cgl.gl.createBuffer();
- this._indexType = this._cgl.gl.UNSIGNED_SHORT;
- this._attributes = [];
- this._attribLocs = {};
- this._geom = null;
- this._lastShader = null;
- this._numInstances = 0;
- this._glPrimitive = options.glPrimitive;
-
- this.opId = options.opId || "";
- this._preWireframeGeom = null;
- this.addVertexNumbers = false;
- this._name = "unknown";
-
- this.feedBackAttributes = [];
- this.setGeom(__geom);
-
- this._feedBacks = [];
- this._feedBacksChanged = false;
- this._transformFeedBackLoc = -1;
- this._lastAttrUpdate = 0;
-
- this.memFreed = false;
-
- this._cgl.profileData.addHeavyEvent("mesh constructed", this._name);
-
- this._queryExt = null;
-
- Object.defineProperty(this, "numInstances", {
- get()
- {
- return this._numInstances;
- },
- set(v)
- {
- this.setNumInstances(v);
- },
- });
- };
-
- Mesh.prototype.freeMem = function ()
- {
- this.memFreed = true;
-
- for (let i = 0; i < this._attributes.length; i++)
- {
- this._attributes[i].floatArray = null;
- }
- };
-
- /**
- * @function updateVertices
- * @memberof Mesh
- * @instance
- * @description update vertices only from a geometry
- * @param {Geometry} geom
- */
- Mesh.prototype.updateVertices = function (geom)
- {
- this.setAttribute(CONSTANTS.SHADER.SHADERVAR_VERTEX_POSITION, geom.vertices, 3);
- this._numVerts = geom.vertices.length / 3;
- };
-
- Mesh.prototype.setAttributePointer = function (attrName, name, stride, offset)
- {
- for (let i = 0; i < this._attributes.length; i++)
- {
- if (this._attributes[i].name == attrName)
- {
- if (!this._attributes[i].pointer) this._attributes[i].pointer = [];
-
- this._attributes[i].pointer.push(
- {
- "loc": -1,
- "name": name,
- "stride": stride,
- "offset": offset,
- "instanced": attrName == CONSTANTS.SHADER.SHADERVAR_INSTANCE_MMATRIX,
- }
- );
- }
- }
- };
-
- Mesh.prototype.getAttribute = function (name)
- {
- for (let i = 0; i < this._attributes.length; i++) if (this._attributes[i].name == name) return this._attributes[i];
- };
-
- Mesh.prototype.setAttributeRange = function (attr, array, start, end)
- {
- if (!attr) return;
- if (!start && !end) return;
-
- if (!attr.name)
- {
- this._log.stack("no attrname?!");
- }
-
- this._cgl.gl.bindBuffer(this._cgl.gl.ARRAY_BUFFER, attr.buffer);
- this._cgl.profileData.profileMeshAttributes += (end - start) || 0;
-
- this._cgl.profileData.profileSingleMeshAttribute[this._name] = this._cgl.profileData.profileSingleMeshAttribute[this._name] || 0;
- this._cgl.profileData.profileSingleMeshAttribute[this._name] += (end - start) || 0;
-
- if (attr.numItems < array.length / attr.itemSize)
- {
- this._resizeAttr(array, attr);
- }
-
- if (end > array.length)
- {
- if (CABLES.platform.isDevEnv())
- this._log.log(this._cgl.canvas.id + " " + attr.name + " buffersubdata out of bounds ?", array.length, end, start, attr);
- // end = array.length - 1;
- return;
- }
-
- if (this._cgl.glVersion == 1) this._cgl.gl.bufferSubData(this._cgl.gl.ARRAY_BUFFER, 0, array); // probably slow/ maybe create and array with only changed size ??
- else this._cgl.gl.bufferSubData(this._cgl.gl.ARRAY_BUFFER, start * 4, array, start, (end - start));
- };
-
- Mesh.prototype._resizeAttr = function (array, attr)
- {
- if (attr.buffer)
- this._cgl.gl.deleteBuffer(attr.buffer);
-
- attr.buffer = this._cgl.gl.createBuffer();
- this._cgl.gl.bindBuffer(this._cgl.gl.ARRAY_BUFFER, attr.buffer);
- this._bufferArray(array, attr);
- attr.numItems = array.length / attr.itemSize;// numItems;
- };
-
-
- Mesh.prototype._bufferArray = function (array, attr)
- {
- let floatArray = attr.floatArray || null;
- if (!array) return;
-
-
- if (this._cgl.debugOneFrame)
- {
- console.log("_bufferArray", array.length, attr.name); // eslint-disable-line
- }
-
- if (!(array instanceof Float32Array))
- {
- if (attr && floatArray && floatArray.length == array.length)
- {
- floatArray.set(array);
- // floatArray = floatArray;
- }
- else
- {
- floatArray = new Float32Array(array);
-
- if (this._cgl.debugOneFrame)
- {
- console.log("_bufferArray create new float32array", array.length, attr.name); // eslint-disable-line
- }
-
- if (array.length > 10000)
- {
- this._cgl.profileData.profileNonTypedAttrib++;
- this._cgl.profileData.profileNonTypedAttribNames = "(" + this._name + ":" + attr.name + ")";
- }
- }
- }
- else floatArray = array;
-
- attr.arrayLength = floatArray.length;
- attr.floatArray = null;// floatArray;
-
- this._cgl.gl.bufferData(this._cgl.gl.ARRAY_BUFFER, floatArray, this._cgl.gl.DYNAMIC_DRAW);
- };
-
- /**
- * @function setAttribute
- * @description update attribute
- * @memberof Mesh
- * @instance
- * @param {String} attribute name
- * @param {Array} data
- * @param {Number} itemSize
- * @param {Object} options
- */
- Mesh.prototype.addAttribute = Mesh.prototype.updateAttribute = Mesh.prototype.setAttribute = function (name, array, itemSize, options)
- {
- if (!array)
- {
- this._log.error("mesh addAttribute - no array given! " + name);
- throw new Error();
- }
- let cb = null;
- let instanced = false;
- let i = 0;
- const numItems = array.length / itemSize;
-
- this._cgl.profileData.profileMeshAttributes += numItems || 0;
-
- if (typeof options == "function")
- {
- cb = options;
- }
-
- if (typeof options == "object")
- {
- if (options.cb) cb = options.cb;
- if (options.instanced) instanced = options.instanced;
- }
-
- if (name == CONSTANTS.SHADER.SHADERVAR_INSTANCE_MMATRIX) instanced = true;
-
-
- for (i = 0; i < this._attributes.length; i++)
- {
- const attr = this._attributes[i];
- if (attr.name == name)
- {
- if (attr.numItems === numItems)
- {
- }
- else
- {
- // this._log.log("wrong buffer size", this._geom.name, attr.name, attr.numItems, numItems);
- this._resizeAttr(array, attr);
- }
-
- this._cgl.gl.bindBuffer(this._cgl.gl.ARRAY_BUFFER, attr.buffer);
- this._bufferArray(array, attr);
-
- return attr;
- }
- }
-
- // create new buffer...
-
- const buffer = this._cgl.gl.createBuffer();
-
- this._cgl.gl.bindBuffer(this._cgl.gl.ARRAY_BUFFER, buffer);
- // this._cgl.gl.bufferData(this._cgl.gl.ARRAY_BUFFER, floatArray, this._cgl.gl.DYNAMIC_DRAW);
-
- let type = this._cgl.gl.FLOAT;
- if (options && options.type) type = options.type;
- const attr = {
- "buffer": buffer,
- "name": name,
- "cb": cb,
- "itemSize": itemSize,
- "numItems": numItems,
- "startItem": 0,
- "instanced": instanced,
- "type": type
- };
-
- this._bufferArray(array, attr);
-
- if (name == CONSTANTS.SHADER.SHADERVAR_VERTEX_POSITION) this._bufVertexAttrib = attr;
- this._attributes.push(attr);
- this._attribLocs = {};
-
- return attr;
- };
-
- Mesh.prototype.getAttributes = function ()
- {
- return this._attributes;
- };
-
- /**
- * @function updateTexCoords
- * @description update texture coordinates only from a geometry
- * @memberof Mesh
- * @instance
- * @param {Geometry} geom
- */
- Mesh.prototype.updateTexCoords = function (geom)
- {
- if (geom.texCoords && geom.texCoords.length > 0)
- {
- this.setAttribute(CONSTANTS.SHADER.SHADERVAR_VERTEX_TEXCOORD, geom.texCoords, 2);
- }
- else
- {
- const tcBuff = new Float32Array(Math.round((geom.vertices.length / 3) * 2));
- this.setAttribute(CONSTANTS.SHADER.SHADERVAR_VERTEX_TEXCOORD, tcBuff, 2);
- }
- };
-
-
- /**
- * @function updateNormals
- * @description update normals only from a geometry
- * @memberof Mesh
- * @instance
- * @param {Geometry} geom
- */
- Mesh.prototype.updateNormals = function (geom)
- {
- if (geom.vertexNormals && geom.vertexNormals.length > 0)
- {
- this.setAttribute(CONSTANTS.SHADER.SHADERVAR_VERTEX_NORMAL, geom.vertexNormals, 3);
- }
- else
- {
- const tcBuff = new Float32Array(Math.round((geom.vertices.length)));
- this.setAttribute(CONSTANTS.SHADER.SHADERVAR_VERTEX_NORMAL, tcBuff, 3);
- }
- };
-
-
- Mesh.prototype._setVertexNumbers = function (arr)
- {
- if (!this._verticesNumbers || this._verticesNumbers.length != this._numVerts || arr)
- {
- if (arr) this._verticesNumbers = arr;
- else
- {
- this._verticesNumbers = new Float32Array(this._numVerts);
- for (let i = 0; i < this._numVerts; i++) this._verticesNumbers[i] = i;
- }
-
- this.setAttribute(CONSTANTS.SHADER.SHADERVAR_VERTEX_NUMBER, this._verticesNumbers, 1, (attr, geom, shader) =>
- {
- if (!shader.uniformNumVertices) shader.uniformNumVertices = new Uniform(shader, "f", "numVertices", this._numVerts);
- shader.uniformNumVertices.setValue(this._numVerts);
-
- // console.log("this._numVerts", this._numVerts, attr, shader.uniformNumVertices);
- });
- }
- };
-
- /**
- * @function setVertexIndices
- * @description update vertex indices / faces
- * @memberof Mesh
- * @instance
- * @param {array} vertIndices
- */
- Mesh.prototype.setVertexIndices = function (vertIndices)
- {
- if (!this._bufVerticesIndizes)
- {
- this._log.warn("no bufVerticesIndizes: " + this._name);
- return;
- }
- if (vertIndices.length > 0)
- {
- if (vertIndices instanceof Float32Array) this._log.warn("vertIndices float32Array: " + this._name);
-
- for (let i = 0; i < vertIndices.length; i++)
- {
- if (vertIndices[i] >= this._numVerts)
- {
- this._log.warn("invalid index in " + this._name, i, vertIndices[i]);
- return;
- }
- }
-
- this._cgl.gl.bindBuffer(this._cgl.gl.ELEMENT_ARRAY_BUFFER, this._bufVerticesIndizes);
-
- // todo cache this ?
- // if(!this.vertIndicesTyped || this.vertIndicesTyped.length!=this._geom.verticesIndices.length)
-
- if (vertIndices.length > 65535)
- {
- this.vertIndicesTyped = new Uint32Array(vertIndices);
- this._indexType = this._cgl.gl.UNSIGNED_INT;
- }
- else
- if (vertIndices instanceof Uint32Array)
- {
- this.vertIndicesTyped = vertIndices;
- this._indexType = this._cgl.gl.UNSIGNED_INT;
- }
- else
- if (!(vertIndices instanceof Uint16Array))
- {
- this.vertIndicesTyped = new Uint16Array(vertIndices);
- this._indexType = this._cgl.gl.UNSIGNED_SHORT;
- }
- else this.vertIndicesTyped = vertIndices;
-
- this._cgl.gl.bufferData(this._cgl.gl.ELEMENT_ARRAY_BUFFER, this.vertIndicesTyped, this._cgl.gl.DYNAMIC_DRAW);
- this._bufVerticesIndizes.itemSize = 1;
- this._bufVerticesIndizes.numItems = vertIndices.length;
- }
- else this._bufVerticesIndizes.numItems = 0;
- };
-
- /**
- * @function setGeom
- * @memberof Mesh
- * @instance
- * @description set geometry for mesh
- * @param {Geometry} geom
- * @param {boolean} removeRef
- */
- Mesh.prototype.setGeom = function (geom, removeRef)
- {
- this._geom = geom;
- if (geom.glPrimitive != null) this._glPrimitive = geom.glPrimitive;
- if (this._geom && this._geom.name) this._name = "mesh " + this._geom.name;
-
- MESH.lastMesh = null;
- this._cgl.profileData.profileMeshSetGeom++;
-
- this._disposeAttributes();
-
- this.updateVertices(this._geom);
- this.setVertexIndices(this._geom.verticesIndices);
-
- if (this.addVertexNumbers) this._setVertexNumbers();
-
- const geomAttribs = this._geom.getAttributes();
-
- const attribAssoc = {
- "texCoords": CONSTANTS.SHADER.SHADERVAR_VERTEX_TEXCOORD,
- "vertexNormals": CONSTANTS.SHADER.SHADERVAR_VERTEX_NORMAL,
- "vertexColors": CONSTANTS.SHADER.SHADERVAR_VERTEX_COLOR,
- "tangents": "attrTangent",
- "biTangents": "attrBiTangent",
- };
-
- for (const index in geomAttribs)
- if (geomAttribs[index].data && geomAttribs[index].data.length)
- this.setAttribute(attribAssoc[index] || index, geomAttribs[index].data, geomAttribs[index].itemSize);
-
-
- if (removeRef)
- {
- this._geom = null;
- }
- };
-
- Mesh.prototype._preBind = function (shader)
- {
- for (let i = 0; i < this._attributes.length; i++)
- if (this._attributes[i].cb)
- this._attributes[i].cb(this._attributes[i], this._geom, shader);
- };
-
- Mesh.prototype._checkAttrLengths = function ()
- {
- if (this.memFreed) return;
- // check length
- for (let i = 0; i < this._attributes.length; i++)
- {
- if (this._attributes[i].arrayLength / this._attributes[i].itemSize < this._attributes[0].arrayLength / this._attributes[0].itemSize)
- {
- let name = "unknown";
- if (this._geom)name = this._geom.name;
- // this._log.warn(
- // name + ": " + this._attributes[i].name +
- // " wrong attr length. is:", this._attributes[i].arrayLength / this._attributes[i].itemSize,
- // " should be:", this._attributes[0].arrayLength / this._attributes[0].itemSize,
- // );
- }
- }
- };
-
- Mesh.prototype._bind = function (shader)
- {
- if (!shader.isValid()) return;
-
- let attrLocs = [];
- if (this._attribLocs[shader.id]) attrLocs = this._attribLocs[shader.id];
- else this._attribLocs[shader.id] = attrLocs;
-
- this._lastShader = shader;
- if (shader.lastCompile > this._lastAttrUpdate || attrLocs.length != this._attributes.length)
- {
- this._lastAttrUpdate = shader.lastCompile;
- for (let i = 0; i < this._attributes.length; i++) attrLocs[i] = -1;
- }
-
- for (let i = 0; i < this._attributes.length; i++)
- {
- const attribute = this._attributes[i];
- if (attrLocs[i] == -1)
- {
- if (attribute._attrLocationLastShaderTime != shader.lastCompile)
- {
- attribute._attrLocationLastShaderTime = shader.lastCompile;
- attrLocs[i] = this._cgl.glGetAttribLocation(shader.getProgram(), attribute.name);
- // this._log.log('attribloc',attribute.name,attrLocs[i]);
- this._cgl.profileData.profileAttrLoc++;
- }
- }
-
- if (attrLocs[i] != -1)
- {
- this._cgl.gl.enableVertexAttribArray(attrLocs[i]);
- this._cgl.gl.bindBuffer(this._cgl.gl.ARRAY_BUFFER, attribute.buffer);
-
- if (attribute.instanced)
- {
- // todo: easier way to fill mat4 attribs...
- if (attribute.itemSize <= 4)
- {
- if (!attribute.itemSize || attribute.itemSize == 0) this._log.warn("instanced attrib itemsize error", this._geom.name, attribute);
-
- this._cgl.gl.vertexAttribPointer(attrLocs[i], attribute.itemSize, attribute.type, false, attribute.itemSize * 4, 0);
- this._cgl.gl.vertexAttribDivisor(attrLocs[i], 1);
- }
- else if (attribute.itemSize == 16)
- {
- const stride = 16 * 4;
-
- this._cgl.gl.vertexAttribPointer(attrLocs[i], 4, attribute.type, false, stride, 0);
- this._cgl.gl.enableVertexAttribArray(attrLocs[i] + 1);
- this._cgl.gl.vertexAttribPointer(attrLocs[i] + 1, 4, attribute.type, false, stride, 4 * 4 * 1);
- this._cgl.gl.enableVertexAttribArray(attrLocs[i] + 2);
- this._cgl.gl.vertexAttribPointer(attrLocs[i] + 2, 4, attribute.type, false, stride, 4 * 4 * 2);
- this._cgl.gl.enableVertexAttribArray(attrLocs[i] + 3);
- this._cgl.gl.vertexAttribPointer(attrLocs[i] + 3, 4, attribute.type, false, stride, 4 * 4 * 3);
-
- this._cgl.gl.vertexAttribDivisor(attrLocs[i], 1);
- this._cgl.gl.vertexAttribDivisor(attrLocs[i] + 1, 1);
- this._cgl.gl.vertexAttribDivisor(attrLocs[i] + 2, 1);
- this._cgl.gl.vertexAttribDivisor(attrLocs[i] + 3, 1);
- }
- else
- {
- this._log.warn("unknown instance attrib size", attribute.name);
- }
- }
- else
- {
- if (!attribute.itemSize || attribute.itemSize == 0) this._log.warn("attrib itemsize error", this._name, attribute);
- this._cgl.gl.vertexAttribPointer(attrLocs[i], attribute.itemSize, attribute.type, false, attribute.itemSize * 4, 0);
-
- if (attribute.pointer)
- {
- for (let ip = 0; ip < attribute.pointer.length; ip++)
- {
- const pointer = attribute.pointer[ip];
-
- if (pointer.loc == -1)
- pointer.loc = this._cgl.glGetAttribLocation(shader.getProgram(), pointer.name);
-
- this._cgl.profileData.profileAttrLoc++;
-
- this._cgl.gl.enableVertexAttribArray(pointer.loc);
- this._cgl.gl.vertexAttribPointer(pointer.loc, attribute.itemSize, attribute.type, false, pointer.stride, pointer.offset);
- }
- }
- if (this.bindFeedback) this.bindFeedback(attribute);
- }
- }
- }
-
- if (this._bufVerticesIndizes && this._bufVerticesIndizes.numItems !== 0) this._cgl.gl.bindBuffer(this._cgl.gl.ELEMENT_ARRAY_BUFFER, this._bufVerticesIndizes);
- };
-
- Mesh.prototype.unBind = function ()
- {
- const shader = this._lastShader;
- this._lastShader = null;
- if (!shader) return;
-
- let attrLocs = [];
- if (this._attribLocs[shader.id]) attrLocs = this._attribLocs[shader.id];
- else this._attribLocs[shader.id] = attrLocs;
-
- MESH.lastMesh = null;
-
- for (let i = 0; i < this._attributes.length; i++)
- {
- if (this._attributes[i].instanced)
- {
- // todo: easier way to fill mat4 attribs...
- if (this._attributes[i].itemSize <= 4)
- {
- if (attrLocs[i] != -1) this._cgl.gl.vertexAttribDivisor(attrLocs[i], 0);
- if (attrLocs[i] >= 0) this._cgl.gl.disableVertexAttribArray(attrLocs[i]);
- }
- else
- {
- this._cgl.gl.vertexAttribDivisor(attrLocs[i], 0);
- this._cgl.gl.vertexAttribDivisor(attrLocs[i] + 1, 0);
- this._cgl.gl.vertexAttribDivisor(attrLocs[i] + 2, 0);
- this._cgl.gl.vertexAttribDivisor(attrLocs[i] + 3, 0);
- this._cgl.gl.disableVertexAttribArray(attrLocs[i] + 1);
- this._cgl.gl.disableVertexAttribArray(attrLocs[i] + 2);
- this._cgl.gl.disableVertexAttribArray(attrLocs[i] + 3);
- }
- }
-
- if (attrLocs[i] != -1) this._cgl.gl.disableVertexAttribArray(attrLocs[i]);
- }
- };
-
- Mesh.prototype.meshChanged = function ()
- {
- return this._cgl.lastMesh && this._cgl.lastMesh != this;
- };
-
- Mesh.prototype.printDebug = function (shader)
- {
- console.log("--attributes");
- for (let i = 0; i < this._attributes.length; i++)
- {
- console.log("attribute " + i + " " + this._attributes[i].name);
- }
- };
-
- Mesh.prototype.setNumVertices = function (num)
- {
- this._bufVertexAttrib.numItems = num;
- };
-
- Mesh.prototype.getNumVertices = function ()
- {
- return this._bufVertexAttrib.numItems;
- };
-
-
- /**
- * @function render
- * @memberof Mesh
- * @instance
- * @description draw mesh to screen
- * @param {Shader} shader
- */
- Mesh.prototype.render = function (shader)
- {
- // TODO: enable/disablevertex only if the mesh has changed... think drawing 10000x the same mesh
-
- if (!shader || !shader.isValid() || this._cgl.aborted) return;
-
- this._checkAttrLengths();
-
- if (this._geom)
- {
- if (this._preWireframeGeom && !shader.wireframe && !this._geom.isIndexed())
- {
- this.setGeom(this._preWireframeGeom);
- this._preWireframeGeom = null;
- // console.log("remove prewireframe geom");
- }
-
- if (shader.wireframe)
- {
- let changed = false;
-
- if (this._geom.isIndexed())
- {
- if (!this._preWireframeGeom)
- {
- this._preWireframeGeom = this._geom;
- this._geom = this._geom.copy();
- }
-
- this._geom.unIndex();
- changed = true;
- }
-
- if (!this._geom.getAttribute("attrBarycentric"))
- {
- if (!this._preWireframeGeom)
- {
- this._preWireframeGeom = this._geom;
- this._geom = this._geom.copy();
- }
- changed = true;
-
- this._geom.calcBarycentric();
- }
- if (changed) this.setGeom(this._geom);
- }
- // if (shader.wireframe)
- // console.log(shader.wireframe, this._geom.isIndexed());
- }
-
- let needsBind = false;
- if (MESH.lastMesh != this)
- {
- if (MESH.lastMesh) MESH.lastMesh.unBind();
- needsBind = true;
- }
-
-
- // var needsBind=false;
- // {
- // needsBind=true;
- // }
- if (needsBind) this._preBind(shader);
-
- if (!shader.bind()) return;
-
- // if(needsBind)
- this._bind(shader);
- if (this.addVertexNumbers) this._setVertexNumbers();
-
- MESH.lastMesh = this;
-
- let prim = this._cgl.gl.TRIANGLES;
- if (this._glPrimitive !== undefined) prim = this._glPrimitive;
- if (shader.glPrimitive !== null) prim = shader.glPrimitive;
-
- let elementDiv = 1;
- let doQuery = this._cgl.profileData.doProfileGlQuery;
- let queryStarted = false;
- if (doQuery)
- {
- let id = this._name + " - " + shader.getName() + " #" + shader.id;
- if (this._numInstances) id += " instanced " + this._numInstances + "x";
-
- let queryProfilerData = this._cgl.profileData.glQueryData[id];
-
- if (!queryProfilerData) queryProfilerData = { "id": id, "num": 0 };
-
- if (shader.opId)queryProfilerData.shaderOp = shader.opId;
- if (this.opId)queryProfilerData.meshOp = this.opId;
-
- this._cgl.profileData.glQueryData[id] = queryProfilerData;
-
- if (!this._queryExt && this._queryExt !== false) this._queryExt = this._cgl.enableExtension("EXT_disjoint_timer_query_webgl2") || false;
- if (this._queryExt)
- {
- if (queryProfilerData._drawQuery)
- {
- const available = this._cgl.gl.getQueryParameter(queryProfilerData._drawQuery, this._cgl.gl.QUERY_RESULT_AVAILABLE);
- if (available)
- {
- const elapsedNanos = this._cgl.gl.getQueryParameter(queryProfilerData._drawQuery, this._cgl.gl.QUERY_RESULT);
- const currentTimeGPU = elapsedNanos / 1000000;
-
- queryProfilerData._times = queryProfilerData._times || 0;
- queryProfilerData._times += currentTimeGPU;
- queryProfilerData._numcount++;
- queryProfilerData.when = performance.now();
- queryProfilerData._drawQuery = null;
- queryProfilerData.queryStarted = false;
- }
- }
-
- if (!queryProfilerData.queryStarted)
- {
- queryProfilerData._drawQuery = this._cgl.gl.createQuery();
- this._cgl.gl.beginQuery(this._queryExt.TIME_ELAPSED_EXT, queryProfilerData._drawQuery);
- queryStarted = queryProfilerData.queryStarted = true;
- }
- }
- }
-
-
- if (this.hasFeedbacks && this.hasFeedbacks()) this.drawFeedbacks(shader, prim);
- else if (!this._bufVerticesIndizes || this._bufVerticesIndizes.numItems === 0)
- {
- // for (let i = 0; i < this._attributes.length; i++)
- // {
- // if (this._attributes[i].arrayLength / this._attributes[i].itemSize != this._bufVertexAttrib.floatArray.length / 3)
- // {
- // this._log.warn("attrib buffer length wrong! ", this._attributes[i].name, this._attributes[i].arrayLength / this._attributes[i].itemSize, this._bufVertexAttrib.floatArray.length / 3, this._attributes[i].itemSize);
- // // this._log.log(this);
- // // debugger;
- // return;
- // }
- // }
-
-
- if (prim == this._cgl.gl.TRIANGLES)elementDiv = 3;
- if (this._numInstances === 0) this._cgl.gl.drawArrays(prim, this._bufVertexAttrib.startItem, this._bufVertexAttrib.numItems - this._bufVertexAttrib.startItem);
- else this._cgl.gl.drawArraysInstanced(prim, this._bufVertexAttrib.startItem, this._bufVertexAttrib.numItems, this._numInstances);
- }
- else
- {
- if (prim == this._cgl.gl.TRIANGLES)elementDiv = 3;
- if (this._numInstances === 0)
- {
- // console.log("la", this._bufVerticesIndizes.numItems);
-
- this._cgl.gl.drawElements(prim, this._bufVerticesIndizes.numItems, this._indexType, 0);
- }
- else
- {
- this._cgl.gl.drawElementsInstanced(prim, this._bufVerticesIndizes.numItems, this._indexType, 0, this._numInstances);
- }
- }
-
- if (this._cgl.debugOneFrame && this._cgl.gl.getError() != this._cgl.gl.NO_ERROR)
- {
- this._log.error("mesh draw gl error");
- this._log.error("mesh", this);
- this._log.error("shader", shader);
-
- const attribNames = [];
- for (let i = 0; i < this._cgl.gl.getProgramParameter(shader.getProgram(), this._cgl.gl.ACTIVE_ATTRIBUTES); i++)
- {
- const name = this._cgl.gl.getActiveAttrib(shader.getProgram(), i).name;
- this._log.error("attrib ", name);
- }
- }
-
- this._cgl.profileData.profileMeshNumElements += (this._bufVertexAttrib.numItems / elementDiv) * (this._numInstances || 1);
- this._cgl.profileData.profileMeshDraw++;
-
- if (doQuery && queryStarted)
- {
- this._cgl.gl.endQuery(this._queryExt.TIME_ELAPSED_EXT);
- }
-
- this._cgl.printError("mesh render " + this._name);
-
- this.unBind();
- };
-
- Mesh.prototype.setNumInstances = function (n)
- {
- n = Math.max(0, n);
- if (this._numInstances != n)
- {
- this._numInstances = n;
- const indexArr = new Float32Array(n);
- for (let i = 0; i < n; i++) indexArr[i] = i;
- this.setAttribute(CONSTANTS.SHADER.SHADERVAR_INSTANCE_INDEX, indexArr, 1, { "instanced": true });
- }
- };
-
- Mesh.prototype._disposeAttributes = function ()
- {
- if (!this._attributes) return;
-
- for (let i = 0; i < this._attributes.length; i++)
- {
- if (this._attributes[i].buffer)
- {
- this._cgl.gl.deleteBuffer(this._attributes[i].buffer);
- this._attributes[i].buffer = null;
- }
- }
- this._attributes.length = 0;
- };
-
- Mesh.prototype.dispose = function ()
- {
- if (this._bufVertexAttrib && this._bufVertexAttrib.buffer) this._cgl.gl.deleteBuffer(this._bufVertexAttrib.buffer);
- if (this._bufVerticesIndizes) this._cgl.gl.deleteBuffer(this._bufVerticesIndizes);
- this._bufVerticesIndizes = null;
-
- this._disposeAttributes();
- };
-
-
-
- export { Mesh, MESH };