我想访问framebuffer来获取RGB并更改每个像素的值。这是因为glReadPixels和glDrawPixels使用起来太慢,所以我应该使用着色器而不是使用它们。
现在,我编写代码,并成功使用GLSL着色器显示三维模型。
我按如下方式画了两个立方体。....
glDrawArrays(GL_TRIANGLES, 0, 12*6);
....
和片段着色器:
varying vec3 fragmentColor;
void main()
{
gl_FragColor = vec4(fragmentColor, 1);
}
然后,我如何访问RGB值并进行更改? 例如,如果窗口上的(u1,v1)和(u2,v2)的像素值是(0,0,255),那么我想将它们更改为(255,0,0)
答案 0 :(得分:1)
除了OpenGL ES-only扩展外,片段着色器不能只读取当前的帧缓冲区。否则,我们不需要blending。
您也不能只渲染到您在着色器中读取的图像。因此,如果您需要进行某种后处理,那么最好通过渲染到单独的图像来完成。也就是说,您对图像1进行渲染,然后将其作为纹理绑定并更改FBO,以便渲染到图像2。
或者,如果您有权访问OpenGL 4.5/ARB/NV_texture_barrier,则可以使用纹理障碍来处理此问题。如果将当前帧缓冲区的图像绑定为纹理,则允许您进行单个读取/修改/写入传递。您在执行读取/修改/写入之前发出屏障,然后将该纹理绑定到采样器,同时仍然呈现给该帧缓冲区。
此外,这要求FS从精确纹理中读取它要写入的内容。假设视口锚定在0,0,则代码为texelFetch(sampler, ivec2(gl_FragCoord.xy), 0)
。你不能从别人的纹理元素中读取并修改它。
显然你必须渲染到纹理;你不能使用默认的帧缓冲。
纹理屏障可用于从不同的纹素读取的情况。但这需要做类似第一种切换绑定图像的情况。虽然你不需要完全改变FBO;您可以更改渲染到的FBO的区域。也就是说,只要您从不同的区域读取而不是渲染,并且在这些区域之间切换时适当地使用障碍,一切都很好。