[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] Issue with enable vertex attributes and re-binding VBOs



On 08/13/2010 01:20 PM, Vladimir Vukicevic wrote:
Hmm, do you have a testcase or a code snippet that shows what you're trying to do?  You shouldn't need to re-enable vertex attributes, unless there's a bug somewhere..

- Vlad
Here's the generated Javascript for the most relevant part. I've tried clarify with comments (*not* machine-generated :) )
Originally, the bit which is between XXXXs was where ===>> is in the code below. It gave the behavior as originally described. Where it is now gives the expected results.


This snippet is a method which is called when the scenegraph is traversed.

Regards

Alan


function $doHandleGeometry(this$static, node, pass){
var arrayBuffer, at, at$iterator, attributeIndex, colorFound, colorIndex, defColor, elementBuffer, enabledAttributes, enabledCount, gl, i, mvf, pmf, strideOffset, ulmodelView, ulperspective, vbo, vertexBuffer;
vbo = dynamicCast(node.instance, 91);
gl = this$static.displayContext.canvas_0.context;
switch (pass.ordinal) {
case 0:
return;
case 1:
// Stuff to set up the transform.
{
ulperspective = dynamicCastJso(this$static.displayContext.vertexUniformMap.get('u_perspectiveMatrix'));
ulmodelView = dynamicCastJso(this$static.displayContext.vertexUniformMap.get('u_modelViewMatrix'));
pmf = convertToFloatArray(this$static.transformManager.perspectiveMatrix);
gl.uniformMatrix4fv(ulperspective, false, create_2(pmf));
mvf = convertToFloatArray(this$static.transformManager.modelViewMatrix);
gl.uniformMatrix4fv(ulmodelView, false, create_2(mvf));
checkError(gl, 'after setting matrices in doHandleGeometry');


// First time around vertexBuffer and elementBuffer are null, so they are created
// and references stored so that subsequent times they can be re-used.


        vertexBuffer = null;
        if (!vbo.arrayBuffer) {
          vertexBuffer = gl.createBuffer();
          gl.bindBuffer(34962, vertexBuffer);
          gl.bufferData(34962, create_2(vbo.arrayData), 35044);
          vbo.arrayBuffer = vertexBuffer;
        }

// the VBO is taken from the 'arrayBuffer' property of the 'vbo' object.
         else {
          vertexBuffer = vbo.arrayBuffer;
          gl.bindBuffer(34962, vertexBuffer);
        }

// Same again but with the element buffer.

        elementBuffer = null;
        if (!vbo.elementBuffer) {
          elementBuffer = gl.createBuffer();
          gl.bindBuffer(34963, elementBuffer);
          gl.bufferData(34963, create_3(vbo.elementData), 35044);
          vbo.elementBuffer = elementBuffer;

        //  ===>>   XXXXXX.... stuff was here.
        }
         else {
          elementBuffer = vbo.elementBuffer;
          gl.bindBuffer(34963, elementBuffer);
        }
        checkError(gl, 'after binding to buffers');

// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXxx
// The next bit enables those attributes which are *used* by this buffer and *required* by the shader.
// allows one generic shader to be used with objects with a 'mixed' attribute set.


strideOffset = 0;
colorFound = false;
enabledAttributes = initDim(_3I_classLit, 241, -1, vbo.attributes.size_1(), 1);
enabledCount = 0;
for (at$iterator = vbo.attributes.iterator(); at$iterator.hasNext();) {
at = dynamicCast(at$iterator.next_0(), 46);
attributeIndex = gl.getAttribLocation(this$static.displayContext.shaderProgram, at.name_0);
if (attributeIndex >= 0) {
colorFound = $equals_3('a_color', at.name_0);
gl.enableVertexAttribArray(attributeIndex);
if (($clinit_354() , FLOAT_0) == at.type_0) {
gl.vertexAttribPointer(attributeIndex, at.stride, 5126, false, vbo.vertexStride * 4, strideOffset);
enabledAttributes[enabledCount] = attributeIndex;
++enabledCount;
}
else
throw $UnsupportedOperationException(new UnsupportedOperationException, 'Can only handle FLOAT attributes');
}
strideOffset += at.stride * 4;
}


// this bit sets a default color if there is no COLLADA COLOR semantic in the vertex data.

if (!colorFound) {
defColor = initValues(_3F_classLit, 240, -1, [0.20000000298023224, 0.800000011920929, 0.800000011920929, 1]);
colorIndex = gl.getAttribLocation(this$static.displayContext.shaderProgram, 'a_color');
if (colorIndex != -1) {
gl.disableVertexAttribArray(colorIndex);
gl.vertexAttrib4fv(colorIndex, create_2(defColor));
}
}
checkError(gl, 'after bindingAttributes');
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX



// The actual drawing happens here. gl.drawElements(4, vbo.elementData.length, 5123, 0);

// Then disable the vertex attributes we enabled above
        for (i = 0; i < enabledCount; ++i) {
          gl.disableVertexAttribArray(enabledAttributes[i]);
        }
        checkError(gl, 'after drawArrays');

// and unbind the buffers.
        gl.bindBuffer(34962, null);
        gl.bindBuffer(34963, null);
      }

      break;

// this is for a 'clean' pass which deletes buffers when the scenegraph is being changed.
case 3:
{
arrayBuffer = vbo.arrayBuffer;
if (arrayBuffer) {
gl.deleteBuffer(arrayBuffer);
vbo.arrayBuffer = null;
}
elementBuffer = vbo.elementBuffer;
if (elementBuffer) {
gl.deleteBuffer(elementBuffer);
vbo.elementBuffer = null;
}
}


  }
}

----- Original Message -----
Hi List

This may be a very dumb question, but is it actually specifically
stated
anywhere that you must enable vertex attributes each time you bind to
a
buffer target?

I've found (empirically) that unless you re-enable all the vertex
attributes each time you *re-use* a buffer, the following
drawElements/drawArrays displays the data from the last VBO originally
created. In other words, if you create VBO A, B and C and then redraw
A,
B or C, each time you redraw them you must go through the
enableVertexAttribute stuff, even if the bindings are unchanged. If
you
don't when you re-draw A or B you get the data from C.

What happened was the the first time I drew a scene everything was
fine,
but as soon as it was redrawn (e.g. camera move) all the rendered
objects changed to the geometry of the last object originally created.
I've fixed it by now specifically enabling vertex attributes as
required
(and then disabling them again). My inspiration in this was the San
Angeles demo which appears to work this way.

I have no idea whether this is GL ES 2.0 behavior - I have found
nothing
in either the spec or the man pages to indicate that the above would
happen. There's an example in the GL3.0/3.1 Programmer's guide which
only enables the vertex attributes once, but of course, that's not GL
ES
2/WebGL.


Regards

Alan




-----------------------------------------------------------
You are currently subscribed to public_webgl@khronos.org.
To unsubscribe, send an email to majordomo@khronos.org with
the following command in the body of your email:

----------------------------------------------------------- You are currently subscribed to public_webgl@khronos.org. To unsubscribe, send an email to majordomo@khronos.org with the following command in the body of your email: