按左键或右键更改颜色时遇到问题

Having trouble changing color by pressing left or right button

当您从左按钮到右按钮时,我无法更改颜色。按住鼠标左键并在canvas内移动应该画出按住鼠标右键时鼠标运动的红点和蓝点轨迹。

问题是:一旦您使用左键绘制并点击右键,它会改变左键绘制的颜色,反之亦然。

需要有关如何解决此问题的帮助或提示。谢谢。

javascript:

// Vertex shader program
var VSHADER_SOURCE =
    'attribute vec4 a_Position;\n' +
    'void main() {\n' +
    '  gl_Position = a_Position;\n' +
    '  gl_PointSize = 10.0;\n' +
    '}\n';

// Fragment shader program
var FSHADER_SOURCE =
    'precision mediump float;\n' +
    'uniform vec4 u_FragColor;\n' + 
    'void main() {\n' +
    '  gl_FragColor = u_FragColor;\n' +
    '}\n';

 var mousePressed = false;      // Holds boolean if mouse is pressed down
 var leftClick = false;         // Holds boolean if left click is pressed down
 var rightClick = false;        // Holds boolean if right click is pressed down

 function main() 
 {
    // Retrieve <canvas> element
    var canvas = document.getElementById('webgl');

    // Get the rendering context for WebGL
    var gl = getWebGLContext(canvas);
    if (!gl) 
    {
        console.log('Failed to get the rendering context for WebGL');

        return;
    }

    // Initialize shaders
    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) 
    {
        console.log('Failed to intialize shaders.');
        return;
    }

    // Get the storage location of a_Position
    var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    if (a_Position < 0) 
    {
        console.log('Failed to get the storage location of a_Position');
        return;
    }

    // Get the storage location of u_FragColor
    var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
    if (!u_FragColor) 
    {
        console.log('Failed to get the storage location of u_FragColor');
        return;
    }

    // Register function (event handler) to be called on a mouse mousePressed
    canvas.onmousedown = function(ev)
    { 
    console.log('f1 called');
        // Identify which click is being press down
        switch (ev.which)
        {
            case 1:         // leftClick click
            leftClick = true;
            break;
            case 3:         // rightClick click
            rightClick = true;
            break;
        }

        // Mouse click is being pressed down
        mousePressed = true;

        // call function
        //console.log('calling f1');
        //drawDots(ev, gl, canvas, a_Position, u_FragColor, false); 
        //drawDots(ev, gl, a_Position, u_FragColor, false); 
    };

    canvas.onmousemove = function(ev)
    {
        console.log('f2 called');
        if (mousePressed)
        {
            console.log('calling drawDots');
            drawDots(ev, gl, canvas, a_Position, u_FragColor, true); 
        }
            //drawDots(ev, gl, a_Position, u_FragColor, true);
    };

    canvas.onmouseup = function(ev)
    {
        console.log('f3 called');
        mousePressed = false;
        leftClick = false;
        rightClick = false;
    };

    // Specify the color for clearing <canvas>
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    console.log('clearColor call');

    // Clear <canvas>
    gl.clear(gl.COLOR_BUFFER_BIT);
    console.log('clear call');
}

var g_points = []; // The array for the position of a mouse mousePressed

