1
votes

This code works fine:

  circlesGeometry = new THREE.CircleBufferGeometry(10, 32);
  var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
  var mesh = new THREE.Mesh(circlesGeometry, material);
  scene.add(mesh);

Then I trying add position:

  circlesGeometry = new THREE.CircleBufferGeometry(10, 32);
  circlesGeometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array([0, 0, 0]), 3));
  var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
  var mesh = new THREE.Mesh(circlesGeometry, material);
  scene.add(mesh);

I have an error:

[.Offscreen-For-WebGL-0x7f9abda5ea00]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 0

What is wrong?

1

1 Answers

1
votes

Documentation says:

.addAttribute ( name, attribute )

Adds an attribute to this geometry. Use this rather than the attributes property, because an internal hashmap of .attributes is maintained to speed up iterating over attributes.

and, digging into BufferGeometry.js, we can see that .addAttribute() does next (shortly):

addAttribute: function ( name, attribute ) {

    ... 
    this.attributes[ name ] = attribute; // here you set the property

    return this;

}

As your buffer geometry already has position property (object) of attributes property (object), when you do this:

circlesGeometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array([0, 0, 0]), 3));

you simply replace the existing position object with the new one whose array contains just 3 items. In simple words, an object can't contain several properties of the same name.

As you created THREE.CircleBufferGeometry(), it already has filled index property, containing indices of vertices for faces. In your case, its array property has 96 elements. Element 31's value is 12. But, when you replaced position attribute with the new array, which contains just 3 elements [0..2], there is no element with index of 12.