174 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			174 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								import DataMap from './DataMap.js';
							 | 
						||
| 
								 | 
							
								import { AttributeType } from './Constants.js';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Bindings extends DataMap {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									constructor( backend, nodes, textures, attributes, pipelines, info ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										super();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.backend = backend;
							 | 
						||
| 
								 | 
							
										this.textures = textures;
							 | 
						||
| 
								 | 
							
										this.pipelines = pipelines;
							 | 
						||
| 
								 | 
							
										this.attributes = attributes;
							 | 
						||
| 
								 | 
							
										this.nodes = nodes;
							 | 
						||
| 
								 | 
							
										this.info = info;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.pipelines.bindings = this; // assign bindings to pipelines
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									getForRender( renderObject ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const bindings = renderObject.getBindings();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const data = this.get( renderObject );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( data.bindings !== bindings ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											// each object defines an array of bindings (ubos, textures, samplers etc.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											data.bindings = bindings;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											this._init( bindings );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											this.backend.createBindings( bindings );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return data.bindings;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									getForCompute( computeNode ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const data = this.get( computeNode );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( data.bindings === undefined ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											const nodeBuilderState = this.nodes.getForCompute( computeNode );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											const bindings = nodeBuilderState.bindings;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											data.bindings = bindings;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											this._init( bindings );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											this.backend.createBindings( bindings );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return data.bindings;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									updateForCompute( computeNode ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this._update( computeNode, this.getForCompute( computeNode ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									updateForRender( renderObject ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this._update( renderObject, this.getForRender( renderObject ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									_init( bindings ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for ( const binding of bindings ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( binding.isSampledTexture ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												this.textures.updateTexture( binding.texture );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											} else if ( binding.isStorageBuffer ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												const attribute = binding.attribute;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												this.attributes.update( attribute, AttributeType.STORAGE );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									_update( object, bindings ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const { backend } = this;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										let needsBindingsUpdate = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// iterate over all bindings and check if buffer updates or a new binding group is required
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for ( const binding of bindings ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( binding.isNodeUniformsGroup ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												const updated = this.nodes.updateGroup( binding );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( ! updated ) continue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( binding.isUniformBuffer ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												const updated = binding.update();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( updated ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													backend.updateBinding( binding );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											} else if ( binding.isSampledTexture ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												const texture = binding.texture;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( binding.needsBindingsUpdate ) needsBindingsUpdate = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												const updated = binding.update();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( updated ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													this.textures.updateTexture( binding.texture );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if ( texture.isStorageTexture === true ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													const textureData = this.get( texture );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													if ( binding.store === true ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
														textureData.needsMipmap = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													} else if ( texture.generateMipmaps === true && this.textures.needsMipmaps( texture ) && textureData.needsMipmap === true ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
														this.backend.generateMipmaps( texture );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
														textureData.needsMipmap = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( needsBindingsUpdate === true ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											const pipeline = this.pipelines.getForRender( object );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											this.backend.updateBindings( bindings, pipeline );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default Bindings;
							 |