WebGLObjects.js 4.6 KB
Newer Older
R
Rich Harris 已提交
1 2 3
import { BufferAttribute } from '../../core/BufferAttribute';
import { WebGLGeometries } from './WebGLGeometries';

M
Mr.doob 已提交
4 5 6 7
/**
* @author mrdoob / http://mrdoob.com/
*/

R
Rich Harris 已提交
8 9
function WebGLObjects ( gl, properties, info ) {
	this.isWebGLObjects = true;
M
Mr.doob 已提交
10

R
Rich Harris 已提交
11
	var geometries = new WebGLGeometries( gl, properties, info );
12

M
Mr.doob 已提交
13 14
	//

15
	function update( object ) {
16 17

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

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

R
Rich Harris 已提交
21
		if ( (object.geometry && object.geometry.isGeometry) ) {
22

23
			geometry.updateFromObject( object );
24 25

		}
26

27
		var index = geometry.index;
28
		var attributes = geometry.attributes;
M
Mr.doob 已提交
29

30 31 32 33 34 35
		if ( index !== null ) {

			updateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );

		}

36
		for ( var name in attributes ) {
M
Mr.doob 已提交
37

38
			updateAttribute( attributes[ name ], gl.ARRAY_BUFFER );
M
Mr.doob 已提交
39

40
		}
41

42 43 44 45
		// morph targets

		var morphAttributes = geometry.morphAttributes;

46
		for ( var name in morphAttributes ) {
47

48 49 50 51
			var array = morphAttributes[ name ];

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

52
				updateAttribute( array[ i ], gl.ARRAY_BUFFER );
53 54

			}
55 56 57

		}

58 59
		return geometry;

60
	}
M
Mr.doob 已提交
61

62
	function updateAttribute( attribute, bufferType ) {
M
Mr.doob 已提交
63

R
Rich Harris 已提交
64
		var data = ( (attribute && attribute.isInterleavedBufferAttribute) ) ? attribute.data : attribute;
M
Mr.doob 已提交
65

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

M
Mr.doob 已提交
105
			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 已提交
106 107 108 109 110

		} else {

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

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

		}
115

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

	}
M
Mr.doob 已提交
119

120
	function getAttributeBuffer( attribute ) {
121

R
Rich Harris 已提交
122
		if ( (attribute && attribute.isInterleavedBufferAttribute) ) {
123

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

		}

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

130 131 132 133
	}

	function getWireframeAttribute( geometry ) {

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

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

			return property.wireframe;
139 140 141 142 143

		}

		var indices = [];

144
		var index = geometry.index;
145
		var attributes = geometry.attributes;
146 147
		var position = attributes.position;

M
Mr.doob 已提交
148
		// console.time( 'wireframe' );
149

150
		if ( index !== null ) {
151 152 153 154

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

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

				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 {

169
			var array = attributes.position.array;
170

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

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

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

			}

		}

M
Mr.doob 已提交
183
		// console.timeEnd( 'wireframe' );
184

M
Mr.doob 已提交
185
		var TypeArray = position.count > 65535 ? Uint32Array : Uint16Array;
R
Rich Harris 已提交
186
		var attribute = new BufferAttribute( new TypeArray( indices ), 1 );
187

188
		updateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );
189

190
		property.wireframe = attribute;
191 192 193 194 195 196 197

		return attribute;

	}

	function checkEdge( edges, a, b ) {

M
Mr.doob 已提交
198
		if ( a > b ) {
199

A
Alexander Rose 已提交
200 201 202
			var tmp = a;
			a = b;
			b = tmp;
M
Mr.doob 已提交
203

A
Alexander Rose 已提交
204 205 206 207
		}

		var list = edges[ a ];

M
Mr.doob 已提交
208
		if ( list === undefined ) {
A
Alexander Rose 已提交
209 210 211 212

			edges[ a ] = [ b ];
			return true;

M
Mr.doob 已提交
213
		} else if ( list.indexOf( b ) === -1 ) {
A
Alexander Rose 已提交
214 215 216 217 218

			list.push( b );
			return true;

		}
219

A
Alexander Rose 已提交
220
		return false;
221 222 223 224 225

	}

	this.getAttributeBuffer = getAttributeBuffer;
	this.getWireframeAttribute = getWireframeAttribute;
226

227 228
	this.update = update;

M
Mr.doob 已提交
229
};
R
Rich Harris 已提交
230 231 232


export { WebGLObjects };