webgl入门实例-09索引缓冲区示例

发布于:2025-04-18 ⋅ 阅读:(31) ⋅ 点赞:(0)

实现效果

在这里插入图片描述

实现代码

<!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, maximum-scale=1, minimum-scale=1, user-scalable=no" />
    <meta name="description" content="Render voxel primitives with different shape types." />
    <meta name="cesium-sandcastle-labels" content="Showcases, WEBGL" />
    <title>WEBGL Demo</title>
</head>

<body>
    <canvas id="myCanvas" style="border: 1px solid red;" width='600' height='600'></canvas>

    <script type="text/plain" id="VSHADER_SOURCE">
        attribute vec3 v3Position;
        void main(void)
        {
            gl_Position = vec4(v3Position, 1.0);
        }
    </script>

    <script type="text/plain" id="FSHADER_SOURCE">
        void main(void)
        {
            gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);
        }
    </script>
    
    <script id="cesium_sandcastle_script">
        "use strict";
        function Init() {
            //Sandcastle_Begin

            /**
             * 索引缓冲区(也称为元素数组缓冲区)是WebGL中一种优化渲染性能的重要机制,它允许您重用顶点数据来绘制复杂的几何图形。
             * 减少内存使用:可以重用顶点数据而不需要重复存储
             * 提高性能:减少需要传输到GPU的数据量
             * 支持复杂几何:更容易构建由多个三角形组成的复杂形状
             */

            var webgl = null;
            var VSHADER_SOURCE = document.getElementById("VSHADER_SOURCE").textContent;
            var FSHADER_SOURCE = document.getElementById("FSHADER_SOURCE").textContent;

            var canvas = document.getElementById('myCanvas');
            webgl = canvas.getContext("webgl");

            webgl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight);

            var vertexShaderObject = webgl.createShader(webgl.VERTEX_SHADER);
            var fragmentShaderObject = webgl.createShader(webgl.FRAGMENT_SHADER);

            webgl.shaderSource(vertexShaderObject,VSHADER_SOURCE);
            webgl.shaderSource(fragmentShaderObject,FSHADER_SOURCE);

            webgl.compileShader(vertexShaderObject);
            webgl.compileShader(fragmentShaderObject);

            if (!webgl.getShaderParameter(vertexShaderObject, webgl.COMPILE_STATUS)) 
            { 
                alert("error:vertexShaderObject");
                return; 
            }
            if (!webgl.getShaderParameter(fragmentShaderObject, webgl.COMPILE_STATUS))
            { 
                alert("error:fragmentShaderObject");
                return;
            }

            var programObject = webgl.createProgram();

            webgl.attachShader(programObject, vertexShaderObject);
            webgl.attachShader(programObject, fragmentShaderObject);

            var v3PositionIndex = 0;
            webgl.bindAttribLocation(programObject, v3PositionIndex, "v3Position");

            webgl.linkProgram(programObject);
            if (!webgl.getProgramParameter(programObject, webgl.LINK_STATUS)) 
            { 
                alert("error:programObject"); 
                return; 
            }

            webgl.useProgram(programObject);
 
            // n代表法线
            var jsArrayData = 
                [
                    // 每6个为一个顶点的信息
                    //x     y       z       nx      ny      nz
                    -0.5,   +0.5,   0.0,    0.0,    0.0,    0.0, // 0
                    +0.5,   +0.5,   0.0,    0.0,    0.0,    0.0, // 1
                    +0.5,   -0.5,   0.0,    0.0,    0.0,    0.0, // 2
                    -0.5,   -0.5,   0.0,    0.0,    0.0,    0.0, // 3
                ];//右顶点

            var indexDatas = [
                    0,1,2, // 第一个三角形对应 jsArrayData 中的 0 1 2
                    0,2,3, // 第二个三角形
                ];
        

            //指定绘制所使用的顶点数据 从 该缓冲区中获取
            var triangleBuffer  =   webgl.createBuffer();
            webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);
            // 将顶点数据存入缓冲区
            webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(jsArrayData), webgl.STATIC_DRAW);
           
            var indexBuffer     =   webgl.createBuffer();
            webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, indexBuffer);
            webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexDatas), webgl.STATIC_DRAW);

            // 设置重绘背景的颜色
            webgl.clearColor(0.0, 0.0, 0.0, 1.0);
            //! 执行绘制,即将背景清空成制定的颜色(clearColor)
            webgl.clear(webgl.COLOR_BUFFER_BIT);
            
            webgl.enableVertexAttribArray(v3PositionIndex);

            webgl.vertexAttribPointer(
                v3PositionIndex, 
                3, // 每个点对应 类型为 vec4(), 如这里写的3, 假设顶点缓冲区中的xyz都为1.0, 3-->vec4(1.0, 1.0, 1.0, 1.0)   2--> vec4(1.0, 1.0, 0.0, 1.0)  1-->vec4(1.0, 0.0, 0.0, 1.0)
                webgl.FLOAT, 
                false, // 是否正交化
                4 * 6, // jsArrayData中的没6个存储一个点的信息
                0 // 顶点的起始位置
            );

            // 索引缓冲区使用 drawElements 
            webgl.drawElements(
                webgl.TRIANGLES,
                6, // 画6给索引, 即indexDatas的长度
                webgl.UNSIGNED_SHORT, // 索引缓冲区中的数据类型
                0 // 顶点位置偏移量
            );
            //Sandcastle_End
        }

        window.onload = function() {
            Sandcastle.finishedLoading();
            Init()
        }
    
    </script>
</body>

</html>

网站公告

今日签到

点亮在社区的每一天
去签到