WebGLRenderer.js 83.6 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

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

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

89 90
	this.context = _gl;

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

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

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

	};
N
Nicolas Garcia Belmonte 已提交
101

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

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

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

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

140
	};
A
alteredq 已提交
141

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

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

	};
147

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

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

	};

M
Mr.doob 已提交
154

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

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

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

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

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

168
			dlength = 0,
169
			plength = 0,
170

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

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

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

			if ( light instanceof THREE.AmbientLight ) {

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

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

189
				doffset = dlength * 3;
190

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

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

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

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

203
				poffset = plength * 3;
204

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

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

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

215 216 217
			}

		}
218

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

222 223
		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 已提交
224

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

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

232
	};
M
Mr.doob 已提交
233

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

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

239
	};
M
Mr.doob 已提交
240

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

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

246
	};
247

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

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

	};

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

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

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

269 270
		geometryGroup.__webGLFaceBuffer = _gl.createBuffer();
		geometryGroup.__webGLLineBuffer = _gl.createBuffer();
271 272
		
		
273
		if( geometryGroup.numMorphTargets ) {
274
			
275 276
			var m, ml;
			geometryGroup.__webGLMorphTargetsBuffers = []; 
277
			
278
			for( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m++ ) {
279
				
280
				geometryGroup.__webGLMorphTargetsBuffers.push( _gl.createBuffer());	
281 282 283
			}

		}
M
Mr.doob 已提交
284

285
	};
286

287
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
288

289 290 291
		var nvertices = geometry.vertices.length;

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

294
		geometry.__webGLLineCount = nvertices;
M
Mr.doob 已提交
295

296
	};
M
Mr.doob 已提交
297

298
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
299 300 301 302 303 304 305 306 307

		var nvertices = geometry.vertices.length;

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

		geometry.__webGLVertexCount = nvertices;

	};
308

309
	function initParticleBuffers ( geometry ) {
310 311 312 313

		var nvertices = geometry.vertices.length;

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

316
		geometry.__sortArray = [];
317 318 319 320 321

		geometry.__webGLParticleCount = nvertices;

	};

322
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
323

324
		var f, fl, nvertices = 0, ntris = 0, nlines = 0,
M
Mr.doob 已提交
325
			obj_faces = object.geometry.faces,
326
			chunk_faces = geometryGroup.faces;
M
Mr.doob 已提交
327

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

330 331
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
332

333
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
334

335 336 337
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
338

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

341 342
				nvertices += 4;
				ntris += 2;
343
				nlines += 4;
M
Mr.doob 已提交
344

345
			}
M
Mr.doob 已提交
346

347
		}
M
Mr.doob 已提交
348

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

351 352 353 354 355 356
		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 已提交
357

358 359 360 361
		geometryGroup.__skinVertexAArray = new Float32Array( nvertices * 4 );
		geometryGroup.__skinVertexBArray = new Float32Array( nvertices * 4 );
		geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
		geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 );
362

363 364
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
365

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

368 369
		geometryGroup.__webGLFaceCount = ntris * 3;
		geometryGroup.__webGLLineCount = nlines * 2;
M
Mr.doob 已提交
370

371
		if( geometryGroup.numMorphTargets ) {
372
			
373 374
			var m, ml;
			geometryGroup.__morphTargetsArrays = []; 
375
			
376
			for( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m++ ) {
377
				
378
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ));
379 380 381 382
			}

		}

383
	};
M
Mr.doob 已提交
384

385
	function setMeshBuffers ( geometryGroup, object, hint ) {
386

387 388
		var f, fl, fi, face, vertexNormals, faceNormal, normal,
			uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
389
			c1, c2, c3, c4,
A
alteredq 已提交
390 391 392 393
			sw1, sw2, sw3, sw4,
			si1, si2, si3, si4,
			sa1, sa2, sa3, sa4,
			sb1, sb2, sb3, sb4,
394
			m, ml, i,
395
			vn, uvi, uv2i,
396
			vk, vkl, vka,
M
Mr.doob 已提交
397

398
		vertexIndex = 0,
399

400 401
		offset = 0,
		offset_uv = 0,
402
		offset_uv2 = 0,
403 404 405 406
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
407
		offset_color = 0,
A
alteredq 已提交
408
		offset_skin = 0,
409
		offset_morphTarget = 0,
M
Mr.doob 已提交
410

411 412 413 414 415 416
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
417

418 419 420 421
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
422

423 424
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

425 426
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
427

428
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
429

430
		geometry = object.geometry, // this is shared for all chunks
431

432
		dirtyVertices = geometry.__dirtyVertices,
433 434 435
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
436
		dirtyTangents = geometry.__dirtyTangents,
437
		dirtyColors = geometry.__dirtyColors,
438
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
439

440
		vertices = geometry.vertices,
441
		chunk_faces = geometryGroup.faces,
442
		obj_faces = geometry.faces,
443
		obj_uvs = geometry.uvs,
444
		obj_uvs2 = geometry.uvs2,
A
alteredq 已提交
445
		obj_colors = geometry.colors,
446

A
alteredq 已提交
447 448 449
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
450 451 452 453
		obj_skinWeights = geometry.skinWeights,

		morphTargets = geometry.morphTargets;
		
454

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

457 458 459
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
			uv = obj_uvs[ fi ];
460
			uv2 = obj_uvs2[ fi ];
M
Mr.doob 已提交
461

462
			vertexNormals = face.vertexNormals;
463
			faceNormal = face.normal;
464 465 466

			if ( face instanceof THREE.Face3 ) {

467
				if ( dirtyVertices ) {
M
Mr.doob 已提交
468

469 470 471
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
472

473 474 475
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
476

477 478 479
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
480

481 482 483
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
484

485
					offset += 9;
M
Mr.doob 已提交
486

487
				}
488

489
				if ( dirtyMorphTargets ) {
490
					
491
					for( vk = 0, vkl = morphTargets.length; vk < vkl; vk++ ) {
492
						
493 494 495
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
496

497
						vka = morphTargetsArrays[ vk ];
498
	
499 500 501
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
502
	
503 504 505
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
506
	
507 508 509
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
510 511
					}

512
					offset_morphTarget += 9;
513 514 515
					
				}

A
alteredq 已提交
516 517 518
				if ( obj_skinWeights.length ) {

					// weights
519

A
alteredq 已提交
520 521 522
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
523

A
alteredq 已提交
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
					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
540

A
alteredq 已提交
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
					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
561

A
alteredq 已提交
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
					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
582

A
alteredq 已提交
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
					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;
603

A
alteredq 已提交
604
				}
605

606
				if ( dirtyColors && obj_colors.length ) {
607

608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
					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;
623

624 625 626 627
					offset_color += 9;

				}

628
				if ( dirtyTangents && geometry.hasTangents ) {
629

630 631 632
					t1 = vertices[ face.a ].tangent;
					t2 = vertices[ face.b ].tangent;
					t3 = vertices[ face.c ].tangent;
633

634 635 636 637
					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 已提交
638

639 640 641 642
					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 已提交
643

644 645 646 647
					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 已提交
648

649
					offset_tangent += 12;
M
Mr.doob 已提交
650

651 652
				}

653
				if ( dirtyNormals ) {
M
Mr.doob 已提交
654

655 656 657
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

659
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
660

661 662 663
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
664

665
							offset_normal += 3;
M
Mr.doob 已提交
666

667
						}
M
Mr.doob 已提交
668

669
					} else {
670

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

673 674 675
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
676

677
							offset_normal += 3;
M
Mr.doob 已提交
678

679
						}
M
Mr.doob 已提交
680 681

					}
