|
@@ -152,6 +152,9 @@ var BABYLON;
|
|
|
this._activeTexturesCache = new Array(this._maxTextureChannels);
|
|
|
this._compiledEffects = {};
|
|
|
this._uintIndicesCurrentlySet = false;
|
|
|
+ this._currentBoundBuffer = new Array();
|
|
|
+ this._currentInstanceLocations = new Array();
|
|
|
+ this._currentInstanceBuffers = new Array();
|
|
|
this._renderingCanvas = canvas;
|
|
|
this._externalData = new BABYLON.StringDictionary();
|
|
|
options = options || {};
|
|
@@ -699,12 +702,12 @@ var BABYLON;
|
|
|
};
|
|
|
// VBOs
|
|
|
Engine.prototype._resetVertexBufferBinding = function () {
|
|
|
- this._gl.bindBuffer(this._gl.ARRAY_BUFFER, null);
|
|
|
+ this.bindBuffer(null, this._gl.ARRAY_BUFFER);
|
|
|
this._cachedVertexBuffers = null;
|
|
|
};
|
|
|
Engine.prototype.createVertexBuffer = function (vertices) {
|
|
|
var vbo = this._gl.createBuffer();
|
|
|
- this._gl.bindBuffer(this._gl.ARRAY_BUFFER, vbo);
|
|
|
+ this.bindBuffer(vbo, this._gl.ARRAY_BUFFER);
|
|
|
if (vertices instanceof Float32Array) {
|
|
|
this._gl.bufferData(this._gl.ARRAY_BUFFER, vertices, this._gl.STATIC_DRAW);
|
|
|
}
|
|
@@ -715,34 +718,49 @@ var BABYLON;
|
|
|
vbo.references = 1;
|
|
|
return vbo;
|
|
|
};
|
|
|
- Engine.prototype.createDynamicVertexBuffer = function (capacity) {
|
|
|
+ Engine.prototype.createDynamicVertexBuffer = function (vertices) {
|
|
|
var vbo = this._gl.createBuffer();
|
|
|
- this._gl.bindBuffer(this._gl.ARRAY_BUFFER, vbo);
|
|
|
- this._gl.bufferData(this._gl.ARRAY_BUFFER, capacity, this._gl.DYNAMIC_DRAW);
|
|
|
+ this.bindBuffer(vbo, this._gl.ARRAY_BUFFER);
|
|
|
+ if (vertices instanceof Float32Array) {
|
|
|
+ this._gl.bufferData(this._gl.ARRAY_BUFFER, vertices, this._gl.DYNAMIC_DRAW);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(vertices), this._gl.DYNAMIC_DRAW);
|
|
|
+ }
|
|
|
this._resetVertexBufferBinding();
|
|
|
vbo.references = 1;
|
|
|
return vbo;
|
|
|
};
|
|
|
- Engine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, vertices, offset) {
|
|
|
- this._gl.bindBuffer(this._gl.ARRAY_BUFFER, vertexBuffer);
|
|
|
+ Engine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, vertices, offset, count) {
|
|
|
+ this.bindBuffer(vertexBuffer, this._gl.ARRAY_BUFFER);
|
|
|
if (offset === undefined) {
|
|
|
offset = 0;
|
|
|
}
|
|
|
- if (vertices instanceof Float32Array) {
|
|
|
- this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, vertices);
|
|
|
+ if (count === undefined) {
|
|
|
+ if (vertices instanceof Float32Array) {
|
|
|
+ this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, vertices);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, new Float32Array(vertices));
|
|
|
+ }
|
|
|
}
|
|
|
else {
|
|
|
- this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, new Float32Array(vertices));
|
|
|
+ if (vertices instanceof Float32Array) {
|
|
|
+ this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, vertices.subarray(offset, offset + count));
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, new Float32Array(vertices).subarray(offset, offset + count));
|
|
|
+ }
|
|
|
}
|
|
|
this._resetVertexBufferBinding();
|
|
|
};
|
|
|
Engine.prototype._resetIndexBufferBinding = function () {
|
|
|
- this._gl.bindBuffer(this._gl.ELEMENT_ARRAY_BUFFER, null);
|
|
|
+ this.bindBuffer(null, this._gl.ELEMENT_ARRAY_BUFFER);
|
|
|
this._cachedIndexBuffer = null;
|
|
|
};
|
|
|
Engine.prototype.createIndexBuffer = function (indices) {
|
|
|
var vbo = this._gl.createBuffer();
|
|
|
- this._gl.bindBuffer(this._gl.ELEMENT_ARRAY_BUFFER, vbo);
|
|
|
+ this.bindBuffer(vbo, this._gl.ELEMENT_ARRAY_BUFFER);
|
|
|
// Check for 32 bits indices
|
|
|
var arrayBuffer;
|
|
|
var need32Bits = false;
|
|
@@ -764,11 +782,17 @@ var BABYLON;
|
|
|
vbo.is32Bits = need32Bits;
|
|
|
return vbo;
|
|
|
};
|
|
|
- Engine.prototype.bindBuffers = function (vertexBuffer, indexBuffer, vertexDeclaration, vertexStrideSize, effect) {
|
|
|
+ Engine.prototype.bindBuffer = function (buffer, target) {
|
|
|
+ if (this._currentBoundBuffer[target] !== buffer) {
|
|
|
+ this._gl.bindBuffer(target, buffer);
|
|
|
+ this._currentBoundBuffer[target] = buffer;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ Engine.prototype.bindBuffersDirectly = function (vertexBuffer, indexBuffer, vertexDeclaration, vertexStrideSize, effect) {
|
|
|
if (this._cachedVertexBuffers !== vertexBuffer || this._cachedEffectForVertexBuffers !== effect) {
|
|
|
this._cachedVertexBuffers = vertexBuffer;
|
|
|
this._cachedEffectForVertexBuffers = effect;
|
|
|
- this._gl.bindBuffer(this._gl.ARRAY_BUFFER, vertexBuffer);
|
|
|
+ this.bindBuffer(vertexBuffer, this._gl.ARRAY_BUFFER);
|
|
|
var offset = 0;
|
|
|
for (var index = 0; index < vertexDeclaration.length; index++) {
|
|
|
var order = effect.getAttributeLocation(index);
|
|
@@ -780,11 +804,11 @@ var BABYLON;
|
|
|
}
|
|
|
if (this._cachedIndexBuffer !== indexBuffer) {
|
|
|
this._cachedIndexBuffer = indexBuffer;
|
|
|
- this._gl.bindBuffer(this._gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
|
|
+ this.bindBuffer(indexBuffer, this._gl.ELEMENT_ARRAY_BUFFER);
|
|
|
this._uintIndicesCurrentlySet = indexBuffer.is32Bits;
|
|
|
}
|
|
|
};
|
|
|
- Engine.prototype.bindMultiBuffers = function (vertexBuffers, indexBuffer, effect) {
|
|
|
+ Engine.prototype.bindBuffers = function (vertexBuffers, indexBuffer, effect) {
|
|
|
if (this._cachedVertexBuffers !== vertexBuffers || this._cachedEffectForVertexBuffers !== effect) {
|
|
|
this._cachedVertexBuffers = vertexBuffers;
|
|
|
this._cachedEffectForVertexBuffers = effect;
|
|
@@ -796,18 +820,37 @@ var BABYLON;
|
|
|
if (!vertexBuffer) {
|
|
|
continue;
|
|
|
}
|
|
|
- var stride = vertexBuffer.getStrideSize();
|
|
|
- this._gl.bindBuffer(this._gl.ARRAY_BUFFER, vertexBuffer.getBuffer());
|
|
|
- this._gl.vertexAttribPointer(order, stride, this._gl.FLOAT, false, stride * 4, 0);
|
|
|
+ var buffer = vertexBuffer.getBuffer();
|
|
|
+ this.bindBuffer(buffer, this._gl.ARRAY_BUFFER);
|
|
|
+ this._gl.vertexAttribPointer(order, vertexBuffer.getSize(), this._gl.FLOAT, false, vertexBuffer.getStrideSize() * 4, vertexBuffer.getOffset() * 4);
|
|
|
+ if (vertexBuffer.getIsInstanced()) {
|
|
|
+ this._caps.instancedArrays.vertexAttribDivisorANGLE(order, 1);
|
|
|
+ this._currentInstanceLocations.push(order);
|
|
|
+ this._currentInstanceBuffers.push(buffer);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (indexBuffer != null && this._cachedIndexBuffer !== indexBuffer) {
|
|
|
this._cachedIndexBuffer = indexBuffer;
|
|
|
- this._gl.bindBuffer(this._gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
|
|
+ this.bindBuffer(indexBuffer, this._gl.ELEMENT_ARRAY_BUFFER);
|
|
|
this._uintIndicesCurrentlySet = indexBuffer.is32Bits;
|
|
|
}
|
|
|
};
|
|
|
+ Engine.prototype.unbindInstanceAttributes = function () {
|
|
|
+ var boundBuffer;
|
|
|
+ for (var i = 0, ul = this._currentInstanceLocations.length; i < ul; i++) {
|
|
|
+ var instancesBuffer = this._currentInstanceBuffers[i];
|
|
|
+ if (boundBuffer != instancesBuffer) {
|
|
|
+ boundBuffer = instancesBuffer;
|
|
|
+ this.bindBuffer(instancesBuffer, this._gl.ARRAY_BUFFER);
|
|
|
+ }
|
|
|
+ var offsetLocation = this._currentInstanceLocations[i];
|
|
|
+ this._caps.instancedArrays.vertexAttribDivisorANGLE(offsetLocation, 0);
|
|
|
+ }
|
|
|
+ this._currentInstanceBuffers.length = 0;
|
|
|
+ this._currentInstanceLocations.length = 0;
|
|
|
+ };
|
|
|
Engine.prototype._releaseBuffer = function (buffer) {
|
|
|
buffer.references--;
|
|
|
if (buffer.references === 0) {
|
|
@@ -819,7 +862,7 @@ var BABYLON;
|
|
|
Engine.prototype.createInstancesBuffer = function (capacity) {
|
|
|
var buffer = this._gl.createBuffer();
|
|
|
buffer.capacity = capacity;
|
|
|
- this._gl.bindBuffer(this._gl.ARRAY_BUFFER, buffer);
|
|
|
+ this.bindBuffer(buffer, this._gl.ARRAY_BUFFER);
|
|
|
this._gl.bufferData(this._gl.ARRAY_BUFFER, capacity, this._gl.DYNAMIC_DRAW);
|
|
|
return buffer;
|
|
|
};
|
|
@@ -827,7 +870,7 @@ var BABYLON;
|
|
|
this._gl.deleteBuffer(buffer);
|
|
|
};
|
|
|
Engine.prototype.updateAndBindInstancesBuffer = function (instancesBuffer, data, offsetLocations) {
|
|
|
- this._gl.bindBuffer(this._gl.ARRAY_BUFFER, instancesBuffer);
|
|
|
+ this.bindBuffer(instancesBuffer, this._gl.ARRAY_BUFFER);
|
|
|
if (data) {
|
|
|
this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);
|
|
|
}
|
|
@@ -842,6 +885,8 @@ var BABYLON;
|
|
|
this._gl.enableVertexAttribArray(ai.index);
|
|
|
this._gl.vertexAttribPointer(ai.index, ai.attributeSize, ai.attribyteType || this._gl.FLOAT, ai.normalized || false, stride, ai.offset);
|
|
|
this._caps.instancedArrays.vertexAttribDivisorANGLE(ai.index, 1);
|
|
|
+ this._currentInstanceLocations.push(ai.index);
|
|
|
+ this._currentInstanceBuffers.push(instancesBuffer);
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
@@ -850,23 +895,8 @@ var BABYLON;
|
|
|
this._gl.enableVertexAttribArray(offsetLocation);
|
|
|
this._gl.vertexAttribPointer(offsetLocation, 4, this._gl.FLOAT, false, 64, index * 16);
|
|
|
this._caps.instancedArrays.vertexAttribDivisorANGLE(offsetLocation, 1);
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
- Engine.prototype.unBindInstancesBuffer = function (instancesBuffer, offsetLocations) {
|
|
|
- this._gl.bindBuffer(this._gl.ARRAY_BUFFER, instancesBuffer);
|
|
|
- if (offsetLocations[0].index !== undefined) {
|
|
|
- for (var i = 0; i < offsetLocations.length; i++) {
|
|
|
- var ai = offsetLocations[i];
|
|
|
- this._gl.disableVertexAttribArray(ai.index);
|
|
|
- this._caps.instancedArrays.vertexAttribDivisorANGLE(ai.index, 0);
|
|
|
- }
|
|
|
- }
|
|
|
- else {
|
|
|
- for (var index = 0; index < 4; index++) {
|
|
|
- var offsetLocation = offsetLocations[index];
|
|
|
- this._gl.disableVertexAttribArray(offsetLocation);
|
|
|
- this._caps.instancedArrays.vertexAttribDivisorANGLE(offsetLocation, 0);
|
|
|
+ this._currentInstanceLocations.push(offsetLocation);
|
|
|
+ this._currentInstanceBuffers.push(instancesBuffer);
|
|
|
}
|
|
|
}
|
|
|
};
|
|
@@ -981,25 +1011,33 @@ var BABYLON;
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
- this._vertexAttribArrays = this._vertexAttribArrays || [];
|
|
|
+ this._vertexAttribArraysToUse = this._vertexAttribArraysToUse || [];
|
|
|
+ this._vertexAttribArraysEnabled = this._vertexAttribArraysEnabled || [];
|
|
|
// Use program
|
|
|
this._gl.useProgram(effect.getProgram());
|
|
|
- for (var i in this._vertexAttribArrays) {
|
|
|
- //make sure this is a number)
|
|
|
- var iAsNumber = +i;
|
|
|
- if (iAsNumber > this._gl.VERTEX_ATTRIB_ARRAY_ENABLED || !this._vertexAttribArrays[iAsNumber]) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- this._vertexAttribArrays[iAsNumber] = false;
|
|
|
- this._gl.disableVertexAttribArray(iAsNumber);
|
|
|
+ var i, ul;
|
|
|
+ for (i = 0, ul = this._vertexAttribArraysToUse.length; i < ul; i++) {
|
|
|
+ this._vertexAttribArraysToUse[i] = false;
|
|
|
}
|
|
|
var attributesCount = effect.getAttributesCount();
|
|
|
- for (var index = 0; index < attributesCount; index++) {
|
|
|
+ for (i = 0; i < attributesCount; i++) {
|
|
|
// Attributes
|
|
|
- var order = effect.getAttributeLocation(index);
|
|
|
+ var order = effect.getAttributeLocation(i);
|
|
|
if (order >= 0) {
|
|
|
- this._vertexAttribArrays[order] = true;
|
|
|
- this._gl.enableVertexAttribArray(order);
|
|
|
+ this._vertexAttribArraysToUse[order] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (i = 0, ul = this._vertexAttribArraysEnabled.length; i < ul; i++) {
|
|
|
+ if (i > this._gl.VERTEX_ATTRIB_ARRAY_ENABLED || !this._vertexAttribArraysEnabled[i] || this._vertexAttribArraysToUse[i]) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ this._vertexAttribArraysEnabled[i] = false;
|
|
|
+ this._gl.disableVertexAttribArray(i);
|
|
|
+ }
|
|
|
+ for (i = 0, ul = this._vertexAttribArraysToUse.length; i < ul; i++) {
|
|
|
+ if (this._vertexAttribArraysToUse[i] && !this._vertexAttribArraysEnabled[i]) {
|
|
|
+ this._vertexAttribArraysEnabled[i] = true;
|
|
|
+ this._gl.enableVertexAttribArray(i);
|
|
|
}
|
|
|
}
|
|
|
this._currentEffect = effect;
|
|
@@ -1930,13 +1968,13 @@ var BABYLON;
|
|
|
this._gl.deleteProgram(this._compiledEffects[name]._program);
|
|
|
}
|
|
|
// Unbind
|
|
|
- for (var i in this._vertexAttribArrays) {
|
|
|
- //making sure this is a string
|
|
|
- var iAsNumber = +i;
|
|
|
- if (iAsNumber > this._gl.VERTEX_ATTRIB_ARRAY_ENABLED || !this._vertexAttribArrays[iAsNumber]) {
|
|
|
- continue;
|
|
|
+ if (this._vertexAttribArraysEnabled) {
|
|
|
+ for (var i = 0, ul = this._vertexAttribArraysEnabled.length; i < ul; i++) {
|
|
|
+ if (i > this._gl.VERTEX_ATTRIB_ARRAY_ENABLED || !this._vertexAttribArraysEnabled[i]) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ this._gl.disableVertexAttribArray(i);
|
|
|
}
|
|
|
- this._gl.disableVertexAttribArray(iAsNumber);
|
|
|
}
|
|
|
this._gl = null;
|
|
|
// Events
|