mirror of
https://github.com/pissang/claygl.git
synced 2026-02-01 17:27:08 +00:00
fix: buffers not updated when geometry is shared by multiple context.
This commit is contained in:
parent
4a6fdb8898
commit
8b21e6f5a2
@ -83,11 +83,6 @@ export class GeometryAttribute<TSize extends AttributeSize = AttributeSize> {
|
||||
*/
|
||||
semantic?: AttributeSemantic;
|
||||
|
||||
/**
|
||||
* If attributes needs update buffer
|
||||
*/
|
||||
__dirty?: boolean = true;
|
||||
|
||||
/**
|
||||
* Value of the attribute.
|
||||
*/
|
||||
@ -255,6 +250,7 @@ class GeometryBase {
|
||||
|
||||
private _attributeList: string[];
|
||||
private _enabledAttributes?: string[];
|
||||
private _attributesUploaded: Record<string, boolean> = {};
|
||||
|
||||
__indicesDirty: boolean = true;
|
||||
|
||||
@ -288,10 +284,7 @@ class GeometryBase {
|
||||
* Usually called after you change the data in attributes.
|
||||
*/
|
||||
dirty() {
|
||||
const enabledAttributes = this.getEnabledAttributes();
|
||||
for (let i = 0; i < enabledAttributes.length; i++) {
|
||||
this.dirtyAttribute(enabledAttributes[i]);
|
||||
}
|
||||
this._attributesUploaded = {};
|
||||
this.dirtyIndices();
|
||||
this._enabledAttributes = undefined;
|
||||
}
|
||||
@ -306,8 +299,7 @@ class GeometryBase {
|
||||
* @param {string} [attrName]
|
||||
*/
|
||||
dirtyAttribute(attrName: string) {
|
||||
const attr = this.attributes[attrName];
|
||||
attr && (attr.__dirty = true);
|
||||
this._attributesUploaded[attrName] = false;
|
||||
}
|
||||
/**
|
||||
* Is any of attributes dirty.
|
||||
@ -318,12 +310,23 @@ class GeometryBase {
|
||||
}
|
||||
const enabledAttributes = this.getEnabledAttributes();
|
||||
for (let i = 0; i < enabledAttributes.length; i++) {
|
||||
if (this.attributes[enabledAttributes[i]].__dirty) {
|
||||
if (this.isAttributeDirty(enabledAttributes[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
isAttributeDirty(attrName: string) {
|
||||
return !this._attributesUploaded[attrName];
|
||||
}
|
||||
|
||||
// Mark this attribute has been uploaded to GPU.
|
||||
// Used internal
|
||||
__markAttributeUploaded(attrName: string) {
|
||||
this._attributesUploaded[attrName] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get indices of triangle at given index.
|
||||
* @param {number} idx
|
||||
|
||||
@ -79,26 +79,26 @@ class GLBuffers {
|
||||
let k;
|
||||
// FIXME If some attributes removed
|
||||
for (k = 0; k < attributeList.length; k++) {
|
||||
const name = attributeList[k];
|
||||
const attribute = geometry.attributes[name];
|
||||
const attrName = attributeList[k];
|
||||
const attribute = geometry.attributes[attrName];
|
||||
|
||||
const existsBufferInfo = attributeBufferMap[name];
|
||||
const existsBufferInfo = attributeBufferMap[attrName];
|
||||
let buffer: WebGLBuffer;
|
||||
if (existsBufferInfo) {
|
||||
buffer = existsBufferInfo.buffer;
|
||||
} else {
|
||||
buffer = gl.createBuffer()!;
|
||||
}
|
||||
if (attribute.__dirty) {
|
||||
if (geometry.isAttributeDirty(attrName)) {
|
||||
// Only update when they are dirty.
|
||||
// TODO: Use BufferSubData?
|
||||
gl.bindBuffer(constants.ARRAY_BUFFER, buffer);
|
||||
gl.bufferData(constants.ARRAY_BUFFER, attribute.value as Float32Array, DRAW);
|
||||
attribute.__dirty = false;
|
||||
geometry.__markAttributeUploaded(attrName);
|
||||
}
|
||||
|
||||
attributeBuffers[k] = new GLAttributeBuffer(
|
||||
name,
|
||||
attrName,
|
||||
attribute.type,
|
||||
buffer,
|
||||
attribute.size,
|
||||
@ -208,19 +208,15 @@ class GLBuffers {
|
||||
dispose(gl: WebGLRenderingContext) {
|
||||
const attributeBuffers = this._attrbBuffs;
|
||||
const indicesBuffer = this._idxBuff;
|
||||
|
||||
attributeBuffers && attributeBuffers.forEach((buffer) => gl.deleteBuffer(buffer.buffer));
|
||||
|
||||
if (indicesBuffer) {
|
||||
gl.deleteBuffer(indicesBuffer.buffer);
|
||||
}
|
||||
|
||||
const vao = this._vao;
|
||||
const vaoExt = this._vaoExt;
|
||||
if (vaoExt && vao && vao.vao) {
|
||||
vaoExt.deleteVertexArrayOES(vao.vao);
|
||||
}
|
||||
|
||||
this._attrbBuffs = [];
|
||||
this._idxBuff = undefined;
|
||||
}
|
||||
|
||||
@ -421,6 +421,9 @@ class GLRenderer {
|
||||
const glBuffersMap = this._glBuffersMap;
|
||||
let buffers = glBuffersMap.get(geometry);
|
||||
if (!buffers) {
|
||||
// Force mark geometry to be dirty
|
||||
// In case this geometry is used by multiple gl context.
|
||||
geometry.dirty();
|
||||
buffers = new GLBuffers(geometry);
|
||||
glBuffersMap.set(geometry, buffers);
|
||||
}
|
||||
@ -555,6 +558,9 @@ class GLRenderer {
|
||||
const instancedBufferMap = this._glInstancedBufferMap;
|
||||
let buffer = instancedBufferMap.get(renderable as InstancedMesh);
|
||||
if (!buffer) {
|
||||
// Force mark renderable to be dirty if its a new created buffer.
|
||||
// In case the object is used by multiple gl context.
|
||||
renderable.__dirty = true;
|
||||
buffer = new GLInstancedBuffers(renderable as InstancedMesh);
|
||||
instancedBufferMap.set(renderable as InstancedMesh, buffer);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user