M
Mr.doob 已提交
682

683 684
				}

685
				if ( dirtyUvs && uv ) {
686

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

689
						uvi = uv[ i ];
M
Mr.doob 已提交
690

691 692
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
693

694
						offset_uv += 2;
M
Mr.doob 已提交
695

M
Mr.doob 已提交
696
					}
697 698 699

				}

700 701 702 703 704 705 706 707 708 709 710 711 712 713 714
				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;

					}

				}

715
				if( dirtyElements ) {
M
Mr.doob 已提交
716

717 718 719
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
720

721
					offset_face += 3;
M
Mr.doob 已提交
722

723 724
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
725

726 727
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
728

729 730
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
731

732
					offset_line += 6;
733

734
					vertexIndex += 3;
M
Mr.doob 已提交
735

736
				}
M
Mr.doob 已提交
737

738 739 740

			} else if ( face instanceof THREE.Face4 ) {

741
				if ( dirtyVertices ) {
M
Mr.doob 已提交
742

743 744 745 746
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
747

748 749 750
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
751

752 753 754
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
755

756 757 758
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
759

760 761 762
					vertexArray[ offset + 9 ] = v4.x;
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
763

764
					offset += 12;
M
Mr.doob 已提交
765

766
				}
767

768
				if ( dirtyMorphTargets ) {
769
					
770
					for( vk = 0, vkl = morphTargets.length; vk < vkl; vk++ ) {
771
						
772 773 774 775
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
						v4 = morphTargets[ vk ].vertices[ face.d ].position;
776
	
777
						vka = morphTargetsArrays[ vk ];
778
	
779 780 781
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
782
	
783 784 785
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
786
	
787 788 789
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
790
	
791 792 793
						vka[ offset_morphTarget + 9 ] = v4.x;
						vka[ offset_morphTarget + 10 ] = v4.y;
						vka[ offset_morphTarget + 11 ] = v4.z;
794 795
					}

796
					offset_morphTarget += 12;
797 798 799
					
				}

A
alteredq 已提交
800 801 802
				if ( obj_skinWeights.length ) {

					// weights
803

A
alteredq 已提交
804 805 806 807
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
808

A
alteredq 已提交
809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829
					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
830

A
alteredq 已提交
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856
					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
857

A
alteredq 已提交
858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883
					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
884

A
alteredq 已提交
885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909
					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;

910 911
					offset_skin += 16;

A
alteredq 已提交
912
				}
913

914 915 916 917 918
				if ( dirtyColors && obj_colors.length ) {

					c1 = obj_colors[ face.a ];
					c2 = obj_colors[ face.b ];
					c3 = obj_colors[ face.c ];
919
					c4 = obj_colors[ face.d ];
920 921 922 923 924 925 926 927 928 929 930 931

					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;
932

933 934 935
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
936

937 938
					offset_color += 12;

939 940
				}

941
				if ( dirtyTangents && geometry.hasTangents ) {
942

943 944 945 946
					t1 = vertices[ face.a ].tangent;
					t2 = vertices[ face.b ].tangent;
					t3 = vertices[ face.c ].tangent;
					t4 = vertices[ face.d ].tangent;
947

948 949 950 951
					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 已提交
952

953 954 955 956
					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 已提交
957

958 959 960 961
					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 已提交
962

963 964 965 966
					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 已提交
967

968
					offset_tangent += 16;
M
Mr.doob 已提交
969

970
				}
M
Mr.doob 已提交
971

972
				if( dirtyNormals ) {
M
Mr.doob 已提交
973

974
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
975

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

978
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
979

980 981 982
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
983

984
							offset_normal += 3;
M
Mr.doob 已提交
985

986
						}
M
Mr.doob 已提交
987

988
					} else {
989

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

992 993 994
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
995

996
							offset_normal += 3;
M
Mr.doob 已提交
997

998
						}
M
Mr.doob 已提交
999 1000

					}
M
Mr.doob 已提交
1001

1002 1003
				}

1004
				if ( dirtyUvs && uv ) {
1005

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

1008
						uvi = uv[ i ];
M
Mr.doob 已提交
1009

1010 1011
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1012

1013
						offset_uv += 2;
M
Mr.doob 已提交
1014

M
Mr.doob 已提交
1015
					}
1016 1017

				}
1018

1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
				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 已提交
1033

1034
				if ( dirtyElements ) {
M
Mr.doob 已提交
1035

1036 1037 1038
					faceArray[ offset_face ]     = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
1039

1040 1041 1042
					faceArray[ offset_face + 3 ] = vertexIndex;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
1043

1044
					offset_face += 6;
M
Mr.doob 已提交
1045

1046 1047
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1048

1049
					lineArray[ offset_line + 2 ] = vertexIndex;
1050
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
1051

1052 1053
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1054

1055 1056
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
1057

1058
					offset_line += 8;
M
Mr.doob 已提交
1059

1060
					vertexIndex += 4;
M
Mr.doob 已提交
1061

1062
				}
M
Mr.doob 已提交
1063

1064
			}
M
Mr.doob 已提交
1065

1066 1067
		}

1068
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1069

1070
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
1071
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1072

1073
		}
M
Mr.doob 已提交
1074

1075
		if ( dirtyMorphTargets ) {
1076
			
1077
			for( vk = 0, vkl = morphTargets.length; vk < vkl; vk++ ) {
1078
		
1079 1080
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLMorphTargetsBuffers[ vk ] );
				_gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
1081 1082 1083 1084
				
			}
		}

1085 1086
		if ( dirtyColors && obj_colors.length ) {

1087
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
1088 1089 1090
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
1091

1092
		if ( dirtyNormals ) {
M
Mr.doob 已提交
1093

1094
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
1095
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1096

1097 1098
		}

1099
		if ( dirtyTangents && geometry.hasTangents ) {
1100

1101
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
1102
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
1103

1104
		}
1105

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

1108
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1109
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
1110

1111
		}
M
Mr.doob 已提交
1112

1113 1114
		if ( dirtyUvs && offset_uv2 > 0 ) {

1115
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
1116 1117 1118 1119
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

1120
		if ( dirtyElements ) {
M
Mr.doob 已提交
1121

1122
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
1123
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1124

1125
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
1126
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
1127

1128
		}
1129

1130
		if ( offset_skin > 0 ) {
1131

1132
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1133 1134
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

1135
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer );
A
alteredq 已提交
1136 1137
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

1138
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer );
A
alteredq 已提交
1139 1140
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

1141
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer );
A
alteredq 已提交
1142
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1143

A
alteredq 已提交
1144
		}
1145 1146

	};
1147

1148
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1149

1150
		var v, c, vertex, offset,
1151
			vertices = geometry.vertices,
1152
			colors = geometry.colors,
1153
			vl = vertices.length,
1154
			cl = colors.length,
