const vs = ` attribute vec3 aPos; attribute vec2 aVertexTextureCoord; varying highp vec2 vTextureCoord; void main(void){ gl_Position = vec4(aPos, 1); vTextureCoord = aVertexTextureCoord; } `; const fs = ` varying highp vec2 vTextureCoord; uniform sampler2D uSampler; void main(void) { gl_FragColor = texture2D(uSampler, vTextureCoord); } `; const vertex = [ -1, -1, 0.0, 1, -1, 0.0, 1, 1, 0.0, -1, 1, 0.0, ]; const vertexIndice = [ 0, 1, 2, 0, 2, 3, ]; const texCoords = [ 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, ]; function createShader(gl, src, type) { const shader = gl.createShader(type); gl.shaderSource(shader, src); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { console.error(`Error compiling shader: ${gl.getShaderInfoLog(shader)}`); } return shader; } const buffers = {}; function createRenderer(canvas, width, height) { const gl = canvas.getContext('webgl'); if (!gl) { console.error('Unable to get webgl context.'); return; } const info = xhs.getSystemInfoSync(); gl.canvas.width = info.pixelRatio * width; gl.canvas.height = info.pixelRatio * height; gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); const vertexShader = createShader(gl, vs, gl.VERTEX_SHADER); const fragmentShader = createShader(gl, fs, gl.FRAGMENT_SHADER); const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { console.error('Unable to initialize the shader program.'); return; } gl.useProgram(program); const texture = gl.createTexture(); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 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); gl.bindTexture(gl.TEXTURE_2D, null); buffers.vertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffers.vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertex), gl.STATIC_DRAW); buffers.vertexIndiceBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.vertexIndiceBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vertexIndice), gl.STATIC_DRAW); const aVertexPosition = gl.getAttribLocation(program, 'aPos'); gl.vertexAttribPointer(aVertexPosition, 3, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(aVertexPosition); buffers.trianglesTexCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffers.trianglesTexCoordBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoords), gl.STATIC_DRAW); const vertexTexCoordAttribute = gl.getAttribLocation(program, 'aVertexTextureCoord'); gl.enableVertexAttribArray(vertexTexCoordAttribute); gl.vertexAttribPointer(vertexTexCoordAttribute, 2, gl.FLOAT, false, 0, 0); const samplerUniform = gl.getUniformLocation(program, 'uSampler'); gl.uniform1i(samplerUniform, 0); return (arrayBuffer, width, height) => { gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, arrayBuffer); gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); }; } Page({ onShareAppMessage() { return { title: 'camera', path: 'page/component/pages/camera/camera', }; }, data: { src: '', videoSrc: '', position: 'back', mode: 'scanCode', result: {}, frameWidth: 0, frameHeight: 0, width: 288, height: 358, showCanvas: false, }, onReady() { this.ctx = xhs.createCameraContext(); // const selector = xhs.createSelectorQuery(); // selector.select('#webgl') // .node(this.init) // .exec() }, init(res) { if (this.listener) { this.listener.stop(); } const canvas = res.node; const render = createRenderer(canvas, this.data.width, this.data.height); // if (!render || typeof render !== 'function') return this.listener = this.ctx.onCameraFrame(frame => { render(new Uint8Array(frame.data), frame.width, frame.height); const { frameWidth, frameHeight, } = this.data; if (frameWidth === frame.width && frameHeight == frame.height) return; this.setData({ frameWidth: frame.width, frameHeight: frame.height, }); }); this.listener.start(); }, takePhoto() { this.ctx.takePhoto({ quality: 'high', success: res => { this.setData({ src: res.tempImagePath, }); }, }); }, startRecord() { this.ctx.startRecord({ success: () => { console.log('startRecord'); }, }); }, stopRecord() { this.ctx.stopRecord({ success: res => { this.setData({ src: res.tempThumbPath, videoSrc: res.tempVideoPath, }); }, }); }, togglePosition() { this.setData({ position: this.data.position === 'front' ? 'back' : 'front', }); }, error(e) { console.log(e.detail); }, handleShowCanvas() { const that = this; this.setData({ showCanvas: !this.data.showCanvas, }, () => { if (this.data.showCanvas) { const selector = xhs.createSelectorQuery(); selector.select('#webgl') .node(this.init) .exec(); } }); }, });