OPENGL 不同绘制图元的类型,顶点索引的解释方式不同

先看几个摘抄的代码例子

1

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <canvas id="canvas" width="400" height="400">
        Please use a browser that supports "canvas"
    </canvas>
    <script src="../lib/cuon-matrix.js"></script>
    <script>
        var VSHADER_SOURCE =
            'attribute vec4 a_Position;\n' +
            'attribute vec4 a_Color;\n' +
            'uniform mat4 u_ViewProjMatrix;\n' +
            'varying vec4 v_Color;\n' +
            'void main() {\n' +
            '  gl_Position = u_ViewProjMatrix * a_Position;\n' +
            '  v_Color = a_Color;\n' +
            '}\n';

        // Fragment shader program
        var FSHADER_SOURCE =
            '#ifdef GL_ES\n' +
            'precision mediump float;\n' +
            '#endif\n' +
            'varying vec4 v_Color;\n' +
            'void main() {\n' +
            '  gl_FragColor = v_Color;\n' +
            '}\n';
        const gl = canvas.getContext('webgl');
        const createShader = (type, source) => {
            const shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            const compileState = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
            if (!compileState) {
                const info = gl.getShaderInfoLog(shader);
                console.log('编译白痴信息为' + info)
                gl.deleteShader(shader);
                return null;
            }
            return shader
        }
        const createProgram = (vshader, fshader) => {
            const vertexShader = createShader(gl.VERTEX_SHADER, vshader);
            const fragementSaher = createShader(gl.FRAGMENT_SHADER, fshader);
            if (!vertexShader || !fragementSaher) {
                console.log('创建着色器失败')
                return null
            }
            const program = gl.createProgram();
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragementSaher);
            gl.linkProgram(program);
            const linkState = gl.getProgramParameter(program, gl.LINK_STATUS);
            if (!linkState) {
                const err = gl.getProgramInfoLog(program);
                console.log('链接报错信息为' + err);
                gl.deleteShader(vertexShader);
                gl.deleteShader(fragementSaher);
                gl.deleteProgram(program);
                return null
            }
            return program
        }
        const program = createProgram(VSHADER_SOURCE, FSHADER_SOURCE)
        gl.useProgram(program);
        gl.program = program;
        const initVertexBuffers = () => {
            var verticesColors = new Float32Array([
                // Vertex coordinates and color
                1.0, 1.0, 1.0, 1.0, 1.0, 1.0,  // v0 White
                -1.0, 1.0, 1.0, 1.0, 0.0, 1.0,  // v1 Magenta
                -1.0, -1.0, 1.0, 1.0, 0.0, 0.0,  // v2 Red
                1.0, -1.0, 1.0, 1.0, 1.0, 0.0,  // v3 Yellow
                1.0, -1.0, -1.0, 0.0, 1.0, 0.0,  // v4 Green
                1.0, 1.0, -1.0, 0.0, 1.0, 1.0,  // v5 Cyan
                -1.0, 1.0, -1.0, 0.0, 0.0, 1.0,  // v6 Blue
                -1.0, -1.0, -1.0, 0.0, 0.0, 0.0   // v7 Black
            ]);

            var indices = new Uint8Array([
                0, 1, 2, 0, 2, 3,    // front
                0, 3, 4, 0, 4, 5,    // right
                0, 5, 6, 0, 6, 1,    // up
                1, 6, 7, 1, 7, 2,    // left
                7, 4, 3, 7, 3, 2,    // down
                4, 7, 6, 4, 6, 5     // back
            ]);
            const vertexColorbuffer = gl.createBuffer();
            const indexBuffer = gl.createBuffer();
            const size = verticesColors.BYTES_PER_ELEMENT;
            gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
            gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
            var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
            gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, size * 6, 0);
            gl.enableVertexAttribArray(a_Position);
            var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
            gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, size * 6, size * 3);
            gl.enableVertexAttribArray(a_Color);

            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

            return indices.length;
        }
        const n = initVertexBuffers();
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.enable(gl.DEPTH_TEST);
        console.log(n, 'nnn')
        var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_ViewProjMatrix');
        var mvpMatrix = new Matrix4();
        mvpMatrix.setPerspective(30, 1, 1, 100);
        mvpMatrix.lookAt(3, 3, 7, 0, 0, 0, 0, 1, 0);
        gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);

    </script>
</body>