M
Mr.doob 已提交
1155 1156

			vertexArray = geometry.__vertexArray,
1157
			colorArray = geometry.__colorArray,
1158 1159

			dirtyVertices = geometry.__dirtyVertices,
1160
			dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1161

1162
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1163

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

1166
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1167

1168
				offset = v * 3;
M
Mr.doob 已提交
1169

1170 1171 1172
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1173

1174 1175
			}

A
alteredq 已提交
1176 1177 1178
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1179
		}
M
Mr.doob 已提交
1180

1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
		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 );

		}

1200
	};
M
Mr.doob 已提交
1201

1202
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
1203 1204 1205 1206 1207 1208 1209 1210 1211

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

			vertexArray = geometry.__vertexArray,
			colorArray = geometry.__colorArray,
1212 1213

			dirtyVertices = geometry.__dirtyVertices,
A
alteredq 已提交
1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
			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 );

		}

	};
1255

1256
	function setParticleBuffers ( geometry, hint, object ) {
1257

A
alteredq 已提交
1258
		var v, c, vertex, offset,
1259 1260 1261
			vertices = geometry.vertices,
			vl = vertices.length,

A
alteredq 已提交
1262 1263
			colors = geometry.colors,
			cl = colors.length,
1264

1265
			vertexArray = geometry.__vertexArray,
A
alteredq 已提交
1266
			colorArray = geometry.__colorArray,
1267

1268
			sortArray = geometry.__sortArray,
1269

1270 1271 1272
			dirtyVertices = geometry.__dirtyVertices,
			dirtyElements = geometry.__dirtyElements,
			dirtyColors = geometry.__dirtyColors;
1273

1274
		if ( object.sortParticles ) {
1275

1276
			_projScreenMatrix.multiplySelf( object.matrixWorld );
1277

1278 1279 1280
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
1281

1282 1283
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
1284

1285
				sortArray[ v ] = [ _vector3.z, v ];
1286

1287
			}
1288

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

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

1293
				vertex = vertices[ sortArray[v][1] ].position;
1294

1295
				offset = v * 3;
1296

1297 1298 1299
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
1300

1301
			}
1302

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

A
alteredq 已提交
1305
				offset = c * 3;
1306

A
alteredq 已提交
1307 1308 1309 1310 1311
				color = colors[ sortArray[c][1] ];

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

1313
			}
1314 1315


1316
		} else {
1317

1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330
			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;

				}
1331 1332

			}
1333

A
alteredq 已提交
1334
			if ( dirtyColors ) {
1335

A
alteredq 已提交
1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
				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;

1346
				}
1347

A
alteredq 已提交
1348
			}
1349 1350

		}
1351

A
alteredq 已提交
1352
		if ( dirtyVertices || object.sortParticles ) {
1353

A
alteredq 已提交
1354 1355
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
1356

A
alteredq 已提交
1357
		}
1358

A
alteredq 已提交
1359
		if ( dirtyColors || object.sortParticles ) {
1360

A
alteredq 已提交
1361 1362
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
1363

A
alteredq 已提交
1364
		}
1365

1366
	};
M
Mr.doob 已提交
1367

1368
	function setMaterialShaders ( material, shaders ) {
1369

1370 1371
		material.fragmentShader = shaders.fragmentShader;
		material.vertexShader = shaders.vertexShader;
1372
		material.uniforms = Uniforms.clone( shaders.uniforms );
1373

M
Mr.doob 已提交
1374
	};
1375

1376
	function refreshUniformsCommon ( uniforms, material ) {
M
Mr.doob 已提交
1377

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

1381
		// pure color
A
alteredq 已提交
1382
		//uniforms.color.value.setHex( material.color.hex );
M
Mr.doob 已提交
1383

A
alteredq 已提交
1384 1385
		uniforms.opacity.value = material.opacity;
		uniforms.map.texture = material.map;
1386

1387
		uniforms.lightMap.texture = material.lightMap;
1388

1389
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
1390
		uniforms.reflectivity.value = material.reflectivity;
1391
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
1392
		uniforms.combine.value = material.combine;
1393
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
1394

1395
	};
1396

1397
	function refreshUniformsLine ( uniforms, material ) {
1398

A
alteredq 已提交
1399 1400
		uniforms.diffuse.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
		uniforms.opacity.value = material.opacity;
1401 1402

	};
M
Mr.doob 已提交
1403

1404
	function refreshUniformsParticle ( uniforms, material ) {
1405

A
alteredq 已提交
1406 1407 1408
		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 已提交
1409
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
A
alteredq 已提交
1410
		uniforms.map.texture = material.map;
1411

A
alteredq 已提交
1412
	};
1413

1414
	function refreshUniformsFog ( uniforms, fog ) {
1415

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

A
alteredq 已提交
1418
		if ( fog instanceof THREE.Fog ) {
1419

A
alteredq 已提交
1420 1421
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
1422

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

A
alteredq 已提交
1425
			uniforms.fogDensity.value = fog.density;
1426 1427

		}
1428

1429 1430
	};

1431
	function refreshUniformsPhong ( uniforms, material ) {
M
Mr.doob 已提交
1432

A
alteredq 已提交
1433 1434 1435 1436 1437
		//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 已提交
1438

1439
	};
M
Mr.doob 已提交
1440 1441


1442
	function refreshUniformsLights ( uniforms, lights ) {
M
Mr.doob 已提交
1443

A
alteredq 已提交
1444 1445 1446 1447 1448 1449
		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 已提交
1450

A
alteredq 已提交
1451
	};
M
Mr.doob 已提交
1452

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

M
Mikael Emtinger 已提交
1455
		var u, a, identifiers, i, parameters, maxLightCount, maxBones;
1456

A
alteredq 已提交
1457
		if ( material instanceof THREE.MeshDepthMaterial ) {
1458

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

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

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

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

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

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

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

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

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

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

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

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

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

A
alteredq 已提交
1485
		}
1486

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

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

1492 1493
		maxBones = allocateBones( object );
		
1494
		parameters = { fog: fog, map: material.map, envMap: material.envMap, lightMap: material.lightMap, vertexColors: material.vertexColors,
A
alteredq 已提交
1495
					   sizeAttenuation: material.sizeAttenuation,
1496
					   skinning: material.skinning,
1497
					   morphTargets: material.morphTargets,
1498 1499
					   maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
					   maxBones: maxBones };
1500

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

M
Mikael Emtinger 已提交
1503 1504 1505

		// load uniforms

1506
		identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
1507
						'cameraInverseMatrix', 'boneGlobalMatrices', 'morphTargetInfluences'
A
alteredq 已提交
1508
						];
A
alteredq 已提交
1509

M
Mikael Emtinger 已提交
1510

A
alteredq 已提交
1511
		for( u in material.uniforms ) {
1512

A
alteredq 已提交
1513 1514
			identifiers.push(u);
		}
M
Mr.doob 已提交
1515

A
alteredq 已提交
1516
		cacheUniformLocations( material.program, identifiers );
1517
		
M
Mikael Emtinger 已提交
1518 1519

		// load attributes
