为什么 WebGL 'clear' 绘制到前端缓冲区?

Why WebGL 'clear' draw to front buffer?

为什么不需要交换缓冲区或 glFinish?

<!DOCTYPE html>
<html>
    <head>
        <title>Game v.0.0</title>
        <script>
            var gl = null;
            function startGame()
            {   {   var canvas = document.getElementById('gameCanvas');
                    var glNames = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
                    for (var glNameI = 0; glNameI < glNames.length; ++glNameI)
                        try
                        {   gl = canvas.getContext(glNames[glNameI]);
                            if (gl) break;
                        }
                        catch(e)
                        {}
                    if(!gl)
                    {   canvas.outerHTML = "<a>WebGL NOT SUPPORTED? :(</a>";
                        return;
                    }
                }

                window.onkeydown = function(ev)
                {   switch(ev.keyCode)
                    {
                    case 49:// 1 key
                        gl.clearColor(0.3,0.7,0.2,1.0);
                        gl.clear(gl.COLOR_BUFFER_BIT); 
                        break;
                    case 50:// 2 key
                        gl.clearColor(0.3,0.2,0.7,1.0);
                        gl.clear(gl.COLOR_BUFFER_BIT); 
                        break;
                    }
                };
            }
        </script>
        <style type="text/css">
            canvas {border: 2px dotted blue;}
        </style>
    </head>

    <body onload="startGame()">
        <div><canvas id="gameCanvas" width="640" height="480"></canvas></div>
    </body>

</html>

因为这就是 WebGL 的工作方式。

WebGL swaps/copies 自动。任何时候你做任何影响 WebGL drawingBuffer(想想“后台缓冲区”)的事情都会被标记为 swap/copy。下次浏览器合成网页时,它会进行交换或复制。你可以告诉它总是复制. 你不能告诉它总是 swap

具体来说,使用 {preserveDrawingBuffer: true} 创建 WebGL 上下文,如

gl = someCanvas.getContext("webgl", {preserveDrawingBuffer: true});

告诉 WebGL 您总是希望它进行复制。

默认是WebGL根据各种因素选择交换或复制。例如,如果抗锯齿打开,它总是有效的副本(解析),而如果抗锯齿关闭,它可能是一个交换。此外,在这种默认情况下,当 preserveDrawingBuffer 在执行复制或交换后为 false 时,它​​将清除后备缓冲区。这是为了无论选择复制还是交换,都尽量让它看起来一致。

如果 preserveDrawingBuffer = true 那么它永远不会清除后台缓冲区。

如果你想在多个 JavaScript 事件上做一堆工作并且在你完成所有工作之前不让用户看到结果你需要渲染到带有附加纹理的帧缓冲区或renderbuffer 然后当你所有的工作都完成渲染而不是附加到 canvas (后备缓冲区)。

至于 gl.finish 那是 WebGL 中的空操作。没有意义。