WebGL编程指南案例解析之绘制一个点

<!DOCTYPE html>
<html>
<head>
    <title>webgl</title>
    <style type="text/css">
        #webgl{
            border:1px solid;
        }
    </style>
</head>
<body>

    <canvas id="webgl" width="400" height="400"></canvas>


    <!-- WebGL编程指南作者提供的开发工具类 -->
    <script src="./js/webgl-utils.js"></script>
    <script src="./js/webgl-debug.js"></script>
    <script src="./js/cuon-utils.js"></script>
    <!-- 案例相关代码 -->
    <script type="text/javascript" src="./lesson/webgl1.js"></script>
</body>
</html>

后续的本系列博客页都将基于这个页面进行开发,只是替换了案例相关代码部分的js文件。

首先让我们来看webgl1.js:

//第一章.绘制一个点,通过顶点着色器和片元着色器传参

//顶点着色器,接收attribute型变量a_Position
var vShader = `
    attribute vec4 a_Position;
    void main(){
        gl_Position = a_Position;
        gl_PointSize = 10.0;
    }
`;
//片元着色器,接收uniform型变量u_FragColor
var fShader = `
    precision mediump float;
    uniform vec4 u_FragColor;
    void main(){
        gl_FragColor = u_FragColor;
    }
`;

//注意:顶点着色器利用外部数据来初始化gl_Position变量
//     gl_Position变量(坐标)将输出到片元着色器,告诉片元着色器哪些坐标需要被着色
//     片元着色器对gl_Position中的坐标进行一一渲染(染色),并将颜色输出,这个颜色就是gl_FragColor
//     同样,这个输出的颜色,也是可以由外部数据初始化的

function main(){
    //获取canvas元素
    var canvas = document.getElementById('webgl');
    //获取webgl上下文
    var gl = getWebGLContext(canvas);
    if(!gl){
        console.log('Failed to get the rendering context for WebGL!');
        return;
    }
    //初始化着色器
    if(!initShaders(gl,vShader,fShader)){
        console.log('Failed to initialize shaders.');
        return;
    }
    //获取shaderProgram中attribute变量a_Position的地址和uniform变量u_FragColor的地址
    var a_Position = gl.getAttribLocation(gl.program,'a_Position');
    var u_FragColor = gl.getUniformLocation(gl.program,'u_FragColor');
    canvas.onmousedown = function(ev){
        click(ev,gl,canvas,a_Position);
    }
    var g_points = [];
    var g_colors = [];
    function click(ev,gl,canvas,a_Position){
        var x = ev.clientX;
        var y = ev.clientY;
        var 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.push([x,y]);
        //存储颜色
        //第一象限
        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])
        }
        //用指定颜色填充webgl容器,就是设置背景
        gl.clearColor(0.4,0.5,0.0,1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);

        var len = g_points.length;
        //根据已有的点和对应的颜色绘制图形(点)
        for (var i = 0; i < len; i++) {
            var xy = g_points[i];
            var rgba = g_colors[i];
            //将数据分配给a_Position变量和u_FragColor变量
            gl.vertexAttrib3f(a_Position,xy[0],xy[1],0.0);
            gl.uniform4f(u_FragColor,rgba[0],rgba[1],rgba[2],rgba[3]);
            //绘制一个点
            gl.drawArrays(gl.POINTS,0,1);
        }
    }
}
main();

注释很详细,如有疑问,请留言,点击之后的效果如下图:

原文地址:https://www.cnblogs.com/eco-just/p/10673442.html