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

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



Ugh, your generated code is extremely hard to read, but I think I understand; I think what you had before was just incorrect.  The current attribute bindings are part of global state, not tied to a shader.  The current buffer binding is only used to set up attribute bindings; that is, the current binding itself is not tied to the attribute arrays.  Your code before was setting up and enabling attributes only the first time, when you were creating the VBOs, and as such they would have always pointed to the first VBO that was created.

If I didn't understand that correctly, you'll have to write out some hand-written code or some pseudocode :)

   - Vlad


----- Original Message -----
> 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: