【问题标题】:WeChat (WebGL) MiniGame not working on a device, but works in devtool微信(WebGL)小游戏无法在设备上运行,但可以在 devtool 中运行
【发布时间】:2019-01-09 10:27:23
【问题描述】:

我想做什么

我正在尝试将自己的基于 WebGL 的引擎移植到微信小游戏环境中,目前正在尝试将 WebGL 上下文以粉红色清除:

有什么问题

我关注了腾讯提供的示例以及有关如何设置游戏项目的 ThreeJS 示例。它在微信开发者工具中运行良好(如上图所示),但是当我尝试在我的设备(Android 手机)上打开它时,它卡在 100% 加载屏幕:

这样停留约1分钟,然后显示黑屏。

我的代码

我的代码中没有资源加载。 这是我的main.js 中的内容:


var ctx = canvas.getContext('webgl', {
  antialias: true,
  depth: true,
  preserveDrawingBuffer: true
});

ctx.viewport(0,0,ctx.canvas.width,ctx.canvas.height)
ctx.colorMask(true,true,true,true)
ctx.depthMask(true)
ctx.enable(ctx.BLEND)
ctx.blendFunc(ctx.SRC_ALPHA, ctx.ONE_MINUS_SRC_ALPHA)
ctx.clearColor(1.0,0.0,1.0,1.0)

export default class Main {

  constructor() {
    window.requestAnimationFrame(this.loop.bind(this), canvas)
  }

  render() {
    ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT)
  }

  update() {

  }

  loop() {
    this.update()
    this.render()
    window.requestAnimationFrame(this.loop.bind(this), canvas)
  }
}

我的game.js也很简单:

import './weapp-adapter/index.js'
import './symbol'
import Main from './js/main'
new Main()

我的game.json 仅包含以下内容:

{
    "deviceOrientation": "portrait"
}

附加信息

我还注意到,当我尝试 Threejs 示例(适用于设备)和渲染函数中的注释行时,它的行为将相同(卡在 100% 加载中)。

