-
Notifications
You must be signed in to change notification settings - Fork 27
/
Canvas2DDisplay.js
executable file
·131 lines (112 loc) · 4.94 KB
/
Canvas2DDisplay.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
"use strict";
/*
Use : JEEFACEFILTERAPI.Canvas2DDisplay(spec) where spec is the returned object of the initialization function (callbackReady)
Return an object width these properties :
- canvas : the CANVAS element
- ctx : the canvas drawing context
- update_canvasTexture : function to launch each time the canvas has been updated (somethink has been drawn on it)
- draw : draw the video with the canvas above
- getCoordinates : transform the detectedState relative 2D viewport coords into canvas 2D pixel coordinates
- resize: to call if the HTML canvas size has changed
*/
JEEFACEFILTERAPI.Canvas2DDisplay=function(spec){
//some globalz :
var CV, CANVAS2D, CTX, GL, CANVASTEXTURE, CANVASTEXTURENEEDSUPDATE=false,SHADERCOPY, VIDEOTEXTURE;
var COORDINATES={
x:0, y:0,s:0
};
//BEGIN WEBGL HELPERS
//compile a shader
function compile_shader(source, type, typeString) {
var shader = GL.createShader(type);
GL.shaderSource(shader, source);
GL.compileShader(shader);
if (!GL.getShaderParameter(shader, GL.COMPILE_STATUS)) {
alert("ERROR IN "+typeString+ " SHADER : " + GL.getShaderInfoLog(shader));
}
return shader;
};
//helper function to build the shader program :
function build_shaderProgram(shaderVertexSource, shaderFragmentSource, id) {
//compile both shader separately
var shaderVertex=compile_shader(shaderVertexSource, GL.VERTEX_SHADER, "VERTEX "+id);
var shaderFragment=compile_shader(shaderFragmentSource, GL.FRAGMENT_SHADER, "FRAGMENT "+id);
var shaderProgram=GL.createProgram();
GL.attachShader(shaderProgram, shaderVertex);
GL.attachShader(shaderProgram, shaderFragment);
//start the linking stage :
GL.linkProgram(shaderProgram);
return shaderProgram;
} //end build_shaderProgram()
//END WEBGL HELPERS
//affect some globalz
GL=spec.GL;
CV=spec.canvasElement;
VIDEOTEXTURE=spec.videoTexture;
//create and size the 2D canvas and its drawing context
CANVAS2D=document.createElement('canvas');
CANVAS2D.width=CV.width;
CANVAS2D.height=CV.height;
CTX=CANVAS2D.getContext('2d');
//create the WebGL texture with the canvas
CANVASTEXTURE=GL.createTexture();
GL.bindTexture(GL.TEXTURE_2D, CANVASTEXTURE);
GL.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, CANVAS2D);
GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
//build the copy shader program :
var copyVertexShaderSource="attribute vec2 position;\n\
varying vec2 vUV;\n\
void main(void){\n\
gl_Position=vec4(position, 0., 1.);\n\
vUV=vec2(0.5,0.5)+0.5*position;\n\
}";
var copyFragmentShaderSource="precision lowp float;\n\
uniform sampler2D samplerImage;\n\
varying vec2 vUV;\n\
\n\
void main(void){\n\
gl_FragColor=texture2D(samplerImage, vUV);\n\
}";
SHADERCOPY=build_shaderProgram(copyVertexShaderSource, copyFragmentShaderSource, 'VIDEO');
var uSampler=GL.getUniformLocation(SHADERCOPY, 'samplerImage');
GL.useProgram(SHADERCOPY);
GL.uniform1i(uSampler, 0);
return {
canvas: CANVAS2D,
ctx: CTX,
update_canvasTexture: function(){
CANVASTEXTURENEEDSUPDATE=true;
},
draw: function(){ //draw the video and the canvas above
GL.viewport(0,0,CV.width, CV.height);
GL.useProgram(SHADERCOPY);
//enable blending
GL.enable(GL.BLEND);
GL.blendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA);
//draw the video first
GL.bindTexture(GL.TEXTURE_2D, VIDEOTEXTURE);
GL.drawElements(GL.TRIANGLES, 3, GL.UNSIGNED_SHORT, 0);
//then draw the canvas
GL.bindTexture(GL.TEXTURE_2D, CANVASTEXTURE);
if (CANVASTEXTURENEEDSUPDATE) {
GL.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, CANVAS2D);
}
GL.drawElements(GL.TRIANGLES, 3, GL.UNSIGNED_SHORT, 0);
GL.disable(GL.BLEND);
}, //end draw()
getCoordinates: function(detectedState){
COORDINATES.x=Math.round((0.5+0.5*detectedState.x-0.5*detectedState.s)*CV.width);
COORDINATES.y=Math.round((0.5+0.5*detectedState.y-0.5*detectedState.s)*CV.height);
COORDINATES.w=Math.round(detectedState.s*CV.width);
COORDINATES.h=COORDINATES.w;
return COORDINATES;
},
resize: function(){
CANVAS2D.width=CV.width;
CANVAS2D.height=CV.height;
}
}; //end Canvas2DDisplay return value
} //end JEEFACEFILTERAPI.Canvas2DDisplay()