gl_FragColor and glReadPixels

5

我仍在努力从片段着色器中读取像素,有一些问题需要解决。 我知道 gl_FragColor 返回 vec4 表示 RGBA,即 4 个通道。 接着,我使用 glReadPixels 读取 FBO 并将其写入数据。

GLubyte *pixels = new GLubyte[640*480*4];
glReadPixels(0, 0, 640,480, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

这个功能可以正常工作,但速度存在问题。我想只读取RGB而忽略alpha通道。我尝试了:

GLubyte *pixels = new GLubyte[640*480*3];
glReadPixels(0, 0, 640,480, GL_RGB, GL_UNSIGNED_BYTE, pixels);

尝试了替换,但并没有起作用。我猜是因为gl_FragColor返回了4个通道,也许我需要在此之前进行一些处理?实际上,由于我的返回图像(gl_FragColor)是灰度的,所以我做了类似于以下的操作:

float gray = 0.5 //or some other values
gl_FragColor = vec4(gray,gray,gray,1.0);

有没有更高效的方法使用glReadPixels而不是使用前4个通道的方法?有什么建议吗?顺便说一句,这是OpenGL ES 2.0代码。
1个回答

4

OpenGL ES 2.0规范指出,有两种有效的调用形式:

glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

或者
GLint format, type;
glGetIntegerv(IMPLEMENTATION_COLOR_READ_FORMAT, &format);
glGetIntegerv(IMPLEMENTATION_COLOR_READ_TYPE, &type);
glReadPixels(x, y, w, h, format, type, pixels);

可能的格式类型(type)组合如下(截自规格说明): table 实现将决定哪种组合可用。
然而,如果您创建了一个适当格式的渲染表面,则这将是您获得的格式。尝试修改代码以获得RGB帧缓冲区(即具有alpha通道的0位)。或者,也许您想要创建一个离屏帧缓冲对象来达到这个目的?

谢谢回复!我一定会尽快尝试!但是你能否给我更多关于离屏帧缓冲的想法或描述?我对图形学还不太熟悉,所以不熟悉这些术语。也许有教程的链接吗?再次感谢! - user2168
1
一个帧缓冲对象(FBO)基本上是一个你自己创建的次要渲染目标。它可以包含颜色缓冲区、深度缓冲区、alpha缓冲区或其他什么内容。然后,你可以向其绘制(而不是向“屏幕”,即主帧缓冲区)并以某种方式使用结果,例如作为效果的纹理,或读取像素(在你的情况下)。 - Kos
1
http://www.songho.ca/opengl/gl_fbo.html 看起来是一个很好的实用教程,有示例代码(虽然是针对OpenGL的,但在ES 2中应该差不多)。同时也可以阅读规范(之前提供的链接,第4.4.3章节)。 - Kos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接