2
votes

I'm having this error while adding my own geometry's attribute. I've already read this WebGL GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1 , and I understand what is the problem, but I can't figure out why.

I'm building a BufferGeometry, a tree, starting from 1000 object. 300 objects are using a LeafGeometry, 700 objects are using a BoxGeometry.

I want to fulfill a buffer, containing a value that tells if a vertex belongs to the trunk or to the foliage. What I'm doing is the follow:

1) First I calculate the dimension of the buffer (and here I think I'm doing it wrong) calling : getTotNumVertices(LeafGeometry.new(options), BoxGeometry.new(options), 1000, 3000)

function getTotNumVertices(foliage_geometry, trunk_geometry, tot_objects, foliage_start_at){
    let n_vertices_in_leaf = foliage_geometry.vertices.length * 3;
    let n_vertices_in_trunk = trunk_geometry.vertices.length * 3;
    let n_vertices_in_leafs = foliage_start_at * n_vertices_in_leaf;
    let n_vertices_in_stam = (tot_objects - foliage_start_at) * n_vertices_in_trunk;
    return{
        tot_vertices: (n_vertices_in_stam + n_vertices_in_leafs),
        n_vertices_leaf: n_vertices_in_leaf,
        n_vertices_trunk: n_vertices_in_trunk
    };
}

2)Once I've got the total number of vertex, I create the buffer

function createBuffers(n_vert){
    // I'm returnin an array becuase in my real code I'm returning
    // more than one buffer
    return {
        isLeafBuffer: new Float32Array(n_vert)
    };
}

3) Then I build my BufferGeometry, merging together the 1000 objects:

let hash_vertex_info = getTotNumVertices(leafGeom, geometries["box"], 1000, 300);
let buffers = createBuffers(hash_vertex_info.tot_vertices);
let geometry = new THREE.Geometry();
let objs = buildTheTree(1000, 300);
for (let i = 0; i < objs.length; i++){
    // here code that fullfills the buffers
    let mesh = objs[i];
    mesh.updateMatrix();
    geometry.merge(mesh.geometry, mesh.matrix);
}
let bufGeometry = new THREE.BufferGeometry().fromGeometry(geometry);
console.log(bufGeometry.attributes.position.count);
console.log(hash_vertex_info.tot_vertices);

And here the problem, the value of is bufGeometry.attributes.position.count is 623616, the value of hash_vertex_info.tot_vertices is 308940.

When drawing, WebGL try do access a value bigger than 308940 and then the error. What am I doing wrong?

///////////EDIT AFTER A WHILE

Basically, I'm having facing the same problem explained in this question Does converting a Geometry to a BufferGeometry in Three.js increase the number of vertices?

I need to calculate the total number of vertices in order to create a buffer that will contain values for my shader. This is my code, the number of vertices it is still different between the merged geometry and the buffer geometry obtained from it.

let tot_objects = 100;
let material = new THREE.MeshStandardMaterial( {color: 0x00ff00} );
let geometry = new THREE.BoxGeometry(5, 5, 5, 4, 4, 4);
let objs = populateGroup(geometry, material, tot_objects);

//let's merge all the objects in one geometry
let mergedGeometry = new THREE.Geometry();
for (let i = 0; i < objs.length; i++){
    let mesh = objs[i];
    mesh.updateMatrix();
    mergedGeometry.merge(mesh.geometry, mesh.matrix);
}

let bufGeometry = new THREE.BufferGeometry().fromGeometry(mergedGeometry);

let totVerticesMergedGeometry = (mergedGeometry.vertices.length ) + (mergedGeometry.faces.length * 3);
console.log(bufGeometry.attributes.position.count); // 57600
console.log(totVerticesMergedGeometry); // 67400 !!!
scene.add(new THREE.Mesh(bufGeometry, material));

function populateGroup(selected_geometry, selected_material, tot_objects) {
    let objects = [];
    for (var i = 0; i< tot_objects; i++) {
        let coord = {x:i, y:i, z:i};
        let object = new THREE.Mesh(selected_geometry, selected_material);
        object.position.set(coord.x, coord.y, coord.z);
        object.rotateY( (90 + 40 + i * 100/tot_objects) * -Math.PI/180.0 );
        objects.push(object);
    }
    return objects;
}

The number of totVerticesMergedGeometry and bufGeometry.attributes.position.count should be the same, but is is still different.

Is my way of counting vertices wrong? actually it is the same used here https://github.com/mrdoob/three.js/blob/master/src/core/DirectGeometry.js#L166, meaning (geometry.vertices.length) + (geometry.faces.length * 3).

2
I've thought the same thing too. I've reduced the number of objects, from 1000 to 100, but the problem still persists. Now bufGeometry.attributes.position.count returns 105216, but the Buffer that I've created has size 44340. That's why I think the problem is in the way in which I'm counting the vertices in the Geometry. But I think that geometry.vertices.length * 3 is the correct way to do itedap
I think I've found the right track, stackoverflow.com/questions/33290544/… i will post updates later. I'm calculating the size of the buffer in a wrong way. @gaitat, the linked answer comes from you ;) let's see if it fixes my problemedap
@gaitat nope, the problem persists. I've nailed down a the problem a bit more specifically in this question stackoverflow.com/questions/42130753/…edap

2 Answers

0
votes

What I was doing wrong was the way to calculate the number of vertices. The number of vertices used for the buffer is calculate with MyObjectGeometry.faces.lenght * 3 * NumberOfObjectThatWillBeMerged A more detailed answer is here Why the number of vertices in a merged Geometry differs from the number of vertices in the BufferedGeometry obtained from it?

0
votes

I had this error, because I was calling the constructor with the values instead of an array of values:

-    var colors = new Float32Array(
+    var colors = new Float32Array( [
       1.0, 0.0, 0.0,
       0.0, 1.0, 0.0,
       0.0, 0.0, 1.0,
       1.0, 0.0, 1.0,
       0.0, 1.0, 1.0,
       1.0, 1.0, 1.0,
-    );
+    ] );