function drawDots(ev, gl, canvas, a_Position, u_FragColor, down) 
//function drawDots(ev, gl, a_Position, u_FragColor, down)
{
    console.log('drawDots called');
    var rect = ev.target.getBoundingClientRect() ;

    var x = ev.clientX; // x coordinate of a mouse pointer
    var y = ev.clientY; // y coordinate of a mouse pointer

    x = ((x - rect.left) - canvas.width/2)/(canvas.width/2);
    y = (canvas.height/2 - (y - rect.top))/(canvas.height/2);

    // For left click
    if (down == true && leftClick == true)
    {
        console.log('called left');
        // Store the coordinates to g_points array
        g_points.push(x); g_points.push(y);

        // Clear <canvas>
        gl.clear(gl.COLOR_BUFFER_BIT);

        var len = g_points.length;

        for(var i = 0; i < len; i += 2) 
        {
            // Pass the position of a point to a_Position variable
            gl.uniform4f(u_FragColor, 1.0, 0.0, 0.0, 1.0);
            gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);


            // Draw
            gl.drawArrays(gl.POINTS, 0, 1);
        }
    }
    // Right click
    else if (down == true && rightClick == true)
    {
        console.log('called right');
        // Store the coordinates to g_points array
        g_points.push(x); g_points.push(y);

        // Clear <canvas>
        gl.clear(gl.COLOR_BUFFER_BIT);

        var len = g_points.length;
        for(var i = 0; i < len; i += 2) 
        {
            // Pass the position of a point to a_Position variable
            gl.uniform4f(u_FragColor, 0.0, 0.0, 1.0, 1.0);
            gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);


            // Draw
            gl.drawArrays(gl.POINTS, 0, 1);
        }
    }
}

对于添加到 g_points 的每个点,您需要记住创建该点的颜色。所以你可以创建另一个数组来跟踪点颜色。

var g_points = []; // The array for the position of a mouse mousePressed
var g_colors = []; 

并在每次添加一个点时将颜色添加到数组中。

// Store the coordinates to g_points array
g_points.push(x); g_points.push(y);

// Store the color
g_colors.push([1.0, 0.0, 0.0, 1.0]);

然后更新您的 for 循环以对每个点使用给定的颜色。

for(var i = 0; i < len; i += 2) 
{
    // Pass the position of a point to a_Position variable
    gl.uniform4fv(u_FragColor, g_colors[i/2]);
    gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);


    // Draw
    gl.drawArrays(gl.POINTS, 0, 1);
}

记得同时更新左键单击代码和右键单击代码以存储和使用颜色。

这是你的完整代码和修复:

// Vertex shader program
var VSHADER_SOURCE =
    'attribute vec4 a_Position;\n' +
    'void main() {\n' +
    '  gl_Position = a_Position;\n' +
    '  gl_PointSize = 10.0;\n' +
    '}\n';

// Fragment shader program
var FSHADER_SOURCE =
    'precision mediump float;\n' +
    'uniform vec4 u_FragColor;\n' + 
    'void main() {\n' +
    '  gl_FragColor = u_FragColor;\n' +
    '}\n';

 var mousePressed = false;      // Holds boolean if mouse is pressed down
 var leftClick = false;         // Holds boolean if left click is pressed down
 var rightClick = false;        // Holds boolean if right click is pressed down

 function main() 
 {
    // Retrieve <canvas> element
    var canvas = document.getElementById('webgl');
    canvas.oncontextmenu = function (e) {
        e.preventDefault();
    };

    // Get the rendering context for WebGL
    //var gl = getWebGLContext(canvas);
    var gl = canvas.getContext('webgl');
    if (!gl) 
    {
        console.log('Failed to get the rendering context for WebGL');

        return;
    }

    // Initialize shaders
    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) 
    {
        console.log('Failed to intialize shaders.');
        return;
    }

    // Get the storage location of a_Position
    var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    if (a_Position < 0) 
    {
        console.log('Failed to get the storage location of a_Position');
        return;
    }

    // Get the storage location of u_FragColor
    var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
    if (!u_FragColor) 
    {
        console.log('Failed to get the storage location of u_FragColor');
        return;
    }

    // Register function (event handler) to be called on a mouse mousePressed
    canvas.onmousedown = function(ev)
    { 
    console.log('f1 called');
        // Identify which click is being press down
        switch (ev.which)
        {
            case 1:         // leftClick click
            leftClick = true;
            break;
            case 3:         // rightClick click
            rightClick = true;
            break;
        }

        // Mouse click is being pressed down
        mousePressed = true;

        // call function
        //console.log('calling f1');
        //drawDots(ev, gl, canvas, a_Position, u_FragColor, false); 
        //drawDots(ev, gl, a_Position, u_FragColor, false); 
    };

    canvas.onmousemove = function(ev)
    {
        console.log('f2 called');
        if (mousePressed)
        {
            console.log('calling drawDots');
            drawDots(ev, gl, canvas, a_Position, u_FragColor, true); 
        }
            //drawDots(ev, gl, a_Position, u_FragColor, true);
    };

    canvas.onmouseup = function(ev)
    {
        console.log('f3 called');
        mousePressed = false;
        leftClick = false;
        rightClick = false;
    };

    // Specify the color for clearing <canvas>
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    console.log('clearColor call');

    // Clear <canvas>
    gl.clear(gl.COLOR_BUFFER_BIT);
    console.log('clear call');
}

