WebGLRenderer.js 76.4 KB
Newer Older
N
Nicolas Garcia Belmonte 已提交
1 2 3
/**
 * @author supereggbert / http://www.paulbrunt.co.uk/
 * @author mrdoob / http://mrdoob.com/
4
 * @author alteredq / http://alteredqualia.com/
5
 * @author szimek / https://github.com/szimek/
N
Nicolas Garcia Belmonte 已提交
6 7
 */

8
THREE.WebGLRenderer = function ( parameters ) {
M
Mr.doob 已提交
9

M
Mr.doob 已提交
10 11
	// Currently you can use just up to 4 directional / point lights total.
	// Chrome barfs on shader linking when there are more than 4 lights :(
M
Mr.doob 已提交
12

13
	// The problem comes from shader using too many varying vectors.
M
Mr.doob 已提交
14

15
	// This is not GPU limitation as the same shader works ok in Firefox
M
Mr.doob 已提交
16
	// and Chrome with "--use-gl=desktop" flag.
M
Mr.doob 已提交
17

M
Mr.doob 已提交
18
	// Difference comes from Chrome on Windows using by default ANGLE,
19
	// thus going DirectX9 route (while FF uses OpenGL).
M
Mr.doob 已提交
20

21
	// See http://code.google.com/p/chromium/issues/detail?id=63491
M
Mr.doob 已提交
22

M
Mr.doob 已提交
23
	var _canvas = document.createElement( 'canvas' ), _gl,
24
	_oldProgram = null,
25
	_oldFramebuffer = null,
M
Mr.doob 已提交
26

A
alteredq 已提交
27
	_this = this,
28

A
alteredq 已提交
29
	// gl state cache
30

31 32
	_oldDoubleSided = null,
	_oldFlipSided = null,
A
alteredq 已提交
33
	_oldBlending = null,
A
alteredq 已提交
34
	_oldDepth = null,
35

36 37 38 39 40
	_viewportX = 0,
	_viewportY = 0,
	_viewportWidth = 0,
	_viewportHeight = 0,

41
	// camera matrices caches
42 43

	_frustum = [
44 45 46 47 48 49 50 51
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4()
	 ],

52
	_projScreenMatrix = new THREE.Matrix4(),
53
	_projectionMatrixArray = new Float32Array( 16 ),
54
	_viewMatrixArray = new Float32Array( 16 ),
55

56
	_vector3 = new THREE.Vector4(),
57

A
alteredq 已提交
58 59 60 61 62 63 64 65 66 67
	// light arrays cache
	
	_lights = {

		ambient: 	 [ 0, 0, 0 ],
		directional: { length: 0, colors: new Array(), positions: new Array() },
		point: 		 { length: 0, colors: new Array(), positions: new Array() }

	},

68
	// parameters defaults
M
Mr.doob 已提交
69

70 71 72
	antialias = true,
	clearColor = new THREE.Color( 0x000000 ),
	clearAlpha = 0;
73

74
	if ( parameters ) {
M
Mr.doob 已提交
75

76 77 78
		if ( parameters.antialias !== undefined ) antialias = parameters.antialias;
		if ( parameters.clearColor !== undefined ) clearColor.setHex( parameters.clearColor );
		if ( parameters.clearAlpha !== undefined ) clearAlpha = parameters.clearAlpha;
M
Mr.doob 已提交
79

80
	}
M
Mr.doob 已提交
81

N
Nicolas Garcia Belmonte 已提交
82 83
	this.domElement = _canvas;
	this.autoClear = true;
84
	this.sortObjects = true;
N
Nicolas Garcia Belmonte 已提交
85

86
	initGL( antialias, clearColor, clearAlpha );
M
Mr.doob 已提交
87

88 89
	this.context = _gl;

90
	//alert( dumpObject( getGLParams() ) );
M
Mr.doob 已提交
91

N
Nicolas Garcia Belmonte 已提交
92 93 94 95
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
96 97 98 99
		
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
100

101
	this.setViewport = function ( x, y, width, height ) {
102 103 104 105 106 107 108 109 110
		
		_viewportX = x;
		_viewportY = y;
		
		_viewportWidth = width;
		_viewportHeight = height;
		
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
		
N
Nicolas Garcia Belmonte 已提交
111
	};
112
	
113
	this.setScissor = function ( x, y, width, height ) {
N
Nicolas Garcia Belmonte 已提交
114

115 116 117 118
		_gl.scissor( x, y, width, height );
		
	};
	
119
	this.enableScissorTest = function ( enable ) {
120 121 122 123 124 125 126 127
		
		if ( enable )
			_gl.enable( _gl.SCISSOR_TEST );
		else
			_gl.disable( _gl.SCISSOR_TEST );
		
	};
	
128 129 130 131 132 133
	this.enableDepthBufferWrite = function ( enable ) {
		
		_gl.depthMask( enable );

	};
	
134
	this.setClearColorHex = function ( hex, alpha ) {
135

136 137
		var color = new THREE.Color( hex );
		_gl.clearColor( color.r, color.g, color.b, alpha );
138

139
	};
A
alteredq 已提交
140

141
	this.setClearColor = function ( color, alpha ) {
A
alteredq 已提交
142 143 144 145

		_gl.clearColor( color.r, color.g, color.b, alpha );

	};
146

N
Nicolas Garcia Belmonte 已提交
147 148 149 150 151 152
	this.clear = function () {

		_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT );

	};

M
Mr.doob 已提交
153

A
alteredq 已提交
154
	function setupLights ( program, lights ) {
155

156
		var l, ll, light, r = 0, g = 0, b = 0,
157
			color, position, intensity,
M
Mr.doob 已提交
158

A
alteredq 已提交
159
			zlights = _lights,
M
Mr.doob 已提交
160

161 162
			dcolors    = zlights.directional.colors,
			dpositions = zlights.directional.positions,
163

164 165
			pcolors    = zlights.point.colors,
			ppositions = zlights.point.positions,
166

167
			dlength = 0,
168
			plength = 0,
169

170 171
			doffset = 0,
			poffset = 0;
M
Mr.doob 已提交
172

173
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
174

175
			light = lights[ l ];
176 177 178
			color = light.color;
			position = light.position;
			intensity = light.intensity;
179 180 181

			if ( light instanceof THREE.AmbientLight ) {

182 183 184
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
185

186
			} else if ( light instanceof THREE.DirectionalLight ) {
187

188
				doffset = dlength * 3;
189

190 191 192
				dcolors[ doffset ]     = color.r * intensity;
				dcolors[ doffset + 1 ] = color.g * intensity;
				dcolors[ doffset + 2 ] = color.b * intensity;
193

194 195 196
				dpositions[ doffset ]     = position.x;
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
197

198
				dlength += 1;
M
Mr.doob 已提交
199

200 201
			} else if( light instanceof THREE.PointLight ) {

202
				poffset = plength * 3;
203

204 205 206
				pcolors[ poffset ]     = color.r * intensity;
				pcolors[ poffset + 1 ] = color.g * intensity;
				pcolors[ poffset + 2 ] = color.b * intensity;
207

208 209 210
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
M
Mr.doob 已提交
211

212
				plength += 1;
M
Mr.doob 已提交
213

214 215 216
			}

		}
217

218 219
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
220

221 222
		for( l = dlength * 3; l < dcolors.length; l++ ) dcolors[ l ] = 0.0;
		for( l = plength * 3; l < pcolors.length; l++ ) pcolors[ l ] = 0.0;
M
Mr.doob 已提交
223

224 225
		zlights.point.length = plength;
		zlights.directional.length = dlength;
M
Mr.doob 已提交
226

227 228 229
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
M
Mr.doob 已提交
230

231
	};
M
Mr.doob 已提交
232

233
	function createParticleBuffers ( geometry ) {
M
Mr.doob 已提交
234

235
		geometry.__webGLVertexBuffer = _gl.createBuffer();
236
		geometry.__webGLColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
237

238
	};
M
Mr.doob 已提交
239

240
	function createLineBuffers ( geometry ) {
M
Mr.doob 已提交
241

242
		geometry.__webGLVertexBuffer = _gl.createBuffer();
243
		geometry.__webGLColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
244

245
	};
246

A
alteredq 已提交
247 248 249 250 251 252 253
	function createRibbonBuffers ( geometry ) {

		geometry.__webGLVertexBuffer = _gl.createBuffer();
		geometry.__webGLColorBuffer = _gl.createBuffer();

	};

254
	function createMeshBuffers ( geometryGroup ) {
M
Mr.doob 已提交
255

256 257 258 259 260 261
		geometryGroup.__webGLVertexBuffer = _gl.createBuffer();
		geometryGroup.__webGLNormalBuffer = _gl.createBuffer();
		geometryGroup.__webGLTangentBuffer = _gl.createBuffer();
		geometryGroup.__webGLColorBuffer = _gl.createBuffer();
		geometryGroup.__webGLUVBuffer = _gl.createBuffer();
		geometryGroup.__webGLUV2Buffer = _gl.createBuffer();
262

263 264 265 266
		geometryGroup.__webGLSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webGLSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webGLSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webGLSkinWeightsBuffer = _gl.createBuffer();
267

268 269
		geometryGroup.__webGLFaceBuffer = _gl.createBuffer();
		geometryGroup.__webGLLineBuffer = _gl.createBuffer();
M
Mr.doob 已提交
270

271
	};
272

273
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
274

275 276 277
		var nvertices = geometry.vertices.length;

		geometry.__vertexArray = new Float32Array( nvertices * 3 );
278
		geometry.__colorArray = new Float32Array( nvertices * 3 );
M
Mr.doob 已提交
279

280
		geometry.__webGLLineCount = nvertices;
M
Mr.doob 已提交
281

282
	};
M
Mr.doob 已提交
283

284
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
285 286 287 288 289 290 291 292 293

		var nvertices = geometry.vertices.length;

		geometry.__vertexArray = new Float32Array( nvertices * 3 );
		geometry.__colorArray = new Float32Array( nvertices * 3 );

		geometry.__webGLVertexCount = nvertices;

	};
294

295
	function initParticleBuffers ( geometry ) {
296 297 298 299

		var nvertices = geometry.vertices.length;

		geometry.__vertexArray = new Float32Array( nvertices * 3 );
A
alteredq 已提交
300
		geometry.__colorArray = new Float32Array( nvertices * 3 );
301

302
		geometry.__sortArray = [];
303 304 305 306 307

		geometry.__webGLParticleCount = nvertices;

	};

308
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
309

310
		var f, fl, nvertices = 0, ntris = 0, nlines = 0,
M
Mr.doob 已提交
311
			obj_faces = object.geometry.faces,
312
			chunk_faces = geometryGroup.faces;
M
Mr.doob 已提交
313

314
		for ( f = 0, fl = chunk_faces.length; f < fl; f++ ) {
M
Mr.doob 已提交
315

316 317
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
318

319
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
320

321 322 323
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
324

325
			} else if ( face instanceof THREE.Face4 ) {
M
Mr.doob 已提交
326

327 328
				nvertices += 4;
				ntris += 2;
329
				nlines += 4;
M
Mr.doob 已提交
330

331
			}
M
Mr.doob 已提交
332

333
		}
M
Mr.doob 已提交
334

335
		// TODO: only create arrays for attributes existing in the object
M
Mr.doob 已提交
336