</html>

 2

    var canvasElement=document.getElementById('webgl');
    var gl=canvasElement.getContext('webgl');
    //顶点着色器源码
    var vertexShaderSource = '' +
        //attribute声明vec4类型变量apos
        'attribute vec4 apos;'+
        'void main(){' +
        //设置几何体轴旋转角度为30度,并把角度值转化为浮点值
        'float radian = radians(30.0);'+
        //求解旋转角度余弦值
        'float cos = cos(radian);'+
        //求解旋转角度正弦值
        'float sin = sin(radian);'+
        //引用上面的计算数据,创建绕x轴旋转矩阵
        // 1      0       0    0
        // 0   cosα   sinα   0
        // 0  -sinα   cosα   0
        // 0      0        0   1
        'mat4 mx = mat4(1,0,0,0,  0,cos,-sin,0,  0,sin,cos,0,  0,0,0,1);'+
        //引用上面的计算数据,创建绕y轴旋转矩阵
        // cosβ   0   sinβ    0
        //     0   1   0        0
        //-sinβ   0   cosβ    0
        //     0   0   0        1
        'mat4 my = mat4(cos,0,-sin,0,  0,1,0,0,  sin,0,cos,0,  0,0,0,1);'+
        //两个旋转矩阵、顶点齐次坐标连乘
        '   gl_Position = mx*my*apos;' +
        '}';
    //片元着色器源码
    var fragShaderSource = '' +
        'void main(){' +
        '   gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
        '}';
    //初始化着色器
    var program = initShader(gl,vertexShaderSource,fragShaderSource);
    //获取顶点着色器的位置变量apos
    var aposLocation = gl.getAttribLocation(program,'apos');

//        8个顶点坐标数组
    var data=new Float32Array([
        0.5,  0.5,  0.5,//顶点0
        -0.5,  0.5,  0.5,//顶点1
        -0.5, -0.5,  0.5,//顶点2
        0.5, -0.5,  0.5,//顶点3
        0.5,  0.5, -0.5,//顶点4
        -0.5,  0.5, -0.5,//顶点5
        -0.5, -0.5, -0.5,//顶点6
        0.5, -0.5, -0.5,//顶点7
    ]);
//        顶点索引数组
    var indexes = new Uint8Array([
//        前四个点
        0,1,2,3,
//        后四个顶点
        4,5,6,7,
//        前后对应点
        0,4,
        1,5,
        2,6,
        3,7
    ]);

    //创建缓冲区对象
    var indexesBuffer=gl.createBuffer();
    //绑定缓冲区对象
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexesBuffer);
    //索引数组indexes数据传入缓冲区
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indexes,gl.STATIC_DRAW);

    //创建缓冲区对象
    var buffer=gl.createBuffer();
    //绑定缓冲区对象
    gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
    //顶点数组data数据传入缓冲区
    gl.bufferData(gl.ARRAY_BUFFER,data,gl.STATIC_DRAW);
    //缓冲区中的数据按照一定的规律传递给位置变量apos
    gl.vertexAttribPointer(aposLocation,3,gl.FLOAT,false,0,0);
    //允许数据传递
    gl.enableVertexAttribArray(aposLocation);


    //LINE_LOOP模式绘制前四个点
    gl.drawElements(gl.LINE_LOOP,4,gl.UNSIGNED_BYTE,0);
    //LINE_LOOP模式从第五个点开始绘制四个点
    gl.drawElements(gl.LINE_LOOP,4,gl.UNSIGNED_BYTE,4);
    //LINES模式绘制后8个点
    gl.drawElements(gl.LINES, 8, gl.UNSIGNED_BYTE, 8);


    //声明初始化着色器函数
    function initShader(gl,vertexShaderSource,fragmentShaderSource){
        var vertexShader = gl.createShader(gl.VERTEX_SHADER);
        var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(vertexShader,vertexShaderSource);
        gl.shaderSource(fragmentShader,fragmentShaderSource);
        gl.compileShader(vertexShader);
        gl.compileShader(fragmentShader);
        var program = gl.createProgram();
        gl.attachShader(program,vertexShader);
        gl.attachShader(program,fragmentShader);
        gl.linkProgram(program);
        gl.useProgram(program);
        return program;
    }

glDrawElements 和glDrawArrays的GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP, GL_QUADS, and GL_POLYGON这个模式mode,不同的模式对indices顶点索引数组有不同的解释,包含步长和步进方式;

譬如

Tips:(一般规定逆时针卷绕为正方向)

GL_TRIANGLES:每三个顶点绘制一个三角形,如果顶点数量不是3的倍数,则忽略最后一个或两个顶点。

GL_TRIANGLE_STRIP:有两种情况,

(1)当前顶点序号n是偶数时,三角形三个顶点的顺序是(n - 2, n - 1, n )。

(2)当前顶点序号n是奇数时,三角形三个顶点的顺序是(n - 1, n - 2, n)。

这两种情况,保证了采用此种渲染方式的三角形顶点的卷绕顺序。

例如:对于v2顶点,其序号为2,此时三个顶点的顺序是(v0, v1, v2);对于v3顶点,其序号为3,此时三个顶点的顺序是(v2, v1, v3),均是逆时针卷绕。

GL_TRIANGLE_FAN:一系列顶点中的第一个点为中心点,其他顶点为边缘点,绘制一系列组成扇形的相邻三角形。例如三角形(v0, v1, v2)、(v0, v2, v3)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙行天下01

你的鼓励将是我的最大写作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值