我正在尝试在我的WebGL程序中实现拾取(使用colors和readPixels)。当我开始我的程序时,我创建了单独的shaderProgram。一个用于phong着色,另一个用于简单地为形状提供一种颜色,用于检测已点击的形状。
phong着色器有2个属性。顶点位置和顶点法线。挑选一个只是有位置。
现在我发现由于一些奇怪的原因,当这两个着色器存在于同一个程序中并且我正在使用拾取一个时,我的drawArray调用似乎失败了。最后一件事是我的gl.vertexAttribPointer调用。我一直在搞乱,发现当我使用以下方法检查活动的attrib数组时: gl.getVertexAttrib(指数,gl.VERTEX_ATTRIB_ARRAY_ENABLED);
0,1都返回true(这是使用gl.useProgram(拾取)激活拾取着色器时)
现在如果我用gl.disableVertexAttribArray(1)禁用1;一切都有效。另一种解决方法是首先使用phong着色器进行绘制,然后使用拾取着色器,然后以某种方式神奇地使其成功。我猜测在那种情况下,在使用phong着色器时附加我的顶点法线缓冲区时,当我切换到拾取着色器并且drawArray调用有效时,它会以某种方式停留。
我想知道我是否使用了gl.enableAttribArray错误,并且应该在切换着色器时禁用它们。
我还尝试以不同的顺序创建着色器程序但没有成功。
答案 0 :(得分:3)
正如您可能已经想到的那样,useProgram不会影响除了应该在下一次绘制调用中运行的程序(着色器代码)之外的任何内容。您必须确保仅启用当前程序使用的属性。
如果你以某种方式包装了你的WebGL代码,提示是保存包装器中某处存储的每个程序的最高可用属性编号,然后与最新使用的程序进行比较,并在绘制调用之前相应地启用/禁用。 / p>
答案 1 :(得分:1)
OpenGL是一个状态机。通过选择拾取着色器,您可以将OpenGL置于不再具有phong着色器的附加属性的状态。
许多人陷入了错误和不好的习惯,认为OpenGL存在某种“一次性初始化”。不是这种情况。你应该在绘图操作之前设置一些绘图操作所需的所有状态,理想情况下还要在完成后恢复设置。这意味着:绑定着色器后,您还应该启用并绑定所需的着色器输入,即顶点属性。
答案 2 :(得分:1)
在没有看到你的代码的情况下很难说但是...... WebGL要求所有要访问的属性都有足够的数据来满足绘制调用。因此,如果您设置2个属性,每个属性有3个数据顶点并绘制3个顶点,则切换着色器并使用6个顶点设置1个属性,并使第二个属性仅包含3个顶点,然后尝试绘制6个顶点,如果着色器为'当前使用两个属性访问绘制WebGL将无法进行绘制调用。
如果您运行Chrome 19,它应该在JavaScript控制台中告诉您这是否是问题。