1520 1521 1522 1523 1524 1525 1526 1527 1528
		
		identifiers = [ "position", "normal", "uv", "uv2", "tangent", "color",
					    "skinVertexA", "skinVertexB", "skinIndex", "skinWeight" ];
		
		for( i = 0; i < this.maxMorphTargets; i++ ) {
			
			identifiers.push( "morphTarget" + i );
		}
		
M
Mikael Emtinger 已提交
1529 1530 1531 1532 1533
		for( a in material.attributes ) {
			
			identifiers.push( a );
		}
		
1534 1535
		cacheAttributeLocations( material.program, identifiers );

1536

A
alteredq 已提交
1537
		var attributes = material.program.attributes;
1538

A
alteredq 已提交
1539
		_gl.enableVertexAttribArray( attributes.position );
1540

A
alteredq 已提交
1541
		if ( attributes.color >= 0 ) 	_gl.enableVertexAttribArray( attributes.color );
1542
		if ( attributes.normal >= 0 ) 	_gl.enableVertexAttribArray( attributes.normal );
A
alteredq 已提交
1543
		if ( attributes.tangent >= 0 ) 	_gl.enableVertexAttribArray( attributes.tangent );
1544 1545 1546

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

A
alteredq 已提交
1549 1550 1551 1552
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
1553

A
alteredq 已提交
1554
		}
1555
		
1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567
		if ( material.morphTargets ) {
			
			material.numSupportedMorphTargets = 0;
			
			if( attributes.morphTarget0 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget0 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget1 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget1 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget2 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget2 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget3 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget3 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget4 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget4 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget5 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget5 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget6 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget6 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget7 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget7 ); material.numSupportedMorphTargets++ }
1568
			 	
1569 1570 1571 1572 1573 1574 1575 1576
			object.__webGLMorphTargetInfluences = new Float32Array( this.maxMorphTargets );
			
			for( var i = 0; i < this.maxMorphTargets; i++ ) {
				
				object.__webGLMorphTargetInfluences[ i ] = 0;
				
			}
			
1577
		}
M
Mr.doob 已提交
1578

1579
	};
1580

1581
	function setProgram( camera, lights, fog, material, object ) {
1582

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

1585
		var program = material.program,
A
alteredq 已提交
1586 1587
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
1588

M
Mr.doob 已提交
1589
		if( program != _oldProgram ) {
M
Mr.doob 已提交
1590

M
Mr.doob 已提交
1591 1592
			_gl.useProgram( program );
			_oldProgram = program;
1593

M
Mr.doob 已提交
1594
		}
1595

1596 1597
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
1598
		// refresh uniforms common to several materials
1599 1600

		if ( fog && (
A
alteredq 已提交
1601 1602
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
1603
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
1604 1605 1606
			 material instanceof THREE.LineBasicMaterial ||
			 material instanceof THREE.ParticleBasicMaterial )
			) {
1607

A
alteredq 已提交
1608
			refreshUniformsFog( m_uniforms, fog );
1609 1610

		}
M
Mr.doob 已提交
1611

M
Mr.doob 已提交
1612
		if ( material instanceof THREE.MeshPhongMaterial ||
1613 1614
			 material instanceof THREE.MeshLambertMaterial ||
			 material.lights ) {
1615

A
alteredq 已提交
1616
			setupLights( program, lights );
A
alteredq 已提交
1617
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
1618 1619 1620

		}

1621 1622 1623
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
1624

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

A
alteredq 已提交
1627
		}
M
Mr.doob 已提交
1628

A
alteredq 已提交
1629
		// refresh single material specific uniforms
1630

1631
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
1632

A
alteredq 已提交
1633
			refreshUniformsLine( m_uniforms, material );
1634

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

A
alteredq 已提交
1637
			refreshUniformsParticle( m_uniforms, material );
1638

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

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

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

1645 1646
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
1647
			m_uniforms.opacity.value = material.opacity;
1648

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

A
alteredq 已提交
1651
			m_uniforms.opacity.value = material.opacity;
1652
		}
1653

A
alteredq 已提交
1654
		// load common uniforms
1655

A
alteredq 已提交
1656 1657
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
1658

A
alteredq 已提交
1659 1660
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
1661

A
alteredq 已提交
1662 1663
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshPhongMaterial ||
1664
			 material.envMap ) {
1665

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

1668
		}
1669

A
alteredq 已提交
1670
		if ( material instanceof THREE.MeshShaderMaterial ||
1671
			 material.envMap ||
1672
			 material.skinning ) {
1673

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

A
alteredq 已提交
1676
		}
1677

A
alteredq 已提交
1678 1679
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
1680
			 material instanceof THREE.MeshShaderMaterial ||
1681 1682
			 material.skinning ) {

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

A
alteredq 已提交
1685
		}
1686

1687
		if ( material.skinning ) {
1688

1689
			loadUniformsSkinning( p_uniforms, object );
1690

A
alteredq 已提交
1691
		}
1692
		
A
alteredq 已提交
1693
		return program;
1694

A
alteredq 已提交
1695
	};
1696

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

1699 1700
		if ( material.opacity == 0 ) return;

A
alteredq 已提交
1701 1702
		var program, attributes, linewidth, primitives;

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

1705
		attributes = program.attributes;
M
Mr.doob 已提交
1706

1707
		// vertices
M
Mr.doob 已提交
1708

1709
		if ( !material.morphTargets ) {
1710 1711 1712 1713 1714
			
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
			
		} else {
M
Mikael Emtinger 已提交
1715 1716
		
			setupMorphTargets( material, geometryGroup, object );
1717 1718 1719
			
		}

A
alteredq 已提交
1720 1721 1722 1723
		// colors

		if ( attributes.color >= 0 ) {

1724
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
1725
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
1726 1727 1728

		}

1729
		// normals
M
Mr.doob 已提交
1730

1731
		if ( attributes.normal >= 0 ) {
1732

1733
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
1734
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
1735

1736
		}
1737

1738 1739 1740
		// tangents

		if ( attributes.tangent >= 0 ) {
1741

1742
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
1743
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
1744

1745
		}
1746

1747
		// uvs
M
Mr.doob 已提交
1748

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

1751
			if ( geometryGroup.__webGLUVBuffer ) {
1752

1753
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1754
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
1755

1756
				_gl.enableVertexAttribArray( attributes.uv );
1757

1758
			} else {
1759

1760
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
1761

1762
			}
1763 1764 1765

		}

1766 1767
		if ( attributes.uv2 >= 0 ) {

1768
			if ( geometryGroup.__webGLUV2Buffer ) {
1769

1770
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

1783
		if ( material.skinning &&
1784
			 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
1785
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
1786

1787
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1788 1789
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

1790
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer );
A
alteredq 已提交
1791 1792
			_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );

1793
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer );
A
alteredq 已提交
1794 1795
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

1796
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer );
A
alteredq 已提交
1797
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
1798

A
alteredq 已提交
1799
		}
1800

1801
		// render mesh
M
Mr.doob 已提交
1802

1803
		if ( object instanceof THREE.Mesh ) {
1804

1805
			// wireframe
1806

1807
			if ( material.wireframe ) {
M
Mr.doob 已提交
1808

1809
				_gl.lineWidth( material.wireframeLinewidth );
1810 1811
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 );
1812

1813
			// triangles
1814

1815
			} else {
1816

1817 1818
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
1819
			}
1820

1821
		// render lines
