美文网首页
《WebGL编程指南》学习笔记2——绘制一个点

《WebGL编程指南》学习笔记2——绘制一个点

作者: 小鸟游露露 | 来源:发表于2021-02-07 16:17 被阅读0次

本系列仅作为本人学习《WebGL编程指南》这本书的笔记所用

1.通过鼠标点击绘点

1.png
2.png

效果图

点击绘制点.gif
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>02描绘一个点2</title>

    <script src="./lib/cuon-matrix.js"></script>
    <script src="./lib/cuon-utils.js"></script>
    <script src="./lib/webgl-debug.js"></script>
    <script src="./lib/webgl-utils.js"></script>
</head>
<body onload="main()">
    <canvas id="webgl" width="400" height="400">
        不支持canvas的浏览器会展示这段文字
    </canvas>

    <script>
        // 顶点着色器程序
        let VSHADER_SOURCE =
        `
        attribute vec4 a_Position;
        attribute float a_PoinSize;
        void main() {
            gl_Position = a_Position; // 设置坐标
            gl_PointSize = a_PoinSize; // 设置尺寸
        }
        `;

        // 片元着色器程序
        let FSHADER_SOURCE = 
        `
        void main() {
            gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
        }
        `;

        // 主程序
        function main() {
            let canvas = document.getElementById('webgl');

            // 获取WebGL绘图上下文
            let gl = getWebGLContext(canvas);
            if(!gl) {
                console.error('无法使用WebGL');
                return;
            }
            
            // 初始化着色器
            if(!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
                console.error('无法使用着色器');
            }

            // 获取attribute 变量的存储位置
            let a_Position = gl.getAttribLocation(gl.program, 'a_Position');
            if (a_Position < 0) {
                console.log('无法获取 a_Position')
                return;
            }
            let a_PoinSize = gl.getAttribLocation(gl.program, 'a_PoinSize');

            // 将顶点位置传输给attribute 变量
            gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);
            gl.vertexAttrib1f(a_PoinSize, 18.0);

            // 注册鼠标点击事件响应函数===============================
            canvas.onmousedown = function (ev) {
                click(ev, gl, canvas, a_Position);
            };
            
            // 设置<canvas> 背景色
            gl.clearColor(0.0, 0.0, 0.0, 1.0);

            // 清除<canvas>
            gl.clear(gl.COLOR_BUFFER_BIT);
        }
            
        // 定义点检鼠标事件=================================================
        let g_points = []; // 鼠标点击位置数组
        function click (ev, gl, canvas, a_Position) {
            let x = ev.clientX; // 鼠标点击处的X坐标
            let y = ev.clientY; // 鼠标点击处的Y坐标
            let rect = ev.target.getBoundingClientRect();
            x = ((x - rect.left) - canvas.height / 2) / (canvas.height / 2);
            y = (canvas.width / 2 - (y - rect.top)) / (canvas.width / 2);
            
            // 将坐标存储到g_points数组中
            g_points.push(x);
            g_points.push(y);

            // 清除<canvas>
            gl.clear(gl.COLOR_BUFFER_BIT);

            let len = g_points.length;
            for(let i = 0; i < len; i += 2) {
                // 将点的位置传递到变量中a_Position
                gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);

                // 绘制点
                gl.drawArrays(gl.POINTS, 0, 1);
            }
        }
        // ===========================================================
    </script>
</body>
</html>

2.通过鼠标点击绘点+改变点的颜色

颜色传输人片元着色器

效果图

点击绘制点改变颜色.gif
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>02描绘一个点2</title>

    <script src="./lib/cuon-matrix.js"></script>
    <script src="./lib/cuon-utils.js"></script>
    <script src="./lib/webgl-debug.js"></script>
    <script src="./lib/webgl-utils.js"></script>