337 338 339 340 341 342
		geometryGroup.__vertexArray  = new Float32Array( nvertices * 3 );
		geometryGroup.__normalArray  = new Float32Array( nvertices * 3 );
		geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
		geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
		geometryGroup.__uvArray = new Float32Array( nvertices * 2 );
		geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );
M
Mr.doob 已提交
343

344 345 346 347
		geometryGroup.__skinVertexAArray = new Float32Array( nvertices * 4 );
		geometryGroup.__skinVertexBArray = new Float32Array( nvertices * 4 );
		geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
		geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 );
348

349 350
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
351

352
		geometryGroup.__needsSmoothNormals = bufferNeedsSmoothNormals ( geometryGroup, object );
M
Mr.doob 已提交
353

354 355
		geometryGroup.__webGLFaceCount = ntris * 3;
		geometryGroup.__webGLLineCount = nlines * 2;
M
Mr.doob 已提交
356

357
	};
M
Mr.doob 已提交
358

359
	function setMeshBuffers ( geometryGroup, object, hint ) {
360

361 362
		var f, fl, fi, face, vertexNormals, faceNormal, normal,
			uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
363
			c1, c2, c3, c4,
A
alteredq 已提交
364 365 366 367
			sw1, sw2, sw3, sw4,
			si1, si2, si3, si4,
			sa1, sa2, sa3, sa4,
			sb1, sb2, sb3, sb4,
368
			m, ml, i,
369
			vn, uvi, uv2i,
M
Mr.doob 已提交
370

371
		vertexIndex = 0,
372

373 374
		offset = 0,
		offset_uv = 0,
375
		offset_uv2 = 0,
376 377 378 379
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
380
		offset_color = 0,
A
alteredq 已提交
381
		offset_skin = 0,
M
Mr.doob 已提交
382

383 384 385 386 387 388
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
389

390 391 392 393
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
394

395 396
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
397

398
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
399

400
		geometry = object.geometry, // this is shared for all chunks
401

402
		dirtyVertices = geometry.__dirtyVertices,
403 404 405
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
406
		dirtyTangents = geometry.__dirtyTangents,
407
		dirtyColors = geometry.__dirtyColors,
M
Mr.doob 已提交
408

409
		vertices = geometry.vertices,
410
		chunk_faces = geometryGroup.faces,
411
		obj_faces = geometry.faces,
412
		obj_uvs = geometry.uvs,
413
		obj_uvs2 = geometry.uvs2,
A
alteredq 已提交
414
		obj_colors = geometry.colors,
415

A
alteredq 已提交
416 417 418 419
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
		obj_skinWeights = geometry.skinWeights;
420

421
		for ( f = 0, fl = chunk_faces.length; f < fl; f++ ) {
M
Mr.doob 已提交
422

423 424 425
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
			uv = obj_uvs[ fi ];
426
			uv2 = obj_uvs2[ fi ];
M
Mr.doob 已提交
427

428
			vertexNormals = face.vertexNormals;
429
			faceNormal = face.normal;
430 431 432

			if ( face instanceof THREE.Face3 ) {

433
				if ( dirtyVertices ) {
M
Mr.doob 已提交
434

435 436 437
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
438

439 440 441
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
442

443 444 445
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
446

447 448 449
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
450

451
					offset += 9;
M
Mr.doob 已提交
452

453
				}
454

A
alteredq 已提交
455 456 457
				if ( obj_skinWeights.length ) {

					// weights
458

A
alteredq 已提交
459 460 461
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
462

A
alteredq 已提交
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
					skinWeightArray[ offset_skin ]     = sw1.x;
					skinWeightArray[ offset_skin + 1 ] = sw1.y;
					skinWeightArray[ offset_skin + 2 ] = sw1.z;
					skinWeightArray[ offset_skin + 3 ] = sw1.w;

					skinWeightArray[ offset_skin + 4 ] = sw2.x;
					skinWeightArray[ offset_skin + 5 ] = sw2.y;
					skinWeightArray[ offset_skin + 6 ] = sw2.z;
					skinWeightArray[ offset_skin + 7 ] = sw2.w;

					skinWeightArray[ offset_skin + 8 ]  = sw3.x;
					skinWeightArray[ offset_skin + 9 ]  = sw3.y;
					skinWeightArray[ offset_skin + 10 ] = sw3.z;
					skinWeightArray[ offset_skin + 11 ] = sw3.w;

					// indices
479

A
alteredq 已提交
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
					si1 = obj_skinIndices[ face.a ];
					si2 = obj_skinIndices[ face.b ];
					si3 = obj_skinIndices[ face.c ];

					skinIndexArray[ offset_skin ]     = si1.x;
					skinIndexArray[ offset_skin + 1 ] = si1.y;
					skinIndexArray[ offset_skin + 2 ] = si1.z;
					skinIndexArray[ offset_skin + 3 ] = si1.w;

					skinIndexArray[ offset_skin + 4 ] = si2.x;
					skinIndexArray[ offset_skin + 5 ] = si2.y;
					skinIndexArray[ offset_skin + 6 ] = si2.z;
					skinIndexArray[ offset_skin + 7 ] = si2.w;

					skinIndexArray[ offset_skin + 8 ]  = si3.x;
					skinIndexArray[ offset_skin + 9 ]  = si3.y;
					skinIndexArray[ offset_skin + 10 ] = si3.z;
					skinIndexArray[ offset_skin + 11 ] = si3.w;

					// vertices A
500

A
alteredq 已提交
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
					sa1 = obj_skinVerticesA[ face.a ];
					sa2 = obj_skinVerticesA[ face.b ];
					sa3 = obj_skinVerticesA[ face.c ];

					skinVertexAArray[ offset_skin ]     = sa1.x;
					skinVertexAArray[ offset_skin + 1 ] = sa1.y;
					skinVertexAArray[ offset_skin + 2 ] = sa1.z;
					skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader

					skinVertexAArray[ offset_skin + 4 ] = sa2.x;
					skinVertexAArray[ offset_skin + 5 ] = sa2.y;
					skinVertexAArray[ offset_skin + 6 ] = sa2.z;
					skinVertexAArray[ offset_skin + 7 ] = 1;

					skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
					skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
					skinVertexAArray[ offset_skin + 10 ] = sa3.z;
					skinVertexAArray[ offset_skin + 11 ] = 1;

					// vertices B
521

A
alteredq 已提交
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
					sb1 = obj_skinVerticesB[ face.a ];
					sb2 = obj_skinVerticesB[ face.b ];
					sb3 = obj_skinVerticesB[ face.c ];

					skinVertexBArray[ offset_skin ]     = sb1.x;
					skinVertexBArray[ offset_skin + 1 ] = sb1.y;
					skinVertexBArray[ offset_skin + 2 ] = sb1.z;
					skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader

					skinVertexBArray[ offset_skin + 4 ] = sb2.x;
					skinVertexBArray[ offset_skin + 5 ] = sb2.y;
					skinVertexBArray[ offset_skin + 6 ] = sb2.z;
					skinVertexBArray[ offset_skin + 7 ] = 1;

					skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
					skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
					skinVertexBArray[ offset_skin + 10 ] = sb3.z;
					skinVertexBArray[ offset_skin + 11 ] = 1;

					offset_skin += 12;
542

A
alteredq 已提交
543
				}
544

545
				if ( dirtyColors && obj_colors.length ) {
546

547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
					c1 = obj_colors[ face.a ];
					c2 = obj_colors[ face.b ];
					c3 = obj_colors[ face.c ];

					colorArray[ offset_color ]     = c1.r;
					colorArray[ offset_color + 1 ] = c1.g;
					colorArray[ offset_color + 2 ] = c1.b;

					colorArray[ offset_color + 3 ] = c2.r;
					colorArray[ offset_color + 4 ] = c2.g;
					colorArray[ offset_color + 5 ] = c2.b;

					colorArray[ offset_color + 6 ] = c3.r;
					colorArray[ offset_color + 7 ] = c3.g;
					colorArray[ offset_color + 8 ] = c3.b;
562

563 564 565 566
					offset_color += 9;

				}

567
				if ( dirtyTangents && geometry.hasTangents ) {
568

569 570 571
					t1 = vertices[ face.a ].tangent;
					t2 = vertices[ face.b ].tangent;
					t3 = vertices[ face.c ].tangent;
572

573 574 575 576
					tangentArray[ offset_tangent ]     = t1.x;
					tangentArray[ offset_tangent + 1 ] = t1.y;
					tangentArray[ offset_tangent + 2 ] = t1.z;
					tangentArray[ offset_tangent + 3 ] = t1.w;
M
Mr.doob 已提交
577

578 579 580 581
					tangentArray[ offset_tangent + 4 ] = t2.x;
					tangentArray[ offset_tangent + 5 ] = t2.y;
					tangentArray[ offset_tangent + 6 ] = t2.z;
					tangentArray[ offset_tangent + 7 ] = t2.w;
M
Mr.doob 已提交
582

583 584 585 586
					tangentArray[ offset_tangent + 8 ]  = t3.x;
					tangentArray[ offset_tangent + 9 ]  = t3.y;
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
M
Mr.doob 已提交
587

588
					offset_tangent += 12;
M
Mr.doob 已提交
589

590 591
				}

592
				if ( dirtyNormals ) {
M
Mr.doob 已提交
593

594 595 596
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

						for ( i = 0; i < 3; i ++ ) {
597

598
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
599

600 601 602
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
603

604
							offset_normal += 3;
M
Mr.doob 已提交
605

606
						}
M
Mr.doob 已提交
607

608
					} else {
609

610
						for ( i = 0; i < 3; i ++ ) {
611

612 613 614
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
615

616
							offset_normal += 3;
M
Mr.doob 已提交
617

618
						}
M
Mr.doob 已提交
619 620

					}
M
Mr.doob 已提交
621

622 623
				}

624
				if ( dirtyUvs && uv ) {
625

M
Mr.doob 已提交
626 627
					for ( i = 0; i < 3; i ++ ) {

628
						uvi = uv[ i ];
M
Mr.doob 已提交
629

630 631
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
632

633
						offset_uv += 2;
M
Mr.doob 已提交
634

M
Mr.doob 已提交
635
					}
636 637 638

				}

639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
				if ( dirtyUvs && uv2 ) {

					for ( i = 0; i < 3; i ++ ) {

						uv2i = uv2[ i ];

						uv2Array[ offset_uv2 ]     = uv2i.u;
						uv2Array[ offset_uv2 + 1 ] = uv2i.v;

						offset_uv2 += 2;

					}

				}

654
				if( dirtyElements ) {
M
Mr.doob 已提交
655

656 657 658
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
659

660
					offset_face += 3;
M
Mr.doob 已提交
661

662 663
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
664

665 666
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
667

668 669
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
670

671
					offset_line += 6;
672

673
					vertexIndex += 3;
M
Mr.doob 已提交
674

675
				}
M
Mr.doob 已提交
676

677 678 679

			} else if ( face instanceof THREE.Face4 ) {

680
				if ( dirtyVertices ) {
M
Mr.doob 已提交
681

682 683 684 685
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
686

687 688 689
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
690

691 692 693
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
694

695 696 697
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
698

699 700 701
					vertexArray[ offset + 9 ] = v4.x;
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
702

703
					offset += 12;
M
Mr.doob 已提交
704

705
				}
706

A
alteredq 已提交
707 708 709
				if ( obj_skinWeights.length ) {

					// weights
710

A
alteredq 已提交
711 712 713 714
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
715

A
alteredq 已提交
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736
					skinWeightArray[ offset_skin ]     = sw1.x;
					skinWeightArray[ offset_skin + 1 ] = sw1.y;
					skinWeightArray[ offset_skin + 2 ] = sw1.z;
					skinWeightArray[ offset_skin + 3 ] = sw1.w;

					skinWeightArray[ offset_skin + 4 ] = sw2.x;
					skinWeightArray[ offset_skin + 5 ] = sw2.y;
					skinWeightArray[ offset_skin + 6 ] = sw2.z;
					skinWeightArray[ offset_skin + 7 ] = sw2.w;

					skinWeightArray[ offset_skin + 8 ]  = sw3.x;
					skinWeightArray[ offset_skin + 9 ]  = sw3.y;
					skinWeightArray[ offset_skin + 10 ] = sw3.z;
					skinWeightArray[ offset_skin + 11 ] = sw3.w;

					skinWeightArray[ offset_skin + 12 ] = sw4.x;
					skinWeightArray[ offset_skin + 13 ] = sw4.y;
					skinWeightArray[ offset_skin + 14 ] = sw4.z;
					skinWeightArray[ offset_skin + 15 ] = sw4.w;

					// indices
737

A
alteredq 已提交
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
					si1 = obj_skinIndices[ face.a ];
					si2 = obj_skinIndices[ face.b ];
					si3 = obj_skinIndices[ face.c ];
					si4 = obj_skinIndices[ face.d ];

					skinIndexArray[ offset_skin ]     = si1.x;
					skinIndexArray[ offset_skin + 1 ] = si1.y;
					skinIndexArray[ offset_skin + 2 ] = si1.z;
					skinIndexArray[ offset_skin + 3 ] = si1.w;

					skinIndexArray[ offset_skin + 4 ] = si2.x;
					skinIndexArray[ offset_skin + 5 ] = si2.y;
					skinIndexArray[ offset_skin + 6 ] = si2.z;
					skinIndexArray[ offset_skin + 7 ] = si2.w;

					skinIndexArray[ offset_skin + 8 ]  = si3.x;
					skinIndexArray[ offset_skin + 9 ]  = si3.y;
					skinIndexArray[ offset_skin + 10 ] = si3.z;
					skinIndexArray[ offset_skin + 11 ] = si3.w;

					skinIndexArray[ offset_skin + 12 ] = si4.x;
					skinIndexArray[ offset_skin + 13 ] = si4.y;
					skinIndexArray[ offset_skin + 14 ] = si4.z;
					skinIndexArray[ offset_skin + 15 ] = si4.w;

					// vertices A
764

A
alteredq 已提交
765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
					sa1 = obj_skinVerticesA[ face.a ];
					sa2 = obj_skinVerticesA[ face.b ];
					sa3 = obj_skinVerticesA[ face.c ];
					sa4 = obj_skinVerticesA[ face.d ];

					skinVertexAArray[ offset_skin ]     = sa1.x;
					skinVertexAArray[ offset_skin + 1 ] = sa1.y;
					skinVertexAArray[ offset_skin + 2 ] = sa1.z;
					skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader

					skinVertexAArray[ offset_skin + 4 ] = sa2.x;
					skinVertexAArray[ offset_skin + 5 ] = sa2.y;
					skinVertexAArray[ offset_skin + 6 ] = sa2.z;
					skinVertexAArray[ offset_skin + 7 ] = 1;

					skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
					skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
					skinVertexAArray[ offset_skin + 10 ] = sa3.z;
					skinVertexAArray[ offset_skin + 11 ] = 1;

					skinVertexAArray[ offset_skin + 12 ] = sa4.x;
					skinVertexAArray[ offset_skin + 13 ] = sa4.y;
					skinVertexAArray[ offset_skin + 14 ] = sa4.z;
					skinVertexAArray[ offset_skin + 15 ] = 1;

					// vertices B
791

A
alteredq 已提交
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
					sb1 = obj_skinVerticesB[ face.a ];
					sb2 = obj_skinVerticesB[ face.b ];
					sb3 = obj_skinVerticesB[ face.c ];
					sb4 = obj_skinVerticesB[ face.d ];

					skinVertexBArray[ offset_skin ]     = sb1.x;
					skinVertexBArray[ offset_skin + 1 ] = sb1.y;
					skinVertexBArray[ offset_skin + 2 ] = sb1.z;
					skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader

					skinVertexBArray[ offset_skin + 4 ] = sb2.x;
					skinVertexBArray[ offset_skin + 5 ] = sb2.y;
					skinVertexBArray[ offset_skin + 6 ] = sb2.z;
					skinVertexBArray[ offset_skin + 7 ] = 1;

					skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
					skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
					skinVertexBArray[ offset_skin + 10 ] = sb3.z;
					skinVertexBArray[ offset_skin + 11 ] = 1;

					skinVertexBArray[ offset_skin + 12 ]  = sb4.x;
					skinVertexBArray[ offset_skin + 13 ]  = sb4.y;
					skinVertexBArray[ offset_skin + 14 ] = sb4.z;
					skinVertexBArray[ offset_skin + 15 ] = 1;

817 818
					offset_skin += 16;

A
alteredq 已提交
819
				}
820

821 822 823 824 825
				if ( dirtyColors && obj_colors.length ) {

					c1 = obj_colors[ face.a ];
					c2 = obj_colors[ face.b ];
					c3 = obj_colors[ face.c ];
826
					c4 = obj_colors[ face.d ];
827 828 829 830 831 832 833 834 835 836 837 838

					colorArray[ offset_color ]     = c1.r;
					colorArray[ offset_color + 1 ] = c1.g;
					colorArray[ offset_color + 2 ] = c1.b;

					colorArray[ offset_color + 3 ] = c2.r;
					colorArray[ offset_color + 4 ] = c2.g;
					colorArray[ offset_color + 5 ] = c2.b;

					colorArray[ offset_color + 6 ] = c3.r;
					colorArray[ offset_color + 7 ] = c3.g;
					colorArray[ offset_color + 8 ] = c3.b;
839

840 841 842
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
843

844 845
					offset_color += 12;

846 847
				}

848
				if ( dirtyTangents && geometry.hasTangents ) {
849

850 851 852 853
					t1 = vertices[ face.a ].tangent;
					t2 = vertices[ face.b ].tangent;
					t3 = vertices[ face.c ].tangent;
					t4 = vertices[ face.d ].tangent;
854

855 856 857 858
					tangentArray[ offset_tangent ]     = t1.x;
					tangentArray[ offset_tangent + 1 ] = t1.y;
					tangentArray[ offset_tangent + 2 ] = t1.z;
					tangentArray[ offset_tangent + 3 ] = t1.w;
M
Mr.doob 已提交
859

860 861 862 863
					tangentArray[ offset_tangent + 4 ] = t2.x;
					tangentArray[ offset_tangent + 5 ] = t2.y;
					tangentArray[ offset_tangent + 6 ] = t2.z;
					tangentArray[ offset_tangent + 7 ] = t2.w;
M
Mr.doob 已提交
864

865 866 867 868
					tangentArray[ offset_tangent + 8 ] = t3.x;
					tangentArray[ offset_tangent + 9 ] = t3.y;
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
M
Mr.doob 已提交
869

870 871 872 873
					tangentArray[ offset_tangent + 12 ] = t4.x;
					tangentArray[ offset_tangent + 13 ] = t4.y;
					tangentArray[ offset_tangent + 14 ] = t4.z;
					tangentArray[ offset_tangent + 15 ] = t4.w;
M
Mr.doob 已提交
874

875
					offset_tangent += 16;
M
Mr.doob 已提交
876

877
				}
M
Mr.doob 已提交
878

879
				if( dirtyNormals ) {
M
Mr.doob 已提交
880

881
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
882

883
						for ( i = 0; i < 4; i ++ ) {
884

885
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
886

887 888 889
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
890

891
							offset_normal += 3;
M
Mr.doob 已提交
892

893
						}
M
Mr.doob 已提交
894

895
					} else {
896

897
						for ( i = 0; i < 4; i ++ ) {
898

899 900 901
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
902

903
							offset_normal += 3;
M
Mr.doob 已提交
904

905
						}
M
Mr.doob 已提交
906 907

					}
M
Mr.doob 已提交
908

909 910
				}

911
				if ( dirtyUvs && uv ) {
912

M
Mr.doob 已提交
913 914
					for ( i = 0; i < 4; i ++ ) {

915
						uvi = uv[ i ];
M
Mr.doob 已提交
916

917 918
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
919

920
						offset_uv += 2;
M
Mr.doob 已提交
921

M
Mr.doob 已提交
922
					}
923 924

				}
925

926 927 928 929 930 931 932 933 934 935 936 937 938 939
				if ( dirtyUvs && uv2 ) {

					for ( i = 0; i < 4; i ++ ) {

						uv2i = uv2[ i ];

						uv2Array[ offset_uv2 ]     = uv2i.u;
						uv2Array[ offset_uv2 + 1 ] = uv2i.v;

						offset_uv2 += 2;

					}

				}
M
Mr.doob 已提交
940

941
				if ( dirtyElements ) {
M
Mr.doob 已提交
942

943 944 945
					faceArray[ offset_face ]     = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
946

947 948 949
					faceArray[ offset_face + 3 ] = vertexIndex;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
950

951
					offset_face += 6;
M
Mr.doob 已提交
952

953 954
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
955

956
					lineArray[ offset_line + 2 ] = vertexIndex;
957
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
958

959 960
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
961

962 963
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
964

965
					offset_line += 8;
M
Mr.doob 已提交
966

967
					vertexIndex += 4;
M
Mr.doob 已提交
968

969
				}
M
Mr.doob 已提交
970

971
			}