1822

1823
		} else if ( object instanceof THREE.Line ) {
1824

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

1827
			_gl.lineWidth( material.linewidth );
1828
			_gl.drawArrays( primitives, 0, geometryGroup.__webGLLineCount );
1829

1830
		// render particles
1831

1832
		} else if ( object instanceof THREE.ParticleSystem ) {
1833

1834
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webGLParticleCount );
1835

A
alteredq 已提交
1836
		// render ribbon
1837

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

1840
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webGLVertexCount );
1841

1842 1843 1844 1845
		}

	};

M
Mikael Emtinger 已提交
1846

M
Mikael Emtinger 已提交
1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929
	function setupMorphTargets( material, geometryGroup, object ) {
		
		// set base
		
		var attributes = material.program.attributes;
		
		if(  object.morphTargetBase !== -1 ) {
			
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
			
		} else {
			
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
			
		}
		
		
		if( object.morphTargetForcedOrder.length ) {

			// set forced order
			
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;
			
			while( m < material.numSupportedMorphTargets && m < order.length ) {
			
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLMorphTargetsBuffers[ order[ m ] ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
				
				object.__webGLMorphTargetInfluences[ m ] = influences[ order[ m ]];

				m++;
			}			
			
		} else {
			
			// find most influencing
			
			var used = [];
			var candidateInfluence = -1;
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
	
			if( object.morphTargetBase !== -1 ) {
				
				used[ object.morphTargetBase ] = true;
				
			}
	
			while( m < material.numSupportedMorphTargets ) {
				
				for( i = 0; i < il; i++ ) {
					
					if( !used[ i ] && influences[ i ] > candidateInfluence ) {
						
						candidate = i;
						candidateInfluence = influences[ candidate ];
					}
				}
				
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLMorphTargetsBuffers[ candidate ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
				
				object.__webGLMorphTargetInfluences[ m ] = candidateInfluence;
	
				used[ candidate ] = 1;
				candidateInfluence = -1;
				m++;
			}
		}


		// load updated influences uniform
		
		_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webGLMorphTargetInfluences );
	}


1930
	function renderBufferImmediate ( object, program ) {
1931

A
alteredq 已提交
1932 1933
		if ( ! object.__webGLVertexBuffer ) object.__webGLVertexBuffer = _gl.createBuffer();
		if ( ! object.__webGLNormalBuffer ) object.__webGLNormalBuffer = _gl.createBuffer();
1934

A
alteredq 已提交
1935
		if ( object.hasPos ) {
1936

A
alteredq 已提交
1937 1938 1939 1940
		  _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 );
1941

A
alteredq 已提交
1942
		}
1943

A
alteredq 已提交
1944
		if ( object.hasNormal ) {
1945

A
alteredq 已提交
1946 1947 1948 1949
		  _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 );
1950

A
alteredq 已提交
1951
		}
1952

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

A
alteredq 已提交
1955
		object.count = 0;
1956

A
alteredq 已提交
1957
	};
1958

1959
	function setObjectFaces ( object ) {
1960

1961
		if ( _oldDoubleSided != object.doubleSided ) {
1962

1963
			if( object.doubleSided ) {
1964

1965
				_gl.disable( _gl.CULL_FACE );
1966

1967
			} else {
1968

A
alteredq 已提交
1969
				_gl.enable( _gl.CULL_FACE );
1970

A
alteredq 已提交
1971
			}
1972

1973
			_oldDoubleSided = object.doubleSided;
1974

1975
		}
1976

1977
		if ( _oldFlipSided != object.flipSided ) {
1978

1979 1980 1981 1982
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

1983
			} else {
1984 1985 1986 1987

				_gl.frontFace( _gl.CCW );

			}
1988

1989
			_oldFlipSided = object.flipSided;
1990 1991

		}
1992

1993
	};
1994

1995
	function setDepthTest ( test ) {
1996

A
alteredq 已提交
1997 1998 1999
		if ( _oldDepth != test ) {

			if( test ) {
2000

A
alteredq 已提交
2001
				_gl.enable( _gl.DEPTH_TEST );
2002

A
alteredq 已提交
2003
			} else {
2004

A
alteredq 已提交
2005
				_gl.disable( _gl.DEPTH_TEST );
2006

A
alteredq 已提交
2007
			}
2008

A
alteredq 已提交
2009 2010 2011
			_oldDepth = test;

		}
2012

A
alteredq 已提交
2013
	};
2014

2015
	function computeFrustum ( m ) {
2016 2017 2018 2019 2020 2021 2022 2023 2024

		_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;
2025

A
alteredq 已提交
2026
		for ( i = 0; i < 6; i ++ ) {
2027 2028 2029 2030 2031 2032 2033

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

		}

	};
2034

2035
	function isInFrustum ( object ) {
2036

2037
		var distance, matrix = object.matrixWorld,
2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049
		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;

	};
2050

2051
	function addToFixedArray ( where, what ) {
2052

2053 2054
		where.list[ where.count ] = what;
		where.count += 1;
2055

2056
	};
2057

2058
	function unrollImmediateBufferMaterials ( globject ) {
2059

2060 2061 2062 2063 2064 2065 2066
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
2067

2068 2069 2070
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			material = object.materials[ m ];
2071

2072 2073 2074 2075
			if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
				addToFixedArray( transparent, material );
			else
				addToFixedArray( opaque, material );
2076

2077
		}
2078

2079
	};
2080

2081
	function unrollBufferMaterials ( globject ) {
2082

2083 2084 2085 2086 2087 2088 2089 2090
		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;
2091

2092 2093 2094 2095 2096 2097 2098 2099 2100
		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 ];
2101

2102
					if ( material ) {
2103

2104 2105 2106 2107
						if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
							addToFixedArray( transparent, material );
						else
							addToFixedArray( opaque, material );
2108

2109 2110 2111 2112 2113 2114 2115
					}

				}

			} else {

				material = meshMaterial;
2116

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

2119
					addToFixedArray( transparent, material );
2120 2121 2122

				} else {

2123 2124
					addToFixedArray( opaque, material );

2125 2126
				}

2127 2128 2129
			}

		}
2130

2131
	};
2132 2133


2134
	function painterSort ( a, b ) {
2135

2136
		return b.z - a.z;
2137 2138

	};
2139

2140
	this.render = function ( scene, camera, renderTarget, forceClear ) {
2141

A
alteredq 已提交
2142
		var i, program, opaque, transparent, material,
2143
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
2144
			lights = scene.lights,
2145 2146
			fog = scene.fog,
			ol;
2147

M
Mr.doob 已提交
2148
		camera.matrixAutoUpdate && camera.updateMatrix();
2149

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

M
Mr.doob 已提交
2152
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
2153
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
2154

M
Mr.doob 已提交
2155
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
2156
		computeFrustum( _projScreenMatrix );
2157

A
alteredq 已提交
2158
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
2159

A
alteredq 已提交
2160
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
2161

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

2164
			this.clear();
M
Mr.doob 已提交
2165

2166 2167
		}

2168
		// set matrices
2169

2170
		ol = scene.__webglObjects.length;
2171

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

2174 2175
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
2176

