WebGL中enableVertexAttribArray等渲染函数作用及冗余代码疑问
你在WebGL示例中注释掉以下代码后渲染结果不变,疑惑这些代码的作用:
gl.enableVertexAttribArray(a_Vertex_location); // this gl.bindBuffer(gl.ARRAY_BUFFER, triangles_color_buffer_id); // this gl.vertexAttribPointer(a_Color_location, 3, gl.FLOAT, false, 0, 0); // this gl.enableVertexAttribArray(a_Color_location); // and this
核心原因:WebGL是状态机
WebGL的本质是状态机——一旦你设置了某个状态(比如绑定缓冲、启用顶点属性数组),这个状态会持续生效,直到你主动修改它。你注释掉这些代码后渲染结果不变,是因为这些状态在之前的代码执行中(比如初始化阶段、上一帧渲染)已经被正确设置过了,当前帧跳过这些步骤,状态依然保留,所以渲染正常。
逐行解析代码作用
gl.enableVertexAttribArray(a_Vertex_location)/gl.enableVertexAttribArray(a_Color_location):
启用指定位置的顶点属性数组,告诉WebGL:这个属性的数据要从绑定的缓冲区中读取,而不是使用gl.vertexAttrib[1-4]f设置的固定常量值。如果不启用这个状态,WebGL会忽略缓冲区数据,用固定值渲染。gl.bindBuffer(gl.ARRAY_BUFFER, triangles_color_buffer_id):
将颜色数据缓冲区绑定到ARRAY_BUFFER目标。WebGL的ARRAY_BUFFER是一个全局绑定点,后续的gl.vertexAttribPointer调用会基于当前绑定的缓冲区来设置属性数据的来源。gl.vertexAttribPointer(a_Color_location, 3, gl.FLOAT, false, 0, 0):
配置颜色属性的读取规则:每个颜色属性由3个浮点数组成(对应RGB),不对数据做归一化处理,属性之间的步长为0(数据紧密排列),从缓冲区起始位置开始读取。这条指令会把当前绑定的ARRAY_BUFFER和该属性位置关联起来。
为什么现在注释掉没事,但不能省略?
如果你的渲染逻辑只渲染这一个模型,且永远不修改相关状态,这些代码确实可以只执行一次。但如果后续要渲染其他模型(比如切换顶点/颜色缓冲、禁用属性数组),再回到这个模型时,必须重新设置这些状态,否则会使用错误的缓冲区数据或常量值,导致渲染异常。
内容的提问来源于stack exchange,提问作者luek baja

