|
@@ -25,6 +25,7 @@ import { Vector4 } from '../math/Vector4.js';
|
|
import { WebGLAnimation } from './webgl/WebGLAnimation.js';
|
|
import { WebGLAnimation } from './webgl/WebGLAnimation.js';
|
|
import { WebGLAttributes } from './webgl/WebGLAttributes.js';
|
|
import { WebGLAttributes } from './webgl/WebGLAttributes.js';
|
|
import { WebGLBackground } from './webgl/WebGLBackground.js';
|
|
import { WebGLBackground } from './webgl/WebGLBackground.js';
|
|
|
|
+import { WebGLBindingStates } from './webgl/WebGLBindingStates.js';
|
|
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer.js';
|
|
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer.js';
|
|
import { WebGLCapabilities } from './webgl/WebGLCapabilities.js';
|
|
import { WebGLCapabilities } from './webgl/WebGLCapabilities.js';
|
|
import { WebGLClipping } from './webgl/WebGLClipping.js';
|
|
import { WebGLClipping } from './webgl/WebGLClipping.js';
|
|
@@ -130,14 +131,6 @@ function WebGLRenderer( parameters ) {
|
|
let _currentFramebuffer = null;
|
|
let _currentFramebuffer = null;
|
|
let _currentMaterialId = - 1;
|
|
let _currentMaterialId = - 1;
|
|
|
|
|
|
- // geometry and program caching
|
|
|
|
-
|
|
|
|
- const _currentGeometryProgram = {
|
|
|
|
- geometry: null,
|
|
|
|
- program: null,
|
|
|
|
- wireframe: false
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
let _currentCamera = null;
|
|
let _currentCamera = null;
|
|
let _currentArrayCamera = null;
|
|
let _currentArrayCamera = null;
|
|
|
|
|
|
@@ -271,7 +264,7 @@ function WebGLRenderer( parameters ) {
|
|
|
|
|
|
let background, morphtargets, bufferRenderer, indexedBufferRenderer;
|
|
let background, morphtargets, bufferRenderer, indexedBufferRenderer;
|
|
|
|
|
|
- let utils;
|
|
|
|
|
|
+ let utils, bindingStates;
|
|
|
|
|
|
function initGLContext() {
|
|
function initGLContext() {
|
|
|
|
|
|
@@ -287,6 +280,7 @@ function WebGLRenderer( parameters ) {
|
|
extensions.get( 'OES_texture_half_float_linear' );
|
|
extensions.get( 'OES_texture_half_float_linear' );
|
|
extensions.get( 'OES_standard_derivatives' );
|
|
extensions.get( 'OES_standard_derivatives' );
|
|
extensions.get( 'OES_element_index_uint' );
|
|
extensions.get( 'OES_element_index_uint' );
|
|
|
|
+ extensions.get( 'OES_vertex_array_object' );
|
|
extensions.get( 'ANGLE_instanced_arrays' );
|
|
extensions.get( 'ANGLE_instanced_arrays' );
|
|
|
|
|
|
}
|
|
}
|
|
@@ -303,10 +297,11 @@ function WebGLRenderer( parameters ) {
|
|
properties = new WebGLProperties();
|
|
properties = new WebGLProperties();
|
|
textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info );
|
|
textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info );
|
|
attributes = new WebGLAttributes( _gl, capabilities );
|
|
attributes = new WebGLAttributes( _gl, capabilities );
|
|
- geometries = new WebGLGeometries( _gl, attributes, info );
|
|
|
|
|
|
+ bindingStates = new WebGLBindingStates( _gl, extensions, attributes, capabilities );
|
|
|
|
+ geometries = new WebGLGeometries( _gl, attributes, info, bindingStates );
|
|
objects = new WebGLObjects( _gl, geometries, attributes, info );
|
|
objects = new WebGLObjects( _gl, geometries, attributes, info );
|
|
morphtargets = new WebGLMorphtargets( _gl );
|
|
morphtargets = new WebGLMorphtargets( _gl );
|
|
- programCache = new WebGLPrograms( _this, extensions, capabilities );
|
|
|
|
|
|
+ programCache = new WebGLPrograms( _this, extensions, capabilities, bindingStates );
|
|
materials = new WebGLMaterials( properties );
|
|
materials = new WebGLMaterials( properties );
|
|
renderLists = new WebGLRenderLists();
|
|
renderLists = new WebGLRenderLists();
|
|
renderStates = new WebGLRenderStates();
|
|
renderStates = new WebGLRenderStates();
|
|
@@ -602,6 +597,7 @@ function WebGLRenderer( parameters ) {
|
|
renderStates.dispose();
|
|
renderStates.dispose();
|
|
properties.dispose();
|
|
properties.dispose();
|
|
objects.dispose();
|
|
objects.dispose();
|
|
|
|
+ bindingStates.dispose();
|
|
|
|
|
|
xr.dispose();
|
|
xr.dispose();
|
|
|
|
|
|
@@ -680,7 +676,7 @@ function WebGLRenderer( parameters ) {
|
|
|
|
|
|
this.renderBufferImmediate = function ( object, program ) {
|
|
this.renderBufferImmediate = function ( object, program ) {
|
|
|
|
|
|
- state.initAttributes();
|
|
|
|
|
|
+ bindingStates.initAttributes();
|
|
|
|
|
|
const buffers = properties.get( object );
|
|
const buffers = properties.get( object );
|
|
|
|
|
|
@@ -696,7 +692,7 @@ function WebGLRenderer( parameters ) {
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
|
|
|
|
|
|
- state.enableAttribute( programAttributes.position );
|
|
|
|
|
|
+ bindingStates.enableAttribute( programAttributes.position );
|
|
_gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 );
|
|
_gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 );
|
|
|
|
|
|
}
|
|
}
|
|
@@ -706,7 +702,7 @@ function WebGLRenderer( parameters ) {
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
|
|
|
|
|
|
- state.enableAttribute( programAttributes.normal );
|
|
|
|
|
|
+ bindingStates.enableAttribute( programAttributes.normal );
|
|
_gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 );
|
|
_gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 );
|
|
|
|
|
|
}
|
|
}
|
|
@@ -716,7 +712,7 @@ function WebGLRenderer( parameters ) {
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
|
|
|
|
|
|
- state.enableAttribute( programAttributes.uv );
|
|
|
|
|
|
+ bindingStates.enableAttribute( programAttributes.uv );
|
|
_gl.vertexAttribPointer( programAttributes.uv, 2, _gl.FLOAT, false, 0, 0 );
|
|
_gl.vertexAttribPointer( programAttributes.uv, 2, _gl.FLOAT, false, 0, 0 );
|
|
|
|
|
|
}
|
|
}
|
|
@@ -726,12 +722,12 @@ function WebGLRenderer( parameters ) {
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
|
|
|
|
|
|
- state.enableAttribute( programAttributes.color );
|
|
|
|
|
|
+ bindingStates.enableAttribute( programAttributes.color );
|
|
_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
|
|
_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- state.disableUnusedAttributes();
|
|
|
|
|
|
+ bindingStates.disableUnusedAttributes();
|
|
|
|
|
|
_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
|
|
_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
|
|
|
|
|
|
@@ -749,33 +745,6 @@ function WebGLRenderer( parameters ) {
|
|
|
|
|
|
state.setMaterial( material, frontFaceCW );
|
|
state.setMaterial( material, frontFaceCW );
|
|
|
|
|
|
- let updateBuffers = false;
|
|
|
|
-
|
|
|
|
- if ( _currentGeometryProgram.geometry !== geometry.id ||
|
|
|
|
- _currentGeometryProgram.program !== program.id ||
|
|
|
|
- _currentGeometryProgram.wireframe !== ( material.wireframe === true ) ) {
|
|
|
|
-
|
|
|
|
- _currentGeometryProgram.geometry = geometry.id;
|
|
|
|
- _currentGeometryProgram.program = program.id;
|
|
|
|
- _currentGeometryProgram.wireframe = material.wireframe === true;
|
|
|
|
- updateBuffers = true;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ( material.morphTargets || material.morphNormals ) {
|
|
|
|
-
|
|
|
|
- morphtargets.update( object, geometry, material, program );
|
|
|
|
-
|
|
|
|
- updateBuffers = true;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ( object.isInstancedMesh === true ) {
|
|
|
|
-
|
|
|
|
- updateBuffers = true;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
//
|
|
//
|
|
|
|
|
|
let index = geometry.index;
|
|
let index = geometry.index;
|
|
@@ -804,6 +773,14 @@ function WebGLRenderer( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if ( material.morphTargets || material.morphNormals ) {
|
|
|
|
+
|
|
|
|
+ morphtargets.update( object, geometry, material, program );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bindingStates.setup( object, material, program, geometry, index );
|
|
|
|
+
|
|
let attribute;
|
|
let attribute;
|
|
let renderer = bufferRenderer;
|
|
let renderer = bufferRenderer;
|
|
|
|
|
|
@@ -816,18 +793,6 @@ function WebGLRenderer( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- if ( updateBuffers ) {
|
|
|
|
-
|
|
|
|
- setupVertexAttributes( object, geometry, material, program );
|
|
|
|
-
|
|
|
|
- if ( index !== null ) {
|
|
|
|
-
|
|
|
|
- _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
//
|
|
//
|
|
|
|
|
|
const dataCount = ( index !== null ) ? index.count : position.count;
|
|
const dataCount = ( index !== null ) ? index.count : position.count;
|
|
@@ -910,153 +875,6 @@ function WebGLRenderer( parameters ) {
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
- function setupVertexAttributes( object, geometry, material, program ) {
|
|
|
|
-
|
|
|
|
- if ( capabilities.isWebGL2 === false && ( object.isInstancedMesh || geometry.isInstancedBufferGeometry ) ) {
|
|
|
|
-
|
|
|
|
- if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) return;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- state.initAttributes();
|
|
|
|
-
|
|
|
|
- const geometryAttributes = geometry.attributes;
|
|
|
|
-
|
|
|
|
- const programAttributes = program.getAttributes();
|
|
|
|
-
|
|
|
|
- const materialDefaultAttributeValues = material.defaultAttributeValues;
|
|
|
|
-
|
|
|
|
- for ( const name in programAttributes ) {
|
|
|
|
-
|
|
|
|
- const programAttribute = programAttributes[ name ];
|
|
|
|
-
|
|
|
|
- if ( programAttribute >= 0 ) {
|
|
|
|
-
|
|
|
|
- const geometryAttribute = geometryAttributes[ name ];
|
|
|
|
-
|
|
|
|
- if ( geometryAttribute !== undefined ) {
|
|
|
|
-
|
|
|
|
- const normalized = geometryAttribute.normalized;
|
|
|
|
- const size = geometryAttribute.itemSize;
|
|
|
|
-
|
|
|
|
- const attribute = attributes.get( geometryAttribute );
|
|
|
|
-
|
|
|
|
- // TODO Attribute may not be available on context restore
|
|
|
|
-
|
|
|
|
- if ( attribute === undefined ) continue;
|
|
|
|
-
|
|
|
|
- const buffer = attribute.buffer;
|
|
|
|
- const type = attribute.type;
|
|
|
|
- const bytesPerElement = attribute.bytesPerElement;
|
|
|
|
-
|
|
|
|
- if ( geometryAttribute.isInterleavedBufferAttribute ) {
|
|
|
|
-
|
|
|
|
- const data = geometryAttribute.data;
|
|
|
|
- const stride = data.stride;
|
|
|
|
- const offset = geometryAttribute.offset;
|
|
|
|
-
|
|
|
|
- if ( data && data.isInstancedInterleavedBuffer ) {
|
|
|
|
-
|
|
|
|
- state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute );
|
|
|
|
-
|
|
|
|
- if ( geometry._maxInstanceCount === undefined ) {
|
|
|
|
-
|
|
|
|
- geometry._maxInstanceCount = data.meshPerAttribute * data.count;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- state.enableAttribute( programAttribute );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
|
|
|
|
- state.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- if ( geometryAttribute.isInstancedBufferAttribute ) {
|
|
|
|
-
|
|
|
|
- state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute );
|
|
|
|
-
|
|
|
|
- if ( geometry._maxInstanceCount === undefined ) {
|
|
|
|
-
|
|
|
|
- geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- state.enableAttribute( programAttribute );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
|
|
|
|
- state.vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else if ( name === 'instanceMatrix' ) {
|
|
|
|
-
|
|
|
|
- const attribute = attributes.get( object.instanceMatrix );
|
|
|
|
-
|
|
|
|
- // TODO Attribute may not be available on context restore
|
|
|
|
-
|
|
|
|
- if ( attribute === undefined ) continue;
|
|
|
|
-
|
|
|
|
- const buffer = attribute.buffer;
|
|
|
|
- const type = attribute.type;
|
|
|
|
-
|
|
|
|
- state.enableAttributeAndDivisor( programAttribute + 0, 1 );
|
|
|
|
- state.enableAttributeAndDivisor( programAttribute + 1, 1 );
|
|
|
|
- state.enableAttributeAndDivisor( programAttribute + 2, 1 );
|
|
|
|
- state.enableAttributeAndDivisor( programAttribute + 3, 1 );
|
|
|
|
-
|
|
|
|
- _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
|
|
|
|
-
|
|
|
|
- _gl.vertexAttribPointer( programAttribute + 0, 4, type, false, 64, 0 );
|
|
|
|
- _gl.vertexAttribPointer( programAttribute + 1, 4, type, false, 64, 16 );
|
|
|
|
- _gl.vertexAttribPointer( programAttribute + 2, 4, type, false, 64, 32 );
|
|
|
|
- _gl.vertexAttribPointer( programAttribute + 3, 4, type, false, 64, 48 );
|
|
|
|
-
|
|
|
|
- } else if ( materialDefaultAttributeValues !== undefined ) {
|
|
|
|
-
|
|
|
|
- const value = materialDefaultAttributeValues[ name ];
|
|
|
|
-
|
|
|
|
- if ( value !== undefined ) {
|
|
|
|
-
|
|
|
|
- switch ( value.length ) {
|
|
|
|
-
|
|
|
|
- case 2:
|
|
|
|
- _gl.vertexAttrib2fv( programAttribute, value );
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 3:
|
|
|
|
- _gl.vertexAttrib3fv( programAttribute, value );
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 4:
|
|
|
|
- _gl.vertexAttrib4fv( programAttribute, value );
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- default:
|
|
|
|
- _gl.vertexAttrib1fv( programAttribute, value );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- state.disableUnusedAttributes();
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
// Compile
|
|
// Compile
|
|
|
|
|
|
this.compile = function ( scene, camera ) {
|
|
this.compile = function ( scene, camera ) {
|
|
@@ -1174,9 +992,7 @@ function WebGLRenderer( parameters ) {
|
|
|
|
|
|
// reset caching for this frame
|
|
// reset caching for this frame
|
|
|
|
|
|
- _currentGeometryProgram.geometry = null;
|
|
|
|
- _currentGeometryProgram.program = null;
|
|
|
|
- _currentGeometryProgram.wireframe = false;
|
|
|
|
|
|
+ bindingStates.resetDefaultState();
|
|
_currentMaterialId = - 1;
|
|
_currentMaterialId = - 1;
|
|
_currentCamera = null;
|
|
_currentCamera = null;
|
|
|
|
|
|
@@ -1472,9 +1288,7 @@ function WebGLRenderer( parameters ) {
|
|
|
|
|
|
state.setMaterial( material );
|
|
state.setMaterial( material );
|
|
|
|
|
|
- _currentGeometryProgram.geometry = null;
|
|
|
|
- _currentGeometryProgram.program = null;
|
|
|
|
- _currentGeometryProgram.wireframe = false;
|
|
|
|
|
|
+ bindingStates.reset();
|
|
|
|
|
|
renderObjectImmediate( object, program );
|
|
renderObjectImmediate( object, program );
|
|
|
|
|