123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /*
- Usage: JeelizCanvas2DHelper(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
- */
- const JeelizCanvas2DHelper = function(spec){
- // some globalz:
- let CV = null, CANVAS2D = null, CTX = null, GL = null, CANVASTEXTURE = null, CANVASTEXTURENEEDSUPDATE = null, SHADERCOPY = null, VIDEOTEXTURE = null;
- let VIDEOTEXTURETRANSFORMMAT2 = null, UUVTRANSFORM = null;
- const COORDINATES = {
- x:0, y:0, s:0
- };
- //BEGIN WEBGL HELPERS
- // compile a shader:
- function compile_shader(source, glType, typeString) {
- const glShader = GL.createShader(glType);
- GL.shaderSource(glShader, source);
- GL.compileShader(glShader);
- if (!GL.getShaderParameter(glShader, GL.COMPILE_STATUS)) {
- alert("ERROR IN " + typeString + " SHADER: " + GL.getShaderInfoLog(glShader));
- return null;
- }
- return glShader;
- };
- // helper function to build the shader program:
- function build_shaderProgram(shaderVertexSource, shaderFragmentSource, id) {
- // compile both shader separately:
- const glShaderVertex = compile_shader(shaderVertexSource, GL.VERTEX_SHADER, "VERTEX " + id);
- const glShaderFragment = compile_shader(shaderFragmentSource, GL.FRAGMENT_SHADER, "FRAGMENT " + id);
- const glShaderProgram = GL.createProgram();
- GL.attachShader(glShaderProgram, glShaderVertex);
- GL.attachShader(glShaderProgram, glShaderFragment);
- // start the linking stage:
- GL.linkProgram(glShaderProgram);
- return glShaderProgram;
- }
- //END WEBGL HELPERS
- // affect some globalz:
- GL = spec.GL;
- CV = spec.canvasElement;
- VIDEOTEXTURE = spec.videoTexture;
- VIDEOTEXTURETRANSFORMMAT2 = spec.videoTransformMat2;
- // 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:
- const copyVertexShaderSource = "attribute vec2 position;\n\
- uniform mat2 UVTransformMat2;\n\
- varying vec2 vUV;\n\
- void main(void){\n\
- gl_Position = vec4(position, 0., 1.);\n\
- vUV = vec2(0.5,0.5) + UVTransformMat2 * position;\n\
- }";
- const 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');
- const uSampler = GL.getUniformLocation(SHADERCOPY, 'samplerImage');
- UUVTRANSFORM = GL.getUniformLocation(SHADERCOPY, 'UVTransformMat2');
- 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.uniformMatrix2fv(UUVTRANSFORM, false, VIDEOTEXTURETRANSFORMMAT2);
- GL.drawElements(GL.TRIANGLES, 3, GL.UNSIGNED_SHORT, 0);
- // then draw the canvas:
- GL.bindTexture(GL.TEXTURE_2D, CANVASTEXTURE);
- GL.uniformMatrix2fv(UUVTRANSFORM, false, [0.5, 0, 0, 0.5]);
- 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);
- },
- 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 JeelizCanvas2DHelper()
- // const JeelizCanvas2DHelper = JeelizCanvas2DHelper();
- if(typeof(module) !== 'undefined') {
- module.exports = JeelizCanvas2DHelper;
- }
|