2
votes

I'm attempting to apply a texture to an object in webGL, but I get the following error:

WebGL warning: drawElements: Vertex attrib array 0 is enabled but has no buffer bound.

which I am unable to find any information on online. Otherwise the scene shows, but the object that needs the texture is appearing as a flat square.

The error points to my drawElements

  gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
  gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, cubeVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);

  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.uniform1i(shaderProgram.samplerUniform, 0);

  gl.bindBuffer(gl.ARRAY_BUFFER, cubeNormalBuffer);
  gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, cubeNormalBuffer.itemSize, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);

  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
  setMatrixUniforms();
  gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);

and my buffer for the texture

  cubeVertexTextureCoordBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
  const textureCoords = [
      // Front
      0.0,  0.0,
      1.0,  0.0,
      1.0,  1.0,
      0.0,  1.0,
      // Back
      0.0,  0.0,
      1.0,  0.0,
      1.0,  1.0,
      0.0,  1.0,
      // Top
      0.0,  0.0,
      1.0,  0.0,
      1.0,  1.0,
      0.0,  1.0,
      // Bottom
      0.0,  0.0,
      1.0,  0.0,
      1.0,  1.0,
      0.0,  1.0,
      // Right
      0.0,  0.0,
      1.0,  0.0,
      1.0,  1.0,
      0.0,  1.0,
      // Left
      0.0,  0.0,
      1.0,  0.0,
      1.0,  1.0,
      0.0,  1.0,
  ];
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);
  cubeVertexTextureCoordBuffer.itemSize = 2;
  cubeVertexTextureCoordBuffer.numItems = 24;

and the texture code

let texture;
function initTexture(){
    texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0,0,255,255]));
    const image = new Image();
    image.onload = function () {
        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
        if(isPowerOf2(image.width) && isPowerOf2(image.height)){
            gl.generateMipmap(gl.TEXTURE_2D);
        }
        else{
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        }
        drawScene();
    };
    // image.src = "crate.gif";
    image.src = "WoodFine23_COL_3K.jpg";
}
function isPowerOf2(value) {
    return(value & (value - 1)) == 0;
}

Otherwise my entire code can be found here https://pastebin.com/HaQBFEuL

Also, I have followed the following tutorials http://learningwebgl.com/blog/?p=1359, https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL, and https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Lighting_in_WebGL

Any help would be greatly appreciated.

1

1 Answers

1
votes

In the function initShaders the generic vertex attribute arrays for the indices shaderProgram.vertexPositionAttribut, shaderProgram.vertexColorAttribute, shaderProgram.vertexNormalAttribute, shaderProgram.textureCoordAttribute are enabled and they are never disabled in your code.

But in the function drawScene there are only defined the arrays of generic vertex attribute data for the indices shaderProgram.vertexPositionAttribut, shaderProgram.vertexNormalAttribute and shaderProgram.textureCoordAttribute.
shaderProgram.vertexColorAttribute is missing because it is under comment.

The error messag

WebGL warning: drawElements: Vertex attrib array 0 is enabled but has no buffer bound.

means, that there is a vertex attribute index, which is "enabled", but where are no data defined for.

In your case this is shaderProgram.textureCoordAttribute, which is defined but not enabled.

Skip enabling the vertex attribute with index shaderProgram.vertexColoAttribute and your code should proper run.
Of course the vertex attributes can be enable in the function initShaders and defined in the function drawScene. But the vertex attrbute shaderProgram.vertexNormalAttribute is enabled in the function drawScene too. You should not call gl.enableVertexAttribArray twice for the same attribute index, without of any need.