Kaynağa Gözat

Added loading animation for WebGL; cleanup

Dominic Szablewski 11 yıl önce
ebeveyn
işleme
42cc895828
1 değiştirilmiş dosya ile 60 ekleme ve 26 silme
  1. 60 26
      jsmpg.js

+ 60 - 26
jsmpg.js Dosyayı Görüntüle

@@ -277,16 +277,16 @@ jsmpeg.prototype.load = function( url ) {
277 277
 		}
278 278
 	};
279 279
 
280
-	if( !this.gl ) {
281
-		request.onprogress = this.updateLoader.bind(this);
282
-	}
280
+	request.onprogress = this.gl 
281
+		? this.updateLoaderGL.bind(this) 
282
+		: this.updateLoader2D.bind(this);
283 283
 
284 284
 	request.open('GET', url);
285 285
 	request.responseType = "arraybuffer";
286 286
 	request.send();
287 287
 };
288 288
 
289
-jsmpeg.prototype.updateLoader = function( ev ) {
289
+jsmpeg.prototype.updateLoader2D = function( ev ) {
290 290
 	var 
291 291
 		p = ev.loaded / ev.total,
292 292
 		w = this.canvas.width,
@@ -298,6 +298,12 @@ jsmpeg.prototype.updateLoader = function( ev ) {
298 298
 	ctx.fillStyle = '#fff';
299 299
 	ctx.fillRect(0, h - h*p, w, h*p);
300 300
 };
301
+
302
+jsmpeg.prototype.updateLoaderGL = function( ev ) {
303
+	var gl = this.gl;
304
+	gl.uniform1f(gl.getUniformLocation(this.loadingProgram, 'loaded'), (ev.loaded / ev.total));
305
+	gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
306
+};
301 307
 	
302 308
 jsmpeg.prototype.loadCallback = function(file) {
303 309
 	var time = Date.now();
@@ -550,7 +556,10 @@ jsmpeg.prototype.initBuffers = function() {
550 556
 	this.canvas.width = this.width;
551 557
 	this.canvas.height = this.height;
552 558
 	
553
-	if( !this.gl ) {
559
+	if( this.gl ) {
560
+		this.gl.useProgram(this.program);
561
+	}
562
+	else {
554 563
 		this.currentRGBA = this.canvasContext.getImageData(0, 0, this.width, this.height);
555 564
 		this.fillArray(this.currentRGBA.data, 255);
556 565
 	}
@@ -736,8 +745,8 @@ jsmpeg.prototype.renderFrame2D = function() {
736 745
 jsmpeg.prototype.gl = null;
737 746
 jsmpeg.prototype.program = null;
738 747
 jsmpeg.prototype.YTexture = null;
739
-jsmpeg.prototype.UTexture = null;
740
-jsmpeg.prototype.VTexture = null;
748
+jsmpeg.prototype.CBTexture = null;
749
+jsmpeg.prototype.CRTexture = null;
741 750
 
742 751
 jsmpeg.prototype.createTexture = function(index, name) {
743 752
 	var gl = this.gl;
@@ -777,11 +786,16 @@ jsmpeg.prototype.initWebGL = function() {
777 786
 	if (!gl) {
778 787
 		return false;
779 788
 	}
780
-	
781
-	// setup shaders
789
+
790
+	// init buffers
791
+	this.buffer = gl.createBuffer();
792
+	gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
793
+	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]), gl.STATIC_DRAW);
794
+
795
+	// The main YCbCrToRGBA Shader
782 796
 	this.program = gl.createProgram();
783
-	gl.attachShader(this.program, this.compileShader(gl.VERTEX_SHADER, YCBCRTORGBA_VERTEX_SHADER));
784
-	gl.attachShader(this.program, this.compileShader(gl.FRAGMENT_SHADER, YCBCRTORGBA_FRAGMENT_SHADER));
797
+	gl.attachShader(this.program, this.compileShader(gl.VERTEX_SHADER, SHADER_VERTEX_IDENTITY));
798
+	gl.attachShader(this.program, this.compileShader(gl.FRAGMENT_SHADER, SHADER_FRAGMENT_YCBCRTORGBA));
785 799
 	gl.linkProgram(this.program);
786 800
 	
787 801
 	if( !gl.getProgramParameter(this.program, gl.LINK_STATUS) ) {
@@ -792,17 +806,25 @@ jsmpeg.prototype.initWebGL = function() {
792 806
 	
793 807
 	// setup textures
794 808
 	this.YTexture = this.createTexture(0, 'YTexture');
795
-	this.UTexture = this.createTexture(1, 'UTexture');
796
-	this.VTexture = this.createTexture(2, 'VTexture');
797
-	
798
-	// init buffers
799
-	this.buffer = gl.createBuffer();
800
-	gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
801
-	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]), gl.STATIC_DRAW);
809
+	this.CBTexture = this.createTexture(1, 'CBTexture');
810
+	this.CRTexture = this.createTexture(2, 'CRTexture');
802 811
 	
803 812
 	var vertexAttr = gl.getAttribLocation(this.program, 'vertex');
804 813
 	gl.enableVertexAttribArray(vertexAttr);
805 814
 	gl.vertexAttribPointer(vertexAttr, 2, gl.FLOAT, false, 0, 0);
815
+
816
+
817
+	// Shader for the loading screen
818
+	this.loadingProgram = gl.createProgram();
819
+	gl.attachShader(this.loadingProgram, this.compileShader(gl.VERTEX_SHADER, SHADER_VERTEX_IDENTITY));
820
+	gl.attachShader(this.loadingProgram, this.compileShader(gl.FRAGMENT_SHADER, SHADER_FRAGMENT_LOADING));
821
+	gl.linkProgram(this.loadingProgram);
822
+
823
+	gl.useProgram(this.loadingProgram);
824
+
825
+	vertexAttr = gl.getAttribLocation(this.loadingProgram, 'vertex');
826
+	gl.enableVertexAttribArray(vertexAttr);
827
+	gl.vertexAttribPointer(vertexAttr, 2, gl.FLOAT, false, 0, 0);
806 828
 	
807 829
 	return true;
808 830
 };
@@ -822,11 +844,11 @@ jsmpeg.prototype.renderFrameGL = function() {
822 844
 	gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, this.width, this.height, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, uint8Y);
823 845
 	
824 846
 	gl.activeTexture(gl.TEXTURE1);
825
-	gl.bindTexture(gl.TEXTURE_2D, this.UTexture);
847
+	gl.bindTexture(gl.TEXTURE_2D, this.CBTexture);
826 848
 	gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, this.halfWidth, this.halfHeight, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, uint8Cr);
827 849
 	
828 850
 	gl.activeTexture(gl.TEXTURE2);
829
-	gl.bindTexture(gl.TEXTURE_2D, this.VTexture);
851
+	gl.bindTexture(gl.TEXTURE_2D, this.CRTexture);
830 852
 	gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, this.halfWidth, this.halfHeight, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, uint8Cb);
831 853
 	
832 854
 	gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
@@ -2288,17 +2310,17 @@ var
2288 2310
 	START_USER_DATA = 0xB2,
2289 2311
 
2290 2312
 	// Shaders for accelerated WebGL YCbCrToRGBA conversion
2291
-	YCBCRTORGBA_FRAGMENT_SHADER = [
2313
+	SHADER_FRAGMENT_YCBCRTORGBA = [
2292 2314
 		'precision highp float;',
2293 2315
 		'uniform sampler2D YTexture;',
2294
-		'uniform sampler2D UTexture;',
2295
-		'uniform sampler2D VTexture;',
2316
+		'uniform sampler2D CBTexture;',
2317
+		'uniform sampler2D CRTexture;',
2296 2318
 		'varying vec2 texCoord;',
2297 2319
 	
2298 2320
 		'void main() {',
2299 2321
 			'float y = texture2D(YTexture, texCoord).r;',
2300
-			'float cr = texture2D(UTexture, texCoord).r - 0.5;',
2301
-			'float cb = texture2D(VTexture, texCoord).r - 0.5;',
2322
+			'float cr = texture2D(CBTexture, texCoord).r - 0.5;',
2323
+			'float cb = texture2D(CRTexture, texCoord).r - 0.5;',
2302 2324
 			
2303 2325
 			'gl_FragColor = vec4(',
2304 2326
 				'y + 1.4 * cr,',
@@ -2308,8 +2330,20 @@ var
2308 2330
 			');',
2309 2331
 		'}'
2310 2332
 	].join('\n'),
2333
+
2334
+	SHADER_FRAGMENT_LOADING = [
2335
+		'precision highp float;',
2336
+		'uniform float loaded;',
2337
+		'varying vec2 texCoord;',
2338
+
2339
+		'void main() {',
2340
+			'float c = ceil(loaded-(1.0-texCoord.y));',
2341
+			//'float c = ceil(loaded-(1.0-texCoord.y) +sin((texCoord.x+loaded)*16.0)*0.01);', // Fancy wave anim
2342
+			'gl_FragColor = vec4(c,c,c,1);',
2343
+		'}'
2344
+	].join('\n'),
2311 2345
 	
2312
-	YCBCRTORGBA_VERTEX_SHADER = [
2346
+	SHADER_VERTEX_IDENTITY = [
2313 2347
 		'attribute vec2 vertex;',
2314 2348
 		'varying vec2 texCoord;',
2315 2349