WebGLObjects.js 4.3 KB
Newer Older
M
Mr.doob 已提交
1 2 3 4
/**
* @author mrdoob / http://mrdoob.com/
*/

5
THREE.WebGLObjects = function ( gl, properties, info ) {
M
Mr.doob 已提交
6

7
	var geometries = new THREE.WebGLGeometries( gl, properties, info );
8

M
Mr.doob 已提交
9 10
	//

11
	function update( object ) {
12 13

		// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.
M
Mr.doob 已提交
14

15
		var geometry = geometries.get( object );
M
Mr.doob 已提交
16

17
		if ( object.geometry instanceof THREE.Geometry ) {
18

19
			geometry.updateFromObject( object );
20 21

		}
22

23
		var attributes = geometry.attributes;
M
Mr.doob 已提交
24

25
		for ( var name in attributes ) {
M
Mr.doob 已提交
26

M
Mr.doob 已提交
27
			updateAttribute( attributes[ name ] );
M
Mr.doob 已提交
28

29
		}
30

31 32 33 34
		// morph targets

		var morphAttributes = geometry.morphAttributes;

35
		for ( var name in morphAttributes ) {
36

37 38 39 40
			var array = morphAttributes[ name ];

			for ( var i = 0, l = array.length; i < l; i ++ ) {

M
Mr.doob 已提交
41
				updateAttribute( array[ i ] );
42 43

			}
44 45 46

		}

47 48
		return geometry;

49
	}
M
Mr.doob 已提交
50

M
Mr.doob 已提交
51
	function updateAttribute( attribute ) {
52

M
Mr.doob 已提交
53 54 55 56 57 58 59 60 61 62 63
		var bufferType;

		if ( attribute instanceof THREE.IndexBufferAttribute ) {

			bufferType = gl.ELEMENT_ARRAY_BUFFER;

		} else {

			bufferType = gl.ARRAY_BUFFER;

		}
M
Mr.doob 已提交
64

65
		var data = ( attribute instanceof THREE.InterleavedBufferAttribute ) ? attribute.data : attribute;
M
Mr.doob 已提交
66

67
		var attributeProperties = properties.get( data );
M
Mr.doob 已提交
68

69
		if ( attributeProperties.__webglBuffer === undefined ) {
M
Mr.doob 已提交
70

D
dubejf 已提交
71
			createBuffer( attributeProperties, data, bufferType );
M
Mr.doob 已提交
72

73
		} else if ( attributeProperties.version !== data.version ) {
M
Mr.doob 已提交
74

D
dubejf 已提交
75
			updateBuffer( attributeProperties, data, bufferType );
M
Mr.doob 已提交
76

D
dubejf 已提交
77
		}
M
Mr.doob 已提交
78

D
dubejf 已提交
79
	}
M
Mr.doob 已提交
80

81
	function createBuffer( attributeProperties, data, bufferType ) {
M
Mr.doob 已提交
82

D
dubejf 已提交
83 84
		attributeProperties.__webglBuffer = gl.createBuffer();
		gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
M
Mr.doob 已提交
85

M
Mr.doob 已提交
86
		var usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;
M
Mr.doob 已提交
87

D
dubejf 已提交
88
		gl.bufferData( bufferType, data.array, usage );
M
Mr.doob 已提交
89

90
		attributeProperties.version = data.version;
M
Mr.doob 已提交
91

D
dubejf 已提交
92
	}
M
Mr.doob 已提交
93

94
	function updateBuffer( attributeProperties, data, bufferType ) {
95

D
dubejf 已提交
96
		gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
97

M
Mr.doob 已提交
98
		if ( data.dynamic === false || data.updateRange.count === - 1 ) {
G
gero3 已提交
99 100

			// Not using update ranges
M
Mr.doob 已提交
101

D
dubejf 已提交
102
			gl.bufferSubData( bufferType, 0, data.array );
103

D
dubejf 已提交
104
		} else if ( data.updateRange.count === 0 ) {
M
Mr.doob 已提交
105

M
Mr.doob 已提交
106
			console.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );
D
dubejf 已提交
107 108 109 110 111

		} else {

			gl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,
							  data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );
112

D
dubejf 已提交
113 114 115
			data.updateRange.count = 0; // reset range

		}
116

117
		attributeProperties.version = data.version;
D
dubejf 已提交
118 119

	}
M
Mr.doob 已提交
120

121
	function getAttributeBuffer( attribute ) {
122

123 124
		if ( attribute instanceof THREE.InterleavedBufferAttribute ) {

D
dubejf 已提交
125
			return properties.get( attribute.data ).__webglBuffer;
126 127 128

		}

129
		return properties.get( attribute ).__webglBuffer;
130

131 132 133 134
	}

	function getWireframeAttribute( geometry ) {

135
		var property = properties.get( geometry );
136

137 138 139
		if ( property.wireframe !== undefined ) {

			return property.wireframe;
140 141 142 143 144

		}

		var indices = [];

145 146
		var attributes = geometry.attributes;

147 148 149
		var index = attributes.index;
		var position = attributes.position;

M
Mr.doob 已提交
150
		// console.time( 'wireframe' );
151 152 153 154 155 156

		if ( index !== undefined ) {

			var edges = {};
			var array = index.array;

157
			for ( var i = 0, l = array.length; i < l; i += 3 ) {
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172

				var a = array[ i + 0 ];
				var b = array[ i + 1 ];
				var c = array[ i + 2 ];

				if ( checkEdge( edges, a, b ) ) indices.push( a, b );
				if ( checkEdge( edges, b, c ) ) indices.push( b, c );
				if ( checkEdge( edges, c, a ) ) indices.push( c, a );

			}

		} else {

			var array = position.array;

173
			for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
174 175 176 177 178 179 180 181 182 183 184

				var a = i + 0;
				var b = i + 1;
				var c = i + 2;

				indices.push( a, b, b, c, c, a );

			}

		}

M
Mr.doob 已提交
185
		// console.timeEnd( 'wireframe' );
186

M
Mr.doob 已提交
187
		var TypeArray = position.count > 65535 ? Uint32Array : Uint16Array;
M
Mr.doob 已提交
188
		var attribute = new THREE.IndexBufferAttribute( new TypeArray( indices ), 1 );
189

M
Mr.doob 已提交
190
		updateAttribute( attribute );
191

192
		property.wireframe = attribute;
193 194 195 196 197 198 199

		return attribute;

	}

	function checkEdge( edges, a, b ) {

M
Mr.doob 已提交
200
		var hash = a < b ? a + '_' + b : b + '_' + a;
201

M
Mr.doob 已提交
202 203 204
		if ( edges.hasOwnProperty( hash ) ) return false;

		edges[ hash ] = 1;
205 206 207 208 209 210 211

		return true;

	}

	this.getAttributeBuffer = getAttributeBuffer;
	this.getWireframeAttribute = getWireframeAttribute;
212

213 214
	this.update = update;

M
Mr.doob 已提交
215
};