2177
			if ( object.visible ) {
2178 2179

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

2181
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2182

2183
					setupMatrices( object, camera );
2184

2185
					unrollBufferMaterials( webglObject );
2186

2187
					webglObject.render = true;
2188

2189
					if ( this.sortObjects ) {
2190

2191 2192 2193
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

2194
						webglObject.z = _vector3.z;
2195

2196
					}
2197

2198
				} else {
2199

2200
					webglObject.render = false;
2201

2202
				}
2203

2204
			} else {
2205

2206
				webglObject.render = false;
2207

2208
			}
2209

2210
		}
2211

2212
		if ( this.sortObjects ) {
2213

2214
			scene.__webglObjects.sort( painterSort );
2215

2216
		}
2217

2218
		oil = scene.__webglObjectsImmediate.length;
2219

2220
		for ( o = 0; o < oil; o++ ) {
2221

2222 2223
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2224

2225
			if ( object.visible ) {
2226 2227 2228

				if( object.matrixAutoUpdate ) {

2229
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2230

A
alteredq 已提交
2231
				}
2232

2233
				setupMatrices( object, camera );
2234

2235
				unrollImmediateBufferMaterials( webglObject );
2236

2237
			}
2238

2239
		}
A
alteredq 已提交
2240

2241 2242
		// opaque pass

2243
		setBlending( THREE.NormalBlending );
2244

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

2247
			webglObject = scene.__webglObjects[ o ];
2248

2249
			if ( webglObject.render ) {
2250

2251 2252 2253
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
2254

2255
				setObjectFaces( object );
2256

2257
				for( i = 0; i < opaque.count; i++ ) {
2258

2259
					material = opaque.list[ i ];
2260

2261
					setDepthTest( material.depthTest );
A
alteredq 已提交
2262
					renderBuffer( camera, lights, fog, material, buffer, object );
2263

2264
				}
2265 2266 2267 2268 2269

			}

		}

A
alteredq 已提交
2270
		// opaque pass (immediate simulator)
2271

2272
		for ( o = 0; o < oil; o++ ) {
2273

2274 2275
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2276

A
alteredq 已提交
2277
			if ( object.visible ) {
2278

2279
				opaque = webglObject.opaque;
2280

2281
				setObjectFaces( object );
2282

2283
				for( i = 0; i < opaque.count; i++ ) {
2284

2285
					material = opaque.list[ i ];
2286

2287
					setDepthTest( material.depthTest );
2288

A
alteredq 已提交
2289
					program = setProgram( camera, lights, fog, material, object );
2290
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2291

2292
				}
2293

A
alteredq 已提交
2294
			}
2295

A
alteredq 已提交
2296 2297
		}

2298 2299
		// transparent pass

2300
		for ( o = 0; o < ol; o++ ) {
2301

2302
			webglObject = scene.__webglObjects[ o ];
2303

2304
			if ( webglObject.render ) {
2305

2306 2307 2308
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
2309

2310
				setObjectFaces( object );
2311

2312
				for( i = 0; i < transparent.count; i++ ) {
2313

2314
					material = transparent.list[ i ];
2315

2316
					setBlending( material.blending );
2317
					setDepthTest( material.depthTest );
2318

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

2321
				}
2322

2323
			}
M
Mr.doob 已提交
2324

M
Mr.doob 已提交
2325
		}
M
Mr.doob 已提交
2326

2327
		// transparent pass (immediate simulator)
2328

2329
		for ( o = 0; o < oil; o++ ) {
2330

2331 2332
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2333

2334
			if ( object.visible ) {
2335

2336
				transparent = webglObject.transparent;
2337

2338
				setObjectFaces( object );
2339

2340
				for( i = 0; i < transparent.count; i++ ) {
2341

2342
					material = transparent.list[ i ];
2343

2344
					setBlending( material.blending );
2345
					setDepthTest( material.depthTest );
2346

A
alteredq 已提交
2347
					program = setProgram( camera, lights, fog, material, object );
2348
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2349

2350
				}
2351

2352
			}
2353

2354
		}
2355

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

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

2360
			updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
2361

2362
		}
2363

M
Mr.doob 已提交
2364
	};
M
Mr.doob 已提交
2365

2366
	function setupMatrices ( object, camera ) {
2367

2368 2369
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
2370

2371
	};
2372

A
alteredq 已提交
2373
	this.initWebGLObjects = function ( scene ) {
2374

2375
		if ( !scene.__webglObjects ) {
2376

2377 2378
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
2379 2380 2381

		}

M
Mr.doob 已提交
2382
		while ( scene.__objectsAdded.length ) {
2383

M
Mr.doob 已提交
2384 2385
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
2386 2387 2388

		}

M
Mr.doob 已提交
2389
		while ( scene.__objectsRemoved.length ) {
2390

M
Mr.doob 已提交
2391 2392
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
2393 2394

		}
2395

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

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

M
Mr.doob 已提交
2400
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
2401 2402 2403

		}

2404
	};
2405

2406
	function addObject ( object, scene ) {
2407

2408
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
2409

2410
		if ( object._modelViewMatrix == undefined ) {
2411

2412
			object._modelViewMatrix = new THREE.Matrix4();
2413

2414 2415 2416
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
2417

2418
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
2419

2420
		}
A
alteredq 已提交
2421

2422
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
2423

2424 2425 2426 2427 2428 2429 2430 2431
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

2432
			// create separate VBOs per geometry chunk
A
alteredq 已提交
2433

2434
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
2435

2436
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
2437

2438
				// initialise VBO on the first access
M
Mr.doob 已提交
2439

2440
				if ( ! geometryGroup.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2441

2442 2443
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
2444

2445
					geometry.__dirtyVertices = true;
2446
					geometry.__dirtyMorphTargets = true;
2447 2448 2449 2450 2451
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
2452

2453
				}
2454

2455
				// create separate wrapper per each use of VBO
2456

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

2459
			}
M
Mr.doob 已提交
2460

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

2463 2464
			geometry = object.geometry;

A
alteredq 已提交
2465 2466 2467 2468 2469 2470 2471 2472 2473 2474
			if( ! geometry.__webGLVertexBuffer ) {

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

2479 2480
			geometry = object.geometry;

2481
			if( ! geometry.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2482

2483 2484
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
2485

2486 2487
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
2488

2489
			}
M
Mr.doob 已提交
2490

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

A
alteredq 已提交
2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

			if ( ! geometry.__webGLVertexBuffer ) {

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

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

2505
			}
2506

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

A
alteredq 已提交
2509 2510 2511 2512 2513 2514 2515 2516 2517 2518
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

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

		}*/

	};

2519
	function updateObject ( object, scene ) {
A
alteredq 已提交
2520

M
Mr.doob 已提交
2521
		var g, geometry, geometryGroup;
A
alteredq 已提交
2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

2533
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
A
alteredq 已提交
2534 2535 2536 2537 2538 2539 2540 2541 2542
					geometry.__dirtyUvs || geometry.__dirtyNormals ||
					geometry.__dirtyColors || geometry.__dirtyTangents ) {

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

2543
			geometry.__dirtyVertices = false;
2544
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
2545 2546 2547 2548
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
2549
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2550

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

2553 2554
			geometry = object.geometry;

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

A
alteredq 已提交
2557
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
2558

A
alteredq 已提交
2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570
			}

			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 );
