javascriptwebglobjloader

WebGL INVALID OPERATION insufficient buffer size


I'm trying to write a simple program in WebGL and javascript to draw a simple object from .obj files. I'm using npm's webgl-obj-loader to load the objects. As the title says I keep getting Insufficient buffer size (Edge) and index buffer too small(FF). I used gl.geterror function and I'm getting 1282 error code which means INVALID_OPERATION.

window.onload = function () {
            OBJ.downloadMeshes(
            {
                'dragon_vrip': 'models/dragon_vrip.obj',
                'cube2': 'models/cube2.obj'
            }, webGLStart);
}

This is the way I use to load obj files.

        app.meshes = meshes;

        OBJ.initMeshBuffers(gl, app.meshes.dragon_vrip);
        OBJ.initMeshBuffers(gl, app.meshes.cube2);

        vertArray = app.meshes.cube2.vertices.slice();
        normArray = app.meshes.cube2.vertexNormals.slice();
        indicesArray = app.meshes.cube2.indices.slice();
        texCoord = app.meshes.cube2.textures.slice();
            var myMesh=app.meshes.cube2;

            var pointsBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, pointsBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, vertArray, gl.STATIC_DRAW);
            gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(0);

            var textureBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, texCoord, gl.STATIC_DRAW);
            gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(1);

            var normalBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, normArray, gl.STATIC_DRAW);
            gl.vertexAttribPointer(2, 3, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(2);

            var indices = gl.createBuffer();
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indices);
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicesArray, gl.STATIC_DRAW);
            console.log(indices.size);

Step two: Init of the buffers.

                function drawFunc() {
                    rotateAngleX += 0.01;
                    rotateAngleY += 0.02;

                    mat4.fromXRotation(rotateXMatrix, rotateAngleX);
                    mat4.fromYRotation(rotateYMatrix, rotateAngleY);
                    mat4.multiply(modelMatrix, rotateXMatrix, rotateYMatrix);

                    gl.uniformMatrix4fv(modelMatrixLocation, false, modelMatrix);

                    gl.clear(gl.COLOR_BUFFER_BIT);
                    gl.drawElements(gl.TRIANGLES, indicesArray.length, gl.UNSIGNED_SHORT, 0);

                    requestAnimationFrame(drawFunc);

                }
                requestAnimationFrame(drawFunc);

And here I'm trying to draw a simple cube.

Arrays size is: vertices:72 indices:36 texCoords:48 normals:72

Considering vertices are triplets of x,y,z points the vertex buffer contains 24 points(vertex[0]=x, vertex[1]=y, vertex[2]=z, ...), and indices array doesn't contain higher number than 23, so I don't understand where the error occurs. Also is there any way to debug the buffers? I tried spector.js but didn't help much since the draw calls do nothing because of the errors.


Solution

  • See a complete example below:

    "use strict";
    
    var m = ThreeDMath;
    
    function main() {
      var cubeVertices = [-1, -1, -1,
        1, -1, -1,
        1, 1, -1, -1, 1, -1, -1, -1, 1,
        1, -1, 1,
        1, 1, 1, -1, 1, 1,
      ];
      var indices = [
        0, 1,
        1, 2,
        2, 3,
        3, 0,
        4, 5,
        5, 6,
        6, 7,
        7, 4,
        0, 4,
        1, 5,
        2, 6,
        3, 7,
      ];
    
      var canvas = document.getElementById("c");
      var gl = canvas.getContext("webgl");
      if (!gl) {
        alert("no webgl");
        return;
      }
    
      var program = webglUtils.createProgramFromScripts(
        gl, ["2d-vertex-shader", "2d-fragment-shader"]);
      gl.useProgram(program);
    
      var positionLoc = gl.getAttribLocation(program, "a_position");
      var worldViewProjectionLoc =
        gl.getUniformLocation(program, "u_worldViewProjection");
    
      var buffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
      gl.bufferData(
        gl.ARRAY_BUFFER,
        new Float32Array(cubeVertices),
        gl.STATIC_DRAW);
      gl.enableVertexAttribArray(positionLoc);
      gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, 0, 0);
    
      var buffer = gl.createBuffer();
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
      gl.bufferData(
        gl.ELEMENT_ARRAY_BUFFER,
        new Uint16Array(indices),
        gl.STATIC_DRAW);
    
      function render(clock) {
        clock *= 0.001;
    
        var scale = 4;
    
        webglUtils.resizeCanvasToDisplaySize(gl.canvas, window.devicePixelRatio);
    
        gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
    
        gl.clear(gl.COLOR_BUFFER_BIT);
    
        var fieldOfView = Math.PI * 0.25;
        var aspect = canvas.clientWidth / canvas.clientHeight;
        var projection = m.perspective(fieldOfView, aspect, 0.0001, 500);
        var radius = 5;
        var eye = [
          Math.sin(clock) * radius,
          1,
          Math.cos(clock) * radius,
        ];
        var target = [0, 0, 0];
        var up = [0, 1, 0];
        var view = m.lookAt(eye, target, up);
    
        var worldViewProjection = m.multiplyMatrix(view, projection);
        gl.uniformMatrix4fv(worldViewProjectionLoc, false, worldViewProjection);
    
        gl.drawElements(gl.LINES, indices.length, gl.UNSIGNED_SHORT, 0);
        requestAnimationFrame(render);
      }
      requestAnimationFrame(render);
    }
    
    main();
    <script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
    <script src="https://webglfundamentals.org/webgl/resources/webgl-lessons-helper.js"></script>
    <script src="https://webglfundamentals.org/webgl/lessons/resources/3d-math.js"></script>
    <!-- vertex shader -->
    <script id="2d-vertex-shader" type="x-shader/x-vertex">
      attribute vec4 a_position; uniform mat4 u_worldViewProjection; void main() { gl_Position = u_worldViewProjection * a_position; }
    </script>
    <!-- fragment shader -->
    <script id="2d-fragment-shader" type="x-shader/x-fragment">
      void main() { gl_FragColor = vec4(0,0,0,1); }
    </script>
    <canvas id="c"></canvas>

    Working code on JSFiddle