M
Mr.doob 已提交
972

973 974
		}

975
		if ( dirtyVertices ) {
M
Mr.doob 已提交
976

977
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
978
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
979

980
		}
M
Mr.doob 已提交
981

982 983
		if ( dirtyColors && obj_colors.length ) {

984
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
985 986 987
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
988

989
		if ( dirtyNormals ) {
M
Mr.doob 已提交
990

991
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
992
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
993

994 995
		}

996
		if ( dirtyTangents && geometry.hasTangents ) {
997

998
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
999
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
1000

1001
		}
1002

1003
		if ( dirtyUvs && offset_uv > 0 ) {
M
Mr.doob 已提交
1004

1005
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1006
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
1007

1008
		}
M
Mr.doob 已提交
1009

1010 1011
		if ( dirtyUvs && offset_uv2 > 0 ) {

1012
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
1013 1014 1015 1016
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

1017
		if ( dirtyElements ) {
M
Mr.doob 已提交
1018

1019
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
1020
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1021

1022
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
1023
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
1024

1025
		}
1026

1027
		if ( offset_skin > 0 ) {
1028

1029
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1030 1031
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

1032
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer );
A
alteredq 已提交
1033 1034
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

1035
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer );
A
alteredq 已提交
1036 1037
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

1038
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer );
A
alteredq 已提交
1039
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1040

A
alteredq 已提交
1041
		}
1042 1043

	};
1044

1045
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1046

1047
		var v, c, vertex, offset,
1048
			vertices = geometry.vertices,
1049
			colors = geometry.colors,
1050
			vl = vertices.length,
1051
			cl = colors.length,
M
Mr.doob 已提交
1052 1053

			vertexArray = geometry.__vertexArray,
