0
\$\begingroup\$

I've setup 3 different instances of the same shader code (e.g. I've compiled the code into 3 separate programs)

For each program, I've gone through the whole route of something like this:

//Setup
gl.useProgram(program);
const buffer = gl.createBuffer();
const location = gl.getAttribLocation(program, aName);

//Upload (each uses the buffer/location it created in Setup
gl.useProgram(program);
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, data, usagePattern);
gl.vertexAttribPointer(location, nComponents, dataType, false, 0, 0);
gl.enableVertexAttribArray(location);

//Draw
gl.useProgram(program);
gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

However, no matter what I pass into data - e.g. different sized quads, all three are the same size.

Notably, changes to other uniforms/attributes like matrices and color do change per object

How do I change this so that the changes to data per instance will be drawn properly?

(I realize if they actually use the same shader I should maybe keep a reference to one program and use some sort of buffer pool- but I'm not there yet, just getting started with WebGL)

\$\endgroup\$
  • \$\begingroup\$ Which buffer is bound when you draw? Because the buffer is not part of the program state, it must be bound again for drawing. \$\endgroup\$ – Maximus Minimus Nov 3 '17 at 6:14
  • \$\begingroup\$ Thanks - I clarified the answer above to add in the drawing part which I forgot :) Will try re-binding before drawing... \$\endgroup\$ – davidkomer Nov 3 '17 at 6:51
  • \$\begingroup\$ Yup, that did the trick! Want to write it as a separate answer and I'll accept? \$\endgroup\$ – davidkomer Nov 3 '17 at 6:57
  • \$\begingroup\$ Also- generally speaking, if I have lots of objects that use the same shader... is there a good resource out there you can recommend that talks about how do efficiently pool things? e.g. do I keep all the buffer locations in some manual counter? Stuff like that... \$\endgroup\$ – davidkomer Nov 3 '17 at 6:58
  • \$\begingroup\$ There, added as an answer. \$\endgroup\$ – Maximus Minimus Nov 3 '17 at 9:15
1
\$\begingroup\$

Your problem is that the current buffer binding is not part of the program state.

In more general terms, buffers (or more correctly, vertex attrib state) and programs are separate objects, and in earlier versions of OpenGL you can even draw without either or without both. So it makes sense that the state of one will not affect the state of the other.

So if in your case you bind 3 buffers at startup, then draw without rebinding your buffers, only the most recently bound buffer will be used for drawing.

To solve, you simply need to rebind the appropriate buffer before drawing.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.