</head>
<body onload="main()">
    <canvas id="webgl" width="400" height="400">
        不支持canvas的浏览器会展示这段文字
    </canvas>

    <script>
        // 顶点着色器程序
        let VSHADER_SOURCE =
        `
        attribute vec4 a_Position;
        attribute float a_PoinSize;
        void main() {
            gl_Position = a_Position; // 设置坐标
            gl_PointSize = a_PoinSize; // 设置尺寸
        }
        `;

        // 片元着色器程序============================
        let FSHADER_SOURCE = 
        `
        precision mediump float; // 精度限定词-来指定变量的范围和精度,这里是中等精度
        uniform vec4 u_FragColor; // uniform 变量
        void main() {
            gl_FragColor = u_FragColor;
        }
        `;

        // 主程序
        function main() {
            let canvas = document.getElementById('webgl');

            // 获取WebGL绘图上下文
            let gl = getWebGLContext(canvas);
            if(!gl) {
                console.error('无法使用WebGL');
                return;
            }
            
            // 初始化着色器
            if(!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
                console.error('无法使用着色器');
                return;
            }

            // 获取a_Position、a_PoinSize 变量的存储位置
            let a_Position = gl.getAttribLocation(gl.program, 'a_Position');
            if (a_Position < 0) {
                console.log('无法获取 a_Position')
                return;
            }
            let a_PoinSize = gl.getAttribLocation(gl.program, 'a_PoinSize');
            if (a_PoinSize < 0) {
                console.log('无法获取 a_PoinSize')
                return;
            }

            // 获取u_FragColor 变量的存储位置===================
            let u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
            if (!u_FragColor) {
                console.log('无法获取 u_FragColor')
                return;
            }

            // 将顶点位置传输给attribute 变量 —————— 此处js传入值
            gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);
            gl.vertexAttrib1f(a_PoinSize, 18.0);

            // 注册鼠标点击事件响应函数===============================
            canvas.onmousedown = function (ev) {
                click(ev, gl, canvas, a_Position, u_FragColor);
            };
            
            // 设置<canvas> 背景色
            gl.clearColor(0.0, 0.0, 0.0, 1.0);

            // 清除<canvas>
            gl.clear(gl.COLOR_BUFFER_BIT);
        }
            
        // 定义点检鼠标事件=================================================
        let g_points = []; // 鼠标点击位置数组
        let g_colors = []; // 存储点颜色数组===============
        function click (ev, gl, canvas, a_Position, u_FragColor) { //===========================
            let x = ev.clientX; // 鼠标点击处的X坐标
            let y = ev.clientY; // 鼠标点击处的Y坐标
            let rect = ev.target.getBoundingClientRect();
            x = ((x - rect.left) - canvas.height / 2) / (canvas.height / 2);
            y = (canvas.width / 2 - (y - rect.top)) / (canvas.width / 2);
            
            // 将坐标存储到g_points数组中
            // g_points.push(x);
            // g_points.push(y);
            g_points.push([x, y]);

            // 将点的颜色存储到g_colors数组中=============================
            if (x >= 0.0 && y >= 0.0) {  // 第一象限
                g_colors.push([1.0, 0.0, 0.0, 1.0]); // 红色
            }
            else if (x < 0.0 && y < 0.0) { // 第三象限
               g_colors.push([0.0, 1.0, 0.0, 1.0]); // 绿色 
            }
            else {                          // 其它
                g_colors.push([1.0, 1.0, 1.0, 1.0]); // 白色
            }

            // 清除<canvas>
            gl.clear(gl.COLOR_BUFFER_BIT);
            
            // ===============================================
            let len = g_points.length;
            for(let i = 0; i < len; i++) {
                let xy = g_points[i];
                let rgba = g_colors[i];
                // 将点的位置传递到变量中a_Position
                gl.vertexAttrib3f(a_Position, xy[0], xy[1], 0.0);
                // 将点的颜色传输到变量中u_FragColor
                gl.uniform4f(u_FragColor, rgba[0], rgba[1], rgba[2], rgba[3]);

                // 绘制点
                gl.drawArrays(gl.POINTS, 0, 1);
            }
        }
        // ===========================================================
    </script>
</body>
</html>

未完待续。。。

相关文章

网友评论

      本文标题:《WebGL编程指南》学习笔记2——绘制一个点

      本文链接:https://www.haomeiwen.com/subject/dcvztltx.html