1054
			colorArray = geometry.__colorArray,
1055 1056

			dirtyVertices = geometry.__dirtyVertices,
1057
			dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1058

1059
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1060

1061
			for ( v = 0; v < vl; v++ ) {
M
Mr.doob 已提交
1062

1063
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1064

1065
				offset = v * 3;
M
Mr.doob 已提交
1066

1067 1068 1069
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1070

1071 1072
			}

A
alteredq 已提交
1073 1074 1075
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1076
		}
M
Mr.doob 已提交
1077

1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096
		if ( dirtyColors ) {

			for ( c = 0; c < cl; c++ ) {

				color = colors[ c ];

				offset = c * 3;

				colorArray[ offset ]     = color.r;
				colorArray[ offset + 1 ] = color.g;
				colorArray[ offset + 2 ] = color.b;

			}

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

1097
	};
M
Mr.doob 已提交
1098

1099
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
1100 1101 1102 1103 1104 1105 1106 1107 1108

		var v, c, vertex, offset,
			vertices = geometry.vertices,
			colors = geometry.colors,
			vl = vertices.length,
			cl = colors.length,

			vertexArray = geometry.__vertexArray,
			colorArray = geometry.__colorArray,
1109 1110

			dirtyVertices = geometry.__dirtyVertices,
A
alteredq 已提交
1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
			dirtyColors = geometry.__dirtyColors;

		if ( dirtyVertices ) {

			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;

				offset = v * 3;

				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;

			}

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

		}

		if ( dirtyColors ) {

			for ( c = 0; c < cl; c++ ) {

				color = colors[ c ];

				offset = c * 3;

				colorArray[ offset ]     = color.r;
				colorArray[ offset + 1 ] = color.g;
				colorArray[ offset + 2 ] = color.b;

			}

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

	};
1152

1153
	function setParticleBuffers ( geometry, hint, object ) {
1154

A
alteredq 已提交
1155
		var v, c, vertex, offset,
1156 1157 1158
			vertices = geometry.vertices,
			vl = vertices.length,

A
alteredq 已提交
1159 1160
			colors = geometry.colors,
			cl = colors.length,
1161

1162
			vertexArray = geometry.__vertexArray,
A
alteredq 已提交
1163
			colorArray = geometry.__colorArray,
1164

1165
			sortArray = geometry.__sortArray,
1166

1167 1168 1169
			dirtyVertices = geometry.__dirtyVertices,
			dirtyElements = geometry.__dirtyElements,
			dirtyColors = geometry.__dirtyColors;
1170

1171
		if ( object.sortParticles ) {
1172

1173
			_projScreenMatrix.multiplySelf( object.matrixWorld );
1174

1175 1176 1177
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
1178

1179 1180
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
1181

1182
				sortArray[ v ] = [ _vector3.z, v ];
1183

1184
			}
1185

1186
			sortArray.sort( function(a,b) { return b[0] - a[0]; } );
1187

1188
			for ( v = 0; v < vl; v++ ) {
1189

1190
				vertex = vertices[ sortArray[v][1] ].position;
1191

1192
				offset = v * 3;
1193

1194 1195 1196
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
1197

1198
			}
1199

A
alteredq 已提交
1200
			for ( c = 0; c < cl; c++ ) {
1201

A
alteredq 已提交
1202
				offset = c * 3;
1203

A
alteredq 已提交
1204 1205 1206 1207 1208
				color = colors[ sortArray[c][1] ];

				colorArray[ offset ]     = color.r;
				colorArray[ offset + 1 ] = color.g;
				colorArray[ offset + 2 ] = color.b;
1209

1210
			}
1211 1212


1213
		} else {
1214

1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
			if ( dirtyVertices ) {

				for ( v = 0; v < vl; v++ ) {

					vertex = vertices[ v ].position;

					offset = v * 3;

					vertexArray[ offset ]     = vertex.x;
					vertexArray[ offset + 1 ] = vertex.y;
					vertexArray[ offset + 2 ] = vertex.z;

				}
1228 1229

			}
1230

A
alteredq 已提交
1231
			if ( dirtyColors ) {
1232

A
alteredq 已提交
1233 1234 1235 1236 1237 1238 1239 1240 1241 1242
				for ( c = 0; c < cl; c++ ) {

					color = colors[ c ];

					offset = c * 3;

					colorArray[ offset ]     = color.r;
					colorArray[ offset + 1 ] = color.g;
					colorArray[ offset + 2 ] = color.b;

1243
				}
1244

A
alteredq 已提交
1245
			}
1246 1247

		}
1248

A
alteredq 已提交
1249
		if ( dirtyVertices || object.sortParticles ) {
1250

A
alteredq 已提交
1251 1252
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
1253

A
alteredq 已提交
1254
		}
1255

A
alteredq 已提交
1256
		if ( dirtyColors || object.sortParticles ) {
1257

A
alteredq 已提交
1258 1259
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
1260

A
alteredq 已提交
1261
		}
1262

1263
	};
M
Mr.doob 已提交
1264

1265
	function setMaterialShaders ( material, shaders ) {
1266

1267 1268
		material.fragmentShader = shaders.fragmentShader;
		material.vertexShader = shaders.vertexShader;
1269
		material.uniforms = Uniforms.clone( shaders.uniforms );
1270

M
Mr.doob 已提交
1271
	};
1272

1273
	function refreshUniformsCommon ( uniforms, material ) {
M
Mr.doob 已提交
1274

1275
		// premultiply alpha
A
alteredq 已提交
1276
		uniforms.diffuse.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
M
Mr.doob 已提交
1277

1278
		// pure color
A
alteredq 已提交
1279
		//uniforms.color.value.setHex( material.color.hex );
M
Mr.doob 已提交
1280

A
alteredq 已提交
1281 1282
		uniforms.opacity.value = material.opacity;
		uniforms.map.texture = material.map;
1283

1284
		uniforms.lightMap.texture = material.lightMap;
1285

1286
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
1287
		uniforms.reflectivity.value = material.reflectivity;
1288
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
1289
		uniforms.combine.value = material.combine;
1290
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
1291

1292
	};
1293

1294
	function refreshUniformsLine ( uniforms, material ) {
1295

A
alteredq 已提交
1296 1297
		uniforms.diffuse.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
		uniforms.opacity.value = material.opacity;
1298 1299

	};
M
Mr.doob 已提交
1300

1301
	function refreshUniformsParticle ( uniforms, material ) {
1302

A
alteredq 已提交
1303 1304 1305
		uniforms.psColor.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
M
Mr.doob 已提交
1306
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
A
alteredq 已提交
1307
		uniforms.map.texture = material.map;
1308

A
alteredq 已提交
1309
	};
1310

1311
	function refreshUniformsFog ( uniforms, fog ) {
1312

A
alteredq 已提交
1313
		uniforms.fogColor.value.setHex( fog.color.hex );
1314

A
alteredq 已提交
1315
		if ( fog instanceof THREE.Fog ) {
1316

A
alteredq 已提交
1317 1318
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
1319

A
alteredq 已提交
1320
		} else if ( fog instanceof THREE.FogExp2 ) {
1321

A
alteredq 已提交
1322
			uniforms.fogDensity.value = fog.density;
1323 1324

		}
1325

1326 1327
	};

1328
	function refreshUniformsPhong ( uniforms, material ) {
M
Mr.doob 已提交
1329

A
alteredq 已提交
1330 1331 1332 1333 1334
		//uniforms.ambient.value.setHex( material.ambient.hex );
		//uniforms.specular.value.setHex( material.specular.hex );
		uniforms.ambient.value.setRGB( material.ambient.r, material.ambient.g, material.ambient.b );
		uniforms.specular.value.setRGB( material.specular.r, material.specular.g, material.specular.b );
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
1335

1336
	};
M
Mr.doob 已提交
1337 1338


1339
	function refreshUniformsLights ( uniforms, lights ) {
M
Mr.doob 已提交
1340

A
alteredq 已提交
1341 1342 1343 1344 1345 1346
		uniforms.enableLighting.value = lights.directional.length + lights.point.length;
		uniforms.ambientLightColor.value = lights.ambient;
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
M
Mr.doob 已提交
1347

A
alteredq 已提交
1348
	};
M
Mr.doob 已提交
1349

1350
	this.initMaterial = function ( material, lights, fog, object ) {
M
Mr.doob 已提交
1351

1352
		var u, identifiers, parameters, maxLightCount, maxBones;
1353

A
alteredq 已提交
1354
		if ( material instanceof THREE.MeshDepthMaterial ) {
1355

A
alteredq 已提交
1356
			setMaterialShaders( material, THREE.ShaderLib[ 'depth' ] );
1357

A
alteredq 已提交
1358
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
1359

A
alteredq 已提交
1360
			setMaterialShaders( material, THREE.ShaderLib[ 'normal' ] );
1361

A
alteredq 已提交
1362
		} else if ( material instanceof THREE.MeshBasicMaterial ) {
1363

A
alteredq 已提交
1364
			setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );
1365

A
alteredq 已提交
1366
		} else if ( material instanceof THREE.MeshLambertMaterial ) {
M
Mr.doob 已提交
1367

A
alteredq 已提交
1368
			setMaterialShaders( material, THREE.ShaderLib[ 'lambert' ] );
M
Mr.doob 已提交
1369

A
alteredq 已提交
1370
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
1371

A
alteredq 已提交
1372
			setMaterialShaders( material, THREE.ShaderLib[ 'phong' ] );
M
Mr.doob 已提交
1373

A
alteredq 已提交
1374
		} else if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
1375

A
alteredq 已提交
1376
			setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );
1377

A
alteredq 已提交
1378
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
1379

A
alteredq 已提交
1380
			setMaterialShaders( material, THREE.ShaderLib[ 'particle_basic' ] );
1381

A
alteredq 已提交
1382
		}
1383

A
alteredq 已提交
1384 1385
		// heuristics to create shader parameters according to lights in the scene
		// (not to blow over maxLights budget)
M
Mr.doob 已提交
1386

A
alteredq 已提交
1387
		maxLightCount = allocateLights( lights, 4 );
M
Mr.doob 已提交
1388

1389
		maxBones = allocateBones( object );
1390 1391 1392 1393 1394 1395 1396 1397

		parameters = {
				fog: fog, map: material.map, envMap: material.envMap,
				lightMap: material.lightMap, vertexColors: material.vertexColors,
				sizeAttenuation: material.sizeAttenuation, skinning: material.skinning,
				maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
				maxBones: maxBones
		};
1398

1399
		material.program = buildProgram( material.fragmentShader, material.vertexShader, parameters );
M
Mr.doob 已提交
1400

1401
		identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
A
alteredq 已提交
1402
						'cameraInverseMatrix', 'boneGlobalMatrices'
A
alteredq 已提交
1403
						];
A
alteredq 已提交
1404

A
alteredq 已提交
1405
		for( u in material.uniforms ) {
1406

A
alteredq 已提交
1407
			identifiers.push(u);
M
Mr.doob 已提交
1408

A
alteredq 已提交
1409
		}
M
Mr.doob 已提交
1410

A
alteredq 已提交
1411
		cacheUniformLocations( material.program, identifiers );
1412
		cacheAttributeLocations( material.program, [ "position", "normal", "uv", "uv2", "tangent", "color",
A
alteredq 已提交
1413
													 "skinVertexA", "skinVertexB", "skinIndex", "skinWeight" ] );
1414

A
alteredq 已提交
1415
		var attributes = material.program.attributes;
