我的webgl学习之路(四)用webgl画三角形

如何绘制三角形,其实注意观察,你会发现,点变成线,线的多种绘制样式,都是修改gl.drawArrays(gl.LINES, 0, n); 里的第一个参数;它就是绘制方式;
把它修改成gl.TRIANGLES;它就变成三角形,
它的绘制方式有:
//开始绘制,显示器显示结果;参数二:从哪个点开始绘制;参数三:绘制几个点
TRIANGLES:一系列单独的三角形;绘制方式:(v0,v1,v2),(v2,v1,v3),(v2,v3,v4)
TRIANGLE_STRIP:一系列带状的三角形
TRIANGLE_FAN:扇形绘制方式
 

绘制方式如下图:


 
 

绘制矩形,它是两个三角形组成;如图:

把gl.TRIANGLES(gl.TRIANGLE_STRIP,0,n)里的n改成4,因为它是4个点组成的两个三角形;

但是如果你把gl.TRIANGLE_STRIP修改成gl.TRIANGLE_FAN,你会发现成剪刀状;那是它绘制点的方式变了,gl.TRIANGLE_FAN所有的三角形都会共享顶点V0;

绘制三角形的代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>三角行</title>
    <script id="vs" type="x-shader/x-vertex">
        attribute vec4 a_Position;
        void main(void){
            gl_PointSize = 20.0;
            gl_Position = a_Position;
        }
    </script>
    <script id="fs" type="x-shader/x-fragment">
        void main(void){
            gl_FragColor = vec4(1.0,0.0,0.0,1.0);
        }
    </script>
</head>
<body>
<canvas id="canvas" style="background-color: black"></canvas>

<script>
    onload = function () {
        var canvas = document.getElementById("canvas");
        canvas.width = 500;
        canvas.height = 500;
        var gl = canvas.getContext("webgl");

        /*清空画板上的颜色,并初始化颜色*/
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        //设定canvas初始化时候的深度
        gl.clearDepth(1.0);
        //清空画面上的颜色
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        //顶点着色器和片段着色器生成
        var v_shader = create_shader("vs");
        var f_shader = create_shader("fs");

        // 程序对象的生成和连接
        var program = create_program(v_shader, f_shader);
        //获取a_Position变量的存储位置
        var a_Position = gl.getAttribLocation(program,"a_Position");

        //创建缓冲区
        var vertices = new Float32Array([
            0.0,0.5,-0.5,
            -0.5,0.5,-0.5,
        ]);
        /*正方形数据*/
        var vertices1 = new Float32Array([
            -0.5,0.5,
            -0.5,-0.5,
            0.5,0.5,
            0.5,-0.5
        ]);
        var n = 4;//点的个数

        //创建缓冲区
        var vertexBuffer = gl.createBuffer();
        if(!vertexBuffer){
            console.log("Failed to create the buffer object");//缓冲区创建失败
            return -1;
        }

        //将缓冲区绑定到目标对象
        gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);

        //向缓冲区写入数据
        gl.bufferData(gl.ARRAY_BUFFER,vertices1,gl.STATIC_DRAW);

        //将缓冲区对象分配给a_Position; 参数一:传入数据;参数二:指定每个顶点传入多少个数(2表示只取两个数传入,剩下的两个数0.0和1.0补上;1.0是透明度,跟vertexAttrib2f()类似)
        gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,0,0);

        //连接a_Position变量与分配给它的缓冲区对象
        gl.enableVertexAttribArray(a_Position);

        gl.clearColor(0.0,0.0,0.0,1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);
        //开始绘制,显示器显示结果;参数二:从哪个点开始绘制;参数三:绘制几个点
        //TRIANGLES:一系列单独的三角形;绘制方式:(v0,v1,v2),(v2,v1,v3),(v2,v3,v4)
        //TRIANGLE_STRIP:一系列带状的三角形
        //TRIANGLE_FAN:扇形绘制方式
        gl.drawArrays(gl.TRIANGLES, 0, n);

        function create_program(v_shader, f_shader) {
            var program = gl.createProgram();

            gl.attachShader(program, v_shader);
            gl.attachShader(program, f_shader);

            gl.linkProgram(program);
            gl.useProgram(program);
            return program;
        }

        function create_shader(id) {
            // 用来保存着色器的变量
            var shader;

            // 根据id从HTML中获取指定的script标签
            var scriptElement = document.getElementById(id);

            // 如果指定的script标签不存在,则返回
            if (!scriptElement) {
                return;
            }

            // 判断script标签的type属性
            switch (scriptElement.type) {

                // 顶点着色器的时候
                case 'x-shader/x-vertex':
                    shader = gl.createShader(gl.VERTEX_SHADER);//生成顶点着色器
                    break;

                // 片段着色器的时候
                case 'x-shader/x-fragment':
                    shader = gl.createShader(gl.FRAGMENT_SHADER);//生成片元着色器
                    break;
                default :
                    return;
            }

            // 将标签中的代码分配给生成的着色器
            gl.shaderSource(shader, scriptElement.text);

            // 编译着色器
            gl.compileShader(shader);

            // 判断一下着色器是否编译成功
            if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {

                // 编译成功,则返回着色器
                return shader;
            } else {

                // 编译失败,弹出错误消息
                alert(gl.getShaderInfoLog(shader));
            }
        }
        function create_program(vs, fs) {
            // 程序对象的生成
            var program = gl.createProgram();

            // 向程序对象里分配着色器
            gl.attachShader(program, vs);
            gl.attachShader(program, fs);

            // 将着色器连接
            gl.linkProgram(program);

            // 判断着色器的连接是否成功
            if (gl.getProgramParameter(program, gl.LINK_STATUS)) {

                // 成功的话,将程序对象设置为有效
                gl.useProgram(program);

                // 返回程序对象
                return program;
            } else {

                // 如果失败,弹出错误信息
                alert(gl.getProgramInfoLog(program));
            }
        }
    }
</script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/qq_25909453/article/details/80735201