Sign in to follow this  

Reading texture/framebuffer data with glReadPixels()

This topic is 3554 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm rendering an image to the screen, and I then want to get the screen buffer and dump all the colour data per pixel to a set of three arrays (one per colour channel). I've sorta played with this stuff before, but not actually getting data from the buffer back to the application. Heres what I've got so far:

void GetTextureData()
{
//Setup FBO
		// First we bind the FBO so we can render to it
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
		
		// Save the view port and set it to the size of the texture
		glPushAttrib(GL_VIEWPORT_BIT);
		glViewport(0,0,width,height);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer
		glLoadIdentity();									// Reset The View

		PreDisplay();			//Setup to draw in ortho
		glBindTexture(GL_TEXTURE_2D, imageTexture[0]);
 		glEnable(GL_TEXTURE_2D);
		glDisable(GL_LIGHTING);
		glDisable(GL_DEPTH_TEST);	//Disable depth testing and masking
		glDepthMask(GL_FALSE);

		float dimensionsNeg = 0.0f;
		float dimensionsPos = 1.0f;

		PreDisplay();			//Setup to draw in ortho
			glColor3f(1.0f,1.0f,1.0f);
			glBegin(GL_QUADS);
				glTexCoord2f(0.0f, 0.0f); glVertex3f(dimensionsNeg, dimensionsNeg, 0.0f);
				glTexCoord2f(0.0f, 1.0f); glVertex3f(dimensionsNeg, dimensionsPos, 0.0f);
				glTexCoord2f(1.0f, 1.0f); glVertex3f(dimensionsPos, dimensionsPos, 0.0f);
				glTexCoord2f(1.0f, 0.0f); glVertex3f(dimensionsPos, dimensionsNeg, 0.0f);
			glEnd();
		ViewPerspective();

			for(int i = 0 ; i < N ; i++)
			{
				for(int j = 0 ; j < N ; j++)
				{
					glReadPixels(i,j,1,1,GL_RED, GL_FLOAT, &dens_prev_r[IX(i,j)]);
					glReadPixels(i,j,1,1,GL_GREEN, GL_FLOAT, &dens_prev_g[IX(i,j)]);
					glReadPixels(i,j,1,1,GL_BLUE, GL_FLOAT, &dens_prev_b[IX(i,j)]);
					dens_r[IX(i,j)] = dens_prev_r[IX(i,j)];
					dens_g[IX(i,j)] = dens_prev_g[IX(i,j)];
					dens_b[IX(i,j)] = dens_prev_b[IX(i,j)];

				}
			}

		// Restore old view port and set rendering back to default frame buffer
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer
		glPopAttrib();
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


}


The data pumped to the arrays is either 1.0f or 0.0f, with nothing in between.

Share this post


Link to post
Share on other sites
I always recommend that you read the FBO in the same format that it is in because this case MUST be correctly implemented in the driver.
It is possible that other cases are not well tested, not well debugged by driver team, or fall into the who-cares category.

Depending on your format :

glReadPixels(i,j,1,1,GL_BGRA, GL_FLOAT, pixels);
or
glReadPixels(i,j,1,1,GL_BGRA, GL_UNSIGNED_BYTE, pixels);

Share this post


Link to post
Share on other sites
How do you store GL_BGRA ? With GL_FLOAT it made sense to store it in a single variable. If i store GL_BGRA, do I have to dissasemble it into different channels?

Share this post


Link to post
Share on other sites
thanks, I tried that (I didn't realise it would be so intuitive but I'm still getting 1.0f for everything.

Could it be that I've setup the framebuffer object wrong? It's based mostly on a sample, and I think it might be setup to record depth and not colour, or something?


void SetupFBO()
{
// Setup our FBO
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

// Create the render buffer for depth
glGenRenderbuffersEXT(1, &depthBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);

// Now setup a texture to render to
glGenTextures(1, &img);
glBindTexture(GL_TEXTURE_2D, img);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RED, GL_FLOAT, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

// The following 3 lines enable mipmap filtering and generate the mipmap data so rendering works
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
// glGenerateMipmapEXT(GL_TEXTURE_2D);

// And attach it to the FBO so we can render to it
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, img, 0);

// Attach the depth render buffer to the FBO as it's depth attachment
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);


GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
exit(1);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind the FBO for now
}

Share this post


Link to post
Share on other sites

This topic is 3554 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this