1416

A
alteredq 已提交
1417
		_gl.enableVertexAttribArray( attributes.position );
1418

A
alteredq 已提交
1419
		if ( attributes.color >= 0 ) 	_gl.enableVertexAttribArray( attributes.color );
1420
		if ( attributes.normal >= 0 ) 	_gl.enableVertexAttribArray( attributes.normal );
A
alteredq 已提交
1421
		if ( attributes.tangent >= 0 ) 	_gl.enableVertexAttribArray( attributes.tangent );
1422 1423 1424

		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
1425
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
1426

A
alteredq 已提交
1427 1428 1429 1430
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
1431

A
alteredq 已提交
1432
		}
M
Mr.doob 已提交
1433

1434
	};
1435

1436
	function setProgram( camera, lights, fog, material, object ) {
1437

1438
		if ( !material.program ) _this.initMaterial( material, lights, fog, object );
M
Mr.doob 已提交
1439

1440
		var program = material.program,
A
alteredq 已提交
1441 1442
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
1443

M
Mr.doob 已提交
1444
		if( program != _oldProgram ) {
M
Mr.doob 已提交
1445

M
Mr.doob 已提交
1446 1447
			_gl.useProgram( program );
			_oldProgram = program;
1448

M
Mr.doob 已提交
1449
		}
1450

1451 1452
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
1453
		// refresh uniforms common to several materials
1454 1455

		if ( fog && (
A
alteredq 已提交
1456 1457
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
1458
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
1459 1460 1461
			 material instanceof THREE.LineBasicMaterial ||
			 material instanceof THREE.ParticleBasicMaterial )
			) {
1462

A
alteredq 已提交
1463
			refreshUniformsFog( m_uniforms, fog );
1464 1465

		}
M
Mr.doob 已提交
1466

M
Mr.doob 已提交
1467
		if ( material instanceof THREE.MeshPhongMaterial ||
1468
			 material instanceof THREE.MeshLambertMaterial ) {
1469

A
alteredq 已提交
1470
			setupLights( program, lights );
A
alteredq 已提交
1471
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
1472 1473 1474

		}

1475 1476 1477
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
1478

A
alteredq 已提交
1479
			refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1480

A
alteredq 已提交
1481
		}
M
Mr.doob 已提交
1482

A
alteredq 已提交
1483
		// refresh single material specific uniforms
1484

1485
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
1486

A
alteredq 已提交
1487
			refreshUniformsLine( m_uniforms, material );
1488

A
alteredq 已提交
1489
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
1490

A
alteredq 已提交
1491
			refreshUniformsParticle( m_uniforms, material );
1492

A
alteredq 已提交
1493
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
1494

A
alteredq 已提交
1495
			refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
1496

A
alteredq 已提交
1497
		} else if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
1498

1499 1500
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
1501
			m_uniforms.opacity.value = material.opacity;
1502

A
alteredq 已提交
1503
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
1504

A
alteredq 已提交
1505
			m_uniforms.opacity.value = material.opacity;
1506

1507
		}
1508

A
alteredq 已提交
1509
		// load common uniforms
1510

A
alteredq 已提交
1511 1512
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
1513

A
alteredq 已提交
1514 1515
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
1516

A
alteredq 已提交
1517 1518
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshPhongMaterial ||
1519
			 material.envMap ) {
1520

A
alteredq 已提交
1521
			_gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
1522

1523
		}
1524

A
alteredq 已提交
1525
		if ( material instanceof THREE.MeshShaderMaterial ||
1526
			 material.envMap ||
1527
			 material.skinning ) {
1528

A
alteredq 已提交
1529
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
1530

A
alteredq 已提交
1531
		}
1532

A
alteredq 已提交
1533 1534
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
1535
			 material instanceof THREE.MeshShaderMaterial ||
1536 1537
			 material.skinning ) {

A
alteredq 已提交
1538
			_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
1539

A
alteredq 已提交
1540
		}
1541

1542
		if ( material.skinning ) {
1543

1544
			loadUniformsSkinning( p_uniforms, object );
1545

A
alteredq 已提交
1546
		}
1547

A
alteredq 已提交
1548
		return program;
1549

A
alteredq 已提交
1550
	};
1551

1552
	function renderBuffer ( camera, lights, fog, material, geometryGroup, object ) {
A
alteredq 已提交
1553

1554 1555
		if ( material.opacity == 0 ) return;

A
alteredq 已提交
1556 1557
		var program, attributes, linewidth, primitives;

A
alteredq 已提交
1558
		program = setProgram( camera, lights, fog, material, object );
1559

1560
		attributes = program.attributes;
M
Mr.doob 已提交
1561

1562
		// vertices
M
Mr.doob 已提交
1563

1564
		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
1565
		_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
1566

A
alteredq 已提交
1567 1568 1569 1570
		// colors

		if ( attributes.color >= 0 ) {

1571
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
1572
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
1573 1574 1575

		}

1576
		// normals
M
Mr.doob 已提交
1577

1578
		if ( attributes.normal >= 0 ) {
1579

1580
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
1581
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
1582

1583
		}
1584

1585 1586 1587
		// tangents

		if ( attributes.tangent >= 0 ) {
1588

1589
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
1590
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
1591

1592
		}
1593

1594
		// uvs
M
Mr.doob 已提交
1595

M
Mr.doob 已提交
1596 1597
		if ( attributes.uv >= 0 ) {

1598
			if ( geometryGroup.__webGLUVBuffer ) {
1599

1600
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1601
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
1602

1603
				_gl.enableVertexAttribArray( attributes.uv );
1604

1605
			} else {
1606

1607
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
1608

1609
			}
1610 1611 1612

		}

1613 1614
		if ( attributes.uv2 >= 0 ) {

1615
			if ( geometryGroup.__webGLUV2Buffer ) {
1616

1617
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

1630
		if ( material.skinning &&
1631
			 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
1632
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
1633

1634
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1635 1636
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

1637
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer );
A
alteredq 已提交
1638 1639
			_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );

1640
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer );
A
alteredq 已提交
1641 1642
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

1643
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer );
A
alteredq 已提交
1644
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
1645

A
alteredq 已提交
1646
		}
1647

1648
		// render mesh
M
Mr.doob 已提交
1649

1650
		if ( object instanceof THREE.Mesh ) {
1651

1652
			// wireframe
1653

1654
			if ( material.wireframe ) {
M
Mr.doob 已提交
1655

1656
				_gl.lineWidth( material.wireframeLinewidth );
1657 1658
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 );
1659

1660
			// triangles
1661

1662
			} else {
1663

1664 1665
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
1666

1667
			}
1668

1669
		// render lines
1670

1671
		} else if ( object instanceof THREE.Line ) {
1672

1673
			primitives = ( object.type == THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
M
Mr.doob 已提交
1674

1675
			_gl.lineWidth( material.linewidth );
1676
			_gl.drawArrays( primitives, 0, geometryGroup.__webGLLineCount );
1677

1678
		// render particles
1679

1680
		} else if ( object instanceof THREE.ParticleSystem ) {
1681

1682
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webGLParticleCount );
1683

A
alteredq 已提交
1684
		// render ribbon
1685

A
alteredq 已提交
1686
		} else if ( object instanceof THREE.Ribbon ) {
1687

1688
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webGLVertexCount );
1689

1690 1691 1692 1693
		}

	};

1694
	function renderBufferImmediate ( object, program ) {
1695

A
alteredq 已提交
1696 1697
		if ( ! object.__webGLVertexBuffer ) object.__webGLVertexBuffer = _gl.createBuffer();
		if ( ! object.__webGLNormalBuffer ) object.__webGLNormalBuffer = _gl.createBuffer();
1698

A
alteredq 已提交
1699
		if ( object.hasPos ) {
1700

A
alteredq 已提交
1701 1702 1703 1704
		  _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLVertexBuffer );
		  _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
		  _gl.enableVertexAttribArray( program.attributes.position );
		  _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 );
1705

A
alteredq 已提交
1706
		}
1707

A
alteredq 已提交
1708
		if ( object.hasNormal ) {
1709

A
alteredq 已提交
1710 1711 1712 1713
		  _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLNormalBuffer );
		  _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
		  _gl.enableVertexAttribArray( program.attributes.normal );
		  _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
1714

A
alteredq 已提交
1715
		}
1716

A
alteredq 已提交
1717
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
1718

A
alteredq 已提交
1719
		object.count = 0;
1720

A
alteredq 已提交
1721
	};
1722

1723
	function setObjectFaces ( object ) {
1724

1725
		if ( _oldDoubleSided != object.doubleSided ) {
1726

1727
			if( object.doubleSided ) {
1728

1729
				_gl.disable( _gl.CULL_FACE );
1730

1731
			} else {
1732

A
alteredq 已提交
1733
				_gl.enable( _gl.CULL_FACE );
1734

A
alteredq 已提交
1735
			}
1736

1737
			_oldDoubleSided = object.doubleSided;
1738

1739
		}
1740

1741
		if ( _oldFlipSided != object.flipSided ) {
1742

1743 1744 1745 1746
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

1747
			} else {
1748 1749 1750 1751

				_gl.frontFace( _gl.CCW );

			}
1752

1753
			_oldFlipSided = object.flipSided;
1754 1755

		}
1756

1757
	};
1758

1759
	function setDepthTest ( test ) {
1760

A
alteredq 已提交
1761 1762 1763
		if ( _oldDepth != test ) {

			if( test ) {
1764

A
alteredq 已提交
1765
				_gl.enable( _gl.DEPTH_TEST );
1766

A
alteredq 已提交
1767
			} else {
1768

A
alteredq 已提交
1769
				_gl.disable( _gl.DEPTH_TEST );
1770

A
alteredq 已提交
1771
			}
1772

A
alteredq 已提交
1773 1774 1775
			_oldDepth = test;

		}
1776

A
alteredq 已提交
1777
	};
1778

1779
	function computeFrustum ( m ) {
1780 1781 1782 1783 1784 1785 1786 1787 1788

		_frustum[ 0 ].set( m.n41 - m.n11, m.n42 - m.n12, m.n43 - m.n13, m.n44 - m.n14 );
		_frustum[ 1 ].set( m.n41 + m.n11, m.n42 + m.n12, m.n43 + m.n13, m.n44 + m.n14 );
		_frustum[ 2 ].set( m.n41 + m.n21, m.n42 + m.n22, m.n43 + m.n23, m.n44 + m.n24 );
		_frustum[ 3 ].set( m.n41 - m.n21, m.n42 - m.n22, m.n43 - m.n23, m.n44 - m.n24 );
		_frustum[ 4 ].set( m.n41 - m.n31, m.n42 - m.n32, m.n43 - m.n33, m.n44 - m.n34 );
		_frustum[ 5 ].set( m.n41 + m.n31, m.n42 + m.n32, m.n43 + m.n33, m.n44 + m.n34 );

		var i, plane;
1789

A
alteredq 已提交
1790
		for ( i = 0; i < 6; i ++ ) {
1791 1792 1793 1794 1795 1796 1797

			plane = _frustum[ i ];
			plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) );

		}

	};
1798

1799
	function isInFrustum ( object ) {
1800

1801
		var distance, matrix = object.matrixWorld,
1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813
		radius = - object.geometry.boundingSphere.radius * Math.max( object.scale.x, Math.max( object.scale.y, object.scale.z ) );

		for ( var i = 0; i < 6; i ++ ) {

			distance = _frustum[ i ].x * matrix.n14 + _frustum[ i ].y * matrix.n24 + _frustum[ i ].z * matrix.n34 + _frustum[ i ].w;
			if ( distance <= radius ) return false;

		}

		return true;

	};
