收藏
回答

华为鸿蒙系统 微信公众号网页 webgl 图形显示异常

在业务开发过程中发现在IOS微信中打开微信公众号网页webgl图形显示正常, 在鸿蒙系统的微信中打开微信公众号网页webgl图形不显示

正常显示:ios

鸿蒙系统版本号

鸿蒙系统微信版本号

显示异常:(不显示)



渲染函数

// 渲染方法
  render(leafletTop: { x: number, y: number }, renderWidth: number, renderHeight: number) {
    const gl = this.getGLContext();
    if (!gl) {
      console.error('webgl not init');
      return;
    }
    let program = this.shaderProgram;



    gl.enable(gl.STENCIL_TEST);
    // 定义背景色,默认为(0,0,0,0)
    gl.clearColor(0, 0, 0, 0.0)
    // 定义模板缓冲区的背景值,默认为0,这不是颜色,就是一个模板参考值
    gl.clearStencil(0)
    // 用定义好的背景色理缓冲区
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);


    const size = 2;          // 每次迭代运行提取两个单位数据
    const type = gl.FLOAT;   // 每个单位的数据类型是32位浮点型
    const normalize = false; // 不需要归一化数据
    const stride = 0;        // 0 = 移动单位数量 * 每个单位占用内存(sizeof(type))
    // 每次迭代运行运动多少内存到下一个数据开始点
    const offset = 0;        // 从缓冲起始位置开始读取


    const primitiveType = gl.TRIANGLES;
    const count = 6;



    if (this.options.render) {
      (this.options.render as (gl: WebGLRenderingContext) => void)(gl);
      return;
    }


    // canvas调整到与显示器分辨率相匹配的大小
    resizeCanvasToDisplaySize(gl.canvas as HTMLCanvasElement);
    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);






    // 获取 uniform变量的位置
    // 1. 获取u_resolution
    const resolutionUniformLocation = gl.getUniformLocation(program!, "u_resolution");
    // 2. 获取u_textureSize
    const textureSizeLocation = gl.getUniformLocation(program!, "u_textureSize");
    // 将WebGL上下文的画布(canvas)的宽度和高度传递给着色器(shader)中的一个uniform变量(resolutionUniformLocation), shader变量名为u_resolution
    gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);
    // 将颜色传给着色器(shader)中的一个uniform变量(colorUniformLocation), shader变量名为u_color
    gl.uniform2f(textureSizeLocation, this.image!.width, this.image!.height);




    // 获取a_textcoord    
    const texcoordLocation = gl.getAttribLocation(program!, "a_texCoord");
    const texcoordBuffer = gl.createBuffer();
    // bind the texcoord buffer.
    gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
    // Turn on the texcoord attribute
    gl.enableVertexAttribArray(texcoordLocation);
    gl.vertexAttribPointer(texcoordLocation, size, type, normalize, stride, offset);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
      0.0, 0.0,
      1.0, 0.0,
      0.0, 1.0,
      0.0, 1.0,
      1.0, 0.0,
      1.0, 1.0,
    ]), gl.STATIC_DRAW);
    gl.bindBuffer(gl.ARRAY_BUFFER, null);




    // 获取顶点着色器中的属性变量a_position
    const positionAttributeLocation = gl.getAttribLocation(program!, "a_position");
    // 创建position buffer
    const positionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    gl.enableVertexAttribArray(positionAttributeLocation);
    gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset)
    gl.bindBuffer(gl.ARRAY_BUFFER, null)



    // 行政边界模版
    let areabuffers = this.areaArry
    if (areabuffers) {


      areabuffers.forEach((area, index) => {
        if (index == 0) {


        }
        if (area && navigator.platform.includes("Win")) {
          let buffer = area.flat()
          // console.log(buffer);


          gl.stencilFunc(gl.ALWAYS, 1, 0xff)
          // 当模板测试或深度测试失败时,保留模板当前值,即gl.clearStencil(0)中的0;
          // 否则测试都通过,或者模板测试通过且深度缓冲区无效时,取stencilFunc()里的reference,即1。
          gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE)
          //绑定缓冲对象
          gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)


          //不需要绘制模板
          gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(buffer), gl.STATIC_DRAW)
          gl.bindBuffer(gl.ARRAY_BUFFER, null)


          // gl.colorMask(true, true, true, true)


          gl.colorMask(false, false, false, false)
          gl.drawArrays(gl.TRIANGLES, 0, buffer.length / 2);
        }
        if (area && area.length > 0 && navigator.platform.includes("Mac")) {
          //   console.time('绘制边界')
          area.forEach((item: any, index: number) => {
            /* 模板 */
            // ALWAYS永远通过测试,1&0xff=1
            gl.stencilFunc(gl.ALWAYS, 1, 0xff)
            // 当模板测试或深度测试失败时,保留模板当前值,即gl.clearStencil(0)中的0;
            // 否则测试都通过,或者模板测试通过且深度缓冲区无效时,取stencilFunc()里的reference,即1。
            gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE)
            //绑定缓冲对象
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)


            //不需要绘制模板
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(item), gl.STATIC_DRAW)
            gl.bindBuffer(gl.ARRAY_BUFFER, null)



            gl.colorMask(false, false, false, false)
            gl.drawArrays(gl.TRIANGLES, 0, item.length / 2);
            gl.colorMask(true, true, true, true)
          })
          console.timeEnd('绘制边界')
        }
      });
      gl.colorMask(true, true, true, true)


    } else {
      // gl.clearStencil(1)
      console.log('没有交集, 没有掩膜');
    }


    // /* 绘图 */
    // 指定接下来要绘制的图形与之前模板之间测试方法,以及参考值 
    if (this.areaArry) {
      gl.stencilFunc(gl.EQUAL, 1, 0xff)
    }
    // 创建取色器纹理
    if (!this.colorGradientTexture) {
      this.createColorTexture()
    }


    const colorMaplocation = gl.getUniformLocation(program!, "u_colorMap");
    const uImageLocation = gl.getUniformLocation(program!, "u_image");
    var unit = 2;  // 挑选一个纹理单元


    gl.activeTexture(gl.TEXTURE1);
    gl.bindTexture(gl.TEXTURE_2D, this.texture);
    gl.uniform1i(uImageLocation, 1);


    gl.activeTexture(gl.TEXTURE0 + unit);
    gl.bindTexture(gl.TEXTURE_2D, this.colorGradientTexture);
    gl.uniform1i(colorMaplocation, unit);


    // 绑定缓冲对象
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
    // 写入数据
    // 绘制矩形,设置矩形的左上角坐标为(0, 0),右下角坐标为(gl.canvas.width, gl.canvas.height)。



    this.setRectangle(gl, leafletTop.x, leafletTop.y, renderWidth, renderHeight);
    gl.bindBuffer(gl.ARRAY_BUFFER, null)
    gl.drawArrays(primitiveType, offset, count);


  }

回答关注问题邀请回答
收藏

1 个回答

登录 后发表内容