2571

2572
			}
2573

A
alteredq 已提交
2574 2575 2576 2577 2578 2579 2580
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

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

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

2585
			}
M
Mr.doob 已提交
2586

2587 2588
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2589

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

A
alteredq 已提交
2592
			// it updates itself in render callback
2593 2594

		} else if ( object instanceof THREE.Particle ) {
2595 2596

		}*/
2597

2598
	};
2599

2600
	function removeObject ( object, scene ) {
M
Mr.doob 已提交
2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617

		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 );

			}

		}

	};

2618
	function sortFacesByMaterial ( geometry ) {
2619 2620 2621 2622 2623 2624 2625

		// 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 = {};
2626
		var numMorphTargets = geometry.morphTargets !== undefined ? geometry.morphTargets.length : 0;
2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668

		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 ) {

2669
				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681

			}

			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 ) {

2682
					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694

				}

			}

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

		}

	};

2695
	function addBuffer ( objlist, buffer, object ) {
2696

2697 2698 2699 2700
		objlist.push( { buffer: buffer, object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
M
Mr.doob 已提交
2701

2702
	};
2703

2704
	function addBufferImmediate ( objlist, object ) {
2705

2706 2707 2708 2709
		objlist.push( { object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
2710

2711
	};
2712

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

2715
		if ( cullFace ) {
M
Mr.doob 已提交
2716

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

2719
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
2720

2721
			} else {
M
Mr.doob 已提交
2722

2723
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
2724

2725
			}
M
Mr.doob 已提交
2726

2727
			if( cullFace == "back" ) {
M
Mr.doob 已提交
2728

2729
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
2730

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

2733
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
2734

2735
			} else {
M
Mr.doob 已提交
2736

2737
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
2738

2739
			}
M
Mr.doob 已提交
2740

2741
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2742

2743
		} else {
M
Mr.doob 已提交
2744

2745
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
2746

2747 2748 2749
		}

	};
N
Nicolas Garcia Belmonte 已提交
2750

2751
	this.supportsVertexTextures = function () {
2752

2753
		return maxVertexTextures() > 0;
2754

2755
	};
2756

2757
	function maxVertexTextures () {
2758

2759 2760 2761
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
2762

2763
	function initGL ( antialias, clearColor, clearAlpha ) {
N
Nicolas Garcia Belmonte 已提交
2764 2765 2766

		try {

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

2769
				throw 'Error creating WebGL context.';
N
Nicolas Garcia Belmonte 已提交
2770

2771 2772 2773
			}

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

2775
			console.error( e );
N
Nicolas Garcia Belmonte 已提交
2776 2777 2778 2779 2780 2781 2782 2783 2784

		}

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

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

2785 2786
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
2787
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2788

N
Nicolas Garcia Belmonte 已提交
2789
		_gl.enable( _gl.BLEND );
2790
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
2791
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
2792

A
alteredq 已提交
2793
		_cullEnabled = true;
N
Nicolas Garcia Belmonte 已提交
2794

2795
	};
M
Mr.doob 已提交
2796

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

M
Mr.doob 已提交
2799
		var program = _gl.createProgram(),
M
Mr.doob 已提交
2800

M
Mr.doob 已提交
2801 2802 2803 2804
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
2805

2806 2807
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
2808

2809 2810
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
2811

2812
			parameters.map ? "#define USE_MAP" : "",
2813 2814 2815
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
2816

2817
			"uniform mat4 viewMatrix;",
2818
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
2819 2820
			""
		].join("\n"),
2821

M
Mr.doob 已提交
2822
		prefix_vertex = [
2823
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
2824

2825 2826 2827
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

2828 2829
			"#define MAX_BONES " + parameters.maxBones,

2830
			parameters.map ? "#define USE_MAP" : "",
2831 2832 2833
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
2834
			parameters.skinning ? "#define USE_SKINNING" : "",
2835
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
2836

2837

2838 2839
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
2840 2841 2842
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
2843 2844
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
2845
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
2846 2847 2848

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
2849
			"attribute vec3 position;",
2850 2851 2852 2853 2854 2855 2856 2857
			"attribute vec3 morphTarget0;",
			"attribute vec3 morphTarget1;",
			"attribute vec3 morphTarget2;",
			"attribute vec3 morphTarget3;",
			"attribute vec3 morphTarget4;",
			"attribute vec3 morphTarget5;",
			"attribute vec3 morphTarget6;",
			"attribute vec3 morphTarget7;",
M
Mr.doob 已提交
2858
			"attribute vec3 normal;",
A
alteredq 已提交
2859
			"attribute vec3 color;",
M
Mr.doob 已提交
2860
			"attribute vec2 uv;",
2861
			"attribute vec2 uv2;",
2862

A
alteredq 已提交
2863 2864 2865 2866
			"attribute vec4 skinVertexA;",
			"attribute vec4 skinVertexB;",
			"attribute vec4 skinIndex;",
			"attribute vec4 skinWeight;",
M
Mr.doob 已提交
2867 2868
			""
		].join("\n");
2869

2870 2871
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
2872

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

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

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

2880 2881
			//console.log( prefix_fragment + fragmentShader );
			//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
2882

N
Nicolas Garcia Belmonte 已提交
2883
		}
2884

2885 2886
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
2887

M
Mr.doob 已提交
2888
		program.uniforms = {};
2889
		program.attributes = {};
M
Mr.doob 已提交
2890

M
Mr.doob 已提交
2891
		return program;
M
Mr.doob 已提交
2892

M
Mr.doob 已提交
2893
	};
M
Mr.doob 已提交
2894

2895
	function loadUniformsSkinning ( uniforms, object ) {
2896

M
Mr.doob 已提交
2897
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
2898
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
2899

2900
	};
2901
		
2902

2903
	function loadUniformsMatrices ( uniforms, object ) {
2904

A
alteredq 已提交
2905 2906 2907 2908
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
2909

2910
	function loadUniformsGeneric ( program, uniforms ) {
M
Mr.doob 已提交
2911

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

M
Mr.doob 已提交
2914
		for( u in uniforms ) {
M
Mr.doob 已提交
2915

2916 2917
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
2918

2919
			uniform = uniforms[u];
M
Mr.doob 已提交
2920

2921 2922
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
2923

M
Mr.doob 已提交
2924
			if( type == "i" ) {
M
Mr.doob 已提交
2925

M
Mr.doob 已提交
2926
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
2927

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

M
Mr.doob 已提交
2930
				_gl.uniform1f( location, value );
2931

A
alteredq 已提交
2932 2933 2934
			} else if( type == "fv1" ) {

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

2936 2937 2938 2939
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

2940 2941 2942 2943
			} else if( type == "v2" ) {

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

2944 2945 2946
			} else if( type == "v3" ) {

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

2948 2949 2950
			} else if( type == "c" ) {

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

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

M
Mr.doob 已提交
2954
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
2955

2956
				texture = uniform.texture;
M
Mr.doob 已提交
2957

2958
				if ( !texture ) continue;
M
Mr.doob 已提交
2959

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

2962
					setCubeTexture( texture, value );
M
Mr.doob 已提交
2963

2964
				} else {
M
Mr.doob 已提交
2965

2966
					setTexture( texture, value );
M
Mr.doob 已提交
2967

2968
				}
M
Mr.doob 已提交
2969

2970
			}
M
Mr.doob 已提交
2971

2972
		}
M
Mr.doob 已提交
2973

2974
	};