1814

1815
	function addToFixedArray ( where, what ) {
1816

1817 1818
		where.list[ where.count ] = what;
		where.count += 1;
1819

1820
	};
1821

1822
	function unrollImmediateBufferMaterials ( globject ) {
1823

1824 1825 1826 1827 1828 1829 1830
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
1831

1832 1833 1834
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			material = object.materials[ m ];
1835

1836 1837 1838 1839
			if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
				addToFixedArray( transparent, material );
			else
				addToFixedArray( opaque, material );
1840

1841
		}
1842

1843
	};
1844

1845
	function unrollBufferMaterials ( globject ) {
1846

1847 1848 1849 1850 1851 1852 1853 1854
		var i, l, m, ml, material, meshMaterial,
			object = globject.object,
			buffer = globject.buffer,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
1855

1856 1857 1858 1859 1860 1861 1862 1863 1864
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			meshMaterial = object.materials[ m ];

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

				for ( i = 0, l = buffer.materials.length; i < l; i++ ) {

					material = buffer.materials[ i ];
1865

1866
					if ( material ) {
1867

1868 1869 1870 1871
						if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
							addToFixedArray( transparent, material );
						else
							addToFixedArray( opaque, material );
1872

1873 1874 1875 1876 1877 1878 1879
					}

				}

			} else {

				material = meshMaterial;
1880

1881 1882
				if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending ) {

1883
					addToFixedArray( transparent, material );
1884 1885 1886

				} else {

1887 1888
					addToFixedArray( opaque, material );

1889 1890
				}

1891 1892 1893
			}

		}
1894

1895
	};
1896 1897


1898
	function painterSort ( a, b ) {
1899

1900
		return b.z - a.z;
1901 1902

	};
1903

1904
	this.render = function ( scene, camera, renderTarget, forceClear ) {
1905

A
alteredq 已提交
1906
		var i, program, opaque, transparent, material,
1907
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
1908
			lights = scene.lights,
1909 1910
			fog = scene.fog,
			ol;
1911

M
Mr.doob 已提交
1912
		camera.matrixAutoUpdate && camera.updateMatrix();
1913

1914
		scene.update( undefined, false, camera );
M
Mr.doob 已提交
1915

M
Mr.doob 已提交
1916
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
1917
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
1918

M
Mr.doob 已提交
1919
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
1920
		computeFrustum( _projScreenMatrix );
1921

A
alteredq 已提交
1922
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
1923

A
alteredq 已提交
1924
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
1925

A
alteredq 已提交
1926
		if ( this.autoClear || forceClear ) {
M
Mr.doob 已提交
1927

1928
			this.clear();
M
Mr.doob 已提交
1929

1930 1931
		}

1932
		// set matrices
1933

1934
		ol = scene.__webglObjects.length;
1935

1936
		for ( o = 0; o < ol; o++ ) {
M
Mr.doob 已提交
1937

1938 1939
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
1940

1941
			if ( object.visible ) {
1942 1943

				if ( ! ( object instanceof THREE.Mesh ) || isInFrustum( object ) ) {
1944

1945
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
1946

1947
					setupMatrices( object, camera );
1948

1949
					unrollBufferMaterials( webglObject );
1950

1951
					webglObject.render = true;
1952

1953
					if ( this.sortObjects ) {
1954

1955 1956 1957
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

1958
						webglObject.z = _vector3.z;
1959

1960
					}
1961

1962
				} else {
1963

1964
					webglObject.render = false;
1965

1966
				}
1967

1968
			} else {
1969

1970
				webglObject.render = false;
1971

1972
			}
1973

1974
		}
1975

1976
		if ( this.sortObjects ) {
1977

1978
			scene.__webglObjects.sort( painterSort );
1979

1980
		}
1981

1982
		oil = scene.__webglObjectsImmediate.length;
1983

1984
		for ( o = 0; o < oil; o++ ) {
1985

1986 1987
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
1988

1989
			if ( object.visible ) {
1990 1991 1992

				if( object.matrixAutoUpdate ) {

1993
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
1994

A
alteredq 已提交
1995
				}
1996

1997
				setupMatrices( object, camera );
1998

1999
				unrollImmediateBufferMaterials( webglObject );
2000

2001
			}
2002

2003
		}
A
alteredq 已提交
2004

2005 2006
		// opaque pass

2007
		setBlending( THREE.NormalBlending );
2008

2009
		for ( o = 0; o < ol; o++ ) {
M
Mr.doob 已提交
2010

2011
			webglObject = scene.__webglObjects[ o ];
2012

2013
			if ( webglObject.render ) {
2014

2015 2016 2017
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
2018

2019
				setObjectFaces( object );
2020

2021
				for( i = 0; i < opaque.count; i++ ) {
2022

2023
					material = opaque.list[ i ];
2024

2025
					setDepthTest( material.depthTest );
A
alteredq 已提交
2026
					renderBuffer( camera, lights, fog, material, buffer, object );
2027

2028
				}
2029 2030 2031 2032 2033

			}

		}

A
alteredq 已提交
2034
		// opaque pass (immediate simulator)
2035

2036
		for ( o = 0; o < oil; o++ ) {
2037

2038 2039
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2040

A
alteredq 已提交
2041
			if ( object.visible ) {
2042

2043
				opaque = webglObject.opaque;
2044

2045
				setObjectFaces( object );
2046

2047
				for( i = 0; i < opaque.count; i++ ) {
2048

2049
					material = opaque.list[ i ];
2050

2051
					setDepthTest( material.depthTest );
2052

A
alteredq 已提交
2053
					program = setProgram( camera, lights, fog, material, object );
2054
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2055

2056
				}
2057

A
alteredq 已提交
2058
			}
2059

A
alteredq 已提交
2060 2061
		}

2062 2063
		// transparent pass

2064
		for ( o = 0; o < ol; o++ ) {
2065

2066
			webglObject = scene.__webglObjects[ o ];
2067

2068
			if ( webglObject.render ) {
2069

2070 2071 2072
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
2073

2074
				setObjectFaces( object );
2075

2076
				for( i = 0; i < transparent.count; i++ ) {
2077

2078
					material = transparent.list[ i ];
2079

2080
					setBlending( material.blending );
2081
					setDepthTest( material.depthTest );
2082

A
alteredq 已提交
2083
					renderBuffer( camera, lights, fog, material, buffer, object );
2084

2085
				}
2086

2087
			}
M
Mr.doob 已提交
2088

M
Mr.doob 已提交
2089
		}
M
Mr.doob 已提交
2090

2091
		// transparent pass (immediate simulator)
2092

2093
		for ( o = 0; o < oil; o++ ) {
2094

2095 2096
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2097

2098
			if ( object.visible ) {
2099

2100
				transparent = webglObject.transparent;
2101

2102
				setObjectFaces( object );
2103

2104
				for( i = 0; i < transparent.count; i++ ) {
2105

2106
					material = transparent.list[ i ];
2107

2108
					setBlending( material.blending );
2109
					setDepthTest( material.depthTest );
2110

A
alteredq 已提交
2111
					program = setProgram( camera, lights, fog, material, object );
2112
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2113

2114
				}
2115

2116
			}
2117

2118
		}
2119

2120
		// Generate mipmap if we're using any kind of mipmap filtering
M
Mr.doob 已提交
2121

2122
		if ( renderTarget && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
M
Mr.doob 已提交
2123

2124
			updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
2125

2126
		}
2127

M
Mr.doob 已提交
2128
	};
M
Mr.doob 已提交
2129

2130
	function setupMatrices ( object, camera ) {
2131

2132 2133
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
2134

2135
	};
2136

A
alteredq 已提交
2137
	this.initWebGLObjects = function ( scene ) {
2138

2139
		if ( !scene.__webglObjects ) {
2140

2141 2142
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
2143 2144 2145

		}

M
Mr.doob 已提交
2146
		while ( scene.__objectsAdded.length ) {
2147

M
Mr.doob 已提交
2148 2149
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
2150 2151 2152

		}

M
Mr.doob 已提交
2153
		while ( scene.__objectsRemoved.length ) {
2154

M
Mr.doob 已提交
2155 2156
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
2157 2158

		}
2159

A
alteredq 已提交
2160
		// update must be called after objects adding / removal
M
Mr.doob 已提交
2161

A
alteredq 已提交
2162 2163
		for ( var o = 0, ol = scene.__webglObjects.length; o < ol; o ++ ) {

M
Mr.doob 已提交
2164
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
2165 2166 2167

		}

2168
	};
2169

2170
	function addObject ( object, scene ) {
2171

2172
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
2173

2174
		if ( object._modelViewMatrix == undefined ) {
2175

2176
			object._modelViewMatrix = new THREE.Matrix4();
2177

2178 2179 2180
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
2181

2182
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
2183

2184
		}
A
alteredq 已提交
2185

2186
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
2187

2188 2189 2190 2191 2192 2193 2194 2195
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

2196
			// create separate VBOs per geometry chunk
A
alteredq 已提交
2197

2198
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
2199

2200
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
2201

2202
				// initialise VBO on the first access
M
Mr.doob 已提交
2203

2204
				if ( ! geometryGroup.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2205

2206 2207
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
2208

2209 2210 2211 2212 2213 2214
					geometry.__dirtyVertices = true;
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
2215

2216
				}
2217

2218
				// create separate wrapper per each use of VBO
2219

M
Mr.doob 已提交
2220
				addBuffer( scene.__webglObjects, geometryGroup, object );
M
Mr.doob 已提交
2221

2222
			}
M
Mr.doob 已提交
2223

A
alteredq 已提交
2224 2225
		} else if ( object instanceof THREE.Ribbon ) {

2226 2227
			geometry = object.geometry;

A
alteredq 已提交
2228 2229 2230 2231 2232 2233 2234 2235 2236 2237
			if( ! geometry.__webGLVertexBuffer ) {

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;

			}

M
Mr.doob 已提交
2238
			addBuffer( scene.__webglObjects, geometry, object );
A
alteredq 已提交
2239

2240
		} else if ( object instanceof THREE.Line ) {
M
Mr.doob 已提交
2241

2242 2243
			geometry = object.geometry;

2244
			if( ! geometry.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2245

2246 2247
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
2248

2249 2250
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
2251

2252
			}
M
Mr.doob 已提交
2253

M
Mr.doob 已提交
2254
			addBuffer( scene.__webglObjects, geometry, object );
2255

A
alteredq 已提交
2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

			if ( ! geometry.__webGLVertexBuffer ) {

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
2267

2268
			}
2269

M
Mr.doob 已提交
2270
			addBuffer( scene.__webglObjects, geometry, object );
M
Mr.doob 已提交
2271

A
alteredq 已提交
2272 2273 2274 2275 2276 2277 2278 2279 2280 2281
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

		}/*else if ( object instanceof THREE.Particle ) {

		}*/

	};

