调用glDisableVertexAttribArray()是否很重要?

我并不完全清楚启用顶点属性数组的范围。 我有几个不同的着色器程序,具有不同数量的顶点属性。 glEnableVertexAttribArray局部调用着色器程序还是全局?

现在我在创build着色器程序时启用了顶点attrib数组,并且从不禁用它们,而且似乎都可以工作,但好像我可能应该在绘制调用之前/之后启用/禁用它们。 这有没有影响?

(我正在使用WebGL,所以我们真的在谈论gl.enableVertexAttribArraygl.disableVertexAttribArray 。我还会注意到,这本橙色的书, OpenGL Shading Language对这些调用没有任何意义。)

顶点属性数组启用的状态可以绑定到顶点数组对象(VAO),也可以是全局的。

如果您使用的是VAO,那么您不应该禁用属性数组,因为它们被封装在VAO中。

但是,对于全局顶点属性数组启用状态,您应该禁用它们,因为如果它们保持启用状态,OpenGL将尝试从数组中读取,这些数组可能会绑定到无效指针,如果指针指向客户端地址空间,或者如果它指出一个绑定的顶点缓冲区对象的限制,则会引发OpenGL错误。

WebGL与OpenGL不一样。

在WebGL中,只要存在一个附加到属性的缓冲区,并且(a)使用的足够大以满足绘制调用或(b)不使用WebGL,则允许启用WebGL。

与OpenGL ES 2.0不同,WebGL不允许客户端arrays。

certificate:

 var gl = document.querySelector("canvas").getContext("webgl"); var m4 = twgl.m4; var programInfo2Attribs = twgl.createProgramInfo(gl, ["vs-uses-2-attributes", "fs"]); var programInfo1Attrib = twgl.createProgramInfo(gl, ["vs-uses-1-attribute", "fs"]); var arrays2Attribs = { position: [ -1, -1, 0, 1, -1, 0, -1, 1, 0, ], color: [ 1,0,0,1, 1,1,0,1, 0,1,0,1, ], }; var arrays1Attrib = { position: [ -1, -1, 0, 1, -1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 0, 1, 1, 0, ], }; var bufferInfo2Attribs = twgl.createBufferInfoFromArrays(gl, arrays2Attribs); var bufferInfo1Attrib = twgl.createBufferInfoFromArrays(gl, arrays1Attrib); var uniforms = { u_matrix: m4.scale(m4.translation([-0.5, 0, 0]), [0.25, 0.5, 0.5]), }; gl.useProgram(programInfo2Attribs.program); twgl.setBuffersAndAttributes(gl, programInfo2Attribs, bufferInfo2Attribs); twgl.setUniforms(programInfo2Attribs, uniforms); twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo2Attribs); uniforms.u_matrix = m4.scale(m4.translation([0.5, 0, 0]), [0.25, 0.5, 0.5]); gl.useProgram(programInfo1Attrib.program); twgl.setBuffersAndAttributes(gl, programInfo1Attrib, bufferInfo1Attrib); twgl.setUniforms(programInfo1Attrib, uniforms); twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo1Attrib); 
 canvas { border: 1px solid black; } 
 <script src="dist/twgl-full.min.js"></script> <script id="vs-uses-2-attributes" type="not-js"> attribute vec4 position; attribute vec4 color; varying vec4 v_color; uniform mat4 u_matrix; void main() { gl_Position = u_matrix * position; v_color = color; } </script> <script id="vs-uses-1-attribute" type="not-js"> attribute vec4 position; varying vec4 v_color; uniform mat4 u_matrix; void main() { gl_Position = u_matrix * position; v_color = vec4(0,1,0,1); } </script> <script id="fs" type="not-js"> precision mediump float; varying vec4 v_color; void main() { gl_FragColor = v_color; } </script> <p> 1st it draws a triangle (3 vertices, 2 attributes)<br/> 2nd it draws a quad (6 vertices, 1 attribute)<br/> It does NOT called gl.disableVertexAttrib so on the second draw call one of the attributes is still enabled. It is pointing to a buffer with only 3 vertices in it even though 6 vertices will be drawn. There are no errors. </p> <canvas></canvas> 

对于webGL我打算去是的 ,重要的是调用gl.disableVertexAttribArray。

Chrome给了我这个警告:

 WebGL: INVALID_OPERATION: drawElements: attribs not setup correctly 

当程序改变为使用less于最大数量的属性时发生这种情况。 显然,解决scheme是在绘制之前禁用未使用的属性。

如果所有的程序都使用相同数量的属性,那么在初始化时可能会调用gl.enableVertexAttribArray。 否则,当你改变程序时你需要pipe理它们。