M
Mr.doob 已提交
2975

2976
	function setBlending ( blending ) {
A
alteredq 已提交
2977 2978

		if ( blending != _oldBlending ) {
2979

A
alteredq 已提交
2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002
			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;

3003 3004 3005 3006 3007 3008
				case THREE.ReverseSubtractiveBlending:

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

    				break;
A
alteredq 已提交
3009 3010 3011 3012 3013 3014
				default:

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

					break;
3015

A
alteredq 已提交
3016
			}
3017

A
alteredq 已提交
3018
			_oldBlending = blending;
3019

A
alteredq 已提交
3020 3021 3022
		}

	};
3023

3024
	function setTextureParameters ( textureType, texture, image ) {
3025

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

3028 3029
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
3030

3031 3032
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
3033

3034
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
3035

3036
		} else {
M
Mr.doob 已提交
3037

3038 3039 3040 3041 3042
			_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 已提交
3043

3044
		}
M
Mr.doob 已提交
3045

3046 3047
	};
	
3048
	function setTexture ( texture, slot ) {
3049

3050
		if ( texture.needsUpdate ) {
A
alteredq 已提交
3051

3052
			if ( !texture.__wasSetOnce ) {
M
Mr.doob 已提交
3053

3054
				texture.__webGLTexture = _gl.createTexture();
A
alteredq 已提交
3055

3056 3057
				_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 已提交
3058

A
alteredq 已提交
3059
				texture.__wasSetOnce = true;
M
Mr.doob 已提交
3060

A
alteredq 已提交
3061
			} else {
M
Mr.doob 已提交
3062

A
alteredq 已提交
3063 3064
				_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 已提交
3065 3066 3067

			}

3068 3069 3070
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			
A
alteredq 已提交
3071
			texture.needsUpdate = false;
3072 3073 3074 3075

		}

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

3078
	};
M
Mr.doob 已提交
3079

3080
	function setCubeTexture ( texture, slot ) {
3081 3082 3083 3084

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

			if ( texture.needsUpdate ) {
3085 3086
				
				if ( !texture.__wasSetOnce ) {
3087 3088 3089

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

3090
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
3091

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

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

3096 3097 3098
					}
				
					texture.__wasSetOnce = true;
3099 3100 3101

				} else {

3102
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
3103

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

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

3108
					}
3109 3110 3111

				}

3112
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
3113 3114 3115
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
3116
				
3117 3118 3119 3120 3121 3122 3123 3124 3125
			}

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

		}

	};

3126
	function setRenderTarget ( renderTexture ) {
3127 3128

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

3130 3131 3132 3133 3134
			renderTexture.__webGLFramebuffer = _gl.createFramebuffer();
			renderTexture.__webGLRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webGLTexture = _gl.createTexture();

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

3136 3137 3138 3139
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );

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

3141
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webGLTexture );
3142 3143 3144 3145
			_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 ) );
3146
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
3147 3148

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

3150 3151
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webGLFramebuffer );
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webGLTexture, 0 );
3152
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
3153 3154

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

3156 3157 3158
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
3159

3160 3161
		}

3162
		var framebuffer, width, height;
M
Mr.doob 已提交
3163

3164
		if ( renderTexture ) {
M
Mr.doob 已提交
3165

3166 3167 3168
			framebuffer = renderTexture.__webGLFramebuffer;
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
3169

3170
		} else {
M
Mr.doob 已提交
3171

3172
			framebuffer = null;
3173 3174
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
3175

3176
		}
M
Mr.doob 已提交
3177

3178
		if( framebuffer != _oldFramebuffer ) {
M
Mr.doob 已提交
3179

3180
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3181
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
3182

3183
			_oldFramebuffer = framebuffer;
M
Mr.doob 已提交
3184

3185
		}
3186

3187
	};
M
Mr.doob 已提交
3188

3189
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
3190

3191 3192 3193
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webGLTexture );
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3194 3195

	};
3196

3197
	function cacheUniformLocations ( program, identifiers ) {
M
Mr.doob 已提交
3198

M
Mr.doob 已提交
3199
		var i, l, id;
M
Mr.doob 已提交
3200

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

3203 3204
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
3205

M
Mr.doob 已提交
3206
		}
M
Mr.doob 已提交
3207

M
Mr.doob 已提交
3208
	};
M
Mr.doob 已提交
3209

3210
	function cacheAttributeLocations ( program, identifiers ) {
3211

3212
		var i, l, id;
M
Mr.doob 已提交
3213

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

3216 3217
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
3218

3219
		}
M
Mr.doob 已提交
3220

M
Mr.doob 已提交
3221
	};
M
Mr.doob 已提交
3222

3223
	function getShader ( type, string ) {
N
Nicolas Garcia Belmonte 已提交
3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247

		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 已提交
3248

3249
	};
N
Nicolas Garcia Belmonte 已提交
3250

3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268
	// 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;

		}
		
	};
	
3269
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
3270

3271
		switch ( p ) {
M
Mr.doob 已提交
3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284

			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;

3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298
			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;

3299
		}
M
Mr.doob 已提交
3300

3301
		return 0;
M
Mr.doob 已提交
3302

3303 3304
	};

3305
	function isPowerOfTwo ( value ) {
3306 3307 3308 3309 3310

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

	};

3311
	function materialNeedsSmoothNormals ( material ) {
3312 3313 3314

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

3315
	};
M
Mr.doob 已提交
3316

3317
	function bufferNeedsSmoothNormals ( geometryGroup, object ) {
M
Mr.doob 已提交
3318

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

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

M
Mr.doob 已提交
3323
			meshMaterial = object.materials[ m ];
3324 3325 3326

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

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

3329
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
3330

3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
3352

3353
		return needsSmoothNormals;
M
Mr.doob 已提交
3354

3355
	};
M
Mr.doob 已提交
3356

3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379
	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 ) {
3380

3381 3382
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
3383

3384
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
3385

3386
			light = lights[ l ];
3387

3388 3389
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
3390

3391
		}
3392

3393
		if ( ( pointLights + dirLights ) <= maxLights ) {
3394

3395 3396
			maxDirLights = dirLights;
			maxPointLights = pointLights;
3397

3398
		} else {
3399

3400 3401
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
3402 3403 3404

		}

3405
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
3406 3407

	};
M
Mr.doob 已提交
3408

A
alteredq 已提交
3409
	/* DEBUG
3410
	function getGLParams() {
M
Mr.doob 已提交
3411

3412
		var params  = {
M
Mr.doob 已提交
3413

3414 3415
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
3416

3417 3418 3419
			'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 已提交
3420

3421 3422 3423
			'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 已提交
3424

3425 3426
		return params;
	};
M
Mr.doob 已提交
3427

3428
	function dumpObject( obj ) {
M
Mr.doob 已提交
3429

3430 3431
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
3432

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

3435
		}
M
Mr.doob 已提交
3436

3437 3438
		return str;
	}
A
alteredq 已提交
3439
	*/
3440
};
3441