首页 > 解决方案 > 告诉 PixiJS WebGL 状态已被外部修改

问题描述

我正在尝试将 PixiJS 与现有的自定义 WebGL 引擎集成。现有的自定义引擎是主机,每帧处理对 PixiJS 的控制。现有的自定义引擎将 WebGL 状态配置为“几乎”默认状态,然后调用 PixiJS;PixiJS 完成后,现有的自定义引擎会完全重置 WebGL 状态。

在代码中:

onFrame() {
  resetWebGLStateToDefault(gl);
  gl.bindFramebuffer(...)
  gl.viewport(...)
  thenWeUsePixiJSToDoSomeAdvancedStuff();
  resetWebGLStateToDefault(gl);
}

我的问题 thenWeUsePixiJSToDoSomeAdvancedStuff()中,我怎么能告诉 PixiJS 状态不是上次运行时的状态?几乎所有东西都已重置;PixiJS 应该假设一切都是默认的,我还想告诉 PixiJS 当前的视口和帧缓冲区是什么。

我试过Renderer.reset, StateSystem.resetStateSystem.forceState但我想这还不够;PixiJS 一直假设它之前设置的一些纹理仍然是绑定的(它们不是,现有的自定义引擎取消绑定所有内容)并且我得到了很多[.WebGL-0x7fd105545e00]RENDER WARNING: there is no texture bound to the unit ?. 几乎所有纹理单元,1-15,除了第一个。

编辑

可能值得一提的是,我直接调用了渲染器;我认为我需要这样做,因为现有的自定义引擎拥有渲染循环。我基本上是在尝试这样的事情,但是在第一帧之后我得到了 WebGL 纹理错误。

          renderer.reset();
          renderer.render(sprite);
          renderer.reset();

编辑

我用应用程序尝试了同样的事情autoStart: false,我得到了同样的错误。

          pixiApp.renderer.reset();
          pixiApp.render();
          pixiApp.renderer.reset();

标签: pixi.js

解决方案


问题似乎是我正在使用当前绑定的 FBO 调用 PixiJS;我通过创建一个单独的PIXI.RenderTexture,在那里渲染,然后使用全屏四边形在我的 WebGL 引擎上合成来解决我的所有问题。

        // Create a render texture
        const renderTexture = PIXI.RenderTexture.create(640, 360);

        // Render with PixiJS
        renderer.reset();
        renderer.render(this.stage, renderTexture);
        renderer.reset();

        // Retrieve the raw WebGL texture
        const texture = renderTexture.baseTexture._glTextures[renderer.texture.CONTEXT_UID].texture;

        // Now composite on top of the other engine
        gl.bindFramebuffer(gl.FRAMEBUFFER, theFramebufferWhereINeededPixiJSToRenderInTheFirstPlace);

        gl.useProgram(quadProgram);
        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.uniform1i(u_Texture, 0);

        gl.bindBuffer(gl.ARRAY_BUFFER, quadBuffer);
        gl.vertexAttribPointer(0, 2, gl.BYTE, false, 2, 0);
        gl.enableVertexAttribArray(0);
        gl.bindBuffer(gl.ARRAY_BUFFER, null);
        gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
        gl.useProgram(null);

您可能需要resize()渲染器和/或渲染纹理,具体取决于您的实际设置。


推荐阅读