WebGL通过索引绘制

时间:2015-07-02 07:37:06

标签: javascript webgl

我是WebGL的新手,我正在尝试使用两个三角形和索引绘制一个正方形。但是我没有得到正确的答案。我一直在查看代码和示例,但遗漏了一些东西。我想让事情变得非常简单。

<html>
<head>        
    <meta charset="utf-8"/>   
        <script id="vertex" type="x-shader">
            attribute vec2 aVertexPosition;
            void main() {
                    gl_Position = vec4(aVertexPosition, 0.0, 1.0);
            }
    </script>  
    <script id="fragment" type="x-shader">
             #ifdef GL_ES
                 precision highp float;
             #endif

             uniform vec4 uColor;

             void main() {
                gl_FragColor = uColor;
             }
    </script>        
    <script type="text/javascript">
            function init(){
                var canvas = document.getElementById("mycanvas");
                var gl = canvas.getContext("experimental-webgl");   
                gl.viewport(0, 0, canvas.width, canvas.height);
                gl.clearColor(0.5, 0.0, 0.2, 1);
                gl.clear(gl.COLOR_BUFFER_BIT);

                var v = document.getElementById("vertex").firstChild.nodeValue;
                var f = document.getElementById("fragment").firstChild.nodeValue;

                var vs = gl.createShader(gl.VERTEX_SHADER);
                gl.shaderSource(vs, v);
                gl.compileShader(vs);

                var fs = gl.createShader(gl.FRAGMENT_SHADER);
                gl.shaderSource(fs, f);
                gl.compileShader(fs);

                var program = gl.createProgram();
                gl.attachShader(program, vs);
                gl.attachShader(program, fs);
                gl.linkProgram(program);

                var vertices = [ -0.5, -0.5, -0.5, 0.5,  0.5, 0.5, 0.5, -0.5];
                var indices = [ 3, 2, 1, 3, 1, 0 ]

                var vbuffer = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);                                       
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

                var ebuffer = gl.createBuffer();
                gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebuffer);                                       
                gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);



                var itemSize = 2;
                var numItems = vertices.length / itemSize;


                gl.useProgram(program);

                program.uColor = gl.getUniformLocation(program, "uColor");
                gl.uniform4fv(program.uColor, [0.0, 0.3, 0.0, 1.0]);

                program.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
                gl.enableVertexAttribArray(program.aVertexPosition);
                gl.vertexAttribPointer(program.aVertexPosition, itemsize, gl.UNSIGNED_SHORT, false, 0, 0);

                gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
        }



</script>

</head>
<body onload="init()">
        <canvas id="mycanvas" width="800" height="500"></canvas>
</body>

出现背景,但方块没有。

下载的代码运行,所以我知道错误仅在我的代码中。

2 个答案:

答案 0 :(得分:1)

你的gl.vertexAttribPointer不正确。你创建了一个Float32Array但你告诉webGL使用unsigned short并且你拼错了itemSize。

更改为gl.vertexAttribPointer(program.aVertexPosition, itemSize, gl.FLOAT, false, 0, 0);,这对我有用。

答案 1 :(得分:0)

您的顶点数组缺少最后一个元素的坐标。总是,顶点数组每个顶点应该有3个坐标,并且是3的倍数。

您的indices数组,指向哪些顶点应连接为三角形以使您显示几何体。尝试一下这个。这应该工作。

function init(){
                var canvas = document.getElementById("mycanvas");
                var gl = canvas.getContext("experimental-webgl");   
                gl.viewport(0, 0, canvas.width, canvas.height);
                gl.clearColor(0.5, 0.0, 0.2, 1);
                gl.clear(gl.COLOR_BUFFER_BIT);

                var v = document.getElementById("vertex").firstChild.nodeValue;
                var f = document.getElementById("fragment").firstChild.nodeValue;

                var vs = gl.createShader(gl.VERTEX_SHADER);
                gl.shaderSource(vs, v);
                gl.compileShader(vs);

                var fs = gl.createShader(gl.FRAGMENT_SHADER);
                gl.shaderSource(fs, f);
                gl.compileShader(fs);

                var program = gl.createProgram();
                gl.attachShader(program, vs);
                gl.attachShader(program, fs);
                gl.linkProgram(program);

                var vertices = [ -0.5, 0, 0, 0,  0.5, 0, 0.5, 0, 0];
                var indices = [ 0, 1, 2 ]

                var vbuffer = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);                                       
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

                var ebuffer = gl.createBuffer();
                gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebuffer);                                       
                gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);



                var itemSize = 2;
                var numItems = vertices.length / itemSize;


                gl.useProgram(program);

                program.uColor = gl.getUniformLocation(program, "uColor");
                gl.uniform4fv(program.uColor, [0.0, 0.3, 0.0, 1.0]);

                program.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
                gl.enableVertexAttribArray(program.aVertexPosition);
                gl.vertexAttribPointer(program.aVertexPosition, itemsize, gl.UNSIGNED_SHORT, false, 0, 0);

                gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0);
        }