2282
	function updateObject ( object, scene ) {
A
alteredq 已提交
2283

M
Mr.doob 已提交
2284
		var g, geometry, geometryGroup;
A
alteredq 已提交
2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

				if ( geometry.__dirtyVertices || geometry.__dirtyElements ||
					geometry.__dirtyUvs || geometry.__dirtyNormals ||
					geometry.__dirtyColors || geometry.__dirtyTangents ) {

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

2306
			geometry.__dirtyVertices = false;
A
alteredq 已提交
2307 2308 2309 2310
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
2311
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2312

A
alteredq 已提交
2313
		} else if ( object instanceof THREE.Ribbon ) {
M
Mr.doob 已提交
2314

2315 2316
			geometry = object.geometry;

A
alteredq 已提交
2317
			if( geometry.__dirtyVertices || geometry.__dirtyColors ) {
M
Mr.doob 已提交
2318

A
alteredq 已提交
2319
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
2320

A
alteredq 已提交
2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332
			}

			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.Line ) {

			geometry = object.geometry;

			if( geometry.__dirtyVertices ||  geometry.__dirtyColors ) {

				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
2333

2334
			}
2335

A
alteredq 已提交
2336 2337 2338 2339 2340 2341 2342
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

2343
			if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles ) {
M
Mr.doob 已提交
2344

2345
				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
M
Mr.doob 已提交
2346

2347
			}
M
Mr.doob 已提交
2348

2349 2350
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2351

2352
		}/* else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {
2353

A
alteredq 已提交
2354
			// it updates itself in render callback
2355 2356

		} else if ( object instanceof THREE.Particle ) {
2357 2358

		}*/
2359

2360
	};
2361

2362
	function removeObject ( object, scene ) {
M
Mr.doob 已提交
2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379

		var o, ol, zobject;

		for ( o = scene.__webglObjects.length - 1; o >= 0; o-- ) {

			zobject = scene.__webglObjects[ o ].object;

			if ( object == zobject ) {

				scene.__webglObjects.splice( o, 1 );

			}

		}

	};

2380
	function sortFacesByMaterial ( geometry ) {
2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455

		// TODO
		// Should optimize by grouping faces with ColorFill / ColorStroke materials
		// which could then use vertex color attributes instead of each being
		// in its separate VBO

		var i, l, f, fl, face, material, materials, vertices, mhash, ghash, hash_map = {};

		geometry.geometryGroups = {};

		function materialHash( material ) {

			var hash_array = [];

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

				if ( material[ i ] == undefined ) {

					hash_array.push( "undefined" );

				} else {

					hash_array.push( material[ i ].id );

				}

			}

			return hash_array.join( '_' );

		}

		for ( f = 0, fl = geometry.faces.length; f < fl; f++ ) {

			face = geometry.faces[ f ];
			materials = face.materials;

			mhash = materialHash( materials );

			if ( hash_map[ mhash ] == undefined ) {

				hash_map[ mhash ] = { 'hash': mhash, 'counter': 0 };

			}

			ghash = hash_map[ mhash ].hash + '_' + hash_map[ mhash ].counter;

			if ( geometry.geometryGroups[ ghash ] == undefined ) {

				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0 };

			}

			vertices = face instanceof THREE.Face3 ? 3 : 4;

			if ( geometry.geometryGroups[ ghash ].vertices + vertices > 65535 ) {

				hash_map[ mhash ].counter += 1;
				ghash = hash_map[ mhash ].hash + '_' + hash_map[ mhash ].counter;

				if ( geometry.geometryGroups[ ghash ] == undefined ) {

					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0 };

				}

			}

			geometry.geometryGroups[ ghash ].faces.push( f );
			geometry.geometryGroups[ ghash ].vertices += vertices;

		}

	};

2456
	function addBuffer ( objlist, buffer, object ) {
2457

2458 2459 2460 2461
		objlist.push( { buffer: buffer, object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
M
Mr.doob 已提交
2462

2463
	};
2464

2465
	function addBufferImmediate ( objlist, object ) {
2466

2467 2468 2469 2470
		objlist.push( { object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
2471

2472
	};
2473

2474
	this.setFaceCulling = function ( cullFace, frontFace ) {
M
Mr.doob 已提交
2475

2476
		if ( cullFace ) {
M
Mr.doob 已提交
2477

2478
			if ( !frontFace || frontFace == "ccw" ) {
M
Mr.doob 已提交
2479

2480
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
2481

2482
			} else {
M
Mr.doob 已提交
2483

2484
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
2485

2486
			}
M
Mr.doob 已提交
2487

2488
			if( cullFace == "back" ) {
M
Mr.doob 已提交
2489

2490
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
2491

2492
			} else if( cullFace == "front" ) {
M
Mr.doob 已提交
2493

2494
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
2495

2496
			} else {
M
Mr.doob 已提交
2497

2498
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
2499

2500
			}
M
Mr.doob 已提交
2501

2502
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2503

2504
		} else {
M
Mr.doob 已提交
2505

2506
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
2507

2508 2509 2510
		}

	};
N
Nicolas Garcia Belmonte 已提交
2511

2512
	this.supportsVertexTextures = function () {
2513

2514
		return maxVertexTextures() > 0;
2515

2516
	};
2517

2518
	function maxVertexTextures () {
2519

2520 2521 2522
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
2523

2524
	function initGL ( antialias, clearColor, clearAlpha ) {
N
Nicolas Garcia Belmonte 已提交
2525 2526 2527

		try {

2528
			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias } ) ) ) {
N
Nicolas Garcia Belmonte 已提交
2529

2530
				throw 'Error creating WebGL context.';
N
Nicolas Garcia Belmonte 已提交
2531

2532 2533 2534
			}

		} catch ( e ) {
N
Nicolas Garcia Belmonte 已提交
2535

2536
			console.error( e );
N
Nicolas Garcia Belmonte 已提交
2537 2538 2539 2540 2541 2542 2543 2544 2545

		}

		_gl.clearColor( 0, 0, 0, 1 );
		_gl.clearDepth( 1 );

		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthFunc( _gl.LEQUAL );

2546 2547
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
2548
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2549

N
Nicolas Garcia Belmonte 已提交
2550
		_gl.enable( _gl.BLEND );
2551
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
2552
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
2553

A
alteredq 已提交
2554
		_cullEnabled = true;
N
Nicolas Garcia Belmonte 已提交
2555

2556
	};
M
Mr.doob 已提交
2557

2558
	function buildProgram ( fragmentShader, vertexShader, parameters ) {
M
Mr.doob 已提交
2559

M
Mr.doob 已提交
2560
		var program = _gl.createProgram(),
M
Mr.doob 已提交
2561

M
Mr.doob 已提交
2562 2563 2564 2565
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
2566

2567 2568
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
2569

2570 2571
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
2572

2573
			parameters.map ? "#define USE_MAP" : "",
2574 2575 2576
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
2577

2578
			"uniform mat4 viewMatrix;",
2579
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
2580 2581
			""
		].join("\n"),
2582

M
Mr.doob 已提交
2583
		prefix_vertex = [
2584
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
2585

2586 2587 2588
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

2589 2590
			"#define MAX_BONES " + parameters.maxBones,

2591
			parameters.map ? "#define USE_MAP" : "",
2592 2593 2594
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
2595
			parameters.skinning ? "#define USE_SKINNING" : "",
2596

2597 2598
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
2599 2600 2601
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
2602 2603
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
2604
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
2605 2606 2607

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
2608 2609
			"attribute vec3 position;",
			"attribute vec3 normal;",
A
alteredq 已提交
2610
			"attribute vec3 color;",
M
Mr.doob 已提交
2611
			"attribute vec2 uv;",
2612
			"attribute vec2 uv2;",
2613

A
alteredq 已提交
2614 2615 2616 2617
			"attribute vec4 skinVertexA;",
			"attribute vec4 skinVertexB;",
			"attribute vec4 skinIndex;",
			"attribute vec4 skinWeight;",
M
Mr.doob 已提交
2618 2619
			""
		].join("\n");
2620

2621 2622
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
2623

M
Mr.doob 已提交
2624
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
2625

M
Mr.doob 已提交
2626
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
2627

M
Mr.doob 已提交
2628 2629
			alert( "Could not initialise shaders\n"+
					"VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
2630

2631 2632
			//console.log( prefix_fragment + fragmentShader );
			//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
2633

N
Nicolas Garcia Belmonte 已提交
2634
		}
2635

2636 2637
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
2638

M
Mr.doob 已提交
2639
		program.uniforms = {};
2640
		program.attributes = {};
M
Mr.doob 已提交
2641

M
Mr.doob 已提交
2642
		return program;
M
Mr.doob 已提交
2643

M
Mr.doob 已提交
2644
	};
M
Mr.doob 已提交
2645

2646
	function loadUniformsSkinning ( uniforms, object ) {
2647

M
Mr.doob 已提交
2648
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
2649
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
2650

2651
	};
2652

2653
	function loadUniformsMatrices ( uniforms, object ) {
2654

A
alteredq 已提交
2655 2656 2657 2658
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
2659

2660
	function loadUniformsGeneric ( program, uniforms ) {
M
Mr.doob 已提交
2661

2662
		var u, uniform, value, type, location, texture;
M
Mr.doob 已提交
2663

M
Mr.doob 已提交
2664
		for( u in uniforms ) {
M
Mr.doob 已提交
2665

2666 2667
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
2668

2669
			uniform = uniforms[u];
M
Mr.doob 已提交
2670

2671 2672
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
2673

M
Mr.doob 已提交
2674
			if( type == "i" ) {
M
Mr.doob 已提交
2675

M
Mr.doob 已提交
2676
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
2677

M
Mr.doob 已提交
2678
			} else if( type == "f" ) {
M
Mr.doob 已提交
2679

M
Mr.doob 已提交
2680
				_gl.uniform1f( location, value );
2681

A
alteredq 已提交
2682 2683 2684
			} else if( type == "fv1" ) {

				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
2685

2686 2687 2688 2689
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

2690 2691 2692 2693
			} else if( type == "v2" ) {

				_gl.uniform2f( location, value.x, value.y );

2694 2695 2696
			} else if( type == "v3" ) {

				_gl.uniform3f( location, value.x, value.y, value.z );
2697

2698 2699 2700
			} else if( type == "c" ) {

				_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
2701

M
Mr.doob 已提交
2702
			} else if( type == "t" ) {
M
Mr.doob 已提交
2703

M
Mr.doob 已提交
2704
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
2705

2706
				texture = uniform.texture;
M
Mr.doob 已提交
2707

2708
				if ( !texture ) continue;
M
Mr.doob 已提交
2709

2710
				if ( texture.image instanceof Array && texture.image.length == 6 ) {
M
Mr.doob 已提交
2711

2712
					setCubeTexture( texture, value );
M
Mr.doob 已提交
2713

2714
				} else {
M
Mr.doob 已提交
2715

2716
					setTexture( texture, value );
M
Mr.doob 已提交
2717

2718
				}
M
Mr.doob 已提交
2719

2720
			}
M
Mr.doob 已提交
2721

2722
		}
M
Mr.doob 已提交
2723

2724
	};
M
Mr.doob 已提交
2725

2726
	function setBlending ( blending ) {
A
alteredq 已提交
2727 2728

		if ( blending != _oldBlending ) {
2729

A
alteredq 已提交
2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ONE, _gl.ONE );

					break;

				case THREE.SubtractiveBlending:

					//_gl.blendEquation( _gl.FUNC_SUBTRACT );
					_gl.blendFunc( _gl.DST_COLOR, _gl.ZERO );

					break;

				case THREE.BillboardBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA);

					break;

2753 2754 2755 2756 2757 2758
				case THREE.ReverseSubtractiveBlending:

					_gl.blendEquation( _gl.FUNC_REVERSE_SUBTRACT );
					_gl.blendFunc( _gl.ONE, _gl.ONE );

    				break;
A
alteredq 已提交
2759 2760 2761 2762 2763 2764
				default:

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );

					break;