【问题讨论】:

    标签: javascript webgl wechat


    【解决方案1】:

    解决方案

    终于知道怎么解决了:

    当我在动画帧的第一次调用中放置了 WebGL 上下文初始化,而实际渲染在所有其他调用中完成时,它在我的 Android 设备上按预期工作。这里是main.js我改了:

    export default class Main {
    
      constructor() {
        this.render = this.render_first
        requestAnimationFrame(() => this.animate())
      }
    
      showmsg(t,c) {
        wx.showModal({
          title: ""+t,
          content: ""+c,
          showCancel: false,
          confirmText:'OK',
          success: function(res){}
        });
      }
    
      animate() {
        this.render();
        requestAnimationFrame(() => this.animate())
      }
    
      render_first() {
    
        this.render = this.render_normal
        var _this = this
        this.domElement = canvas
    
        var contextAttributes = {
          alpha: false,
          depth: true,
          stencil: false,
          antialias: false
        }
    
        this.domElement.addEventListener("webglcontextlost", function(e){
          _this.showmsg("WebGL","Context lost");
        }, false)
    
        this.domElement.addEventListener("webglcontextrestored", function(e){
          _this.showmsg("WebGL","Context restored");
        }, false)
    
        this._gl = this.domElement.getContext( 'webgl', contextAttributes ) || this.domElement.getContext( 'experimental-webgl', contextAttributes )
    
        var _gl = this._gl
    
        var vsrc = ""
        vsrc += "uniform mat4 uModelView;"
        vsrc += "uniform mat4 uProjView;"
        vsrc += "attribute highp vec4 aPosition;"
        vsrc += "void main(void) {"
        vsrc += "   gl_Position = ( uProjView * uModelView ) * aPosition;"
        vsrc += "}"
    
        var vid = _gl.createShader(_gl.VERTEX_SHADER)
        _gl.shaderSource(vid,vsrc)
        _gl.compileShader(vid)
        if (!_gl.getShaderParameter(vid, _gl.COMPILE_STATUS)) {
            console.error("Vertex shader failed: ", _gl.getShaderInfoLog(vid))
        }
    
        this._vid = vid
    
        var fsrc = ""
        fsrc += "void main(void) {"
        fsrc += "   gl_FragColor = vec4(1.0,1.0,0.0,1.0);"
        fsrc += "}"
    
        var fid = _gl.createShader(_gl.FRAGMENT_SHADER)
        _gl.shaderSource(fid,fsrc)
        _gl.compileShader(fid)
        if (!_gl.getShaderParameter(fid, _gl.COMPILE_STATUS)) {
          console.error("Fragment shader failed: ", _gl.getShaderInfoLog(fid))
        }
    
        this._fid = fid
    
        var pid = _gl.createProgram()
        _gl.attachShader(pid,vid)
        _gl.attachShader(pid,fid)
        _gl.linkProgram(pid)
    
        if (!_gl.getProgramParameter(pid, _gl.LINK_STATUS)) {
            let info = _gl.getProgramInfoLog(pid)
            console.error("Program link failed:", info )
        }
    
        _gl.useProgram(pid)
    
        this._pid = pid
    
        var aPosition = _gl.getAttribLocation(pid,"aPosition")
        var uModelView = _gl.getUniformLocation(pid,"uModelView")
        var uProjView = _gl.getUniformLocation(pid,"uProjView")
    
        _gl.uniformMatrix4fv( uModelView, false, [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] )
        _gl.uniformMatrix4fv( uProjView, false, [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] )
    
        this.uni = [uModelView, uProjView]
    
        this.phase = 0.0
    
        var data = [0,0,0,1,0,0,0,1,0]
        var idata = [0,1,2]
    
        var vbID = _gl.createBuffer()
        _gl.bindBuffer(_gl.ARRAY_BUFFER,vbID)
        _gl.bufferData(_gl.ARRAY_BUFFER, new Float32Array(data), _gl.STATIC_DRAW)
    
        var vbiID = _gl.createBuffer();
        _gl.bindBuffer(_gl.ELEMENT_ARRAY_BUFFER, vbiID)
        _gl.bufferData(_gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(idata), _gl.STATIC_DRAW)
    
        _gl.vertexAttribPointer( aPosition, 3, _gl.FLOAT, false, 0, 0 )
        _gl.enableVertexAttribArray( aPosition )
        _gl.bindBuffer(_gl.ELEMENT_ARRAY_BUFFER, vbiID)
    
        this.vb = [vbID,vbiID]
    
        _gl.clearColor(1.0,0.0,1.0,1.0)
      }
    
      render_normal() {
    
        var _gl = this._gl
    
        var et = 60.0 / 1000.0
        this.phase += 180.0 * 60.0 / 1000.0
        var py = Math.sin(this.phase * Math.PI/180.0) * 0.5
        _gl.uniformMatrix4fv( this.uni[0], false, [1,0,0,0,0,1,0,0,0,0,1,0,py,0,0,1] )
    
        _gl.clear( _gl.COLOR_BUFFER_BIT )
        _gl.drawElements(_gl.TRIANGLES, 3, _gl.UNSIGNED_SHORT, 0)
    
      }
    }
    
    

    出了什么问题

    似乎在实际设备上,微信小游戏在与主 JavaScript 执行不同的线程中运行动画循环。由于 WebGL (OpenGL) 上下文只能在同一个线程中访问(除了在多个线程可以共享相同上下文的本机应用程序中),它会在设备上崩溃,因为渲染函数会尝试访问在不同线程中初始化的 gl 上下文。

    这在微信开发者工具中是不可见的,因为该工具不能准确模拟设备架构的工作方式,并且动画帧和 JavaScript 执行似乎发生在同一个线程中。

    【讨论】:

      猜你喜欢
      • 2023-03-30
      • 1970-01-01
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 2014-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多