Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gl_FragColor and glReadPixels

I am still trying to read pixels from fragment shader and I have some questions. I know that gl_FragColor returns with vec4 meaning RGBA, 4 channels. After that, I am using glReadPixels to read FBO and write it in data

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

This works fine but it really has speed issue. Instead of this, I want to just read RGB so ignore alpha channels. I tried:

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

instead and this didn't work though. I guess it's because gl_FragColor returns 4 channels and maybe I should do something before this? Actually, since my returned image (gl_FragColor) is grayscale, I did something like

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

So is there any efficient way to use glReadPixels instead of using the first 4 channels method? Any suggestion? By the way, this is on opengl es 2.0 code.

like image 656
user2168 Avatar asked Oct 09 '22 08:10

user2168


1 Answers

The OpenGL ES 2.0 spec says that there are two valid forms of the call:

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

or

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

The possible combinations for format and type are (pic taken from the spec):

table

And the implementation will decide which is available to you.

However, it's likely that if you create a rendering surface of an appropriate format, then that will be the format you'll obtain here. See if you can modify your code to obtain a RGB framebuffer (i.e. with 0 bits for alpha channel). Or perhaps you might want to create an offscreen framebuffer object for that purpose?

like image 120
Kos Avatar answered Oct 13 '22 11:10

Kos