切换GLSL程序时的WebGL状态管理

时间:2013-06-16 14:18:42

标签: 3d glsl webgl

所以这是一个有点模糊的问题,可能是由于我对WebGL(OpenGL)内部的知识仍然有限(但正在改进),特别是在GL上下文中管理状态的方式。请让我澄清或/并添加更多细节。因为我不知道问题到底在哪里,我尽可能多地提供信息。

我有一种情况,我实施挑选一个微小的渲染引擎。 当我有一个简单的着色器,其中每个对象都以恒定的颜色渲染时,一切正常。 我有每个对象2个缓冲区,一个ARRAY_BUFFER和一个ELEMENT_ARRAY_BUFFER。 拾取方面是通过一个额外的FrameBuffer实现的,其中场景通过“拾取”着色器呈现给它。当我需要渲染拾取帧时,我切换到备用FrameBuffer,然后切换到拾取着色器(gl.useProgram()),渲染场景,然后切换回默认画布FrameBuffer。然后我读出了点击的画布坐标上的像素值,并使用该值查找特定元素的ID ...我甚至将整个FrameBuffer渲染到一个单独的画布,作为调试步骤,并显示该画布DOM,看到它确实正确地渲染了东西。

当我打开顶点着色时出现问题。每个顶点指定颜色值,并作为VertexAttribArray传递到着色器(与顶点坐标相同)。但是,当打开着色时,拾取渲染不会渲染任何内容(输出空白屏幕)。

我已经隔离了导致此错误的着色功能部分(拾取框的空白渲染):

Buffer vertex_color_buffer = gl.createBuffer();
gl.bindBuffer(RenderingContext.ARRAY_BUFFER,vertex_color_buffer);

gl.bufferData(RenderingContext.ARRAY_BUFFER,
              new Float32List.fromList(unpacked_colors_lst), 
              RenderingContext.STATIC_DRAW); 

int color_attr_location = gl.getAttribLocation(p_shader, 
                                               "a_vertex_color");
gl.enableVertexAttribArray(color_attr_location);    
gl.vertexAttribPointer(color_attr_location,
                       4,
                       RenderingContext.FLOAT, 
                       false, 
                       4*Float32List.BYTES_PER_ELEMENT, //stride
                       0);                              //offset within the buffer

所以显然在这些线中设置了一些GL状态,然后,当着色器从顶点着色着色器(显示正确的东西)切换到拾取着色器时,导致场景不被渲染。 我认为我的顶点变换可能有问题,但它们在着色着色器和拾取着色器之间是相同的,但是着色着色器显示的东西很好,而拾取着色器却没有。

请让我知道还需要包含哪些内容才能使这个问题更加明确。我花了好几天试图调试这个,但仍然没有任何想法。 (例如,代码是用Dart编写的)。

1 个答案:

答案 0 :(得分:1)

“color_attr_location”和拾取着色器中的某些属性可能共享相同的位置(很难从该代码中分辨出来),因此在指定数组时会替换另一个。如果您只设置一次数组,然后切换程序而不再重新设置,那很可能是问题。

WebGL中的AFAIK需要在每次绘制调用之前手动设置顶点数组(而不是使用顶点数组对象),这意味着最好在以后再次禁用它们。

使用程序 - >设置数组 - >渲染 - >禁用数组 - >使用其他程序 - >设置数组