Conflict when using two or more shaders with different number of attributes

I am trying to implement assembly (using colors and readPixels) in my WebGL program. When I run my program, I create a shaderProgram to split. One for phong shading and another that just gives the shapes a color to use to determine which shape has been clicked.

The phong font has 2 attributes. Vertex position and vertex are normal. The retractable position simply has its own position.

Now I found that for some odd reason, when both of these shaders exist in the same program, and I use a selection, my drawArray call seems to fail. The last thing that happens is my call to gl.vertexAttribPointer. I fiddled around and found out that when I check for active attribute arrays using: gl.getVertexAttrib (index, gl.VERTEX_ATTRIB_ARRAY_ENABLED);

both values ​​0.1 return true (this is when the activating shader is active with gl.useProgram (collection))

Now if I disable 1 with gl.disableVertexAttribArray (1); Everything works again. Another fix is ​​to draw with a phong shader first and then use a picking shader and somehow that magically does it. My guess is that in this case, when attaching my vertex normal buffer while using phong shader, it somehow remains when I then switch to the collector and drawArray works.

I would like to know if I am using gl.enableAttribArray incorrectly and should disable them when switching shaders or something.

I have also tried creating shader programs in a different order with no success.


source to share

3 answers

As you've probably found out, useProgram doesn't affect anything other than the program (shader code) that should run in the next callback. You should make sure that only the attributes used by the current program are included.

If you've wrapped your WebGL code somehow, the advisor should store the highest available attribute number for each program stored somewhere in your shell, and then compare to the last program used and enable / disable accordingly prior to calling the draw.



OpenGL is a state machine. With the selected shader selected, you will place OpenGL in a state that no longer has additional phong shader attributes.

Many people fall into the wrong and bad habit of assuming that there is "one time initialization" in OpenGL. This is not the case. You should set all the necessary state for any paint operation, just before that paint operation, and ideally also return the settings when done. This means: after binding a shader, you must also include and bind the required shader inputs as vertex attributes.



It's hard to tell without seeing your code, but ... WebGL requires all accessible attributes to have enough data to satisfy a paint call. So if you set up 2 attributes each with 3 data vertices and draw 3 vertices, then switch shaders and set 1 attribute with 6 vertices and leave the second attribute with only 3 vertices, then try to draw with 6 vertices, if the shader is currently draws with access to both WebGL attributes will fail to make a draw call.

If you run Chrome 19, it should tell you in the JavaScript console if this was the problem.



All Articles