用剪刀擦除 webgl 绘图

erasing webgl drawing with scissor

我正在尝试为下面的 canvas 实现一个与鼠标点击一起工作的橡皮擦,并且橡皮擦的位置由鼠标位置控制。我如何使用 webgl 的剪刀通过鼠标点击删除 canvas 中的蓝色方块?

var gGL = null;
function initializeGL() {
    var canvas = document.getElementById("GLCanvas");
    gGL = canvas.getContext("webgl") ||
        canvas.getContext("experimental-webgl");

    if (gGL !== null) {
        gGL.clearColor(0.8, 0.8,0.8 ,1.0);  
        initSquareBuffer(); 
        initSimpleShader("VertexShader", "FragmentShader");
    } else {
        document.write("<br><b>WebGL is not supported!</b>");
    }
}
function drawSquare() {
    gGL.clear(gGL.COLOR_BUFFER_BIT);  
    gGL.useProgram(gSimpleShader);
    gGL.enableVertexAttribArray(gShaderVertexPositionAttribute);
    gGL.drawArrays(gGL.TRIANGLE_STRIP, 0, 4);
}

function doGLDraw() {
    initializeGL();   
    drawSquare();   
}

var gSquareVertexBuffer = null;

function initSquareBuffer() {
    var verticesOfSquare = [
        -0.5, -0.5, 0.0,
        0.5, -0.5, 0.0,
        -0.5, 0.5, 0.0,
        0.5, 0.5, 0.0
    ];
    gSquareVertexBuffer = gGL.createBuffer();
    gGL.bindBuffer(gGL.ARRAY_BUFFER, gSquareVertexBuffer);
    gGL.bufferData(gGL.ARRAY_BUFFER, new Float32Array(verticesOfSquare), gGL.STATIC_DRAW);
}

var gSimpleShader = null;
var gShaderVertexPositionAttribute = null;
function initSimpleShader(vertexShaderID, fragmentShaderID) {
    var vertexShader = loadAndCompileShader(vertexShaderID, gGL.VERTEX_SHADER);
    var fragmentShader = loadAndCompileShader(fragmentShaderID, gGL.FRAGMENT_SHADER);

    gSimpleShader = gGL.createProgram();
    gGL.attachShader(gSimpleShader, vertexShader);
    gGL.attachShader(gSimpleShader, fragmentShader);
    gGL.linkProgram(gSimpleShader);
  
    gShaderVertexPositionAttribute = gGL.getAttribLocation(gSimpleShader, "aSquareVertexPosition");
    gGL.bindBuffer(gGL.ARRAY_BUFFER, gSquareVertexBuffer);
    gGL.vertexAttribPointer(gShaderVertexPositionAttribute,
        3,gGL.FLOAT,false,0,0);  
  }
function loadAndCompileShader(id, shaderType) {
    var shaderText, shaderSource, compiledShader;
    shaderText = document.getElementById(id);
    shaderSource = shaderText.firstChild.textContent;
    compiledShader = gGL.createShader(shaderType);
    gGL.shaderSource(compiledShader, shaderSource);
    gGL.compileShader(compiledShader);
    return compiledShader;
}
<html>
    <head>
        <title>Example 2.3: The Draw One Square Project</title>
        <link rel ="icon" type ="image/x-icon" href="./favicon.png">
        <script type="x-shader/x-vertex" id="VertexShader">
            attribute vec3 aSquareVertexPosition;
            void main(void) {
                gl_Position = vec4(aSquareVertexPosition, 1.0); 
            }
        </script>

        <script type="x-shader/x-fragment" id="FragmentShader">
            void main(void) {
                gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
            }
        </script>   
        <script type="text/javascript" src="src/ShaderSupport.js"></script>
        <script type="text/javascript" src="src/VertexBuffer.js"></script>
        <script type="text/javascript" src="src/WebGL.js"></script>
    </head>
    <body onload="doGLDraw()">
        <canvas id="GLCanvas" width="640" height="480">
            Your browser does not support the HTML5 canvas.
        </canvas>
    </body>
</html>

用剪刀擦除听起来不是很有用的功能。它只允许您擦除矩形,但在任何情况下使用剪刀都非常简单

// turn on the scissor
gl.enable(gl.SCISSOR_TEST);

// set the size of the scissor in pixels 
gl.scissor(x, y, width, height);

从现在开始,所有绘图都将被裁剪为 (x, y, width, height)。这包括 gl.clear 和所有形式的 gl.drawXXX

var gl = document.querySelector("canvas").getContext("webgl", { 
  preserveDrawingBuffer: true, 
});

function render() {
  var width  = rand(gl.canvas.width);
  var height = rand(gl.canvas.height);
  var x      = rand(gl.canvas.width - width);
  var y      = rand(gl.canvas.height - height);
  
  gl.enable(gl.SCISSOR_TEST);
  gl.scissor(x, y, width, height);
  gl.clearColor(rand(1), rand(1), rand(1), 1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  
  requestAnimationFrame(render);
}
requestAnimationFrame(render);

function rand(max) {
  return Math.random() * max;
}
canvas { border: 1px solid black; }
<canvas></canvas>