2765

A
alteredq 已提交
2766
			}
2767

A
alteredq 已提交
2768
			_oldBlending = blending;
2769

A
alteredq 已提交
2770 2771 2772
		}

	};
2773

2774
	function setTextureParameters ( textureType, texture, image ) {
2775

2776
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
2777

2778 2779
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
2780

2781 2782
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
2783

2784
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
2785

2786
		} else {
M
Mr.doob 已提交
2787

2788 2789 2790 2791 2792
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
			
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
2793

2794
		}
M
Mr.doob 已提交
2795

2796 2797
	};
	
2798
	function setTexture ( texture, slot ) {
2799

2800
		if ( texture.needsUpdate ) {
A
alteredq 已提交
2801

2802
			if ( !texture.__wasSetOnce ) {
M
Mr.doob 已提交
2803

2804
				texture.__webGLTexture = _gl.createTexture();
A
alteredq 已提交
2805

2806 2807
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture );
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
2808

A
alteredq 已提交
2809
				texture.__wasSetOnce = true;
M
Mr.doob 已提交
2810

A
alteredq 已提交
2811
			} else {
M
Mr.doob 已提交
2812

A
alteredq 已提交
2813 2814
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture );
				_gl.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
2815 2816 2817

			}

2818 2819 2820
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			
A
alteredq 已提交
2821
			texture.needsUpdate = false;
2822 2823 2824 2825

		}

		_gl.activeTexture( _gl.TEXTURE0 + slot );
M
Mr.doob 已提交
2826
		_gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture );
M
Mr.doob 已提交
2827

2828
	};
M
Mr.doob 已提交
2829

2830
	function setCubeTexture ( texture, slot ) {
2831 2832 2833 2834

		if ( texture.image.length == 6 ) {

			if ( texture.needsUpdate ) {
2835 2836
				
				if ( !texture.__wasSetOnce ) {
2837 2838 2839

					texture.image.__webGLTextureCube = _gl.createTexture();

2840
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
2841

2842
					for ( var i = 0; i < 6; ++i ) {
2843

2844
						_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
2845

2846 2847 2848
					}
				
					texture.__wasSetOnce = true;
2849 2850 2851

				} else {

2852
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
2853

2854
					for ( var i = 0; i < 6; ++i ) {
2855

2856
						_gl.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
2857

2858
					}
2859 2860 2861

				}

2862
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
2863 2864 2865
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
2866
				
2867 2868 2869 2870 2871 2872 2873 2874 2875
			}

			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );

		}

	};

2876
	function setRenderTarget ( renderTexture ) {
2877 2878

		if ( renderTexture && !renderTexture.__webGLFramebuffer ) {
M
Mr.doob 已提交
2879

2880 2881 2882 2883 2884
			renderTexture.__webGLFramebuffer = _gl.createFramebuffer();
			renderTexture.__webGLRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webGLTexture = _gl.createTexture();

			// Setup renderbuffer
M
Mr.doob 已提交
2885

2886 2887 2888 2889
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );

			// Setup texture
M
Mr.doob 已提交
2890

2891
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webGLTexture );
2892 2893 2894 2895
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, paramThreeToGL( renderTexture.wrapS ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, paramThreeToGL( renderTexture.wrapT ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( renderTexture.magFilter ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( renderTexture.minFilter ) );
2896
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
2897 2898

			// Setup framebuffer
M
Mr.doob 已提交
2899

2900 2901
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webGLFramebuffer );
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webGLTexture, 0 );
2902
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
2903 2904

			// Release everything
M
Mr.doob 已提交
2905

2906 2907 2908
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
2909

2910 2911
		}

2912
		var framebuffer, width, height;
M
Mr.doob 已提交
2913

2914
		if ( renderTexture ) {
M
Mr.doob 已提交
2915

2916 2917 2918
			framebuffer = renderTexture.__webGLFramebuffer;
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
2919

2920
		} else {
M
Mr.doob 已提交
2921

2922
			framebuffer = null;
2923 2924
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
2925

2926
		}
M
Mr.doob 已提交
2927

2928
		if( framebuffer != _oldFramebuffer ) {
M
Mr.doob 已提交
2929

2930
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2931
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
2932

2933
			_oldFramebuffer = framebuffer;
M
Mr.doob 已提交
2934

2935
		}
2936

2937
	};
M
Mr.doob 已提交
2938

2939
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
2940

2941 2942 2943
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webGLTexture );
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
2944 2945

	};
2946

2947
	function cacheUniformLocations ( program, identifiers ) {
M
Mr.doob 已提交
2948

M
Mr.doob 已提交
2949
		var i, l, id;
M
Mr.doob 已提交
2950

M
Mr.doob 已提交
2951
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
2952

2953 2954
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
2955

M
Mr.doob 已提交
2956
		}
M
Mr.doob 已提交
2957

M
Mr.doob 已提交
2958
	};
M
Mr.doob 已提交
2959

2960
	function cacheAttributeLocations ( program, identifiers ) {
2961

2962
		var i, l, id;
M
Mr.doob 已提交
2963

2964
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
2965

2966 2967
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
2968

2969
		}
M
Mr.doob 已提交
2970

M
Mr.doob 已提交
2971
	};
M
Mr.doob 已提交
2972

2973
	function getShader ( type, string ) {
N
Nicolas Garcia Belmonte 已提交
2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997

		var shader;

		if ( type == "fragment" ) {

			shader = _gl.createShader( _gl.FRAGMENT_SHADER );

		} else if ( type == "vertex" ) {

			shader = _gl.createShader( _gl.VERTEX_SHADER );

		}

		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );

		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {

			alert( _gl.getShaderInfoLog( shader ) );
			return null;

		}

		return shader;
M
Mr.doob 已提交
2998

2999
	};
N
Nicolas Garcia Belmonte 已提交
3000

3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018
	// fallback filters for non-power-of-2 textures
	
	function filterFallback ( f ) {
		
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
			case THREE.LinearMipMapLinearFilter: return _gl.LINEAR; break;

		}
		
	};
	
3019
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
3020

3021
		switch ( p ) {
M
Mr.doob 已提交
3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034

			case THREE.RepeatWrapping: return _gl.REPEAT; break;
			case THREE.ClampToEdgeWrapping: return _gl.CLAMP_TO_EDGE; break;
			case THREE.MirroredRepeatWrapping: return _gl.MIRRORED_REPEAT; break;

			case THREE.NearestFilter: return _gl.NEAREST; break;
			case THREE.NearestMipMapNearestFilter: return _gl.NEAREST_MIPMAP_NEAREST; break;
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST_MIPMAP_LINEAR; break;

			case THREE.LinearFilter: return _gl.LINEAR; break;
			case THREE.LinearMipMapNearestFilter: return _gl.LINEAR_MIPMAP_NEAREST; break;
			case THREE.LinearMipMapLinearFilter: return _gl.LINEAR_MIPMAP_LINEAR; break;

3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048
			case THREE.ByteType: return _gl.BYTE; break;
			case THREE.UnsignedByteType: return _gl.UNSIGNED_BYTE; break;
			case THREE.ShortType: return _gl.SHORT; break;
			case THREE.UnsignedShortType: return _gl.UNSIGNED_SHORT; break;
			case THREE.IntType: return _gl.INT; break;
			case THREE.UnsignedShortType: return _gl.UNSIGNED_INT; break;
			case THREE.FloatType: return _gl.FLOAT; break;

			case THREE.AlphaFormat: return _gl.ALPHA; break;
			case THREE.RGBFormat: return _gl.RGB; break;
			case THREE.RGBAFormat: return _gl.RGBA; break;
			case THREE.LuminanceFormat: return _gl.LUMINANCE; break;
			case THREE.LuminanceAlphaFormat: return _gl.LUMINANCE_ALPHA; break;

3049
		}
M
Mr.doob 已提交
3050

3051
		return 0;
M
Mr.doob 已提交
3052

3053 3054
	};

3055
	function isPowerOfTwo ( value ) {
3056 3057 3058 3059 3060

		return ( value & ( value - 1 ) ) == 0;

	};

3061
	function materialNeedsSmoothNormals ( material ) {
3062 3063 3064

		return material && material.shading != undefined && material.shading == THREE.SmoothShading;

3065
	};
M
Mr.doob 已提交
3066

3067
	function bufferNeedsSmoothNormals ( geometryGroup, object ) {
M
Mr.doob 已提交
3068

3069
		var m, ml, i, l, meshMaterial, needsSmoothNormals = false;
M
Mr.doob 已提交
3070

M
Mr.doob 已提交
3071
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
3072

M
Mr.doob 已提交
3073
			meshMaterial = object.materials[ m ];
3074 3075 3076

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

3077
				for ( i = 0, l = geometryGroup.materials.length; i < l; i++ ) {
3078

3079
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
3080

3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
3102

3103
		return needsSmoothNormals;
M
Mr.doob 已提交
3104

3105
	};
M
Mr.doob 已提交
3106

3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129
	function allocateBones ( object ) {
		
		// default for when object is not specified
		// ( for example when prebuilding shader
		//   to be used with multiple objects )
		//
		// 	- leave some extra space for other uniforms
		//  - limit here is ANGLE's 254 max uniform vectors
		//    (up to 54 should be safe)
		
		var maxBones = 50;
		
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
			
			maxBones = object.bones.length;

		}

		return maxBones;
		
	};
	
	function allocateLights ( lights, maxLights ) {
3130

3131 3132
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
3133

3134
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
3135

3136
			light = lights[ l ];
3137

3138 3139
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
3140

3141
		}
3142

3143
		if ( ( pointLights + dirLights ) <= maxLights ) {
3144

3145 3146
			maxDirLights = dirLights;
			maxPointLights = pointLights;
3147

3148
		} else {
3149

3150 3151
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
3152 3153 3154

		}

3155
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
3156 3157

	};
M
Mr.doob 已提交
3158

A
alteredq 已提交
3159
	/* DEBUG
3160
	function getGLParams() {
M
Mr.doob 已提交
3161

3162
		var params  = {
M
Mr.doob 已提交
3163

3164 3165
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
3166

3167 3168 3169
			'MAX_TEXTURE_IMAGE_UNITS': _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS ),
			'MAX_VERTEX_TEXTURE_IMAGE_UNITS': _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ),
			'MAX_COMBINED_TEXTURE_IMAGE_UNITS' : _gl.getParameter( _gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS ),
M
Mr.doob 已提交
3170

3171 3172 3173
			'MAX_VERTEX_UNIFORM_VECTORS': _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS ),
			'MAX_FRAGMENT_UNIFORM_VECTORS': _gl.getParameter( _gl.MAX_FRAGMENT_UNIFORM_VECTORS )
		}
M
Mr.doob 已提交
3174

3175 3176
		return params;
	};
M
Mr.doob 已提交
3177

3178
	function dumpObject( obj ) {
M
Mr.doob 已提交
3179

3180 3181
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
3182

3183
			str += p + ": " + obj[p] + "\n";
M
Mr.doob 已提交
3184

3185
		}
M
Mr.doob 已提交
3186

3187 3188
		return str;
	}
A
alteredq 已提交
3189
	*/
3190

3191
};