var g_points = []; // The array for the position of a mouse mousePressed
var g_colors = []; 

function drawDots(ev, gl, canvas, a_Position, u_FragColor, down) 
//function drawDots(ev, gl, a_Position, u_FragColor, down)
{
    console.log('drawDots called');
    var rect = ev.target.getBoundingClientRect() ;

    var x = ev.clientX; // x coordinate of a mouse pointer
    var y = ev.clientY; // y coordinate of a mouse pointer

    x = ((x - rect.left) - canvas.width/2)/(canvas.width/2);
    y = (canvas.height/2 - (y - rect.top))/(canvas.height/2);

    // For left click
    if (down == true && leftClick == true)
    {
        console.log('called left');
        // Store the coordinates to g_points array
        g_points.push(x); g_points.push(y);

        // Store the color
        g_colors.push([1.0, 0.0, 0.0, 1.0]);

        // Clear <canvas>
        gl.clear(gl.COLOR_BUFFER_BIT);

        var len = g_points.length;

        for(var i = 0; i < len; i += 2) 
        {
            // Pass the position of a point to a_Position variable
            gl.uniform4fv(u_FragColor, g_colors[i/2]);
            gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);


            // Draw
            gl.drawArrays(gl.POINTS, 0, 1);
        }
    }
    // Right click
    else if (down == true && rightClick == true)
    {
        console.log('called right');
        // Store the coordinates to g_points array
        g_points.push(x); g_points.push(y);

        // Store the color
        g_colors.push([0.0, 0.0, 1.0, 1.0]);

        // Clear <canvas>
        gl.clear(gl.COLOR_BUFFER_BIT);

        var len = g_points.length;
        for(var i = 0; i < len; i += 2) 
        {
            // Pass the position of a point to a_Position variable
            gl.uniform4fv(u_FragColor, g_colors[i/2]);
            gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);


            // Draw
            gl.drawArrays(gl.POINTS, 0, 1);
        }
    }
}
<html>
<script type="text/javascript">
function initShaders(gl, vertexStr, fragmentStr) {
    var fragmentShader = getShader(gl, fragmentStr, true);
    var vertexShader = getShader(gl, vertexStr, false);

    gl.program = gl.createProgram();
    gl.attachShader(gl.program, vertexShader);
    gl.attachShader(gl.program, fragmentShader);
    gl.linkProgram(gl.program);

    if (!gl.getProgramParameter(gl.program, gl.LINK_STATUS)) {
        alert("Could not initialise shaders");
    }

    gl.useProgram(gl.program);

    return true;
}

function getShader(gl, str, isFrag) {
    var shader;
    if (isFrag) {
        shader = gl.createShader(gl.FRAGMENT_SHADER);
    } else {
        shader = gl.createShader(gl.VERTEX_SHADER);
    }

    gl.shaderSource(shader, str);
    gl.compileShader(shader);

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(shader));
        return null;
    }

    return shader;
}
</script>
<body onload="main();">
    <canvas id="webgl" style="border: none;" width="500" height="500"></canvas>
</body>
</html>